From 77d2ad3b6b303d6b374c7506a325c7fa135f0b8a Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Fri, 28 Nov 2025 15:13:46 +0000 Subject: [PATCH] profiles: add ability to directly edit profile JSON allows for customizing small things, like changing admin status. --- Makefile | 14 +++++-- api-profiles.go | 10 +++-- css/base.css | 8 ++-- html/admin.html | 13 +++++++ html/syntaxhighlighting.html | 3 ++ lang/admin/en-us.json | 4 ++ package-lock.json | 21 ++++++++++ package.json | 2 + ts/admin.ts | 2 + ts/modules/common.ts | 8 +++- ts/modules/profiles.ts | 75 +++++++++++++++++++++++++++++++++++- ts/modules/theme.ts | 25 +++++++++++- ts/tsconfig.json | 3 +- ts/typings/d.ts | 1 + 14 files changed, 172 insertions(+), 17 deletions(-) create mode 100644 html/syntaxhighlighting.html diff --git a/Makefile b/Makefile index 591f279..a2c4b1a 100644 --- a/Makefile +++ b/Makefile @@ -160,18 +160,24 @@ $(VARIANTS_TARGET): $(VARIANTS_SRC) ICON_SRC = node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 ICON_TARGET = $(ICON_SRC:node_modules/remixicon/fonts/%=$(DATA)/web/css/%) -SYNTAX_SRC = node_modules/highlight.js/styles/default.min.css -SYNTAX_TARGET = $(DATA)/web/css/$(CSSVERSION)highlightjs.css +SYNTAX_LIGHT_SRC = node_modules/highlight.js/styles/base16/atelier-sulphurpool-light.min.css +SYNTAX_LIGHT_TARGET = $(DATA)/web/css/$(CSSVERSION)highlightjs-light.css +SYNTAX_DARK_SRC = node_modules/highlight.js/styles/base16/circus.min.css +SYNTAX_DARK_TARGET = $(DATA)/web/css/$(CSSVERSION)highlightjs-dark.css +CODEINPUT_SRC = node_modules/@webcoder49/code-input/code-input.min.css +CODEINPUT_TARGET = $(DATA)/web/css/$(CSSVERSION)code-input.css CSS_SRC = $(wildcard css/*.css) CSS_TARGET = $(DATA)/web/css/part-bundle.css CSS_FULLTARGET = $(CSS_BUNDLE) -ALL_CSS_SRC = $(ICON_SRC) $(CSS_SRC) $(SYNTAX_SRC) +ALL_CSS_SRC = $(ICON_SRC) $(CSS_SRC) $(SYNTAX_LIGHT_SRC) $(SYNTAX_DARK_SRC) ALL_CSS_TARGET = $(ICON_TARGET) $(CSS_FULLTARGET): $(TYPESCRIPT_TARGET) $(VARIANTS_TARGET) $(ALL_CSS_SRC) $(wildcard html/*.html) $(info copying fonts) cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 $(DATA)/web/css/ - cp -r $(SYNTAX_SRC) $(SYNTAX_TARGET) + cp -r $(SYNTAX_LIGHT_SRC) $(SYNTAX_LIGHT_TARGET) + cp -r $(SYNTAX_DARK_SRC) $(SYNTAX_DARK_TARGET) + cp -r $(CODEINPUT_SRC) $(CODEINPUT_TARGET) $(info bundling css) rm -f $(CSS_TARGET) $(CSS_FULLTARGET) $(ESBUILD) --bundle css/base.css --outfile=$(CSS_TARGET) --external:remixicon.css --external:../fonts/hanken* --minify diff --git a/api-profiles.go b/api-profiles.go index a8e3f50..1a710ad 100644 --- a/api-profiles.go +++ b/api-profiles.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "net/http" "net/url" "time" @@ -77,7 +78,7 @@ func (app *appContext) GetProfiles(gc *gin.Context) { // @Param name path string true "name of profile (url encoded if necessary)" // @Router /profiles/raw/{name} [get] // @Security Bearer -// @tags Users +// @tags Profiles & Settings func (app *appContext) GetRawProfile(gc *gin.Context) { escapedName := gc.Param("name") name, err := url.QueryUnescape(escapedName) @@ -95,7 +96,8 @@ func (app *appContext) GetRawProfile(gc *gin.Context) { // @Summary Update the raw data of a profile (Configuration, Policy, Jellyseerr/Ombi if applicable, etc.). // @Produce json // @Param ProfileDTO body ProfileDTO true "Raw profile data (all of it, do not omit anything)" -// @Success 200 {object} boolResponse +// @Success 204 {object} boolResponse +// @Success 201 {object} boolResponse // @Failure 400 {object} boolResponse // @Router /profiles/raw/{name} [put] // @Security Bearer @@ -118,6 +120,7 @@ func (app *appContext) ReplaceRawProfile(gc *gin.Context) { if req.Name == "" { req.Name = name } + status := http.StatusNoContent app.storage.SetProfileKey(req.Name, existingProfile) if req.Name != name { // Name change @@ -125,8 +128,9 @@ func (app *appContext) ReplaceRawProfile(gc *gin.Context) { if discordEnabled { app.discord.UpdateCommands() } + status = http.StatusCreated } - respondBool(200, true, gc) + respondBool(status, true, gc) } // @Summary Set the default profile to use. diff --git a/css/base.css b/css/base.css index 14de8f7..ea5ff77 100644 --- a/css/base.css +++ b/css/base.css @@ -235,7 +235,7 @@ sup.\~critical, .text-critical { margin-bottom: 0.25rem; } -.textarea { +.textarea:not(code-input *) { resize: vertical; } @@ -247,7 +247,7 @@ sup.\~critical, .text-critical { overflow-y: visible; } -select, textarea { +select, textarea:not(code-input *) { color: inherit; border: 0 solid var(--color-neutral-300); appearance: none; @@ -255,7 +255,7 @@ select, textarea { -moz-appearance: none; } -html.dark textarea { +html.dark textarea:not(code-input *) { background-color: #202020 } @@ -313,7 +313,7 @@ p.top { bottom: 115%; } -pre { +pre:not(code-input *) { white-space: pre-wrap; /* css-3 */ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ diff --git a/html/admin.html b/html/admin.html index 2be07c1..2d7c7b5 100644 --- a/html/admin.html +++ b/html/admin.html @@ -1,6 +1,7 @@ + {{ template "syntaxhighlighting.html" . }}