nitropage
Version:
A free and open source, extensible visual page builder based on SolidStart.
123 lines (102 loc) • 3.98 kB
text/typescript
import { useAction, useNavigate, useSubmission } from "@solidjs/router";
import { startTransition, useContext } from "solid-js";
import { toast } from "../../../components/toast";
import { useUser } from "../../../lib/auth";
import { EditorUiContext, SettingsContext } from "../../../lib/context/admin";
import { StateContext } from "../../../lib/context/page";
import { makeOwnerBound } from "../../../lib/primitives/function";
import { attempt } from "../../../utils/attempt";
import { cloneDeep } from "../../../utils/object/clone";
import { publishPage, updatePage, useRouterPage } from "../../admin/data";
export const makeSavePageHandler = ({
stateContext = useContext(StateContext),
editorUiContext = useContext(EditorUiContext),
settingsContext = useContext(SettingsContext),
} = {}) => {
const page = useRouterPage();
const user = useUser();
const submitUpdatePage = useAction(updatePage);
const submitPublishPage = useAction(publishPage);
const updatingPage = useSubmission(updatePage);
const navigate = makeOwnerBound(useNavigate());
const [settings] = settingsContext!;
const [state] = stateContext!;
const [editorUi, setEditorUi] = editorUiContext!;
const handleSavePage = async (publish = false) => {
if (editorUi.saving) return;
const projectId = page()!.projectId;
const csrf = user()?.csrf!;
setEditorUi((d) => (d.saving = true));
const [error, success] = await attempt(
(async () => {
if (!editorUi.modification.dirty && publish) {
if (page()?.publishedRevisionId === editorUi.selectedRevisionId) {
return;
}
const [fetchError] = await attempt(
submitPublishPage(editorUi.selectedRevisionId),
);
if (fetchError) {
console.error("Error while publishing the page", fetchError);
toast(`Publishing the page failed. Please try again!`, {
description:
"Check your internet connection if it keeps failing.",
status: "error",
});
throw fetchError;
}
return true;
}
const [fetchError] = await attempt(
submitUpdatePage(csrf, {
publish,
pageId: page()!.id,
pageRevisionId: editorUi.selectedRevisionId,
prevState: editorUi.modification.initialState
? JSON.parse(editorUi.modification.initialState)
: undefined,
state: cloneDeep(state),
prevSettings: editorUi.modification.initialSettings
? JSON.parse(editorUi.modification.initialSettings)
: undefined,
settings: cloneDeep(settings),
}),
);
const result = updatingPage.result;
if (result && "error" in result) {
toast("Saving the page failed!", {
description: "The page you're trying to save, does not exist.",
status: "error",
});
navigate(`/admin/project/${projectId}`, {
replace: true,
});
throw result.error;
}
if (fetchError) {
console.error("Error while saving the page", fetchError);
toast(`Saving the page failed. Please try again!`, {
description: "Check your internet connection if it keeps failing.",
status: "error",
});
throw fetchError;
}
const nextRevisionId = result?.revisionId;
if (nextRevisionId && nextRevisionId !== editorUi.selectedRevisionId) {
await startTransition(function () {
setEditorUi((d) => (d.selectedRevisionId = nextRevisionId));
});
}
return true;
})(),
);
if (publish && success) {
toast(`Successfully published the page.`, {
status: "success",
});
}
setEditorUi((d) => (d.saving = false));
return !error;
};
return handleSavePage;
};