tsondb 0.7.10 → 0.7.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ import { getSerializedDisplayNameFromEntityInstance } from "../../shared/utils/d
7
7
  import { toTitleCase } from "../../shared/utils/string.js";
8
8
  import { validateLocaleIdentifier } from "../../shared/validation/identifier.js";
9
9
  import { deleteInstanceByEntityNameAndId, getChildInstancesForInstanceByEntityName, } from "../api/declarations.js";
10
+ import { EntitiesContext } from "../context/entities.js";
10
11
  import { GitClientContext } from "../context/gitClient.js";
11
12
  import { useEntityFromRoute } from "../hooks/useEntityFromRoute.js";
12
13
  import { useInstanceNamesByEntity } from "../hooks/useInstanceNamesByEntity.js";
@@ -28,6 +29,7 @@ export const InstanceRouteSkeleton = ({ mode, buttons, init, titleBuilder, onSub
28
29
  const [locales] = useSetting("displayedLocales");
29
30
  const [getDeclFromDeclName, declsLoaded] = useGetDeclFromDeclName();
30
31
  const { declaration: entity, isLocaleEntity } = useEntityFromRoute() ?? {};
32
+ const { entities } = useContext(EntitiesContext);
31
33
  const [instanceNamesByEntity] = useInstanceNamesByEntity();
32
34
  const [instanceContent, setInstanceContent] = useState();
33
35
  const [savedInstanceContent, setSavedInstanceContent] = useState();
@@ -73,6 +75,7 @@ export const InstanceRouteSkeleton = ({ mode, buttons, init, titleBuilder, onSub
73
75
  });
74
76
  }
75
77
  }, [entity, declsLoaded, getDeclFromDeclName, id, init, instanceContent, locales, name]);
78
+ const checkIsLocaleEntity = useCallback((entityName) => entities.some(entity => entity.declaration.name === entityName && entity.isLocaleEntity), [entities]);
76
79
  const handleSubmit = (event) => {
77
80
  event.preventDefault();
78
81
  if (entity && instanceContent !== undefined) {
@@ -144,5 +147,5 @@ export const InstanceRouteSkeleton = ({ mode, buttons, init, titleBuilder, onSub
144
147
  }
145
148
  }, children: "Delete" }))] }), !id && isLocaleEntity && (_jsxs("div", { class: "field field--id", children: [_jsx("label", { htmlFor: "id", children: "ID" }), _jsx("p", { className: "comment", children: "The instance\u2019s identifier. An IETF language tag (BCP47)." }), _jsx("input", { type: "text", id: "id", value: customId, required: true, pattern: "[a-z]{2,3}(-[A-Z]{2,3})?", placeholder: "en-US, de-DE, \u2026", onInput: event => {
146
149
  setCustomId(event.currentTarget.value);
147
- }, "aria-invalid": idErrors.length > 0 }), _jsx(ValidationErrors, { errors: idErrors })] })), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TypeInput, { type: entity.type, value: instanceContent, path: undefined, instanceNamesByEntity: instanceNamesByEntity, childInstances: childInstances, getDeclFromDeclName: getDeclFromDeclName, onChange: setInstanceContent, onChildChange: handleOnChildChange, onChildAdd: handleOnChildAdd, onChildRemove: handleOnChildRemove }), _jsx("div", { class: "form-footer btns", children: buttons.map(button => (_jsx("button", { type: "submit", name: button.name, class: button.primary ? "primary" : undefined, children: button.label }, button.name))) })] })] }));
150
+ }, "aria-invalid": idErrors.length > 0 }), _jsx(ValidationErrors, { errors: idErrors })] })), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TypeInput, { type: entity.type, value: instanceContent, path: undefined, instanceNamesByEntity: instanceNamesByEntity, childInstances: childInstances, getDeclFromDeclName: getDeclFromDeclName, onChange: setInstanceContent, onChildChange: handleOnChildChange, onChildAdd: handleOnChildAdd, onChildRemove: handleOnChildRemove, checkIsLocaleEntity: checkIsLocaleEntity }), _jsx("div", { class: "form-footer btns", children: buttons.map(button => (_jsx("button", { type: "submit", name: button.name, class: button.primary ? "primary" : undefined, children: button.label }, button.name))) })] })] }));
148
151
  };
@@ -1,10 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime";
2
2
  import { useContext } from "preact/hooks";
3
3
  import { GitContext } from "../context/git.js";
4
+ import { useSetting } from "../hooks/useSettings.js";
4
5
  import { Settings } from "./Settings.js";
