diff --git a/pkgs/clan-cli/clan_cli/clan/create.py b/pkgs/clan-cli/clan_cli/clan/create.py index 2b2f244a..e198ffa0 100644 --- a/pkgs/clan-cli/clan_cli/clan/create.py +++ b/pkgs/clan-cli/clan_cli/clan/create.py @@ -33,7 +33,7 @@ class ClanMetaInfo: @dataclass class CreateOptions: - directory: Path + directory: Path | str # Metadata for the clan # Metadata can be shown with `clan show` meta: ClanMetaInfo | None = None @@ -43,7 +43,7 @@ class CreateOptions: @API.register def create_clan(options: CreateOptions) -> CreateClanResponse: - directory = options.directory + directory = Path(options.directory) template_url = options.template_url if not directory.exists(): directory.mkdir() diff --git a/pkgs/clan-cli/clan_cli/clan/update.py b/pkgs/clan-cli/clan_cli/clan/update.py new file mode 100644 index 00000000..4dcc33d7 --- /dev/null +++ b/pkgs/clan-cli/clan_cli/clan/update.py @@ -0,0 +1,35 @@ +import json +from dataclasses import dataclass +from pathlib import Path + +from clan_cli.api import API +from clan_cli.clan.create import ClanMetaInfo +from clan_cli.errors import ClanError + + +@dataclass +class UpdateOptions: + directory: str + meta: ClanMetaInfo | None = None + + +@API.register +def update_clan_meta(options: UpdateOptions) -> ClanMetaInfo: + meta_file = Path(options.directory) / Path("clan/meta.json") + if not meta_file.exists(): + raise ClanError( + "File not found", + description=f"Could not find {meta_file} to update.", + location="update_clan_meta", + ) + + meta_content: dict[str, str] = {} + with open(meta_file) as f: + meta_content = json.load(f) + + meta_content = {**meta_content, **options.meta.__dict__} + + with open(meta_file) as f: + json.dump(meta_content, f) + + return ClanMetaInfo(**meta_content) diff --git a/pkgs/webview-ui/app/eslint.config.mjs b/pkgs/webview-ui/app/eslint.config.mjs index 68dc5215..8a408bee 100644 --- a/pkgs/webview-ui/app/eslint.config.mjs +++ b/pkgs/webview-ui/app/eslint.config.mjs @@ -22,6 +22,9 @@ export default tseslint.config( whitelist: ["material-icons"], }, ], + // TODO: make this more strict by removing later + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "off", }, } ); diff --git a/pkgs/webview-ui/app/package-lock.json b/pkgs/webview-ui/app/package-lock.json index d33a88df..c1bef99a 100644 --- a/pkgs/webview-ui/app/package-lock.json +++ b/pkgs/webview-ui/app/package-lock.json @@ -9,6 +9,8 @@ "version": "0.0.1", "license": "MIT", "dependencies": { + "@modular-forms/solid": "^0.21.0", + "@tanstack/solid-query": "^5.44.0", "material-icons": "^1.13.12", "solid-js": "^1.8.11", "solid-toast": "^0.5.0" @@ -1004,6 +1006,17 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@modular-forms/solid": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@modular-forms/solid/-/solid-0.21.0.tgz", + "integrity": "sha512-9QUykslNeVvn/gBj4iXoiNPV1UutS8sOCPGoqBxCNBwVQVjfeMljvXU3kZtctWEMy984q7JtKVVGSOXMDydW6A==", + "dependencies": { + "valibot": ">=0.31.0 <1" + }, + "peerDependencies": { + "solid-js": "^1.3.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1535,6 +1548,31 @@ "node": ">=4" } }, + "node_modules/@tanstack/query-core": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.44.0.tgz", + "integrity": "sha512-Fa1J7iEEyJnjXG1N4+Fz4OXNH/INve3XSn0Htms3X4wgRsXHxMDwqBE2XtDCts7swkwSIs4izEtaFqWVFr/eLQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/solid-query": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/@tanstack/solid-query/-/solid-query-5.44.0.tgz", + "integrity": "sha512-fxsSFGbaHknL1zuymEZqrSRFk0wI3/RVDInlQJS3jZevnKJBAlDohIis6MZdm3EOFRTq+sfaMTNXZTu2B5MpOw==", + "dependencies": { + "@tanstack/query-core": "5.44.0", + "solid-js": "^1.8.17" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "solid-js": "^1.6.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -5819,6 +5857,11 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/valibot": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.31.1.tgz", + "integrity": "sha512-2YYIhPrnVSz/gfT2/iXVTrSj92HwchCt9Cga/6hX4B26iCz9zkIsGTS0HjDYTZfTi1Un0X6aRvhBi1cfqs/i0Q==" + }, "node_modules/validate-html-nesting": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", diff --git a/pkgs/webview-ui/app/package.json b/pkgs/webview-ui/app/package.json index 14e6c399..9bf4f256 100644 --- a/pkgs/webview-ui/app/package.json +++ b/pkgs/webview-ui/app/package.json @@ -37,6 +37,8 @@ "vitest": "^1.6.0" }, "dependencies": { + "@modular-forms/solid": "^0.21.0", + "@tanstack/solid-query": "^5.44.0", "material-icons": "^1.13.12", "solid-js": "^1.8.11", "solid-toast": "^0.5.0" diff --git a/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx b/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx index 50746c1b..beac427b 100644 --- a/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx +++ b/pkgs/webview-ui/app/src/routes/clan/clanDetails.tsx @@ -8,7 +8,12 @@ import { createEffect, createSignal, } from "solid-js"; -import cx from "classnames"; +import { + SubmitHandler, + createForm, + email, + required, +} from "@modular-forms/solid"; interface ClanDetailsProps { directory: string; @@ -23,9 +28,113 @@ interface MetaFieldsProps { const fn = (e: SubmitEvent) => { e.preventDefault(); - console.log(e.currentTarget); + console.log("form submit", e.currentTarget); }; +export default function Login() { + const [, { Form, Field }] = createForm({ + initialValues: { name: "MyClan" }, + }); + + const handleSubmit: SubmitHandler = (values, event) => { + pyApi.open_file.dispatch({ file_request: { mode: "save" } }); + pyApi.open_file.receive((r) => { + if (r.status === "success") { + if (r.data) { + pyApi.create_clan.dispatch({ + options: { directory: r.data, meta: values }, + }); + } + + return; + } + }); + console.log("submit", values); + }; + return ( +
+
+ + {(field, props) => ( + + )} + + + {(field, props) => ( + + )} + + + {(field, props) => ( + + )} + +
+ +
+
+
+ ); +} + export const EditMetaFields = (props: MetaFieldsProps) => { const { meta, editable, actions, directory } = props; @@ -41,8 +150,9 @@ export const EditMetaFields = (props: MetaFieldsProps) => { />
-
-

+ + {/* */} + {/*

{ {directory}

- {actions} - + {actions} */} + {/* */} ); diff --git a/pkgs/webview-ui/flake-module.nix b/pkgs/webview-ui/flake-module.nix index dc3e9212..0adbd223 100644 --- a/pkgs/webview-ui/flake-module.nix +++ b/pkgs/webview-ui/flake-module.nix @@ -11,7 +11,7 @@ npmDeps = pkgs.fetchNpmDeps { src = ./app; - hash = "sha256-NauXhPRKC80yiAeyt5mEBLcPZw3aheZDYXx4vLvpRvI="; + hash = "sha256-3LjcHh+jCuarh9XmS+mOv7xaGgAHxf3L7fWnxxmxUGQ="; }; # The prepack script runs the build script, which we'd rather do in the build phase. npmPackFlags = [ "--ignore-scripts" ];