PMCORE-2550: Advanced Search , improve user filter module (suggest)

This commit is contained in:
Rodrigo Quelca
2020-12-15 20:55:45 +00:00
parent 87861e6bca
commit b51e08a556
10 changed files with 183 additions and 149 deletions

View File

@@ -66,7 +66,8 @@ const services = {
PUT_MY_FILTERS: "/cases/advanced-search/filter/",
DELETE_MY_FILTERS: "/cases/advanced-search/filter/",
SEARCH: "/home/search",
PROCESSES: "/home/processes"
PROCESSES: "/home/processes",
USERS: "/home/users"
};
export default {

View File

@@ -172,10 +172,13 @@ export let cases = {
export let casesHeader = {
get() {
return new Promise((resolutionFunc, rejectionFunc) => {
resolutionFunc({
data: headerData
});
return axios.get(window.config.SYS_SERVER +
'/api/1.0/' +
window.config.SYS_WORKSPACE +
'/home/counters', {
headers: {
'Authorization': 'Bearer ' + window.config.SYS_CREDENTIALS.accessToken
}
});
}
};

View File

@@ -57,6 +57,18 @@ export let filters = {
keys: {},
});
},
/**
* Service to get the users list
*/
userList(query) {
return Api.get({
service: "USERS",
params: {
text: query,
},
keys: {},
});
},
/**
* Service to get the users list
*/

View File

@@ -51,7 +51,7 @@ export default {
}
.v-btn-texts-header {
font-size: 0.7vw;
font-size: 0.8vw;
}
.v-btn-header {
min-width: 150px;

View File

@@ -105,7 +105,7 @@
v-for="tag in tags"
@remove="customRemove(removeTag, tag)"
:key="tag"
:title="tag"
:title="searchTagsModels[tag].tagText"
:variant="tagVariant"
class="mr-1"
>
@@ -173,6 +173,9 @@ import DueDate from "./popovers/DueDate.vue";
import LastModifiedDate from "./popovers/LastModifiedDate.vue";
import CaseTitle from "./popovers/CaseTitle.vue";
import ProcessName from "./popovers/ProcessName.vue";
import CasePriority from "./popovers/CasePriority.vue";
import CaseStatus from "./popovers/CaseStatus.vue";
import CurrentUser from "./popovers/CurrentUser.vue";
import api from "./../../api/index";
export default {
@@ -184,7 +187,10 @@ export default {
DueDate,
LastModifiedDate,
CaseTitle,
ProcessName
ProcessName,
CasePriority,
CaseStatus,
CurrentUser
},
data() {
return {
@@ -224,7 +230,6 @@ export default {
filterBy: ["caseTitle"],
values: {}
},
ProcessName: {
title: `${this.$i18n.t('ID_FILTER')}: ${this.$i18n.t('ID_PROCESS_NAME')}`,
optionLabel: this.$i18n.t('ID_PROCESS_NAME'),
@@ -233,6 +238,45 @@ export default {
tagText: "",
filterBy: ["process", "processOption"],
processOption: {"PRO_TITLE": ""}
},
CasePriority: {
title: `${this.$i18n.t('ID_FILTER')}: ${this.$i18n.t('ID_PRIORITY')}`,
optionLabel: this.$i18n.t('ID_PRIORITY'),
detail: this.$i18n.t('ID_PLEASE_SELECT_THE_PRIORITY_FOR_THE_SEARCH'),
options: [
{ text: this.$i18n.t('ID_VERY_LOW'), value: "VL" },
{ text: this.$i18n.t('ID_LOW'), value: "L" },
{ text: this.$i18n.t('ID_NORMAL'), value: "N" },
{ text: this.$i18n.t('ID_HIGH'), value: "H" },
{ text: this.$i18n.t('ID_VERY_HIGH'), value: "VH" }
],
tagText: "",
filterBy: ["priorities"],
casePriorities: []
},
CaseStatus: {
title: `${this.$i18n.t('ID_FILTER')}: ${this.$i18n.t('ID_STATUS')}`,
optionLabel: this.$i18n.t('ID_STATUS'),
detail: this.$i18n.t('ID_PLEASE_SELECT_THE_STATUS_FOR_THE_SEARCH'),
options: [
{ text: this.$i18n.t('ID_CASES_STATUS_DRAFT'), value: "DRAFT" },
{ text: this.$i18n.t('ID_CASES_STATUS_TO_DO'), value: "TO_DO" },
{ text: this.$i18n.t('ID_CASES_STATUS_COMPLETED'), value: "COMPLETED" },
{ text: this.$i18n.t('ID_CASES_STATUS_CANCELLED'), value: "CANCELLED" },
{ text: this.$i18n.t('ID_CASES_STATUS_PAUSED'), value: "PAUSED" },
],
tagText: "",
filterBy: ["caseStatuses"],
caseStatuses: []
},
CurrentUser: {
title: `${this.$i18n.t('ID_FILTER')}: ${this.$i18n.t('ID_CURRENT_USER')}`,
optionLabel: this.$i18n.t('ID_CURRENT_USER'),
detail: "",
placeholder: this.$i18n.t('ID_USER_NAME'),
tagText: "",
filterBy: ["userId", "selectedOption"],
selectedOption: {"USR_FULLNAME": ""}
}
},
text: "",
@@ -295,32 +339,42 @@ export default {
let label = "";
switch (type) {
case "CaseNumber":
label = `${this.$i18n.t("ID_IUD")}: ${params.filterCases}`
this.searchTagsModels[type].tagText = `${this.$i18n.t("ID_IUD")}: ${params.filterCases}`
this.searchTagsModels[type].values["filterCases"] = params.filterCases;
break;
case "DueDate":
label = `${this.$i18n.t('ID_FROM')}: ${params.dueDateFrom} ${this.$i18n.t('ID_TO')}: ${params.dueDateTo}`;
this.searchTagsModels[type].tagText = `${this.$i18n.t('ID_FROM')}: ${params.dueDateFrom} ${this.$i18n.t('ID_TO')}: ${params.dueDateTo}`;
this.searchTagsModels[type].values["dueDateFrom"] = params.dueDateFrom;
this.searchTagsModels[type].values["dueDateTo"] = params.dueDateTo;
break;
case "LastModifiedDate":
label = `${this.$i18n.t('ID_FROM')}: ${params.delegationDateFrom} ${this.$i18n.t('ID_TO')}: ${params.delegationDateTo}`;
this.searchTagsModels[type].tagText = `${this.$i18n.t('ID_FROM')}: ${params.delegationDateFrom} ${this.$i18n.t('ID_TO')}: ${params.delegationDateTo}`;
this.searchTagsModels[type].values["delegationDateFrom"] = params.delegationDateFrom;
this.searchTagsModels[type].values["delegationDateTo"] = params.delegationDateTo;
break;
case "CaseTitle":
label = `${this.$i18n.t("ID_CASE_TITLE")}: ${params.caseTitle}`;
this.searchTagsModels[type].tagText = `${this.$i18n.t("ID_CASE_TITLE")}: ${params.caseTitle}`;
this.searchTagsModels[type].values["caseTitle"] = params.caseTitle;
break;
case "ProcessName":
label = `${this.$i18n.t("ID_PROCESS")}: ${params.processOption.PRO_TITLE || ''}`;
this.searchTagsModels[type].tagText = `${this.$i18n.t("ID_PROCESS")}: ${params.processOption.PRO_TITLE || ''}`;
this.searchTagsModels[type].processOption = params.processOption || null;
break;
case "CasePriority":
this.searchTagsModels[type].tagText = `${this.$i18n.t('ID_PRIORITY')}: ${_.map(params.selectedOptions, 'text').join(",") || ''}`;
this.searchTagsModels[type].casePriorities = _.map(params.selectedOptions, 'value');
break;
case "CaseStatus":
this.searchTagsModels[type].tagText = `${this.$i18n.t('ID_STATUS')}: ${_.map(params.selectedOptions, 'text').join(",") || ''}`;
this.searchTagsModels[type].caseStatuses = _.map(params.selectedOptions, 'value');
break;
case "CurrentUser":
this.searchTagsModels[type].tagText = `${this.$i18n.t("ID_USER")}: ${params.selectedOption.USR_FULLNAME || ''}`;
this.searchTagsModels[type].selectedOption = params.selectedOption || null;
break;
default:
break;
}
this.searchTagsModels[type].tagText = label;
},
cleanAllTags() {
this.searchTags = [];
@@ -403,7 +457,7 @@ export default {
filters: this.filters
});
}
},
}
};
</script>
<style scoped>

View File

@@ -1,18 +1,12 @@
<template>
<div id="">
<div>
<SearchPopover :target="tag" @savePopover="onOk" :title="info.title">
<template v-slot:target-item>
<div @click="onClickTag(tag)" :id="tag">
<b-icon icon="tags-fill" font-scale="1"></b-icon>
{{ tagText }}
</div>
</template>
<template v-slot:body>
<p>{{ info.detail }}</p>
<b-form-group :label="info.label">
<b-form-checkbox
v-for="option in info.options"
v-model="selected"
v-model="info.casePriorities"
:key="option.value"
:value="option.value"
name="flavour-2a"
@@ -31,19 +25,9 @@ import SearchPopover from "./SearchPopover.vue";
export default {
components: {
SearchPopover,
SearchPopover
},
props: ["tag", "info"],
data() {
return {
selected: [], // Must be an array reference!
};
},
computed: {
tagText: function() {
return `${this.$i18n.t('ID_PRIORITY')}: ${this.selected.join(",")}`;
},
},
methods: {
/**
* Ok button handler
@@ -55,12 +39,22 @@ export default {
* Submit button handler
*/
handleSubmit() {
this.$nextTick(() => {
let selectedOptions = [];
let self = this;
_.forEach(this.info.casePriorities, function(value) {
selectedOptions.push(
_.find(self.info.options, function(o) {
return o.value === value;
})
);
});
this.$emit("updateSearchTag", {
priorities: this.selected.join(","),
CasePriority: {
priorities: this.info.casePriorities.join(","),
selectedOptions: selectedOptions,
},
});
this.$root.$emit("bv::hide::popover");
});
},
/**
* Tag Click handler

View File

@@ -1,22 +1,16 @@
<template>
<div id="">
<div>
<SearchPopover
:target="tag"
@savePopover="onOk"
:title="info.title"
>
<template v-slot:target-item>
<div @click="onClickTag(tag)" :id="tag">
<b-icon icon="tags-fill" font-scale="1"></b-icon>
{{ tagText }}
</div>
</template>
<template v-slot:body>
<h6>{{ info.detail }}</h6>
<b-form-group :label="info.label">
<b-form-checkbox
v-for="option in info.options"
v-model="selected"
v-model="info.caseStatuses"
:key="option.value"
:value="option.value"
name="flavour-2a"
@@ -35,19 +29,9 @@ import SearchPopover from "./SearchPopover.vue";
export default {
components: {
SearchPopover,
SearchPopover
},
props: ["tag", "info"],
data() {
return {
selected: [], // Must be an array reference!
};
},
computed: {
tagText: function() {
return `${this.$i18n.t('ID_STATUS')}: ${this.selected.join(",")}`;
},
},
methods: {
/**
* Ok button handler
@@ -59,12 +43,18 @@ export default {
* Submit button handler
*/
handleSubmit() {
this.$nextTick(() => {
let selectedOptions = [];
let self = this;
_.forEach(this.info.caseStatuses, function(value) {
selectedOptions.push(_.find(self.info.options, function(o) { return o.value === value; }));
});
this.$emit("updateSearchTag", {
caseStatuses: this.selected.join(","),
});
this.$root.$emit("bv::hide::popover");
CaseStatus: {
caseStatuses: this.info.caseStatuses.join(","),
selectedOptions: selectedOptions
}
});
this.$root.$emit("bv::hide::popover")
},
/**
* Tag Click handler

View File

@@ -1,36 +1,27 @@
<template>
<div id="">
<SearchPopover
:target="tag"
@savePopover="onOk"
:title="info.title"
>
<template v-slot:target-item>
<div @click="onClickTag(tag)" :id="tag">
<b-icon icon="tags-fill" font-scale="1"></b-icon>
{{ tagText }}
</div>
</template>
<div>
<SearchPopover :target="tag" @savePopover="onOk" :title="info.title">
<template v-slot:body>
<p>{{ info.detail }}</p>
<form ref="form" @submit.stop.prevent="handleSubmit">
<b-form-group
:state="valueState"
label-for="name"
:invalid-feedback="$t('ID_PROCESS_IS_REQUIRED')"
>
<vue-bootstrap-typeahead
class="mb-4"
id="name"
v-model="query"
:minMatchingChars="minMatchingChars"
:data="users"
:serializer="(item) => item.USR_FULLNAME"
:placeholder="info.placeholder"
required
:state="valueState"
/>
<multiselect
v-model="info.selectedOption"
:options="users"
placeholder="Sselect one"
label="USR_FULLNAME"
track-by="USR_ID"
:show-no-results="false"
@search-change="asyncFind"
:loading="isLoading"
id="ajax"
:limit="10"
:clear-on-select="true"
>
</multiselect>
</b-form-group>
</form>
</template>
@@ -40,41 +31,39 @@
<script>
import SearchPopover from "./SearchPopover.vue";
import VueBootstrapTypeahead from "vue-bootstrap-typeahead";
import Multiselect from "vue-multiselect";
import api from "./../../../api/index";
export default {
components: {
SearchPopover,
VueBootstrapTypeahead
Multiselect
},
props: ["tag", "info"],
data() {
return {
minMatchingChars: 1,
query: "",
users: [],
valueState: null
isLoading: false
};
},
computed: {
tagText: function() {
return `${this.$i18n.t('ID_USER')}: ${this.query}`;
}
},
watch: {
query(newQuery) {
methods: {
/**
* Find asynchronously in the server
* @param {string} query - string from the text field
*/
asyncFind(query) {
this.isLoading = true;
api.filters
.userValues(this.query)
.userList(query)
.then((response) => {
this.users = response.data;
this.isLoading = false;
})
.catch((e) => {
console.error(err);
});
}
},
methods: {
/**
* Form validations review
*/
@@ -93,25 +82,16 @@ export default {
* Form submit handler
*/
handleSubmit() {
// Exit when the form isn't valid
if (!this.checkFormValidity()) {
return;
}
this.$nextTick(() => {
let user = _.find(this.users, { USR_FULLNAME: this.query });
this.$emit("updateSearchTag", {
userId: user.USR_UID
CurrentUser: {
selectedOption: this.info.selectedOption,
userId: this.info.selectedOption.USR_ID
}
});
this.$root.$emit("bv::hide::popover");
});
},
/**
* Cick tag event handler
*/
onClickTag() {
this.$root.$emit("bv::hide::popover");
}
}
};
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style scoped></style>

View File

@@ -1,5 +1,5 @@
<template>
<div id="">
<div>
<SearchPopover :target="tag" @savePopover="onOk" :title="info.title">
<template v-slot:body>
<p>{{ info.detail }}</p>
@@ -31,13 +31,13 @@
<script>
import SearchPopover from "./SearchPopover.vue";
import Multiselect from 'vue-multiselect'
import Multiselect from "vue-multiselect";
import api from "./../../../api/index";
export default {
components: {
SearchPopover,
Multiselect,
Multiselect
},
props: ["tag", "info"],
data() {
@@ -51,14 +51,14 @@ export default {
* Find asynchronously in the server
* @param {string} query - string from the text field
*/
asyncFind (query) {
this.isLoading = true
asyncFind(query) {
this.isLoading = true;
api.filters
.processList(query)
.then((response) => {
this.processes = response.data;
this.countries = response
this.isLoading = false
this.countries = response;
this.isLoading = false;
})
.catch((e) => {
console.error(err);
@@ -85,7 +85,7 @@ export default {
this.$emit("updateSearchTag", {
ProcessName: {
processOption: this.info.processOption,
process: this.info.processOption.PRO_ID
process: this.info.processOption.PRO_ID,
}
});
this.$root.$emit("bv::hide::popover");

View File

@@ -361,15 +361,15 @@ export default {
};
_.forEach(response, (v) => {
data.push({
title: v.name,
counter: v.count,
title: this.$i18n.t(v.id),
counter: v.counter,
item: v.item,
icon: info[v.item].icon,
icon: info[v.id].icon,
onClick: (obj) => {
that.filterHeader = obj.item;
that.$refs["vueTable"].getData();
},
class: info[v.item].class,
class: info[v.id].class,
});
});
return data;