Merged in feature/PMCORE-3122 (pull request #8073)
PMCORE-3122 Approved-by: Rodrigo Quelca
This commit is contained in:
committed by
Rodrigo Quelca
commit
c0b996ebf3
@@ -23,6 +23,7 @@
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.3",
|
||||
"@fortawesome/vue-fontawesome": "^2.0.2",
|
||||
"apexcharts": "^3.27.3",
|
||||
"axios": "^0.15.3",
|
||||
"bootstrap": "^4.5.3",
|
||||
"bootstrap-colorpicker": "^3.0.3",
|
||||
@@ -38,6 +39,7 @@
|
||||
"idempotent-babel-polyfill": "^7.4.4",
|
||||
"jquery": "^3.1.1",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.29.1",
|
||||
"muuri": "^0.7.1",
|
||||
"npm-font-open-sans": "^1.1.0",
|
||||
"popper.js": "^1.12",
|
||||
@@ -48,6 +50,7 @@
|
||||
"verte": "0.0.12",
|
||||
"vfa-picker": "^5.9.1",
|
||||
"vue": "^2.6.12",
|
||||
"vue-apexcharts": "^1.6.1",
|
||||
"vue-awesome-swiper": "^3.1.3",
|
||||
"vue-chartjs": "^3.3.2",
|
||||
"vue-clipboards": "^1.2.4",
|
||||
|
||||
@@ -324,6 +324,17 @@ export let cases = {
|
||||
window.config.SYS_URI +
|
||||
`cases/debug_triggers?r=${r}&_dc=${dc}`);
|
||||
},
|
||||
/**
|
||||
* Make a search request to the Api service
|
||||
* @param {object} dt - filter parameters
|
||||
*/
|
||||
listTotalCases(dt) {
|
||||
return Api.get({
|
||||
service: "LIST_TOTAL_CASES",
|
||||
params: {},
|
||||
keys: {}
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
export let casesHeader = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from "axios";
|
||||
import ApiInstance from "./Api.js";
|
||||
import Services from "./Services";
|
||||
let Api = new ApiInstance( Services );
|
||||
let Api = new ApiInstance(Services);
|
||||
export let filters = {
|
||||
get(data) {
|
||||
return Api.get({
|
||||
@@ -42,8 +42,8 @@ export let filters = {
|
||||
params.append("action", "startCase");
|
||||
return axios.post(
|
||||
window.config.SYS_SERVER_AJAX +
|
||||
window.config.SYS_URI +
|
||||
`cases/casesStartPage_Ajax.php`,
|
||||
window.config.SYS_URI +
|
||||
`cases/casesStartPage_Ajax.php`,
|
||||
params
|
||||
);
|
||||
},
|
||||
@@ -88,11 +88,16 @@ export let filters = {
|
||||
* Service to get the categories list
|
||||
*/
|
||||
categories(query) {
|
||||
let pr = {
|
||||
limit: 15,
|
||||
offset: 0
|
||||
};
|
||||
if (query) {
|
||||
pr["name"] = query;
|
||||
}
|
||||
return Api.get({
|
||||
service: "CATEGORIES",
|
||||
params: {
|
||||
name: query,
|
||||
},
|
||||
params: pr,
|
||||
keys: {},
|
||||
});
|
||||
},
|
||||
@@ -102,8 +107,8 @@ export let filters = {
|
||||
userValues(query) {
|
||||
return axios.post(
|
||||
window.config.SYS_SERVER_AJAX +
|
||||
window.config.SYS_URI +
|
||||
`cases/casesList_Ajax?actionAjax=userValues&action=search`,
|
||||
window.config.SYS_URI +
|
||||
`cases/casesList_Ajax?actionAjax=userValues&action=search`,
|
||||
{
|
||||
query,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ApiInstance from "./Api.js";
|
||||
import Services from "./Services";
|
||||
let Api = new ApiInstance( Services );
|
||||
let Api = new ApiInstance(Services);
|
||||
|
||||
export let process = {
|
||||
list: {
|
||||
@@ -12,5 +12,36 @@ export let process = {
|
||||
keys: {}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
totalCasesByProcess(dt) {
|
||||
return Api.get({
|
||||
service: "TOTAL_CASES_BY_PROCESS",
|
||||
params: dt,
|
||||
keys: {}
|
||||
});
|
||||
},
|
||||
processCategories() {
|
||||
return Api.fetch({
|
||||
service: "PROCESS_CATEGORIES",
|
||||
method: "get",
|
||||
data: {},
|
||||
keys: {}
|
||||
});
|
||||
},
|
||||
totalCasesByRange(dt) {
|
||||
return Api.get({
|
||||
service: "TOTAL_CASES_BY_RANGE",
|
||||
method: "get",
|
||||
params: dt,
|
||||
keys: {}
|
||||
});
|
||||
},
|
||||
totalCasesByRisk(dt) {
|
||||
return Api.get({
|
||||
service: "CASES_RISK",
|
||||
method: "get",
|
||||
params: dt,
|
||||
keys: {}
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -68,6 +68,10 @@
|
||||
TASKS: "/home/tasks",
|
||||
CATEGORIES: "/home/categories",
|
||||
DEBUG_STATUS: "/home/process-debug-status?processUid={prj_uid}",
|
||||
LIST_TOTAL_CASES: "/metrics/list-total-cases",
|
||||
TOTAL_CASES_BY_PROCESS:"/metrics/total-cases-by-process",
|
||||
TOTAL_CASES_BY_RANGE:"/metrics/process-total-cases",
|
||||
CASES_RISK:"/metrics/cases-risk",
|
||||
CONFIG: "/home/config",
|
||||
GET_CONFIG: "/home/config/{id}/{name}",
|
||||
PAUSE_CASE: "/cases/{app_uid}/pause",
|
||||
|
||||
92
resources/assets/js/components/utils/BreadCrumb.vue
Normal file
92
resources/assets/js/components/utils/BreadCrumb.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="vp-breadcrumb">
|
||||
<li
|
||||
v-for="item in formatOptions(options)"
|
||||
:key="item.label"
|
||||
:class="item.classObject"
|
||||
>
|
||||
<span v-if="item.classObject.active === true">{{ item.label }}</span>
|
||||
<a
|
||||
v-if="item.classObject.active === false"
|
||||
href="#"
|
||||
@click="item.onClick"
|
||||
>{{ item.label }}</a
|
||||
>
|
||||
</li>
|
||||
<div
|
||||
v-for="item in settings"
|
||||
:key="item.id"
|
||||
class="vp-bread-crumbs-settings vp-float-right vp-inline-block"
|
||||
>
|
||||
<span
|
||||
@click="item.onClick"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
:title="item.tooltip || ''"
|
||||
>
|
||||
<i :class="formatClass(item)"></i>
|
||||
</span>
|
||||
</div>
|
||||
</ol>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
export default {
|
||||
name: "BreadCrumb",
|
||||
props: ["options", "settings"],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* format options to Bread Crumbs
|
||||
*/
|
||||
formatOptions(data) {
|
||||
let options = data;
|
||||
for (let i = 0; i <= options.length - 1; i++) {
|
||||
if (i === options.length - 1) {
|
||||
options[i].classObject = {
|
||||
"breadcrumb-item": true,
|
||||
active: true,
|
||||
"vp-inline-block": true,
|
||||
};
|
||||
} else {
|
||||
options[i].classObject = {
|
||||
"breadcrumb-item": true,
|
||||
active: false,
|
||||
"vp-inline-block": true,
|
||||
};
|
||||
}
|
||||
}
|
||||
return options;
|
||||
},
|
||||
formatClass(item) {
|
||||
return item.class;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.vp-float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.vp-bread-crumbs-settings {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.vp-breadcrumb {
|
||||
padding: 0.75rem 1rem;
|
||||
margin-bottom: 1rem;
|
||||
list-style: none;
|
||||
background-color: #e9ecef;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.vp-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
@@ -48,6 +48,7 @@ import Inbox from "./Inbox/Inbox.vue";
|
||||
import Paused from "./Paused/Paused.vue";
|
||||
import Draft from "./Draft/Draft.vue";
|
||||
import Unassigned from "./Unassigned/Unassigned.vue";
|
||||
import TaskMetrics from "./TaskMetrics/TaskMetrics.vue";
|
||||
import BatchRouting from "./BatchRouting";
|
||||
import CaseDetail from "./CaseDetail";
|
||||
import XCase from "./XCase";
|
||||
@@ -74,7 +75,8 @@ export default {
|
||||
Unassigned,
|
||||
CaseDetail,
|
||||
LegacyFrame,
|
||||
CustomCaseList,
|
||||
TaskMetrics,
|
||||
CustomCaseList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -122,9 +124,15 @@ export default {
|
||||
parseInt(window.config.FORMATS.casesListRefreshTime) * 1000
|
||||
);
|
||||
// adding eventBus listener
|
||||
eventBus.$on('sort-menu', (data) => {
|
||||
eventBus.$on('sort-menu', (data) => {
|
||||
that.updateUserSettings('customCasesList', data);
|
||||
});
|
||||
eventBus.$on('home-update-page', (data) => {
|
||||
that.onUpdatePage(data);
|
||||
});
|
||||
eventBus.$on('home-update-datacase', (data) => {
|
||||
that.onUpdateDataCase(data);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
@@ -244,6 +252,7 @@ export default {
|
||||
mappingMenu(data) {
|
||||
var i,
|
||||
j,
|
||||
that = this,
|
||||
newData = data,
|
||||
auxId;
|
||||
for (i = 0; i < data.length; i += 1) {
|
||||
@@ -265,7 +274,7 @@ export default {
|
||||
hiddenOnCollapse: data[i].hiddenOnCollapse,
|
||||
icon: 'pie-chart-fill',
|
||||
onClick: function (item) {
|
||||
// TODO click evet handler
|
||||
that.onUpdatePage("task-metrics");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
162
resources/assets/js/home/TaskMetrics/DrillDown.vue
Normal file
162
resources/assets/js/home/TaskMetrics/DrillDown.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div
|
||||
id="v-pm-drill-down"
|
||||
ref="v-pm-drill-down"
|
||||
class="v-pm-drill-down vp-inline-block"
|
||||
>
|
||||
<div class="p-1 v-flex">
|
||||
<h6 class="v-search-title">{{ $t("ID_DRILL_DOWN_NAVIGATOR") }}</h6>
|
||||
</div>
|
||||
<div
|
||||
v-for="item in loadItems(data, level)"
|
||||
:key="item.content"
|
||||
class="vp-padding-b10"
|
||||
@click="onClick(item)"
|
||||
>
|
||||
<span class="vp-inline-block vp-padding-r10 vp-font-size-r1">
|
||||
{{ item.label }}
|
||||
</span>
|
||||
<div class="vp-inline-block">
|
||||
<span :class="item.classObject"> {{ item.content }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
export default {
|
||||
name: "DrillDown",
|
||||
mixins: [],
|
||||
components: {},
|
||||
props: ["level"],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
classObject: {
|
||||
"rounded-circle": true,
|
||||
"v-pm-drill-down-number": true,
|
||||
"vp-btn-secondary": true,
|
||||
"btn-primary": false,
|
||||
"vp-block": true,
|
||||
},
|
||||
data: [
|
||||
{
|
||||
label: that.$t("ID_LEVEL"),
|
||||
content: "0",
|
||||
click() {
|
||||
that.$emit("onChangeLevel", 0);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: that.$t("ID_LEVEL"),
|
||||
content: "1",
|
||||
click() {
|
||||
that.$emit("onChangeLevel", 1);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: that.$t("ID_LEVEL"),
|
||||
content: "2",
|
||||
click() {
|
||||
that.$emit("onChangeLevel", 2);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: that.$t("ID_LEVEL"),
|
||||
content: "3",
|
||||
click() {},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Click in drill option
|
||||
*/
|
||||
onClick(item) {
|
||||
let array,
|
||||
i = 0,
|
||||
nindex;
|
||||
array = _.clone(this.data);
|
||||
array.forEach((el) => {
|
||||
if (el.content === item.content) {
|
||||
nindex = i;
|
||||
}
|
||||
i++;
|
||||
});
|
||||
this.index = nindex;
|
||||
if (nindex <= this.level) {
|
||||
item.click(item);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Load items in drill items
|
||||
*/
|
||||
loadItems(items, index) {
|
||||
let array,
|
||||
i = 0,
|
||||
that = this;
|
||||
array = _.clone(items);
|
||||
array.forEach((el) => {
|
||||
el.classObject = _.clone(that.classObject);
|
||||
if (i <= index) {
|
||||
el.classObject["vp-btn-secondary"] = false;
|
||||
el.classObject["btn-primary"] = true;
|
||||
}
|
||||
i += 1;
|
||||
});
|
||||
return array;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.v-pm-drill-down-number {
|
||||
height: 5rem;
|
||||
width: 5rem;
|
||||
text-align: center;
|
||||
line-height: 5rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.vp-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
.vp-block {
|
||||
display: block;
|
||||
}
|
||||
.vp-padding-r10 {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.vp-padding-b10 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.vp-font-size-r1 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.vp-btn-secondary {
|
||||
color: #2f3133;
|
||||
background-color: #b5b6b6;
|
||||
}
|
||||
|
||||
.vp-btn-secondary:hover {
|
||||
color: #fff;
|
||||
background-color: #6c757d;
|
||||
border-color: #6c757d;
|
||||
}
|
||||
|
||||
.v-pm-drill-down {
|
||||
vertical-align: top;
|
||||
padding-left: 50px;
|
||||
}
|
||||
</style>
|
||||
173
resources/assets/js/home/TaskMetrics/ProcessPopover.vue
Normal file
173
resources/assets/js/home/TaskMetrics/ProcessPopover.vue
Normal file
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div class="pm-all-view-popover">
|
||||
<b-popover
|
||||
:target="target"
|
||||
ref="popover"
|
||||
triggers="click"
|
||||
placement="bottom"
|
||||
@show="onshow"
|
||||
>
|
||||
<template #title>{{ $t("ID_PROCESSES").toUpperCase() }}</template>
|
||||
<div>
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm"
|
||||
><i class="fas fa-search"></i
|
||||
></span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
aria-describedby="inputGroup-sizing-sm"
|
||||
@keyup="search"
|
||||
v-model="text"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-check border-bottom">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
v-model="allColumns"
|
||||
@change="toogleAllColumns"
|
||||
/>
|
||||
<label class="form-check-label" for="flexCheckDefault">
|
||||
{{ $t("ID_ALL") }}
|
||||
</label>
|
||||
</div>
|
||||
<b-form-group>
|
||||
<b-form-checkbox-group
|
||||
v-model="localSelected"
|
||||
:options="results"
|
||||
value-field="key"
|
||||
text-field="value"
|
||||
name="flavour-2a"
|
||||
@change="changeOptions"
|
||||
stacked
|
||||
></b-form-checkbox-group>
|
||||
</b-form-group>
|
||||
<div class="v-popover-footer">
|
||||
<div class="float-right">
|
||||
<b-button @click="onClose" size="sm" variant="danger">
|
||||
{{ $t("ID_CANCEL") }}</b-button
|
||||
>
|
||||
<b-button @click="onSave" size="sm" variant="success">{{
|
||||
$t("ID_SAVE")
|
||||
}}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</b-popover>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "ProcessPopover",
|
||||
props: ["target"],
|
||||
data() {
|
||||
return {
|
||||
options: [],
|
||||
text: "",
|
||||
results: [],
|
||||
allColumns: false,
|
||||
localSelected: [],
|
||||
selected: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.results = this.options;
|
||||
this.localSelected = this.selected;
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Setter options for fill the popover
|
||||
* @param {*} options
|
||||
*/
|
||||
setOptions(options) {
|
||||
this.options = options;
|
||||
this.results = options;
|
||||
},
|
||||
/**
|
||||
* Setter the selected options
|
||||
* @param {*} options
|
||||
*/
|
||||
setSelectedOptions(options) {
|
||||
this.selected = options;
|
||||
this.localSelected = options;
|
||||
},
|
||||
/**
|
||||
* Close buton click handler
|
||||
*/
|
||||
onClose() {
|
||||
this.$refs.popover.$emit("close");
|
||||
this.$emit("closePopover");
|
||||
},
|
||||
/**
|
||||
* Save button click handler
|
||||
*/
|
||||
onSave() {
|
||||
let sels;
|
||||
sels = _.clone(this.localSelected);
|
||||
this.$root.$emit("bv::hide::popover");
|
||||
this.$emit("onUpdateColumnSettings", sels);
|
||||
},
|
||||
/**
|
||||
* Show popover event handler
|
||||
*/
|
||||
onshow() {
|
||||
this.$root.$emit("bv::hide::popover");
|
||||
},
|
||||
/**
|
||||
* Search in the column name
|
||||
*/
|
||||
search() {
|
||||
let txt = this.text.toLowerCase(),
|
||||
val,
|
||||
opts = [];
|
||||
|
||||
opts = _.filter(this.options, function (o) {
|
||||
val = o.value.toLowerCase();
|
||||
|
||||
return val.search(txt) != -1;
|
||||
});
|
||||
|
||||
this.results = opts;
|
||||
},
|
||||
/**
|
||||
* Toogle all options in popover
|
||||
*/
|
||||
toogleAllColumns() {
|
||||
let res = [];
|
||||
if (this.allColumns) {
|
||||
_.each(this.options, function (o) {
|
||||
res.push(o.key);
|
||||
});
|
||||
}
|
||||
this.selected = res;
|
||||
},
|
||||
/**
|
||||
* Handler when change options event
|
||||
*/
|
||||
changeOptions() {
|
||||
let that = this,
|
||||
res = [];
|
||||
_.each(this.options, function (o) {
|
||||
if (
|
||||
_.findIndex(that.localSelected, function (v) {
|
||||
return v === o.key;
|
||||
}) != -1
|
||||
) {
|
||||
res.push(o.key);
|
||||
}
|
||||
});
|
||||
this.localSelected = res;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.pm-all-view-popover .popover {
|
||||
max-width: 350px !important;
|
||||
min-width: 200px !important;
|
||||
}
|
||||
.v-popover-footer {
|
||||
display: flow-root;
|
||||
}
|
||||
</style>
|
||||
79
resources/assets/js/home/TaskMetrics/TaskMetrics.vue
Normal file
79
resources/assets/js/home/TaskMetrics/TaskMetrics.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div id="v-pm-task-metrics" ref="v-pm-task-metrics" class="v-pm-task-metrics">
|
||||
<button-fleft :data="newCase"></button-fleft>
|
||||
<div class="p-1 v-flex">
|
||||
<h4 class="v-search-title">
|
||||
Task metrics
|
||||
<span class="vp-padding-r3"> <i class="fas fa-chart-pie"></i></span>
|
||||
</h4>
|
||||
</div>
|
||||
<modal-new-request ref="newRequest"></modal-new-request>
|
||||
<div class="d-inline-flex p-2">
|
||||
<vue-charts
|
||||
ref="pm-vue-chart"
|
||||
@onChangeLevel="changeLevel"
|
||||
:level="level"
|
||||
/>
|
||||
<div class="vp-6"></div>
|
||||
<drill-down :level="level" @onChangeLevel="updateVueChart" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ButtonFleft from "../../components/home/ButtonFleft.vue";
|
||||
import ModalNewRequest from "../ModalNewRequest.vue";
|
||||
import DrillDown from "./DrillDown.vue";
|
||||
import VueCharts from "./VueCharts.vue";
|
||||
|
||||
import defaultMixins from "./defaultMixins";
|
||||
export default {
|
||||
name: "TaskMetrics",
|
||||
mixins: [defaultMixins],
|
||||
components: {
|
||||
ButtonFleft,
|
||||
ModalNewRequest,
|
||||
DrillDown,
|
||||
VueCharts,
|
||||
},
|
||||
props: [],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
level: 0,
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Change level in drill down
|
||||
*/
|
||||
changeLevel(lv) {
|
||||
this.level = lv;
|
||||
},
|
||||
/**
|
||||
* update data in charts
|
||||
*/
|
||||
updateVueChart(lv) {
|
||||
this.$refs["pm-vue-chart"].onChangeLevel(lv);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.v-pm-task-metrics {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
.vp-padding-r3 {
|
||||
padding-right: 3rem;
|
||||
}
|
||||
</style>
|
||||
365
resources/assets/js/home/TaskMetrics/VueChartLvOne.vue
Normal file
365
resources/assets/js/home/TaskMetrics/VueChartLvOne.vue
Normal file
@@ -0,0 +1,365 @@
|
||||
<template>
|
||||
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
|
||||
<div class="p-1 v-flex">
|
||||
<h6 class="v-search-title">
|
||||
{{ $t("ID_DRILL_DOWN_NUMBER_TASKS_PROCESS") }}
|
||||
</h6>
|
||||
<div>
|
||||
<BreadCrumb
|
||||
:options="breadCrumbs.data"
|
||||
:settings="settingsBreadcrumbs"
|
||||
/>
|
||||
<ProcessPopover
|
||||
:options="optionsProcesses"
|
||||
target="pm-task-process"
|
||||
ref="pm-task-process"
|
||||
@onUpdateColumnSettings="onUpdateColumnSettings"
|
||||
/>
|
||||
<div class="vp-width-p40 vp-inline-block">
|
||||
<multiselect
|
||||
v-model="category"
|
||||
:options="optionsCategory"
|
||||
:searchable="false"
|
||||
:close-on-select="true"
|
||||
:show-labels="false"
|
||||
track-by="id"
|
||||
label="name"
|
||||
@select="changeOption"
|
||||
></multiselect>
|
||||
</div>
|
||||
<label class="vp-inline-block vp-padding-l20">{{
|
||||
$t("ID_TOP")
|
||||
}}</label>
|
||||
<div class="vp-inline-block">
|
||||
<b-form-checkbox
|
||||
v-model="top"
|
||||
name="check-button"
|
||||
@change="changeOption"
|
||||
switch
|
||||
>
|
||||
</b-form-checkbox>
|
||||
</div>
|
||||
<div class="vp-inline-block vp-right vp-padding-r40">
|
||||
<h4
|
||||
class="v-search-title"
|
||||
@click="showProcessesPopover"
|
||||
id="pm-task-process"
|
||||
>
|
||||
<i class="fas fa-cog"></i>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<apexchart
|
||||
ref="LevelOneChart"
|
||||
:width="width"
|
||||
:options="optionsBar"
|
||||
:series="seriesBar"
|
||||
></apexchart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
import Api from "../../api/index";
|
||||
import BreadCrumb from "../../components/utils/BreadCrumb.vue";
|
||||
import ProcessPopover from "./ProcessPopover.vue";
|
||||
import Multiselect from "vue-multiselect";
|
||||
|
||||
export default {
|
||||
name: "VueChartLvOne",
|
||||
mixins: [],
|
||||
components: {
|
||||
Multiselect,
|
||||
BreadCrumb,
|
||||
ProcessPopover,
|
||||
},
|
||||
props: ["data", "breadCrumbs"],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
category: null,
|
||||
dataProcesses: null, //Data API processes
|
||||
settingsBreadcrumbs: [
|
||||
{
|
||||
class: "fas fa-info-circle",
|
||||
tooltip: this.$t("ID_TASK_RISK_LEVEL1_INFO"),
|
||||
onClick() {},
|
||||
},
|
||||
],
|
||||
optionsCategory: [],
|
||||
optionsProcesses: [],
|
||||
selectedProcesses: [],
|
||||
top: false,
|
||||
width: 0,
|
||||
totalCases: [],
|
||||
currentSelection: null,
|
||||
seriesBar: [
|
||||
{
|
||||
data: [],
|
||||
},
|
||||
],
|
||||
optionsBar: {
|
||||
chart: {
|
||||
type: "bar",
|
||||
id: "LevelOneChart",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
events: {
|
||||
legendClick: function (chartContext, seriesIndex, config) {
|
||||
that.currentSelection = that.totalCases[seriesIndex];
|
||||
that.$emit("updateDataLevel", {
|
||||
id: that.currentSelection["PRO_ID"],
|
||||
name: that.currentSelection["PRO_TITLE"],
|
||||
level: 1,
|
||||
data: that.currentSelection,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: "100%",
|
||||
distributed: true,
|
||||
horizontal: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
position: "top",
|
||||
},
|
||||
colors: ["#33b2df", "#546E7A", "#d4526e", "#13d8aa"],
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
xaxis: {
|
||||
categories: [],
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
show: false,
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
formatter: function () {
|
||||
return "";
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.getBodyHeight();
|
||||
this.getCategories();
|
||||
this.getProcesses();
|
||||
},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Return the height for Vue Card View body
|
||||
*/
|
||||
getBodyHeight() {
|
||||
this.width = window.innerHeight;
|
||||
},
|
||||
/**
|
||||
* Get Categories form API
|
||||
*/
|
||||
getCategories() {
|
||||
let that = this;
|
||||
Api.filters
|
||||
.categories()
|
||||
.then((response) => {
|
||||
that.formatDataCategories(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Get Processes form API
|
||||
*/
|
||||
getProcesses() {
|
||||
let that = this;
|
||||
Api.filters
|
||||
.processList("")
|
||||
.then((response) => {
|
||||
that.formatDataProcesses(response.data);
|
||||
that.changeOption({
|
||||
id: 0,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Format categories for multiselect
|
||||
* @param {*} data
|
||||
*/
|
||||
formatDataCategories(data) {
|
||||
let array = [];
|
||||
array.push({
|
||||
name: this.$t("ID_PROCESS_NONE_CATEGORY"),
|
||||
id: "0",
|
||||
});
|
||||
_.each(data, (el) => {
|
||||
array.push({ name: el["CATEGORY_NAME"], id: el["CATEGORY_ID"] });
|
||||
});
|
||||
this.optionsCategory = array;
|
||||
this.category = array[0];
|
||||
},
|
||||
/**
|
||||
* Format processes for popover
|
||||
* @param {*} data
|
||||
*/
|
||||
formatDataProcesses(data) {
|
||||
let sels = [],
|
||||
labels = [],
|
||||
array = [];
|
||||
|
||||
_.each(data, (el) => {
|
||||
array.push({ value: el["PRO_TITLE"], key: el["PRO_ID"] });
|
||||
sels.push(el["PRO_ID"]);
|
||||
labels;
|
||||
});
|
||||
this.optionsProcesses = array;
|
||||
this.selectedProcesses = sels;
|
||||
|
||||
//Update the labels
|
||||
this.dataProcesses = data;
|
||||
this.updateLabels(data);
|
||||
},
|
||||
/**
|
||||
* Change the options in TOTAL CASES BY PROCESS
|
||||
* @param {*} option
|
||||
*/
|
||||
changeOption(option) {
|
||||
let that = this,
|
||||
dt = {};
|
||||
if (this.data.length > 0) {
|
||||
dt = {
|
||||
category: option.id,
|
||||
caseList: this.data[0].id.toLowerCase(),
|
||||
processes: this.selectedProcesses,
|
||||
top: this.top,
|
||||
};
|
||||
Api.process
|
||||
.totalCasesByProcess(dt)
|
||||
.then((response) => {
|
||||
that.totalCases = response.data;
|
||||
that.formatTotalCases(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Show the processes popover
|
||||
*/
|
||||
showProcessesPopover() {
|
||||
this.$root.$emit("bv::show::popover", "pm-task-process");
|
||||
this.$refs["pm-task-process"].setOptions(this.optionsProcesses);
|
||||
this.$refs["pm-task-process"].setSelectedOptions(this.selectedProcesses);
|
||||
},
|
||||
/**
|
||||
* Format response form BE to chart
|
||||
* @param {*} data
|
||||
*/
|
||||
formatTotalCases(data) {
|
||||
let serie = [],
|
||||
labels = [];
|
||||
_.each(data, (el) => {
|
||||
serie.push(el["TOTAL"]);
|
||||
labels.push(el["PRO_TITLE"]);
|
||||
});
|
||||
|
||||
this.$refs["LevelOneChart"].updateOptions({ labels: labels });
|
||||
this.$apexcharts.exec("LevelOneChart", "updateSeries", [
|
||||
{
|
||||
data: serie,
|
||||
},
|
||||
]);
|
||||
},
|
||||
/**
|
||||
* Update list processes in chart
|
||||
* @param {*} data
|
||||
*/
|
||||
onUpdateColumnSettings(data) {
|
||||
let res;
|
||||
this.selectedProcesses = data;
|
||||
res = _.intersectionBy(this.totalCases, data, (el) => {
|
||||
if (_.isNumber(el)) {
|
||||
return el;
|
||||
}
|
||||
if (_.isObject(el) && el["PRO_ID"]) {
|
||||
return el["PRO_ID"];
|
||||
}
|
||||
});
|
||||
this.formatTotalCases(res);
|
||||
},
|
||||
/**
|
||||
* Update labels in chart
|
||||
* @param {*} processes
|
||||
*/
|
||||
updateLabels(processes) {
|
||||
let labels = [];
|
||||
_.each(processes, (el) => {
|
||||
labels.push(el["PRO_TITLE"]);
|
||||
});
|
||||
this.$refs["LevelOneChart"].updateOptions({ labels: labels });
|
||||
},
|
||||
/**
|
||||
* UPdate serie in chart
|
||||
* @param {*} processes
|
||||
*/
|
||||
updateSerie(processes) {
|
||||
let labels = [];
|
||||
_.each(processes, (el) => {
|
||||
labels.push(el["TOTAL"]);
|
||||
});
|
||||
this.$refs["LevelOneChart"].updateOptions({ labels: labels });
|
||||
},
|
||||
/**
|
||||
* Force update view when update level
|
||||
*/
|
||||
forceUpdateView() {
|
||||
this.changeOption({
|
||||
id: 0,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.vp-task-metrics-label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vp-width-p40 {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.vp-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vp-padding-l20 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.vp-padding-r40 {
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
.vp-right {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
||||
493
resources/assets/js/home/TaskMetrics/VueChartLvThree.vue
Normal file
493
resources/assets/js/home/TaskMetrics/VueChartLvThree.vue
Normal file
@@ -0,0 +1,493 @@
|
||||
<template>
|
||||
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
|
||||
<div class="p-1 v-flex">
|
||||
<h6 class="v-search-title">{{$t("ID_DRILL_DOWN_RISK_MATRIX")}}</h6>
|
||||
<div>
|
||||
<BreadCrumb
|
||||
:options="breadCrumbs.data"
|
||||
:settings="settingsBreadcrumbs"
|
||||
/>
|
||||
<div class="vp-width-p30 vp-inline-block">
|
||||
<b-form-datepicker
|
||||
id="date-from"
|
||||
:date-format-options="{
|
||||
year: '2-digit',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}"
|
||||
size="sm"
|
||||
:placeholder="$t('ID_DELEGATE_DATE_FROM')"
|
||||
v-model="dateFrom"
|
||||
@input="changeOption"
|
||||
></b-form-datepicker>
|
||||
</div>
|
||||
<div class="vp-width-p30 vp-inline-block">
|
||||
<b-form-datepicker
|
||||
id="date-to"
|
||||
size="sm"
|
||||
:date-format-options="{
|
||||
year: '2-digit',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}"
|
||||
:placeholder="$t('ID_DELEGATE_DATE_TO')"
|
||||
v-model="dateTo"
|
||||
@input="changeOption"
|
||||
></b-form-datepicker>
|
||||
</div>
|
||||
<div class="vp-inline-block">
|
||||
<label class="form-label">{{
|
||||
$t("ID_TOP")
|
||||
}}</label>
|
||||
</div>
|
||||
<div class="vp-inline-block">
|
||||
<multiselect
|
||||
v-model="size"
|
||||
:options="sizeOptions"
|
||||
:searchable="false"
|
||||
:close-on-select="true"
|
||||
:show-labels="false"
|
||||
track-by="id"
|
||||
label="name"
|
||||
@input="changeOption"
|
||||
></multiselect>
|
||||
</div>
|
||||
</div>
|
||||
<apexchart
|
||||
ref="LevelThreeChart"
|
||||
:width="width"
|
||||
:options="options"
|
||||
:series="series"
|
||||
></apexchart>
|
||||
<div class="vp-width-p100">
|
||||
<div class="vp-text-align-center" role="group">
|
||||
<button
|
||||
type="button"
|
||||
@click="
|
||||
riskType = 'ON_TIME';
|
||||
changeOption();
|
||||
"
|
||||
class="btn vp-btn-success btn-sm"
|
||||
>
|
||||
On Time
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="
|
||||
riskType = 'AT_RISK';
|
||||
changeOption();
|
||||
"
|
||||
class="btn vp-btn-warning btn-sm"
|
||||
>
|
||||
At Risk
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="
|
||||
riskType = 'OVERDUE';
|
||||
changeOption();
|
||||
"
|
||||
class="btn vp-btn-danger btn-sm"
|
||||
>
|
||||
Overdue
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vp-width-p100 vp-text-align-center">
|
||||
<label class="vp-form-label">
|
||||
{{ $t("ID_TODAY") }} : {{ dateNow }}
|
||||
</label>
|
||||
</div>
|
||||
<ModalUnpauseCase ref="modal-unpause-case"></ModalUnpauseCase>
|
||||
<ModalClaimCase ref="modal-claim-case"></ModalClaimCase>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
import Api from "../../api/index";
|
||||
import Multiselect from "vue-multiselect";
|
||||
import BreadCrumb from "../../components/utils/BreadCrumb.vue";
|
||||
import moment from "moment";
|
||||
import ModalUnpauseCase from "../modal/ModalUnpauseCase.vue";
|
||||
import ModalClaimCase from "../modal/ModalClaimCase.vue";
|
||||
|
||||
export default {
|
||||
name: "VueChartLvThree",
|
||||
mixins: [],
|
||||
components: {
|
||||
Multiselect,
|
||||
BreadCrumb,
|
||||
ModalUnpauseCase,
|
||||
ModalClaimCase,
|
||||
},
|
||||
props: ["data", "breadCrumbs"],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
currentSelection: null,
|
||||
dateFrom: "",
|
||||
dateTo: "",
|
||||
dateNow: "",
|
||||
size: { name: this.$t("ID_ALL"), id: "all" },
|
||||
riskType: "ON_TIME",
|
||||
settingsBreadcrumbs: [
|
||||
{
|
||||
class: "fas fa-info-circle",
|
||||
tooltip: this.$t("ID_TASK_RISK_LEVEL3_INFO"),
|
||||
onClick() {},
|
||||
},
|
||||
],
|
||||
sizeOptions: [
|
||||
{ name: this.$t("ID_ALL"), id: "all" },
|
||||
{ name: "5", id: "5" },
|
||||
{ name: "10", id: "10" },
|
||||
{ name: "15", id: "15" },
|
||||
{ name: "20", id: "20" },
|
||||
],
|
||||
dataCasesByRisk: [],
|
||||
width: 0,
|
||||
series: [],
|
||||
options: {
|
||||
chart: {
|
||||
height: 350,
|
||||
type: "bubble",
|
||||
zoom: {
|
||||
enabled: true,
|
||||
type: "xy",
|
||||
},
|
||||
id: "LevelThreeChart",
|
||||
events: {
|
||||
markerClick: function (event, chartContext, config) {
|
||||
that.currentSelection = that.dataCasesByRisk[config.seriesIndex];
|
||||
that.onClickCaseMarker(that.currentSelection);
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter: function (val, opt) {
|
||||
if (that.dataCasesByRisk.length > 0) {
|
||||
return that.dataCasesByRisk[opt["seriesIndex"]]["number_case"];
|
||||
}
|
||||
return "";
|
||||
},
|
||||
offsetX: 0,
|
||||
},
|
||||
xaxis: {
|
||||
type: "datetime",
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 1,
|
||||
},
|
||||
tooltip: {
|
||||
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
|
||||
return that.customTooltip(series, seriesIndex, dataPointIndex, w);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.getBodyHeight();
|
||||
},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Return the height for Vue Card View body
|
||||
*/
|
||||
getBodyHeight() {
|
||||
this.width = window.innerHeight * 0.95;
|
||||
},
|
||||
/**
|
||||
* Change datepickers or radio button
|
||||
*/
|
||||
changeOption() {
|
||||
let that = this,
|
||||
dt;
|
||||
if (this.dateFrom && this.dateTo) {
|
||||
dt = {
|
||||
process: this.data[1].id,
|
||||
caseList: this.data[0].id.toLowerCase(),
|
||||
dateFrom: moment(this.dateFrom).format("DD/MM/YYYY"),
|
||||
dateTo: moment(this.dateTo).format("DD/MM/YYYY"),
|
||||
riskStatus: this.riskType,
|
||||
};
|
||||
this.size.id != "all" ? (dt["topCases"] = this.size.id) : null;
|
||||
this.dateNow = moment().format("DD/MM/YYYY h:mm:ss a");
|
||||
Api.process
|
||||
.totalCasesByRisk(dt)
|
||||
.then((response) => {
|
||||
that.formatDataRange(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Format response fromn API
|
||||
* @param {object} data
|
||||
*/
|
||||
formatDataRange(data) {
|
||||
let that = this,
|
||||
serie = [];
|
||||
this.dataCasesByRisk = data;
|
||||
_.each(data, (el) => {
|
||||
//Format the response to risk type Overdue/At risk/ On time
|
||||
switch (that.riskType) {
|
||||
case "OVERDUE":
|
||||
serie.push({
|
||||
name: el["number_case"].toString(),
|
||||
data: [
|
||||
[moment(el["due_date"]).toDate().getTime(), el["days"], 20],
|
||||
],
|
||||
});
|
||||
break;
|
||||
case "AT_RISK":
|
||||
serie.push({
|
||||
name: el["number_case"].toString(),
|
||||
data: [
|
||||
[moment(el["delegated"]).toDate().getTime(), -el["days"], 20],
|
||||
],
|
||||
});
|
||||
break;
|
||||
case "ON_TIME":
|
||||
serie.push({
|
||||
name: el["number_case"].toString(),
|
||||
data: [
|
||||
[moment(el["delegated"]).toDate().getTime(), -el["days"], 20],
|
||||
],
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this.updateApexchartAxis();
|
||||
if (this.data[0].id.toLowerCase() == "draft") {
|
||||
this.series = []; // Draft is empty
|
||||
} else {
|
||||
this.series = serie;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Update axis chart
|
||||
*/
|
||||
updateApexchartAxis() {
|
||||
switch (this.riskType) {
|
||||
case "OVERDUE":
|
||||
this.$refs["LevelThreeChart"].updateOptions({
|
||||
yaxis: {
|
||||
min: 0,
|
||||
},
|
||||
title: {
|
||||
text: "Overdue days",
|
||||
},
|
||||
});
|
||||
break;
|
||||
case "AT_RISK":
|
||||
this.$refs["LevelThreeChart"].updateOptions({
|
||||
yaxis: {
|
||||
max: 0,
|
||||
},
|
||||
title: {
|
||||
text: "Days before being Overdue",
|
||||
},
|
||||
});
|
||||
break;
|
||||
case "ON_TIME":
|
||||
this.$refs["LevelThreeChart"].updateOptions({
|
||||
yaxis: {
|
||||
max: 0,
|
||||
},
|
||||
title: {
|
||||
text: "Days before being At-Risk",
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Create custom tooltip
|
||||
*/
|
||||
customTooltip(series, seriesIndex, dataPointIndex, w) {
|
||||
let obj = this.dataCasesByRisk[seriesIndex];
|
||||
return `<div class="apexcharts-theme-light">
|
||||
<div class="apexcharts-tooltip-title" style="font-family: Helvetica, Arial, sans-serif; font-size: 12px;">
|
||||
${"Number Case"} : ${obj["number_case"]}
|
||||
</div>
|
||||
<div class="apexcharts-tooltip-series-group apexcharts-active" style="order: 1; display: flex;">
|
||||
<div class="apexcharts-tooltip-text" style="font-family: Helvetica, Arial, sans-serif; font-size: 12px;">
|
||||
<div class="apexcharts-tooltip-y-group">
|
||||
<span class="" style="background-color: #28a745;"></span>
|
||||
<span class="apexcharts-tooltip-text-y-label">Delegated</span> : <span class="apexcharts-tooltip-text-y-value">${
|
||||
obj["delegated"]
|
||||
}</span>
|
||||
</div>
|
||||
<div class="apexcharts-tooltip-y-group">
|
||||
<span class="" style="background-color: #28a745;"></span>
|
||||
<span class="apexcharts-tooltip-text-y-label">At Risk</span> : <span class="apexcharts-tooltip-text-y-value">${
|
||||
obj["at_risk"]
|
||||
}</span>
|
||||
</div>
|
||||
<div class="apexcharts-tooltip-y-group">
|
||||
<span class="" style="background-color: #28a745;"></span>
|
||||
<span class="apexcharts-tooltip-text-y-label">Due Date</span> : <span class="apexcharts-tooltip-text-y-value">${
|
||||
obj["due_date"]
|
||||
}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
},
|
||||
/**
|
||||
* Open selected cases in the inbox
|
||||
* @param {object} item
|
||||
*/
|
||||
openCase(item) {
|
||||
this.$parent.$parent.$emit("onUpdateDataCase", {
|
||||
APP_UID: item.APP_UID,
|
||||
DEL_INDEX: item.DEL_INDEX,
|
||||
PRO_UID: item.PRO_UID,
|
||||
TAS_UID: item.TAS_UID,
|
||||
ACTION: "todo",
|
||||
});
|
||||
this.$parent.$parent.$emit("onUpdatePage", "XCase");
|
||||
},
|
||||
/**
|
||||
* Click in marker chart
|
||||
* @param {object} selection
|
||||
*/
|
||||
onClickCaseMarker(selection) {
|
||||
let process = this.data[1].id,
|
||||
caseList = this.data[0].id.toLowerCase();
|
||||
switch (caseList) {
|
||||
case "inbox":
|
||||
case "draft":
|
||||
this.openCase({
|
||||
APP_UID: selection["app_uid"],
|
||||
DEL_INDEX: selection["del_index"],
|
||||
PRO_UID: process,
|
||||
TAS_UID: selection["tas_uid"],
|
||||
});
|
||||
break;
|
||||
case "paused":
|
||||
this.showModalUnpauseCase({
|
||||
APP_UID: selection["app_uid"],
|
||||
DEL_INDEX: selection["del_index"],
|
||||
PRO_UID: process,
|
||||
TAS_UID: selection["tas_uid"],
|
||||
});
|
||||
break;
|
||||
case "unassigned":
|
||||
this.showModalClaimCase({
|
||||
APP_UID: selection["app_uid"],
|
||||
DEL_INDEX: selection["del_index"],
|
||||
PRO_UID: process,
|
||||
TAS_UID: selection["tas_uid"],
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Show modal unpause
|
||||
* @param {object} item
|
||||
*/
|
||||
showModalUnpauseCase(item) {
|
||||
this.$refs["modal-unpause-case"].data = item;
|
||||
this.$refs["modal-unpause-case"].show();
|
||||
},
|
||||
/**
|
||||
* Claim case
|
||||
* @param {object} item
|
||||
*/
|
||||
showModalClaimCase(item) {
|
||||
let that = this;
|
||||
api.cases.open(_.extend({ ACTION: "unassigned" }, item)).then(() => {
|
||||
api.cases.cases_open(_.extend({ ACTION: "todo" }, item)).then(() => {
|
||||
that.$refs["modal-claim-case"].data = item;
|
||||
that.$refs["modal-claim-case"].show();
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.vp-task-metrics-label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vp-width-p30 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.vp-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vp-padding-l20 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.vp-width-p100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.vp-text-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.vp-btn-success {
|
||||
color: #fff;
|
||||
background-color: #368b48;
|
||||
border-color: #368b48;
|
||||
}
|
||||
.vp-btn-success:hover {
|
||||
color: #fff;
|
||||
background-color: #255a30;
|
||||
border-color: #368b48;
|
||||
}
|
||||
|
||||
.vp-btn-warning {
|
||||
color: #fff;
|
||||
background-color: #c99e11;
|
||||
border-color: #a1831d;
|
||||
}
|
||||
.vp-btn-warning:hover {
|
||||
color: #fff;
|
||||
background-color: #886c0e;
|
||||
border-color: #a1831d;
|
||||
}
|
||||
.vp-btn-danger {
|
||||
color: #fff;
|
||||
background-color: #b63b32;
|
||||
border-color: #b63b32;
|
||||
}
|
||||
|
||||
.vp-btn-danger:hover {
|
||||
color: #fff;
|
||||
background-color: #832923;
|
||||
border-color: #b63b32;
|
||||
}
|
||||
|
||||
.vp-form-label {
|
||||
display: inline-block;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
text-anchor: start;
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
fill: rgb(15 17 18);
|
||||
margin-top: 0.5rem;
|
||||
color: #7d7f93;
|
||||
}
|
||||
</style>
|
||||
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
||||
219
resources/assets/js/home/TaskMetrics/VueChartLvTwo.vue
Normal file
219
resources/assets/js/home/TaskMetrics/VueChartLvTwo.vue
Normal file
@@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
|
||||
<div class="p-1 v-flex">
|
||||
<h6 class="v-search-title">{{$t("ID_DRILL_DOWN_NUMBER_TASKS_PROCESS_BY_TASK")}}</h6>
|
||||
<div>
|
||||
<BreadCrumb
|
||||
:options="breadCrumbs.data"
|
||||
:settings="settingsBreadcrumbs"
|
||||
/>
|
||||
<div class="vp-width-p30 vp-inline-block">
|
||||
<b-form-datepicker
|
||||
id="date-from"
|
||||
:date-format-options="{
|
||||
year: '2-digit',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}"
|
||||
size="sm"
|
||||
:placeholder="$t('ID_DELEGATE_DATE_FROM')"
|
||||
v-model="dateFrom"
|
||||
@input="changeOption"
|
||||
></b-form-datepicker>
|
||||
</div>
|
||||
<div class="vp-width-p30 vp-inline-block">
|
||||
<b-form-datepicker
|
||||
id="date-to"
|
||||
size="sm"
|
||||
:date-format-options="{
|
||||
year: '2-digit',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}"
|
||||
:placeholder="$t('ID_DELEGATE_DATE_TO')"
|
||||
v-model="dateTo"
|
||||
@input="changeOption"
|
||||
></b-form-datepicker>
|
||||
</div>
|
||||
<div class="vp-inline-block">
|
||||
<b-form-radio-group
|
||||
id="btn-radios"
|
||||
v-model="period"
|
||||
:options="periodOptions"
|
||||
button-variant="outline-secondary"
|
||||
size="sm"
|
||||
name="radio-btn-outline"
|
||||
buttons
|
||||
@change="changeOption"
|
||||
></b-form-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<apexchart
|
||||
ref="LevelTwoChart"
|
||||
:width="width"
|
||||
:options="options"
|
||||
:series="series"
|
||||
></apexchart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
import Api from "../../api/index";
|
||||
import Multiselect from "vue-multiselect";
|
||||
import BreadCrumb from "../../components/utils/BreadCrumb.vue";
|
||||
import moment from "moment";
|
||||
export default {
|
||||
name: "VueChartLvTwo",
|
||||
mixins: [],
|
||||
components: {
|
||||
Multiselect,
|
||||
BreadCrumb,
|
||||
},
|
||||
props: ["data", "breadCrumbs"],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
dateFrom: "",
|
||||
dateTo: "",
|
||||
period: "",
|
||||
periodOptions: [
|
||||
{ text: this.$t("ID_DAY"), value: "day" },
|
||||
{ text: this.$t("ID_MONTH"), value: "month" },
|
||||
{ text: this.$t("ID_YEAR"), value: "year" },
|
||||
],
|
||||
settingsBreadcrumbs: [
|
||||
{
|
||||
class: "fas fa-info-circle",
|
||||
tooltip: this.$t("ID_TASK_RISK_LEVEL2_INFO"),
|
||||
onClick() {},
|
||||
},
|
||||
],
|
||||
dataCasesByRange: [],
|
||||
width: 0,
|
||||
options: {
|
||||
chart: {
|
||||
type: "area",
|
||||
zoom: {
|
||||
enabled: false,
|
||||
},
|
||||
id: "LevelTwoChart",
|
||||
events: {
|
||||
markerClick: function (event, chartContext, config) {
|
||||
that.currentSelection = that.dataCasesByRange[config.seriesIndex];
|
||||
that.$emit("updateDataLevel", {
|
||||
id: that.currentSelection["PRO_ID"],
|
||||
name: that.currentSelection["PRO_TITLE"],
|
||||
level: 2,
|
||||
data: null,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
stroke: {
|
||||
curve: "smooth",
|
||||
},
|
||||
xaxis: {
|
||||
type: "datetime",
|
||||
},
|
||||
tooltip: {
|
||||
fixed: {
|
||||
enabled: false,
|
||||
position: "topRight",
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [],
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.getBodyHeight();
|
||||
},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Return the height for Vue Card View body
|
||||
*/
|
||||
getBodyHeight() {
|
||||
this.width = window.innerHeight;
|
||||
},
|
||||
/**
|
||||
* Change datepickers or radio button
|
||||
*/
|
||||
changeOption() {
|
||||
let that = this,
|
||||
dt;
|
||||
if (this.dateFrom && this.dateTo && this.period) {
|
||||
dt = {
|
||||
processId: this.data[1].id,
|
||||
caseList: this.data[0].id.toLowerCase(),
|
||||
dateFrom: moment(this.dateFrom).format("DD/MM/YYYY"),
|
||||
dateTo: moment(this.dateTo).format("DD/MM/YYYY"),
|
||||
groupBy: this.period,
|
||||
};
|
||||
Api.process
|
||||
.totalCasesByRange(dt)
|
||||
.then((response) => {
|
||||
that.formatDataRange(response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Format response from API
|
||||
* @param {object} data
|
||||
*/
|
||||
formatDataRange(data) {
|
||||
let labels = [],
|
||||
serie = [];
|
||||
|
||||
this.dataCasesByRange = data;
|
||||
_.each(data, (el) => {
|
||||
serie.push(el["TOTAL"]);
|
||||
labels.push(el["dateGroup"]);
|
||||
});
|
||||
this.$refs["LevelTwoChart"].updateOptions({
|
||||
labels: labels,
|
||||
title: {
|
||||
text: this.data[0]["PRO_TITLE"],
|
||||
align: "left",
|
||||
},
|
||||
});
|
||||
this.$apexcharts.exec("LevelTwoChart", "updateSeries", [
|
||||
{
|
||||
name: this.data[0]["PRO_TITLE"],
|
||||
data: serie,
|
||||
},
|
||||
]);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.vp-task-metrics-label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vp-width-p30 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.vp-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vp-padding-l20 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
</style>
|
||||
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
||||
248
resources/assets/js/home/TaskMetrics/VueChartLvZero.vue
Normal file
248
resources/assets/js/home/TaskMetrics/VueChartLvZero.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
|
||||
<div class="p-1 v-flex">
|
||||
<h6 class="v-search-title">{{$t("ID_DRILL_DOWN_NUMBER_TASKS")}}</h6>
|
||||
<BreadCrumb :options="breadCrumbs.data" :settings="settingsBreadcrumbs" />
|
||||
<apexchart
|
||||
v-show="typeView === 'donut'"
|
||||
ref="apexchart1"
|
||||
:width="width"
|
||||
:options="optionsDonut"
|
||||
:series="seriesDonut"
|
||||
></apexchart>
|
||||
<apexchart
|
||||
v-show="typeView === 'bar'"
|
||||
ref="apexchart2"
|
||||
:width="width"
|
||||
:options="optionsBar"
|
||||
:series="seriesBar"
|
||||
></apexchart>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm vp-align-right">
|
||||
<button
|
||||
@click="changeView('donut')"
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<i class="fas fa-chart-pie"></i
|
||||
><span class="vp-padding-l10">{{ $t("ID_VIEW") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<button
|
||||
@click="changeView('bar')"
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<i class="fas fa-chart-bar"></i
|
||||
><span class="vp-padding-l10">{{ $t("ID_VIEW") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
import Api from "../../api/index";
|
||||
import BreadCrumb from "./../../components/utils/BreadCrumb.vue";
|
||||
export default {
|
||||
name: "VueChartLvZero",
|
||||
mixins: [],
|
||||
components: { BreadCrumb },
|
||||
props: ["breadCrumbs"],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
typeView: "donut",
|
||||
width: 0,
|
||||
data: [],
|
||||
currentSelection: null,
|
||||
seriesDonut: [],
|
||||
settingsBreadcrumbs: [
|
||||
{
|
||||
class: "fas fa-info-circle",
|
||||
tooltip: this.$t("ID_TASK_RISK_LEVEL0_INFO"),
|
||||
onClick() {},
|
||||
},
|
||||
],
|
||||
optionsDonut: {
|
||||
labels: [
|
||||
this.$i18n.t("ID_INBOX"),
|
||||
this.$i18n.t("ID_DRAFT"),
|
||||
this.$i18n.t("ID_PAUSED"),
|
||||
this.$i18n.t("ID_UNASSIGNED"),
|
||||
],
|
||||
chart: {
|
||||
id: "apexchart1",
|
||||
type: "donut",
|
||||
events: {
|
||||
legendClick: function (chartContext, seriesIndex, config) {
|
||||
that.currentSelection = that.data[seriesIndex];
|
||||
that.$emit("updateDataLevel", {
|
||||
id: that.currentSelection["List Name"],
|
||||
name: that.currentSelection["List Name"],
|
||||
level: 0,
|
||||
data: that.currentSelection,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
position: "top",
|
||||
offsetY: 0,
|
||||
},
|
||||
},
|
||||
seriesBar: [
|
||||
{
|
||||
data: [400, 430, 448, 470],
|
||||
},
|
||||
],
|
||||
optionsBar: {
|
||||
chart: {
|
||||
type: "bar",
|
||||
id: "apexchart2",
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
events: {
|
||||
legendClick: function (chartContext, seriesIndex, config) {
|
||||
that.currentSelection = that.data[seriesIndex];
|
||||
that.$emit("updateDataLevel", {
|
||||
id: that.currentSelection["List Name"],
|
||||
name: that.currentSelection["List Name"],
|
||||
level: 0,
|
||||
data: that.currentSelection,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: "100%",
|
||||
distributed: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
position: "top",
|
||||
offsetY: 0,
|
||||
},
|
||||
colors: ["#33b2df", "#546E7A", "#d4526e", "#13d8aa"],
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
xaxis: {
|
||||
categories: [
|
||||
this.$i18n.t("ID_INBOX"),
|
||||
this.$i18n.t("ID_DRAFT"),
|
||||
this.$i18n.t("ID_PAUSED"),
|
||||
this.$i18n.t("ID_UNASSIGNED"),
|
||||
],
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
show: false,
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
formatter: function () {
|
||||
return "";
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.getBodyHeight();
|
||||
this.getData();
|
||||
},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Return the height for Vue Card View body
|
||||
*/
|
||||
getBodyHeight() {
|
||||
this.width = window.innerHeight * 0.8;
|
||||
},
|
||||
/**
|
||||
* Change view - donut/bar
|
||||
*/
|
||||
changeView(view) {
|
||||
this.typeView = view;
|
||||
this.getData();
|
||||
},
|
||||
/**
|
||||
* Get data from rest API
|
||||
*/
|
||||
getData() {
|
||||
let that = this;
|
||||
Api.cases
|
||||
.listTotalCases()
|
||||
.then((response) => {
|
||||
that.formatData(response.data);
|
||||
})
|
||||
.catch((response) => {});
|
||||
},
|
||||
/**
|
||||
* Format the data for chart
|
||||
*/
|
||||
formatData(data) {
|
||||
let l = [],
|
||||
c = [],
|
||||
s = [];
|
||||
_.each(data, (el) => {
|
||||
l.push(el["List Name"]);
|
||||
s.push(el["Total"]);
|
||||
if (el["Color"] == "green") {
|
||||
c.push("#179a6e");
|
||||
}
|
||||
if (el["Color"] == "yellow") {
|
||||
c.push("#feb019");
|
||||
}
|
||||
if (el["Color"] == "blue") {
|
||||
c.push("#008ffb");
|
||||
}
|
||||
if (el["Color"] == "gray") {
|
||||
c.push("#8f99a0");
|
||||
}
|
||||
});
|
||||
this.data = data;
|
||||
this.seriesDonut = s;
|
||||
this.seriesBar = [
|
||||
{
|
||||
data: s,
|
||||
},
|
||||
];
|
||||
this.$refs["apexchart1"].updateOptions({ labels: l, colors: c });
|
||||
this.$refs["apexchart2"].updateOptions({ labels: l, colors: c });
|
||||
this.$apexcharts.exec("apexchart1", "updateSeries", s);
|
||||
this.$apexcharts.exec("apexchart2", "updateSeries", [
|
||||
{
|
||||
data: s,
|
||||
},
|
||||
]);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.vp-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.vp-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.vp-padding-l10 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
</style>
|
||||
157
resources/assets/js/home/TaskMetrics/VueCharts.vue
Normal file
157
resources/assets/js/home/TaskMetrics/VueCharts.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
|
||||
<vue-chart-lv-zero
|
||||
v-show="level === 0"
|
||||
@updateDataLevel="updateDataLevel"
|
||||
:breadCrumbs="dataBreadCrumbs()"
|
||||
/>
|
||||
<vue-chart-lv-one
|
||||
:key="key1"
|
||||
v-show="level === 1"
|
||||
:data="data"
|
||||
@onChangeLevel="onChangeLevel"
|
||||
@updateDataLevel="updateDataLevel"
|
||||
:breadCrumbs="dataBreadCrumbs()"
|
||||
/>
|
||||
<vue-chart-lv-two
|
||||
:key="key2"
|
||||
v-show="level === 2"
|
||||
:data="data"
|
||||
@onChangeLevel="onChangeLevel"
|
||||
@updateDataLevel="updateDataLevel"
|
||||
:breadCrumbs="dataBreadCrumbs()"
|
||||
/>
|
||||
<vue-chart-lv-three
|
||||
:key="key3"
|
||||
v-show="level === 3"
|
||||
:data="data"
|
||||
@onChangeLevel="onChangeLevel"
|
||||
:breadCrumbs="dataBreadCrumbs()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueChartLvZero from "./VueChartLvZero.vue";
|
||||
import VueChartLvOne from "./VueChartLvOne.vue";
|
||||
import VueChartLvTwo from "./VueChartLvTwo.vue";
|
||||
import VueChartLvThree from "./VueChartLvThree.vue";
|
||||
|
||||
export default {
|
||||
name: "VueCharts",
|
||||
mixins: [],
|
||||
components: {
|
||||
VueChartLvZero,
|
||||
VueChartLvOne,
|
||||
VueChartLvTwo,
|
||||
VueChartLvThree,
|
||||
},
|
||||
props: [],
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
level: 0,
|
||||
key1: 1,
|
||||
key2: 1,
|
||||
key3: 1,
|
||||
data: [],
|
||||
settingsBreadCrumbs: [
|
||||
{
|
||||
class: "fas fa-info-circle",
|
||||
onClick() {},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
computed: {},
|
||||
updated() {},
|
||||
beforeCreate() {},
|
||||
methods: {
|
||||
/**
|
||||
* Set data level 0
|
||||
*/
|
||||
updateDataLevel(data) {
|
||||
this.data.push(data);
|
||||
this.level = data.level + 1;
|
||||
this.$emit("onChangeLevel", data.level + 1);
|
||||
this.updateKey();
|
||||
},
|
||||
updateKey() {
|
||||
switch (this.level) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
this.key1++;
|
||||
break;
|
||||
case 2:
|
||||
this.key2++;
|
||||
break;
|
||||
case 3:
|
||||
this.key3++;
|
||||
break;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Format data to vue charts any level
|
||||
*/
|
||||
formatData() {
|
||||
return {
|
||||
level: this.level,
|
||||
data: this.data,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Change level with changes in data
|
||||
* @param {object} lv
|
||||
*/
|
||||
onChangeLevel(lv) {
|
||||
_.remove(this.data, function (n) {
|
||||
return n.level >= lv;
|
||||
});
|
||||
this.level = lv;
|
||||
this.$emit("onChangeLevel", this.level);
|
||||
},
|
||||
/**
|
||||
* Format data for data beadcrumbs
|
||||
*/
|
||||
dataBreadCrumbs() {
|
||||
let res = [],
|
||||
that = this,
|
||||
index = 0;
|
||||
_.each(this.data, (el) => {
|
||||
if (index <= that.level && el.data) {
|
||||
res.push({
|
||||
label: el.name,
|
||||
onClick() {
|
||||
that.onChangeLevel(el.level);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
res.push({
|
||||
label: this.$t("ID_SELECT"),
|
||||
onClick() {},
|
||||
});
|
||||
switch (this.level) {
|
||||
case 0:
|
||||
return {
|
||||
data: res,
|
||||
settings: this.settingsBreadCrumbs,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
return {
|
||||
data: res,
|
||||
settings: this.settingsBreadCrumbs,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
16
resources/assets/js/home/TaskMetrics/defaultMixins.js
Normal file
16
resources/assets/js/home/TaskMetrics/defaultMixins.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import _ from "lodash";
|
||||
import api from "../../api/index";
|
||||
export default {
|
||||
data() {
|
||||
let that = this;
|
||||
return {
|
||||
newCase: {
|
||||
title: this.$i18n.t("ID_NEW_CASE"),
|
||||
class: "btn-success",
|
||||
onClick: () => {
|
||||
this.$refs["newRequest"].show();
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,13 @@ import Sortable from 'sortablejs';
|
||||
import "@fortawesome/fontawesome-free/css/all.css";
|
||||
import 'bootstrap/dist/css/bootstrap-grid.css';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css';
|
||||
import VueApexCharts from 'vue-apexcharts'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
|
||||
import Home from "./Home";
|
||||
|
||||
Vue.use(VueApexCharts);
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(VueSidebarMenu);
|
||||
Vue.use(BootstrapVue);
|
||||
@@ -26,9 +30,12 @@ Vue.use(ServerTable, {}, false, 'bootstrap3', {
|
||||
});
|
||||
Vue.use(ClientTable, {}, false, 'bootstrap3', {});
|
||||
Vue.component('settings-popover', SettingsPopover);
|
||||
Vue.component('apexchart', VueApexCharts);
|
||||
|
||||
window.ProcessMaker = {
|
||||
apiClient: require('axios')
|
||||
};
|
||||
|
||||
window.ProcessMaker.pluginBase = "/sysworkflow/en/neoclassic/viena/index.php";
|
||||
window.ProcessMaker.apiClient.defaults.baseURL = '/sysworkflow/en/neoclassic/viena/index.php/api/';
|
||||
window.ProcessMaker.SYS_SYS = "workflow";
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
<script>
|
||||
import api from "./../../api/index";
|
||||
import eventBus from "../EventBus/eventBus";
|
||||
|
||||
export default {
|
||||
name: "ModalClaimCase",
|
||||
components: {},
|
||||
@@ -57,14 +59,15 @@ export default {
|
||||
api.cases.claim(this.data).then((response) => {
|
||||
if (response.status === 200) {
|
||||
that.$refs["modal-claim-case"].hide();
|
||||
that.$parent.$emit("onUpdateDataCase", {
|
||||
//TODO Trigger onUpdateDataCase
|
||||
eventBus.$emit("home-update-datacase", {
|
||||
APP_UID: this.data.APP_UID,
|
||||
DEL_INDEX: this.data.DEL_INDEX,
|
||||
PRO_UID: this.data.PRO_UID,
|
||||
TAS_UID: this.data.TAS_UID,
|
||||
ACTION: "todo",
|
||||
});
|
||||
that.$parent.$emit("onUpdatePage", "XCase");
|
||||
eventBus.$emit("home-update-page", "XCase");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -55,7 +55,9 @@ export default {
|
||||
api.cases.unpause(this.data).then((response) => {
|
||||
if (response.statusText == "OK") {
|
||||
that.$refs["modal-unpause-case"].hide();
|
||||
that.$parent.$refs["vueTable"].getData();
|
||||
if (that.$parent.$refs["vueTable"]) { // TODO this component should be return a event to parent to code in the parent
|
||||
that.$parent.$refs["vueTable"].getData();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -53054,3 +53054,69 @@ msgstr "Send email to participants"
|
||||
#: LABEL/ID_TRYING_CANCEL
|
||||
msgid "You are tying to cancel the current case. Please be aware this action cannot be undone"
|
||||
msgstr "You are tying to cancel the current case. Please be aware this action cannot be undone"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_TASK_RISK_LEVEL0_INFO
|
||||
#: LABEL/ID_TASK_RISK_LEVEL0_INFO
|
||||
msgid "Select a task status option to drill down by status for all processes. Then view can be changed as pie or bar chart."
|
||||
msgstr "Select a task status option to drill down by status for all processes. Then view can be changed as pie or bar chart."
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_TASK_RISK_LEVEL1_INFO
|
||||
#: LABEL/ID_TASK_RISK_LEVEL1_INFO
|
||||
msgid "Select the 'Drill' option of a Process in the Chart, to Drill Down By a Range of Dates listing the number of tasks By Task Status of the Process, or use the 'Data' option to open the Task List displaying all Tasks of the Process and Status"
|
||||
msgstr "Select the 'Drill' option of a Process in the Chart, to Drill Down By a Range of Dates listing the number of tasks By Task Status of the Process, or use the 'Data' option to open the Task List displaying all Tasks of the Process and Status"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_TASK_RISK_LEVEL2_INFO
|
||||
#: LABEL/ID_TASK_RISK_LEVEL2_INFO
|
||||
msgid "Select the Drill option to have a Risk Matrix of the tasks or select the Data option to open the Task Folder listing all Tasks of the Process status by a range of date"
|
||||
msgstr "Select the Drill option to have a Risk Matrix of the tasks or select the Data option to open the Task Folder listing all Tasks of the Process status by a range of date"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_TASK_RISK_LEVEL3_INFO
|
||||
#: LABEL/ID_TASK_RISK_LEVEL3_INFO
|
||||
msgid "By selecting the task will be open automatically if the task is Inbox or Draft"
|
||||
msgstr "By selecting the task will be open automatically if the task is Inbox or Draft"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_LEVEL
|
||||
#: LABEL/ID_LEVEL
|
||||
msgid "Level"
|
||||
msgstr "Level"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_DRILL_DOWN_NAVIGATOR
|
||||
#: LABEL/ID_DRILL_DOWN_NAVIGATOR
|
||||
msgid "Drill Down Navigator"
|
||||
msgstr "Drill Down Navigator"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_DRILL_DOWN_NUMBER_TASKS
|
||||
#: LABEL/ID_DRILL_DOWN_NUMBER_TASKS
|
||||
msgid "Number of tasks per Task Status"
|
||||
msgstr "Number of tasks per Task Status"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_DRILL_DOWN_NUMBER_TASKS_PROCESS
|
||||
#: LABEL/ID_DRILL_DOWN_NUMBER_TASKS_PROCESS
|
||||
msgid "Number of Tasks Status per Process"
|
||||
msgstr "Number of Tasks Status per Process"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_DRILL_DOWN_NUMBER_TASKS_PROCESS_BY_TASK
|
||||
#: LABEL/ID_DRILL_DOWN_NUMBER_TASKS_PROCESS_BY_TASK
|
||||
msgid "Number of Tasks Status per Process by task status"
|
||||
msgstr "Number of Tasks Status per Process by task status"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_DRILL_DOWN_RISK_MATRIX
|
||||
#: LABEL/ID_DRILL_DOWN_RISK_MATRIX
|
||||
msgid "Risk Matrix per Process by Task Status"
|
||||
msgstr "Risk Matrix per Process by Task Status"
|
||||
|
||||
# TRANSLATION
|
||||
# LABEL/ID_TOP
|
||||
#: LABEL/ID_TOP
|
||||
msgid "Top"
|
||||
msgstr "Top"
|
||||
@@ -57998,6 +57998,11 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
|
||||
( 'LABEL','ID_DOWN_TRIGGER','en','Down Trigger','2015-02-20') ,
|
||||
( 'LABEL','ID_DRAFT','en','Draft','2014-01-15') ,
|
||||
( 'LABEL','ID_DRIVE_HELP_ENABLE','en','When this option is enabled, all input, output and attached documents generated in your processes can be stored in Google Drive.','2016-01-05') ,
|
||||
( 'LABEL','ID_DRILL_DOWN_NAVIGATOR','en','Drill Down Navigator','2020-08-26') ,
|
||||
( 'LABEL','ID_DRILL_DOWN_NUMBER_TASKS','en','Number of tasks per Task Status','2020-08-26') ,
|
||||
( 'LABEL','ID_DRILL_DOWN_NUMBER_TASKS_PROCESS','en','Number of Tasks Status per Process','2020-08-26') ,
|
||||
( 'LABEL','ID_DRILL_DOWN_NUMBER_TASKS_PROCESS_BY_TASK','en','Number of Tasks Status per Process by task status','2020-08-26') ,
|
||||
( 'LABEL','ID_DRILL_DOWN_RISK_MATRIX','en','Risk Matrix per Process by Task Status','2020-08-26') ,
|
||||
( 'LABEL','ID_DROP_DATABASE_EXISTS','en','Drop database if exists','2014-01-15') ,
|
||||
( 'LABEL','ID_DROP_FILE_HERE','en','Drop file here...','2020-12-10') ,
|
||||
( 'LABEL','ID_DUE_DATE','en','Due Date','2014-01-15') ,
|
||||
@@ -58735,6 +58740,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
|
||||
( 'LABEL','ID_LEFT','en','left','2014-09-18') ,
|
||||
( 'LABEL','ID_LEFT_MARGIN','en','Left Margin','2014-01-15') ,
|
||||
( 'LABEL','ID_LESS_THAN','en','less than','2015-03-23') ,
|
||||
( 'LABEL','ID_LEVEL','en','Level','2021-08-26') ,
|
||||
( 'LABEL','ID_LIBRARY_DOES_NOT_EXIST','en','The library with {0}: "{1}" does not exist.','2014-05-20') ,
|
||||
( 'LABEL','ID_LIBRARY_FUNCTION_DOES_NOT_EXIST','en','The function with {0}: "{1}" does not exist in the library.','2014-05-20') ,
|
||||
( 'LABEL','ID_LICENCE_LOGIN_TITLE','en','License','2015-12-07') ,
|
||||
@@ -61316,6 +61322,10 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
|
||||
( 'LABEL','ID_TAS_EDIT','en','Tasks (Edit mode)','2014-01-15') ,
|
||||
( 'LABEL','ID_TAS_UID_PARAMETER_IS_EMPTY','en','The TAS_UID parameter is empty.','2016-04-08') ,
|
||||
( 'LABEL','ID_TAS_VIEW','en','Tasks (View mode)','2014-01-15') ,
|
||||
( 'LABEL','ID_TASK_RISK_LEVEL0_INFO','en','Select a task status option to drill down by status for all processes. Then view can be changed as pie or bar chart.','2020-08-26') ,
|
||||
( 'LABEL','ID_TASK_RISK_LEVEL1_INFO','en','Select the "Drill" option of a Process in the Chart, to Drill Down By a Range of Dates listing the number of tasks By Task Status of the Process, or use the "Data" option to open the Task List displaying all Tasks of the Process and Status','2020-08-26'),
|
||||
( 'LABEL','ID_TASK_RISK_LEVEL2_INFO','en','Select the Drill option to have a Risk Matrix of the tasks or select the Data option to open the Task Folder listing all Tasks of the Process status by a range of date','2020-08-26') ,
|
||||
( 'LABEL','ID_TASK_RISK_LEVEL3_INFO','en','By selecting the task will be open automatically if the task is Inbox or Draft','2020-08-26') ,
|
||||
( 'LABEL','ID_TEMPLATES','en','Templates','2014-01-15') ,
|
||||
( 'LABEL','ID_TEMPLATE_FILE_NOT_EXIST','en','Template file ''{FILE_TEMPLATE}'' does not exist.','2014-01-15') ,
|
||||
( 'LABEL','ID_TEMPLATE_PARAMETER_EMPTY','en','The TEMPLATE parameter is empty.','2016-04-08') ,
|
||||
@@ -61413,6 +61423,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
|
||||
( 'LABEL','ID_TOOLS','en','Tools','2014-01-15') ,
|
||||
( 'LABEL','ID_TOO_MANY_REQUESTS','en','Upon configurations, you have reached the maximum number of files to upload.','2018-12-17') ,
|
||||
( 'LABEL','ID_TOP_MARGIN','en','Top Margin','2014-01-15') ,
|
||||
( 'LABEL','ID_TOP','en','Top','2020-08-27') ,
|
||||
( 'LABEL','ID_TOTAL_CASES','en','Total Cases','2014-01-15') ,
|
||||
( 'LABEL','ID_TOTAL_CASES_REASSIGNED','en','Total Cases Reassigned','2014-01-15') ,
|
||||
( 'LABEL','ID_TO_DO','en','To do','2014-01-15') ,
|
||||
|
||||
Reference in New Issue
Block a user