mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
add icons + modal working + start actions modal
* add icons to fit services table actions * update modal and button component, they work together * enhance modal content components style * start actions modal ui components : manage, draft/online and delete done, starting plugins status * update services builder * add i18n for services page * add utils
This commit is contained in:
parent
27f55edf3c
commit
1bf72bb55c
29 changed files with 526 additions and 411 deletions
|
|
@ -12,7 +12,7 @@ import Filter from "@components/Widget/Filter.vue";
|
|||
import GroupMultiple from "@components/Forms/Group/Multiple.vue";
|
||||
import { plugin_types } from "@utils/variables";
|
||||
import { useAdvancedForm } from "@store/form.js";
|
||||
import { useCheckPluginsValidity } from "@utils/form.js";
|
||||
import { useCheckPluginsValidity } from "@utils/global.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,7 +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 } from "@utils/form.js";
|
||||
import { useCheckPluginsValidity } from "@utils/global.js";
|
||||
import { useEasyForm } from "@store/form.js";
|
||||
|
||||
/**
|
||||
|
|
|
|||
52
src/ui/client/dashboard/components/Icons/Document.vue
Normal file
52
src/ui/client/dashboard/components/Icons/Document.vue
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<script setup>
|
||||
import { defineProps, reactive } from "vue";
|
||||
/**
|
||||
@name Icons/Document.vue
|
||||
@description This component is a svg icon representing document.
|
||||
@example
|
||||
{
|
||||
color: 'orange',
|
||||
}
|
||||
@param {string} [iconClass="icon-default"] - The class of the icon.
|
||||
@param {string} [color="cyan"] - The color of the icon between some tailwind css available colors (purple, green, red, orange, blue, yellow, gray, dark, amber, emerald, teal, indigo, cyan, sky, pink...). Darker colors are also available using the base color and adding '-darker' (e.g. 'red-darker').
|
||||
@param {boolean} [disabled=false] - If true, the icon will be disabled.
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "icon-default",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "cyan",
|
||||
},
|
||||
disabled: { type: Boolean, required: false, default: false },
|
||||
});
|
||||
|
||||
const icon = reactive({
|
||||
color: props.color || "cyan",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<svg
|
||||
:data-color="icon.color"
|
||||
:aria-disabled="props.disabled ? 'true' : 'false'"
|
||||
data-svg="document"
|
||||
role="img"
|
||||
aria-hidden="true"
|
||||
:class="[props.iconClass, icon.color, 'fill']"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0 0 16.5 9h-1.875a1.875 1.875 0 0 1-1.875-1.875V5.25A3.75 3.75 0 0 0 9 1.5H5.625Z"
|
||||
/>
|
||||
<path
|
||||
d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
52
src/ui/client/dashboard/components/Icons/Eye.vue
Normal file
52
src/ui/client/dashboard/components/Icons/Eye.vue
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<script setup>
|
||||
import { defineProps, reactive } from "vue";
|
||||
/**
|
||||
@name Icons/Eye.vue
|
||||
@description This component is a svg icon representing eye.
|
||||
@example
|
||||
{
|
||||
color: 'green',
|
||||
}
|
||||
@param {string} [iconClass="icon-default"] - The class of the icon.
|
||||
@param {string} [color="cyan"] - The color of the icon between some tailwind css available colors (purple, green, red, orange, blue, yellow, gray, dark, amber, emerald, teal, indigo, cyan, sky, pink...). Darker colors are also available using the base color and adding '-darker' (e.g. 'red-darker').
|
||||
@param {boolean} [disabled=false] - If true, the icon will be disabled.
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "icon-default",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "green",
|
||||
},
|
||||
disabled: { type: Boolean, required: false, default: false },
|
||||
});
|
||||
|
||||
const icon = reactive({
|
||||
color: props.color || "green",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<svg
|
||||
:data-color="icon.color"
|
||||
:aria-disabled="props.disabled ? 'true' : 'false'"
|
||||
data-svg="document"
|
||||
role="img"
|
||||
aria-hidden="true"
|
||||
:class="[props.iconClass, icon.color, 'fill']"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M1.323 11.447C2.811 6.976 7.028 3.75 12.001 3.75c4.97 0 9.185 3.223 10.675 7.69.12.362.12.752 0 1.113-1.487 4.471-5.705 7.697-10.677 7.697-4.97 0-9.186-3.223-10.675-7.69a1.762 1.762 0 0 1 0-1.113ZM17.25 12a5.25 5.25 0 1 1-10.5 0 5.25 5.25 0 0 1 10.5 0Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
|
@ -43,9 +43,10 @@ const icon = reactive({
|
|||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
|
||||
d="M21.731 2.269a2.625 2.625 0 0 0-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 0 0 0-3.712ZM19.513 8.199l-3.712-3.712-8.4 8.4a5.25 5.25 0 0 0-1.32 2.214l-.8 2.685a.75.75 0 0 0 .933.933l2.685-.8a5.25 5.25 0 0 0 2.214-1.32l8.4-8.4Z"
|
||||
/>
|
||||
<path
|
||||
d="M5.25 5.25a3 3 0 0 0-3 3v10.5a3 3 0 0 0 3 3h10.5a3 3 0 0 0 3-3V13.5a.75.75 0 0 0-1.5 0v5.25a1.5 1.5 0 0 1-1.5 1.5H5.25a1.5 1.5 0 0 1-1.5-1.5V8.25a1.5 1.5 0 0 1 1.5-1.5h5.25a.75.75 0 0 0 0-1.5H5.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import { contentIndex } from "@utils/tabindex.js";
|
|||
import Container from "@components/Widget/Container.vue";
|
||||
import Icons from "@components/Widget/Icons.vue";
|
||||
import { useUUID } from "@utils/global.js";
|
||||
import { useForm } from "@utils/form.js";
|
||||
/**
|
||||
@name Widget/Button.vue
|
||||
@description This component is a standard button.
|
||||
|
|
@ -136,7 +135,6 @@ onBeforeMount(() => {
|
|||
});
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("click", useForm);
|
||||
// Case modal, add accessibility data
|
||||
if (typeof props.modal === "object") {
|
||||
btnEl.value.setAttribute("aria-controls", btn.modalId);
|
||||
|
|
@ -156,10 +154,6 @@ watch(
|
|||
}
|
||||
}
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("click", useForm);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -209,6 +203,7 @@ onUnmounted(() => {
|
|||
v-if="btn.openModal"
|
||||
:widgets="props.modal.widgets"
|
||||
:isOpen="btn.openModal"
|
||||
@close="btn.openModal = false"
|
||||
/>
|
||||
</Container>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -64,6 +64,15 @@ onMounted(() => {
|
|||
.closest("[data-is]")
|
||||
.getAttribute("data-is")}`
|
||||
: "button-group-default";
|
||||
|
||||
// Additionnal class for modal
|
||||
if (group.class.includes("modal")) {
|
||||
// Check if next sibling exists
|
||||
// Else, this is the last element, we can add a margin top because this is main modal action buttons
|
||||
if (!groupEl.value.nextElementSibling) {
|
||||
group.class += " last";
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<script setup>
|
||||
import { defineProps, reactive, onMounted, ref, computed } from "vue";
|
||||
import { useEqualStr } from "@utils/global.js";
|
||||
import Box from "@components/Icons/Box.vue";
|
||||
import Carton from "@components/Icons/Carton.vue";
|
||||
import Core from "@components/Icons/Core.vue";
|
||||
|
|
@ -33,6 +34,9 @@ import Lock from "@components/Icons/Lock.vue";
|
|||
import Search from "@components/Icons/Search.vue";
|
||||
import Exclamation from "@components/Icons/Exclamation.vue";
|
||||
import Close from "@components/Icons/Close.vue";
|
||||
import Pen from "@components/Icons/Pen.vue";
|
||||
import Document from "@components/Icons/Document.vue";
|
||||
import Eye from "@components/Icons/Eye.vue";
|
||||
|
||||
/**
|
||||
@name Widget/Icons.vue
|
||||
|
|
@ -81,14 +85,13 @@ const props = defineProps({
|
|||
|
||||
const icon = reactive({
|
||||
color: props.color,
|
||||
class: props.iconClass,
|
||||
name: computed(() => props.iconName.toLowerCase()),
|
||||
iconClass: props.iconClass,
|
||||
});
|
||||
|
||||
const iconEl = ref();
|
||||
|
||||
onMounted(() => {
|
||||
icon.class =
|
||||
icon.iconClass =
|
||||
props.iconClass || iconEl.value.closest("[data-is]")
|
||||
? `icon-${iconEl.value.closest("[data-is]").getAttribute("data-is")}`
|
||||
: "icon-default";
|
||||
|
|
@ -97,197 +100,43 @@ onMounted(() => {
|
|||
<template>
|
||||
<div ref="iconEl" :class="[props.isStick ? 'stick' : '', 'icon-container']">
|
||||
<Exclamation
|
||||
v-if="icon.name === 'exclamation'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
v-if="useEqualStr(props.iconName, 'exclamation')"
|
||||
v-bind="icon"
|
||||
/>
|
||||
<Box
|
||||
v-if="icon.name === 'box'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Carton
|
||||
v-if="icon.name === 'carton'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Core
|
||||
v-if="icon.name === 'core'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<External
|
||||
v-if="icon.name === 'external'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Search
|
||||
v-if="icon.name === 'search'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Trash
|
||||
v-if="icon.name === 'trash'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Lock
|
||||
v-if="icon.name === 'lock'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Crown
|
||||
v-if="icon.name === 'crown'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Discord
|
||||
v-if="icon.name === 'discord'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Disk
|
||||
v-if="icon.name === 'disk'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Disks
|
||||
v-if="icon.name === 'disks'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Globe
|
||||
v-if="icon.name === 'globe'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Info
|
||||
v-if="icon.name === 'info'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Flag
|
||||
v-if="icon.name === 'flag'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Gear
|
||||
v-if="icon.name === 'gear'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Github
|
||||
v-if="icon.name === 'github'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<House
|
||||
v-if="icon.name === 'house'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<List
|
||||
v-if="icon.name === 'list'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Key
|
||||
v-if="icon.name === 'key'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Linkedin
|
||||
v-if="icon.name === 'linkedin'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Plus
|
||||
v-if="icon.name === 'plus'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Puzzle
|
||||
v-if="icon.name === 'puzzle'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Settings
|
||||
v-if="icon.name === 'settings'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Task
|
||||
v-if="icon.name === 'task'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Trespass
|
||||
v-if="icon.name === 'trespass'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Check
|
||||
v-if="icon.name === 'check'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Cross
|
||||
v-if="icon.name === 'cross'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Twitter
|
||||
v-if="icon.name === 'twitter'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Wire
|
||||
v-if="icon.name === 'wire'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Funnel
|
||||
v-if="icon.name === 'funnel'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Redirect
|
||||
v-if="icon.name === 'redirect'"
|
||||
:iconClass="icon.class"
|
||||
:color="props.color"
|
||||
:disabled="props.disabled"
|
||||
/>
|
||||
<Close v-if="icon.name === 'close'" :iconClass="icon.class" />
|
||||
<Box v-if="useEqualStr(props.iconName, 'box')" v-bind="icon" />
|
||||
<Carton v-if="useEqualStr(props.iconName, 'carton')" v-bind="icon" />
|
||||
<Core v-if="useEqualStr(props.iconName, 'core')" v-bind="icon" />
|
||||
<External v-if="useEqualStr(props.iconName, 'external')" v-bind="icon" />
|
||||
<Search v-if="useEqualStr(props.iconName, 'search')" v-bind="icon" />
|
||||
<Trash v-if="useEqualStr(props.iconName, 'trash')" v-bind="icon" />
|
||||
<Lock v-if="useEqualStr(props.iconName, 'lock')" v-bind="icon" />
|
||||
<Crown v-if="useEqualStr(props.iconName, 'crown')" v-bind="icon" />
|
||||
<Discord v-if="useEqualStr(props.iconName, 'discord')" v-bind="icon" />
|
||||
<Disk v-if="useEqualStr(props.iconName, 'disk')" v-bind="icon" />
|
||||
<Disks v-if="useEqualStr(props.iconName, 'disks')" v-bind="icon" />
|
||||
<Globe v-if="useEqualStr(props.iconName, 'globe')" v-bind="icon" />
|
||||
<Info v-if="useEqualStr(props.iconName, 'info')" v-bind="icon" />
|
||||
<Flag v-if="useEqualStr(props.iconName, 'flag')" v-bind="icon" />
|
||||
<Gear v-if="useEqualStr(props.iconName, 'gear')" v-bind="icon" />
|
||||
<Github v-if="useEqualStr(props.iconName, 'github')" v-bind="icon" />
|
||||
<House v-if="useEqualStr(props.iconName, 'house')" v-bind="icon" />
|
||||
<List v-if="useEqualStr(props.iconName, 'list')" v-bind="icon" />
|
||||
<Key v-if="useEqualStr(props.iconName, 'key')" v-bind="icon" />
|
||||
<Linkedin v-if="useEqualStr(props.iconName, 'linkedin')" v-bind="icon" />
|
||||
<Plus v-if="useEqualStr(props.iconName, 'plus')" v-bind="icon" />
|
||||
<Puzzle v-if="useEqualStr(props.iconName, 'puzzle')" v-bind="icon" />
|
||||
<Settings v-if="useEqualStr(props.iconName, 'settings')" v-bind="icon" />
|
||||
<Task v-if="useEqualStr(props.iconName, 'task')" v-bind="icon" />
|
||||
<Trespass v-if="useEqualStr(props.iconName, 'trespass')" v-bind="icon" />
|
||||
<Check v-if="useEqualStr(props.iconName, 'check')" v-bind="icon" />
|
||||
<Cross v-if="useEqualStr(props.iconName, 'cross')" v-bind="icon" />
|
||||
<Twitter v-if="useEqualStr(props.iconName, 'twitter')" v-bind="icon" />
|
||||
<Wire v-if="useEqualStr(props.iconName, 'wire')" v-bind="icon" />
|
||||
<Funnel v-if="useEqualStr(props.iconName, 'funnel')" v-bind="icon" />
|
||||
<Redirect v-if="useEqualStr(props.iconName, 'redirect')" v-bind="icon" />
|
||||
<Close v-if="useEqualStr(props.iconName, 'close')" v-bind="icon" />
|
||||
<Pen v-if="useEqualStr(props.iconName, 'pen')" v-bind="icon" />
|
||||
<Document v-if="useEqualStr(props.iconName, 'document')" v-bind="icon" />
|
||||
<Eye v-if="useEqualStr(props.iconName, 'eye')" v-bind="icon" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -132,7 +132,10 @@ function modalKeyboardEvents(e) {
|
|||
}
|
||||
|
||||
function modalClickEvents(e) {
|
||||
if (e.target.closest("[data-modal]") !== modalEl.value && modalEl.value)
|
||||
if (
|
||||
(e.target.closest("[data-modal]") !== modalEl.value && modalEl.value) ||
|
||||
!modalEl.value
|
||||
)
|
||||
return;
|
||||
if (e.target.hasAttribute("data-close-modal")) useCloseModal();
|
||||
}
|
||||
|
|
@ -167,12 +170,12 @@ const emits = defineEmits(["close"]);
|
|||
:class="['layout-modal-container', props.isOpen ? '' : 'hidden']"
|
||||
:id="props.id"
|
||||
>
|
||||
<div data-close-modal class="layout-backdrop"></div>
|
||||
<div class="layout-modal-wrap">
|
||||
<div class="layout-backdrop"></div>
|
||||
<div data-close-modal class="layout-modal-wrap">
|
||||
<div class="layout-modal">
|
||||
<div class="layout-modal-button-container">
|
||||
<Button
|
||||
data-close-modal
|
||||
:attrs="{ 'data-close-modal': '' }"
|
||||
:text="'action_close_modal'"
|
||||
:hideText="true"
|
||||
:iconName="'close'"
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@
|
|||
"icons_github_desc": "Github icon representing a link to a Github repository.",
|
||||
"icons_linkedin_desc": "Linkedin icon representing a link to a Linkedin profile.",
|
||||
"icons_twitter_desc": "Twitter icon representing a link to a Twitter account.",
|
||||
"action_switch": "switch {name}",
|
||||
"action_send": "send {name}",
|
||||
"action_start": "start {name}",
|
||||
"action_disable": "disable {name}",
|
||||
|
|
@ -271,6 +272,20 @@
|
|||
"services_search_desc": "Search within service name",
|
||||
"services_methods": "Methods",
|
||||
"services_methods_desc": "Only show services of the chosen method",
|
||||
"services_draft": "Draft status",
|
||||
"services_draft_desc": "Only show services of the chosen draft status"
|
||||
"services_draft": "draft",
|
||||
"services_online": "online",
|
||||
"services_draft_desc": "Only show services of the chosen draft status",
|
||||
"services_plugins_title": "plugins",
|
||||
"services_plugins_subtitle": "Main plugins status for this service.",
|
||||
"services_manage_title": "Manage settings",
|
||||
"services_manage_subtitle": "Choose a mode to manage service",
|
||||
"services_mode_easy": "Easy mode",
|
||||
"services_mode_raw": "Raw mode",
|
||||
"services_mode_advanced": "Advanced mode",
|
||||
"services_draft_subtitle": "Service is currently in draft (configuration is not apply).",
|
||||
"services_draft_switch_subtitle": "Switch to online ?",
|
||||
"services_online_subtitle": "Service is currently online (configuration is apply).",
|
||||
"services_online_switch_subtitle": "Switch to draft ?",
|
||||
"services_delete_title": "Delete service",
|
||||
"services_delete_subtitle": "Are you sure you want to delete the service below ?"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<script setup>
|
||||
import { reactive, onBeforeMount } from "vue";
|
||||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderBans from "@components/Builder/Bans.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/Bans.vue
|
||||
|
|
@ -24,6 +25,10 @@ onBeforeMount(() => {
|
|||
bans.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
useGlobal();
|
||||
});
|
||||
|
||||
const builder = [
|
||||
{
|
||||
type: "void",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderGlobalConfig from "@components/Builder/GlobalConfig.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/GlobalConfig.vue
|
||||
|
|
@ -23,6 +24,11 @@ onBeforeMount(() => {
|
|||
: {};
|
||||
globalConfig.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// Set the page title
|
||||
useGlobal();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderHome from "@components/Builder/Home.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/Home.vue
|
||||
|
|
@ -24,6 +25,10 @@ onBeforeMount(() => {
|
|||
home.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// Set the page title
|
||||
useGlobal();
|
||||
});
|
||||
// const data = [
|
||||
// {
|
||||
// type: "card",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderInstances from "@components/Builder/Instances.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/Instances.vue
|
||||
|
|
@ -24,6 +25,10 @@ onBeforeMount(() => {
|
|||
instances.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// Set the page title
|
||||
useGlobal();
|
||||
});
|
||||
// const data = [
|
||||
// {
|
||||
// type: "Instance",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderJobs from "@components/Builder/Jobs.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/Jobs.vue
|
||||
|
|
@ -88,6 +89,7 @@ function downloadCacheEvent() {
|
|||
|
||||
onMounted(() => {
|
||||
downloadCacheEvent();
|
||||
useGlobal();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderPlugins from "@components/Builder/Plugins.vue";
|
||||
import { useForm } from "@utils/form.js";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/PLugins.vue
|
||||
|
|
@ -99,6 +99,7 @@ onBeforeMount(() => {
|
|||
onMounted(() => {
|
||||
redirectPlugin();
|
||||
deletePlugin();
|
||||
useGlobal();
|
||||
});
|
||||
|
||||
const builder = [
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderReports from "@components/Builder/Reports.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/Reports.vue
|
||||
|
|
@ -24,6 +25,11 @@ onBeforeMount(() => {
|
|||
reports.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// Set the page title
|
||||
useGlobal();
|
||||
});
|
||||
|
||||
const builder = [
|
||||
{
|
||||
type: "card",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -2,6 +2,7 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderServices from "@components/Builder/Services.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
|
||||
/**
|
||||
@name Page/Services.vue
|
||||
|
|
@ -23,6 +24,11 @@ onBeforeMount(() => {
|
|||
: {};
|
||||
services.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// Set the page title
|
||||
useGlobal();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import { useSubmitForm } from "@utils/form.js";
|
||||
import { useSubmitForm } from "@utils/global.js";
|
||||
|
||||
/**
|
||||
@name createFormStore
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
@name utils/form.js
|
||||
@description This file contains form utils that will be used in the application by default.
|
||||
This file contains functions related to form validation, form submission, and other form utils.
|
||||
*/
|
||||
|
||||
/**
|
||||
@name useForm
|
||||
@description This function needs to be attach to an event like a click event.
|
||||
This will check if the target element contains a data-submit-form attribute and try to parse it to submit the form.
|
||||
@returns {void}
|
||||
*/
|
||||
function useForm(e) {
|
||||
if (!e.target.hasAttribute("data-submit-form")) return;
|
||||
try {
|
||||
const data = JSON.parse(e.target.getAttribute("data-submit-form"));
|
||||
useSubmitForm(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name useSubmitForm
|
||||
@description Create programmatically a form element and submit it with the given data object of type {key: value}.
|
||||
This will create a FormData and append data arguments to it, retrieve the csrf token and send it with a regular form.
|
||||
@example
|
||||
{
|
||||
instance: "1",
|
||||
operation: "delete",
|
||||
}
|
||||
@param {object} data - Object with the form data to submit.
|
||||
@returns {void}
|
||||
*/
|
||||
function useSubmitForm(data) {
|
||||
// Create a form element
|
||||
const form = document.createElement("form");
|
||||
form.style.display = "none";
|
||||
form.method = "POST";
|
||||
// Retrieve csrf token form data-crfs-token
|
||||
try {
|
||||
const csrfToken = document.querySelector("[data-csrf-token]");
|
||||
if (csrfToken) {
|
||||
data.csrf_token = csrfToken.getAttribute("data-csrf-token");
|
||||
}
|
||||
} catch (e) {}
|
||||
// Add input elements with the data object
|
||||
for (const key in data) {
|
||||
const input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = key;
|
||||
input.value = data[key];
|
||||
form.appendChild(input);
|
||||
}
|
||||
// Append to be able to submit
|
||||
document.querySelector("body").appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
@name useCheckPluginsValidity
|
||||
@description Check all items keys if at least one match exactly the filter value.
|
||||
@example
|
||||
const template = [
|
||||
{
|
||||
name: "test",
|
||||
settings: {
|
||||
test: {
|
||||
required: true,
|
||||
value: "",
|
||||
pattern: "^[a-zA-Z0-9]*$",
|
||||
},
|
||||
},
|
||||
},
|
||||
@param template - Template with plugins list and detail settings
|
||||
@returns {array} - Array with error flags and error details
|
||||
*/
|
||||
function useCheckPluginsValidity(template) {
|
||||
let isRegErr = false;
|
||||
let isReqErr = false;
|
||||
let settingErr = "";
|
||||
let pluginErr = "";
|
||||
let settingNameErr = "";
|
||||
let id = 0;
|
||||
|
||||
template.forEach((plugin, index) => {
|
||||
id = index;
|
||||
for (const [key, value] of Object.entries(plugin.settings)) {
|
||||
if (value.required && !value.value) {
|
||||
isReqErr = true;
|
||||
settingErr = key;
|
||||
settingNameErr = value.name;
|
||||
pluginErr = plugin.name;
|
||||
break;
|
||||
}
|
||||
if (value.pattern && value.value) {
|
||||
const regex = new RegExp(value.pattern);
|
||||
if (!regex.test(value.value)) {
|
||||
isRegErr = true;
|
||||
settingErr = key;
|
||||
settingNameErr = value.name;
|
||||
pluginErr = plugin.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return [isRegErr, isReqErr, settingErr, settingNameErr, pluginErr, id];
|
||||
}
|
||||
|
||||
export { useForm, useSubmitForm, useCheckPluginsValidity };
|
||||
|
|
@ -6,6 +6,123 @@ import { v4 as uuidv4 } from "uuid";
|
|||
This file contains functions related to accessibilities, cookies, and other global utils.
|
||||
*/
|
||||
|
||||
/**
|
||||
@name useGlobal
|
||||
@description This function needs to be apply on global level and will do some logic related to form, attributes, and other global actions.
|
||||
For example, it will check if the target element has a data-link attribute and redirect the user to the define link.
|
||||
It will check if the target element has a data-submit-form attribute and try to parse it to submit the form.
|
||||
@returns {void}
|
||||
*/
|
||||
function useGlobal() {
|
||||
window.addEventListener("click", useDataLinkAttr);
|
||||
window.addEventListener("click", useSubmitAttr);
|
||||
}
|
||||
|
||||
/**
|
||||
@name useSubmitAttr
|
||||
@description This function needs to be attach to an event like a click event.
|
||||
This will check if the target element contains a data-submit-form attribute and try to parse it to submit the form.
|
||||
@returns {void}
|
||||
*/
|
||||
function useSubmitAttr(e) {
|
||||
if (!e.target.hasAttribute("data-submit-form")) return;
|
||||
try {
|
||||
const data = JSON.parse(e.target.getAttribute("data-submit-form"));
|
||||
useSubmitForm(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@name useSubmitForm
|
||||
@description Create programmatically a form element and submit it with the given data object of type {key: value}.
|
||||
This will create a FormData and append data arguments to it, retrieve the csrf token and send it with a regular form.
|
||||
@example
|
||||
{
|
||||
instance: "1",
|
||||
operation: "delete",
|
||||
}
|
||||
@param {object} data - Object with the form data to submit.
|
||||
@returns {void}
|
||||
*/
|
||||
function useSubmitForm(data) {
|
||||
// Create a form element
|
||||
const form = document.createElement("form");
|
||||
form.style.display = "none";
|
||||
form.method = "POST";
|
||||
// Retrieve csrf token form data-crfs-token
|
||||
try {
|
||||
const csrfToken = document.querySelector("[data-csrf-token]");
|
||||
if (csrfToken) {
|
||||
data.csrf_token = csrfToken.getAttribute("data-csrf-token");
|
||||
}
|
||||
} catch (e) {}
|
||||
// Add input elements with the data object
|
||||
for (const key in data) {
|
||||
const input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = key;
|
||||
input.value = data[key];
|
||||
form.appendChild(input);
|
||||
}
|
||||
// Append to be able to submit
|
||||
document.querySelector("body").appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
/**
|
||||
@name useCheckPluginsValidity
|
||||
@description Check all items keys if at least one match exactly the filter value.
|
||||
@example
|
||||
const template = [
|
||||
{
|
||||
name: "test",
|
||||
settings: {
|
||||
test: {
|
||||
required: true,
|
||||
value: "",
|
||||
pattern: "^[a-zA-Z0-9]*$",
|
||||
},
|
||||
},
|
||||
},
|
||||
@param template - Template with plugins list and detail settings
|
||||
@returns {array} - Array with error flags and error details
|
||||
*/
|
||||
function useCheckPluginsValidity(template) {
|
||||
let isRegErr = false;
|
||||
let isReqErr = false;
|
||||
let settingErr = "";
|
||||
let pluginErr = "";
|
||||
let settingNameErr = "";
|
||||
let id = 0;
|
||||
|
||||
template.forEach((plugin, index) => {
|
||||
id = index;
|
||||
for (const [key, value] of Object.entries(plugin.settings)) {
|
||||
if (value.required && !value.value) {
|
||||
isReqErr = true;
|
||||
settingErr = key;
|
||||
settingNameErr = value.name;
|
||||
pluginErr = plugin.name;
|
||||
break;
|
||||
}
|
||||
if (value.pattern && value.value) {
|
||||
const regex = new RegExp(value.pattern);
|
||||
if (!regex.test(value.value)) {
|
||||
isRegErr = true;
|
||||
settingErr = key;
|
||||
settingNameErr = value.name;
|
||||
pluginErr = plugin.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return [isRegErr, isReqErr, settingErr, settingNameErr, pluginErr, id];
|
||||
}
|
||||
|
||||
/**
|
||||
@name useUUID
|
||||
@description This function return a unique identifier using uuidv4 and a random number.
|
||||
|
|
@ -39,4 +156,23 @@ function useEqualStr(type, compare) {
|
|||
}
|
||||
}
|
||||
|
||||
export { useUUID, useEqualStr };
|
||||
/**
|
||||
@name useDataLinkAttr
|
||||
@description Check from event if the target has a data-link attribute. Case it is, it will be used to redirect the user to the define link.
|
||||
This is useful to avoid using the <a> tag and use a <div> or <button> instead.
|
||||
@param {e} event - The event to attach the function logic
|
||||
@returns {void}
|
||||
*/
|
||||
function useDataLinkAttr(e) {
|
||||
if (!e.target.hasAttribute("data-link")) return;
|
||||
const link = e.target.getAttribute("data-link");
|
||||
window.location.href = link;
|
||||
}
|
||||
|
||||
export {
|
||||
useGlobal,
|
||||
useUUID,
|
||||
useEqualStr,
|
||||
useSubmitForm,
|
||||
useCheckPluginsValidity,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -527,6 +527,10 @@ body {
|
|||
@apply absolute right-4 top-4 z-[30];
|
||||
}
|
||||
|
||||
.layout-modal-content {
|
||||
@apply gap-2 col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
||||
.layout-settings {
|
||||
@apply py-4 sm:gap-x-8 gap-y-8 col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
|
@ -1142,7 +1146,11 @@ body {
|
|||
}
|
||||
|
||||
.button-group-modal {
|
||||
@apply col-span-12 flex justify-center items-center mt-4 mx-4;
|
||||
@apply col-span-12 flex justify-center items-center my-1 mx-4;
|
||||
}
|
||||
|
||||
.button-group-modal.last {
|
||||
@apply mt-5 mb-0;
|
||||
}
|
||||
|
||||
.button-group-table {
|
||||
|
|
@ -1234,7 +1242,7 @@ body {
|
|||
}
|
||||
|
||||
.no-subtitle.title-modal {
|
||||
@apply mb-6;
|
||||
@apply mb-4;
|
||||
}
|
||||
|
||||
.no-subtitle.title-container {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -76,7 +76,6 @@ export default {
|
|||
"sm:flex-nowrap",
|
||||
"md:flex-nowrap",
|
||||
"lg:flex-nowrap",
|
||||
|
||||
"justify-center",
|
||||
"sm:justify-center",
|
||||
"md:justify-center",
|
||||
|
|
@ -217,6 +216,22 @@ export default {
|
|||
"sm:fixed",
|
||||
"md:fixed",
|
||||
"lg:fixed",
|
||||
"mb-0",
|
||||
"sm:mb-0",
|
||||
"md:mb-0",
|
||||
"lg:mb-0",
|
||||
"ml-0",
|
||||
"sm:ml-0",
|
||||
"md:ml-0",
|
||||
"lg:ml-0",
|
||||
"mr-0",
|
||||
"sm:mr-0",
|
||||
"md:mr-0",
|
||||
"lg:mr-0",
|
||||
"mt-0",
|
||||
"sm:mt-0",
|
||||
"md:mt-0",
|
||||
"lg:mt-0",
|
||||
"ml-2",
|
||||
"sm:ml-2",
|
||||
"md:ml-2",
|
||||
|
|
@ -241,6 +256,30 @@ export default {
|
|||
"sm:mx-2",
|
||||
"md:mx-2",
|
||||
"lg:mx-2",
|
||||
"m-4",
|
||||
"sm:m-4",
|
||||
"md:m-4",
|
||||
"lg:m-4",
|
||||
"mx-4",
|
||||
"sm:mx-4",
|
||||
"md:mx-4",
|
||||
"lg:mx-4",
|
||||
"mt-4",
|
||||
"sm:mt-4",
|
||||
"md:mt-4",
|
||||
"lg:mt-4",
|
||||
"mb-4",
|
||||
"sm:mb-4",
|
||||
"md:mb-4",
|
||||
"lg:mb-4",
|
||||
"ml-4",
|
||||
"sm:ml-4",
|
||||
"md:ml-4",
|
||||
"lg:ml-4",
|
||||
"mr-4",
|
||||
"sm:mr-4",
|
||||
"md:mr-4",
|
||||
"lg:mr-4",
|
||||
"pl-2",
|
||||
"sm:pl-2",
|
||||
"md:pl-2",
|
||||
|
|
|
|||
|
|
@ -3007,9 +3007,7 @@ def plugins_builder(plugins, data={}):
|
|||
plugins_details = []
|
||||
for plugin in plugins:
|
||||
|
||||
can_be_delete = plugin.get("type", "ui") == "external" and plugin.get(
|
||||
"method", "ui"
|
||||
) in (
|
||||
can_be_delete = plugin.get("type", "ui") == "external" and plugin.get("method", "ui") in (
|
||||
"manual",
|
||||
"default",
|
||||
"ui",
|
||||
|
|
@ -3021,18 +3019,11 @@ def plugins_builder(plugins, data={}):
|
|||
"attrs": {
|
||||
"data-plugin-id": plugin.get("id"),
|
||||
"data-plugin-delete": "true" if can_be_delete else "false",
|
||||
"data-plugin-redirect": (
|
||||
"true" if plugin.get("page", False) else "false"
|
||||
),
|
||||
"data-plugin-redirect": ("true" if plugin.get("page", False) else "false"),
|
||||
"data-plugin-type": plugin.get("type", "").lower(),
|
||||
"data-plugin-name": plugin.get("name"),
|
||||
},
|
||||
"disabled": (
|
||||
True
|
||||
if is_readonly
|
||||
or (plugin.get("type", "ui") == "pro" and not is_pro_version)
|
||||
else False
|
||||
),
|
||||
"disabled": (True if is_readonly or (plugin.get("type", "ui") == "pro" and not is_pro_version) else False),
|
||||
"popovers": [],
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,19 +49,25 @@
|
|||
"data": {
|
||||
"buttons": [
|
||||
{
|
||||
"id": "open-modal-settings-0",
|
||||
"text": "settings",
|
||||
"id": "open-modal-plugins-0",
|
||||
"text": "plugins",
|
||||
"hideText": true,
|
||||
"color": "info",
|
||||
"color": "success",
|
||||
"size": "normal",
|
||||
"iconName": "settings",
|
||||
"iconName": "eye",
|
||||
"iconColor": "white",
|
||||
"modal": {
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Title",
|
||||
"data": {
|
||||
"title": "services_settings_title"
|
||||
"title": "services_plugins_title"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "services_plugins_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -91,9 +97,9 @@
|
|||
"id": "open-modal-manage-0",
|
||||
"text": "manage",
|
||||
"hideText": true,
|
||||
"color": "success",
|
||||
"color": "edit",
|
||||
"size": "normal",
|
||||
"iconName": "gear",
|
||||
"iconName": "pen",
|
||||
"iconColor": "white",
|
||||
"modal": {
|
||||
"widgets": [
|
||||
|
|
@ -103,15 +109,21 @@
|
|||
"title": "services_manage_title"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "services_manage_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ButtonGroup",
|
||||
"data": {
|
||||
"buttons": [
|
||||
{
|
||||
"id": "manage-service-btn-app1.example.com",
|
||||
"text": "services_easy",
|
||||
"text": "services_mode_easy",
|
||||
"disabled": false,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -120,9 +132,9 @@
|
|||
},
|
||||
{
|
||||
"id": "manage-service-btn-app1.example.com",
|
||||
"text": "services_advanced",
|
||||
"text": "services_mode_advanced",
|
||||
"disabled": false,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -131,9 +143,9 @@
|
|||
},
|
||||
{
|
||||
"id": "manage-service-btn-app1.example.com",
|
||||
"text": "services_raw",
|
||||
"text": "services_mode_raw",
|
||||
"disabled": false,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -171,7 +183,7 @@
|
|||
"id": "open-modal-draft-0",
|
||||
"text": "online",
|
||||
"hideText": true,
|
||||
"color": "cyan",
|
||||
"color": "blue",
|
||||
"size": "normal",
|
||||
"iconName": "globe",
|
||||
"iconColor": "white",
|
||||
|
|
@ -180,20 +192,20 @@
|
|||
{
|
||||
"type": "Title",
|
||||
"data": {
|
||||
"title": "services_edit_title"
|
||||
"title": "services_online"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "services_edit_subtitle"
|
||||
"text": "services_online_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "app1.example.com",
|
||||
"bold": true
|
||||
"bold": true,
|
||||
"text": "services_online_switch_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -212,9 +224,9 @@
|
|||
},
|
||||
{
|
||||
"id": "edit-service-btn-app1.example.com",
|
||||
"text": "action_edit",
|
||||
"text": "action_switch",
|
||||
"disabled": false,
|
||||
"color": "cyan",
|
||||
"color": "success",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"data-submit-form": "{\"SERVER_NAME\" : app1.example.com, \"OLD_SERVER_NAME\" : app1.example.com, \"operation\" : \"edit\", \"IS_DRAFT\" : no }"
|
||||
|
|
@ -302,10 +314,10 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"method": "scheduler",
|
||||
"method": "ui",
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "scheduler"
|
||||
"text": "ui"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -313,19 +325,25 @@
|
|||
"data": {
|
||||
"buttons": [
|
||||
{
|
||||
"id": "open-modal-settings-1",
|
||||
"text": "settings",
|
||||
"id": "open-modal-plugins-1",
|
||||
"text": "plugins",
|
||||
"hideText": true,
|
||||
"color": "info",
|
||||
"color": "success",
|
||||
"size": "normal",
|
||||
"iconName": "settings",
|
||||
"iconName": "eye",
|
||||
"iconColor": "white",
|
||||
"modal": {
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Title",
|
||||
"data": {
|
||||
"title": "services_settings_title"
|
||||
"title": "services_plugins_title"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "services_plugins_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -355,9 +373,9 @@
|
|||
"id": "open-modal-manage-1",
|
||||
"text": "manage",
|
||||
"hideText": true,
|
||||
"color": "success",
|
||||
"color": "edit",
|
||||
"size": "normal",
|
||||
"iconName": "gear",
|
||||
"iconName": "pen",
|
||||
"iconColor": "white",
|
||||
"modal": {
|
||||
"widgets": [
|
||||
|
|
@ -367,15 +385,21 @@
|
|||
"title": "services_manage_title"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "services_manage_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ButtonGroup",
|
||||
"data": {
|
||||
"buttons": [
|
||||
{
|
||||
"id": "manage-service-btn-www.example.com",
|
||||
"text": "services_easy",
|
||||
"text": "services_mode_easy",
|
||||
"disabled": false,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -384,9 +408,9 @@
|
|||
},
|
||||
{
|
||||
"id": "manage-service-btn-www.example.com",
|
||||
"text": "services_advanced",
|
||||
"text": "services_mode_advanced",
|
||||
"disabled": false,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -395,9 +419,9 @@
|
|||
},
|
||||
{
|
||||
"id": "manage-service-btn-www.example.com",
|
||||
"text": "services_raw",
|
||||
"text": "services_mode_raw",
|
||||
"disabled": false,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -430,34 +454,34 @@
|
|||
{
|
||||
"attrs": {
|
||||
"data-server-name": "www.example.com",
|
||||
"data-is-draft": "no"
|
||||
"data-is-draft": "yes"
|
||||
},
|
||||
"id": "open-modal-draft-1",
|
||||
"text": "online",
|
||||
"text": "draft",
|
||||
"hideText": true,
|
||||
"color": "cyan",
|
||||
"color": "blue",
|
||||
"size": "normal",
|
||||
"iconName": "globe",
|
||||
"iconName": "document",
|
||||
"iconColor": "white",
|
||||
"modal": {
|
||||
"widgets": [
|
||||
{
|
||||
"type": "Title",
|
||||
"data": {
|
||||
"title": "services_edit_title"
|
||||
"title": "services_draft"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "services_edit_subtitle"
|
||||
"text": "services_draft_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": "www.example.com",
|
||||
"bold": true
|
||||
"bold": true,
|
||||
"text": "services_draft_switch_subtitle"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -476,12 +500,12 @@
|
|||
},
|
||||
{
|
||||
"id": "edit-service-btn-www.example.com",
|
||||
"text": "action_edit",
|
||||
"text": "action_switch",
|
||||
"disabled": false,
|
||||
"color": "cyan",
|
||||
"color": "success",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"data-submit-form": "{\"SERVER_NAME\" : www.example.com, \"OLD_SERVER_NAME\" : www.example.com, \"operation\" : \"edit\", \"IS_DRAFT\" : no }"
|
||||
"data-submit-form": "{\"SERVER_NAME\" : www.example.com, \"OLD_SERVER_NAME\" : www.example.com, \"operation\" : \"edit\", \"IS_DRAFT\" : yes }"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -496,7 +520,7 @@
|
|||
},
|
||||
"id": "open-modal-delete-1",
|
||||
"text": "delete",
|
||||
"disabled": true,
|
||||
"disabled": false,
|
||||
"hideText": true,
|
||||
"color": "red",
|
||||
"size": "normal",
|
||||
|
|
@ -600,6 +624,7 @@
|
|||
"id": "services-methods",
|
||||
"value": "all",
|
||||
"values": [
|
||||
"ui",
|
||||
"scheduler"
|
||||
],
|
||||
"name": "services-methods",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ services = [
|
|||
},
|
||||
{
|
||||
"USE_REVERSE_PROXY": {"value": "yes", "method": "scheduler", "global": False},
|
||||
"IS_DRAFT": {"value": "no", "method": "default", "global": False},
|
||||
"IS_DRAFT": {"value": "yes", "method": "default", "global": False},
|
||||
"SERVE_FILES": {"value": "no", "method": "scheduler", "global": True},
|
||||
"REMOTE_PHP": {"value": "", "method": "default", "global": True},
|
||||
"AUTO_LETS_ENCRYPT": {"value": "no", "method": "default", "global": True},
|
||||
|
|
@ -27,7 +27,7 @@ services = [
|
|||
"USE_BAD_BEHAVIOR": {"value": "yes", "method": "default", "global": True},
|
||||
"USE_LIMIT_REQ": {"value": "yes", "method": "default", "global": True},
|
||||
"USE_DNSBL": {"value": "yes", "method": "default", "global": True},
|
||||
"SERVER_NAME": {"value": "www.example.com", "method": "scheduler", "global": False},
|
||||
"SERVER_NAME": {"value": "www.example.com", "method": "ui", "global": False},
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -55,7 +55,9 @@ def table_widget(positions, header, items, filters, minWidth, title):
|
|||
}
|
||||
|
||||
|
||||
def services_action(server_name: str = "", operation: str = "", title: str = "", subtitle: str = "", is_draft: Union[bool, None] = None) -> dict:
|
||||
def services_action(
|
||||
server_name: str = "", operation: str = "", title: str = "", subtitle: str = "", additionnal: str = "", is_draft: Union[bool, None] = None
|
||||
) -> dict:
|
||||
|
||||
buttons = [
|
||||
{
|
||||
|
|
@ -87,9 +89,9 @@ def services_action(server_name: str = "", operation: str = "", title: str = "",
|
|||
buttons.append(
|
||||
{
|
||||
"id": f"{operation}-service-btn-{server_name}",
|
||||
"text": f"action_{operation}",
|
||||
"text": "action_switch",
|
||||
"disabled": False,
|
||||
"color": "cyan",
|
||||
"color": "success",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"data-submit-form": f"""{{"SERVER_NAME" : {server_name}, "OLD_SERVER_NAME" : {server_name}, "operation" : "edit", "IS_DRAFT" : {draft_value} }}""",
|
||||
|
|
@ -104,17 +106,26 @@ def services_action(server_name: str = "", operation: str = "", title: str = "",
|
|||
"title": title,
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": subtitle,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
if operation == "delete" or operation == "edit":
|
||||
if additionnal:
|
||||
content.append(
|
||||
{
|
||||
"type": "Text",
|
||||
"data": {
|
||||
"text": subtitle,
|
||||
"bold": True,
|
||||
"text": additionnal,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if operation == "delete":
|
||||
content.append(
|
||||
{
|
||||
"type": "Text",
|
||||
|
|
@ -133,9 +144,9 @@ def services_action(server_name: str = "", operation: str = "", title: str = "",
|
|||
mode_buttons.append(
|
||||
{
|
||||
"id": f"{operation}-service-btn-{server_name}",
|
||||
"text": f"services_{mode}",
|
||||
"text": f"services_mode_{mode}",
|
||||
"disabled": False,
|
||||
"color": "green",
|
||||
"color": "info",
|
||||
"size": "normal",
|
||||
"attrs": {
|
||||
"role": "link",
|
||||
|
|
@ -183,15 +194,15 @@ def get_services_list(services):
|
|||
"data": {
|
||||
"buttons": [
|
||||
{
|
||||
"id": f"open-modal-settings-{index}",
|
||||
"text": "settings",
|
||||
"id": f"open-modal-plugins-{index}",
|
||||
"text": "plugins",
|
||||
"hideText": True,
|
||||
"color": "info",
|
||||
"color": "success",
|
||||
"size": "normal",
|
||||
"iconName": "settings",
|
||||
"iconName": "eye",
|
||||
"iconColor": "white",
|
||||
"modal": services_action(
|
||||
server_name=server_name, operation="settings", title="services_settings_title", subtitle="services_settings_subtitle"
|
||||
server_name=server_name, operation="plugins", title="services_plugins_title", subtitle="services_plugins_subtitle"
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -199,9 +210,9 @@ def get_services_list(services):
|
|||
"id": f"open-modal-manage-{index}",
|
||||
"text": "manage",
|
||||
"hideText": True,
|
||||
"color": "success",
|
||||
"color": "edit",
|
||||
"size": "normal",
|
||||
"iconName": "gear",
|
||||
"iconName": "pen",
|
||||
"iconColor": "white",
|
||||
"modal": services_action(
|
||||
server_name=server_name, operation="manage", title="services_manage_title", subtitle="services_manage_subtitle"
|
||||
|
|
@ -212,12 +223,17 @@ def get_services_list(services):
|
|||
"id": f"open-modal-draft-{index}",
|
||||
"text": "draft" if is_draft else "online",
|
||||
"hideText": True,
|
||||
"color": "cyan",
|
||||
"color": "blue",
|
||||
"size": "normal",
|
||||
"iconName": "pen" if is_draft else "globe",
|
||||
"iconName": "document" if is_draft else "globe",
|
||||
"iconColor": "white",
|
||||
"modal": services_action(
|
||||
server_name=server_name, operation="edit", title="services_edit_title", subtitle="services_edit_subtitle", is_draft=is_draft
|
||||
server_name=server_name,
|
||||
operation="edit",
|
||||
title="services_draft" if is_draft else "services_online",
|
||||
subtitle="services_draft_subtitle" if is_draft else "services_online_subtitle",
|
||||
additionnal="services_draft_switch_subtitle" if is_draft else "services_online_switch_subtitle",
|
||||
is_draft=is_draft,
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue