normalized field settings argument name and multiple required tooltip

This commit is contained in:
Gani Georgiev
2026-06-08 09:50:49 +03:00
parent bff6b4c3ab
commit 77639f94ce
23 changed files with 232 additions and 233 deletions
+8 -8
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -20,9 +20,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -34,9 +34,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+14 -14
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -21,10 +21,10 @@ export function settings(data) {
type: "datetime-local",
id: uniqueId + ".min",
step: 1,
name: () => `fields.${data.fieldIndex}.min`,
value: () => app.utils.toDatetimeLocalInputValue(data.field.min),
name: () => `fields.${props.fieldIndex}.min`,
value: () => app.utils.toDatetimeLocalInputValue(props.field.min),
onchange: (e) => {
data.field.min = app.utils.toRFC3339Datetime(e.target.value);
props.field.min = app.utils.toRFC3339Datetime(e.target.value);
},
}),
),
@@ -38,10 +38,10 @@ export function settings(data) {
type: "datetime-local",
id: uniqueId + ".max",
step: 1,
name: () => `fields.${data.fieldIndex}.max`,
value: () => app.utils.toDatetimeLocalInputValue(data.field.max),
name: () => `fields.${props.fieldIndex}.max`,
value: () => app.utils.toDatetimeLocalInputValue(props.field.max),
onchange: (e) => {
data.field.max = app.utils.toRFC3339Datetime(e.target.value);
props.field.max = app.utils.toRFC3339Datetime(e.target.value);
},
}),
),
@@ -54,9 +54,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -68,9 +68,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+3 -3
View File
@@ -7,7 +7,7 @@
export function input(props) {
const uniqueId = "editor_" + app.utils.randomString();
const data = store({
const local = store({
lazyEditor: "",
});
@@ -18,7 +18,7 @@ export function input(props) {
className: "record-field-input field-type-editor large-modal",
onmount: () => {
lazyEditorTimeoutId = setTimeout(() => {
data.lazyEditor = app.components.tinymce({
local.lazyEditor = app.components.tinymce({
id: uniqueId,
name: () => props.field.name,
required: () => props.field.required,
@@ -41,7 +41,7 @@ export function input(props) {
t.i({ className: app.fieldTypes.editor.icon, ariaHidden: true }),
t.span({ className: "txt" }, () => props.field.name),
),
() => data.lazyEditor,
() => local.lazyEditor,
),
() => {
if (props.field.help) {
+14 -14
View File
@@ -5,14 +5,14 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
const local = store({
showInfo: false,
});
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -28,14 +28,14 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".maxSize",
name: () => `fields.${data.fieldIndex}.maxSize`,
name: () => `fields.${props.fieldIndex}.maxSize`,
min: 0,
step: 1,
max: Number.MAX_SAFE_INTEGER,
placeholder: "Default to max ~5MB",
value: () => data.field.maxSize || "",
value: () => props.field.maxSize || "",
oninput: (e) => {
data.field.maxSize = parseInt(e.target.value, 10);
props.field.maxSize = parseInt(e.target.value, 10);
},
}),
),
@@ -48,9 +48,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -62,9 +62,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
@@ -81,9 +81,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".convertURLs",
name: () => `fields.${data.fieldIndex}.convertURLs`,
checked: () => !!data.field.convertURLs,
onchange: (e) => (data.field.convertURLs = e.target.checked),
name: () => `fields.${props.fieldIndex}.convertURLs`,
checked: () => !!props.field.convertURLs,
onchange: (e) => (props.field.convertURLs = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".convertURLs" },
+16 -16
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -29,12 +29,12 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".exceptDomains",
disabled: () => !app.utils.isEmpty(data.field.onlyDomains),
name: () => `fields.${data.fieldIndex}.exceptDomains`,
value: () => app.utils.joinNonEmpty(data.field.exceptDomains),
disabled: () => !app.utils.isEmpty(props.field.onlyDomains),
name: () => `fields.${props.fieldIndex}.exceptDomains`,
value: () => app.utils.joinNonEmpty(props.field.exceptDomains),
onchange: (
e,
) => (data.field.exceptDomains = app.utils.splitNonEmpty(e.target.value, ",")),
) => (props.field.exceptDomains = app.utils.splitNonEmpty(e.target.value, ",")),
}),
),
t.div({ className: "field-help" }, "Use comma as separator."),
@@ -56,10 +56,10 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".onlyDomains",
disabled: () => !app.utils.isEmpty(data.field.exceptDomains),
name: () => `fields.${data.fieldIndex}.onlyDomains`,
value: () => app.utils.joinNonEmpty(data.field.onlyDomains),
onchange: (e) => (data.field.onlyDomains = app.utils.splitNonEmpty(e.target.value, ",")),
disabled: () => !app.utils.isEmpty(props.field.exceptDomains),
name: () => `fields.${props.fieldIndex}.onlyDomains`,
value: () => app.utils.joinNonEmpty(props.field.onlyDomains),
onchange: (e) => (props.field.onlyDomains = app.utils.splitNonEmpty(e.target.value, ",")),
}),
),
t.div({ className: "field-help" }, "Use comma as separator."),
@@ -72,9 +72,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -86,9 +86,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+38 -36
View File
@@ -5,7 +5,7 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
const isMultipleOptions = [
@@ -13,7 +13,7 @@ export function settings(data) {
{ label: "Multiple", value: true },
];
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
header: [
t.div(
{
@@ -23,15 +23,15 @@ export function settings(data) {
required: true,
options: isMultipleOptions,
value: () => {
return data.field.maxSelect > 1;
return props.field.maxSelect > 1;
},
onchange: (opts) => {
if (opts?.[0]?.value) {
if (!data.field.maxSelect || data.field.maxSelect < 2) {
data.field.maxSelect = 10;
if (!props.field.maxSelect || props.field.maxSelect < 2) {
props.field.maxSelect = 10;
}
} else {
data.field.maxSelect = 1;
props.field.maxSelect = 1;
}
},
}),
@@ -68,9 +68,9 @@ export function settings(data) {
),
};
}),
name: () => `fields.${data.fieldIndex}.mimeTypes`,
value: () => app.utils.toArray(data.field.mimeTypes),
onchange: (opts) => (data.field.mimeTypes = opts.map((opt) => opt.value)),
name: () => `fields.${props.fieldIndex}.mimeTypes`,
value: () => app.utils.toArray(props.field.mimeTypes),
onchange: (opts) => (props.field.mimeTypes = opts.map((opt) => opt.value)),
}),
),
t.div(
@@ -95,7 +95,7 @@ export function settings(data) {
className: "dropdown-item",
role: "menuitem",
onclick: (e) => {
data.field.mimeTypes = [
props.field.mimeTypes = [
"image/jpeg",
"image/png",
"image/svg+xml",
@@ -112,7 +112,7 @@ export function settings(data) {
className: "dropdown-item",
role: "menuitem",
onclick: (e) => {
data.field.mimeTypes = [
props.field.mimeTypes = [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
@@ -129,7 +129,7 @@ export function settings(data) {
className: "dropdown-item",
role: "menuitem",
onclick: (e) => {
data.field.mimeTypes = [
props.field.mimeTypes = [
"video/mp4",
"video/mpeg",
"video/x-msvideo",
@@ -146,7 +146,7 @@ export function settings(data) {
className: "dropdown-item",
role: "menuitem",
onclick: (e) => {
data.field.mimeTypes = [
props.field.mimeTypes = [
"application/zip",
"application/x-7z-compressed",
"application/x-rar-compressed",
@@ -160,7 +160,7 @@ export function settings(data) {
),
),
t.div(
{ className: () => (data.field.maxSelect > 1 ? "col-sm-6" : "col-sm-9") },
{ className: () => (props.field.maxSelect > 1 ? "col-sm-6" : "col-sm-9") },
t.div(
{ className: "field" },
t.label(
@@ -179,9 +179,9 @@ export function settings(data) {
type: "text",
id: uniqueId + ".thumbs",
placeholder: "e.g. 50x50, 480x720",
name: () => `fields.${data.fieldIndex}.thumbs`,
value: () => app.utils.joinNonEmpty(data.field.thumbs),
onchange: (e) => (data.field.thumbs = app.utils.splitNonEmpty(e.target.value, ",")),
name: () => `fields.${props.fieldIndex}.thumbs`,
value: () => app.utils.joinNonEmpty(props.field.thumbs),
onchange: (e) => (props.field.thumbs = app.utils.splitNonEmpty(e.target.value, ",")),
}),
),
t.div(
@@ -250,15 +250,15 @@ export function settings(data) {
min: 0,
max: Number.MAX_SAFE_INTEGER,
placeholder: "~5MB default",
name: () => `fields.${data.fieldIndex}.maxSize`,
value: () => data.field.maxSize || "",
oninput: (e) => (data.field.maxSize = parseInt(e.target.value, 10)),
name: () => `fields.${props.fieldIndex}.maxSize`,
value: () => props.field.maxSize || "",
oninput: (e) => (props.field.maxSize = parseInt(e.target.value, 10)),
}),
),
t.div({ className: "field-help" }, "In bytes."),
),
() => {
if (data.field.maxSelect > 1) {
if (props.field.maxSelect > 1) {
return t.div(
{ className: "col-sm-3" },
t.div(
@@ -272,14 +272,14 @@ export function settings(data) {
min: 2,
required: true,
max: Number.MAX_SAFE_INTEGER,
name: () => `fields.${data.fieldIndex}.maxSelect`,
value: () => data.field.maxSelect || "",
name: () => `fields.${props.fieldIndex}.maxSelect`,
value: () => props.field.maxSelect || "",
onchange: (e) => {
const maxSelect = parseInt(e.target.value, 10);
if (maxSelect > 1) {
data.field.maxSelect = maxSelect;
props.field.maxSelect = maxSelect;
} else {
data.field.maxSelect = 1;
props.field.maxSelect = 1;
}
},
}),
@@ -295,9 +295,9 @@ export function settings(data) {
className: "switch",
type: "checkbox",
id: uniqueId + ".protected",
name: () => `fields.${data.fieldIndex}.protected`,
checked: () => !!data.field.protected,
onchange: (e) => (data.field.protected = e.target.checked),
name: () => `fields.${props.fieldIndex}.protected`,
checked: () => !!props.field.protected,
onchange: (e) => (props.field.protected = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".protected" },
@@ -324,9 +324,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -338,17 +338,19 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
t.span({ className: "txt" }, "Required"),
t.small({ className: "txt-hint" }, "(!='')"),
t.small({ className: "txt-hint" }, () => props.field.maxSelect > 1 ? "(!=[])" : "(!='')"),
t.i({
className: "ri-information-line link-hint",
ariaDescription: app.attrs.tooltip("Requires the field value to be nonempty string"),
ariaDescription: app.attrs.tooltip(() =>
`Requires the field value to be nonempty ${props.field.maxSelect > 1 ? "array" : "string"}`
),
}),
),
),
+17 -17
View File
@@ -4,7 +4,7 @@
// get record: undefined,
// get field: undefined,
// }
export function input(data) {
export function input(props) {
const uniqueId = "geo_" + app.utils.randomString();
const local = store({
@@ -14,11 +14,11 @@ export function input(data) {
return t.div(
{ className: "record-field-input field-type-geoPoint" },
t.div(
{ className: () => `field-list ${data.field.required ? "required" : ""}` },
{ className: () => `field-list ${props.field.required ? "required" : ""}` },
t.label(
{ htmlFor: uniqueId },
t.i({ className: app.fieldTypes.geoPoint.icon, ariaHidden: true }),
t.span({ className: "txt" }, () => data.field.name),
t.span({ className: "txt" }, () => props.field.name),
),
t.div(
{ className: "field-list-content" },
@@ -36,12 +36,12 @@ export function input(data) {
min: -180,
max: 180,
placeholder: 0,
name: () => data.field.name,
required: () => data.field.required,
value: () => data.record[data.field.name]?.lon || "",
name: () => props.field.name,
required: () => props.field.required,
value: () => props.record[props.field.name]?.lon || "",
onchange: (e) => {
data.record[data.field.name] = data.record[data.field.name] || {};
data.record[data.field.name].lon = Number(e.target.value);
props.record[props.field.name] = props.record[props.field.name] || {};
props.record[props.field.name].lon = Number(e.target.value);
},
}),
),
@@ -56,12 +56,12 @@ export function input(data) {
min: -90,
max: 90,
placeholder: 0,
name: () => data.field.name,
required: () => data.field.required,
value: () => data.record[data.field.name]?.lat || "",
name: () => props.field.name,
required: () => props.field.required,
value: () => props.record[props.field.name]?.lat || "",
onchange: (e) => {
data.record[data.field.name] = data.record[data.field.name] || {};
data.record[data.field.name].lat = Number(e.target.value);
props.record[props.field.name] = props.record[props.field.name] || {};
props.record[props.field.name].lat = Number(e.target.value);
},
}),
),
@@ -87,9 +87,9 @@ export function input(data) {
return t.div(
{ className: "field-list-item p-0", style: "height: 250px" },
app.components.leaflet({
point: () => data.record[data.field.name] || { lat: 0, lon: 0 },
point: () => props.record[props.field.name] || { lat: 0, lon: 0 },
onchange: (newPoint) => {
data.record[data.field.name] = structuredClone(newPoint);
props.record[props.field.name] = structuredClone(newPoint);
},
}),
);
@@ -97,8 +97,8 @@ export function input(data) {
),
),
() => {
if (data.field.help) {
return t.div({ className: "field-help" }, data.field.help);
if (props.field.help) {
return t.div({ className: "field-help" }, props.field.help);
}
},
);
+8 -8
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -20,9 +20,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -34,9 +34,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+2 -2
View File
@@ -3,11 +3,11 @@
// field: undefined,
// short: false,
// }
export function view(data) {
export function view(props) {
return t.div(
{ className: "record-field-view field-type-geoPoint" },
t.span({ className: "label" }, () => {
const coords = data.record[data.field.name];
const coords = props.record[props.field.name];
return `${coords?.lon || 0}, ${coords?.lat || 0}`;
}),
);
+11 -11
View File
@@ -5,14 +5,14 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
const local = store({
showInfo: false,
});
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -28,14 +28,14 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".maxSize",
name: () => `fields.${data.fieldIndex}.maxSize`,
name: () => `fields.${props.fieldIndex}.maxSize`,
min: 0,
step: 1,
max: Number.MAX_SAFE_INTEGER,
placeholder: "Default to max ~1MB",
value: () => data.field.maxSize || "",
value: () => props.field.maxSize || "",
oninput: (e) => {
data.field.maxSize = parseInt(e.target.value, 10);
props.field.maxSize = parseInt(e.target.value, 10);
},
}),
),
@@ -48,9 +48,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -114,9 +114,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+20 -20
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -20,13 +20,13 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".min",
name: () => `fields.${data.fieldIndex}.min`,
value: () => typeof data.field.min == "number" ? data.field.min : "",
name: () => `fields.${props.fieldIndex}.min`,
value: () => typeof props.field.min == "number" ? props.field.min : "",
oninput: (e) => {
if (!e.target.value) {
data.field.min = null;
props.field.min = null;
} else {
data.field.min = Number(e.target.value);
props.field.min = Number(e.target.value);
}
},
}),
@@ -40,14 +40,14 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".max",
min: () => data.field.min,
name: () => `fields.${data.fieldIndex}.max`,
value: () => typeof data.field.max == "number" ? data.field.max : "",
min: () => props.field.min,
name: () => `fields.${props.fieldIndex}.max`,
value: () => typeof props.field.max == "number" ? props.field.max : "",
oninput: (e) => {
if (!e.target.value) {
data.field.max = null;
props.field.max = null;
} else {
data.field.max = Number(e.target.value);
props.field.max = Number(e.target.value);
}
},
}),
@@ -61,9 +61,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -75,9 +75,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
@@ -95,9 +95,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".onlyInt",
name: () => `fields.${data.fieldIndex}.onlyInt`,
checked: () => !!data.field.onlyInt,
onchange: (e) => (data.field.onlyInt = e.target.checked),
name: () => `fields.${props.fieldIndex}.onlyInt`,
checked: () => !!props.field.onlyInt,
onchange: (e) => (props.field.onlyInt = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".onlyInt" },
+22 -22
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
showHidden: false,
showPresentable: false,
showDuplicate: false,
@@ -29,14 +29,14 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".min",
name: () => `fields.${data.fieldIndex}.min`,
name: () => `fields.${props.fieldIndex}.min`,
step: 1,
min: 0,
max: 71,
placeholder: "No min limit",
value: () => data.field.min || "",
value: () => props.field.min || "",
oninput: (e) => {
data.field.min = parseInt(e.target.value, 10);
props.field.min = parseInt(e.target.value, 10);
},
}),
),
@@ -58,14 +58,14 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".max",
name: () => `fields.${data.fieldIndex}.max`,
name: () => `fields.${props.fieldIndex}.max`,
step: 1,
min: () => data.field.min || 0,
min: () => props.field.min || 0,
max: 71,
placeholder: "Up to 71 chars",
value: () => data.field.max || "",
value: () => props.field.max || "",
oninput: (e) => {
data.field.max = parseInt(e.target.value, 10);
props.field.max = parseInt(e.target.value, 10);
},
}),
),
@@ -87,15 +87,15 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".cost",
name: () => `fields.${data.fieldIndex}.cost`,
name: () => `fields.${props.fieldIndex}.cost`,
step: 1,
// https://pkg.go.dev/golang.org/x/crypto/bcrypt#pkg-constants
min: 4,
max: 31,
placeholder: "Default to 10",
value: () => data.field.cost || "",
value: () => props.field.cost || "",
oninput: (e) => {
data.field.cost = parseInt(e.target.value, 10);
props.field.cost = parseInt(e.target.value, 10);
},
}),
),
@@ -112,9 +112,9 @@ export function settings(data) {
type: "text",
id: uniqueId + ".pattern",
placeholder: "ex. ^\\w+$",
name: () => `fields.${data.fieldIndex}.pattern`,
value: () => data.field.pattern || "",
oninput: (e) => (data.field.pattern = e.target.value),
name: () => `fields.${props.fieldIndex}.pattern`,
value: () => props.field.pattern || "",
oninput: (e) => (props.field.pattern = e.target.value),
}),
),
),
@@ -126,16 +126,16 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
),
footer: () => {
// the system password auth field is always required
if (data.collection?.type == "auth" && data.field.name == "password") {
if (props.collection?.type == "auth" && props.field.name == "password") {
return;
}
@@ -146,9 +146,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+4 -2
View File
@@ -192,10 +192,12 @@ export function settings(props) {
t.label(
{ htmlFor: uniqueId + ".required" },
t.span({ className: "txt" }, "Required"),
t.small({ className: "txt-hint" }, "(!='')"),
t.small({ className: "txt-hint" }, () => props.field.maxSelect > 1 ? "(!=[])" : "(!='')"),
t.i({
className: "ri-information-line link-hint",
ariaDescription: app.attrs.tooltip("Requires the field value to be nonempty string"),
ariaDescription: app.attrs.tooltip(() =>
`Requires the field value to be nonempty ${props.field.maxSelect > 1 ? "array" : "string"}`
),
}),
),
),
+4 -9
View File
@@ -170,17 +170,12 @@ export function settings(props) {
t.label(
{ htmlFor: uniqueId + ".required" },
t.span({ className: "txt" }, "Required"),
t.small({
className: "txt-hint",
textContent: () => (props.field.maxSelect > 1 ? "(!=[])" : "(!='')"),
}),
t.small({ className: "txt-hint" }, () => props.field.maxSelect > 1 ? "(!=[])" : "(!='')"),
t.i({
className: "ri-information-line link-hint",
ariaDescription: app.attrs.tooltip(() => {
return `Requires the field value to be nonempty ${
props.field.maxSelect > 1 ? "array" : "string"
}.`;
}),
ariaDescription: app.attrs.tooltip(() =>
`Requires the field value to be nonempty ${props.field.maxSelect > 1 ? "array" : "string"}`
),
}),
),
),
+5 -5
View File
@@ -7,7 +7,7 @@
export function input(props) {
const uniqueId = "text_" + app.utils.randomString();
const data = store({
const local = store({
get hasAutogenerate() {
return !app.utils.isEmpty(props.field.autogeneratePattern) && app.utils.isEmpty(props.originalRecord?.id);
},
@@ -15,7 +15,7 @@ export function input(props) {
return !app.utils.isEmpty(props.originalRecord?.id) && props.field.primaryKey;
},
get isRequired() {
return props.field.required && !data.hasAutogenerate && !data.isDisabled;
return props.field.required && !local.hasAutogenerate && !local.isDisabled;
},
});
@@ -46,9 +46,9 @@ export function input(props) {
// className: "autoexpand",
rows: 1,
name: () => props.field.name,
required: () => data.isRequired,
disabled: () => data.isDisabled,
placeholder: () => (data.hasAutogenerate ? "Leave empty to autogenerate..." : ""),
required: () => local.isRequired,
disabled: () => local.isDisabled,
placeholder: () => (local.hasAutogenerate ? "Leave empty to autogenerate..." : ""),
value: () => props.record[props.field.name] || "",
oninput: (e) => (props.record[props.field.name] = e.target.value || ""),
}),
+22 -22
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -27,14 +27,14 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".min",
name: () => `fields.${data.fieldIndex}.min`,
name: () => `fields.${props.fieldIndex}.min`,
step: 1,
min: 0,
max: Number.MAX_SAFE_INTEGER,
placeholder: "No min limit",
value: () => data.field.min || "",
value: () => props.field.min || "",
oninput: (e) => {
data.field.min = parseInt(e.target.value, 10);
props.field.min = parseInt(e.target.value, 10);
},
}),
),
@@ -56,14 +56,14 @@ export function settings(data) {
t.input({
type: "number",
id: uniqueId + ".max",
name: () => `fields.${data.fieldIndex}.max`,
name: () => `fields.${props.fieldIndex}.max`,
step: 1,
min: () => data.field.min || 0,
min: () => props.field.min || 0,
max: Number.MAX_SAFE_INTEGER,
placeholder: "Default to max 5000 characters",
value: () => data.field.max || "",
value: () => props.field.max || "",
oninput: (e) => {
data.field.max = parseInt(e.target.value, 10);
props.field.max = parseInt(e.target.value, 10);
},
}),
),
@@ -76,7 +76,7 @@ export function settings(data) {
{ htmlFor: uniqueId + ".pattern" },
t.span({ className: "txt" }, "Validation pattern"),
() => {
if (data.field.primaryKey) {
if (props.field.primaryKey) {
return t.i({
className: "ri-information-line link-hint",
ariaDescription: app.attrs.tooltip(
@@ -89,9 +89,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".pattern",
name: () => `fields.${data.fieldIndex}.pattern`,
value: () => data.field.pattern || "",
oninput: (e) => (data.field.pattern = e.target.value),
name: () => `fields.${props.fieldIndex}.pattern`,
value: () => props.field.pattern || "",
oninput: (e) => (props.field.pattern = e.target.value),
}),
),
t.div({ className: "field-help" }, "Ex. ", t.code(null, "^[a-z0-9]+$")),
@@ -113,9 +113,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".autogeneratePattern",
name: () => `fields.${data.fieldIndex}.autogeneratePattern`,
value: () => data.field.autogeneratePattern || "",
oninput: (e) => (data.field.autogeneratePattern = e.target.value),
name: () => `fields.${props.fieldIndex}.autogeneratePattern`,
value: () => props.field.autogeneratePattern || "",
oninput: (e) => (props.field.autogeneratePattern = e.target.value),
}),
),
t.div({ className: "field-help" }, "Ex. ", t.code(null, "[a-z0-9]{30}")),
@@ -128,9 +128,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -142,9 +142,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },
+16 -16
View File
@@ -5,10 +5,10 @@
// get fieldIndex: int/-1,
// get originalField: undefined
// }
export function settings(data) {
export function settings(props) {
const uniqueId = "f_" + app.utils.randomString();
return app.components.fieldSettings(data, {
return app.components.fieldSettings(props, {
content: () =>
t.div(
{ className: "grid sm" },
@@ -29,12 +29,12 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".exceptDomains",
disabled: () => !app.utils.isEmpty(data.field.onlyDomains),
name: () => `fields.${data.fieldIndex}.exceptDomains`,
value: () => app.utils.joinNonEmpty(data.field.exceptDomains),
disabled: () => !app.utils.isEmpty(props.field.onlyDomains),
name: () => `fields.${props.fieldIndex}.exceptDomains`,
value: () => app.utils.joinNonEmpty(props.field.exceptDomains),
onchange: (
e,
) => (data.field.exceptDomains = app.utils.splitNonEmpty(e.target.value, ",")),
) => (props.field.exceptDomains = app.utils.splitNonEmpty(e.target.value, ",")),
}),
),
t.div({ className: "field-help" }, "Use comma as separator."),
@@ -56,10 +56,10 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".onlyDomains",
disabled: () => !app.utils.isEmpty(data.field.exceptDomains),
name: () => `fields.${data.fieldIndex}.onlyDomains`,
value: () => app.utils.joinNonEmpty(data.field.onlyDomains),
onchange: (e) => (data.field.onlyDomains = app.utils.splitNonEmpty(e.target.value, ",")),
disabled: () => !app.utils.isEmpty(props.field.exceptDomains),
name: () => `fields.${props.fieldIndex}.onlyDomains`,
value: () => app.utils.joinNonEmpty(props.field.onlyDomains),
onchange: (e) => (props.field.onlyDomains = app.utils.splitNonEmpty(e.target.value, ",")),
}),
),
t.div({ className: "field-help" }, "Use comma as separator."),
@@ -72,9 +72,9 @@ export function settings(data) {
t.input({
type: "text",
id: uniqueId + ".help",
name: () => `fields.${data.fieldIndex}.help`,
value: () => data.field.help || "",
oninput: (e) => (data.field.help = e.target.value),
name: () => `fields.${props.fieldIndex}.help`,
value: () => props.field.help || "",
oninput: (e) => (props.field.help = e.target.value),
}),
),
),
@@ -86,9 +86,9 @@ export function settings(data) {
className: "sm",
type: "checkbox",
id: uniqueId + ".required",
name: () => `fields.${data.fieldIndex}.required`,
checked: () => !!data.field.required,
onchange: (e) => (data.field.required = e.target.checked),
name: () => `fields.${props.fieldIndex}.required`,
checked: () => !!props.field.required,
onchange: (e) => (props.field.required = e.target.checked),
}),
t.label(
{ htmlFor: uniqueId + ".required" },