add uuid per default and update event handling

This commit is contained in:
Jordan Blasenhauer 2024-06-05 17:20:24 +02:00
parent 94bbc0f0a1
commit 180a014644
8 changed files with 50 additions and 34 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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,

View file

@ -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,

View file

@ -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",

View file

@ -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.

View file

@ -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>