mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
add uuid per default and update event handling
This commit is contained in:
parent
94bbc0f0a1
commit
180a014644
8 changed files with 50 additions and 34 deletions
|
|
@ -848,7 +848,7 @@ body {
|
|||
}
|
||||
|
||||
.content-detail-list-subtitle {
|
||||
@apply min-w-[2rem] break-all transition duration-300 ease-in-out pl-2 col-span-1 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-gray-100;
|
||||
@apply min-w-[2rem] break-all transition duration-300 ease-in-out pl-3 col-span-1 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-gray-100;
|
||||
}
|
||||
|
||||
/* STAT COMPONENT */
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -4,14 +4,16 @@ import { contentIndex } from "@utils/tabindex.js";
|
|||
import { useEventStore } from "@store/event.js";
|
||||
import Container from "@components/Widget/Container.vue";
|
||||
import Icons from "@components/Widget/Icons.vue";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
/**
|
||||
@name Widget/Button.vue
|
||||
@description This component is a standard button.
|
||||
You can link this button to the event store on click with eventAttr.
|
||||
You can link this button to the event store with the clickAttr object.
|
||||
This will allow you to share a value with other components, for example switching form on a click.
|
||||
The eventAttr object must contain the store name and the value to send on click at least.
|
||||
It can also contain the target id element and the expanded value, this will add additionnal accessibility attributs to the button.
|
||||
The clickAttr object must contain at least the key, defaultValue and value to work with the event store.
|
||||
It can also contain the targetId element in case the button is linked to another element, like a modal or a sidebar.
|
||||
We can specify a valueExpanded value, we will check the current value in the store and the valueExpanded, this will update the aria-expanded attribute of the button.
|
||||
@example
|
||||
{
|
||||
id: "open-modal-btn",
|
||||
|
|
@ -22,9 +24,9 @@ import Icons from "@components/Widget/Icons.vue";
|
|||
size: "normal",
|
||||
iconName: "modal",
|
||||
iconColor: "white",
|
||||
eventAttr: {"store" : "modal", "value" : "open", "target" : "modal_id", "valueExpanded" : "open"},7
|
||||
clickAttr: {"key" : "modal-config", "defaultValue" : "close", "clickValue" : "open", "targetId" : "modal_id", "valueExpanded" : "open"},
|
||||
}
|
||||
@param {string} id
|
||||
@param {string} [id=uuid()] - Unique id of the button
|
||||
@param {string} text - Content of the button. Can be a translation key or by default raw text.
|
||||
@param {string} [type="button"] - Can be of type button || submit
|
||||
@param {boolean} [disabled=false]
|
||||
|
|
@ -33,7 +35,8 @@ import Icons from "@components/Widget/Icons.vue";
|
|||
@param {string} [size="normal"] - Can be of size sm || normal || lg || xl
|
||||
@param {string} [iconName=""] - Name in lowercase of icons store on /Icons. If falsy value, no icon displayed.
|
||||
@param {string} [iconColor=""]
|
||||
@param {object} [eventAttr={}] - Store event on click {"store" : <store_name>, "default" : <default_value>, "value" : <value_stored_on_click>, "target"<optional> : <target_id_element>, "valueExpanded" : "expanded_value"}
|
||||
@param {object} [clickAttr={}] - Click event manage with event store {"key" : <key_name>, "defaultValue" : <defaultValue = "set this value to store if not done">, "clickValue" : <value_set_on_click>, "targetId"<optional> : <targetId_element="id of element link to the button event">, "valueExpanded<optional>" : <expanded_value="check current value in store and this value to determine a expanded true or false">}
|
||||
@param {array} [staticAttr=[]] - Static attributes that can be useful to do some check with script (for example {"data-attr" : "value"} will add data-attr="value" to the button)
|
||||
@param {string|number} [tabId=contentIndex] - The tabindex of the field, by default it is the contentIndex
|
||||
*/
|
||||
|
||||
|
|
@ -42,8 +45,8 @@ const eventStore = useEventStore();
|
|||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
required: false,
|
||||
default: uuidv4(),
|
||||
},
|
||||
// valid || delete || info
|
||||
text: {
|
||||
|
|
@ -91,10 +94,13 @@ const props = defineProps({
|
|||
required: false,
|
||||
default: "",
|
||||
},
|
||||
// {"store" : <store_name>, "default" : <default_value>, "value" : <value_stored_on_click>, "target"<optional> : <target_id_element>, "valueExpanded" : "expanded_value"}
|
||||
// type will add additionnal accessibility attributs to the button
|
||||
// for example, if button open a modal : {"store" : "modal", "default" : "close", "value" : "open", "target" : "modal_id", "valueExpanded" : "open"}
|
||||
eventAttr: {
|
||||
// Example of button opening a modal : {"key" : "modal", "defaultValue" : "close", "clickValue" : "open", "targetId" : "modal_id", "valueExpanded" : "open"}
|
||||
clickAttr: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: {},
|
||||
},
|
||||
staticAttr: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: {},
|
||||
|
|
@ -118,6 +124,7 @@ const buttonClass = computed(() => {
|
|||
});
|
||||
|
||||
onMounted(() => {
|
||||
setStaticAttr();
|
||||
updateData();
|
||||
});
|
||||
|
||||
|
|
@ -125,20 +132,26 @@ watch(eventStore, () => {
|
|||
updateData();
|
||||
});
|
||||
|
||||
function setStaticAttr() {
|
||||
for (const [key, value] of Object.entries(props.staticAttr)) {
|
||||
btnEl.value.setAttribute(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
function updateData(isClick = false) {
|
||||
const isStore = props.eventAttr?.store ? true : false;
|
||||
const isValue = props.eventAttr?.value ? true : false;
|
||||
const isDefault = props.eventAttr?.default ? true : false;
|
||||
if (!isStore || !isValue || !isDefault) return;
|
||||
const isKey = props.clickAttr?.key ? true : false;
|
||||
const isValue = props.clickAttr?.clickValue ? true : false;
|
||||
const isDefault = props.clickAttr?.defaultValue ? true : false;
|
||||
if (!isKey || !isValue || !isDefault) return;
|
||||
|
||||
isClick
|
||||
? eventStore.updateEvent(props.eventAttr.store, props.eventAttr.value)
|
||||
: eventStore.addEvent(props.eventAttr.store, props.eventAttr.default);
|
||||
? eventStore.updateEvent(props.clickAttr.key, props.clickAttr.clickValue)
|
||||
: eventStore.addEvent(props.clickAttr.key, props.clickAttr.defaultValue);
|
||||
|
||||
try {
|
||||
const expanded = props.eventAttr?.valueExpanded
|
||||
? props.eventAttr.valueExpanded ===
|
||||
eventStore.getEvent(props.eventAttr.store)
|
||||
const expanded = props.clickAttr?.valueExpanded
|
||||
? props.clickAttr.valueExpanded ===
|
||||
eventStore.getEvent(props.clickAttr.key)
|
||||
? "true"
|
||||
: "false"
|
||||
: false;
|
||||
|
|
@ -152,7 +165,9 @@ function updateData(isClick = false) {
|
|||
} catch (e) {}
|
||||
|
||||
try {
|
||||
const controls = props.eventAttr?.target ? props.eventAttr.target : false;
|
||||
const controls = props.clickAttr?.targetId
|
||||
? props.clickAttr.targetId
|
||||
: false;
|
||||
if (controls) {
|
||||
btnEl.value.setAttribute("aria-controls", controls);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<script setup>
|
||||
import { computed, ref, watch, onBeforeMount, onMounted } from "vue";
|
||||
import { contentIndex } from "@utils/tabindex.js";
|
||||
import Flex from "@components/Widget/Flex.vue";
|
||||
import Button from "@components/Widget/Button.vue";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
/**
|
||||
@name Widget/ButtonGroup.vue
|
||||
|
|
@ -38,7 +37,7 @@ import Button from "@components/Widget/Button.vue";
|
|||
},
|
||||
],
|
||||
}
|
||||
@param {string} id
|
||||
@param {string} [id=uuidv4()] - Unique id of the button group
|
||||
@param {string} [groupClass="justify-center align-center"] - Additional class for the flex container
|
||||
@param {array} buttons - List of buttons to display. Button component is used.
|
||||
*/
|
||||
|
|
@ -47,7 +46,7 @@ const props = defineProps({
|
|||
id: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "group-btn",
|
||||
default: uuidv4(),
|
||||
},
|
||||
groupClass: {
|
||||
type: String,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import TitleCardContent from "@components/Title/CardContent.vue";
|
|||
import IconStatus from "@components/Icon/Status.vue";
|
||||
import ContentDetailList from "@components/Content/DetailList.vue";
|
||||
import ButtonGroup from "@components/Widget/ButtonGroup.vue";
|
||||
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
/**
|
||||
@name Widget/Instance.vue
|
||||
@description This component is an instance widget.
|
||||
|
|
@ -34,7 +34,7 @@ import ButtonGroup from "@components/Widget/ButtonGroup.vue";
|
|||
},
|
||||
]
|
||||
}
|
||||
@param {string} id
|
||||
@param {string} [id=uuid()] - Unique id of the instance
|
||||
@param {string} title
|
||||
@param {string} status
|
||||
@param {array} details - List of details to display
|
||||
|
|
@ -44,7 +44,8 @@ import ButtonGroup from "@components/Widget/ButtonGroup.vue";
|
|||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
required: false,
|
||||
default: uuidv4(),
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
"dashboard_status_warning": "status warning or alert.",
|
||||
"dashboard_status_info": "status loading or waiting or unknown.",
|
||||
"action_send": "send {name}",
|
||||
"action_start": "start {name}",
|
||||
"action_disable": "disable {name}",
|
||||
"action_enable": "enable {name}",
|
||||
"action_save": "save {name}",
|
||||
|
|
@ -108,7 +109,7 @@
|
|||
"home_plugins": "plugins",
|
||||
"home_no_error": "no error",
|
||||
"home_errors_found": "errors found",
|
||||
"instance_hostname": "hostname",
|
||||
"instances_hostname": "hostname",
|
||||
"instances_method": "method",
|
||||
"instances_port": "port",
|
||||
"instances_status": "status",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { reactive, onBeforeMount } from "vue";
|
|||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import Builder from "@components/Builder.vue";
|
||||
|
||||
/**
|
||||
/**
|
||||
@name Page/Home.vue
|
||||
@description This component is the home page.
|
||||
This page displays an overview of multiple stats related to BunkerWeb.
|
||||
|
|
|
|||
|
|
@ -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", "link" : "/services", "containerClass":"","containerColumns":{"pc":4,"tablet":6,"mobile":12},"widgets":[{"type":"Stat", "link": "https://github.com/bunkerity/bunkerweb","data":{"title":"home_version","subtitle":"home_all_features_available","subtitleColor":"success","value":"home_pro","iconName":"crown","iconColor":"amber"}}]},{"type":"card","containerClass":"","containerColumns":{"pc":4,"tablet":6,"mobile":12},"widgets":[{"type":"Stat","data":{"title":"home_version_number","subtitle":"home_latest_version","subtitleColor":"success","value":"1.5.7","iconName":"wire","iconColor":"teal"}}]},{"type":"card","containerClass":"","containerColumns":{"pc":4,"tablet":6,"mobile":12},"widgets":[{"type":"Stat","data":{"title":"home_instances","subtitle":"home_total_number","subtitleColor":"info", "value":"1","iconName":"box","iconColor":"dark"}}]}, {"type":"card","containerClass":"","containerColumns":{"pc":4,"tablet":6,"mobile":12},"widgets":[{"type":"Stat","data":{"title":"home_services","subtitle":"home_all_methods_included","subtitleColor":"info","value":"2","iconName":"disk","iconColor":"orange"}}]}, {"type":"card","containerClass":"","containerColumns":{"pc":4,"tablet":6,"mobile":12},"widgets":[{"type":"Stat","data":{"title":"home_plugins","subtitle":"home_no_error","subtitleColor":"success","value":"42","iconName":"puzzle","iconColor":"yellow"}}]}]'>
|
||||
data-server-builder='[{"type":"card","link":"/services","containerClass":"","containerColumns":{"pc":6,"tablet":6,"mobile":12},"widgets":[{"type":"Instance","data":{"details":[{"key":"instances_hostname","value":"www.example.com"},{"key":"instances_method","value":"dashboard_ui"},{"key":"instances_port","value":"1084"},{"key":"instances_status","value":"instances_active"}],"status":"success","title":"www.example.com","buttons":[{"type" : "submit", "text":"action_edit","color":"edit","size":"normal"}]}}]},{"type":"card","link":"/services","containerClass":"","containerColumns":{"pc":6,"tablet":6,"mobile":12},"widgets":[{"type":"Instance","data":{"details":[{"key":"instances_hostname","value":"www.example.com"},{"key":"instances_method","value":"dashboard_ui"},{"key":"instances_port","value":"1084"},{"key":"instances_status","value":"instances_active"}],"status":"error","title":"www.example.com","buttons":[{"type" : "submit", "text":"action_start","color":"valid","size":"normal"}]}}]}]'>
|
||||
</div>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="instances.js"></script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue