Skip to content

Commit

Permalink
fix: Kanban data refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
areknawo committed Jul 14, 2023
1 parent 899b255 commit 569ed8e
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 16 deletions.
28 changes: 15 additions & 13 deletions apps/web/src/context/cache/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { UseContentGroups, useContentGroups } from "./content-groups";
import { UseContentPieces, useContentPieces } from "./content-pieces";
import { UseOpenedContentPiece, useOpenedContentPiece } from "./opened-content-piece";
import { ParentComponent, createContext, onCleanup, useContext } from "solid-js";
import { ParentComponent, createContext, createEffect, on, onCleanup, useContext } from "solid-js";

interface CacheContextData {
useContentGroups(): UseContentGroups;
Expand All @@ -11,16 +11,21 @@ interface CacheContextData {

const CacheContext = createContext<CacheContextData>();
const CacheContextProvider: ParentComponent = (props) => {
let useContentGroupsCache: UseContentGroups | null = null;

const useContentGroupsCache = useContentGroups();
const useOpenedContentPieceCache = useOpenedContentPiece();

let useContentPiecesCache: Record<string, UseContentPieces> = {};

onCleanup(() => {
useContentGroupsCache = null;
useContentPiecesCache = {};
});
createEffect(
on(useContentGroupsCache.contentGroups, (contentGroups) => {
contentGroups.forEach(({ id }) => {
useContentPiecesCache[id] = useContentPiecesCache[id] || useContentPieces(id);
});
onCleanup(() => {
useContentPiecesCache = {};
});
})
);

return (
<CacheContext.Provider
Expand All @@ -29,13 +34,10 @@ const CacheContextProvider: ParentComponent = (props) => {
return useOpenedContentPieceCache;
},
useContentGroups() {
return useContentGroupsCache || (useContentGroupsCache = useContentGroups());
return useContentGroupsCache;
},
useContentPieces(contentGroupId: string) {
return (
useContentPiecesCache[contentGroupId] ||
(useContentPiecesCache[contentGroupId] = useContentPieces(contentGroupId))
);
useContentPieces(id: string) {
return useContentPieces(id);
}
}}
>
Expand Down
147 changes: 144 additions & 3 deletions apps/web/src/views/dashboard/column.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ContentPieceCard } from "./content-piece-card";
import { useColumnsContext } from "./columns-context";
import { Component, createEffect, createMemo, createSignal, For, on, Show } from "solid-js";
import {
Component,
createEffect,
createMemo,
createSignal,
For,
on,
onCleanup,
Show
} from "solid-js";
import {
mdiDotsVertical,
mdiFileDocumentPlus,
Expand All @@ -11,6 +20,7 @@ import {
mdiTrashCan
} from "@mdi/js";
import clsx from "clsx";
import { createStore } from "solid-js/store";
import {
Card,
IconButton,
Expand All @@ -27,7 +37,6 @@ import {
useNotificationsContext,
useConfirmationContext,
useUIContext,
useCacheContext,
hasPermission
} from "#context";
import { createRef } from "#lib/utils";
Expand All @@ -42,6 +51,139 @@ interface AddColumnProps {
class?: string;
}

interface UseContentPieces {
contentPieces(): Array<App.ExtendedContentPieceWithAdditionalData<"locked" | "order">>;
setContentPieces(
contentPieces: Array<App.ExtendedContentPieceWithAdditionalData<"locked" | "order">>
): void;
loading(): boolean;
loadMore(): void;
}

const useContentPieces = (contentGroupId: string): UseContentPieces => {
const { notify } = useNotificationsContext();
const { client } = useClientContext();
const [loading, setLoading] = createSignal(false);
const [moreToLoad, setMoreToLoad] = createSignal(true);
const [state, setState] = createStore<{
contentPieces: Array<App.ExtendedContentPieceWithAdditionalData<"locked" | "order">>;
}>({
contentPieces: []
});
const loadMore = (): void => {
const lastOrder = state.contentPieces[state.contentPieces.length - 1]?.order;

if (loading() || !moreToLoad()) return;

setLoading(true);
client.contentPieces.list.query({ contentGroupId, perPage: 20, lastOrder }).then((data) => {
setLoading(false);
setState("contentPieces", (contentPieces) => [...contentPieces, ...data]);
setMoreToLoad(data.length === 20);
});
};
const contentPiecesChanges = client.contentPieces.changes.subscribe(
{ contentGroupId },
{
onData({ action, data }) {
switch (action) {
case "delete":
setState("contentPieces", (contentPieces) => {
return contentPieces.filter((contentPiece) => {
return contentPiece.id !== data.id;
});
});
notify({ text: "Content piece deleted", type: "success" });
break;
case "create":
setState("contentPieces", (contentPieces) => [data, ...contentPieces]);
break;
case "update":
setState(
"contentPieces",
state.contentPieces.findIndex((contentPiece) => contentPiece.id === data.id),
(contentPiece) => ({ ...contentPiece, ...data })
);
break;
case "move":
setState("contentPieces", (contentPieces) => {
const currentIndex = contentPieces.findIndex(
(contentPiece) => data.contentPiece.id === contentPiece.id
);

if (currentIndex >= 0) {
if (contentGroupId === data.contentPiece.contentGroupId) {
const newContentPieces = [...contentPieces];

newContentPieces.splice(currentIndex, 1);

const previousReferenceIndex = newContentPieces.findIndex((contentPieces) => {
return contentPieces.id === data.previousReferenceId;
});

if (previousReferenceIndex >= 0) {
newContentPieces.splice(previousReferenceIndex, 0, data.contentPiece);
} else {
const nextReferenceIndex = newContentPieces.findIndex((contentPieces) => {
return contentPieces.id === data.nextReferenceId;
});

if (nextReferenceIndex >= 0) {
newContentPieces.splice(nextReferenceIndex + 1, 0, data.contentPiece);
} else if (!data.previousReferenceId && !data.nextReferenceId) {
newContentPieces.push(data.contentPiece);
}
}

return newContentPieces;
}

return contentPieces.filter((contentPiece) => {
return contentPiece.id !== data.contentPiece.id;
});
} else if (contentGroupId === data.contentPiece.contentGroupId) {
const newContentPieces = [...contentPieces];
const previousReferenceIndex = newContentPieces.findIndex((contentPieces) => {
return contentPieces.id === data.previousReferenceId;
});

if (previousReferenceIndex >= 0) {
newContentPieces.splice(previousReferenceIndex, 0, data.contentPiece);
} else {
const nextReferenceIndex = newContentPieces.findIndex((contentPieces) => {
return contentPieces.id === data.nextReferenceId;
});

if (nextReferenceIndex >= 0) {
newContentPieces.splice(nextReferenceIndex + 1, 0, data.contentPiece);
} else if (!data.previousReferenceId && !data.nextReferenceId) {
newContentPieces.push(data.contentPiece);
}
}

return newContentPieces;
}

return contentPieces;
});
break;
}
}
}
);

loadMore();
onCleanup(() => {
contentPiecesChanges.unsubscribe();
});

return {
contentPieces: () => state.contentPieces,
setContentPieces: (contentPieces) => setState("contentPieces", contentPieces),
loading,
loadMore
};
};
const AddColumn: Component<AddColumnProps> = (props) => {
const { client } = useClientContext();
const { notify } = useNotificationsContext();
Expand Down Expand Up @@ -74,7 +216,6 @@ const AddColumn: Component<AddColumnProps> = (props) => {
const Column: Component<ColumnProps> = (props) => {
const { notify } = useNotificationsContext();
const { confirmDelete } = useConfirmationContext();
const { useContentPieces } = useCacheContext();
const { setStorage } = useUIContext();
const { contentPieces, setContentPieces, loadMore, loading } = useContentPieces(
props.contentGroup.id
Expand Down

0 comments on commit 569ed8e

Please sign in to comment.