diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue index 4a072b2b5427f04317854dbf1175a23a90df2f54..0e6b96ea6c6318b57dcf08ec41b88e427e183c90 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue @@ -160,189 +160,12 @@ export default { // computed should not have side effects // but this was actually done before filters was refactored into // its own component - this.resetDate(); + this.$refs.iterator.resetDate(); // might skip query until both set = atomic } }, }, }, - methods: { - resetDate(toDate) { - // Assure current date - console.log("Resetting date range", this.$route.hash); - this.currentDate = toDate || this.$route.hash?.substring(1); - if (!this.currentDate) { - console.log("Set default date"); - this.setDate(DateTime.now().toISODate()); - } - - const date = DateTime.fromISO(this.currentDate); - this.initDate = date; - this.dateStart = date.minus({ days: this.dayIncrement }).toISODate(); - this.dateEnd = date.plus({ days: this.dayIncrement }).toISODate(); - }, - transition() { - this.initDate = false; - this.ready = true; - }, - groupDocsByDay(docs) { - // => {dt: {date: dt, docs: doc ...} ...} - const docsByDay = docs.reduce((byDay, doc) => { - // This works with dummy. Does actual doc have dateStart instead? - const day = DateTime.fromISO(doc.datetimeStart).startOf("day"); - byDay[day] ??= { date: day, docs: [] }; - byDay[day].docs.push(doc); - return byDay; - }, {}); - // => [{date: dt, docs: doc ..., idx: idx, lastIdx: last-idx} ...] - // sorting is necessary since backend can send docs unordered - return Object.keys(docsByDay) - .sort() - .map((key, idx, { length }) => { - const day = docsByDay[key]; - day.first = idx === 0; - const lastIdx = length - 1; - day.last = idx === lastIdx; - return day; - }); - }, - // docsByDay: {dt: [dt doc ...] ...} - fetchMore(from, to, then) { - console.log("fetching", from, to); - this.lastQuery.fetchMore({ - variables: { - dateStart: from, - dateEnd: to, - }, - // Transform the previous result with new data - updateQuery: (previousResult, { fetchMoreResult }) => { - console.log("Received more"); - then(); - return { items: previousResult.items.concat(fetchMoreResult.items) }; - }, - }); - }, - setDate(date) { - this.currentDate = date; - if (!this.hashUpdater) { - this.hashUpdater = window.requestIdleCallback(() => { - if (!(this.$route.hash.substring(1) === this.currentDate)) { - this.$router.replace({ hash: this.currentDate }); - } - this.hashUpdater = false; - }); - } - }, - fixScrollPos(height, top) { - this.$nextTick(() => { - if (height < document.documentElement.scrollHeight) { - document.documentElement.scrollTop = - document.documentElement.scrollHeight - height + top; - this.ready = true; - } else { - // Update top, could have changed in the meantime. - this.fixScrollPos(height, document.documentElement.scrollTop); - } - }); - }, - intersectHandler(date, first, last) { - let once = true; - return (entries) => { - const entry = entries[0]; - if (entry.isIntersecting) { - if (entry.boundingClientRect.top <= this.topMargin || first) { - console.log("@ ", date.toISODate()); - this.setDate(date.toISODate()); - } - - if (once && this.ready && first) { - console.log("load up", date.toISODate()); - this.ready = false; - this.fetchMore( - date.minus({ days: this.dayIncrement }).toISODate(), - date.minus({ days: 1 }).toISODate(), - () => { - this.fixScrollPos( - document.documentElement.scrollHeight, - document.documentElement.scrollTop, - ); - }, - ); - once = false; - } else if (once && this.ready && last) { - console.log("load down", date.toISODate()); - this.ready = false; - this.fetchMore( - date.plus({ days: 1 }).toISODate(), - date.plus({ days: this.dayIncrement }).toISODate(), - () => { - this.ready = true; - }, - ); - once = false; - } - } - }; - }, - // Improve me? - // The navigation logic could be a bit simpler if the current days - // where known as a sorted array (= result of groupDocsByDay) But - // then the list would need its own component and this gets rather - // complicated. Then the calendar could also show the present days - // / gray out the missing. - // - // Next two: arg date is ts object - findPrev(date) { - return this.$refs.days - .map((day) => day.date) - .sort() - .reverse() - .find((date2) => date2 < date); - }, - findNext(date) { - return this.$refs.days - .map((day) => day.date) - .sort() - .find((date2) => date2 > date); - }, - gotoDate(date) { - const present = this.$refs.days.find( - (day) => day.date.toISODate() === date, - ); - - if (present) { - // React immediatly -> smoother navigation - // Also intersect handler does not always react to scrollIntoView - this.setDate(date); - present.focus("smooth"); - } else { - const prev = this.findPrev(DateTime.fromISO(date)); - const next = this.findNext(DateTime.fromISO(date)); - if (prev && next) { - // In between two present days -> goto prev - this.gotoDate(prev.toISODate()); - } else { - // Outsite present day range - this.resetDate(date); - } - } - }, - gotoPrev() { - const prev = this.findPrev(DateTime.fromISO(this.currentDate)); - if (prev) { - this.gotoDate(prev.toISODate()); - } - }, - gotoNext() { - const next = this.findNext(DateTime.fromISO(this.currentDate)); - if (next) { - this.gotoDate(next.toISODate()); - } - }, - }, - created() { - this.resetDate(); - }, }; </script>