mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
fix/update form store, utils, jsdoc and components
* fix advanced form template condition (check if keys in object instead of if exists) * refactor store in order to avoid replace template when remount by adding a force param * form store now has a rawData variable to store misc elements, use this to store format raw data (from json) and retrive it when the component is unmount and mount again * replace computed to check validity by a regular function that run every time there is an editor input * add internal store function to format the template to key-value pair (setting_id-value) in order to send it on backend * check if there is at least one setting update to allow save on template (advanced and easy mode only) * enhance jsdoc by adding returns args and by enhancing params on stores * update builder and refactor store in order to check a prev_value key to determine if setting is update * submit now working on advanced and raw mode
This commit is contained in:
parent
7f26dd233b
commit
96f139e94d
15 changed files with 545 additions and 120 deletions
|
|
@ -529,6 +529,9 @@ def format_setting(
|
|||
setting_value["value"] = settings[setting_name].get("value", setting_value.get("value", setting_value.get("default")))
|
||||
setting_value["method"] = settings[setting_name].get("method", "ui")
|
||||
|
||||
# Add prev_value in order to check if value has changed to submit it
|
||||
setting_value["prev_value"] = setting_value.get("value")
|
||||
|
||||
# Then override by service settings
|
||||
if setting_name in settings:
|
||||
setting_value["disabled"] = False if settings[setting_name].get("method", "ui") in ("ui", "default", "manual") else True
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { plugin_types } from "@utils/variables";
|
|||
import { useAdvancedForm } from "@store/form.js";
|
||||
import { useCheckPluginsValidity } from "@utils/form.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
/**
|
||||
@name Form/Advanced.vue
|
||||
@description This component is used to create a complete advanced form with plugin selection.
|
||||
|
|
@ -190,13 +191,17 @@ const filters = [
|
|||
|
||||
function filter(filterData) {
|
||||
advancedForm.templateUIFormat = filterData;
|
||||
setValidity();
|
||||
updateStates();
|
||||
}
|
||||
|
||||
function updateStates() {
|
||||
data.plugins = getPluginNames(advancedForm.templateUIFormat);
|
||||
// Check after a filter if previous plugin is still in the list and if at least one plugin is available
|
||||
// Update if not the case
|
||||
data.currPlugin = data.plugins.includes(data.currPlugin)
|
||||
? data.currPlugin
|
||||
: getFirstPlugin(advancedForm.templateUIFormat);
|
||||
setValidity();
|
||||
}
|
||||
|
||||
function setValidity() {
|
||||
|
|
@ -231,13 +236,9 @@ function getPluginNames(template) {
|
|||
}
|
||||
|
||||
onMounted(() => {
|
||||
// SetTemplate only if first time we mount it
|
||||
advancedForm.setTemplate(props.template);
|
||||
// Get first props.forms template name
|
||||
data.currPlugin = getFirstPlugin(advancedForm.templateUIFormat);
|
||||
data.plugins = getPluginNames(advancedForm.templateUIFormat);
|
||||
setValidity();
|
||||
// Store update data on
|
||||
|
||||
updateStates();
|
||||
// I want updatInp to access event, data.base and the container attribut
|
||||
advancedForm.useListenTempFields();
|
||||
});
|
||||
|
|
@ -271,7 +272,7 @@ onUnmounted(() => {
|
|||
@inp="data.currPlugin = $event"
|
||||
/>
|
||||
</Filter>
|
||||
<MessageUnmatch v-if="!advancedForm.templateUIFormat.length" />
|
||||
<MessageUnmatch v-if="!Object.keys(advancedForm.templateUIFormat).length" />
|
||||
<template v-for="(plugin, pluginId) in advancedForm.templateUIFormat">
|
||||
<Container
|
||||
data-is="content"
|
||||
|
|
@ -301,15 +302,23 @@ onUnmounted(() => {
|
|||
</Container>
|
||||
</template>
|
||||
<Button
|
||||
v-if="advancedForm.templateUIFormat.length"
|
||||
v-if="Object.keys(advancedForm.templateUIFormat).length"
|
||||
v-bind="buttonSave"
|
||||
:disabled="data.isReqErr || data.isRegErr ? true : false"
|
||||
:disabled="
|
||||
data.isReqErr || data.isRegErr
|
||||
? true
|
||||
: advancedForm.isUpdateData
|
||||
? false
|
||||
: true
|
||||
"
|
||||
@click="advancedForm.submit()"
|
||||
/>
|
||||
<div class="flex justify-center items-center" data-is="form-error">
|
||||
<Text
|
||||
v-if="
|
||||
(advancedForm.templateUIFormat.length && data.isRegErr) ||
|
||||
(advancedForm.templateUIFormat.length && data.isReqErr)
|
||||
(Object.keys(advancedForm.templateUIFormat).length &&
|
||||
data.isRegErr) ||
|
||||
(Object.keys(advancedForm.templateUIFormat).length && data.isReqErr)
|
||||
"
|
||||
:text="
|
||||
data.isReqErr
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ import { useRawForm } from "@store/form.js";
|
|||
@example
|
||||
{
|
||||
"IS_LOADING": "no",
|
||||
"NGINX_PREFIX": "/etc/nginx/",
|
||||
"HTTP_PORT": "8080",
|
||||
"HTTPS_PORT": "8443",
|
||||
"MULTISITE": "yes"
|
||||
"NGINX_PREFIX": "/etc/nginx/",
|
||||
"HTTP_PORT": "8080",
|
||||
"HTTPS_PORT": "8443",
|
||||
"MULTISITE": "yes"
|
||||
}
|
||||
@param {object} template - Template object with plugin and settings data.
|
||||
@param {string} containerClass - Container
|
||||
|
|
@ -47,48 +47,48 @@ const props = defineProps({
|
|||
});
|
||||
|
||||
const data = reactive({
|
||||
str: "",
|
||||
// Check if the raw data is valid when trying to revert from raw to JSON
|
||||
// Case this is invalid, we will display an error message and disabled save button
|
||||
// Case this is valid, we will store the JSON in the store and enable the save button
|
||||
isValid: computed(() => {
|
||||
// Transform to a possible valid JSON
|
||||
let dataToCheck = data.str;
|
||||
// Replace quotes "" with quotes ''
|
||||
dataToCheck = dataToCheck.replace(/"/g, "'");
|
||||
|
||||
let isValidRaw = true;
|
||||
let jsonReady = "";
|
||||
|
||||
// loop on each line
|
||||
dataToCheck = dataToCheck.split("\n");
|
||||
dataToCheck = dataToCheck.map((line) => {
|
||||
// Get index of the first equal sign
|
||||
const index = line.indexOf("=");
|
||||
// Case no equal sign in a line, this is invalid
|
||||
if (index === -1) isValidRaw = false;
|
||||
|
||||
// Update at this index with a colon
|
||||
jsonReady +=
|
||||
'"' + line.slice(0, index) + '":"' + line.slice(index + 1) + '",';
|
||||
});
|
||||
|
||||
if (!isValidRaw) return false;
|
||||
|
||||
// Try to parse the JSON
|
||||
jsonReady = "{" + jsonReady.slice(0, -1) + "}";
|
||||
|
||||
try {
|
||||
const json = JSON.parse(jsonReady);
|
||||
rawForm.setTemplate(json);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
isValid: true,
|
||||
});
|
||||
|
||||
function updateRaw(v) {
|
||||
console.log("update");
|
||||
// Transform to a possible valid JSON
|
||||
rawForm.setRawData(v, true);
|
||||
let dataToCheck = v;
|
||||
// Replace quotes "" with quotes ''
|
||||
dataToCheck = dataToCheck.replace(/"/g, "'");
|
||||
|
||||
let isValidRaw = true;
|
||||
let jsonReady = "";
|
||||
|
||||
// loop on each line
|
||||
dataToCheck = dataToCheck.split("\n");
|
||||
dataToCheck = dataToCheck.map((line) => {
|
||||
// Get index of the first equal sign
|
||||
const index = line.indexOf("=");
|
||||
// Case no equal sign in a line, this is invalid
|
||||
if (index === -1) isValidRaw = false;
|
||||
|
||||
// Update at this index with a colon
|
||||
jsonReady +=
|
||||
'"' + line.slice(0, index) + '":"' + line.slice(index + 1) + '",';
|
||||
});
|
||||
|
||||
if (!isValidRaw) return (data.isValid = false);
|
||||
|
||||
// Try to parse the JSON
|
||||
jsonReady = "{" + jsonReady.slice(0, -1) + "}";
|
||||
|
||||
try {
|
||||
const json = JSON.parse(jsonReady);
|
||||
rawForm.setTemplate(json, true);
|
||||
data.isValid = true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
data.isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
function json2raw(json) {
|
||||
let dataStr = JSON.stringify(json);
|
||||
// Remove first and last curly brackets
|
||||
|
|
@ -133,7 +133,7 @@ const buttonSave = {
|
|||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
data.str = json2raw(props.template);
|
||||
rawForm.setRawData(json2raw(props.template));
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -151,12 +151,16 @@ onBeforeMount(() => {
|
|||
|
||||
<Container class="form-raw-editor-container layout-settings">
|
||||
<Editor
|
||||
@inp="(v) => (data.str = v)"
|
||||
@inp="(v) => updateRaw(v)"
|
||||
v-bind="editorData"
|
||||
:value="data.str"
|
||||
:value="rawForm.rawData"
|
||||
/>
|
||||
</Container>
|
||||
<Button :disabled="data.isValid ? false : true" v-bind="buttonSave" />
|
||||
<Button
|
||||
@click="rawForm.submit()"
|
||||
:disabled="data.isValid ? false : rawForm.isUpdateData ? false : true"
|
||||
v-bind="buttonSave"
|
||||
/>
|
||||
|
||||
<div class="flex justify-center items-center" data-is="form-error">
|
||||
<Text
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,13 +1,15 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import { useSubmitForm } from "@utils/form.js";
|
||||
|
||||
/**
|
||||
@name createFormStore
|
||||
@description This is a factory function that will create a form store.
|
||||
This store contains all the logic to manage the form template and update it.
|
||||
By defining the form type, this will update some function to avoid errors.
|
||||
@param storeName - Name of the store, must be unique.
|
||||
@param formType - Type of form, can be "advanced", "raw" or "easy".
|
||||
@param {string} storeName - Name of the store, must be unique.
|
||||
@param {string} formType - Type of form, can be "advanced", "raw" or "easy".
|
||||
@returns {store} - Return a form store with all the logic to manage the form template and update it.
|
||||
*/
|
||||
export const createFormStore = (storeName, formType) => {
|
||||
return defineStore(storeName, () => {
|
||||
|
|
@ -22,33 +24,44 @@ export const createFormStore = (storeName, formType) => {
|
|||
const templateUI = ref({});
|
||||
// UI template will keep the data that will be render on UI with additionnal format like filtering.
|
||||
const templateUIFormat = ref({});
|
||||
// Store any raw information that can be usefull for the form.
|
||||
const rawData = ref("");
|
||||
// Increment when some functions are updating template to force rerendering when attach to a component using the reactive value.
|
||||
const updateCount = ref(0);
|
||||
// After a submit attempt or an event listener updating a template, check if a date is updating (different from default and previous value).
|
||||
const isUpdateData = ref(false);
|
||||
// Data we gonna submit
|
||||
const formattedData = ref({});
|
||||
|
||||
/**
|
||||
@name setTemplate
|
||||
@description Set the template we are going to use to generate the form and update it (like adding multiples).
|
||||
@param template - Template with plugins list and detail settings
|
||||
@param {object} tempData - Template with plugins list and detail settings
|
||||
@param {boolean} [force=false] - Force to update the template even if already set before
|
||||
@returns {void}
|
||||
*/
|
||||
function setTemplate(template) {
|
||||
function setTemplate(tempData, force = false) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy", "raw"])) return;
|
||||
if (Object.keys(template.value).length > 0 && !force) return;
|
||||
// Unlink the template
|
||||
template.value = JSON.parse(JSON.stringify(tempData));
|
||||
templateBase.value = JSON.parse(JSON.stringify(tempData));
|
||||
templateUI.value = JSON.parse(JSON.stringify(tempData));
|
||||
templateUIFormat.value = templateUI.value;
|
||||
_updateTempState();
|
||||
}
|
||||
|
||||
const copyTemplate = JSON.parse(JSON.stringify(template));
|
||||
template.value = copyTemplate;
|
||||
templateBase.value = template;
|
||||
templateUI.value = template;
|
||||
templateUIFormat.value = template;
|
||||
|
||||
// console.log("template", type.value, template);
|
||||
// console.log(typeof template);
|
||||
// const formattedData = {};
|
||||
// // Loop dict items
|
||||
// for (const [key, value] of Object.entries(template)) {
|
||||
// // Case key "value" is here, we are directly on the right level (and maybe on the raw mode)
|
||||
// if (value?.value) {
|
||||
// }
|
||||
// console.log(key, value);
|
||||
// formattedData[key] = value;
|
||||
// if (!value?.settings || value?.multiples) continue;
|
||||
// }
|
||||
/**
|
||||
@name setRawData
|
||||
@description Set raw data that can be usefull for the form.
|
||||
@param {array} data - Template with plugins list and detail settings
|
||||
@param {boolean} [force=false] - Template with plugins list and detail settings
|
||||
@returns {void}
|
||||
*/
|
||||
function setRawData(data, force = false) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy", "raw"])) return;
|
||||
if (rawData.value && !force) return;
|
||||
rawData.value = data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -57,9 +70,10 @@ export const createFormStore = (storeName, formType) => {
|
|||
The way the backend is working is that to delete a group, we need to send the group name with all default values.
|
||||
This function needs to be call from the multiples component parent with the template and the group name to delete.
|
||||
We will update the values of the group to default values.
|
||||
@param pluginId - id of the plugin on the template array.
|
||||
@param multName - Input id to update
|
||||
@param groupName - Input value to update
|
||||
@param {string} pluginId - id of the plugin on the template array.
|
||||
@param {string} multName - Input id to update
|
||||
@param {string|number} groupName - Input value to update
|
||||
@returns {void}
|
||||
*/
|
||||
function delMultiple(pluginId, multName, groupName) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -79,6 +93,8 @@ export const createFormStore = (storeName, formType) => {
|
|||
// For UI, we can delete the group to avoid rendering it
|
||||
delete templateUI.value[index].multiples[multName][groupName];
|
||||
updateCount.value++;
|
||||
|
||||
_updateTempState();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,8 +102,9 @@ export const createFormStore = (storeName, formType) => {
|
|||
@description This function will add a group of multiple in the template with default values.
|
||||
Each plugin has a key "multiples_schema" with each multiples group and their default values.
|
||||
We will retrieve the wanted multiple group and add it on the "multiples" key that contains the multiples that apply to the plugin.
|
||||
@param pluginId - id of the plugin on the template array.
|
||||
@param multName - multiple group name to add
|
||||
@param {string} pluginId - id of the plugin on the template array.
|
||||
@param {string} multName - multiple group name to add
|
||||
@returns {void}
|
||||
*/
|
||||
function addMultiple(pluginId, multName) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -119,6 +136,7 @@ export const createFormStore = (storeName, formType) => {
|
|||
// We need to show the new group on UI too
|
||||
templateUI.value[index].multiples[multName][nextGroupId] = newMultiple;
|
||||
updateCount.value++;
|
||||
_updateTempState();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -130,6 +148,7 @@ export const createFormStore = (storeName, formType) => {
|
|||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
_useUpdateTemp(e, data.base);
|
||||
}
|
||||
@returns {void}
|
||||
*/
|
||||
function useListenTempFields() {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -147,6 +166,7 @@ export const createFormStore = (storeName, formType) => {
|
|||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
_useUpdateTemp(e, data.base);
|
||||
}
|
||||
@returns {void}
|
||||
*/
|
||||
function useUnlistenTempFields() {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -172,6 +192,7 @@ export const createFormStore = (storeName, formType) => {
|
|||
},
|
||||
];
|
||||
@param e - Event object, get it by default in the event listener.
|
||||
@returns {void}
|
||||
*/
|
||||
function _useUpdateTemp(e) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -208,6 +229,7 @@ export const createFormStore = (storeName, formType) => {
|
|||
// update settings
|
||||
_useUpdateTempSettings(templates, inpId, inpValue, e.target);
|
||||
_useUpdateTempMultiples(templates, inpId, inpValue, e.target);
|
||||
_updateTempState();
|
||||
}, 50);
|
||||
}
|
||||
|
||||
|
|
@ -216,9 +238,10 @@ export const createFormStore = (storeName, formType) => {
|
|||
@description This function will loop on template settings in order to update the setting value.
|
||||
This will check each plugin.settings (what I call regular) instead of other type of settings like multiples (in plugin.multiples).
|
||||
This function needs to be call in _useUpdateTemp.
|
||||
@param templates - Templates array with plugins list and detail settings
|
||||
@param inpId - Input id to update
|
||||
@param inpValue - Input value to update
|
||||
@param {array} templates - Templates array with plugins list and detail settings
|
||||
@param {string|number} inpId - Input id to update
|
||||
@param {string|number} inpValue - Input value to update
|
||||
@returns {void}
|
||||
*/
|
||||
function _useUpdateTempSettings(templates, inpId, inpValue, target) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -252,9 +275,10 @@ export const createFormStore = (storeName, formType) => {
|
|||
@description This function will loop on template multiples in order to update the setting value.
|
||||
This will check each plugin.multiples that can be found in the template.
|
||||
This function needs to be call in _useUpdateTemp.
|
||||
@param templates - Templates array with plugins list and detail settings
|
||||
@param inpId - Input id to update
|
||||
@param inpValue - Input value to update
|
||||
@param {array} templates - Templates array with plugins list and detail settings
|
||||
@param {string|number} inpId - Input id to update
|
||||
@param {string|number} inpValue - Input value to update
|
||||
@returns {void}
|
||||
*/
|
||||
function _useUpdateTempMultiples(templates, inpId, inpValue, target) {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy"])) return;
|
||||
|
|
@ -298,22 +322,101 @@ export const createFormStore = (storeName, formType) => {
|
|||
}
|
||||
|
||||
/**
|
||||
@name submitForm
|
||||
@description This function will format the template base on the form type in order to render a form to submit.
|
||||
The send data will change depending on the form type.
|
||||
Case raw mode, we will send the raw data as it is.
|
||||
Case easy / advanced mode, we will filter value to send only the needed one (enabled and not default).
|
||||
After formatting, we will use the utils useSubmitForm from @utils/form to submit the form.
|
||||
@name submit
|
||||
@description Case we have at least one setting updating, we will allow to submit the form.
|
||||
@returns {void}
|
||||
*/
|
||||
function submitForm() {
|
||||
function submit() {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy", "raw"])) return;
|
||||
console.log("submitForm");
|
||||
const formattedData = {};
|
||||
_updateTempState();
|
||||
if (!isUpdateData.value) return;
|
||||
return useSubmitForm(formattedData.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@name _updateTempState
|
||||
@description This function will run after a template update and will do two things :
|
||||
1. Format the template to send needed data to the backend.
|
||||
2. Check if at least one setting is updating. Case true, we will allow to submit the form.
|
||||
@returns {void}
|
||||
*/
|
||||
function _updateTempState() {
|
||||
formattedData.value = {};
|
||||
|
||||
// Loop dict items
|
||||
for (const [key, value] of Object.entries(templateBase.value)) {
|
||||
// Case we have a primitive value as value, we can stop here
|
||||
if (typeof value !== "object") {
|
||||
formattedData.value = templateBase.value;
|
||||
break;
|
||||
}
|
||||
|
||||
// Case no wanted keys, continue
|
||||
if (!value?.settings && !value?.multiples) continue;
|
||||
|
||||
_getPluginSettingsValue(value, formattedData.value);
|
||||
_getPluginMultiplesValue(value, formattedData.value);
|
||||
}
|
||||
|
||||
isUpdateData.value = Object.keys(formattedData.value).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@name _getPluginMultiplesValue
|
||||
@description Case we have a multiples key, we have a plugin object.
|
||||
We will loop on each multiples settings and check if the value is different from the previous value in order to add it to the formattedData.
|
||||
@returns {void}
|
||||
*/
|
||||
function _getPluginMultiplesValue(value) {
|
||||
// Get multiples value
|
||||
if (!value?.multiples) return;
|
||||
for (const [multName, multGroups] of Object.entries(value.multiples)) {
|
||||
for (const [groupName, group] of Object.entries(multGroups)) {
|
||||
_checkSettingToAddValue(group, groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name _getPluginSettingsValue
|
||||
@description Case we have a settings key, we have a plugin object.
|
||||
We will loop on each settings and check if the value is different from the previous value in order to add it to the formattedData.
|
||||
@returns {void}
|
||||
*/
|
||||
function _getPluginSettingsValue(value) {
|
||||
if (!value?.settings) return;
|
||||
|
||||
for (const [settName, setting] of Object.entries(value.settings)) {
|
||||
_checkSettingToAddValue(setting, settName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name _checkSettingToAddValue
|
||||
@description Check if the setting value is different from the previous value in order to add it to the formattedData.
|
||||
@returns {void}
|
||||
*/
|
||||
function _checkSettingToAddValue(setting, settingName) {
|
||||
// Case current value is the same as previous, we don't need to send it
|
||||
if (setting?.value === setting?.prev_value) return;
|
||||
formattedData.value[settingName] = setting?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
@name _isFormTypeAllowed
|
||||
@description Set in on the top of other functions, this will get the function name that called it and check if the form type is allowed to execute this function.
|
||||
Case a function is not register, we will not allow it.
|
||||
@returns {boolean} - Return true if the form type is allowed to execute the function.
|
||||
*/
|
||||
function _isFormTypeAllowed(allowTypes) {
|
||||
if (!allowTypes.includes(type.value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@name $reset
|
||||
@description Will reset the template to the original one using the default template. The default template need to be set once.
|
||||
@returns {void}
|
||||
*/
|
||||
function $reset() {
|
||||
if (!_isFormTypeAllowed(["advanced", "easy", "raw"])) return;
|
||||
|
|
@ -323,26 +426,18 @@ export const createFormStore = (storeName, formType) => {
|
|||
updateCount.value++;
|
||||
}
|
||||
|
||||
/**
|
||||
@name _isFormTypeAllowed
|
||||
@description Set in on the top of other functions, this will get the function name that called it and check if the form type is allowed to execute this function.
|
||||
Case a function is not register, we will not allow it.
|
||||
*/
|
||||
function _isFormTypeAllowed(allowTypes) {
|
||||
if (!allowTypes.includes(type.value)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return {
|
||||
templateBase,
|
||||
templateUI,
|
||||
templateUIFormat,
|
||||
rawData,
|
||||
setTemplate,
|
||||
setRawData,
|
||||
addMultiple,
|
||||
delMultiple,
|
||||
useListenTempFields,
|
||||
useUnlistenTempFields,
|
||||
submitForm,
|
||||
submit,
|
||||
$reset,
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { ref } from "vue";
|
|||
@name useBannerStore
|
||||
@description Store to share the current banner state (visible or not).
|
||||
This is useful to update components, specially fixed ones, related to the banner visibility.
|
||||
@returns {object{boolean, string, function}} - Object with the banner state, banner class and function to set the banner visibility.
|
||||
*/
|
||||
export const useBannerStore = defineStore("banner", () => {
|
||||
const isBanner = ref(true);
|
||||
|
|
@ -22,6 +23,7 @@ export const useBannerStore = defineStore("banner", () => {
|
|||
@name useReadonlyStore
|
||||
@description Store to share the current readonly state (true or false).
|
||||
This is useful to unable or enable some inputs or actions related to the readonly state.
|
||||
@returns {object{boolean, function}} - Object with the readonly state and function to set the readonly state.
|
||||
*/
|
||||
export const useReadonlyStore = defineStore("readonly", () => {
|
||||
const isReadOnly = ref(true);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
];
|
||||
@param {object} plugins - Object with the plugins data.
|
||||
@param {array} filters - Array with the filters data.
|
||||
@returns {array} - Array with the filtered data.
|
||||
*/
|
||||
function useFilter(items, filters) {
|
||||
// loop on filters to determine types
|
||||
|
|
@ -82,6 +83,7 @@ function useFilter(items, filters) {
|
|||
},
|
||||
];
|
||||
@param filters - Array of filters to remove default filters
|
||||
@returns {array} - Array of filters without default filters
|
||||
*/
|
||||
function removeDefaultFilters(filters) {
|
||||
// Remove filters with type "select" and "all" as value
|
||||
|
|
@ -113,6 +115,7 @@ function removeDefaultFilters(filters) {
|
|||
}
|
||||
@param filters - Array of filters
|
||||
@param items - Array of items
|
||||
@returns {boolean} - True if at least one key match with the filter value
|
||||
*/
|
||||
function isItemKeyword(filters, item) {
|
||||
// Match if at least one match
|
||||
|
|
@ -166,6 +169,7 @@ function isItemKeyword(filters, item) {
|
|||
}
|
||||
@param filters - Array of filters
|
||||
@param items - Array of items
|
||||
@returns {boolean} - True if at least one key match exactly the filter value
|
||||
*/
|
||||
function isItemSelect(filters, item) {
|
||||
for (let j = 0; j < filters.length; j++) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
@name useForm
|
||||
@description This function is a composable wrapper that contains all the form utils functions.
|
||||
This function will for example look for JSON-type in the data-submit-form attribute of an element and submit the form with the data object.
|
||||
@returns {void}
|
||||
*/
|
||||
function useForm() {
|
||||
window.addEventListener("click", (e) => {
|
||||
|
|
@ -31,6 +32,7 @@ function useForm() {
|
|||
operation: "delete",
|
||||
}
|
||||
@param {object} data - Object with the form data to submit.
|
||||
@returns {void}
|
||||
*/
|
||||
function useSubmitForm(data) {
|
||||
// Create a form element
|
||||
|
|
@ -73,6 +75,7 @@ function useSubmitForm(data) {
|
|||
},
|
||||
},
|
||||
@param template - Template with plugins list and detail settings
|
||||
@returns {array} - Array with error flags and error details
|
||||
*/
|
||||
function useCheckPluginsValidity(template) {
|
||||
let isRegErr = false;
|
||||
|
|
@ -108,4 +111,4 @@ function useCheckPluginsValidity(template) {
|
|||
return [isRegErr, isReqErr, settingErr, settingNameErr, pluginErr, id];
|
||||
}
|
||||
|
||||
export { useForm, useCheckPluginsValidity };
|
||||
export { useForm, useSubmitForm, useCheckPluginsValidity };
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { v4 as uuidv4 } from "uuid";
|
|||
@name useGlobal
|
||||
@description This function is a wrapper that contains all the global utils functions.
|
||||
This function handle global click and keydown events to manage some states like show/hide elements, focus modals, and close modals.
|
||||
@returns {void}
|
||||
*/
|
||||
function useGlobal() {
|
||||
setShowHideElA11y();
|
||||
|
|
@ -38,6 +39,7 @@ function useGlobal() {
|
|||
@name setShowHideElA11y
|
||||
@description This function will check if aria-controls and aria-expanded attributes are present on elements that controls an element visibility.
|
||||
Case they are not present, the function will create them.
|
||||
@returns {void}
|
||||
*/
|
||||
function setShowHideElA11y() {
|
||||
// Wait that elements are mounted and ids are set
|
||||
|
|
@ -65,6 +67,7 @@ function setShowHideElA11y() {
|
|||
<button data-close-el="modal">Close modal</button>
|
||||
<div id="modal" class="">Modal content</div>
|
||||
@param {Event} e - The event object.
|
||||
@returns {void}
|
||||
*/
|
||||
function useHideEl(e) {
|
||||
if (!e.target.hasAttribute("data-hide-el")) return;
|
||||
|
|
@ -86,6 +89,7 @@ function useHideEl(e) {
|
|||
<button data-show-el="modal">Open modal</button>
|
||||
<div id="modal" class="hidden">Modal content</div>
|
||||
@param {Event} e - The event object.
|
||||
@returns {void}
|
||||
*/
|
||||
function useShowEl(e) {
|
||||
if (!e.target.hasAttribute("data-show-el")) return;
|
||||
|
|
@ -103,6 +107,7 @@ function useShowEl(e) {
|
|||
If it's the case, the function will focus the element.
|
||||
Case there is already a focused element inside the modal, avoid to focus it again.
|
||||
@param {String} modalId - The id of the modal element.
|
||||
@returns {void}
|
||||
*/
|
||||
function useFocusModal() {
|
||||
setTimeout(() => {
|
||||
|
|
@ -123,6 +128,7 @@ function useFocusModal() {
|
|||
@name useCloseModal
|
||||
@description This function check if a modal is present and will close it.
|
||||
This is a shortcut to close a modal when the escape key is pressed, for example.
|
||||
@returns {void}
|
||||
*/
|
||||
function useCloseModal() {
|
||||
// Check if a data-modal element without hidden class is present
|
||||
|
|
@ -136,6 +142,7 @@ function useCloseModal() {
|
|||
@name isElHidden
|
||||
@description This function is a util that checks if an element is hidden.
|
||||
This will check for multiple ways to hide an element like aria-hidden, hidden class, display none, visibility hidden, and !hidden class.
|
||||
@returns {boolean} - True if the element is hidden, false if not.
|
||||
*/
|
||||
function isElHidden(el) {
|
||||
return el.hasAttribute("aria-hidden")
|
||||
|
|
@ -159,6 +166,7 @@ function isElHidden(el) {
|
|||
Adding random number to avoid duplicate uuids when some components are rendered at the same time.
|
||||
We can pass a possible existing id, the function will only generate one if the id is empty.
|
||||
@param {String} [id=""] - Possible existing id, check if it's empty to generate a new one.
|
||||
@retrurns {String} - The unique identifier.
|
||||
*/
|
||||
function useUUID(id = "") {
|
||||
if (id) return id;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const availablesLangs = ["en", "fr"];
|
|||
/**
|
||||
@name getAllLang
|
||||
@description Return all the languages json data available in the application.
|
||||
@returns {object} - Object with all the languages data.
|
||||
*/
|
||||
function getAllLang() {
|
||||
return { en: en, fr: fr };
|
||||
|
|
@ -26,6 +27,7 @@ function getAllLang() {
|
|||
@description Filter the needed translations for the current page in order to reduce the size of the i18n object.
|
||||
@example ["dashboard", "settings", "profile"]
|
||||
@param {array} pagesArr - Array of strings with the names of the prefixes of the translations needed.
|
||||
@returns {object} - Object with the languages data for the current page.
|
||||
*/
|
||||
function getAllLangCurrPage(pagesArr) {
|
||||
const langs = getAllLang();
|
||||
|
|
@ -47,6 +49,7 @@ function getAllLangCurrPage(pagesArr) {
|
|||
@description Return the i18n object with the translations needed for the current page for all available languages.
|
||||
@example ["dashboard", "settings", "profile"]
|
||||
@param {array} pagesArr - Array of strings with the names of the prefixes of the translations needed.
|
||||
@returns {object} - Object with the i18n object.
|
||||
*/
|
||||
function getI18n(pagesArr = []) {
|
||||
const messages =
|
||||
|
|
@ -73,6 +76,7 @@ function getI18n(pagesArr = []) {
|
|||
/**
|
||||
@name getLocalLang
|
||||
@description This will return the user langage checking the store, the browser, or the default lang.
|
||||
@returns {string} - The user langage.
|
||||
*/
|
||||
function getLocalLang() {
|
||||
// get store lang, or local, or default
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3667,6 +3667,9 @@ def format_setting(
|
|||
if setting_name in settings and not "multiple" in setting_value:
|
||||
setting_value["value"] = settings[setting_name].get("value", setting_value.get("value", setting_value.get("default")))
|
||||
setting_value["method"] = settings[setting_name].get("method", "ui")
|
||||
|
||||
# Add prev_value in order to check if value has changed to submit it
|
||||
setting_value["prev_value"] = setting_value.get("value")
|
||||
|
||||
# Then override by service settings
|
||||
if setting_name in settings:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
4
src/ui/templates/global-config.html
vendored
4
src/ui/templates/global-config.html
vendored
|
|
@ -7,10 +7,10 @@
|
|||
<link rel="stylesheet" href="css/flag-icons.min.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>BunkerWeb | Global config</title>
|
||||
<script type="module" crossorigin nonce="{{ script_nonce }}" src="assets/global_config-BRF_V6yP.js"></script>
|
||||
<script type="module" crossorigin nonce="{{ script_nonce }}" src="assets/global_config-BRcItP4U.js"></script>
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/Title-DELxfw1F.js">
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/Text-Dad4BU7k.js">
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/form-BpBCT1YO.js">
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/form-DBYbte-L.js">
|
||||
<link rel="stylesheet" crossorigin href="assets/global_config-D2kv0NCW.css">
|
||||
</head>
|
||||
|
||||
|
|
|
|||
4
src/ui/templates/instances.html
vendored
4
src/ui/templates/instances.html
vendored
|
|
@ -7,9 +7,9 @@
|
|||
<link rel="stylesheet" href="css/flag-icons.min.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>BunkerWeb | Instances</title>
|
||||
<script type="module" crossorigin nonce="{{ script_nonce }}" src="assets/instances-DNq7VNrL.js"></script>
|
||||
<script type="module" crossorigin nonce="{{ script_nonce }}" src="assets/instances-DaTfTNdd.js"></script>
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/Title-DELxfw1F.js">
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/form-BpBCT1YO.js">
|
||||
<link rel="modulepreload" crossorigin nonce="{{ script_nonce }}" href="assets/form-DBYbte-L.js">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
|||
Loading…
Reference in a new issue