5
6
  export const Layout = ({ breadcrumbs, children }) => {
6
- const [_, setIsGitOpen] = useContext(GitContext);
7
- return (_jsxs(_Fragment, { children: [_jsxs("header", { children: [_jsx("nav", { children: _jsx("ol", { children: breadcrumbs.map(({ url, label }) => (_jsx("li", { children: _jsx("a", { href: url, children: label }) }, url))) }) }), _jsxs("div", { class: "nav-buttons", children: [_jsx("button", { class: "git-toggle", onClick: () => {
7
+ const [_1, setIsGitOpen] = useContext(GitContext);
8
+ const [isGitAlwaysOpen, _2] = useSetting("gitSidebar");
9
+ return (_jsxs(_Fragment, { children: [_jsxs("header", { children: [_jsx("nav", { children: _jsx("ol", { children: breadcrumbs.map(({ url, label }) => (_jsx("li", { children: _jsx("a", { href: url, children: label }) }, url))) }) }), _jsxs("div", { class: "nav-buttons", children: [_jsx("button", { class: `git-toggle${!isGitAlwaysOpen ? " git-toggle--no-sidebar" : ""}`, onClick: () => {
8
10
  setIsGitOpen(b => !b);
9
11
  }, children: "File changes" }), _jsx(Settings, {})] })] }), _jsx("main", { children: children })] }));
10
12
  };
@@ -11,6 +11,7 @@ const localeMapper = (result) => result.instances;
11
11
  export const Settings = () => {
12
12
  const [locales, setLocales] = useSetting("displayedLocales");
13
13
  const [enumDisplay, setEnumDisplay] = useSetting("enumDisplay");
14
+ const [isGitAlwaysOpen, setIsGitAlwaysOpen] = useSetting("gitSidebar");
14
15
  const [isSettingsOpen, setIsSettingsOpen] = useState(false);
15
16
  const config = useContext(ConfigContext);
16
17
  const [localeInstances] = useMappedAPIResource(getLocaleInstances, localeMapper, locales, config.localeEntityName);
@@ -43,5 +44,7 @@ export const Settings = () => {
43
44
  setEnumDisplay("select");
44
45
  } }), _jsx("label", { htmlFor: "enum-display-select", children: "Compact (Dropdowns)" })] }), _jsxs("div", { className: "field--option", children: [_jsx("input", { type: "radio", name: "enum-display", id: "enum-display-radio", value: "radio", checked: enumDisplay === "radio", onChange: () => {
45
46
  setEnumDisplay("radio");
46
- } }), _jsx("label", { htmlFor: "enum-display-radio", children: "Expanded (all nested form fields in radio lists)" })] })] })] }));
47
+ } }), _jsx("label", { htmlFor: "enum-display-radio", children: "Expanded (all nested form fields in radio lists)" })] }), _jsx("h3", { children: "Version Control" }), _jsxs("div", { className: "field--option", children: [_jsx("input", { type: "checkbox", name: "git-sidebar-always-open", id: "git-sidebar-always-open", checked: isGitAlwaysOpen, onChange: () => {
48
+ setIsGitAlwaysOpen(v => !v);
49
+ } }), _jsx("label", { htmlFor: "git-sidebar-always-open", children: "Display as sidebar in larger viewports" })] })] })] }));
47
50
  };
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-ru
2
2
  import { useContext, useState } from "preact/hooks";
3
3
  import { GitContext } from "../../context/git.js";
4
4
  import { GitClientContext } from "../../context/gitClient.js";
5
+ import { useSetting } from "../../hooks/useSettings.js";
5
6
  import { ModalDialog } from "../ModalDialog.js";
6
7
  import { GitBranchManager } from "./GitBranchManager.js";
7
8
  import { GitFileManager } from "./GitFileManager.js";
@@ -9,6 +10,7 @@ export const Git = () => {
9
10
  const [isOpen, setIsOpen] = useContext(GitContext);
10
11
  const [mode, setMode] = useState("files");
11
12
  const client = useContext(GitClientContext);
13
+ const [isGitAlwaysOpen] = useSetting("gitSidebar");
12
14
  if (!client || !client.isRepo) {
13
15
  return null;
14
16
  }
@@ -40,7 +42,7 @@ export const Git = () => {
40
42
  default:
41
43
  return null;
42
44
  }
43
- })()] }), isOpen && mode === "files" ? null : (_jsxs("aside", { class: "git", children: [_jsx("h2", { class: "h1-faded", children: "Version Control" }), _jsx(GitFileManager, { client: client, manageBranches: () => {
45
+ })()] }), !isGitAlwaysOpen || (isOpen && mode === "files") ? null : (_jsxs("aside", { class: "git", children: [_jsx("h2", { class: "h1-faded", children: "Version Control" }), _jsx(GitFileManager, { client: client, manageBranches: () => {
44
46
  setIsOpen(true);
45
47
  setMode("branches");
46
48
  } })] }))] }));
@@ -7,7 +7,7 @@ import { Select } from "../Select.js";
7
7
  import { TypeInput } from "./TypeInput.js";
8
8
  import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
9
9
  export const NestedEntityMapTypeInput = props => {
10
- const { type, path, value, instanceNamesByEntity, disabled, getDeclFromDeclName, onChange } = props;
10
+ const { type, path, value, instanceNamesByEntity, disabled, getDeclFromDeclName, checkIsLocaleEntity, onChange, } = props;
11
11
  const [newKey, setNewKey] = useState("");
12
12
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
13
13
  return _jsx(MismatchingTypeError, { expected: "object", actual: value });
@@ -17,10 +17,11 @@ export const NestedEntityMapTypeInput = props => {
17
17
  .slice()
18
18
  .filter(instance => !existingKeys.includes(instance.id))
19
19
  .sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true }));
