Files
raven-client/ayanova/src/views/home-schedule.vue
2021-09-21 17:26:41 +00:00

1079 lines
33 KiB
Vue

<template>
<div v-if="formState.ready" v-resize="onResize" class="my-n8">
<!-- `{{ "focus:" + focus }}` {{ diagInfo() }}
{{ evInfo }}
{{ events }}-->
<gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
<v-sheet height="64">
<v-toolbar flat>
<v-btn outlined class="mr-4" color="grey darken-2" @click="setToday">
{{ $ay.t("DateRangeToday") }}
</v-btn>
<v-btn fab text small color="grey darken-2" @click="prev">
<v-icon small>$prev</v-icon>
</v-btn>
<v-btn fab text small color="grey darken-2" @click="next">
<v-icon small>$next</v-icon>
</v-btn>
<v-toolbar-title v-if="$refs.calendar">
<v-btn text @click="viewType = 'month'">
{{ $refs.calendar.title }}</v-btn
>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn
class="mr-3"
fab
text
small
color="grey darken-2"
@click="settingsDialog = true"
>
<v-icon small>$ayiCog</v-icon>
</v-btn>
<v-menu bottom right>
<template v-slot:activator="{ on, attrs }">
<v-btn outlined color="grey darken-2" v-bind="attrs" v-on="on">
<span>{{ typeToLabel() }}</span>
<v-icon right>$sort</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item @click="viewType = 'day'">
<v-list-item-title>{{ $ay.t("ScheduleDay") }}</v-list-item-title>
</v-list-item>
<v-list-item @click="viewType = 'week'">
<v-list-item-title>{{ $ay.t("ScheduleWeek") }}</v-list-item-title>
</v-list-item>
<v-list-item @click="viewType = 'month'">
<v-list-item-title>{{
$ay.t("ScheduleMonth")
}}</v-list-item-title>
</v-list-item>
<v-list-item @click="viewType = '4day'">
<v-list-item-title>{{ $ay.t("Schedule4Day") }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-toolbar>
</v-sheet>
<v-sheet :height="calendarHeight">
<v-calendar
ref="calendar"
v-model="focus"
color="primary"
:events="events"
:event-color="getEventColor"
:type="viewType"
:locale="languageName"
@click:event="showMoreInfo"
@click:more="viewDay"
@click:date="viewDay"
@change="fetchEvents"
@mousedown:event="startDrag"
@mousedown:time="startTime"
@mousemove:time="mouseMoveDayView"
@mousemove:day="mouseMoveMonthView"
@mouseup:day="endDragExtend"
@mouseup:time="endDragExtend"
@mouseleave.native="cancelDrag"
:event-more-text="$ay.t('More')"
>
<template v-slot:event="{ event, timed, eventSummary }">
<div class="v-event-draggable">
<v-icon small :color="event.textColor" class="mr-1">{{
iconForEvent(event.type)
}}</v-icon>
<span
:class="event.textColor + '--text'"
v-html="eventSummary()"
/><v-icon
v-if="!event.editable"
x-small
:color="event.textColor"
class="ml-1"
>
$ayiLock</v-icon
>
</div>
<div
v-if="timed && event.editable"
class="v-event-drag-bottom"
@mousedown.stop="extendBottom(event)"
></div>
</template>
</v-calendar>
<!-- NEW ITEM DIALOG -->
<template>
<v-row justify="center">
<v-dialog max-width="360px" persistent v-model="newItemDialog">
<v-card>
<v-card-title>{{ $ay.t("New") }}</v-card-title>
<v-card-text>
<v-col cols="12">
<v-btn
x-large
block
@click="newItem($ay.ayt().WorkOrderItemScheduledUser)"
><v-icon large left>$ayiTools</v-icon
>{{ $ay.t("WorkOrder") }}</v-btn
> </v-col
><v-col cols="12">
<v-btn x-large block @click="newItem($ay.ayt().Reminder)"
><v-icon large left>$ayiStickyNote</v-icon
>{{ $ay.t("Reminder") }}</v-btn
>
</v-col>
</v-card-text>
<v-card-actions>
<v-btn text @click="cancelAddNew" color="primary">{{
$ay.t("Cancel")
}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
<!-- MORE INFO DIALOG -->
<v-menu
v-model="moreInfoDialog"
:close-on-content-click="false"
:activator="selectedElement"
offset-x
>
<v-card color="grey lighten-4" min-width="350px" flat>
<v-toolbar>
<v-btn icon @click="openScheduledItem()">
<v-icon color="primary">{{ iconForSelectedEvent() }}</v-icon>
</v-btn>
<v-toolbar-title>{{ selectedEvent.name }}</v-toolbar-title>
</v-toolbar>
<v-card-text>
<!--reminder -->
<template v-if="selectedEvent.type == $ay.ayt().Reminder">
<div>
<span class="text-h6">{{ $ay.t("ReminderName") }}:</span>
<span class="text-body-1 ml-2">{{ evInfo.name }}</span>
</div>
<div>
<span class="text-h6">{{ $ay.t("ReviewDate") }}:</span>
<span class="text-body-1 ml-2"
>{{ $ay.dt(evInfo.startDate) }}&nbsp;&mdash;&nbsp;{{
$ay.dt(evInfo.stopDate)
}}</span
>
</div>
<div>
<span class="text-h6">{{ $ay.t("ReminderNotes") }}:</span>
<span class="text-body-1 ml-2">
<v-icon class="mr-3" :color="evInfo.color"
>$ayiSquareFull</v-icon
>{{ evInfo.notes }}</span
>
</div>
</template>
<!--review -->
<template v-if="selectedEvent.type == $ay.ayt().Review">
<div class="mb-1" v-if="evInfo.aType">
<v-icon
large
color="primary"
@click="openObject(evInfo.aType, evInfo.objectId)"
>{{ $ay.util().iconForType(evInfo.aType) }}</v-icon
><span
class="text-h6"
@click="openObject(evInfo.aType, evInfo.objectId)"
>
{{ evInfo.reviewObjectViz }}</span
>
</div>
<div>
<span class="text-h6">{{ $ay.t("ReviewName") }}:</span>
<span class="text-body-1 ml-2">{{ evInfo.name }}</span>
</div>
<div>
<span class="text-h6">{{ $ay.t("ReviewDate") }}:</span>
<span class="text-body-1 ml-2">{{
$ay.dt(evInfo.reviewDate)
}}</span>
</div>
<div>
<span class="text-h6">{{ $ay.t("ReviewNotes") }}:</span>
<span class="text-body-1 ml-2"> {{ evInfo.notes }}</span>
</div>
<template v-if="evInfo.completedDate">
<div>
<span class="text-h6"
>{{ $ay.t("ReviewCompletedDate") }}:</span
>
<span class="text-body-1 ml-2">{{
$ay.dt(evInfo.reviewCompletedDate)
}}</span>
</div>
<div>
<span class="text-h6">{{ $ay.t("ReviewNotes") }}:</span>
<span class="text-body-1 ml-2">
{{ evInfo.reviewNotes }}</span
>
</div>
</template>
</template>
<!--woitemscheduleduser -->
<template
v-if="selectedEvent.type == $ay.ayt().WorkOrderItemScheduledUser"
>
<div>
<span class="text-h6">{{ $ay.t("WorkOrder") }}:</span>
<span class="text-body-1 ml-2"
>{{ evInfo.serial }}&nbsp; {{ evInfo.customerViz }}</span
>
</div>
<div>
<span class="text-h6">{{ $ay.t("Tags") }}:</span>
<span class="text-body-1 ml-2">{{
$ay.util().formatTags(evInfo.wotags)
}}</span>
</div>
<div>
<span class="text-h6">{{ $ay.t("DashboardScheduled") }}:</span>
<span class="text-body-1 ml-2"
>{{ $ay.dt(evInfo.startDate) }}&nbsp;&mdash;&nbsp;{{
$ay.dt(evInfo.stopDate)
}}</span
>
</div>
<div>
<span class="text-h6"
>{{
$ay.t("WorkOrderItemScheduledUserEstimatedQuantity")
}}:</span
>
<span class="text-body-1 ml-2">{{ evInfo.qty }}</span>
</div>
<div>
<span class="text-h6"
>{{ $ay.t("WorkOrderItemScheduledUserServiceRateID") }}:</span
>
<span class="text-body-1 ml-2">{{ evInfo.rate }}</span>
</div>
<div v-if="evInfo.haswostatus">
<span class="text-h6">{{ $ay.t("WorkOrderStatus") }}:</span>
<span class="text-body-1 ml-2">{{ evInfo.wostatus }}</span>
<v-icon :color="evInfo.wostatuscolor" class="ml-4"
>$ayiFlag</v-icon
>
<v-icon
color="primary"
v-if="evInfo.wostatuslocked"
class="ml-4"
>$ayiLock</v-icon
>
<v-icon
color="primary"
v-if="evInfo.wostatuscompleted"
class="ml-4"
>$ayiCheckCircle</v-icon
>
</div>
<div>
<span class="text-h6"
>{{ $ay.t("WorkOrderItemSummary") }}:</span
>
<span class="text-body-1 ml-2">
<v-icon class="mr-3" :color="evInfo.woitemstatuscolor"
>$ayiCircle</v-icon
>{{ evInfo.woitemstatus }}</span
>
</div>
<div>
<span class="text-h6"
>{{ $ay.t("WorkOrderItemPriorityID") }}:</span
>
<span class="text-body-1 ml-2">
<v-icon class="mr-3" :color="evInfo.woitemprioritycolor"
>$ayiFireAlt</v-icon
>{{ evInfo.woitempriority }}</span
>
</div>
<div>
<span class="text-h6">{{ $ay.t("WorkOrderItemTags") }}:</span>
<span class="text-body-1 ml-2">{{
$ay.util().formatTags(evInfo.woitemtags)
}}</span>
</div>
</template>
</v-card-text>
<v-card-actions>
<v-btn color="primary" text @click="openScheduledItem()">{{
$ay.t("Open")
}}</v-btn>
<v-spacer v-if="!$vuetify.breakpoint.xs"></v-spacer>
<v-btn color="primary" text @click="moreInfoDialog = false">
{{ $ay.t("Close") }}
</v-btn>
</v-card-actions>
</v-card>
</v-menu>
</v-sheet>
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="settingsDialog">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
settings here
</v-card-text>
<v-card-actions>
<v-btn text @click="settingsDialog = false" color="primary">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer v-if="!$vuetify.breakpoint.xs"></v-spacer>
<v-btn
color="primary"
text
@click="acceptSettings()"
class="ml-4"
>{{ $ay.t("OK") }}</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
</div>
</template>
<script>
/*
TODO NEXT:
Display and open Reviews
Review object changes:
Due date sb changed to "ReviewDate" meaning this is when the review should happen
if completed date is set then editable is false for schedule adn it should should a checkmark symbol indicating it's been done
review icon, appt color - no inherent so do grayish neutral and test on both dark and light modes
Settings form
persist, imminentize
Save / load from server (or locally only? as formSettings.saved)??
saved with device or saved with account is the heart of it
wo display section:
DISPLAY
Color: wostatus/woitemstatus/woitempriority/none
Weekdays: weekdays to display, copy from pm exclude days thingy
More info: checkbox beside each item below that can be shown in wo
Needs a refresh button at top
Issue
needs a fast click to open an item for more info, related to 100ms??
if too slow a click it ignores it
TESTING:
drag/extend in all views working?
touch mode still can do all ops
ultimately test on devices
Move common functionality out of home-schedule to be re-used in svc-schedule and also potentially other scheds like customer view of workorders or visual calendar view of work for a single customer for techs etc
the more I can move out of it the easier to do more scheds in other places
DOCS:
how to use the schedule
reporting - make it happen
could just default to regular reporting list, doesn't absolutely need to be a calendar at least at first
as long as it has all appointments consolidated in single list
Move on to the shared service schedule with categories being people and all that entails
*/
// const FORM_CUSTOM_TEMPLATE_KEY = "home-schedule";
const FORM_KEY = "home-schedule";
const CLICK_DETECT_TIMEOUT = 200;
export default {
async created() {
let vm = this;
try {
await initForm(vm);
window.$gz.eventBus.$on("menu-click", clickHandler);
//----------------------------
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
beforeDestroy() {
saveFormSettings(this);
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
//formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
focus: "",
viewType: "month",
firstTime: "8:00",
selectedEvent: {},
selectedElement: null,
moreInfoDialog: false,
events: [],
evInfo: {},
dragEvent: null,
dragStart: null,
extendEvent: null,
createStart: null,
extendOriginal: null,
dragged: false,
dragTimeout: null,
formState: {
ready: false,
dirty: false,
valid: true,
readOnly: false,
loading: true,
errorBoxMessage: null,
appError: null,
serverError: {}
},
rights: window.$gz.role.defaultRightsObject(),
calendarHeight: 600,
settingsDialog: false,
newItemDialog: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage(),
hour12: window.$gz.locale.getHour12()
};
},
methods: {
openObject: function(type, id) {
window.$gz.eventBus.$emit("openobject", {
type: type,
id: id
});
},
newItem(atype) {
let newEvent = this.events[this.events.length - 1];
const addStart = window.$gz.locale.localScheduleFormatToUTC8601String(
newEvent.start,
this.timeZoneName
);
const addEnd = window.$gz.locale.localScheduleFormatToUTC8601String(
newEvent.end,
this.timeZoneName
);
switch (atype) {
case this.$ay.ayt().WorkOrderItemScheduledUser:
this.$router.push({
name: "workorder-edit",
params: {
recordid: 0,
add: {
type: atype,
start: addStart,
end: addEnd,
userId: this.$store.state.userId,
name: this.$store.state.userName
}
}
});
break;
case this.$ay.ayt().Reminder:
this.$router.push({
name: "reminder-edit",
params: {
recordid: 0,
add: {
start: addStart,
end: addEnd,
userId: this.$store.state.userId,
name: this.$store.state.userName
}
}
});
break;
}
//remove faux item, server will provide it back once it's created anyway
this.events.splice(this.events.length - 1);
this.newItemDialog = false;
},
cancelAddNew() {
this.events.splice(this.events.length - 1);
this.newItemDialog = false;
},
startDrag({ event }) {
if (event) {
if (event.editable) {
//My work around to disambiguate dragging and clicking
clearTimeout(this.dragTimeout);
this.dragged = false;
this.dragTimeout = setTimeout(() => {
this.dragged = true;
}, CLICK_DETECT_TIMEOUT); // Min delay to be regarded as extend instead of click, also affects click time to display more info, too short needs faster click
this.dragEvent = event;
this.dragTime = null;
this.extendOriginal = null;
} else {
this.dragged = false;
}
}
},
extendBottom(event) {
if (event.editable) {
//My work around to disambiguate extending and clicking
clearTimeout(this.dragTimeout);
this.dragged = false;
this.dragTimeout = setTimeout(() => {
this.dragged = true;
}, CLICK_DETECT_TIMEOUT); // Min delay to be regarded as extend instead of click, also affects click time to display more info, too short needs faster click
//this.dragEvent = event;
this.extendEvent = event;
this.createStart = event.start;
this.extendOriginal = event.end;
}
},
async endDragExtend() {
//On drag then dragged is set to true and dragEvent and dragTime are set
//on extend then dragged is set to true extendEvent (actual event), extendOriginal and createStart are set, dragEvent is null
//on create then dragged is set to false and createStart is only value set, dragEvent is null and extendEvent is null
//Handle the event, could be one of three things: changing an event start time, changing an event length or creating a new event
if (this.extendEvent && this.extendEvent.type == 0) {
//NEW, prompt for deets and create or if cancelled then just remove this faux event from events list (it will be the last one in the array)
this.newItemDialog = true;
} else {
if (!this.dragged) {
//we're here due to mouse up but it's not a drag or an extend so it's a More Info mouse up click so bail out now
return;
}
//MODIFY existing event, drag or extend
if (this.dragEvent || this.extendEvent) {
let param = { type: null, id: null, start: null, end: null };
if (this.dragEvent) {
// && this.dragged
param.type = this.dragEvent.type;
param.id = this.dragEvent.id;
param.start = window.$gz.locale.localScheduleFormatToUTC8601String(
this.dragEvent.start,
this.timeZoneName
);
param.end = window.$gz.locale.localScheduleFormatToUTC8601String(
this.dragEvent.end,
this.timeZoneName
);
} else {
param.type = this.extendEvent.type;
param.id = this.extendEvent.id;
param.start = window.$gz.locale.localScheduleFormatToUTC8601String(
this.extendEvent.start,
this.timeZoneName
);
param.end = window.$gz.locale.localScheduleFormatToUTC8601String(
this.extendEvent.end,
this.timeZoneName
);
}
try {
window.$gz.form.deleteAllErrorBoxErrors(this);
let res = await window.$gz.api.post("schedule/adjust", param);
if (res.error) {
this.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(this);
} else {
}
} catch (error) {
window.$gz.errorHandler.handleFormError(error, this);
}
}
}
this.dragTime = null;
this.dragEvent = null;
this.extendEvent = null;
this.createStart = null;
this.extendOriginal = null;
},
cancelDrag() {
if (this.extendEvent) {
if (this.extendOriginal) {
this.extendEvent.end = this.extendOriginal;
} else {
const i = this.events.indexOf(this.extendEvent);
if (i !== -1) {
this.events.splice(i, 1);
}
}
}
this.extendEvent = null;
this.createStart = null;
this.dragTime = null;
this.dragEvent = null;
},
mouseMoveDayView(tms) {
//no event being dragged or exgtended?
if (!this.dragEvent && !this.extendEvent) {
return;
}
const mouse = this.toTime(tms);
if (this.dragEvent && this.dragTime !== null) {
//# DRAGGING PATH
const start = this.dragEvent.start;
const end = this.dragEvent.end;
const duration = end - start;
const newStartTime = mouse - this.dragTime;
const newStart = this.roundTime(newStartTime);
const newEnd = newStart + duration;
this.dragEvent.start = newStart;
this.dragEvent.end = newEnd;
} else if (this.extendEvent && this.createStart !== null) {
//# EXTENDING PATH
const mouseRounded = this.roundTime(mouse, false);
const min = Math.min(mouseRounded, this.createStart);
const max = Math.max(mouseRounded, this.createStart);
this.extendEvent.start = min;
this.extendEvent.end = max;
}
},
mouseMoveMonthView(dd) {
if (!this.dragEvent) {
return;
}
//# DRAGGING PATH MONTH VIEW
//need to get the actual start time as it isn't in the mouse date
const dragEventStartDate = new Date(this.dragEvent.start);
const mouseDate = new Date(
dd.year,
dd.month - 1,
dd.day,
dragEventStartDate.getHours(),
dragEventStartDate.getMinutes()
).getTime();
const moveDelta = mouseDate - this.dragEvent.start;
this.dragEvent.start = mouseDate;
this.dragEvent.end = this.dragEvent.end + moveDelta;
},
startTime(tms) {
//This is called on the start of dragging an existing schedule item or drag extending a NEW schedule item
const mouse = this.toTime(tms);
if (this.dragEvent && this.dragTime === null) {
//# DAY VIEW *DRAG* EXISTING START EVENT (not extend)
const start = this.dragEvent.start;
this.dragTime = mouse - start;
} else {
//# DAY VIEW CREATE START EVENT
this.createStart = this.roundTime(mouse);
this.extendEvent = {
name: "-",
color: this.$store.state.darkMode ? "white" : "black",
textColor: this.$store.state.darkMode ? "black" : "white",
start: this.createStart,
end: this.createStart,
timed: true,
type: 0,
id: 0,
editable: true
};
this.events.push(this.extendEvent);
}
},
roundTime(time, down = true) {
const roundTo = 15; // minutes
const roundDownTime = roundTo * 60 * 1000;
return down
? time - (time % roundDownTime)
: time + (roundDownTime - (time % roundDownTime));
},
toTime(tms) {
return new Date(
tms.year,
tms.month - 1,
tms.day,
tms.hour,
tms.minute
).getTime();
},
diagInfo() {
if (this.$refs.calendar) {
return (
"cal" +
JSON.stringify({
start: this.$refs.calendar.start,
end: this.$refs.calendar.end,
focus: this.focus,
firstInterval: this.$refs.calendar.firstInterval
})
);
} else {
return "no calendar";
}
},
typeToLabel() {
switch (this.viewType) {
case "month":
return this.$ay.t("ScheduleMonth");
case "week":
return this.$ay.t("ScheduleWeek");
case "day":
return this.$ay.t("ScheduleDay");
case "4day":
return this.$ay.t("Schedule4Day");
}
},
onResize() {
this.calendarHeight = window.innerHeight * 0.84;
},
viewDay({ date }) {
this.focus = date;
this.viewType = "day";
},
getEventColor(event) {
return event.color;
},
setToday() {
this.focus = "";
},
prev() {
this.$refs.calendar.prev();
},
next() {
this.$refs.calendar.next();
},
iconForSelectedEvent() {
return window.$gz.util.iconForType(this.selectedEvent.type);
},
iconForEvent(type) {
return window.$gz.util.iconForType(type);
},
openScheduledItem() {
window.$gz.eventBus.$emit("openobject", {
type: this.selectedEvent.type,
id: this.selectedEvent.id
});
},
async showMoreInfo({ nativeEvent, event }) {
//workaround to disambiguate drag click from view more info click
if (this.dragged) {
return;
}
let route = null;
this.evInfo = {};
switch (event.type) {
case window.$gz.type.WorkOrderItemScheduledUser:
route = `workorder/items/scheduled-users/sched-info/${event.id}`;
break;
case window.$gz.type.Reminder:
route = `reminder/sched-info/${event.id}`;
break;
case window.$gz.type.Review:
route = `review/sched-info/${event.id}`;
break;
}
if (route) {
let res = await window.$gz.api.get(route);
if (!res.error) {
this.evInfo = res.data;
}
}
const open = () => {
this.selectedEvent = event;
this.selectedElement = nativeEvent.target;
requestAnimationFrame(() =>
requestAnimationFrame(() => (this.moreInfoDialog = true))
);
};
if (this.moreInfoDialog) {
this.moreInfoDialog = false;
requestAnimationFrame(() => requestAnimationFrame(() => open()));
} else {
open();
}
nativeEvent.stopPropagation();
},
async fetchEvents({ start, end }) {
try {
window.$gz.form.deleteAllErrorBoxErrors(this);
let res = await window.$gz.api.post("schedule/personal", {
view: window.$gz.util.calendarViewToAyaNovaEnum(this.viewType),
dark: this.$store.state.darkMode,
start: window.$gz.locale.localTimeDateStringToUTC8601String(
`${start.date}T00:00:00`,
this.timeZoneName
),
end: window.$gz.locale.localTimeDateStringToUTC8601String(
`${end.date}T23:59:59`,
this.timeZoneName
),
colorSource: 4,
workOrders: true,
reviews: true,
reminders: true
});
if (res.error) {
this.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(this);
} else {
this.events = res.data.map(x => {
return {
...x,
start: window.$gz.locale.utcDateToScheduleCompatibleFormatLocalized(
x.start,
this.timeZoneName
),
end: window.$gz.locale.utcDateToScheduleCompatibleFormatLocalized(
x.end,
this.timeZoneName
)
};
});
}
} catch (error) {
window.$gz.errorHandler.handleFormError(error, this);
}
}
//eom
}
};
/////////////////////////////
//
//
async function clickHandler(menuItem) {
if (!menuItem) {
return;
}
let m = window.$gz.menu.parseMenuItem(menuItem);
if (m.owner == FORM_KEY && !m.disabled) {
switch (m.key) {
// case "report":
// let res = await m.vm.$refs.reportSelector.open(
// {
// AType: window.$gz.type.Project,
// selectedRowIds: [m.vm.obj.id]
// },
// m.id
// );
// if (res == null) {
// return;
// }
// window.$gz.form.setLastReport(FORM_KEY, res);
// generateMenu(m.vm);
// break;
case "WorkOrderItemScheduledUserList":
m.vm.$router.push({
name: "svc-workorder-item-scheduled-users",
params: {
aType: window.$gz.type.User,
objectId: m.vm.$store.state.userId,
name: m.vm.$store.state.userName
}
});
break;
case "WorkOrderItemLaborList":
m.vm.$router.push({
name: "svc-workorder-item-labors",
params: {
aType: window.$gz.type.User,
objectId: m.vm.$store.state.userId,
name: m.vm.$store.state.userName
}
});
break;
default:
window.$gz.eventBus.$emit(
"notify-warning",
FORM_KEY + "::context click: [" + m.key + "]"
);
}
}
}
//////////////////////
//
//
function generateMenu(vm) {
let menuOptions = {
isMain: true,
readOnly: vm.formState.readOnly,
icon: "$ayiCalendarDay",
title: "Schedule",
helpUrl: "home-schedule",
menuItems: []
};
// //REPORTS
// //Report not Print, print is a further option
// menuOptions.menuItems.push({
// title: "Report",
// icon: "$ayiFileAlt",
// key: FORM_KEY + ":report",
// vm: vm
// });
// //get last report selected
// let lastReport = window.$gz.form.getLastReport(FORM_KEY);
// if (lastReport != null) {
// menuOptions.menuItems.push({
// title: lastReport.name,
// notrans: true,
// icon: "$ayiFileAlt",
// key: FORM_KEY + ":report:" + lastReport.id,
// vm: vm
// });
// }
// if (vm.rights.change) {
// menuOptions.menuItems.push({
// title: "New",
// icon: "$ayiPlus",
// key: FORM_KEY + ":new",
// vm: vm
// });
// }
if (vm.$store.getters.isScheduleableUser) {
menuOptions.menuItems.push({ divider: true, inset: false });
menuOptions.menuItems.push({
title: "WorkOrderItemScheduledUserList",
icon: "$ayiUserClock",
key: FORM_KEY + ":WorkOrderItemScheduledUserList",
vm: vm
});
menuOptions.menuItems.push({
title: "WorkOrderItemLaborList",
icon: "$ayiHammer",
key: FORM_KEY + ":WorkOrderItemLaborList",
vm: vm
});
//--- /show all ---
}
menuOptions.menuItems.push({ divider: true, inset: false });
window.$gz.eventBus.$emit("menu-change", menuOptions);
}
/////////////////////////////////
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
getFormSettings(vm);
}
function getFormSettings(vm) {
let formSettings = window.$gz.form.getFormSettings(FORM_KEY);
if (!formSettings || !formSettings.temp || !formSettings.temp.viewType) {
//defaults
formSettings = { temp: { viewType: "month", focus: null } };
}
vm.viewType = formSettings.temp.viewType;
vm.focus = formSettings.temp.focus;
return formSettings;
}
function saveFormSettings(vm) {
let formSettings = window.$gz.form.getFormSettings(FORM_KEY);
formSettings.temp = { viewType: vm.viewType, focus: vm.focus };
window.$gz.form.setFormSettings(FORM_KEY, formSettings);
}
//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
await window.$gz.translation.cacheTranslations([
"DateRangeToday",
"ScheduleMonth",
"ScheduleDay",
"ScheduleWeek",
"Schedule4Day",
"WorkOrder",
"Reminder",
"Review",
"DashboardScheduled",
"WorkOrderItemPriorityID",
"WorkOrderItemSummary",
"WorkOrderStatus",
"WorkOrderItemScheduledUserEstimatedQuantity",
"WorkOrderItemScheduledUserServiceRateID",
"WorkOrderItemTags"
]);
}
</script>
<style scoped lang="scss">
.v-event-draggable {
padding-left: 6px;
}
.v-event-timed {
user-select: none;
-webkit-user-select: none;
}
.v-event-drag-bottom {
position: absolute;
left: 0;
right: 0;
bottom: 4px;
height: 4px;
cursor: ns-resize;
&::after {
display: none;
position: absolute;
left: 50%;
height: 4px;
border-top: 1px solid gray;
border-bottom: 1px solid gray;
width: 32px;
margin-left: -8px;
// opacity: 0.8;
content: "";
}
&:hover::after {
display: block;
}
}
</style>