mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 07:05:24 +00:00
feat(homepage): synchronize canvas layouts across devices (#1515)
This commit is contained in:
1 parent
fdb2f74259
commit
7d06686f62
4 files changed
+145
-4
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { mapLayoutItemIds } from "./layout-item-ids.js";
|
||||
import type { Router } from "express";
|
||||
import type { PluginContext } from "@termix/plugin-sdk/backend";
|
||||
import {
|
||||
@@ -45,6 +46,27 @@ export async function activate(ctx: PluginContext) {
|
||||
order: 70,
|
||||
});
|
||||
|
||||
ctx.sync.registerEntity({
|
||||
type: "homepageLayouts",
|
||||
table: layouts,
|
||||
order: 81,
|
||||
singleton: true,
|
||||
serialize: async (row, resolveSyncId) => ({
|
||||
...row,
|
||||
layout: await mapLayoutItemIds(row.layout as string, async (id) =>
|
||||
typeof id === "number" && Number.isInteger(id)
|
||||
? resolveSyncId("homepageItems", id)
|
||||
: null,
|
||||
),
|
||||
}),
|
||||
deserialize: async (row, resolveId) => ({
|
||||
...row,
|
||||
layout: await mapLayoutItemIds(row.layout as string, async (id) =>
|
||||
typeof id === "string" ? resolveId("homepageItems", id) : null,
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
ctx.services.provide("homepage.items", createHomepageItemsService(ctx, repo));
|
||||
|
||||
ctx.log.info("Homepage routes mounted at /plugin-api/homepage");
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/** Canvas positions refer to local widget ids; only sync ids can cross devices. */
|
||||
export async function mapLayoutItemIds(
|
||||
layoutJson: string,
|
||||
mapId: (id: string | number) => Promise<string | number | null>,
|
||||
): Promise<string> {
|
||||
const layout = JSON.parse(layoutJson);
|
||||
if (!layout || typeof layout !== "object" || Array.isArray(layout)) {
|
||||
throw new Error("Invalid homepage layout");
|
||||
}
|
||||
if (layout.entries === undefined) return layoutJson;
|
||||
if (!Array.isArray(layout.entries))
|
||||
throw new Error("Invalid homepage layout entries");
|
||||
const entries = [];
|
||||
for (const entry of layout.entries) {
|
||||
if (!entry || typeof entry !== "object") continue;
|
||||
const id = entry.itemId;
|
||||
if (typeof id !== "string" && typeof id !== "number") continue;
|
||||
const itemId = await mapId(id);
|
||||
if (itemId !== null) entries.push({ ...entry, itemId });
|
||||
}
|
||||
return JSON.stringify({ ...layout, entries });
|
||||
}
|
||||
Reference in new issue
Block a user