mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
start raw format on both sides
This commit is contained in:
parent
db9bbeb99c
commit
bf10816c4a
14 changed files with 284 additions and 145 deletions
|
|
@ -291,7 +291,7 @@ body {
|
|||
}
|
||||
|
||||
.input-editor {
|
||||
@apply z-10 min-h-[200px] w-full;
|
||||
@apply z-10 min-h-[200px] h-full w-full;
|
||||
}
|
||||
|
||||
.disabled.input-editor {
|
||||
|
|
@ -307,7 +307,7 @@ body {
|
|||
}
|
||||
|
||||
.editor.input-clipboard-container {
|
||||
@apply top-2 right-4;
|
||||
@apply top-2 right-6;
|
||||
}
|
||||
|
||||
.pw-input.input-clipboard-container {
|
||||
|
|
@ -913,9 +913,10 @@ body {
|
|||
|
||||
/* CONTENT COMPONENT */
|
||||
|
||||
.content-text {
|
||||
@apply leading-normal text-base mb-0 lowercase;
|
||||
.text-content {
|
||||
@apply leading-normal mb-0 lowercase;
|
||||
}
|
||||
|
||||
/* CONTENT DETAIL LSIT COMPONENT */
|
||||
|
||||
.content-detail-list-container {
|
||||
|
|
@ -935,7 +936,7 @@ body {
|
|||
}
|
||||
|
||||
.content-stat {
|
||||
@apply my-1 font-bold dark:text-white/90 uppercase;
|
||||
@apply my-1 font-bold dark:text-white/90 text-black uppercase;
|
||||
}
|
||||
|
||||
/* TITLE */
|
||||
|
|
@ -1383,7 +1384,8 @@ body {
|
|||
.success.subtitle-card,
|
||||
.success.title-card,
|
||||
.success.title-container,
|
||||
.success.title-stat {
|
||||
.success.title-stat,
|
||||
.success.text-content {
|
||||
@apply text-green-500;
|
||||
}
|
||||
|
||||
|
|
@ -1391,7 +1393,8 @@ body {
|
|||
.error.subtitle-card,
|
||||
.error.title-card,
|
||||
.error.title-container,
|
||||
.error.title-stat {
|
||||
.error.title-stat,
|
||||
.error.text-content {
|
||||
@apply text-red-500;
|
||||
}
|
||||
|
||||
|
|
@ -1399,7 +1402,8 @@ body {
|
|||
.warning.subtitle-card,
|
||||
.warning.title-card,
|
||||
.warning.title-container,
|
||||
.warning.title-stat {
|
||||
.warning.title-stat,
|
||||
.warning.text-content {
|
||||
@apply text-yellow-500;
|
||||
}
|
||||
|
||||
|
|
@ -1407,7 +1411,8 @@ body {
|
|||
.info.subtitle-card,
|
||||
.info.title-card,
|
||||
.info.title-container,
|
||||
.info.title-stat {
|
||||
.info.title-stat,
|
||||
.info.text-content {
|
||||
@apply text-sky-500;
|
||||
}
|
||||
|
||||
|
|
@ -1415,7 +1420,8 @@ body {
|
|||
.purple.subtitle-card,
|
||||
.purple.title-card,
|
||||
.purple.title-container,
|
||||
.purple.title-stat {
|
||||
.purple.title-stat,
|
||||
.purple.text-content {
|
||||
@apply text-purple-500;
|
||||
}
|
||||
|
||||
|
|
@ -1423,7 +1429,8 @@ body {
|
|||
.green.subtitle-card,
|
||||
.green.title-card,
|
||||
.green.title-container,
|
||||
.green.title-stat {
|
||||
.green.title-stat,
|
||||
.green.text-content {
|
||||
@apply text-green-500;
|
||||
}
|
||||
|
||||
|
|
@ -1431,7 +1438,8 @@ body {
|
|||
.red.subtitle-card,
|
||||
.red.title-card,
|
||||
.red.title-container,
|
||||
.red.title-stat {
|
||||
.red.title-stat,
|
||||
.red.text-content {
|
||||
@apply text-red-500;
|
||||
}
|
||||
|
||||
|
|
@ -1439,7 +1447,8 @@ body {
|
|||
.orange.subtitle-card,
|
||||
.orange.title-card,
|
||||
.orange.title-container,
|
||||
.orange.title-stat {
|
||||
.orange.title-stat,
|
||||
.orange.text-content {
|
||||
@apply text-orange-500;
|
||||
}
|
||||
|
||||
|
|
@ -1447,7 +1456,8 @@ body {
|
|||
.blue.subtitle-card,
|
||||
.blue.title-card,
|
||||
.blue.title-container,
|
||||
.blue.title-stat {
|
||||
.blue.title-stat,
|
||||
.blue.text-content {
|
||||
@apply text-blue-500;
|
||||
}
|
||||
|
||||
|
|
@ -1455,7 +1465,8 @@ body {
|
|||
.yellow.subtitle-card,
|
||||
.yellow.title-card,
|
||||
.yellow.title-container,
|
||||
.yellow.title-stat {
|
||||
.yellow.title-stat,
|
||||
.yellow.text-content {
|
||||
@apply text-yellow-500;
|
||||
}
|
||||
|
||||
|
|
@ -1463,7 +1474,8 @@ body {
|
|||
.gray.subtitle-card,
|
||||
.gray.title-card,
|
||||
.gray.title-container,
|
||||
.gray.title-stat {
|
||||
.gray.title-stat,
|
||||
.gray.text-content {
|
||||
@apply text-gray-500;
|
||||
}
|
||||
|
||||
|
|
@ -1471,7 +1483,8 @@ body {
|
|||
.dark.subtitle-card,
|
||||
.dark.title-card,
|
||||
.dark.title-container,
|
||||
.dark.title-stat {
|
||||
.dark.title-stat,
|
||||
.dark.text-content {
|
||||
@apply text-slate-500;
|
||||
}
|
||||
|
||||
|
|
@ -1479,7 +1492,8 @@ body {
|
|||
.amber.subtitle-card,
|
||||
.amber.title-card,
|
||||
.amber.title-container,
|
||||
.amber.title-stat {
|
||||
.amber.title-stat,
|
||||
.amber.text-content {
|
||||
@apply text-amber-500;
|
||||
}
|
||||
|
||||
|
|
@ -1487,7 +1501,8 @@ body {
|
|||
.emerald.subtitle-card,
|
||||
.emerald.title-card,
|
||||
.emerald.title-container,
|
||||
.emerald.title-stat {
|
||||
.emerald.title-stat,
|
||||
.emerald.text-content {
|
||||
@apply text-emerald-500;
|
||||
}
|
||||
|
||||
|
|
@ -1495,7 +1510,8 @@ body {
|
|||
.teal.subtitle-card,
|
||||
.teal.title-card,
|
||||
.teal.title-container,
|
||||
.teal.title-stat {
|
||||
.teal.title-stat,
|
||||
.teal.text-content {
|
||||
@apply text-teal-500;
|
||||
}
|
||||
|
||||
|
|
@ -1503,7 +1519,8 @@ body {
|
|||
.indigo.subtitle-card,
|
||||
.indigo.title-card,
|
||||
.indigo.title-container,
|
||||
.indigo.title-stat {
|
||||
.indigo.title-stat,
|
||||
.indigo.text-content {
|
||||
@apply text-indigo-500;
|
||||
}
|
||||
|
||||
|
|
@ -1511,7 +1528,8 @@ body {
|
|||
.cyan.subtitle-card,
|
||||
.cyan.title-card,
|
||||
.cyan.title-container,
|
||||
.cyan.title-stat {
|
||||
.cyan.title-stat,
|
||||
.cyan.text-content {
|
||||
@apply text-cyan-500;
|
||||
}
|
||||
|
||||
|
|
@ -1519,7 +1537,8 @@ body {
|
|||
.sky.subtitle-card,
|
||||
.sky.title-card,
|
||||
.sky.title-container,
|
||||
.sky.title-stat {
|
||||
.sky.title-stat,
|
||||
.sky.text-content {
|
||||
@apply text-sky-500;
|
||||
}
|
||||
|
||||
|
|
@ -1527,7 +1546,8 @@ body {
|
|||
.pink.subtitle-card,
|
||||
.pink.title-card,
|
||||
.pink.title-container,
|
||||
.pink.title-stat {
|
||||
.pink.title-stat,
|
||||
.pink.text-content {
|
||||
@apply text-pink-500;
|
||||
}
|
||||
|
||||
|
|
@ -1535,7 +1555,8 @@ body {
|
|||
.lime.subtitle-card,
|
||||
.lime.title-card,
|
||||
.lime.title-container,
|
||||
.lime.title-stat {
|
||||
.lime.title-stat,
|
||||
.lime.text-content {
|
||||
@apply text-lime-500;
|
||||
}
|
||||
|
||||
|
|
@ -1543,7 +1564,8 @@ body {
|
|||
.purple.subtitle-card,
|
||||
.purple.title-card,
|
||||
.purple.title-container,
|
||||
.purple.title-stat {
|
||||
.purple.title-stat,
|
||||
.purple.text-content {
|
||||
@apply text-purple-600;
|
||||
}
|
||||
|
||||
|
|
@ -1551,7 +1573,8 @@ body {
|
|||
.green-dark.subtitle-card,
|
||||
.green-dark.title-card,
|
||||
.green-dark.title-container,
|
||||
.green-dark.title-stat {
|
||||
.green-dark.title-stat,
|
||||
.green-darker.text-content {
|
||||
@apply text-green-700;
|
||||
}
|
||||
|
||||
|
|
@ -1559,7 +1582,8 @@ body {
|
|||
.red-darker.subtitle-card,
|
||||
.red-darker.title-card,
|
||||
.red-darker.title-container,
|
||||
.red-darker.title-stat {
|
||||
.red-darker.title-stat,
|
||||
.red-darker.text-content {
|
||||
@apply text-red-700;
|
||||
}
|
||||
|
||||
|
|
@ -1567,7 +1591,8 @@ body {
|
|||
.orange-darker.subtitle-card,
|
||||
.orange-darker.title-card,
|
||||
.orange-darker.title-container,
|
||||
.orange-darker.title-stat {
|
||||
.orange-darker.title-stat,
|
||||
.orange-darker.text-content {
|
||||
@apply text-orange-600;
|
||||
}
|
||||
|
||||
|
|
@ -1575,7 +1600,8 @@ body {
|
|||
.blue-darker.subtitle-card,
|
||||
.blue-darker.title-card,
|
||||
.blue-darker.title-container,
|
||||
.blue-darker.title-stat {
|
||||
.blue-darker.title-stat,
|
||||
.blue-darker.text-content {
|
||||
@apply text-blue-600;
|
||||
}
|
||||
|
||||
|
|
@ -1583,7 +1609,8 @@ body {
|
|||
.yellow-darker.subtitle-card,
|
||||
.yellow-darker.title-card,
|
||||
.yellow-darker.title-container,
|
||||
.yellow-darker.title-stat {
|
||||
.yellow-darker.title-stat,
|
||||
.yellow-darker.text-content {
|
||||
@apply text-yellow-600;
|
||||
}
|
||||
|
||||
|
|
@ -1591,7 +1618,8 @@ body {
|
|||
.gray-darker.subtitle-card,
|
||||
.gray-darker.title-card,
|
||||
.gray-darker.title-container,
|
||||
.gray-darker.title-stat {
|
||||
.gray-darker.title-stat,
|
||||
.gray-darker.text-content {
|
||||
@apply text-gray-600;
|
||||
}
|
||||
|
||||
|
|
@ -1599,7 +1627,8 @@ body {
|
|||
.dark-darker.subtitle-card,
|
||||
.dark-darker.title-card,
|
||||
.dark-darker.title-container,
|
||||
.dark-darker.title-stat {
|
||||
.dark-darker.title-stat,
|
||||
.dark-darker.text-content {
|
||||
@apply text-slate-600;
|
||||
}
|
||||
|
||||
|
|
@ -1607,7 +1636,8 @@ body {
|
|||
.amber-darker.subtitle-card,
|
||||
.amber-darker.title-card,
|
||||
.amber-darker.title-container,
|
||||
.amber-darker.title-stat {
|
||||
.amber-darker.title-stat,
|
||||
.amber-darker.text-content {
|
||||
@apply text-amber-600;
|
||||
}
|
||||
|
||||
|
|
@ -1615,7 +1645,8 @@ body {
|
|||
.emerald-darker.subtitle-card,
|
||||
.emerald-darker.title-card,
|
||||
.emerald-darker.title-container,
|
||||
.emerald-darker.title-stat {
|
||||
.emerald-darker.title-stat,
|
||||
.emerald-darker.text-content {
|
||||
@apply text-emerald-600;
|
||||
}
|
||||
|
||||
|
|
@ -1623,7 +1654,8 @@ body {
|
|||
.teal-darker.subtitle-card,
|
||||
.teal-darker.title-card,
|
||||
.teal-darker.title-container,
|
||||
.teal-darker.title-stat {
|
||||
.teal-darker.title-stat,
|
||||
.teal-darker.text-content {
|
||||
@apply text-teal-600;
|
||||
}
|
||||
|
||||
|
|
@ -1631,7 +1663,8 @@ body {
|
|||
.indigo-darker.subtitle-card,
|
||||
.indigo-darker.title-card,
|
||||
.indigo-darker.title-container,
|
||||
.indigo-darker.title-stat {
|
||||
.indigo-darker.title-stat,
|
||||
.indigo-darker.text-content {
|
||||
@apply text-indigo-600;
|
||||
}
|
||||
|
||||
|
|
@ -1639,7 +1672,8 @@ body {
|
|||
.cyan-darker.subtitle-card,
|
||||
.cyan-darker.title-card,
|
||||
.cyan-darker.title-container,
|
||||
.cyan-darker.title-stat {
|
||||
.cyan-darker.title-stat,
|
||||
.cyan-darker.text-content {
|
||||
@apply text-cyan-600;
|
||||
}
|
||||
|
||||
|
|
@ -1647,7 +1681,8 @@ body {
|
|||
.sky-darker.subtitle-card,
|
||||
.sky-darker.title-card,
|
||||
.sky-darker.title-container,
|
||||
.sky-darker.title-stat {
|
||||
.sky-darker.title-stat,
|
||||
.sky-darker.text-content {
|
||||
@apply text-sky-700;
|
||||
}
|
||||
|
||||
|
|
@ -1655,7 +1690,8 @@ body {
|
|||
.pink-darker.subtitle-card,
|
||||
.pink-darker.title-card,
|
||||
.pink-darker.title-container,
|
||||
.pink-darker.title-stat {
|
||||
.pink-darker.title-stat,
|
||||
.pink-darker.text-content {
|
||||
@apply text-pink-600;
|
||||
}
|
||||
|
||||
|
|
@ -1663,7 +1699,8 @@ body {
|
|||
.lime-darker.subtitle-card,
|
||||
.lime-darker.title-card,
|
||||
.lime-darker.title-container,
|
||||
.lime-darker.title-stat {
|
||||
.lime-darker.title-stat,
|
||||
.lime-darker.text-content {
|
||||
@apply text-lime-600;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
@param {string} stat - The stat value. Can be a translation key or by default raw text.
|
||||
@param {string} [statClass=""] - Additional class, useful when component is used directly on a grid system
|
||||
@param {string} [tag="p"] - The tag of the stat. Can be p, span, div, h1, h2, h3, h4, h5, h6
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -23,11 +24,16 @@ const props = defineProps({
|
|||
required: false,
|
||||
default: "",
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "p",
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h5 :class="['content-stat', props.statClass]">
|
||||
<component :is="props.tag" :class="['content-stat', props.statClass]">
|
||||
{{ $t(props.stat, props.stat) }}
|
||||
</h5>
|
||||
</component>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -5,36 +5,20 @@ import Title from "@components/Widget/Title.vue";
|
|||
import Subtitle from "@components/Widget/Subtitle.vue";
|
||||
import Editor from "@components/Forms/Field/Editor.vue";
|
||||
import Button from "@components/Widget/Button.vue";
|
||||
import Text from "@components/Widget/Text.vue";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
/**
|
||||
@name Form/Advanced.vue
|
||||
@description This component is used to create a complete advanced form with plugin selection.
|
||||
@name Form/RAW.vue
|
||||
@description This component is used to create a complete raw form with settings as JSON format.
|
||||
@example
|
||||
template: [
|
||||
{
|
||||
columns: { pc: 6, tablet: 12, mobile: 12 },
|
||||
id: "test-check",
|
||||
value: "yes",
|
||||
label: "Checkbox",
|
||||
name: "checkbox",
|
||||
required: true,
|
||||
hideLabel: false,
|
||||
headerClass: "text-red-500",
|
||||
inpType: "checkbox",
|
||||
},
|
||||
{
|
||||
id: "test-input",
|
||||
value: "yes",
|
||||
type: "text",
|
||||
name: "test-input",
|
||||
disabled: false,
|
||||
required: true,
|
||||
label: "Test input",
|
||||
pattern: "(test)",
|
||||
inpType: "input",
|
||||
},
|
||||
],
|
||||
{
|
||||
"IS_LOADING": "no",
|
||||
"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
|
||||
@param {object} columns - Columns object.
|
||||
|
|
@ -60,28 +44,81 @@ const props = defineProps({
|
|||
});
|
||||
|
||||
const data = reactive({
|
||||
format: computed(() => {
|
||||
const dataStr = JSON.stringify(props.template);
|
||||
// Add a new line after the comma
|
||||
return dataStr.replace(/,/g, ",\n");
|
||||
str: JSON.stringify(props.template),
|
||||
// Data on creation of editor
|
||||
entry: computed(() => {
|
||||
// TODO : WORK WITH LINE LOOP
|
||||
// ONLY REPLACE FIRST ':' IS REPLACED (IN CASE VALUE CONTAIN ':')
|
||||
let dataStr = data.str;
|
||||
// Remove first and last curly brackets
|
||||
dataStr = dataStr.slice(1, -1);
|
||||
// Remove all '\"' from stringified JSON
|
||||
dataStr = dataStr.replace(/\\"/g, '"');
|
||||
// Remove all newlines
|
||||
dataStr = dataStr.replace(/\n/g, "");
|
||||
// Add new line only at the end of each key value
|
||||
dataStr = dataStr.replace(/",/g, "\n");
|
||||
// Replace ":" with "=" when between quotes ""
|
||||
dataStr = dataStr.replace(/":"/g, "=");
|
||||
// Remove quotes before a new line
|
||||
dataStr = dataStr.replace(/\n"/g, "\n");
|
||||
// Remove first char if it is a quote
|
||||
dataStr = dataStr[0] === '"' ? dataStr.slice(1) : dataStr;
|
||||
// Remove last char if it is a quote
|
||||
dataStr = dataStr.slice(-1) === '"' ? dataStr.slice(0, -1) : dataStr;
|
||||
|
||||
return dataStr;
|
||||
}),
|
||||
// Data retrieve from editor after creation
|
||||
inp: "",
|
||||
isValid: computed(() => {
|
||||
// Transform to a possible valid JSON
|
||||
let dataToCheck = data.inp || data.entry;
|
||||
// Replace quotes "" with quotes ''
|
||||
dataToCheck = dataToCheck.replace(/"/g, "'");
|
||||
// loop on each line
|
||||
dataToCheck = dataToCheck.split("\n");
|
||||
let jsonReady = "";
|
||||
dataToCheck = dataToCheck.map((line) => {
|
||||
// Get index of the first equal sign
|
||||
const index = line.indexOf("=");
|
||||
// Update at this index with a colon
|
||||
jsonReady +=
|
||||
'"' + line.slice(0, index) + '":"' + line.slice(index + 1) + '",';
|
||||
});
|
||||
|
||||
jsonReady = "{" + jsonReady.slice(0, -1) + "}";
|
||||
try {
|
||||
JSON.parse(jsonReady);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
const editorData = {
|
||||
value: data.format,
|
||||
name: "test-editor",
|
||||
label: "Test editor",
|
||||
value: data.inp || data.entry,
|
||||
name: uuidv4(),
|
||||
label: uuidv4(),
|
||||
hideLabel: true,
|
||||
columns: { pc: 12, tablet: 12, mobile: 12 },
|
||||
editorClass: "min-h-96",
|
||||
};
|
||||
|
||||
const buttonSave = {
|
||||
id: uuidv4(),
|
||||
text: "action_save",
|
||||
disabled: false,
|
||||
color: "success",
|
||||
size: "normal",
|
||||
type: "submit",
|
||||
containerClass: "flex justify-center",
|
||||
attrs: data.isValid
|
||||
? {
|
||||
"data-submit-form":
|
||||
data.inp.replace(/\n/g, "") || data.entry.replace(/\n/g, ""),
|
||||
}
|
||||
: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -92,11 +129,17 @@ const buttonSave = {
|
|||
:containerClass="`col-span-12 w-full m-1 p-1`"
|
||||
:columns="props.columns"
|
||||
>
|
||||
{{ data.isValid ? "Valid" : "Not Valid" }}
|
||||
<Title type="card" :title="'dashboard_raw_mode'" />
|
||||
<Subtitle type="card" :subtitle="'dashboard_raw_mode_subtitle'" />
|
||||
<Container class="col-span-12 w-full">
|
||||
<Editor v-bind="editorData" />
|
||||
<Editor @inp="(v) => (data.inp = v)" v-bind="editorData" />
|
||||
</Container>
|
||||
<Button v-bind="buttonSave" />
|
||||
<Button :disabled="data.isValid ? false : true" v-bind="buttonSave" />
|
||||
<Text
|
||||
v-if="!data.isValid"
|
||||
:text="'dashboard_raw_invalid'"
|
||||
:textClass="'text-center error'"
|
||||
/>
|
||||
</Container>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -276,6 +276,8 @@ onMounted(() => {
|
|||
editorEl.readOnlyBool(props.disabled);
|
||||
editorEl.editor.on("change", () => {
|
||||
editor.value = editorEl.getValue();
|
||||
// emit inp
|
||||
emits("inp", editor.value);
|
||||
});
|
||||
// Add tabindex to editor
|
||||
try {
|
||||
|
|
@ -321,7 +323,11 @@ onUnmounted(() => {
|
|||
class="input-editor-error"
|
||||
></div>
|
||||
<div
|
||||
:class="['input-editor', props.disabled ? 'disabled' : 'enabled']"
|
||||
:class="[
|
||||
'input-editor',
|
||||
props.disabled ? 'disabled' : 'enabled',
|
||||
props.editorClass,
|
||||
]"
|
||||
:aria-description="$t('inp_editor_desc')"
|
||||
:id="props.id"
|
||||
></div>
|
||||
|
|
|
|||
|
|
@ -115,6 +115,12 @@ onMounted(() => {
|
|||
|
||||
function setAttrs() {
|
||||
for (const [key, value] of Object.entries(props.attrs)) {
|
||||
// stringify if object
|
||||
if (typeof value === "object") {
|
||||
btnEl.value.setAttribute(key, JSON.stringify(value));
|
||||
continue;
|
||||
}
|
||||
|
||||
btnEl.value.setAttribute(key, value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import { v4 as uuidv4 } from "uuid";
|
|||
size: "normal",
|
||||
iconName: "modal",
|
||||
iconColor: "white",
|
||||
eventAttr: {"store" : "modal", "value" : "open", "target" : "modal_id", "valueExpanded" : "open"},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ const props = defineProps({
|
|||
props.iconName ? 'is-icon' : 'no-icon',
|
||||
]"
|
||||
>
|
||||
<Title type="stat" :title="props.title" />
|
||||
<Title :tag="'h3'" type="stat" :title="props.title" />
|
||||
<ContentStat :stat="props.stat" />
|
||||
<Subtitle
|
||||
type="stat"
|
||||
|
|
|
|||
|
|
@ -1,31 +1,37 @@
|
|||
<script setup>
|
||||
/**
|
||||
@name Content/Text.vue
|
||||
@description This component is used for regular paragraph.
|
||||
@example
|
||||
{
|
||||
text: "This is a paragraph",
|
||||
textClass: "text-3xl"
|
||||
}
|
||||
@param {string} text - The text value. Can be a translation key or by default raw text.
|
||||
@param {string} [textClass=""] - Additional class if needef
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
text: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
textClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h5 :class="['content-text', props.textClass]">
|
||||
{{ $t(props.text, props.text) }}
|
||||
</h5>
|
||||
</template>
|
||||
<script setup>
|
||||
/**
|
||||
@name Widget/Text.vue
|
||||
@description This component is used for regular paragraph.
|
||||
@example
|
||||
{
|
||||
text: "This is a paragraph",
|
||||
textClass: "text-3xl"
|
||||
}
|
||||
@param {string} text - The text value. Can be a translation key or by default raw text.
|
||||
@param {string} [textClass=""] - Additional class if needed
|
||||
@param {string} [tag="p"] - The tag of the text. Can be p, span, div, h1, h2, h3, h4, h5, h6
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
text: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
textClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "",
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "p",
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component :is="props.tag" :class="['text-content', props.textClass]">
|
||||
{{ $t(props.text, props.text) }}
|
||||
</component>
|
||||
</template>
|
||||
|
|
@ -84,6 +84,7 @@
|
|||
"dashboard_status_info": "status loading or waiting or unknown.",
|
||||
"dashboard_raw_mode": "raw mode",
|
||||
"dashboard_raw_mode_subtitle": "Raw mode shows settings as raw key-value pairs of settings.",
|
||||
"dashboard_raw_invalid": "Invalid raw format. Impossible to save.",
|
||||
"dashboard_advanced_mode": "Advanced mode",
|
||||
"dashboard_advanced_mode_subtitle": "Advanced mode show settings by plugin in dedicated fields.",
|
||||
"inp_input_valid": "input valid",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
data-server-flash='[{"type" : "success", "title" : "title", "message" : "Success feedback"}, {"type" : "error", "title" : "title", "message" : "Error feedback"}, {"type" : "warning", "title" : "title", "message" : "Warning feedback"}, {"type" : "info", "title" : "title", "message" : "Info feedback"}]'>
|
||||
</div>
|
||||
<div class="hidden"
|
||||
data-server-builder='[{"type":"card","containerColumns":{"pc":6,"tablet":6,"mobile":12},"widgets":[{"type":"Instance","data":{"details":[{"key":"instances_hostname","value":"bunkerweb"},{"key":"instances_type","value":"manual"},{"key":"instances_status","value":"instances_active"}],"status":"success","title":"bunkerweb","buttons":[{"attrs":{"data-form-INSTANCE_ID":"bunkerweb","data-form-operation":"reload","data-submit-form":"true"},"text":"action_reload","color":"warning","size":"normal"},{"attrs":{"data-form-INSTANCE_ID":"bunkerweb","data-form-operation":"stop","data-submit-form":"true"},"text":"action_stop","color":"error","size":"normal"}]}}]}]'>
|
||||
data-server-builder='[{"type":"card","containerColumns":{"pc":6,"tablet":6,"mobile":12},"widgets":[{"type":"Instance","data":{"details":[{"key":"instances_hostname","value":"bunkerweb"},{"key":"instances_type","value":"manual"},{"key":"instances_status","value":"instances_active"}],"status":"success","title":"bunkerweb","buttons":[{"attrs":{"data-submit-form": {"operation" : "reload", "INSTANCE_ID" : "bunkerweb"} },"text":"action_reload","color":"warning","size":"normal"},{"attrs":{"data-submit-form": { "operation" : "stop", "INSTANCE_ID" : "bunkerweb"} },"text":"action_stop","color":"error","size":"normal"}]}}]}]'>
|
||||
</div>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="instances.js"></script>
|
||||
|
|
|
|||
|
|
@ -7,13 +7,17 @@
|
|||
/**
|
||||
@name useForm
|
||||
@description This function is a composable wrapper that contains all the form utils functions.
|
||||
This function will for example look for elements with data-submit-form attribute and submit the form with the data attributes.
|
||||
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.
|
||||
*/
|
||||
function useForm() {
|
||||
window.addEventListener("click", (e) => {
|
||||
if (!e.target.hasAttribute("data-submit-form")) return;
|
||||
const data = useGetFormDataAttr(e.target);
|
||||
useSubmitForm(data);
|
||||
try {
|
||||
const data = JSON.parse(e.target.getAttribute("data-submit-form"));
|
||||
useSubmitForm(data);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -50,29 +54,9 @@ function useSubmitForm(data) {
|
|||
}
|
||||
// Append the form to the body and submit it
|
||||
document.querySelector("body").appendChild(form);
|
||||
console.log(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
@name useGetFormDataAttr
|
||||
@description Get the form data store on attributes of the element.
|
||||
Format is data-form-<key>="<value>"
|
||||
@example document.querySelector("[data-submit-form]")
|
||||
@param {DOMElement} el - Element to get the data attributes.
|
||||
*/
|
||||
function useGetFormDataAttr(el) {
|
||||
const data = {};
|
||||
const attributes = el.attributes;
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
if (attributes[i].name.includes("data-form-")) {
|
||||
const key = attributes[i].name.replace("data-form-", "");
|
||||
data[key] = attributes[i].value;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
@name useFilter
|
||||
@description Filter keys of an items list of objects with filters.
|
||||
|
|
|
|||
|
|
@ -132,6 +132,58 @@ export default {
|
|||
"sm:place-content-between",
|
||||
"md:place-content-between",
|
||||
"lg:place-content-between",
|
||||
"text-base",
|
||||
"sm:text-base",
|
||||
"md:text-base",
|
||||
"lg:text-base",
|
||||
"text-sm",
|
||||
"sm:text-sm",
|
||||
"md:text-sm",
|
||||
"lg:text-sm",
|
||||
"text-lg",
|
||||
"sm:text-lg",
|
||||
"md:text-lg",
|
||||
"lg:text-lg",
|
||||
"text-xl",
|
||||
"sm:text-xl",
|
||||
"md:text-xl",
|
||||
"lg:text-xl",
|
||||
"text-2xl",
|
||||
"sm:text-2xl",
|
||||
"md:text-2xl",
|
||||
"lg:text-2xl",
|
||||
"text-3xl",
|
||||
"sm:text-3xl",
|
||||
"md:text-3xl",
|
||||
"lg:text-3xl",
|
||||
"text-center",
|
||||
"sm:text-center",
|
||||
"md:text-center",
|
||||
"lg:text-center",
|
||||
"text-left",
|
||||
"sm:text-left",
|
||||
"md:text-left",
|
||||
"lg:text-left",
|
||||
"text-right",
|
||||
"sm:text-right",
|
||||
"md:text-right",
|
||||
"lg:text-right",
|
||||
"min-h-screen",
|
||||
"sm:min-h-screen",
|
||||
"md:min-h-screen",
|
||||
"lg:min-h-screen",
|
||||
"h-full",
|
||||
"sm:h-full",
|
||||
"md:h-full",
|
||||
"lg:h-full",
|
||||
"min-h-96",
|
||||
"sm:min-h-96",
|
||||
"md:min-h-96",
|
||||
"lg:min-h-96",
|
||||
"w-full",
|
||||
"sm:w-full",
|
||||
"md:w-full",
|
||||
"lg:w-full",
|
||||
],
|
||||
important: true,
|
||||
darkMode: "class",
|
||||
|
|
|
|||
|
|
@ -91,14 +91,13 @@ def set_raw(template, plugins_data):
|
|||
# Update settings with global config data
|
||||
for plugin in plugins :
|
||||
for setting, value in plugin.get("settings").items() :
|
||||
value["value"] = value.get("default")
|
||||
|
||||
# check if setting is in template
|
||||
# avoid some methods
|
||||
if value.get("method", "default") not in ("ui", "default", "manual") :
|
||||
continue
|
||||
# check if setting is in template (not a default value)
|
||||
if setting in settings :
|
||||
# Update value or set default as value
|
||||
value["value"] = settings[setting].get("value", value.get("default"))
|
||||
|
||||
raw_settings[setting] = value.get("value", value.get("default"))
|
||||
raw_settings[setting] = value.get("value", value.get("default"))
|
||||
|
||||
return raw_settings
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue