166 lines
4.8 KiB
JavaScript
166 lines
4.8 KiB
JavaScript
window.app = window.app || {};
|
|
window.app.components = window.app.components || {};
|
|
|
|
/**
|
|
* API rule input element.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* app.components.ruleField({
|
|
* name: "listRule",
|
|
* autocomplete: (word) => {
|
|
* return app.utils.collectionAutocompleteKeys(someCollection, word);
|
|
* },
|
|
* value: () => someCollection.listRule,
|
|
* oninput: (newVal) => someCollection.listRule = newVal,
|
|
* })
|
|
* ```
|
|
*
|
|
* @param {Object} [propsArg]
|
|
* @return {Element}
|
|
*/
|
|
window.app.components.ruleField = function(propsArg = {}) {
|
|
const uniqueId = "rule_" + app.utils.randomString();
|
|
|
|
const props = store({
|
|
rid: undefined,
|
|
id: undefined,
|
|
hidden: undefined,
|
|
inert: undefined,
|
|
className: "",
|
|
required: false,
|
|
disabled: false,
|
|
name: undefined,
|
|
label: undefined,
|
|
help: undefined,
|
|
value: null,
|
|
nullable: true,
|
|
placeholder: "Leave empty to grant everyone access...",
|
|
autocomplete: (word) => [],
|
|
oninput: (newVal) => {},
|
|
onmount: (el) => {},
|
|
onunmount: (el) => {},
|
|
// ---
|
|
get isLocked() {
|
|
return props.value == null;
|
|
},
|
|
});
|
|
|
|
const watchers = app.utils.extendStore(props, propsArg, "isLocked");
|
|
|
|
let ruleField;
|
|
let _prevValue = "";
|
|
|
|
function updateValue(newValue) {
|
|
props.value = newValue;
|
|
props.oninput?.(newValue);
|
|
ruleField?.dispatchEvent(new CustomEvent("change", { detail: newValue }));
|
|
}
|
|
|
|
function lock() {
|
|
if (props.value === null) {
|
|
return;
|
|
}
|
|
|
|
_prevValue = props.value;
|
|
updateValue(null);
|
|
}
|
|
|
|
function unlock() {
|
|
if (_prevValue != null) {
|
|
updateValue(_prevValue);
|
|
} else {
|
|
updateValue("");
|
|
}
|
|
|
|
setTimeout(() => {
|
|
document.getElementById(uniqueId)?.focus();
|
|
}, 0);
|
|
}
|
|
|
|
ruleField = t.div(
|
|
{
|
|
rid: props.rid,
|
|
id: () => props.id,
|
|
hidden: () => props.hidden,
|
|
inert: () => props.inert,
|
|
"html-name": () => props.name, // used for the error reset
|
|
className: () =>
|
|
[
|
|
"field",
|
|
"rule-field",
|
|
props.required ? "required" : null,
|
|
props.value === null ? "locked" : null,
|
|
props.disabled ? "disabled" : null,
|
|
].filter(Boolean).join(" "),
|
|
onmount: (el) => {
|
|
props.onmount?.(el);
|
|
},
|
|
onunmount: (el) => {
|
|
props.onunmount?.(el);
|
|
watchers.forEach((w) => w?.unwatch());
|
|
},
|
|
},
|
|
t.label(
|
|
{ htmlFor: uniqueId },
|
|
(el) => {
|
|
if (!props.label) {
|
|
return t.span({ className: "txt" }, "Rule");
|
|
}
|
|
|
|
if (typeof props.label == "function") {
|
|
return props.label(el);
|
|
}
|
|
|
|
if (typeof props.label == "string") {
|
|
return t.span({ className: "txt" }, props.label);
|
|
}
|
|
|
|
return props.label;
|
|
},
|
|
t.span({ hidden: () => !props.isLocked, className: "txt superusers-label" }, "(Superusers only)"),
|
|
),
|
|
(el) => {
|
|
if (props.isLocked) {
|
|
return t.button(
|
|
{
|
|
type: "button",
|
|
className: "unlock-overlay",
|
|
disabled: () => props.disabled,
|
|
onclick: unlock,
|
|
},
|
|
t.span({ className: "txt" }, "Unlock and set custom rule"),
|
|
t.i({ className: "ri-lock-unlock-line", ariaHidden: true }),
|
|
);
|
|
}
|
|
|
|
return [
|
|
app.components.codeEditor({
|
|
id: uniqueId,
|
|
language: "pbrule",
|
|
required: () => props.required,
|
|
disabled: () => props.disabled,
|
|
value: () => props.value,
|
|
oninput: updateValue,
|
|
placeholder: () => props.placeholder,
|
|
autocomplete: props.autocomplete,
|
|
autocompleteContainer: el,
|
|
}),
|
|
t.button(
|
|
{
|
|
hidden: () => !props.nullable,
|
|
type: "button",
|
|
className: "superuser-toggle",
|
|
disabled: () => props.disabled,
|
|
onclick: lock,
|
|
},
|
|
t.i({ className: "ri-lock-line", ariaHidden: true }),
|
|
t.span({ className: "txt" }, "Set superusers only"),
|
|
),
|
|
];
|
|
},
|
|
);
|
|
|
|
return ruleField;
|
|
};
|