mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-25 07:59:28 +00:00
WIP: fixing issues found with cypress tests
This commit is contained in:
@@ -60,6 +60,7 @@ export default {
|
||||
template: /* html */`
|
||||
<div
|
||||
class="fhc-calendar-base-grid-line"
|
||||
:data-day="date.toISODate()"
|
||||
style="position:relative;display:grid;grid-auto-flow:dense"
|
||||
:style="'grid-template-' + axisRow + 's:subgrid'"
|
||||
>
|
||||
@@ -71,7 +72,7 @@ export default {
|
||||
></line-background>
|
||||
<line-event
|
||||
v-for="(event, i) in eventsWithRowInfo"
|
||||
:key="event.orig.eindeutige_gruppen_id || i"
|
||||
:key="event.orig.kalender_id || i"
|
||||
:style="'grid-' + axisRow + ': ' + event.rows.join('/')"
|
||||
:event="event"
|
||||
@resize-start="$emit('resize-start', $event)"
|
||||
|
||||
@@ -1,201 +1,212 @@
|
||||
import FhcCalendar from "./Base.js";
|
||||
|
||||
import { useEventLoader } from '../../composables/EventLoader.js';
|
||||
|
||||
import ModeWeek from './Mode/Week.js';
|
||||
import ModeMonth from './Mode/Month.js';
|
||||
import ModeTable from './Mode/Table.js';
|
||||
import ApiKalender from '../../api/factory/tempus/kalender.js';
|
||||
import draggable from '../../directives/draggable.js';
|
||||
import { useEventLoader } from "../../composables/EventLoader.js";
|
||||
|
||||
import ModeWeek from "./Mode/Week.js";
|
||||
import ModeMonth from "./Mode/Month.js";
|
||||
import ModeTable from "./Mode/Table.js";
|
||||
import ApiKalender from "../../api/factory/tempus/kalender.js";
|
||||
import draggable from "../../directives/draggable.js";
|
||||
|
||||
export default {
|
||||
name: "CalendarTempus",
|
||||
components: {
|
||||
FhcCalendar
|
||||
},
|
||||
inject: {
|
||||
renderers: {from: 'renderers'},
|
||||
appConfig: {
|
||||
from: 'appConfig',
|
||||
default: {
|
||||
visible_status: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
draggable,
|
||||
},
|
||||
props: {
|
||||
timezone: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
date: {
|
||||
type: [Date, String, Number, luxon.DateTime],
|
||||
default: luxon.DateTime.local()
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'Week'
|
||||
},
|
||||
getPromiseFunc: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
parkedEvents: {
|
||||
type: Object,
|
||||
default: () => new Set()
|
||||
},
|
||||
visibleLecturers: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
extraBackgrounds: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
visibleStatus: {
|
||||
type: Array,
|
||||
default: () => ['all']
|
||||
},
|
||||
},
|
||||
emits: [
|
||||
"update:date",
|
||||
"update:mode",
|
||||
"update:range",
|
||||
"drop",
|
||||
"resize"
|
||||
],
|
||||
name: "CalendarTempus",
|
||||
components: {
|
||||
FhcCalendar,
|
||||
},
|
||||
inject: {
|
||||
renderers: { from: "renderers" },
|
||||
appConfig: {
|
||||
from: "appConfig",
|
||||
default: {
|
||||
visible_status: "all",
|
||||
},
|
||||
},
|
||||
},
|
||||
directives: {
|
||||
draggable,
|
||||
},
|
||||
props: {
|
||||
timezone: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
date: {
|
||||
type: [Date, String, Number, luxon.DateTime],
|
||||
default: luxon.DateTime.local(),
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: "Week",
|
||||
},
|
||||
getPromiseFunc: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
parkedEvents: {
|
||||
type: Object,
|
||||
default: () => new Set(),
|
||||
},
|
||||
visibleLecturers: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
extraBackgrounds: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
visibleStatus: {
|
||||
type: Array,
|
||||
default: () => ["all"],
|
||||
},
|
||||
},
|
||||
emits: ["update:date", "update:mode", "update:range", "drop", "resize"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
modes: {
|
||||
week: Vue.markRaw(ModeWeek),
|
||||
month: Vue.markRaw(ModeMonth),
|
||||
tableList: Vue.markRaw(ModeTable),
|
||||
},
|
||||
modeOptions: {
|
||||
day: {
|
||||
emptyMessage: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
||||
emptyMessageDetails: Vue.computed(() => this.$p.t('lehre/noLvFound'))
|
||||
},
|
||||
week: {
|
||||
collapseEmptyDays: false
|
||||
}
|
||||
},
|
||||
currentMode: this.mode,
|
||||
teachingunits: null,
|
||||
hoursplan: null,
|
||||
showRaster: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
backgrounds() {
|
||||
let now = luxon.DateTime.now().setZone(this.timezone);
|
||||
data() {
|
||||
return {
|
||||
modes: {
|
||||
week: Vue.markRaw(ModeWeek),
|
||||
month: Vue.markRaw(ModeMonth),
|
||||
tableList: Vue.markRaw(ModeTable),
|
||||
},
|
||||
modeOptions: {
|
||||
day: {
|
||||
emptyMessage: Vue.computed(() => this.$p.t("lehre/noLvFound")),
|
||||
emptyMessageDetails: Vue.computed(() => this.$p.t("lehre/noLvFound")),
|
||||
},
|
||||
week: {
|
||||
collapseEmptyDays: false,
|
||||
},
|
||||
},
|
||||
currentMode: this.mode,
|
||||
teachingunits: null,
|
||||
hoursplan: null,
|
||||
showRaster: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
backgrounds() {
|
||||
let now = luxon.DateTime.now().setZone(this.timezone);
|
||||
|
||||
let past = [];
|
||||
if (this.mode == 'Month')
|
||||
{
|
||||
past = [{
|
||||
class: 'background-past',
|
||||
end: now.startOf('day')
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
past = [{
|
||||
class: 'background-past',
|
||||
end: now,
|
||||
label: now.startOf('minute').toISOTime({ suppressSeconds: true, includeOffset: false })
|
||||
}];
|
||||
}
|
||||
let past = [];
|
||||
if (this.mode == "Month") {
|
||||
past = [
|
||||
{
|
||||
class: "background-past",
|
||||
end: now.startOf("day"),
|
||||
},
|
||||
];
|
||||
} else {
|
||||
past = [
|
||||
{
|
||||
class: "background-past",
|
||||
end: now,
|
||||
label: now
|
||||
.startOf("minute")
|
||||
.toISOTime({ suppressSeconds: true, includeOffset: false }),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
...past,
|
||||
...(this.extraBackgrounds || [])
|
||||
];
|
||||
},
|
||||
visibleEvents()
|
||||
{
|
||||
let list = this.events;
|
||||
return [...past, ...(this.extraBackgrounds || [])];
|
||||
},
|
||||
visibleEvents() {
|
||||
let list = this.events;
|
||||
|
||||
if (Array.isArray(this.visibleLecturers))
|
||||
{
|
||||
const visibleLectures = new Set(this.visibleLecturers);
|
||||
if (Array.isArray(this.visibleLecturers)) {
|
||||
const visibleLectures = new Set(this.visibleLecturers);
|
||||
|
||||
list = list.filter(event => {
|
||||
if (!event.lektor?.length)
|
||||
return true;
|
||||
return event.lektor.some(lektor => visibleLectures.has(lektor.mitarbeiter_uid));
|
||||
});
|
||||
}
|
||||
list = list.filter((event) => {
|
||||
if (!event.lektor?.length) return true;
|
||||
return event.lektor.some((lektor) =>
|
||||
visibleLectures.has(lektor.mitarbeiter_uid),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.visibleStatus.length || this.visibleStatus.includes('all'))
|
||||
return list;
|
||||
if (!this.visibleStatus.length || this.visibleStatus.includes("all"))
|
||||
return list;
|
||||
|
||||
return list.filter(event => this.visibleStatus.includes(event.status_kurzbz));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
eventStyle(event) {
|
||||
if (!event.farbe)
|
||||
return undefined;
|
||||
return '--event-bg:#' + event.farbe;
|
||||
},
|
||||
updateRange(rangeInterval) {
|
||||
this.rangeInterval = rangeInterval;
|
||||
this.$emit('update:range', rangeInterval);
|
||||
},
|
||||
ondrop(payload){
|
||||
this.$emit('drop', payload);
|
||||
},
|
||||
onresize(payload){
|
||||
this.$emit('resize', payload);
|
||||
},
|
||||
resetEventLoader() {
|
||||
this.reset();
|
||||
},
|
||||
return list.filter((event) =>
|
||||
this.visibleStatus.includes(event.status_kurzbz),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
eventStyle(event) {
|
||||
if (!event.farbe) return undefined;
|
||||
return "--event-bg:#" + event.farbe;
|
||||
},
|
||||
updateRange(rangeInterval) {
|
||||
this.rangeInterval = rangeInterval;
|
||||
this.$emit("update:range", rangeInterval);
|
||||
},
|
||||
ondrop(payload) {
|
||||
this.$emit("drop", payload);
|
||||
},
|
||||
onresize(payload) {
|
||||
this.$emit("resize", payload);
|
||||
},
|
||||
resetEventLoader() {
|
||||
this.reset();
|
||||
},
|
||||
clearOutCalendarEventEmphasis() {
|
||||
this.$refs.calendar.$el
|
||||
.querySelectorAll(
|
||||
".fhc-calendar-base-grid .fhc-calendar-base-grid-line-event",
|
||||
)
|
||||
.forEach((el) => {
|
||||
const spinner = el.querySelector(".spinner-overlay");
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
|
||||
},
|
||||
setup(props, context) {
|
||||
const rangeInterval = Vue.ref(null);
|
||||
el.classList.remove(
|
||||
"updating-event",
|
||||
"updated-event",
|
||||
"updated-event-long",
|
||||
"deemphasized-event",
|
||||
"deemphasized-event-long",
|
||||
);
|
||||
});
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const rangeInterval = Vue.ref(null);
|
||||
|
||||
const { events, lv, reset } = useEventLoader(rangeInterval, props.getPromiseFunc);
|
||||
const { events, lv, reset } = useEventLoader(
|
||||
rangeInterval,
|
||||
props.getPromiseFunc,
|
||||
);
|
||||
|
||||
Vue.watch(lv, newValue => {
|
||||
context.emit('update:lv', newValue);
|
||||
});
|
||||
Vue.watch(lv, (newValue) => {
|
||||
context.emit("update:lv", newValue);
|
||||
});
|
||||
|
||||
return {
|
||||
rangeInterval,
|
||||
events,
|
||||
lv,
|
||||
reset
|
||||
};
|
||||
},
|
||||
return {
|
||||
rangeInterval,
|
||||
events,
|
||||
lv,
|
||||
reset,
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiKalender.getStunden())
|
||||
.then(res => {
|
||||
return this.teachingunits = res.data.map(el => ({
|
||||
id: el.stunde,
|
||||
start: el.beginn,
|
||||
end: el.ende
|
||||
}));
|
||||
});
|
||||
created() {
|
||||
this.$api.call(ApiKalender.getStunden()).then((res) => {
|
||||
return (this.teachingunits = res.data.map((el) => ({
|
||||
id: el.stunde,
|
||||
start: el.beginn,
|
||||
end: el.ende,
|
||||
})));
|
||||
});
|
||||
|
||||
this.$api
|
||||
.call(ApiKalender.getCalendarHours())
|
||||
.then(res => {
|
||||
this.hoursplan = {
|
||||
start: res.data.start,
|
||||
end: res.data.end
|
||||
};
|
||||
});
|
||||
},
|
||||
template: /* html */`
|
||||
this.$api.call(ApiKalender.getCalendarHours()).then((res) => {
|
||||
this.hoursplan = {
|
||||
start: res.data.start,
|
||||
end: res.data.end,
|
||||
};
|
||||
});
|
||||
},
|
||||
template: /* html */ `
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
class="fhc-calendar-lvplan"
|
||||
@@ -265,5 +276,5 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</fhc-calendar>`
|
||||
}
|
||||
</fhc-calendar>`,
|
||||
};
|
||||
|
||||
@@ -491,7 +491,15 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
_updateKalenderEvent(obj, startDT, endDT, start_time, end_time, onSuccess) {
|
||||
_updateKalenderEvent(
|
||||
obj,
|
||||
startDT,
|
||||
endDT,
|
||||
start_time,
|
||||
end_time,
|
||||
onSuccess,
|
||||
onError,
|
||||
) {
|
||||
const origStart = luxon.DateTime.fromISO(obj.orig.isostart);
|
||||
const origEnd = luxon.DateTime.fromISO(obj.orig.isoend);
|
||||
|
||||
@@ -517,6 +525,11 @@ export default {
|
||||
this.$refs.calendar.$refs.calendar.$refs.mode.$refs.view.$refs.grid.disableAutoScroll();
|
||||
this.currentlyUpdatedEvent = obj.orig;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (onError) {
|
||||
onError(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -526,14 +539,14 @@ export default {
|
||||
return;
|
||||
const { item, start, end } = payload;
|
||||
const obj = item[0];
|
||||
if (!obj?.orig?.kalender_id)
|
||||
return alert("Kein gültiges Kalender-Event zum Resizen");
|
||||
if (!obj?.orig?.kalender_id) return;
|
||||
|
||||
const dates = this._parseDates(start, end);
|
||||
if (!dates) return;
|
||||
|
||||
if (
|
||||
luxon.DateTime.fromISO(obj.orig.isostart).toMillis() === dates.startDT.toMillis() &&
|
||||
luxon.DateTime.fromISO(obj.orig.isostart).toMillis() ===
|
||||
dates.startDT.toMillis() &&
|
||||
luxon.DateTime.fromISO(obj.orig.isoend).toMillis() ===
|
||||
dates.endDT.toMillis()
|
||||
)
|
||||
@@ -554,6 +567,10 @@ export default {
|
||||
() => {
|
||||
this.$refs.calendar.resetEventLoader();
|
||||
},
|
||||
() => {
|
||||
this.$refs.calendar.clearOutCalendarEventEmphasis();
|
||||
this.$refs.calendar.resetEventLoader();
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@@ -571,7 +588,8 @@ export default {
|
||||
if (!dates) return;
|
||||
|
||||
if (
|
||||
luxon.DateTime.fromISO(obj.orig.isostart).toMillis() === dates.startDT.toMillis() &&
|
||||
luxon.DateTime.fromISO(obj.orig.isostart).toMillis() ===
|
||||
dates.startDT.toMillis() &&
|
||||
luxon.DateTime.fromISO(obj.orig.isoend).toMillis() ===
|
||||
dates.endDT.toMillis()
|
||||
)
|
||||
@@ -617,6 +635,16 @@ export default {
|
||||
this.$refs.calendar.resetEventLoader();
|
||||
this.bcc.postMessage("dropped");
|
||||
},
|
||||
() => {
|
||||
this.$refs.calendar.clearOutCalendarEventEmphasis();
|
||||
this.updateKalenderEventElementDisplay(
|
||||
obj.orig.kalender_id,
|
||||
luxon.DateTime.fromISO(obj.orig.isostart),
|
||||
luxon.DateTime.fromISO(obj.orig.isoend)
|
||||
);
|
||||
this.$refs.calendar.clearOutCalendarEventEmphasis();
|
||||
this.$refs.calendar.resetEventLoader();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
alert("Unbekannter Drop-Typ: " + obj.type);
|
||||
@@ -886,29 +914,7 @@ export default {
|
||||
scrollToAndEmphasizeUpdatedEvent() {
|
||||
if (!this.currentlyUpdatedEvent) return;
|
||||
|
||||
document
|
||||
.querySelectorAll(".fhc-calendar-base-grid .part-body")
|
||||
.forEach((el) => {
|
||||
el.classList.remove("deemphasized-event", "deemphasized-event-long");
|
||||
});
|
||||
document
|
||||
.querySelectorAll(
|
||||
".fhc-calendar-base-grid .fhc-calendar-base-grid-line-event",
|
||||
)
|
||||
.forEach((el) => {
|
||||
const spinner = el.querySelector(".spinner-overlay");
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
|
||||
el.classList.remove(
|
||||
"updating-event",
|
||||
"updated-event",
|
||||
"updated-event-long",
|
||||
"deemphasized-event",
|
||||
"deemphasized-event-long",
|
||||
);
|
||||
});
|
||||
this.$refs.calendar.clearOutCalendarEventEmphasis();
|
||||
|
||||
setTimeout(() => {
|
||||
const eventEl = document.querySelector(
|
||||
@@ -958,34 +964,32 @@ export default {
|
||||
el.classList.add(deemphasizedUpdateClassName);
|
||||
}
|
||||
});
|
||||
document
|
||||
.querySelectorAll(".fhc-calendar-base-grid .part-body")
|
||||
.forEach((el) => {
|
||||
if (el !== eventEl) {
|
||||
el.classList.add(deemphasizedUpdateClassName);
|
||||
}
|
||||
});
|
||||
}, timeout);
|
||||
|
||||
this.currentlyUpdatedEvent = null;
|
||||
}, 100);
|
||||
},
|
||||
updateKalenderEventElementDisplay(calendarId, startDT, endDT) {
|
||||
if (!calendarId) return alert("Kein gültiges Kalender-Event zum Resizen");
|
||||
if (!calendarId) return;
|
||||
|
||||
let newPotentialStart =
|
||||
startDT.diff(luxon.DateTime.fromISO("2026-06-22T00:00")).toMillis() ??
|
||||
1;
|
||||
let newPotentialEnd = endDT
|
||||
.diff(luxon.DateTime.fromISO("2026-06-22T00:00"))
|
||||
.toMillis();
|
||||
let startOfDay = startDT.startOf("day");
|
||||
let newPotentialStart = startDT.diff(startOfDay).toMillis() ?? 1;
|
||||
let newPotentialEnd = endDT.diff(startOfDay).toMillis();
|
||||
|
||||
let element = document.querySelector(`[data-id="event-${calendarId}"]`);
|
||||
if (!element) return alert("Kein gültiges Kalender-Event zum Resizen");
|
||||
if (!element) return;
|
||||
|
||||
const calendarView = element.closest(".fhc-calendar-mode-week-view");
|
||||
const targetGridLine = calendarView?.querySelector(
|
||||
`.fhc-calendar-base-grid-line[data-day="${startOfDay.toISODate()}"]`,
|
||||
);
|
||||
if (!targetGridLine)
|
||||
return alert("Kein gültiger Kalendertag zum Verschieben gefunden");
|
||||
|
||||
setTimeout(() => {
|
||||
element.style.gridRowEnd = "t_" + newPotentialEnd;
|
||||
targetGridLine.appendChild(element);
|
||||
element.style.gridRowStart = "t_" + newPotentialStart;
|
||||
element.style.gridRowEnd = "t_" + newPotentialEnd;
|
||||
}, 100);
|
||||
|
||||
const outerDiv = document.createElement("div");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
BASE_URL=https://demo.dev.technikum-wien.at/demoanon
|
||||
USER_NAME=demoadmin
|
||||
USER_PASSWORD=Demo
|
||||
LOGIN_AS_USER=demoadmin
|
||||
USER_NAME=testUser
|
||||
USER_PASSWORD=testPassword
|
||||
LOGIN_AS_USER=testUser
|
||||
|
||||
@@ -81,7 +81,9 @@ context("Tempus course picker tests", () => {
|
||||
waitForOk("@fetchPlanData");
|
||||
|
||||
tempusPage.waitForCalendarToFinishLoading();
|
||||
|
||||
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("@initialEventCount").then((initialEventCount) => {
|
||||
tempusPage
|
||||
.getCalendarEvents()
|
||||
|
||||
@@ -55,7 +55,7 @@ context("Tempus event mutation tests", () => {
|
||||
.getCalendarEventById(eventId)
|
||||
.should("be.visible")
|
||||
.rightclick();
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click();
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click({ force: true });
|
||||
waitForOk("@fetchRoomSuggestions");
|
||||
|
||||
tempusPage
|
||||
@@ -86,6 +86,8 @@ context("Tempus event mutation tests", () => {
|
||||
tempusPage.waitForCalendarToFinishLoading();
|
||||
|
||||
cy.get("@newRoom").then((newRoom) => {
|
||||
console.log(eventId)
|
||||
console.log(newRoom)
|
||||
cy.get("@updatedEventId").then((updatedEventId) => {
|
||||
tempusPage.expectCalendarEventRoom(updatedEventId, newRoom);
|
||||
|
||||
@@ -131,7 +133,7 @@ context("Tempus event mutation tests", () => {
|
||||
.scrollIntoView()
|
||||
.should("be.visible")
|
||||
.rightclick();
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click();
|
||||
tempusPage.getEventContextMenuOption("Raumauswahl").click({ force: true });
|
||||
waitForOk("@fetchRoomSuggestions");
|
||||
|
||||
tempusPage
|
||||
|
||||
@@ -287,7 +287,7 @@ class TempusPage {
|
||||
.contains(".bootstrap-modal.show .modal-title", "Raumauswahl")
|
||||
.closest(".bootstrap-modal.show");
|
||||
getRaumauswahlRoomOptions = () =>
|
||||
this.getRaumauswahlModal().find(".list-group-item");
|
||||
this.getRaumauswahlModal().find(".list-group-item span");
|
||||
getResourcesModal = () =>
|
||||
cy
|
||||
.get("[data-cy='resourcesAssignmentModal']")
|
||||
@@ -378,6 +378,7 @@ class TempusPage {
|
||||
|
||||
setCurrentSemester = () => {
|
||||
this.getSemesterSetterButton().click();
|
||||
waitForOk("@getCurrentSemester");
|
||||
};
|
||||
|
||||
dropEventOnCalendarPart = (eventId, partIndex, options = {}) => {
|
||||
|
||||
Reference in New Issue
Block a user