PMCORE-3067: UI - <List sorting> List Sorting feature

This commit is contained in:
Rodrigo Quelca
2021-07-27 20:38:26 +00:00
parent 89c3311d55
commit 7a63b52e01
10 changed files with 184 additions and 12 deletions

26
package-lock.json generated
View File

@@ -11,12 +11,38 @@
"regenerator-runtime": "^0.13.2"
}
},
"@fortawesome/fontawesome-common-types": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz",
"integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw=="
},
"@fortawesome/fontawesome-free": {
"version": "5.15.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz",
"integrity": "sha512-OEdH7SyC1suTdhBGW91/zBfR6qaIhThbcN8PUXtXilY4GYnSBbVqOntdHbC1vXwsDnX0Qix2m2+DSU1J51ybOQ==",
"dev": true
},
"@fortawesome/fontawesome-svg-core": {
"version": "1.2.35",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz",
"integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
}
},
"@fortawesome/free-solid-svg-icons": {
"version": "5.15.3",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz",
"integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
}
},
"@fortawesome/vue-fontawesome": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.2.tgz",
"integrity": "sha512-ecpKSBUWXsxRJVi/dbOds4tkKwEcBQ1JSDZFzE2jTFpF8xIh3OgTX8POIor6bOltjibr3cdEyvnDjecMwUmxhQ=="
},
"@nuxt/opencollective": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.2.tgz",

View File

@@ -20,6 +20,9 @@
"vue-template-compiler": "^2.6.10"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.2",
"axios": "^0.15.3",
"bootstrap": "^4.5.3",
"bootstrap-colorpicker": "^3.0.3",

View File

@@ -0,0 +1,24 @@
import ApiInstance from "./Api.js";
import Services from "./Services";
let Api = new ApiInstance( Services );
export let config = {
get(data) {
return Api.get({
service: "CONFIG",
params: data
});
},
post(data) {
return Api.post({
service: "CONFIG",
data: data
});
},
put(data) {
return Api.put({
service: "CONFIG",
data: data
});
},
};

View File

@@ -67,5 +67,6 @@
USERS: "/home/users",
TASKS: "/home/tasks",
CATEGORIES: "/home/categories",
DEBUG_STATUS: "/home/process-debug-status?processUid={prj_uid}"
DEBUG_STATUS: "/home/process-debug-status?processUid={prj_uid}",
CONFIG: "/home/config"
};

View File

@@ -1,7 +1,7 @@
import { menu } from "./Menu";
import { cases, casesHeader } from "./Cases";
import { config } from "./Config";
import { caseNotes } from "./CaseNotes";
import { process } from "./Process";
import { filters } from "./Filters";
@@ -13,5 +13,6 @@ export default {
casesHeader,
process,
caseNotes,
filters
filters,
config
};

View File

@@ -0,0 +1,17 @@
<template>
<font-awesome-icon v-if="props.sortable" :icon="icon" class="fa-pull-right"/>
</template>
<script>
export default {
name: "VtSortControl",
props: ['props'],
computed: {
icon() {
// if not sorted return base icon
if (!this.props.sortStatus.sorted) return 'sort';
// return sort direction icon
return this.props.sortStatus.asc ? 'sort-amount-up' : 'sort-amount-down';
}
}
}
</script>

View File

@@ -25,6 +25,7 @@
:pageUri="pageUri"
:name="pageName"
:defaultOption="defaultOption"
:settings="config[page]"
@onSubmitFilter="onSubmitFilter"
@onRemoveFilter="onRemoveFilter"
@onUpdatePage="onUpdatePage"
@@ -32,7 +33,8 @@
@onLastPage="onLastPage"
@onUpdateFilters="onUpdateFilters"
@cleanDefaultOption="cleanDefaultOption"
></component>
@updateUserSettings="updateUserSettings"
></component>
</div>
</div>
</template>
@@ -85,6 +87,11 @@ export default {
pageName: null,
pageUri: null,
filters: null,
config: {},
configParams: {
id: window.config.userId || "1",
name: "home"
},
menuMap: {
CASES_MY_CASES: "MyCases",
CASES_SENT: "MyCases",
@@ -103,6 +110,7 @@ export default {
mounted() {
this.onResize();
this.getMenu();
this.getUserSettings();
this.listenerIframe();
window.setInterval(
this.setCounter,
@@ -148,6 +156,62 @@ export default {
console.error(e);
});
},
/**
* Gets the user config
*/
getUserSettings() {
api.config
.get(this.configParams)
.then((response) => {
if (response.data) {
this.config = response.data;
} else {
this.createUserSettings();
}
})
.catch((e) => {
console.error(e);
});
},
/**
* Creates the user config service
*/
createUserSettings() {
api.config
.post({
...this.configParams,
...{setting: '{}'}
})
.then((response) => {
if (response.data) {
this.config = response.data;
}
})
.catch((e) => {
console.error(e);
});
},
/**
* Update the user config service
*/
updateUserSettings(prop, data) {
if (!this.config.setting[this.page]) {
this.config.setting[this.page] = {};
}
this.config.setting[this.page][prop] = data;
api.config
.put(this.config)
.then((response) => {
if (response.data) {
// this.settings = response.data;
console.log("Udated")
console.log(this.config);
}
})
.catch((e) => {
console.error(e);
});
},
/**
* Set default cases menu option
*/
@@ -335,7 +399,8 @@ export default {
},
onUpdateFilters(filters) {
this.filters = filters;
}
},
}
};
</script>

View File

@@ -86,7 +86,7 @@ export default {
GroupedCell,
ModalComments,
},
props: ["filters", "defaultOption"],
props: ["filters", "defaultOption", "settings"],
data() {
let that = this;
return {
@@ -102,6 +102,11 @@ export default {
allView: [],
filterHeader: "STARTED",
headers: [],
columMap: {
case_number: "APP_NUMBER",
case_title: "DEL_TITLE",
process_name: "PRO_TITLE"
},
newCase: {
title: this.$i18n.t("ID_NEW_CASE"),
class: "btn-success",
@@ -151,6 +156,8 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: ['case_number'],
orderBy: this.settings && this.settings.orderBy ? this.settings.orderBy: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
@@ -304,13 +311,14 @@ export default {
*/
getCasesForVueTable(data) {
let that = this,
dt,
dt,
paged,
limit = data.limit,
start = data.page === 1 ? 0 : limit * (data.page - 1),
filters = {};
paged = start + "," + limit;
filters = {},
sort = "";
paged = start + "," + limit;
debugger;
filters = {
filter: that.filterHeader,
paged: paged,
@@ -320,11 +328,20 @@ export default {
filters[item.filterVar] = item.value;
}
});
sort = that.prepareSortString(data);
if (sort) {
filters["sort"] = sort;
that.$emit("updateUserSettings", "orderBy", {
column: data.orderBy,
ascending: data.ascending === 1 ? true: false
});
}
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases
.myCases(filters)
.then((response) => {
dt = that.formatDataResponse(response.data.data);
resolutionFunc({
data: dt,
count: response.data.total,
@@ -335,6 +352,18 @@ export default {
});
});
},
/**
* Prepare sort string to be sended in the service
* @param {object} data
* @returns {string}
*/
prepareSortString(data){
let sort = "";
if (data.orderBy && this.columMap[data.orderBy]) {
sort = `${this.columMap[data.orderBy]},${data.ascending === 1 ? "ASC": "DESC"}`;
}
return sort;
},
/**
* Format Response API TODO to grid inbox and columns
*/

View File

@@ -5,6 +5,7 @@ import VueI18n from 'vue-i18n';
import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue';
import { ServerTable, Event, ClientTable } from 'vue-tables-2';
import VtTableHeadingCustom from './../components/vuetable/extends/VtTableHeadingCustom';
import VtSortControl from './../components/vuetable/extends/VtSortControl';
import SettingsPopover from "../components/vuetable/SettingsPopover.vue";
import Sortable from 'sortablejs';
import "@fortawesome/fontawesome-free/css/all.css";
@@ -13,15 +14,19 @@ import 'bootstrap/dist/css/bootstrap-grid.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import Home from "./Home";
Vue.use(VueRouter);
Vue.use(VueSidebarMenu);
Vue.use(BootstrapVue);
Vue.use(BootstrapVueIcons);
Vue.use(VueI18n);
Vue.component('font-awesome-icon', FontAwesomeIcon);
Vue.use(ServerTable, {}, false, 'bootstrap3', {
tableHeading: VtTableHeadingCustom
tableHeading: VtTableHeadingCustom,
sortControl: VtSortControl
});
Vue.use(ClientTable, {}, false, 'bootstrap3', {});
Vue.component('settings-popover', SettingsPopover);

View File

@@ -4,6 +4,7 @@ use Eusebiu\JavaScript\Facades\ScriptVariables;
use Illuminate\Support\Facades\View;
use ProcessMaker\Core\System;
use ProcessMaker\Model\Application;
use ProcessMaker\Model\User;
$conf = new Configurations();
@@ -127,7 +128,6 @@ $oHeadPublisher->assign('urlProxy', $urlProxy); //sending the urlProxy to make
$oHeadPublisher->assign("_nodeId", isset($confDefaultOption) ? $confDefaultOption : "PM_USERS"); //User menu permissions
$oHeadPublisher->assign("FORMATS", $conf->getFormats());
$userCanAccess = 1;
global $translation;
@@ -142,4 +142,5 @@ ScriptVariables::add('SYS_URI', SYS_URI);
ScriptVariables::add('SYS_LANG', SYS_LANG);
ScriptVariables::add('TRANSLATIONS', $translation);
ScriptVariables::add('FORMATS', $conf->getFormats());
ScriptVariables::add('userId', User::getId($_SESSION['USER_LOGGED']));
echo View::make('Views::home.home', compact("userCanAccess"))->render();