20
+ const isLocaleEntity = checkIsLocaleEntity(type.secondaryEntity);
20
21
  return (_jsxs("div", { class: "field field--container field--nestedentitymap", children: [existingKeys.length > 0 && (_jsx("ul", { children: Object.entries(value).map(([key, item]) => {
21
22
  const name = instanceNamesByEntity[type.secondaryEntity]?.find(instance => instance.id === key)
22
23
  ?.name ?? key;
23
- return (_jsxs("li", { class: "container-item dict-item", children: [_jsxs("div", { className: "container-item-header", children: [_jsx("div", { className: "container-item-title", children: _jsxs("span", { children: [_jsx("strong", { children: name }), " ", _jsx("span", { className: "id", children: key })] }) }), _jsx("div", { className: "btns", children: _jsxs("button", { class: "destructive", onClick: () => {
24
+ return (_jsxs("li", { class: "container-item dict-item", ...(isLocaleEntity ? { lang: key } : {}), children: [_jsxs("div", { className: "container-item-header", children: [_jsx("div", { className: "container-item-title", children: _jsxs("span", { children: [_jsx("strong", { children: name }), " ", _jsx("span", { className: "id", children: key })] }) }), _jsx("div", { className: "btns", children: _jsxs("button", { class: "destructive", onClick: () => {
24
25
  const newObj = { ...value };
25
26
  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
26
27
  delete newObj[key];
@@ -16,6 +16,7 @@ export type TypeInputProps<T, V = unknown> = {
16
16
  onChildChange: (index: number, value: unknown) => void;
17
17
  onChildAdd: (entityName: string, value: unknown) => void;
18
18
  onChildRemove: (index: number) => void;
19
+ checkIsLocaleEntity: (entityName: string) => boolean;
19
20
  };
20
21
  type Props = TypeInputProps<SerializedType>;
21
22
  declare const MemoizedTypeInput: FunctionComponent<Props>;
@@ -3,6 +3,7 @@ import {} from "../hooks/useSettings.js";
3
3
  export const defaultSettings = {
4
4
  displayedLocales: [],
5
5
  enumDisplay: "select",
6
+ gitSidebar: true,
6
7
  };
7
8
  export const SettingsContext = createContext({
8
9
  settings: defaultSettings,
@@ -5,6 +5,7 @@ import { SettingsContext } from "../context/settings.ts";
5
5
  export type UserSettings = {
6
6
  displayedLocales: string[];
7
7
  enumDisplay: "select" | "radio";
8
+ gitSidebar: boolean;
8
9
  };
9
10
  export declare const useSettings: (config: WebConfig) => SettingsContext;
10
11
  export declare const useSetting: <K extends keyof UserSettings>(key: K) => [UserSettings[K], Dispatch<SetStateAction<UserSettings[K]>>];
@@ -3,6 +3,7 @@ import { defaultSettings, SettingsContext } from "../context/settings.js";
3
3
  const settingsGuards = {
4
4
  displayedLocales: (v) => Array.isArray(v) && v.every(e => typeof e === "string") && v.length > 0,
5
5
  enumDisplay: (v) => typeof v === "string" && ["select", "radio"].includes(v),
6
+ gitSidebar: (v) => typeof v === "boolean",
6
7
  };
7
8
  const defaultSettingsFromConfig = (config) => ({
8
9
  ...defaultSettings,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsondb",
3
- "version": "0.7.10",
3
+ "version": "0.7.11",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "Lukas Obermann",
@@ -196,6 +196,24 @@ h3 {
196
196
  line-height: 1.2;
197
197
  }
198
198
 
199
+ h4 {
200
+ margin: 1.2rem 0 0.6rem;
201
+ font-size: 1.1rem;
202
+ line-height: 1.3;
203
+ }
204
+
205
+ h5 {
206
+ margin: 1rem 0 0.5rem;
207
+ font-size: 1rem;
208
+ line-height: 1.4;
209
+ }
210
+
211
+ h6 {
212
+ margin: 1rem 0 0.5rem;
213
+ font-size: 0.9rem;
214
+ line-height: 1.6;
215
+ }
216
+
199
217
  p {
200
218
  margin: 0.5rem 0;
201
219
  }
@@ -747,9 +765,10 @@ form > .field--container {
747
765
  padding: 1rem;
748
766
  background: var(--color-background-secondary);
749
767
  flex: 1 1 0;
768
+ line-height: 1.6;
750
769
  }
751
770
 
752
- .preview p {
771
+ .preview :is(p, ul, ol, table) {
753
772
  margin: 0.5rem 0 0;
754
773
  }
755
774
 
@@ -934,7 +953,7 @@ aside.git h2 {
934
953
  display: block;
935
954
  }
936
955
 
937
- .git-toggle {
956
+ .git-toggle:not(.git-toggle--no-sidebar) {
938
957
  display: none;
939
958
  }
940
959
  }