From 9f791ba28423c9525a1083446fb08b1c3c656d97 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 5 Sep 2026 13:33:40 +0200 Subject: [PATCH] Support Gitea configuration and safe Catalog Studio furniture completion --- Dockerfile | 3 + .../import/furni/nitro-editor-dialog.tsx | 226 +++++++++--------- src/app/admin/import/furni/nitro-editor.css | 63 +++++ .../studio/sync/catalog-export-client.tsx | 26 +- .../studio/sync/catalog-git-configuration.tsx | 169 +++++++++++++ src/app/admin/studio/sync/page.tsx | 8 +- .../admin/catalog-export/config/route.test.ts | 89 +++++++ .../api/admin/catalog-export/config/route.ts | 91 +++++++ src/app/api/admin/catalog-export/route.ts | 19 +- src/app/api/admin/import/furni/batch/route.ts | 1 + src/app/api/admin/import/furni/route.ts | 2 + src/components/admin/studio/import-review.tsx | 13 +- src/components/admin/studio/studio-client.tsx | 12 + src/lib/api-handler.ts | 4 +- src/lib/services/catalog-git-config.test.ts | 65 +++++ src/lib/services/catalog-git-config.ts | 177 ++++++++++++++ src/lib/services/catalog-git-core.ts | 3 +- src/lib/services/catalog-git-export.ts | 19 +- src/lib/services/catalog-git-managed.ts | 72 ++++++ src/lib/services/catalog-git-queue.ts | 36 ++- src/lib/services/furni-import-repair.test.ts | 120 ++++++++++ src/lib/services/furni-import.ts | 68 ++++-- 22 files changed, 1120 insertions(+), 166 deletions(-) create mode 100644 src/app/admin/import/furni/nitro-editor.css create mode 100644 src/app/admin/studio/sync/catalog-git-configuration.tsx create mode 100644 src/app/api/admin/catalog-export/config/route.test.ts create mode 100644 src/app/api/admin/catalog-export/config/route.ts create mode 100644 src/lib/services/catalog-git-config.test.ts create mode 100644 src/lib/services/catalog-git-config.ts create mode 100644 src/lib/services/catalog-git-managed.ts create mode 100644 src/lib/services/furni-import-repair.test.ts diff --git a/Dockerfile b/Dockerfile index 9c4e005130..252eb24392 100644 --- a/Dockerfile +++ b/Dockerfile @@ -71,6 +71,9 @@ RUN if [ "$PACKAGE_MANAGER" = "yarn" ] || { [ -z "$PACKAGE_MANAGER" ] && [ -f ya # --- Runtime stage --- FROM node:26.8.1-bookworm-slim AS runner +# Catalog Studio publishes to self-hosted Git repositories over HTTPS. +RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates && rm -rf /var/lib/apt/lists/* + # The CMS writes to bind-mounted host directories (/var/www/Gamedata is owned by # the host's www-data user, UID/GID 33). The node base image already ships a # www-data user with UID/GID 33, which matches that ownership — so we run as diff --git a/src/app/admin/import/furni/nitro-editor-dialog.tsx b/src/app/admin/import/furni/nitro-editor-dialog.tsx index 2fefe5c2a3..a4f0f8e973 100644 --- a/src/app/admin/import/furni/nitro-editor-dialog.tsx +++ b/src/app/admin/import/furni/nitro-editor-dialog.tsx @@ -1,4 +1,5 @@ "use client"; +import "./nitro-editor.css"; import { Box, @@ -240,6 +241,7 @@ export function NitroEditorDialog({ setMetadata(JSON.parse(JSON.stringify(originalMetadata))); setFlags({ ...originalFlags }); setJsonText(JSON.stringify(originalMetadata, null, 2)); + setJsonError(null); toast.info("Reset to original values"); }; @@ -334,7 +336,9 @@ export function NitroEditorDialog({ const hasChanges = metadata && originalMetadata && - (JSON.stringify(metadata) !== JSON.stringify(originalMetadata) || + ((activeTab === "json" + ? jsonText !== JSON.stringify(originalMetadata, null, 2) + : JSON.stringify(metadata) !== JSON.stringify(originalMetadata)) || JSON.stringify(flags) !== JSON.stringify(originalFlags)); // Furni preview URL @@ -344,13 +348,16 @@ export function NitroEditorDialog({ return ( - + {/* Header with preview */}
{/* Furni preview */}
{/* Dimensions + Interaction in 2-column layout */} -
- {/* Dimensions card */} -
-
- -

Dimensions

-
-
-
- - setDim("x", e.target.value)} - className="mt-1" - /> +
+
+ {/* Dimensions card */} +
+
+ +

Dimensions

-
- - setDim("y", e.target.value)} - className="mt-1" - /> +
+
+ + setDim("x", e.target.value)} + className="mt-1" + /> +
+
+ + setDim("y", e.target.value)} + className="mt-1" + /> +
+
+ + setDim("z", e.target.value)} + className="mt-1" + /> +
-
- - setDim("z", e.target.value)} - className="mt-1" - /> -
-
-
+
+ {/* Available rotations */} +
+
+ +

Directions

+ + {directions.length} / 8 active + +
+
+ {ALL_DIRECTIONS.map((dir) => ( + + ))} +
+

+ Choose the available rotations. Keep at least one + direction active. +

+
+
{/* Interaction card */}
@@ -506,6 +544,7 @@ export function NitroEditorDialog({
Can Stand On setFlags((f) => ({ ...f, canstandon: !!v })) @@ -515,6 +554,7 @@ export function NitroEditorDialog({
Can Sit On setFlags((f) => ({ ...f, cansiton: !!v })) @@ -524,6 +564,7 @@ export function NitroEditorDialog({
Can Lay On setFlags((f) => ({ ...f, canlayon: !!v })) @@ -581,58 +622,6 @@ export function NitroEditorDialog({
- {/* Directions - visual compass */} -
-
- -

Directions

- - {directions.length} active - -
-
-
- {/* Compass circle */} -
-
- {/* Direction buttons arranged in circle */} - {ALL_DIRECTIONS.map((dir) => { - const angle = (dir * 45 - 90) * (Math.PI / 180); - const r = 80; - const x = 96 + r * Math.cos(angle) - 18; - const y = 96 + r * Math.sin(angle) - 18; - const isActive = directions.includes(dir); - return ( - - ); - })} - {/* Center label */} -
- - {directions.length}/8 - -
-
-
-
- {/* Types */}
@@ -858,7 +847,8 @@ export function NitroEditorDialog({ >