This commit is contained in:
@@ -3,7 +3,6 @@ const role = authorizationroles.AUTHORIZATION_ROLES;
|
||||
export default {
|
||||
registry: [
|
||||
{
|
||||
id: "dash-today-reminders",
|
||||
roles: [
|
||||
role.BizAdmin,
|
||||
role.BizAdminRestricted,
|
||||
@@ -25,7 +24,6 @@ export default {
|
||||
settings: {}
|
||||
},
|
||||
{
|
||||
id: "dash-today-reviews",
|
||||
roles: [
|
||||
role.BizAdmin,
|
||||
role.BizAdminRestricted,
|
||||
@@ -47,7 +45,6 @@ export default {
|
||||
settings: {}
|
||||
},
|
||||
{
|
||||
id: "dash-today-scheduled-wo",
|
||||
roles: [role.Tech, role.TechRestricted],
|
||||
title: "DashboardScheduled",
|
||||
type: "GzDashTodayScheduledWo",
|
||||
@@ -56,35 +53,32 @@ export default {
|
||||
settings: {}
|
||||
},
|
||||
{
|
||||
id: "dash-labor-hours-personal",
|
||||
roles: [role.Tech, role.TechRestricted],
|
||||
title: "Labor hours",
|
||||
title: "WorkOrderItemLaborList",
|
||||
type: "GzDashLaborHoursPersonal",
|
||||
scheduleableUserOnly: true,
|
||||
singleOnly: false,
|
||||
settings: {
|
||||
customTitle: null,
|
||||
dateRange: "*thismonth*",
|
||||
unit: "day",
|
||||
color: "#000000"
|
||||
timeSpan: "*thismonth*",
|
||||
interval: "day",
|
||||
color: "#00205B"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "dash-labor-hours-personal-bar",
|
||||
roles: [role.Tech, role.TechRestricted],
|
||||
title: "Labor hours - bar",
|
||||
title: "WorkOrderItemLaborList",
|
||||
type: "GzDashLaborHoursPersonalBar",
|
||||
scheduleableUserOnly: true,
|
||||
singleOnly: false,
|
||||
settings: {
|
||||
customTitle: null,
|
||||
dateRange: "*thismonth*",
|
||||
unit: "day",
|
||||
color: "#000000"
|
||||
timeSpan: "*thismonth*",
|
||||
interval: "day",
|
||||
color: "#00205B"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "TestBarWidgetCountByUserType",
|
||||
roles: [
|
||||
role.BizAdmin,
|
||||
role.BizAdminRestricted,
|
||||
@@ -98,7 +92,6 @@ export default {
|
||||
settings: { customTitle: "my custom title" }
|
||||
},
|
||||
{
|
||||
id: "TestLineWidgetMonthlyTotalPrice",
|
||||
roles: [
|
||||
role.BizAdmin,
|
||||
role.BizAdminRestricted,
|
||||
@@ -126,7 +119,7 @@ export default {
|
||||
continue;
|
||||
}
|
||||
ret.push({
|
||||
id: item.id,
|
||||
id: i,
|
||||
title: item.title,
|
||||
type: item.type,
|
||||
singleOnly: item.singleOnly,
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
export default {
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
title: { type: String, default: null },
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<gz-dash
|
||||
icon="$ayiUser"
|
||||
:show-context-button="true"
|
||||
:update-frequency="600000"
|
||||
:update-frequency="900000"
|
||||
v-bind="[$props, $attrs]"
|
||||
@dash-refresh="getDataFromApi()"
|
||||
@dash-context="showContext()"
|
||||
@@ -10,17 +10,6 @@
|
||||
>
|
||||
<template slot="main">
|
||||
<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
|
||||
:width="400"
|
||||
:height="330"
|
||||
@@ -46,21 +35,20 @@
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text style="height: 500px;">
|
||||
{{ settings }}
|
||||
<v-select
|
||||
v-model="localSettings.dateRange"
|
||||
v-model="localSettings.timeSpan"
|
||||
:items="selectLists.dateFilterTokens"
|
||||
item-text="name"
|
||||
item-value="id"
|
||||
:label="$ay.t('TimeSpanDateRange')"
|
||||
:label="$ay.t('TimeSpan')"
|
||||
></v-select>
|
||||
|
||||
<v-select
|
||||
v-model="localSettings.unit"
|
||||
v-model="localSettings.interval"
|
||||
:items="selectLists.units"
|
||||
item-text="name"
|
||||
item-value="id"
|
||||
:label="$ay.t('Unit')"
|
||||
:label="$ay.t('Interval')"
|
||||
></v-select>
|
||||
|
||||
<v-text-field
|
||||
@@ -98,7 +86,6 @@
|
||||
</template>
|
||||
<script>
|
||||
import GzDash from "./dash-base.vue";
|
||||
//import Palette from "../api/palette";
|
||||
export default {
|
||||
components: {
|
||||
GzDash
|
||||
@@ -125,7 +112,7 @@ export default {
|
||||
{
|
||||
type: "time",
|
||||
time: {
|
||||
unit: this.settings.unit
|
||||
unit: "day"
|
||||
},
|
||||
gridLines: {
|
||||
drawOnChartArea: false
|
||||
@@ -175,71 +162,22 @@ export default {
|
||||
updateSettings: function() {
|
||||
//copy settings from local to
|
||||
this.settings.customTitle = this.localSettings.customTitle;
|
||||
this.settings.dateRange = this.localSettings.dateRange;
|
||||
this.settings.unit = this.localSettings.unit;
|
||||
this.settings.timeSpan = this.localSettings.timeSpan;
|
||||
this.settings.interval = this.localSettings.interval;
|
||||
this.settings.color = this.localSettings.color;
|
||||
this.$emit("dash-change");
|
||||
this.$emit("dash-change"); //trigger save to server
|
||||
this.context = false;
|
||||
this.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 {
|
||||
this.errorMessage = null;
|
||||
const res = await window.$gz.api.post("kpi", {
|
||||
KPIName: "WorkOrderItemLaborQuantitySummary",
|
||||
criteria: {
|
||||
dateRange: this.settings.dateRange,
|
||||
unit: this.settings.unit
|
||||
timeSpan: this.settings.timeSpan,
|
||||
interval: this.settings.interval
|
||||
},
|
||||
clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
|
||||
});
|
||||
@@ -247,6 +185,8 @@ ORDER BY timeframe ASC
|
||||
this.errorMessage = res.error;
|
||||
} else {
|
||||
// console.log(res);
|
||||
this.chartOptions.scales.xAxes[0].time.unit = this.settings.interval;
|
||||
//console.log(this.chartOptions);
|
||||
this.obj = res.data;
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -315,7 +255,10 @@ async function fetchTranslatedText() {
|
||||
"DateRangePreviousYearNextMonth",
|
||||
"TimeSpanDays",
|
||||
"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>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<v-card-text style="height: 500px;">
|
||||
{{ settings }}
|
||||
<v-select
|
||||
v-model="localSettings.dateRange"
|
||||
v-model="localSettings.timeSpan"
|
||||
:items="selectLists.dateFilterTokens"
|
||||
item-text="name"
|
||||
item-value="id"
|
||||
@@ -57,7 +57,7 @@
|
||||
></v-select>
|
||||
|
||||
<v-select
|
||||
v-model="localSettings.unit"
|
||||
v-model="localSettings.interval"
|
||||
:items="selectLists.units"
|
||||
item-text="name"
|
||||
item-value="id"
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
{
|
||||
type: "time",
|
||||
time: {
|
||||
unit: this.settings.unit
|
||||
unit: this.settings.interval
|
||||
},
|
||||
gridLines: {
|
||||
drawOnChartArea: false
|
||||
@@ -181,8 +181,8 @@ export default {
|
||||
updateSettings: function() {
|
||||
//copy settings from local to
|
||||
this.settings.customTitle = this.localSettings.customTitle;
|
||||
this.settings.dateRange = this.localSettings.dateRange;
|
||||
this.settings.unit = this.localSettings.unit;
|
||||
this.settings.timeSpan = this.localSettings.timeSpan;
|
||||
this.settings.interval = this.localSettings.interval;
|
||||
this.settings.color = this.localSettings.color;
|
||||
|
||||
this.$emit("dash-change");
|
||||
@@ -235,8 +235,8 @@ ORDER BY timeframe ASC
|
||||
// let tt = {
|
||||
// KPIName: "WorkOrderItemLaborQuantitySummary",
|
||||
// criteria: {
|
||||
// dateRange: this.settings.dateRange,
|
||||
// unit: this.settings.unit
|
||||
// timeSpan: this.settings.timeSpan,
|
||||
// interval: this.settings.interval
|
||||
// },
|
||||
// clientTimeStamp: window.$gz.locale.clientLocalZoneTimeStamp()
|
||||
// };
|
||||
@@ -247,8 +247,8 @@ ORDER BY timeframe ASC
|
||||
const res = await window.$gz.api.post("kpi", {
|
||||
KPIName: "WorkOrderItemLaborQuantitySummary",
|
||||
criteria: {
|
||||
dateRange: this.settings.dateRange,
|
||||
unit: this.settings.unit
|
||||
timeSpan: this.settings.timeSpan,
|
||||
interval: this.settings.interval
|
||||
},
|
||||
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>
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="(item, i) in effectiveView"
|
||||
:key="i"
|
||||
v-for="item in effectiveView"
|
||||
:key="item.id"
|
||||
class="d-flex child-flex"
|
||||
cols="12"
|
||||
sm="6"
|
||||
@@ -54,7 +54,6 @@
|
||||
>
|
||||
<component
|
||||
:is="item.type"
|
||||
:ref="item.ref"
|
||||
v-bind="item"
|
||||
:max-list-items="10"
|
||||
@dash-remove="dashRemove"
|
||||
@@ -214,16 +213,31 @@ export default {
|
||||
},
|
||||
addItem: function(item) {
|
||||
this.showSelector = false;
|
||||
item.ref = "db" + Date.now();
|
||||
this.effectiveView.push(item);
|
||||
const newItem = JSON.parse(JSON.stringify(item));
|
||||
newItem.id = Date.now();
|
||||
this.effectiveView.push(newItem);
|
||||
this.saveView();
|
||||
},
|
||||
availableItems: function() {
|
||||
const allItems = DashRegistry.availableItems();
|
||||
const newItems = allItems.filter(
|
||||
z => !this.effectiveView.find(m => m.id == z.id && z.singleOnly)
|
||||
);
|
||||
return newItems;
|
||||
// console.log("availableItems:allItems", JSON.stringify(allItems));
|
||||
// console.log(
|
||||
// "availableItems:effectiveView",
|
||||
// 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() {
|
||||
const vm = this;
|
||||
@@ -246,7 +260,7 @@ export default {
|
||||
const availableItems = DashRegistry.availableItems();
|
||||
//filter out any that are deprecated or no longer accessible due to role change
|
||||
const allowedView = savedView.filter(z =>
|
||||
availableItems.find(m => m.id == z.id)
|
||||
availableItems.find(m => m.type == z.type)
|
||||
);
|
||||
vm.effectiveView = allowedView;
|
||||
generateMenu(vm);
|
||||
|
||||
Reference in New Issue
Block a user