Refactor Calendar component.

- adapts it to Vuex use for fetching data
- displays extra events in 4-day and day views
- allows classifying by event label in 4-day and day views
This commit is contained in:
D. Berge
2023-10-25 16:16:01 +02:00
parent 847f49ad7c
commit bf633f7fdf

View File

@@ -39,6 +39,12 @@
{{ $refs.calendar.title }} {{ $refs.calendar.title }}
</v-toolbar-title> </v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn v-if="categoriesAvailable"
small
class="mx-4"
v-model="useCategories"
@click="useCategories = !useCategories"
>Labels {{useCategories ? "On" : "Off"}}</v-btn>
<v-menu bottom right> <v-menu bottom right>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn <v-btn
@@ -72,16 +78,23 @@
<v-calendar <v-calendar
ref="calendar" ref="calendar"
v-model="focus" v-model="focus"
:events="events" :events="items"
:event-color="getEventColour" :event-color="getEventColour"
color="primary" color="primary"
:type="type" :type="view"
:locale-first-day-of-year="4" :locale-first-day-of-year="4"
:weekdays="weekdays" :weekdays="weekdays"
:show-week="true" :show-week="true"
:category-days="categoryDays"
:categories="categories"
@click:date="showLogForDate" @click:date="showLogForDate"
@click:event="showLogForEvent" @click:event="showLogForEvent"
></v-calendar> @change="setSpan"
>
<template v-slot:event="{ event }">
<div style="height:100%;overflow:scroll;" v-html="event.name"></div>
</template>
</v-calendar>
</v-sheet> </v-sheet>
</div> </div>
</template> </template>
@@ -97,8 +110,9 @@ export default {
weekdays: [1, 2, 3, 4, 5, 6, 0], weekdays: [1, 2, 3, 4, 5, 6, 0],
type: "week", type: "week",
focus: "", focus: "",
events: [ items: [],
], useCategories: false,
span: {},
options: { options: {
sortBy: "sequence" sortBy: "sequence"
} }
@@ -117,28 +131,126 @@ export default {
return labels[this.type]; return labels[this.type];
}, },
...mapGetters(['loading']) view () {
return this.useCategories ? "category" : this.type;
},
categoriesAvailable () {
return this.type == "day" || this.type == "4day";
},
categoryDays () {
if (this.useCategories) {
const days = {
month: 30,
week: 7,
"4day": 4,
day: 1
};
return days[this.type];
}
},
visibleItems () {
return this.items.filter(i => {
const end = i.end ?? i.start;
if (i.start > this.span.end) {
return false;
}
if (end < this.span.start) {
return false;
}
return true;
});
},
categories () {
return [...new Set(this.visibleItems.map(i => i.category ?? "General"))];
},
...mapGetters(['sequencesLoading', 'sequences', 'events'])
},
watch: {
sequences () {
const isFirstLoad = !this.items.length;
this.getEvents();
if (isFirstLoad) {
this.setLast();
}
},
events () {
const isFirstLoad = !this.items.length;
this.getEvents();
if (isFirstLoad) {
this.setLast();
}
},
type () {
this.getEvents();
},
categoriesAvailable (value) {
if (!value) {
this.useCategories = false;
}
}
}, },
methods: { methods: {
async getEvents () { async getEvents () {
const query = new URLSearchParams(this.options); const sequences = this.sequences.map(s => {
const url = `/project/${this.$route.params.project}/sequence?${query.toString()}`;
const finalSequences = await this.api([url]) || [];
this.events = finalSequences.map(s => {
const e = {}; const e = {};
//e.start = s.ts0.substring(0,10)+" "+s.ts0.substring(11,19)
//e.end = s.ts1.substring(0,10)+" "+s.ts1.substring(11,19)
e.routerLink = { name: "logBySequence", params: { sequence: s.sequence } }; e.routerLink = { name: "logBySequence", params: { sequence: s.sequence } };
e.start = new Date(s.ts0); e.start = new Date(s.ts0);
e.end = new Date(s.ts1); e.end = new Date(s.ts1);
e.timed = true; e.timed = true;
e.colour = "orange"; e.colour = "orange";
e.name = `Sequence ${s.sequence}`; e.name = `<b>Sequence ${s.sequence}</b><br/>Line ${s.line}<br/><abbr title="Shotpoints">SP</abbr> ${s.fgsp ?? s.fsp}${s.lgsp ?? s.lsp}`;
e.category = "Sequence"
return e; return e;
}); });
const lineChanges = this.events.filter(i => i.meta?.["*ReportLineChangeTime*"]?.value && i.meta?.["*ReportLineChangeTime*"]?.type != "excess").map(i => {
const e = {};
const duration = i.meta?.["*ReportLineChangeTime*"]?.value;
e.end = new Date(i.tstamp);
e.start = new Date(e.end - duration);
e.timed = true;
e.colour = "pink";
e.name = "Line change";
e.category = "Production"
return e;
});
const excludedLabels = [ "FSP", "FGSP", "LSP", "LGSP", "QC" ];
const otherEvents = this.events.filter(i => !excludedLabels.some(l => i.labels.includes(l))).map(i => {
const e = {};
e.start = new Date(i.tstamp);
e.colour = "brown";
e.timed = true;
e.name = this.$options.filters.markdownInline(i.remarks);
e.category = i.labels[0];
return e;
});
this.items = [...sequences];
if (this.type == "day" || this.type == "4day") {
this.items.push(...lineChanges, ...otherEvents);
}
}, },
getEventColour (event) { getEventColour (event) {
@@ -150,11 +262,15 @@ export default {
}, },
setFirst () { setFirst () {
this.focus = this.events[this.events.length-1].start; if (this.items.length) {
this.focus = this.items[this.items.length-1].start;
}
}, },
setLast () { setLast () {
this.focus = this.events[0].start; if (this.items.length) {
this.focus = this.items[0].start;
}
}, },
prev () { prev () {
@@ -175,6 +291,13 @@ export default {
} }
}, },
setSpan (span) {
this.span = {
start: new Date(span.start.date),
end: new Date((new Date(span.end.date)).valueOf() + 86400000)
};
},
...mapActions(["api"]) ...mapActions(["api"])
@@ -182,9 +305,7 @@ export default {
async mounted () { async mounted () {
await this.getEvents(); await this.getEvents();
if (this.events.length) { this.setLast();
this.setLast();
}
} }
} }