Skip to content

Commit

Permalink
improved directives
Browse files Browse the repository at this point in the history
  • Loading branch information
mono424 committed Sep 15, 2023
1 parent 8090778 commit c810b4c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
28 changes: 20 additions & 8 deletions web/assets/init-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ document.addEventListener("alpine:init", () => {
if (!data[fieldName]) {
el.value = "";
}
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: data[fieldName] } }));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand All @@ -110,7 +110,7 @@ document.addEventListener("alpine:init", () => {

const onChangeSetUpdateHandler = (data) => {
el.checked = !!data[fieldName];
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: !!data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: !!data[fieldName] }}));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand All @@ -127,7 +127,7 @@ document.addEventListener("alpine:init", () => {

const onChangeSetUpdateHandler = (data) => {
el.value = `${data[fieldName]}`;
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: data[fieldName] } }));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand All @@ -145,7 +145,7 @@ document.addEventListener("alpine:init", () => {

const onChangeSetUpdateHandler = (data) => {
el.value = `${data[fieldName]}`;
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: data[fieldName] }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value: data[fieldName] } }));
};

changeSet.listen(onChangeSetUpdateHandler);
Expand Down Expand Up @@ -186,7 +186,7 @@ document.addEventListener("alpine:init", () => {
if (modifiers.includes("text")) {
el.innerText = `${value}`;
}
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: value }));
el.dispatchEvent(new CustomEvent(nativeEventName, { detail: { changeSet, value } }));
};

onChangeSetUpdateHandler(changeSet.get());
Expand All @@ -208,7 +208,9 @@ document.addEventListener("alpine:init", () => {
* - expression: The JavaScript expression to be evaluated when the "csupdate" event is triggered.
*
* Modifiers:
* - "init": When provided, the directive will also execute the expression during initialization.
* - "init": When provided, the directive will execute the expression during initialization (no matter if its dirty or clean).
* - "clean": When provided, the directive will only execute if changeSet is not dirty.
* - "dirty": When provided, the directive will only execute if changeSet is dirty.
*
* Example usage:
* <div x-change-set-listen="sectionEditChangeSet"
Expand All @@ -218,11 +220,21 @@ document.addEventListener("alpine:init", () => {
Alpine.directive("on-change-set-update", (el, { expression, modifiers }, { evaluateLater, cleanup }) => {
const onUpdate = evaluateLater(expression);

const onChangeSetUpdateHandler = () => onUpdate();
const onChangeSetUpdateHandler = (e) => {
const isDirty = e.detail.changeSet.isDirty();

if (modifiers.includes("clean") && isDirty) {
return;
}
if (modifiers.includes("dirty") && !isDirty) {
return;
}
onUpdate();
};
el.addEventListener(nativeEventName, onChangeSetUpdateHandler);

if (modifiers.includes("init")) {
onChangeSetUpdateHandler();
onUpdate();
}

cleanup(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@
<div class="">
<div class="grid gap-2">
<template x-for="section in lectureData.videoSections" :key="sectionKey(section)">
<div x-data="{ sectionEditChangeSet: new admin.ChangeSet(section), editMode: false }" class="w-full border dark:border-gray-600 rounded">
<div x-data="{ sectionEditChangeSet: new admin.ChangeSet(section), editMode: false }" class="w-full border dark:border-gray-600 rounded"
x-change-set-listen="sectionEditChangeSet"
x-on-change-set-update.clean="updateSection(sectionEditChangeSet.get())"
>
<template x-if="!editMode">
<div class="p-1 flex items-center justify-start">
<div class="text-sky-800 bg-sky-200 text-xs dark:text-indigo-200 dark:bg-indigo-800 p-1 rounded"
Expand Down
21 changes: 20 additions & 1 deletion web/ts/edit-course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,23 @@ export function lectureEditor(lecture: Lecture): AlpineComponent {
const customComparator = comparatorPipeline([
ignoreKeys(["files"]),
singleProperty("videoSections", (a: Lecture, b: Lecture): boolean | null => {
// List length differs, something was removed or added
if (a.videoSections.length !== b.videoSections.length) {
return true;
}
if (a.videoSections.some(({ id }) => !b.videoSections.some(({ id: bId }) => id === bId))) {

// List length is the same but items do have no id, so they are new.
if (a.videoSections.some(({ id }) => id === undefined) || b.videoSections.some(({ id }) => id === undefined)) {
return true;
}

// A section has edited and different information now
return (a.videoSections.some((sectionA) => b.videoSections.some((sectionB) => {
return sectionA.id === sectionB.id && (
sectionA.description !== sectionB.description ||
videoSectionTimestamp(sectionA) !== videoSectionTimestamp(sectionB)
);
})));
}),
]);

Expand Down Expand Up @@ -220,6 +231,14 @@ export function lectureEditor(lecture: Lecture): AlpineComponent {
this.changeSet.patch("videoSections", [...this.lectureData.videoSections, section].sort(videoSectionSort));
},

updateSection(section: VideoSection) {
const sectionKey = this.sectionKey(section);
this.changeSet.patch("videoSections", [
...this.lectureData.videoSections.filter((s) => sectionKey !== this.sectionKey(s)),
section
].sort(videoSectionSort));
},

deleteSection(id: number) {
this.changeSet.patch(
"videoSections",
Expand Down

0 comments on commit c810b4c

Please sign in to comment.