mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
remain multiples and advanced form
* fix vuln braces * show multiples in reverse order for better UX * created a advanced store for a better advanced form management
This commit is contained in:
parent
93ecef0373
commit
3c38278f3a
11 changed files with 503 additions and 357 deletions
|
|
@ -4796,7 +4796,8 @@
|
|||
"text": "Custom header to add (HeaderName: HeaderValue)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-13"
|
||||
"containerClass": "z-13",
|
||||
"plugin_id": "headers"
|
||||
}
|
||||
},
|
||||
"cookie-flags": {
|
||||
|
|
@ -4829,7 +4830,8 @@
|
|||
"text": "Cookie flags automatically added to all cookies (value accepted for nginx_cookie_flag_module)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-12"
|
||||
"containerClass": "z-12",
|
||||
"plugin_id": "headers"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -5173,7 +5175,8 @@
|
|||
"text": "URL (PCRE regex) where the limit request will be applied or special value / for all requests."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-6"
|
||||
"containerClass": "z-6",
|
||||
"plugin_id": "limit"
|
||||
},
|
||||
"LIMIT_REQ_RATE": {
|
||||
"context": "multisite",
|
||||
|
|
@ -5204,7 +5207,8 @@
|
|||
"text": "Rate to apply to the URL (s for second, m for minute, h for hour and d for day)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-5"
|
||||
"containerClass": "z-5",
|
||||
"plugin_id": "limit"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -7540,7 +7544,8 @@
|
|||
"text": "Full URL of the proxied resource (proxy_pass)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-26"
|
||||
"containerClass": "z-26",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_URL": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7571,7 +7576,8 @@
|
|||
"text": "Location URL that will be proxied."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-25"
|
||||
"containerClass": "z-25",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_WS": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7602,7 +7608,8 @@
|
|||
"text": "Enable websocket on the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-24"
|
||||
"containerClass": "z-24",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_HEADERS": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7633,7 +7640,8 @@
|
|||
"text": "List of HTTP headers to send to proxied resource separated with semicolons (values for proxy_set_header directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-23"
|
||||
"containerClass": "z-23",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_HEADERS_CLIENT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7664,7 +7672,8 @@
|
|||
"text": "List of HTTP headers to send to client separated with semicolons (values for add_header directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-22"
|
||||
"containerClass": "z-22",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_BUFFERING": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7695,7 +7704,8 @@
|
|||
"text": "Enable or disable buffering of responses from proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-21"
|
||||
"containerClass": "z-21",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_KEEPALIVE": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7726,7 +7736,8 @@
|
|||
"text": "Enable or disable keepalive connections with the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-20"
|
||||
"containerClass": "z-20",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7757,7 +7768,8 @@
|
|||
"text": "Enable authentication using an external provider (value of auth_request directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-19"
|
||||
"containerClass": "z-19",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_SIGNIN_URL": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7788,7 +7800,8 @@
|
|||
"text": "Redirect clients to sign-in URL when using REVERSE_PROXY_AUTH_REQUEST (used when auth_request call returned 401)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-18"
|
||||
"containerClass": "z-18",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_SET": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7819,7 +7832,8 @@
|
|||
"text": "List of variables to set from the authentication provider, separated with semicolons (values of auth_request_set directives)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-17"
|
||||
"containerClass": "z-17",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_CONNECT_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7850,7 +7864,8 @@
|
|||
"text": "Timeout when connecting to the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-16"
|
||||
"containerClass": "z-16",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_READ_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7881,7 +7896,8 @@
|
|||
"text": "Timeout when reading from the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-15"
|
||||
"containerClass": "z-15",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_SEND_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7912,7 +7928,8 @@
|
|||
"text": "Timeout when sending to the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-14"
|
||||
"containerClass": "z-14",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_INCLUDES": {
|
||||
"context": "multisite",
|
||||
|
|
@ -7943,7 +7960,8 @@
|
|||
"text": "Additional configuration to include in the location block, separated with spaces."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-13"
|
||||
"containerClass": "z-13",
|
||||
"plugin_id": "reverseproxy"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -7984,6 +8002,7 @@
|
|||
}
|
||||
],
|
||||
"containerClass": "z-26",
|
||||
"plugin_id": "reverseproxy",
|
||||
"method": "scheduler"
|
||||
},
|
||||
"REVERSE_PROXY_URL_1": {
|
||||
|
|
@ -8015,7 +8034,8 @@
|
|||
"text": "Location URL that will be proxied."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-25"
|
||||
"containerClass": "z-25",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_WS_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8046,7 +8066,8 @@
|
|||
"text": "Enable websocket on the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-24"
|
||||
"containerClass": "z-24",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_HEADERS_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8077,7 +8098,8 @@
|
|||
"text": "List of HTTP headers to send to proxied resource separated with semicolons (values for proxy_set_header directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-23"
|
||||
"containerClass": "z-23",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_HEADERS_CLIENT_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8108,7 +8130,8 @@
|
|||
"text": "List of HTTP headers to send to client separated with semicolons (values for add_header directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-22"
|
||||
"containerClass": "z-22",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_BUFFERING_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8139,7 +8162,8 @@
|
|||
"text": "Enable or disable buffering of responses from proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-21"
|
||||
"containerClass": "z-21",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_KEEPALIVE_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8170,7 +8194,8 @@
|
|||
"text": "Enable or disable keepalive connections with the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-20"
|
||||
"containerClass": "z-20",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8201,7 +8226,8 @@
|
|||
"text": "Enable authentication using an external provider (value of auth_request directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-19"
|
||||
"containerClass": "z-19",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_SIGNIN_URL_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8232,7 +8258,8 @@
|
|||
"text": "Redirect clients to sign-in URL when using REVERSE_PROXY_AUTH_REQUEST (used when auth_request call returned 401)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-18"
|
||||
"containerClass": "z-18",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_SET_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8263,7 +8290,8 @@
|
|||
"text": "List of variables to set from the authentication provider, separated with semicolons (values of auth_request_set directives)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-17"
|
||||
"containerClass": "z-17",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_CONNECT_TIMEOUT_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8294,7 +8322,8 @@
|
|||
"text": "Timeout when connecting to the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-16"
|
||||
"containerClass": "z-16",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_READ_TIMEOUT_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8325,7 +8354,8 @@
|
|||
"text": "Timeout when reading from the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-15"
|
||||
"containerClass": "z-15",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_SEND_TIMEOUT_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8356,7 +8386,8 @@
|
|||
"text": "Timeout when sending to the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-14"
|
||||
"containerClass": "z-14",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_INCLUDES_1": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8387,7 +8418,8 @@
|
|||
"text": "Additional configuration to include in the location block, separated with spaces."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-13"
|
||||
"containerClass": "z-13",
|
||||
"plugin_id": "reverseproxy"
|
||||
}
|
||||
},
|
||||
"0": {
|
||||
|
|
@ -8421,6 +8453,7 @@
|
|||
}
|
||||
],
|
||||
"containerClass": "z-26",
|
||||
"plugin_id": "reverseproxy",
|
||||
"method": "ui"
|
||||
},
|
||||
"REVERSE_PROXY_URL": {
|
||||
|
|
@ -8452,7 +8485,8 @@
|
|||
"text": "Location URL that will be proxied."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-25"
|
||||
"containerClass": "z-25",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_WS": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8483,7 +8517,8 @@
|
|||
"text": "Enable websocket on the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-24"
|
||||
"containerClass": "z-24",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_HEADERS": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8514,7 +8549,8 @@
|
|||
"text": "List of HTTP headers to send to proxied resource separated with semicolons (values for proxy_set_header directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-23"
|
||||
"containerClass": "z-23",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_HEADERS_CLIENT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8545,7 +8581,8 @@
|
|||
"text": "List of HTTP headers to send to client separated with semicolons (values for add_header directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-22"
|
||||
"containerClass": "z-22",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_BUFFERING": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8576,7 +8613,8 @@
|
|||
"text": "Enable or disable buffering of responses from proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-21"
|
||||
"containerClass": "z-21",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_KEEPALIVE": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8607,7 +8645,8 @@
|
|||
"text": "Enable or disable keepalive connections with the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-20"
|
||||
"containerClass": "z-20",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8638,7 +8677,8 @@
|
|||
"text": "Enable authentication using an external provider (value of auth_request directive)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-19"
|
||||
"containerClass": "z-19",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_SIGNIN_URL": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8669,7 +8709,8 @@
|
|||
"text": "Redirect clients to sign-in URL when using REVERSE_PROXY_AUTH_REQUEST (used when auth_request call returned 401)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-18"
|
||||
"containerClass": "z-18",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_AUTH_REQUEST_SET": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8700,7 +8741,8 @@
|
|||
"text": "List of variables to set from the authentication provider, separated with semicolons (values of auth_request_set directives)."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-17"
|
||||
"containerClass": "z-17",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_CONNECT_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8731,7 +8773,8 @@
|
|||
"text": "Timeout when connecting to the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-16"
|
||||
"containerClass": "z-16",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_READ_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8762,7 +8805,8 @@
|
|||
"text": "Timeout when reading from the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-15"
|
||||
"containerClass": "z-15",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_SEND_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8793,7 +8837,8 @@
|
|||
"text": "Timeout when sending to the proxied resource."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-14"
|
||||
"containerClass": "z-14",
|
||||
"plugin_id": "reverseproxy"
|
||||
},
|
||||
"REVERSE_PROXY_INCLUDES": {
|
||||
"context": "multisite",
|
||||
|
|
@ -8824,7 +8869,8 @@
|
|||
"text": "Additional configuration to include in the location block, separated with spaces."
|
||||
}
|
||||
],
|
||||
"containerClass": "z-13"
|
||||
"containerClass": "z-13",
|
||||
"plugin_id": "reverseproxy"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { defineProps, reactive, onMounted, onUnmounted } from "vue";
|
||||
import { defineProps, reactive, onMounted, onUnmounted, computed } from "vue";
|
||||
import MessageUnmatch from "@components/Message/Unmatch.vue";
|
||||
import Container from "@components/Widget/Container.vue";
|
||||
import Fields from "@components/Form/Fields.vue";
|
||||
|
|
@ -11,14 +11,8 @@ import Text from "@components/Widget/Text.vue";
|
|||
import Filter from "@components/Widget/Filter.vue";
|
||||
import GroupMultiple from "@components/Forms/Group/Multiple.vue";
|
||||
import { plugin_types } from "@utils/variables";
|
||||
import {
|
||||
useCheckPluginsValidity,
|
||||
useUpdateTemp,
|
||||
useListenTempFields,
|
||||
useUnlistenTempFields,
|
||||
useDelAdvancedMult,
|
||||
useAddAdvancedMult,
|
||||
} from "@utils/form.js";
|
||||
import { useAdvancedForm } from "@store/advanced.js";
|
||||
import { useCheckPluginsValidity } from "@utils/form.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
/**
|
||||
@name Form/Advanced.vue
|
||||
|
|
@ -53,6 +47,8 @@ import { v4 as uuidv4 } from "uuid";
|
|||
@param {object} columns - Columns object.
|
||||
*/
|
||||
|
||||
const advancedForm = useAdvancedForm();
|
||||
|
||||
const props = defineProps({
|
||||
// id && value && method
|
||||
template: {
|
||||
|
|
@ -75,13 +71,11 @@ const props = defineProps({
|
|||
const data = reactive({
|
||||
currPlugin: "",
|
||||
plugins: [],
|
||||
base: JSON.parse(JSON.stringify(props.template)),
|
||||
base: props.template,
|
||||
isRegErr: false,
|
||||
isReqErr: false,
|
||||
settingErr: "",
|
||||
pluginErr: "",
|
||||
// Add filtering and check validity with regex and required
|
||||
format: JSON.parse(JSON.stringify(props.template)),
|
||||
});
|
||||
|
||||
const comboboxPlugin = {
|
||||
|
|
@ -109,7 +103,7 @@ const buttonSave = {
|
|||
size: "normal",
|
||||
type: "button",
|
||||
attrs: {
|
||||
"data-submit-form": JSON.stringify(data.base),
|
||||
"data-submit-form": JSON.stringify(advancedForm.templateBase),
|
||||
},
|
||||
containerClass: "flex justify-center",
|
||||
iconName: "plus",
|
||||
|
|
@ -201,19 +195,19 @@ const filters = [
|
|||
];
|
||||
|
||||
function filter(filterData) {
|
||||
advancedForm.templateUIFormat = filterData;
|
||||
setValidity();
|
||||
data.format = filterData;
|
||||
data.plugins = getPluginNames(filterData);
|
||||
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(filterData);
|
||||
: getFirstPlugin(advancedForm.templateUIFormat);
|
||||
}
|
||||
|
||||
function setValidity() {
|
||||
const [isRegErr, isReqErr, settingErr, settingNameErr, pluginErr, id] =
|
||||
useCheckPluginsValidity(data.base);
|
||||
useCheckPluginsValidity(advancedForm.templateUI);
|
||||
data.isRegErr = isRegErr;
|
||||
data.isReqErr = isReqErr;
|
||||
data.settingErr = settingErr;
|
||||
|
|
@ -242,24 +236,20 @@ function getPluginNames(template) {
|
|||
}
|
||||
}
|
||||
|
||||
function updateTemplate(e) {
|
||||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
useUpdateTemp(e, data.base);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
advancedForm.setTemplate(props.template);
|
||||
// Get first props.forms template name
|
||||
data.currPlugin = getFirstPlugin(props.template);
|
||||
data.plugins = getPluginNames(props.template);
|
||||
data.currPlugin = getFirstPlugin(advancedForm.templateUIFormat);
|
||||
data.plugins = getPluginNames(advancedForm.templateUIFormat);
|
||||
setValidity();
|
||||
// Store update data on
|
||||
|
||||
// I want updatInp to access event, data.base and the container attribut
|
||||
useListenTempFields(updateTemplate);
|
||||
advancedForm.useListenTempFields();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
useUnlistenTempFields(updateTemplate);
|
||||
advancedForm.useUnlistenTempFields();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -277,7 +267,7 @@ onUnmounted(() => {
|
|||
<Filter
|
||||
v-if="filters.length"
|
||||
@filter="(v) => filter(v)"
|
||||
:data="data.base"
|
||||
:data="advancedForm.templateUI"
|
||||
:filters="filters"
|
||||
>
|
||||
<Combobox
|
||||
|
|
@ -287,8 +277,8 @@ onUnmounted(() => {
|
|||
@inp="data.currPlugin = $event"
|
||||
/>
|
||||
</Filter>
|
||||
<MessageUnmatch v-if="!data.format.length" />
|
||||
<template v-for="plugin in data.format">
|
||||
<MessageUnmatch v-if="!advancedForm.templateUIFormat.length" />
|
||||
<template v-for="(plugin, pluginId) in advancedForm.templateUIFormat">
|
||||
<Container
|
||||
data-is="content"
|
||||
data-advanced-form-plugin
|
||||
|
|
@ -309,24 +299,23 @@ onUnmounted(() => {
|
|||
<GroupMultiple
|
||||
@delete="
|
||||
(multName, groupName) =>
|
||||
useDelAdvancedMult(data.base, multName, groupName)
|
||||
advancedForm.delMultiple(plugin.id, multName, groupName)
|
||||
"
|
||||
@add="(multName) => useAddAdvancedMult(data.base, multName)"
|
||||
v-if="plugin.multiples"
|
||||
@add="(multName) => advancedForm.addMultiple(plugin.id, multName)"
|
||||
:multiples="plugin.multiples"
|
||||
/>
|
||||
</Container>
|
||||
</template>
|
||||
<Button
|
||||
v-if="data.format.length"
|
||||
v-if="advancedForm.templateUIFormat.length"
|
||||
v-bind="buttonSave"
|
||||
:disabled="data.isReqErr || data.isRegErr ? true : false"
|
||||
/>
|
||||
<div class="flex justify-center items-center" data-is="form-error">
|
||||
<Text
|
||||
v-if="
|
||||
(data.format.length && data.isRegErr) ||
|
||||
(data.format.length && data.isReqErr)
|
||||
(advancedForm.templateUIFormat.length && data.isRegErr) ||
|
||||
(advancedForm.templateUIFormat.length && data.isReqErr)
|
||||
"
|
||||
:text="
|
||||
data.isReqErr
|
||||
|
|
|
|||
|
|
@ -7,12 +7,7 @@ import Subtitle from "@components/Widget/Subtitle.vue";
|
|||
import Button from "@components/Widget/Button.vue";
|
||||
import Text from "@components/Widget/Text.vue";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {
|
||||
useCheckPluginsValidity,
|
||||
useUpdateTemp,
|
||||
useListenTempFields,
|
||||
useUnlistenTempFields,
|
||||
} from "@utils/form.js";
|
||||
import { useCheckPluginsValidity } from "@utils/form.js";
|
||||
|
||||
/**
|
||||
@name Form/Easy.vue
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
<script setup>
|
||||
import { reactive, defineProps, defineEmits } from "vue";
|
||||
import {
|
||||
reactive,
|
||||
defineProps,
|
||||
defineEmits,
|
||||
watch,
|
||||
computed,
|
||||
onMounted,
|
||||
} from "vue";
|
||||
import { contentIndex } from "@utils/tabindex.js";
|
||||
import ButtonGroup from "@components/Widget/ButtonGroup.vue";
|
||||
import Button from "@components/Widget/Button.vue";
|
||||
|
|
@ -205,6 +212,9 @@ const buttonDelete = {
|
|||
containerClass: "flex justify-center",
|
||||
};
|
||||
|
||||
// emits
|
||||
const emits = defineEmits(["delete", "add"]);
|
||||
|
||||
// Check if at least one input is disabled (this means a method different than ui, default or manual is used)
|
||||
// If true, disable the delete button
|
||||
function setDeleteState(group) {
|
||||
|
|
@ -230,19 +240,16 @@ function delInvisible(id) {
|
|||
}
|
||||
|
||||
function toggleVisible(id) {
|
||||
if (multiples.invisible.includes(id)) {
|
||||
delInvisible(id);
|
||||
} else {
|
||||
setInvisible(id);
|
||||
}
|
||||
multiples.invisible.includes(id) ? delInvisible(id) : setInvisible(id);
|
||||
}
|
||||
|
||||
// emits
|
||||
const emits = defineEmits(["delete", "add"]);
|
||||
function delGroup(multName, groupName) {
|
||||
emits("delete", multName, groupName);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template :key="multName" v-for="(multObj, multName, id) in props.multiples">
|
||||
<template v-for="(multObj, multName, id) in props.multiples">
|
||||
<Container
|
||||
data-is="multiple"
|
||||
class="layout-settings-multiple"
|
||||
|
|
@ -264,36 +271,43 @@ const emits = defineEmits(["delete", "add"]);
|
|||
</div>
|
||||
</Container>
|
||||
|
||||
<template
|
||||
:key="groupId"
|
||||
v-for="(group, groupName, groupId) in props.multiples[multName]"
|
||||
<div
|
||||
:aria-hidden="
|
||||
multiples.invisible.includes(`${multName}${id}`) ? 'false' : 'true'
|
||||
"
|
||||
:class="[
|
||||
'flex-col-reverse col-span-12',
|
||||
multiples.invisible.includes(`${multName}${id}`) ? 'hidden' : 'flex',
|
||||
]"
|
||||
>
|
||||
<Container
|
||||
data-group="multiple"
|
||||
:data-group-name="groupName"
|
||||
:data-mult-name="multName"
|
||||
:data-plugin-name="multName"
|
||||
class="layout-settings-multiple-group"
|
||||
:aria-hidden="multiples.invisible.includes(`${multName}${id}`)"
|
||||
v-show="
|
||||
multiples.invisible.includes(`${multName}${id}`) ? false : true
|
||||
"
|
||||
<template
|
||||
:key="groupName"
|
||||
v-for="(group, groupName, groupId) in props.multiples[multName]"
|
||||
>
|
||||
<Subtitle
|
||||
:subtitle="`${multName.replaceAll('-', ' ')} #${+groupName + 1}`"
|
||||
/>
|
||||
<template
|
||||
:key="setting"
|
||||
v-for="(setting, settingName, settingId) in group"
|
||||
<Container
|
||||
data-group="multiple"
|
||||
:data-group-name="groupName"
|
||||
:data-mult-name="multName"
|
||||
class="layout-settings-multiple-group"
|
||||
>
|
||||
<Fields :setting="setting" />
|
||||
</template>
|
||||
<ButtonGroup
|
||||
@click="$emit('delete', multName, groupName)"
|
||||
:buttons="[setDeleteState(group)]"
|
||||
/>
|
||||
</Container>
|
||||
</template>
|
||||
<Subtitle
|
||||
:subtitle="`${multName.replaceAll('-', ' ')} #${+groupName + 1}`"
|
||||
/>
|
||||
<template
|
||||
:key="settingName"
|
||||
v-for="(setting, settingName, settingId) in group"
|
||||
>
|
||||
<Fields :setting="setting" />
|
||||
</template>
|
||||
<div class="col-span-12 flex justify-center">
|
||||
<Button
|
||||
@click="delGroup(multName, groupName)"
|
||||
v-bind="setDeleteState(group)"
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
</template>
|
||||
</div>
|
||||
</Container>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -75,9 +75,13 @@ const filters = reactive({
|
|||
isFiltering: false,
|
||||
});
|
||||
|
||||
watch(props.data, () => {
|
||||
filterData();
|
||||
});
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
filterData();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
function startFilter(filter = {}, value) {
|
||||
// Case we have new filter value, update it
|
||||
|
|
@ -133,7 +137,6 @@ function startFilter(filter = {}, value) {
|
|||
// Remove empty row
|
||||
template = template.filter((row) => row.length > 0);
|
||||
}
|
||||
|
||||
emits("filter", template);
|
||||
}
|
||||
|
||||
|
|
|
|||
285
src/client/vite/src/store/advanced.js
Normal file
285
src/client/vite/src/store/advanced.js
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
|
||||
/**
|
||||
@name useAdvancedForm
|
||||
@description Store to share the template and others form data.
|
||||
*/
|
||||
export const useAdvancedForm = defineStore("advanced", () => {
|
||||
// Default template, don't touch it. It will be used to reset the template.
|
||||
const template = ref({});
|
||||
// Base template will keep every data (data that doesn't need to be render on UI but need to be there for backend).
|
||||
const templateBase = ref({});
|
||||
// UI template will keep the data that will be render on UI.
|
||||
const templateUI = ref({});
|
||||
// UI template will keep the data that will be render on UI with additionnal format like filtering.
|
||||
const templateUIFormat = ref({});
|
||||
const updateCount = ref(0);
|
||||
/**
|
||||
@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
|
||||
*/
|
||||
function setTemplate(template) {
|
||||
template.value = template;
|
||||
templateBase.value = template;
|
||||
templateUI.value = JSON.parse(JSON.stringify(template));
|
||||
templateUIFormat.value = JSON.parse(JSON.stringify(template));
|
||||
}
|
||||
|
||||
/**
|
||||
@name delMultiple
|
||||
@description This function will delete a group of multiples in the template.
|
||||
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
|
||||
*/
|
||||
function delMultiple(pluginId, multName, groupName) {
|
||||
// Get the index of plugin using pluginId
|
||||
const index = templateBase.value.findIndex(
|
||||
(plugin) => plugin.id === pluginId
|
||||
);
|
||||
|
||||
// For back end, we need to keep the group but updating values to default in order to delete it
|
||||
for (const [key, value] of Object.entries(
|
||||
templateBase.value[index].multiples[multName][groupName]
|
||||
)) {
|
||||
value.value = value.default;
|
||||
}
|
||||
|
||||
// For UI, we can delete the group to avoid rendering it
|
||||
delete templateUI.value[index].multiples[multName][groupName];
|
||||
updateCount.value++;
|
||||
}
|
||||
|
||||
/**
|
||||
@name addMultiple
|
||||
@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
|
||||
*/
|
||||
function addMultiple(pluginId, multName) {
|
||||
// Get the index of plugin using pluginId
|
||||
const index = templateBase.value.findIndex(
|
||||
(plugin) => plugin.id === pluginId
|
||||
);
|
||||
// Get the right multiple schema
|
||||
const multipleSchema = JSON.parse(
|
||||
JSON.stringify(templateBase.value[index]?.multiples_schema[multName])
|
||||
);
|
||||
const newMultiple = {};
|
||||
|
||||
// Get the highest id in Object.keys(plugin?.multiples[multName])
|
||||
const nextGroupId =
|
||||
Math.max(...Object.keys(templateBase.value[index]?.multiples[multName])) +
|
||||
1;
|
||||
|
||||
// Set the default values as value
|
||||
for (const [key, value] of Object.entries(multipleSchema)) {
|
||||
value.value = value.default;
|
||||
newMultiple[`${key}${nextGroupId > 0 ? "_" + nextGroupId : ""}`] = value;
|
||||
}
|
||||
// Add new group as first key of plugin.multiples.multName
|
||||
templateBase.value[index].multiples[multName][nextGroupId] = newMultiple;
|
||||
// We need to show the new group on UI too
|
||||
templateUI.value[index].multiples[multName][nextGroupId] = newMultiple;
|
||||
updateCount.value++;
|
||||
}
|
||||
|
||||
/**
|
||||
@name useListenTempFields
|
||||
@description This will add an handler to all needed event listeners to listen to input, select... fields in order to update the template settings.
|
||||
@example
|
||||
function hander(e) {
|
||||
// some code before calling useUpdateTemp
|
||||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
useUpdateTemp(e, data.base);
|
||||
}
|
||||
*/
|
||||
function useListenTempFields() {
|
||||
window.addEventListener("input", useUpdateTemp);
|
||||
window.addEventListener("change", useUpdateTemp);
|
||||
window.addEventListener("click", useUpdateTemp);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUnlistenTempFields
|
||||
@description This will stop listening to input, select... fields. Performance optimization and avoid duplicate calls conflicts.
|
||||
@example
|
||||
function hander(e) {
|
||||
// some code before calling useUpdateTemp
|
||||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
useUpdateTemp(e, data.base);
|
||||
}
|
||||
*/
|
||||
function useUnlistenTempFields() {
|
||||
window.removeEventListener("change", useUpdateTemp);
|
||||
window.removeEventListener("click", useUpdateTemp);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUpdateTemp
|
||||
@description This function will check if the target is a setting input-like field.
|
||||
In case it is, it will get the id and value for each field case, this will allow to update the template settings.
|
||||
@example
|
||||
template = [
|
||||
{
|
||||
name: "test",
|
||||
settings: {
|
||||
test: {
|
||||
required: true,
|
||||
value: "",
|
||||
pattern: "^[a-zA-Z0-9]*$",
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@param e - Event object, get it by default in the event listener.
|
||||
@param templates - Array of templates to update
|
||||
*/
|
||||
function useUpdateTemp(e, templates) {
|
||||
templates = [templateBase.value, templateUI.value];
|
||||
// Filter to avoid multiple calls
|
||||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
if (e.type === "change" && e.target.tagName === "INPUT") return;
|
||||
// Wait some ms that previous update logic is done like datepicker
|
||||
setTimeout(() => {
|
||||
let inpId, inpValue;
|
||||
|
||||
// Case target is input (a little different for datepicker)
|
||||
if (e.target.tagName === "INPUT") {
|
||||
inpId = e.target.id;
|
||||
inpValue = e.target.hasAttribute("data-timestamp")
|
||||
? e.target.getAttribute("data-timestamp")
|
||||
: e.target.value;
|
||||
}
|
||||
|
||||
// Case target is select
|
||||
if (
|
||||
e.target.closest("[data-field-container]") &&
|
||||
e.target.hasAttribute("data-setting-id") &&
|
||||
e.target.hasAttribute("data-setting-value")
|
||||
) {
|
||||
inpId = e.target.getAttribute("data-setting-id");
|
||||
inpValue = e.target.getAttribute("data-setting-value");
|
||||
}
|
||||
|
||||
// Case target is not an input-like
|
||||
if (!inpId) return;
|
||||
|
||||
// update settings
|
||||
useUpdateTempSettings(templates, inpId, inpValue, e.target);
|
||||
useUpdateTempMultiples(templates, inpId, inpValue, e.target);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUpdateTempSettings
|
||||
@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
|
||||
*/
|
||||
function useUpdateTempSettings(templates, inpId, inpValue, target) {
|
||||
// Case get data-group attribut, this is not a regular setting
|
||||
if (target.closest("[data-group]")) return;
|
||||
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
const template = templates[i];
|
||||
|
||||
// Try to update settings
|
||||
let isSettingUpdated = false;
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const plugin = template[i];
|
||||
const settings = plugin?.settings;
|
||||
if (!settings) continue;
|
||||
for (const [key, value] of Object.entries(settings)) {
|
||||
if (value.id === inpId) {
|
||||
value.value = inpValue;
|
||||
isSettingUpdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSettingUpdated) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUpdateTempMultiples
|
||||
@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
|
||||
*/
|
||||
function useUpdateTempMultiples(templates, inpId, inpValue, target) {
|
||||
// Case get data-group attribut, this is not a regular setting
|
||||
if (!target.closest("[data-group='multiple']")) return;
|
||||
const multName =
|
||||
target
|
||||
.closest("[data-group='multiple']")
|
||||
.getAttribute("data-mult-name") || "";
|
||||
const groupName =
|
||||
target
|
||||
.closest("[data-group='multiple']")
|
||||
.getAttribute("data-group-name") || "";
|
||||
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
const template = templates[i];
|
||||
// Check at the same time the inpId without prefix group he is part of
|
||||
// And try to update an existing inpId
|
||||
// Case we found the inpId, we update the value
|
||||
// Case we didn't find existing inpId, we create a new one
|
||||
let isSettingUpdated = false;
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const plugin = template[i];
|
||||
const multiples = plugin?.multiples;
|
||||
// Case no multiples, continue
|
||||
if (!multiples || Object.keys(multiples).length <= 0) continue;
|
||||
// Check if can find mult name in multiples
|
||||
if (!(multName in multiples)) continue;
|
||||
// Check if can find group name in multiples
|
||||
if (!(groupName in multiples[multName])) continue;
|
||||
const settings = multiples[multName][groupName];
|
||||
for (const [key, value] of Object.entries(settings)) {
|
||||
if (value.id !== inpId) continue;
|
||||
value.value = inpValue;
|
||||
isSettingUpdated = true;
|
||||
break;
|
||||
}
|
||||
if (isSettingUpdated) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name $reset
|
||||
@description Will reset the template to the original one using the default template. The default template need to be set once.
|
||||
*/
|
||||
function $reset() {
|
||||
templateBase.value = template.value;
|
||||
templateUI.value = template.value;
|
||||
updateCount.value++;
|
||||
}
|
||||
|
||||
return {
|
||||
templateBase,
|
||||
templateUI,
|
||||
templateUIFormat,
|
||||
setTemplate,
|
||||
addMultiple,
|
||||
delMultiple,
|
||||
useListenTempFields,
|
||||
useUnlistenTempFields,
|
||||
$reset,
|
||||
};
|
||||
});
|
||||
|
|
@ -302,232 +302,10 @@ function useCheckPluginsValidity(template) {
|
|||
return [isRegErr, isReqErr, settingErr, settingNameErr, pluginErr, id];
|
||||
}
|
||||
|
||||
/**
|
||||
@name useListenTempFields
|
||||
@description This will add an handler to all needed event listeners to listen to input, select... fields in order to update the template settings.
|
||||
@example
|
||||
function hander(e) {
|
||||
// some code before calling useUpdateTemp
|
||||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
useUpdateTemp(e, data.base);
|
||||
}
|
||||
@param handler - Callback function to call when event is triggered. This is usually an intermediate function that will call the useUpdateTemp function.
|
||||
*/
|
||||
function useListenTempFields(handler) {
|
||||
window.addEventListener("input", handler);
|
||||
window.addEventListener("change", handler);
|
||||
window.addEventListener("click", handler);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUnlistenTempFields
|
||||
@description This will stop listening to input, select... fields. Performance optimization and avoid duplicate calls conflicts.
|
||||
@example
|
||||
function hander(e) {
|
||||
// some code before calling useUpdateTemp
|
||||
if (!e.target.closest("[data-advanced-form-plugin]")) return;
|
||||
useUpdateTemp(e, data.base);
|
||||
}
|
||||
@param handler - Callback function to call when event is triggered. Need to be the same function as the one passed to useListenTempFields.
|
||||
*/
|
||||
function useUnlistenTempFields(handler) {
|
||||
window.removeEventListener("input", handler);
|
||||
window.removeEventListener("change", handler);
|
||||
window.removeEventListener("click", handler);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUpdateTemp
|
||||
@description This function will check if the target is a setting input-like field.
|
||||
In case it is, it will get the id and value for each field case, this will allow to update the template settings.
|
||||
@example
|
||||
template = [
|
||||
{
|
||||
name: "test",
|
||||
settings: {
|
||||
test: {
|
||||
required: true,
|
||||
value: "",
|
||||
pattern: "^[a-zA-Z0-9]*$",
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@param e - Event object, get it by default in the event listener.
|
||||
@param template - Template with plugins list and detail settings
|
||||
*/
|
||||
function useUpdateTemp(e, template) {
|
||||
// Wait some ms that previous update logic is done like datepicker
|
||||
setTimeout(() => {
|
||||
let inpId, inpValue;
|
||||
|
||||
// Case target is input (a little different for datepicker)
|
||||
if (e.target.tagName === "INPUT") {
|
||||
inpId = e.target.id;
|
||||
inpValue = e.target.hasAttribute("data-timestamp")
|
||||
? e.target.getAttribute("data-timestamp")
|
||||
: e.target.value;
|
||||
}
|
||||
|
||||
// Case target is select
|
||||
if (
|
||||
e.target.closest("[data-field-container]") &&
|
||||
e.target.hasAttribute("data-setting-id") &&
|
||||
e.target.hasAttribute("data-setting-value")
|
||||
) {
|
||||
inpId = e.target.getAttribute("data-setting-id");
|
||||
inpValue = e.target.getAttribute("data-setting-value");
|
||||
}
|
||||
|
||||
// Case target is not an input-like
|
||||
if (!inpId) return;
|
||||
|
||||
// update settings
|
||||
useUpdateTempSettings(template, inpId, inpValue, e.target);
|
||||
useUpdateTempMultiples(template, inpId, inpValue, e.target);
|
||||
return template;
|
||||
}, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUpdateTempSettings
|
||||
@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 template - Template with plugins list and detail settings
|
||||
@param inpId - Input id to update
|
||||
@param inpValue - Input value to update
|
||||
*/
|
||||
function useUpdateTempSettings(template, inpId, inpValue, target) {
|
||||
// Case get data-group attribut, this is not a regular setting
|
||||
if (target.closest("[data-group]")) return;
|
||||
|
||||
// Try to update settings
|
||||
let isSettingUpdated = false;
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const plugin = template[i];
|
||||
const settings = plugin?.settings;
|
||||
if (!settings) continue;
|
||||
for (const [key, value] of Object.entries(settings)) {
|
||||
if (value.id === inpId) {
|
||||
value.value = inpValue;
|
||||
isSettingUpdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSettingUpdated) break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUpdateTempMultiples
|
||||
@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 template - Template with plugins list and detail settings
|
||||
@param inpId - Input id to update
|
||||
@param inpValue - Input value to update
|
||||
*/
|
||||
function useUpdateTempMultiples(template, inpId, inpValue, target) {
|
||||
// Case get data-group attribut, this is not a regular setting
|
||||
if (!target.closest("[data-group='multiple']")) return;
|
||||
const multName =
|
||||
target.closest("[data-group='multiple']").getAttribute("data-mult-name") ||
|
||||
"";
|
||||
const groupName =
|
||||
target.closest("[data-group='multiple']").getAttribute("data-group-name") ||
|
||||
"";
|
||||
|
||||
// Check at the same time the inpId without prefix group he is part of
|
||||
// And try to update an existing inpId
|
||||
// Case we found the inpId, we update the value
|
||||
// Case we didn't find existing inpId, we create a new one
|
||||
let isSettingUpdated = false;
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const plugin = template[i];
|
||||
const multiples = plugin?.multiples;
|
||||
// Case no multiples, continue
|
||||
if (!multiples || Object.keys(multiples).length <= 0) continue;
|
||||
// Check if can find mult name in multiples
|
||||
if (!(multName in multiples)) continue;
|
||||
// Check if can find group name in multiples
|
||||
if (!(groupName in multiples[multName])) continue;
|
||||
const settings = multiples[multName][groupName];
|
||||
for (const [key, value] of Object.entries(settings)) {
|
||||
if (value.id !== inpId) continue;
|
||||
value.value = inpValue;
|
||||
isSettingUpdated = true;
|
||||
break;
|
||||
}
|
||||
if (isSettingUpdated) break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name useDelAdvancedMult
|
||||
@description This function will delete a group of multiples in the template.
|
||||
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 template - Template with plugins list and detail settings
|
||||
@param multName - Input id to update
|
||||
@param groupName - Input value to update
|
||||
*/
|
||||
function useDelAdvancedMult(template, multName, groupName) {
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const plugin = template[i];
|
||||
const multiples = plugin?.multiples;
|
||||
if (!multiples) continue;
|
||||
if (!(multName in multiples)) continue;
|
||||
if (!(groupName in multiples[multName])) continue;
|
||||
delete multiples[multName][groupName];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name useAddAdvancedMult
|
||||
@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 template - Template with plugins list and detail settings
|
||||
@param multName - Input id to update
|
||||
*/
|
||||
function useAddAdvancedMult(template, multName) {
|
||||
// Get the right multiple schema
|
||||
let multipleSchema = {};
|
||||
let plugin;
|
||||
let nextGroupId;
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
plugin = template[i];
|
||||
const multiples = plugin?.multiples;
|
||||
if (!multiples) continue;
|
||||
if (!(multName in multiples)) continue;
|
||||
multipleSchema = plugin?.multiples_schema[multName];
|
||||
console.log(multipleSchema);
|
||||
// Get the highest id in Object.keys(plugin?.multiples[multName])
|
||||
nextGroupId = Math.max(...Object.keys(plugin?.multiples[multName])) + 1;
|
||||
if (!multipleSchema) return;
|
||||
break;
|
||||
}
|
||||
// Set the default values as value
|
||||
for (const [key, value] of Object.entries(multipleSchema)) {
|
||||
value.value = value.default;
|
||||
}
|
||||
// Add new group as first key of plugin.multiples.multName
|
||||
plugin.multiples[multName][nextGroupId] = multipleSchema;
|
||||
console.log(plugin.multiples[multName]);
|
||||
}
|
||||
|
||||
export {
|
||||
useForm,
|
||||
useFilter,
|
||||
isItemKeyword,
|
||||
isItemSelect,
|
||||
useCheckPluginsValidity,
|
||||
useUpdateTemp,
|
||||
useListenTempFields,
|
||||
useUnlistenTempFields,
|
||||
useDelAdvancedMult,
|
||||
useAddAdvancedMult,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,10 +52,31 @@ export default {
|
|||
"sm:flex-col",
|
||||
"md:flex-col",
|
||||
"lg:flex-col",
|
||||
"flex-col-reverse",
|
||||
"sm:flex-col-reverse",
|
||||
"md:flex-col-reverse",
|
||||
"lg:flex-col-reverse",
|
||||
"flex-row",
|
||||
"sm:flex-row",
|
||||
"md:flex-row",
|
||||
"lg:flex-row",
|
||||
"flex-row-reverse",
|
||||
"sm:flex-row-reverse",
|
||||
"md:flex-row-reverse",
|
||||
"lg:flex-row-reverse",
|
||||
"flex-wrap",
|
||||
"sm:flex-wrap",
|
||||
"md:flex-wrap",
|
||||
"lg:flex-wrap",
|
||||
"flex-wrap-reverse",
|
||||
"sm:flex-wrap-reverse",
|
||||
"md:flex-wrap-reverse",
|
||||
"lg:flex-wrap-reverse",
|
||||
"flex-nowrap",
|
||||
"sm:flex-nowrap",
|
||||
"md:flex-nowrap",
|
||||
"lg:flex-nowrap",
|
||||
|
||||
"justify-center",
|
||||
"sm:justify-center",
|
||||
"md:justify-center",
|
||||
|
|
@ -216,6 +237,10 @@ export default {
|
|||
"sm:m-2",
|
||||
"md:m-2",
|
||||
"lg:m-2",
|
||||
"mx-2",
|
||||
"sm:mx-2",
|
||||
"md:mx-2",
|
||||
"lg:mx-2",
|
||||
"pl-2",
|
||||
"sm:pl-2",
|
||||
"md:pl-2",
|
||||
|
|
@ -236,6 +261,10 @@ export default {
|
|||
"sm:p-2",
|
||||
"md:p-2",
|
||||
"lg:p-2",
|
||||
"px-2",
|
||||
"sm:px-2",
|
||||
"md:px-2",
|
||||
"lg:px-2",
|
||||
"scale-90",
|
||||
"scale-95",
|
||||
"w-fit",
|
||||
|
|
|
|||
23
src/ui/package-lock.json
generated
23
src/ui/package-lock.json
generated
|
|
@ -4,6 +4,7 @@
|
|||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ui",
|
||||
"dependencies": {
|
||||
"ace-builds": "^1.32.7",
|
||||
"dompurify": "^3.0.9",
|
||||
|
|
@ -167,11 +168,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -280,9 +282,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
|
|
@ -1104,10 +1107,12 @@
|
|||
}
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"camelcase-css": {
|
||||
|
|
@ -1184,7 +1189,9 @@
|
|||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
|
|
|
|||
Loading…
Reference in a new issue