@ouestfrance/sipa-bms-ui 8.5.3 → 8.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/form/BmsMultiSelect.vue.d.ts +0 -3
- package/dist/components/table/UiBmsTableCell.vue.d.ts +7 -0
- package/dist/models/table.model.d.ts +6 -0
- package/dist/sipa-bms-ui.css +32 -32
- package/dist/sipa-bms-ui.es.js +4301 -4110
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +4309 -4117
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +18 -18
- package/src/components/form/BmsMultiSelect.vue +1 -2
- package/src/components/form/BmsSelect.vue +1 -0
- package/src/components/form/RawAutocomplete.vue +15 -14
- package/src/components/table/UiBmsTable.stories.js +37 -0
- package/src/components/table/UiBmsTableCell.vue +25 -0
- package/src/components/table/UiBmsTableRow.stories.js +30 -0
- package/src/components/table/UiBmsTableRow.vue +3 -2
- package/src/components/utils/BmsRelativeTime.vue +1 -1
- package/src/models/table.model.ts +7 -0
- package/src/showroom/pages/table.vue +4 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouestfrance/sipa-bms-ui",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.6.0",
|
|
4
4
|
"author": "Ouest-France BMS",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"scripts": {
|
|
@@ -30,49 +30,49 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@chromatic-com/storybook": "^4.0.0",
|
|
33
|
-
"@codemirror/lang-html": "6.4.
|
|
33
|
+
"@codemirror/lang-html": "6.4.10",
|
|
34
34
|
"@codemirror/lang-json": "6.0.2",
|
|
35
35
|
"@commitlint/cli": "19.8.1",
|
|
36
36
|
"@commitlint/config-conventional": "19.8.1",
|
|
37
37
|
"@formkit/vue": "1.6.9",
|
|
38
38
|
"@mdx-js/react": "3.1.1",
|
|
39
|
-
"@storybook/addon-docs": "9.1.
|
|
40
|
-
"@storybook/addon-links": "9.1.
|
|
41
|
-
"@storybook/vue3-vite": "9.1.
|
|
39
|
+
"@storybook/addon-docs": "9.1.5",
|
|
40
|
+
"@storybook/addon-links": "9.1.5",
|
|
41
|
+
"@storybook/vue3-vite": "9.1.5",
|
|
42
42
|
"@types/lodash": "4.17.20",
|
|
43
|
-
"@types/uuid": "
|
|
43
|
+
"@types/uuid": "11.0.0",
|
|
44
44
|
"@vitejs/plugin-vue": "6.0.1",
|
|
45
45
|
"@vue/test-utils": "2.4.6",
|
|
46
46
|
"@vueuse/core": "13.9.0",
|
|
47
47
|
"@vueuse/motion": "^3.0.0",
|
|
48
|
-
"axios": "1.
|
|
48
|
+
"axios": "1.12.2",
|
|
49
49
|
"blob-util": "^2.0.2",
|
|
50
50
|
"chromatic": "13.1.4",
|
|
51
51
|
"codemirror": "6.0.2",
|
|
52
52
|
"cors": "^2.8.5",
|
|
53
53
|
"cross-env": "^10.0.0",
|
|
54
54
|
"cy2": "^4.0.0",
|
|
55
|
-
"cypress": "15.
|
|
55
|
+
"cypress": "15.2.0",
|
|
56
56
|
"express": "^5.0.0",
|
|
57
57
|
"husky": "9.1.7",
|
|
58
|
-
"jsdom": "
|
|
58
|
+
"jsdom": "27.0.0",
|
|
59
59
|
"keycloak-js": "26.1.2",
|
|
60
60
|
"lint-staged": "16.1.6",
|
|
61
61
|
"lodash": "4.17.21",
|
|
62
|
-
"lucide-vue-next": "0.
|
|
62
|
+
"lucide-vue-next": "0.544.0",
|
|
63
63
|
"msw-storybook-addon": "^2.0.3",
|
|
64
64
|
"normalize.css": "8.0.1",
|
|
65
65
|
"path": "0.12.7",
|
|
66
66
|
"prettier": "3.6.2",
|
|
67
|
-
"sass": "1.92.
|
|
68
|
-
"semantic-release": "24.2.
|
|
69
|
-
"start-server-and-test": "2.0
|
|
70
|
-
"storybook": "9.1.
|
|
71
|
-
"storybook-addon-pseudo-states": "9.1.
|
|
67
|
+
"sass": "1.92.1",
|
|
68
|
+
"semantic-release": "24.2.8",
|
|
69
|
+
"start-server-and-test": "2.1.0",
|
|
70
|
+
"storybook": "9.1.5",
|
|
71
|
+
"storybook-addon-pseudo-states": "9.1.5",
|
|
72
72
|
"storybook-vue3-router": "^6.0.2",
|
|
73
73
|
"typescript": "5.2.2",
|
|
74
|
-
"uuid": "
|
|
75
|
-
"vite": "7.1.
|
|
74
|
+
"uuid": "13.0.0",
|
|
75
|
+
"vite": "7.1.5",
|
|
76
76
|
"vite-plugin-dts": "^4.1.0",
|
|
77
77
|
"vite-plugin-mkcert": "1.17.8",
|
|
78
78
|
"vite-plugin-pages": "0.33.1",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"vue-codemirror": "6.1.1",
|
|
83
83
|
"vue-loader": "17.4.2",
|
|
84
84
|
"vue-router": "4.5.1",
|
|
85
|
-
"vue-tsc": "3.0.
|
|
85
|
+
"vue-tsc": "3.0.7"
|
|
86
86
|
},
|
|
87
87
|
"files": [
|
|
88
88
|
"dist",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<BmsSelect
|
|
3
|
-
v-model:open="open"
|
|
4
3
|
v-bind="$props"
|
|
4
|
+
:options="displayedOptions"
|
|
5
5
|
:model-value="modelValue"
|
|
6
6
|
@update:model-value="onSelect"
|
|
7
7
|
>
|
|
@@ -59,7 +59,6 @@ const searching = ref('');
|
|
|
59
59
|
const modelValue = defineModel<InputOption[]>('modelValue', {
|
|
60
60
|
required: true,
|
|
61
61
|
});
|
|
62
|
-
const open = defineModel<boolean>('open', { default: false });
|
|
63
62
|
|
|
64
63
|
const onSelect = (value: string) => {
|
|
65
64
|
const option = props.options.find((o) => o.value === value);
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
:required="required"
|
|
11
11
|
:small="small"
|
|
12
12
|
@input="onInput"
|
|
13
|
-
v-model:focus="isInputFocused"
|
|
14
13
|
>
|
|
15
14
|
<template #icon-start>
|
|
16
15
|
<slot name="icon-start"></slot>
|
|
@@ -20,12 +19,8 @@
|
|
|
20
19
|
<span v-if="inputText.length" class="icon" @click="clearInput">
|
|
21
20
|
<X />
|
|
22
21
|
</span>
|
|
23
|
-
<span
|
|
24
|
-
v-
|
|
25
|
-
class="icon"
|
|
26
|
-
@click.stop="isInputFocused = !isInputFocused"
|
|
27
|
-
>
|
|
28
|
-
<ChevronDown v-if="!isInputFocused" />
|
|
22
|
+
<span v-else class="icon" @click.stop="toggleList">
|
|
23
|
+
<ChevronDown v-if="!showDataList" />
|
|
29
24
|
<ChevronUp v-else />
|
|
30
25
|
</span>
|
|
31
26
|
</slot>
|
|
@@ -33,9 +28,9 @@
|
|
|
33
28
|
</RawInputText>
|
|
34
29
|
<template #datalist>
|
|
35
30
|
<FieldDatalist
|
|
36
|
-
v-show="
|
|
31
|
+
v-show="showDataList"
|
|
37
32
|
data-testid="autocomplete-menu"
|
|
38
|
-
:is-input-focused="
|
|
33
|
+
:is-input-focused="showDataList"
|
|
39
34
|
:can-add-new-option="canAddNewOption"
|
|
40
35
|
:new-option="inputText"
|
|
41
36
|
:options="filteredMenuItems"
|
|
@@ -90,7 +85,7 @@ const getValidOptionByValue = (value: string | null) =>
|
|
|
90
85
|
const inputText = ref<string>(
|
|
91
86
|
getValidOptionByValue(modelValue.value)?.label ?? '',
|
|
92
87
|
);
|
|
93
|
-
const
|
|
88
|
+
const showDataList = ref<boolean>(props.open);
|
|
94
89
|
const autocompleteInput: Ref<HTMLElement | null> = ref(null);
|
|
95
90
|
|
|
96
91
|
const classes = computed(() => {
|
|
@@ -106,7 +101,8 @@ const selectItem = (option: InputOption) => {
|
|
|
106
101
|
const existingOption =
|
|
107
102
|
getValidOptionByLabel(option.label) || getValidOptionByValue(option.value);
|
|
108
103
|
modelValue.value = existingOption?.value ?? null;
|
|
109
|
-
|
|
104
|
+
showDataList.value = false;
|
|
105
|
+
setFocus();
|
|
110
106
|
};
|
|
111
107
|
|
|
112
108
|
const displayItem = (option: InputOption) => {
|
|
@@ -136,7 +132,7 @@ watch(
|
|
|
136
132
|
},
|
|
137
133
|
);
|
|
138
134
|
const onInput = () => {
|
|
139
|
-
|
|
135
|
+
showDataList.value = true;
|
|
140
136
|
if (inputText.value === '') {
|
|
141
137
|
clearInput();
|
|
142
138
|
}
|
|
@@ -144,14 +140,19 @@ const onInput = () => {
|
|
|
144
140
|
|
|
145
141
|
const setFocus = () => {
|
|
146
142
|
if (autocompleteInput.value) {
|
|
147
|
-
autocompleteInput.value.
|
|
143
|
+
(autocompleteInput.value as any).setFocus();
|
|
148
144
|
}
|
|
149
145
|
};
|
|
146
|
+
|
|
150
147
|
const clearInput = () => {
|
|
151
148
|
inputText.value = '';
|
|
152
149
|
modelValue.value = null;
|
|
150
|
+
setFocus();
|
|
151
|
+
};
|
|
152
|
+
const toggleList = () => {
|
|
153
|
+
showDataList.value = !showDataList.value;
|
|
154
|
+
setFocus();
|
|
153
155
|
};
|
|
154
|
-
|
|
155
156
|
defineExpose({
|
|
156
157
|
setFocus,
|
|
157
158
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import UiBmsTable from '@/components/table/UiBmsTable.vue';
|
|
2
2
|
import { Save, Trash } from 'lucide-vue-next';
|
|
3
3
|
import BmsIconButton from '@/components/button/BmsIconButton.vue';
|
|
4
|
+
import { ColumnType } from '@/models/table.model';
|
|
4
5
|
|
|
5
6
|
import template from '@/documentation/template_internal_component.mdx';
|
|
6
7
|
|
|
@@ -379,6 +380,42 @@ SelectableDisabled.args = {
|
|
|
379
380
|
selectableDisabled: true,
|
|
380
381
|
totalSize: 2,
|
|
381
382
|
};
|
|
383
|
+
export const Typed = Template.bind({});
|
|
384
|
+
Typed.args = {
|
|
385
|
+
headers: [
|
|
386
|
+
{
|
|
387
|
+
label: 'Column boolean',
|
|
388
|
+
key: 'col1',
|
|
389
|
+
align: 'start',
|
|
390
|
+
columnType: ColumnType.Boolean,
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
label: 'Column date',
|
|
394
|
+
key: 'col2',
|
|
395
|
+
align: 'center',
|
|
396
|
+
columnType: ColumnType.Date,
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
label: 'Column 3',
|
|
400
|
+
key: 'col3',
|
|
401
|
+
align: 'end',
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
items: [
|
|
405
|
+
{
|
|
406
|
+
col1: true,
|
|
407
|
+
col2: '2024-10-10T12:00:00Z',
|
|
408
|
+
col3: 'Value3',
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
col1: false,
|
|
412
|
+
col2: '2025-01-01T18:00:00Z',
|
|
413
|
+
col3: 'Value3',
|
|
414
|
+
},
|
|
415
|
+
],
|
|
416
|
+
hasFilters: true,
|
|
417
|
+
totalSize: 2,
|
|
418
|
+
};
|
|
382
419
|
|
|
383
420
|
const TemplateWithActionColumn = (args) => ({
|
|
384
421
|
components: {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<template v-if="cell.columnType === ColumnType.Boolean">
|
|
3
|
+
<BmsChip v-if="cellValue" :color="ChipColor.Green">Oui</BmsChip>
|
|
4
|
+
<BmsChip v-else>Non</BmsChip>
|
|
5
|
+
</template>
|
|
6
|
+
<template v-else-if="cell.columnType === ColumnType.Date">
|
|
7
|
+
<BmsRelativeTime :relativeTo="relativeToTime" />
|
|
8
|
+
</template>
|
|
9
|
+
<template v-else>
|
|
10
|
+
{{ cellValue }}
|
|
11
|
+
</template>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { ChipColor, ColumnType, TableHeader } from '@/models';
|
|
16
|
+
import _get from 'lodash/get';
|
|
17
|
+
import BmsChip from '../form/BmsChip.vue';
|
|
18
|
+
import { computed } from 'vue';
|
|
19
|
+
import BmsRelativeTime from '../utils/BmsRelativeTime.vue';
|
|
20
|
+
|
|
21
|
+
const props = defineProps<{ cell: TableHeader; item: any }>();
|
|
22
|
+
|
|
23
|
+
const cellValue = computed(() => _get(props.item, props.cell.key) ?? '');
|
|
24
|
+
const relativeToTime = computed(() => new Date(cellValue.value)?.getTime());
|
|
25
|
+
</script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import UiBmsTableRow from '@/components/table/UiBmsTableRow.vue';
|
|
2
|
+
import { ColumnType } from '@/models/table.model';
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
title: 'Composants/table/UiBmsTableRow',
|
|
@@ -141,3 +142,32 @@ IsChildElement.args = {
|
|
|
141
142
|
},
|
|
142
143
|
},
|
|
143
144
|
};
|
|
145
|
+
|
|
146
|
+
export const Typed = Template.bind({});
|
|
147
|
+
Typed.args = {
|
|
148
|
+
headers: [
|
|
149
|
+
{
|
|
150
|
+
label: 'Column boolean',
|
|
151
|
+
key: 'col1',
|
|
152
|
+
align: 'start',
|
|
153
|
+
columnType: ColumnType.Boolean,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
label: 'Column date',
|
|
157
|
+
key: 'col2',
|
|
158
|
+
align: 'center',
|
|
159
|
+
columnType: ColumnType.Date,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
label: 'Column 3',
|
|
163
|
+
key: 'col3',
|
|
164
|
+
align: 'end',
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
selectedItems: [],
|
|
168
|
+
item: {
|
|
169
|
+
col1: true,
|
|
170
|
+
col2: '2022-01-01',
|
|
171
|
+
col3: 'Value3',
|
|
172
|
+
},
|
|
173
|
+
};
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
:row="item.childElement"
|
|
38
38
|
:isChildElement="isChildElement"
|
|
39
39
|
>
|
|
40
|
-
|
|
40
|
+
<UiBmsTableCell :item="item.childElement" :cell="cell" />
|
|
41
41
|
</slot>
|
|
42
42
|
</div>
|
|
43
43
|
<div v-else-if="cell?.action" class="bms-table__row__cell--action">
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
:row="item"
|
|
54
54
|
:isChildElement="isChildElement"
|
|
55
55
|
>
|
|
56
|
-
|
|
56
|
+
<UiBmsTableCell :item="item" :cell="cell" />
|
|
57
57
|
</slot>
|
|
58
58
|
</td>
|
|
59
59
|
</slot>
|
|
@@ -68,6 +68,7 @@ import _get from 'lodash/get';
|
|
|
68
68
|
import UiBmsInputCheckbox from '../form/UiBmsInputCheckbox.vue';
|
|
69
69
|
import BmsTooltip from '../feedback/BmsTooltip.vue';
|
|
70
70
|
import { CornerDownRight } from 'lucide-vue-next';
|
|
71
|
+
import UiBmsTableCell from './UiBmsTableCell.vue';
|
|
71
72
|
|
|
72
73
|
interface Props {
|
|
73
74
|
item: any;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { InputType } from './form.model';
|
|
2
2
|
import { Sort, SortFunction } from './sort.model';
|
|
3
3
|
|
|
4
|
+
export enum ColumnType {
|
|
5
|
+
Boolean = 'Boolean',
|
|
6
|
+
Date = 'Date',
|
|
7
|
+
String = 'String',
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
export interface TableHeader {
|
|
5
11
|
label: string;
|
|
6
12
|
key: string;
|
|
@@ -10,6 +16,7 @@ export interface TableHeader {
|
|
|
10
16
|
sortable?: boolean;
|
|
11
17
|
sortFunction?: SortFunction;
|
|
12
18
|
action?: boolean;
|
|
19
|
+
columnType?: ColumnType;
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
export interface ServerTableRequestParams {
|
|
@@ -14,21 +14,6 @@
|
|
|
14
14
|
@saveFilter="onSaveFilter"
|
|
15
15
|
@deleteSavedFilter="onDeleteSavedFilter"
|
|
16
16
|
>
|
|
17
|
-
<template #date="{ row }">
|
|
18
|
-
<bms-tooltip :tooltip-text="row.date.toUTCString()">
|
|
19
|
-
{{ row.date.toLocaleDateString() }}
|
|
20
|
-
</bms-tooltip>
|
|
21
|
-
</template>
|
|
22
|
-
<template #dateUpdate="{ row }">
|
|
23
|
-
<bms-tooltip :tooltip-text="row.dateUpdate.toUTCString()">
|
|
24
|
-
{{ row.dateUpdate.toLocaleDateString() }}
|
|
25
|
-
</bms-tooltip>
|
|
26
|
-
</template>
|
|
27
|
-
<template #dateDelete="{ row }">
|
|
28
|
-
<bms-tooltip :tooltip-text="row.dateDelete.toUTCString()">
|
|
29
|
-
{{ row.dateDelete.toLocaleDateString() }}
|
|
30
|
-
</bms-tooltip>
|
|
31
|
-
</template>
|
|
32
17
|
<template #choice2="{ row }">
|
|
33
18
|
<BmsTooltip tooltipText="tooltip">
|
|
34
19
|
{{ row.choice2 }}
|
|
@@ -65,6 +50,7 @@
|
|
|
65
50
|
<script lang="ts" setup>
|
|
66
51
|
import { BmsBackButton, BmsButton, useNotifications } from '@/index';
|
|
67
52
|
import {
|
|
53
|
+
ColumnType,
|
|
68
54
|
Filter,
|
|
69
55
|
InputType,
|
|
70
56
|
SavedFilter,
|
|
@@ -86,9 +72,9 @@ const headers = [
|
|
|
86
72
|
{ label: 'Colonne 1', key: 'column1', sortable: true },
|
|
87
73
|
{ label: 'actions', key: 'action', action: true },
|
|
88
74
|
{ label: 'Colonne 2', key: 'column2' },
|
|
89
|
-
{ label: 'Date', key: 'date' },
|
|
90
|
-
{ label: 'DateUpdate', key: 'dateUpdate' },
|
|
91
|
-
{ label: 'DateDelete', key: 'dateDelete' },
|
|
75
|
+
{ label: 'Date', key: 'date', columnType: ColumnType.Date },
|
|
76
|
+
{ label: 'DateUpdate', key: 'dateUpdate', columnType: ColumnType.Date },
|
|
77
|
+
{ label: 'DateDelete', key: 'dateDelete', columnType: ColumnType.Date },
|
|
92
78
|
{ label: 'choice1', key: 'choice1' },
|
|
93
79
|
{ label: 'choice2', key: 'choice2' },
|
|
94
80
|
{
|