@protobase/ui 0.39.0 → 0.39.1
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.
- package/dist/app/create/create-values.js +2 -2
- package/dist/app/messages.js +2 -0
- package/dist/app/record-page.js +3 -3
- package/dist/app/sensitive-field.js +5 -2
- package/dist/live/columns-from-model.js +2 -2
- package/dist/live/model-helpers.js +2 -1
- package/dist/package.js +1 -1
- package/dist/shell/assets/{app-BCgljtR4.js → app-tNKAme5F.js} +43 -43
- package/dist/shell/assets/{index-Dfo0EmgH.js → index-CO2YwMWQ.js} +2 -2
- package/dist/shell/assets/{records-map-DE5BswCb.js → records-map-CunB7LDy.js} +2 -2
- package/dist/shell/assets/{shared-protobase-ui-D3HUwrUp.js → shared-protobase-ui-B-n4PC6d.js} +2 -2
- package/dist/shell/index.html +3 -3
- package/dist/shell/protobase.shell.json +1 -1
- package/dist/shell/protobase.sw.js +2 -2
- package/dist/shell-source-maps/assets/{app-BCgljtR4.js.map → app-tNKAme5F.js.map} +1 -1
- package/dist/shell-source-maps/assets/{index-Dfo0EmgH.js.map → index-CO2YwMWQ.js.map} +1 -1
- package/dist/shell-source-maps/assets/{records-map-DE5BswCb.js.map → records-map-CunB7LDy.js.map} +1 -1
- package/dist/shell-source-maps/assets/{shared-protobase-ui-D3HUwrUp.js.map → shared-protobase-ui-B-n4PC6d.js.map} +1 -1
- package/package.json +4 -4
|
@@ -10,7 +10,7 @@ const isCreatable = (model, field) => field.name !== model.tenant && !field.read
|
|
|
10
10
|
/**
|
|
11
11
|
* The view's sections limited to creatable fields, plus a section for any creatable field the layout leaves out. The
|
|
12
12
|
* create form is a form, so sections and fields meant only for reading the record stay out of their sections, and a
|
|
13
|
-
* creatable field among them lands in that last section.
|
|
13
|
+
* creatable field among them lands in that last section. A write-only field is on the form only where a section names it.
|
|
14
14
|
*/
|
|
15
15
|
const createSections = (model, view) => {
|
|
16
16
|
const creatable = Object.values(model.fields).filter((field) => isCreatable(model, field)).map((field) => field.name);
|
|
@@ -25,7 +25,7 @@ const createSections = (model, view) => {
|
|
|
25
25
|
fields
|
|
26
26
|
}] : [];
|
|
27
27
|
});
|
|
28
|
-
const rest = creatable.filter((name) => !placed.has(name));
|
|
28
|
+
const rest = creatable.filter((name) => !placed.has(name) && !model.fields[name].writeOnly);
|
|
29
29
|
if (rest.length === 0) return sections;
|
|
30
30
|
return [...sections, {
|
|
31
31
|
title: sections.length === 0 ? text("details") : text("otherFields"),
|
package/dist/app/messages.js
CHANGED
|
@@ -52,6 +52,7 @@ const text = defineMessages({
|
|
|
52
52
|
show: (label) => `Show ${label}`,
|
|
53
53
|
hide: (label) => `Hide ${label}`,
|
|
54
54
|
couldNotShow: (label) => `Could not show the ${label}`,
|
|
55
|
+
setNewValue: "Set a new value",
|
|
55
56
|
noAnswer: "It did not answer.",
|
|
56
57
|
signInRefused: (message) => `It did not accept your sign-in: ${message}`,
|
|
57
58
|
loadingFrom: (label) => `Loading from ${label}`,
|
|
@@ -114,6 +115,7 @@ const text = defineMessages({
|
|
|
114
115
|
show: (label) => `${label} tonen`,
|
|
115
116
|
hide: (label) => `${label} verbergen`,
|
|
116
117
|
couldNotShow: (label) => `Kon ${label} niet tonen`,
|
|
118
|
+
setNewValue: "Nieuwe waarde instellen",
|
|
117
119
|
noAnswer: "Het antwoordde niet.",
|
|
118
120
|
signInRefused: (message) => `Het accepteerde je inlog niet: ${message}`,
|
|
119
121
|
loadingFrom: (label) => `Laden van ${label}`,
|
package/dist/app/record-page.js
CHANGED
|
@@ -80,7 +80,7 @@ const hidden = (model, name) => name === model.tenant || model.primaryKey.includ
|
|
|
80
80
|
*/
|
|
81
81
|
const layoutFor = (model, view, read) => {
|
|
82
82
|
if (view && view.layout.length > 0) return view.layout;
|
|
83
|
-
const shown = Object.values(model.fields).filter((field) => !hidden(model, field.name));
|
|
83
|
+
const shown = Object.values(model.fields).filter((field) => !hidden(model, field.name) && !field.writeOnly);
|
|
84
84
|
const editable = shown.filter((field) => !field.readOnly);
|
|
85
85
|
const fields = (editable.length > 0 && !read ? editable : shown).map((field) => field.name);
|
|
86
86
|
return [
|
|
@@ -222,7 +222,7 @@ const LoadedRecord = ({ model, recordKey, stored, preview }) => {
|
|
|
222
222
|
const status = hasStatus && !sidebarFields.includes("status") && statusValue !== null && statusValue !== void 0 && statusValue !== "" ? String(statusValue) : void 0;
|
|
223
223
|
const updatedAt = auditField(model, "updated");
|
|
224
224
|
const hint = (name) => view?.fields[name];
|
|
225
|
-
const visible = (name) => fieldAccess(stored.permissions, name) !== "hidden" && whenShown(hint(name)?.when, editing);
|
|
225
|
+
const visible = (name) => fieldAccess(stored.permissions, name) !== "hidden" && whenShown(hint(name)?.when, editing) && (shown === "form" || !model.fields[name]?.writeOnly);
|
|
226
226
|
const known = (name) => !preview || Object.hasOwn(stored.record, name);
|
|
227
227
|
const fieldView = (name) => {
|
|
228
228
|
const field = model.fields[name];
|
|
@@ -263,7 +263,7 @@ const LoadedRecord = ({ model, recordKey, stored, preview }) => {
|
|
|
263
263
|
},
|
|
264
264
|
locked: shown !== "form" || access === "read",
|
|
265
265
|
invalid: Boolean(editor.errors[name]),
|
|
266
|
-
reveal: field.sensitive ? () => client.reveal(model.name, recordKey, name) : void 0,
|
|
266
|
+
reveal: field.sensitive && !field.writeOnly ? () => client.reveal(model.name, recordKey, name) : void 0,
|
|
267
267
|
resource: model.name,
|
|
268
268
|
onChange: (next) => pick(name, next)
|
|
269
269
|
}) : /* @__PURE__ */ jsx(Skeleton, { className: "h-9" })
|
|
@@ -12,7 +12,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
12
12
|
import { useMutation } from "@tanstack/react-query";
|
|
13
13
|
//#region src/app/sensitive-field.tsx
|
|
14
14
|
const mask = "••••••••••";
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* A value hidden like a password. Showing a stored one asks the server for it, once per page visit; a write-only one has
|
|
17
|
+
* none to show, so its eye only unmasks what was typed.
|
|
18
|
+
*/
|
|
16
19
|
const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placeholder, onChange }) => {
|
|
17
20
|
const [shown, setShown] = useState(false);
|
|
18
21
|
const stored = useMutation({
|
|
@@ -56,7 +59,7 @@ const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placehol
|
|
|
56
59
|
invalid,
|
|
57
60
|
"aria-label": label,
|
|
58
61
|
className: cn(hints?.format === "code" && "font-mono text-xs"),
|
|
59
|
-
placeholder: typed || !reveal ? placeholder : mask,
|
|
62
|
+
placeholder: typed || !reveal ? placeholder ?? (field.writeOnly ? text("setNewValue") : void 0) : mask,
|
|
60
63
|
value: text$1,
|
|
61
64
|
trailing: eye,
|
|
62
65
|
onChange: (event) => onChange(event.target.value)
|
|
@@ -62,8 +62,8 @@ const kindOf = (field, view, index) => {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
const currencyCents = (value) => Math.round(Number.parseFloat(String(value)) * 100);
|
|
65
|
-
/** The fields a view's list shows as columns: its list columns, else the resource's first six fields. */
|
|
66
|
-
const listColumnNames = (resource, view) => view?.list?.columns ?? Object.
|
|
65
|
+
/** The fields a view's list shows as columns: its list columns, else the resource's first six fields the caller reads. */
|
|
66
|
+
const listColumnNames = (resource, view) => view?.list?.columns ?? Object.values(resource.fields).filter((field) => !field.writeOnly).slice(0, 6).map((field) => field.name);
|
|
67
67
|
/** Grid columns for `names`, by default the view's list: kinds follow the field types and the view's format hints. */
|
|
68
68
|
const columnsFromModel = (resource, view, highlight = [], names = listColumnNames(resource, view)) => {
|
|
69
69
|
const title = recordTitleField(resource, view);
|
|
@@ -9,8 +9,9 @@ const labelCandidates = [
|
|
|
9
9
|
"code",
|
|
10
10
|
"description"
|
|
11
11
|
];
|
|
12
|
+
const namesRecords = (field) => field?.type === "text" && !field.sensitive;
|
|
12
13
|
/** The field that names a record when another record points at it. */
|
|
13
|
-
const labelFieldOf = (model, view) => view?.title ?? labelCandidates.find((name) => model.fields[name]
|
|
14
|
+
const labelFieldOf = (model, view) => view?.title ?? labelCandidates.find((name) => namesRecords(model.fields[name])) ?? Object.values(model.fields).find(namesRecords)?.name ?? model.primaryKey[0];
|
|
14
15
|
/** What names a record: the view's `title`, else the first text column of its list, else `labelFieldOf`. */
|
|
15
16
|
const recordTitleField = (model, view) => view?.title ?? view?.list?.columns.find((name) => model.fields[name]?.type === "text") ?? labelFieldOf(model);
|
|
16
17
|
/** A record's name as shown: its title field's value, an enum's by its label, else `fallback` when the value is missing. */
|
package/dist/package.js
CHANGED