merge newui branch
This commit is contained in:
165
ui/src/base/ruleField.js
Normal file
165
ui/src/base/ruleField.js
Normal file
@@ -0,0 +1,165 @@
|
||||
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;
|
||||
};
|
||||
Reference in New Issue
Block a user