This commit is contained in:
2022-02-26 01:00:45 +00:00
parent 58a636e24c
commit 64d43d8706
5 changed files with 104 additions and 114 deletions

View File

@@ -3,7 +3,6 @@ const role = authorizationroles.AUTHORIZATION_ROLES;
export default { export default {
registry: [ registry: [
{ {
id: "dash-today-reminders",
roles: [ roles: [
role.BizAdmin, role.BizAdmin,
role.BizAdminRestricted, role.BizAdminRestricted,
@@ -25,7 +24,6 @@ export default {
settings: {} settings: {}
}, },
{ {
id: "dash-today-reviews",
roles: [ roles: [
role.BizAdmin, role.BizAdmin,
role.BizAdminRestricted, role.BizAdminRestricted,
@@ -47,7 +45,6 @@ export default {
settings: {} settings: {}
}, },
{ {
id: "dash-today-scheduled-wo",
roles: [role.Tech, role.TechRestricted], roles: [role.Tech, role.TechRestricted],
title: "DashboardScheduled", title: "DashboardScheduled",
type: "GzDashTodayScheduledWo", type: "GzDashTodayScheduledWo",
@@ -56,35 +53,32 @@ export default {
settings: {} settings: {}
}, },
{ {
id: "dash-labor-hours-personal",
roles: [role.Tech, role.TechRestricted], roles: [role.Tech, role.TechRestricted],
title: "Labor hours", title: "WorkOrderItemLaborList",
type: "GzDashLaborHoursPersonal", type: "GzDashLaborHoursPersonal",
scheduleableUserOnly: true, scheduleableUserOnly: true,
singleOnly: false, singleOnly: false,
settings: { settings: {
customTitle: null, customTitle: null,
dateRange: "*thismonth*", timeSpan: "*thismonth*",
unit: "day", interval: "day",
color: "#000000" color: "#00205B"
} }
}, },
{ {
id: "dash-labor-hours-personal-bar",
roles: [role.Tech, role.TechRestricted], roles: [role.Tech, role.TechRestricted],
title: "Labor hours - bar", title: "WorkOrderItemLaborList",
type: "GzDashLaborHoursPersonalBar", type: "GzDashLaborHoursPersonalBar",
scheduleableUserOnly: true, scheduleableUserOnly: true,
singleOnly: false, singleOnly: false,
settings: { settings: {
customTitle: null, customTitle: null,
dateRange: "*thismonth*", timeSpan: "*thismonth*",
unit: "day", interval: "day",
color: "#000000" color: "#00205B"
} }
}, },
{ {
id: "TestBarWidgetCountByUserType",
roles: [ roles: [
role.BizAdmin, role.BizAdmin,
role.BizAdminRestricted, role.BizAdminRestricted,
@@ -98,7 +92,6 @@ export default {
settings: { customTitle: "my custom title" } settings: { customTitle: "my custom title" }
}, },
{ {
id: "TestLineWidgetMonthlyTotalPrice",
roles: [ roles: [
role.BizAdmin, role.BizAdmin,
role.BizAdminRestricted, role.BizAdminRestricted,
@@ -126,7 +119,7 @@ export default {
continue; continue;
} }
ret.push({ ret.push({
id: item.id, id: i,
title: item.title, title: item.title,
type: item.type, type: item.type,
singleOnly: item.singleOnly, singleOnly: item.singleOnly,

View File

@@ -168,7 +168,7 @@
export default { export default {
props: { props: {
id: { id: {
type: String, type: Number,
required: true required: true
}, },
title: { type: String, default: null }, title: { type: String, default: null },

View File

@@ -2,7 +2,7 @@
<gz-dash <gz-dash
icon="$ayiUser" icon="$ayiUser"
:show-context-button="true" :show-context-button="true"
:update-frequency="600000" :update-frequency="900000"
v-bind="[$props, $attrs]" v-bind="[$props, $attrs]"
@dash-refresh="getDataFromApi()" @dash-refresh="getDataFromApi()"
@dash-context="showContext()" @dash-context="showContext()"
@@ -10,17 +10,6 @@
> >
<template slot="main"> <template slot="main">
<div> <div>
<!-- <gz-chart-line
:width="400"
:height="240"
:chart-data="obj"
:options="{
responsive: true,
maintainAspectRatio: false,
legend: { display: false }
}"
></gz-chart-line> -->
<gz-chart-bar <gz-chart-bar
:width="400" :width="400"
:height="330" :height="330"
@@ -46,21 +35,20 @@
</v-card-title> </v-card-title>
<v-card-text style="height: 500px;"> <v-card-text style="height: 500px;">
{{ settings }}
<v-select <v-select
v-model="localSettings.dateRange" v-model="localSettings.timeSpan"
:items="selectLists.dateFilterTokens" :items="selectLists.dateFilterTokens"
item-text="name" item-text="name"
item-value="id" item-value="id"
:label="$ay.t('TimeSpanDateRange')" :label="$ay.t('TimeSpan')"
></v-select> ></v-select>
<v-select <v-select
v-model="localSettings.unit" v-model="localSettings.interval"
:items="selectLists.units" :items="selectLists.units"
item-text="name" item-text="name"
item-value="id" item-value="id"
:label="$ay.t('Unit')" :label="$ay.t('Interval')"
></v-select> ></v-select>
<v-text-field <v-text-field
@@ -98,7 +86,6 @@
</template> </template>
<script> <script>
import GzDash from "./dash-base.vue"; import GzDash from "./dash-base.vue";
//import Palette from "../api/palette";
export default { export default {
components: { components: {
GzDash GzDash
@@ -125,7 +112,7 @@ export default {
{ {
type: "time", type: "time",
time: { time: {
unit: this.settings.unit unit: "day"
}, },
gridLines: { gridLines: {
drawOnChartArea: false drawOnChartArea: false
@@ -175,71 +162,22 @@ export default {
updateSettings: function() { updateSettings: function() {
//copy settings from local to //copy settings from local to
this.settings.customTitle = this.localSettings.customTitle; this.settings.customTitle = this.localSettings.customTitle;
this.settings.dateRange = this.localSettings.dateRange; this.settings.timeSpan = this.localSettings.timeSpan;
this.settings.unit = this.localSettings.unit; this.settings.interval = this.localSettings.interval;
this.settings.color = this.localSettings.color; this.settings.color = this.localSettings.color;
this.$emit("dash-change"); this.$emit("dash-change"); //trigger save to server
this.context = false; this.context = false;
this.getDataFromApi(); this.getDataFromApi();
}, },
async getDataFromApi() { async getDataFromApi() {
//todo: need a equivalent of a datalist at the server but that can take the minimal criteria offered here and return the data easily digestable
//do not want the client end to have to do math or anything and also it needs to drive reporting of the same type as the widget display
//so as similar as possible to the datatable system but handles the math and summarizing ideally in the db server itself
/*
TODO:
DYNAMIC FROM SETS
handle params (time range, currentusertoken,period)
enforce current user only (I guess that's built in if use token or leave out token because it's assumed in which case rename to WorkOrderItemLaborQuantitySummaryPERSONAL )
ACTUAL CHART WORKING
line chart, can it work with this data, does it need adjustment to locale?
scroll? Vertical better than horizontal? Select bar OR line?
REPORTING
v.nexxt?
charts lib at server?
DateTrunc https://www.postgresqltutorial.com/postgresql-date_trunc/ will respect changes of month or year or whatever so this works
SELECT row_to_json(t) as res from (
select SUM(AWORKORDERITEMLABOR.serviceratequantity) SERVICERATESUM, date_trunc('month',AWORKORDERITEMLABOR.servicestartdate) timeframe
FROM AWORKORDER
LEFT JOIN AWORKORDERITEM ON AWORKORDER.ID = AWORKORDERITEM.WORKORDERID
LEFT JOIN AWORKORDERITEMLABOR ON AWORKORDERITEM.ID = AWORKORDERITEMLABOR.WORKORDERITEMID
WHERE AWORKORDERITEMLABOR.userid = 10
GROUP BY timeframe
ORDER BY timeframe ASC
) t
*/
// let tt = {
// KPIName: "WorkOrderItemLaborQuantitySummary",
// criteria: {
// dateRange: this.settings.dateRange,
// unit: this.settings.unit
// },
// clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
// };
// console.log(tt);
try { try {
this.errorMessage = null; this.errorMessage = null;
const res = await window.$gz.api.post("kpi", { const res = await window.$gz.api.post("kpi", {
KPIName: "WorkOrderItemLaborQuantitySummary", KPIName: "WorkOrderItemLaborQuantitySummary",
criteria: { criteria: {
dateRange: this.settings.dateRange, timeSpan: this.settings.timeSpan,
unit: this.settings.unit interval: this.settings.interval
}, },
clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp() clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
}); });
@@ -247,6 +185,8 @@ ORDER BY timeframe ASC
this.errorMessage = res.error; this.errorMessage = res.error;
} else { } else {
// console.log(res); // console.log(res);
this.chartOptions.scales.xAxes[0].time.unit = this.settings.interval;
//console.log(this.chartOptions);
this.obj = res.data; this.obj = res.data;
} }
} catch (error) { } catch (error) {
@@ -315,7 +255,10 @@ async function fetchTranslatedText() {
"DateRangePreviousYearNextMonth", "DateRangePreviousYearNextMonth",
"TimeSpanDays", "TimeSpanDays",
"TimeSpanMonths", "TimeSpanMonths",
"WorkOrderItemLaborServiceRateQuantity" "WorkOrderItemLaborServiceRateQuantity",
"Name",
"TimeSpan",
"Interval"
]); ]);
} }
@@ -401,8 +344,48 @@ function populateSelectionLists(vm) {
] ]
); );
} }
/*
var crit=(string)options.Criteria["dateRange"];
*/ /* //todo: need a equivalent of a datalist at the server but that can take the minimal criteria offered here and return the data easily digestable
//do not want the client end to have to do math or anything and also it needs to drive reporting of the same type as the widget display
//so as similar as possible to the datatable system but handles the math and summarizing ideally in the db server itself
TODO:
DYNAMIC FROM SETS
handle params (time range, currentusertoken,period)
enforce current user only (I guess that's built in if use token or leave out token because it's assumed in which case rename to WorkOrderItemLaborQuantitySummaryPERSONAL )
ACTUAL CHART WORKING
line chart, can it work with this data, does it need adjustment to locale?
scroll? Vertical better than horizontal? Select bar OR line?
REPORTING
v.nexxt?
charts lib at server?
DateTrunc https://www.postgresqltutorial.com/postgresql-date_trunc/ will respect changes of month or year or whatever so this works
SELECT row_to_json(t) as res from (
select SUM(AWORKORDERITEMLABOR.serviceratequantity) SERVICERATESUM, date_trunc('month',AWORKORDERITEMLABOR.servicestartdate) timeframe
FROM AWORKORDER
LEFT JOIN AWORKORDERITEM ON AWORKORDER.ID = AWORKORDERITEM.WORKORDERID
LEFT JOIN AWORKORDERITEMLABOR ON AWORKORDERITEM.ID = AWORKORDERITEMLABOR.WORKORDERITEMID
WHERE AWORKORDERITEMLABOR.userid = 10
GROUP BY timeframe
ORDER BY timeframe ASC
) t
// let tt = {
// KPIName: "WorkOrderItemLaborQuantitySummary",
// criteria: {
// timeSpan: this.settings.timeSpan,
// unit: this.settings.unit
// },
// clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
// };
// console.log(tt); */
</script> </script>

View File

@@ -49,7 +49,7 @@
<v-card-text style="height: 500px;"> <v-card-text style="height: 500px;">
{{ settings }} {{ settings }}
<v-select <v-select
v-model="localSettings.dateRange" v-model="localSettings.timeSpan"
:items="selectLists.dateFilterTokens" :items="selectLists.dateFilterTokens"
item-text="name" item-text="name"
item-value="id" item-value="id"
@@ -57,7 +57,7 @@
></v-select> ></v-select>
<v-select <v-select
v-model="localSettings.unit" v-model="localSettings.interval"
:items="selectLists.units" :items="selectLists.units"
item-text="name" item-text="name"
item-value="id" item-value="id"
@@ -126,7 +126,7 @@ export default {
{ {
type: "time", type: "time",
time: { time: {
unit: this.settings.unit unit: this.settings.interval
}, },
gridLines: { gridLines: {
drawOnChartArea: false drawOnChartArea: false
@@ -181,8 +181,8 @@ export default {
updateSettings: function() { updateSettings: function() {
//copy settings from local to //copy settings from local to
this.settings.customTitle = this.localSettings.customTitle; this.settings.customTitle = this.localSettings.customTitle;
this.settings.dateRange = this.localSettings.dateRange; this.settings.timeSpan = this.localSettings.timeSpan;
this.settings.unit = this.localSettings.unit; this.settings.interval = this.localSettings.interval;
this.settings.color = this.localSettings.color; this.settings.color = this.localSettings.color;
this.$emit("dash-change"); this.$emit("dash-change");
@@ -235,8 +235,8 @@ ORDER BY timeframe ASC
// let tt = { // let tt = {
// KPIName: "WorkOrderItemLaborQuantitySummary", // KPIName: "WorkOrderItemLaborQuantitySummary",
// criteria: { // criteria: {
// dateRange: this.settings.dateRange, // timeSpan: this.settings.timeSpan,
// unit: this.settings.unit // interval: this.settings.interval
// }, // },
// clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp() // clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
// }; // };
@@ -247,8 +247,8 @@ ORDER BY timeframe ASC
const res = await window.$gz.api.post("kpi", { const res = await window.$gz.api.post("kpi", {
KPIName: "WorkOrderItemLaborQuantitySummary", KPIName: "WorkOrderItemLaborQuantitySummary",
criteria: { criteria: {
dateRange: this.settings.dateRange, timeSpan: this.settings.timeSpan,
unit: this.settings.unit interval: this.settings.interval
}, },
clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp() clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
}); });
@@ -411,7 +411,7 @@ function populateSelectionLists(vm) {
); );
} }
/* /*
var crit=(string)options.Criteria["dateRange"]; var crit=(string)options.Criteria["timeSpan"];
*/ */
</script> </script>

View File

@@ -44,8 +44,8 @@
</v-row> </v-row>
<v-row> <v-row>
<v-col <v-col
v-for="(item, i) in effectiveView" v-for="item in effectiveView"
:key="i" :key="item.id"
class="d-flex child-flex" class="d-flex child-flex"
cols="12" cols="12"
sm="6" sm="6"
@@ -54,7 +54,6 @@
> >
<component <component
:is="item.type" :is="item.type"
:ref="item.ref"
v-bind="item" v-bind="item"
:max-list-items="10" :max-list-items="10"
@dash-remove="dashRemove" @dash-remove="dashRemove"
@@ -214,16 +213,31 @@ export default {
}, },
addItem: function(item) { addItem: function(item) {
this.showSelector = false; this.showSelector = false;
item.ref = "db" + Date.now(); const newItem = JSON.parse(JSON.stringify(item));
this.effectiveView.push(item); newItem.id = Date.now();
this.effectiveView.push(newItem);
this.saveView(); this.saveView();
}, },
availableItems: function() { availableItems: function() {
const allItems = DashRegistry.availableItems(); const allItems = DashRegistry.availableItems();
const newItems = allItems.filter( // console.log("availableItems:allItems", JSON.stringify(allItems));
z => !this.effectiveView.find(m => m.id == z.id && z.singleOnly) // console.log(
); // "availableItems:effectiveView",
return newItems; // JSON.stringify(this.effectiveView)
// );
const ret = [];
allItems.forEach(z => {
if (!z.singleOnly) {
ret.push(z);
} else {
if (this.effectiveView.findIndex(m => m.type == z.type) == -1) {
ret.push(z);
}
}
});
// console.log("availableItems:ret", JSON.stringify(ret));
return ret;
}, },
async getDataFromApi() { async getDataFromApi() {
const vm = this; const vm = this;
@@ -246,7 +260,7 @@ export default {
const availableItems = DashRegistry.availableItems(); const availableItems = DashRegistry.availableItems();
//filter out any that are deprecated or no longer accessible due to role change //filter out any that are deprecated or no longer accessible due to role change
const allowedView = savedView.filter(z => const allowedView = savedView.filter(z =>
availableItems.find(m => m.id == z.id) availableItems.find(m => m.type == z.type)
); );
vm.effectiveView = allowedView; vm.effectiveView = allowedView;
generateMenu(vm); generateMenu(vm);