start table component

This commit is contained in:
Jordan Blasenhauer 2024-06-17 10:00:01 +02:00
parent 1b078263b7
commit e61e40b245
5 changed files with 241 additions and 102 deletions

View file

@ -1275,34 +1275,61 @@ body {
@apply fill-gray-700 stroke-gray-600;
}
/* LIST */
.list-container {
/* TABLE */
.table-container {
@apply col-span-12 overflow-x-auto overflow-y-hidden;
}
.table-container-wrap {
@apply col-span-12 overflow-x-auto grid grid-cols-12;
}
.table {
@apply w-full grid grid-cols-12 block;
}
.list-content-container {
@apply dark:text-gray-400 block w-full rounded col-span-12 overflow-x-hidden overflow-y-auto max-h-[300px];
.sm.table {
@apply min-w-[600px];
}
.list-content-item {
@apply text-sm col-span-12 block border-b hover:bg-gray-100 dark:hover:bg-slate-700 items-center grid grid-cols-12 border-gray-300 py-2.5 px-1;
.md.table {
@apply min-w-[800px];
}
.list-content {
@apply border-b hover:bg-gray-100 dark:hover:bg-slate-700 border-gray-300 py-2.5 dark:text-gray-400;
.base.table {
@apply min-w-[1000px];
}
.list-content-item-wrap {
@apply break-words items-center col-span-12 grid grid-cols-12 text-sm dark:text-gray-400;
.lg.table {
@apply min-w-[1200px];
}
.list-header-container {
.xl.table {
@apply min-w-[1400px];
}
.table-header {
@apply block w-full col-span-12 grid grid-cols-12 pl-2;
}
.list-header-item {
.table-header-item {
@apply block dark:text-gray-300 pb-1 text-sm font-bold m-0 border-b border-gray-400;
}
.table-content {
@apply dark:text-gray-400 block w-full rounded col-span-12 overflow-x-hidden overflow-y-auto max-h-[300px];
}
.table-content-item {
@apply text-sm col-span-12 block border-b hover:bg-gray-100 dark:hover:bg-slate-700 items-center grid grid-cols-12 border-gray-300 py-2.5 px-1;
}
.table-content-item-wrap {
@apply py-2.5 px-1;
}
/** MISC **/
.line-separator {

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,149 @@
<script setup>
import Container from "@components/Widget/Container.vue";
import Text from "@components/Widget/Text.vue";
import Icons from "@components/Widget/Icons.vue";
import Fields from "@components/Form/Fields.vue";
import Button from "@components/Widget/Button.vue";
import { reactive, computed, resolveComponent } from "vue";
import { v4 as uuidv4 } from "uuid";
/**
@name Widget/Table.vue
@description This component is used to create a table.
You need to provide a title, a header, a list of positions, and a list of items.
Items need to be an array of array with a cell being a regular widget. Not all widget are supported. Check this component import list to see which widget are supported.
For example, Text, Icons, Icons, Buttons and Fields are supported.
@example
{
"title": "Table title",
"header": ["Header 1", "Header 2", "Header 3"],
"minWidth": "base",
"positions": [4,4,4],
"items": [
[
{
"type": "Text",
"data": {
"text": "whitelist-download"
}
},
...
],
...
],
}
@param {string} title - Determine the title of the table.
@param {array} header - Determine the header of the table.
@param {array} positions - Determine the position of each item in the table in a list of number based on 12 columns grid.
@param {array} items - items to render in the table. This need to be an array (row) of array (cols) with a cell being a regular widget.
@param {string} [minWidth="base"] - Determine the minimum size of the table. Can be "base", "sm", "md", "lg", "xl".
@param {string} [containerClass=""] - Container additional class.
@param {string} [containerWrapClass=""] - Container wrap additional class.
@param {string} [tableClass=""] - Table additional class.
*/
const props = defineProps({
title: {
type: String,
required: true,
},
minWidth: {
type: String,
required: false,
default: "base",
},
positions: {
type: Array,
required: true,
},
header: {
type: Array,
required: true,
},
items: {
type: Array,
required: true,
},
containerClass: {
type: String,
required: false,
default: "",
},
containerWrapClass: {
type: String,
required: false,
default: "",
},
tableClass: {
type: String,
required: false,
default: "",
},
});
const table = reactive({
length: computed(() => {
return props.header.length;
}),
rowLength: computed(() => {
return props.items.length;
}),
title: computed(() => {
return props.title ? props.title : "dashboard_table";
}),
id: uuidv4(),
});
</script>
<template>
<Container :containerClass="`${props.containerClass} table-container`">
<Container
:containerClass="`${props.containerWrapClass} table-container-wrap`"
>
<table
:aria-colcount="table.length"
:aria-rowcount="table.rowLength"
:class="['table', props.minWidth, props.tableClass]"
:aria-describedby="table.id"
>
<span class="sr-only" :id="table.id">
{{ $t(table.title, table.title) }}
</span>
<thead class="table-header">
<tr
v-for="(head, id) in props.header"
:class="['table-header-item', `col-span-${props.positions[id]}`]"
>
<th role="columnheader">
{{ head }}
</th>
</tr>
</thead>
<tbody class="table-content">
<tr
v-for="rowId in table.rowLength"
role="row"
:aria-rowindex="rowId"
class="table-content-item"
>
<template v-for="(col, id) in props.items[rowId - 1]">
<td
:class="[
'table-content-item-wrap',
`col-span-${props.positions[id]}`,
]"
>
<Text v-if="col.type === 'Text'" v-bind="col.data" />
<Icons v-if="col.type === 'Icons'" v-bind="col.data" />
<Fields v-if="col.type === 'Fields'" v-bind="col.data" />
<Button v-if="col.type === 'Button'" v-bind="col.data" />
</td>
</template>
</tr>
</tbody>
</table>
</Container>
</Container>
</template>

View file

@ -96,6 +96,7 @@
"dashboard_easy_required": "{setting} in step {step} is required",
"dashboard_templates_title_default": "Configuration templates",
"dashboard_templates_subtitle_default": "Manage your settings with available templates and using the mode that suits you best.",
"dashboard_table": "Table element",
"inp_input_valid": "input valid",
"inp_input_error_required": "input is required",
"inp_input_error": "input is invalid",

View file

@ -1,38 +1,12 @@
<script setup>
import { reactive, onBeforeMount, triggerRef } from "vue";
import Checkbox from "@components/Forms/Field/Checkbox.vue";
import Select from "@components/Forms/Field/Select.vue";
import Input from "@components/Forms/Field/Input.vue";
import Datepicker from "@components/Forms/Field/Datepicker.vue";
import Combobox from "@components/Forms/Field/Combobox.vue";
import Editor from "@components/Forms/Field/Editor.vue";
import Button from "@components/Widget/Button.vue";
import DashboardLayout from "@components/Dashboard/Layout.vue";
import GridLayout from "@components/Widget/GridLayout.vue";
import Grid from "@components/Widget/Grid.vue";
const checkboxData = {
id: "test-checkbox",
value: "yes",
name: "test-checkbox",
disabled: false,
required: true,
label: "Test checkbox",
tabId: "1",
};
const selectData = {
id: "test-select",
value: "yes",
values: ["yes", "no"],
name: "test-select",
disabled: false,
required: false,
requiredValues: ["no"],
label: "Test select",
tabId: "1",
columns: { pc: 12, tablet: 12, mobile: 12 },
};
import Table from "@components/Widget/Table.vue";
const inputData = {
id: "test-input",
@ -46,66 +20,6 @@ const inputData = {
columns: { pc: 12, tablet: 12, mobile: 12 },
};
const datepickerData = {
id: "test-datepicker",
name: "test-datepicker",
disabled: false,
required: true,
label: "Test datepicker",
tabId: "1",
};
const buttonData = {
id: "test-button",
text: "Test button",
type: "button",
disabled: false,
eventAttr: {
store: "modal",
default: "close",
value: "open",
target: "modal_id",
valueExpanded: "open",
},
columns: { pc: 12, tablet: 12, mobile: 12 },
tabId: "1",
};
const buttonSVGData = {
id: "test-button",
text: "Test button",
type: "button",
disabled: false,
eventAttr: {
store: "modal",
default: "close",
value: "open",
target: "modal_id",
valueExpanded: "open",
},
columns: { pc: 12, tablet: 12, mobile: 12 },
tabId: "1",
iconName: "plus",
};
const buttonOnlySVGData = {
id: "test-button",
text: "Test button",
hideText: true,
type: "button",
disabled: false,
eventAttr: {
store: "modal",
default: "close",
value: "open",
target: "modal_id",
valueExpanded: "open",
},
columns: { pc: 12, tablet: 12, mobile: 12 },
tabId: "1",
iconName: "plus",
};
const comboboxData = {
id: "test-combobox",
value: "yes",
@ -129,6 +43,55 @@ const editorData = {
tabId: "1",
columns: { pc: 12, tablet: 12, mobile: 12 },
};
const tableData = {
title: "Table title",
minWidth: "sm",
header: ["Header 1", "Header 2", "Header 3"],
positions: [4, 4, 4],
items: [
[
{
type: "Text",
data: {
text: "whitelist-download",
},
},
{
type: "Text",
data: {
text: "whitelist-download",
},
},
{
type: "Text",
data: {
text: "whitelist-download",
},
},
],
[
{
type: "Text",
data: {
text: "whitelist-download",
},
},
{
type: "Text",
data: {
text: "whitelist-download",
},
},
{
type: "Text",
data: {
text: "whitelist-download",
},
},
],
],
};
</script>
<template>
@ -142,8 +105,7 @@ const editorData = {
<GridLayout :columns="{ pc: 4, tablet: 6, mobile: 12 }">
<!-- widget grid -->
<Grid>
<Combobox v-bind="comboboxData" />
<Editor v-bind="editorData" />
<Table v-bind="tableData" />
</Grid>
</GridLayout>
</DashboardLayout>