shared-ritm 1.3.78 → 1.3.79
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/index.css +1 -1
- package/dist/shared-ritm.es.js +15 -14
- package/dist/shared-ritm.umd.js +2 -2
- package/package.json +70 -70
- package/src/App.vue +2461 -2461
- package/src/api/services/AuthService.ts +67 -67
- package/src/api/services/ControlsService.ts +96 -96
- package/src/api/services/EquipmentService.ts +29 -29
- package/src/api/services/MetricsService.ts +143 -143
- package/src/api/services/RepairsService.ts +111 -111
- package/src/api/services/UserIssueService.ts +32 -32
- package/src/api/services/UserService.ts +129 -129
- package/src/api/services/VideoService.ts +118 -118
- package/src/api/settings/ApiService.ts +184 -184
- package/src/api/types/Api_Auth.ts +121 -121
- package/src/api/types/Api_Metrics.ts +51 -51
- package/src/api/types/Api_Repairs.ts +187 -187
- package/src/api/types/Api_Tasks.ts +376 -376
- package/src/api/types/Api_User.ts +156 -156
- package/src/api/types/Api_User_Issue.ts +36 -36
- package/src/api/types/Api_Video.ts +244 -244
- package/src/common/app-button/Button.stories.ts +369 -369
- package/src/common/app-checkbox/AppCheckbox.vue +31 -31
- package/src/common/app-checkbox/Checkbox.stories.ts +252 -252
- package/src/common/app-date-picker/DatePicker.stories.ts +66 -66
- package/src/common/app-datepicker/Datepicker.stories.ts +145 -145
- package/src/common/app-dialogs/AppConfirmDialog.vue +109 -109
- package/src/common/app-dialogs/Confirm.stories.ts +93 -93
- package/src/common/app-dropdown/Dropdown.stories.ts +94 -94
- package/src/common/app-file/File.stories.ts +104 -104
- package/src/common/app-icon/AppIcon.vue +110 -110
- package/src/common/app-icon/Icon.stories.ts +91 -91
- package/src/common/app-input/AppInput.vue +2 -0
- package/src/common/app-input/Input.stories.ts +160 -160
- package/src/common/app-input-new/AppInputNew.vue +181 -181
- package/src/common/app-input-new/InputNew.stories.ts +240 -240
- package/src/common/app-input-search/InputSearch.stories.ts +149 -149
- package/src/common/app-layout/components/AppLayoutHeader.vue +289 -289
- package/src/common/app-loader/Loader.stories.ts +114 -114
- package/src/common/app-select/AppSelect.vue +159 -159
- package/src/common/app-select/Select.stories.ts +155 -155
- package/src/common/app-sidebar/AppSidebar.vue +174 -174
- package/src/common/app-table/AppTable.vue +313 -313
- package/src/common/app-table/components/ModalSelect.stories.ts +323 -323
- package/src/common/app-table/components/ModalSelect.vue +302 -302
- package/src/common/app-table/components/TableModal.vue +367 -367
- package/src/common/app-table/controllers/useColumnSelector.ts +45 -45
- package/src/common/app-table/controllers/useTableModel.ts +97 -97
- package/src/common/app-toggle/AppToggle.vue +12 -12
- package/src/common/app-toggle/Toggle.stories.ts +245 -245
- package/src/common/app-wrapper/AppWrapper.vue +31 -31
- package/src/configs/storybook.ts +14 -14
- package/src/icons/sidebar/user-requests-icon.vue +23 -23
- package/src/index.ts +134 -134
- package/src/shared/styles/general.css +140 -140
- package/src/styles/variables.sass +12 -12
- package/src/utils/files.ts +38 -38
- package/src/utils/helpers.ts +59 -59
- package/dist/types/api/services/PhotoService.d.ts +0 -40
- package/dist/types/stories/Button.stories.d.ts +0 -13
- package/dist/types/stories/Checkbox.stories.d.ts +0 -7
- package/dist/types/stories/Confirm.stories.d.ts +0 -8
- package/dist/types/stories/DatePicker.stories.d.ts +0 -8
- package/dist/types/stories/Dropdown.stories.d.ts +0 -8
- package/dist/types/stories/File.stories.d.ts +0 -8
- package/dist/types/stories/Icon.stories.d.ts +0 -7
- package/dist/types/stories/Input.stories.d.ts +0 -11
- package/dist/types/stories/InputNew.stories.d.ts +0 -12
- package/dist/types/stories/InputSearch.stories.d.ts +0 -10
- package/dist/types/stories/Loader.stories.d.ts +0 -8
- package/dist/types/stories/Select.stories.d.ts +0 -7
- package/dist/types/stories/Toggle.stories.d.ts +0 -8
|
@@ -1,323 +1,323 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
-
import ModalSelect from './ModalSelect.vue'
|
|
3
|
-
import { ref } from 'vue'
|
|
4
|
-
|
|
5
|
-
const SAMPLE_OPTIONS = [
|
|
6
|
-
{ value: 1, label: 'Проект Альфа' },
|
|
7
|
-
{ value: 2, label: 'Ремонт №42' },
|
|
8
|
-
{ value: 3, label: 'Инструмент XYZ' },
|
|
9
|
-
{ value: 4, label: 'Объект "Центр"' },
|
|
10
|
-
{ value: 5, label: 'Статус: Готов' },
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
const meta: Meta<typeof ModalSelect> = {
|
|
14
|
-
title: 'Components/ModalSelect',
|
|
15
|
-
component: ModalSelect,
|
|
16
|
-
tags: ['autodocs'],
|
|
17
|
-
argTypes: {
|
|
18
|
-
modelValue: {
|
|
19
|
-
control: false,
|
|
20
|
-
description: 'Выбранное значение (или массив). Используется с v-model.',
|
|
21
|
-
table: { category: '🔤 Значение' },
|
|
22
|
-
},
|
|
23
|
-
options: {
|
|
24
|
-
control: false,
|
|
25
|
-
description: 'Массив опций. Каждая — объект с полями, указанными в optionLabel/optionValue.',
|
|
26
|
-
},
|
|
27
|
-
label: {
|
|
28
|
-
control: 'text',
|
|
29
|
-
description: 'Подпись над селектом.',
|
|
30
|
-
table: { category: '🔤 Текст' },
|
|
31
|
-
},
|
|
32
|
-
placeholder: {
|
|
33
|
-
control: 'text',
|
|
34
|
-
table: { category: '🔤 Текст' },
|
|
35
|
-
},
|
|
36
|
-
emptyText: {
|
|
37
|
-
control: 'text',
|
|
38
|
-
description: 'Текст, отображаемый, если опции не найдены.',
|
|
39
|
-
table: { category: '🔤 Текст' },
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
multiple: {
|
|
43
|
-
control: 'boolean',
|
|
44
|
-
description: 'Разрешить множественный выбор.',
|
|
45
|
-
table: { category: '⚙️ Поведение' },
|
|
46
|
-
},
|
|
47
|
-
hideSearch: {
|
|
48
|
-
control: 'boolean',
|
|
49
|
-
description: 'Скрыть поле поиска.',
|
|
50
|
-
table: { category: '⚙️ Поведение' },
|
|
51
|
-
},
|
|
52
|
-
allowCreate: {
|
|
53
|
-
control: 'boolean',
|
|
54
|
-
description: 'Разрешить создание новых опций из поиска.',
|
|
55
|
-
table: { category: '⚙️ Поведение' },
|
|
56
|
-
},
|
|
57
|
-
showChip: {
|
|
58
|
-
control: 'boolean',
|
|
59
|
-
description: 'Показывать выбранные значения как чипы (даже в single-режиме).',
|
|
60
|
-
table: { category: '⚙️ Поведение' },
|
|
61
|
-
},
|
|
62
|
-
simple: {
|
|
63
|
-
control: 'boolean',
|
|
64
|
-
description: 'Обычный: без chips, но с выбранным значением.',
|
|
65
|
-
table: { category: '⚙️ Поведение' },
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
loading: {
|
|
69
|
-
control: 'boolean',
|
|
70
|
-
description: 'Показывает индикатор загрузки в меню.',
|
|
71
|
-
table: { category: '⚡ Состояния' },
|
|
72
|
-
},
|
|
73
|
-
isDisabled: {
|
|
74
|
-
control: 'boolean',
|
|
75
|
-
description: 'Отключает селект.',
|
|
76
|
-
table: { category: '⚡ Состояния' },
|
|
77
|
-
},
|
|
78
|
-
isShowRequired: {
|
|
79
|
-
control: 'boolean',
|
|
80
|
-
description: 'Показывать звёздочку у лейбла, если есть правила валидации.',
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
chipColor: {
|
|
84
|
-
control: 'color',
|
|
85
|
-
description: 'Фон чипов при multiple-выборе (HEX/RGB).',
|
|
86
|
-
table: { category: '🎨 Стили' },
|
|
87
|
-
},
|
|
88
|
-
borderColor: {
|
|
89
|
-
control: 'color',
|
|
90
|
-
description: 'Цвет границы (HEX/RGB).',
|
|
91
|
-
table: { category: '🎨 Стили' },
|
|
92
|
-
},
|
|
93
|
-
borderRadius: {
|
|
94
|
-
control: 'text',
|
|
95
|
-
description: 'Скругление углов (например, "8px").',
|
|
96
|
-
table: { category: '🎨 Стили' },
|
|
97
|
-
},
|
|
98
|
-
height: {
|
|
99
|
-
control: 'text',
|
|
100
|
-
description: 'Высота поля (например, "50px").',
|
|
101
|
-
table: { category: '🎨 Стили' },
|
|
102
|
-
},
|
|
103
|
-
menuWidth: {
|
|
104
|
-
control: 'text',
|
|
105
|
-
description: 'Ширина выпадающего меню (например, "300px").',
|
|
106
|
-
table: { category: '🎨 Стили' },
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
optionLabel: {
|
|
110
|
-
control: 'text',
|
|
111
|
-
description: 'Ключ объекта опции для отображения (по умолчанию "label").',
|
|
112
|
-
table: { category: '📦 Опции' },
|
|
113
|
-
},
|
|
114
|
-
optionValue: {
|
|
115
|
-
control: 'text',
|
|
116
|
-
description: 'Ключ объекта опции для значения (по умолчанию "value").',
|
|
117
|
-
table: { category: '📦 Опции' },
|
|
118
|
-
},
|
|
119
|
-
popupContentStyle: {
|
|
120
|
-
control: 'text',
|
|
121
|
-
description: 'Дополнительные стили для выпадающего меню.',
|
|
122
|
-
table: { category: '🎨 Стили' },
|
|
123
|
-
},
|
|
124
|
-
rules: {
|
|
125
|
-
table: { disable: true },
|
|
126
|
-
description: 'Массив функций валидации.',
|
|
127
|
-
},
|
|
128
|
-
hideBottomSpace: {
|
|
129
|
-
table: { disable: true },
|
|
130
|
-
},
|
|
131
|
-
dataTest: {
|
|
132
|
-
table: { disable: true },
|
|
133
|
-
},
|
|
134
|
-
isSearch: {
|
|
135
|
-
table: { disable: true },
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
args: {
|
|
139
|
-
label: 'Выберите элемент',
|
|
140
|
-
placeholder: 'Начните ввод...',
|
|
141
|
-
emptyText: 'Ничего не найдено',
|
|
142
|
-
options: SAMPLE_OPTIONS,
|
|
143
|
-
multiple: false,
|
|
144
|
-
hideSearch: false,
|
|
145
|
-
allowCreate: false,
|
|
146
|
-
showChip: false,
|
|
147
|
-
simple: false,
|
|
148
|
-
loading: false,
|
|
149
|
-
isDisabled: false,
|
|
150
|
-
isShowRequired: false,
|
|
151
|
-
chipColor: '#e9eff9',
|
|
152
|
-
borderRadius: '8px',
|
|
153
|
-
optionLabel: 'label',
|
|
154
|
-
optionValue: 'value',
|
|
155
|
-
},
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export default meta
|
|
159
|
-
|
|
160
|
-
type Story = StoryObj<typeof ModalSelect>
|
|
161
|
-
|
|
162
|
-
export const Default: Story = {}
|
|
163
|
-
|
|
164
|
-
export const Modes: Story = {
|
|
165
|
-
render: () => ({
|
|
166
|
-
components: { ModalSelect },
|
|
167
|
-
template: `
|
|
168
|
-
<div>
|
|
169
|
-
<ModalSelect
|
|
170
|
-
v-model="simpleValue"
|
|
171
|
-
:options="options"
|
|
172
|
-
label="Обычный"
|
|
173
|
-
:simple="true"
|
|
174
|
-
/>
|
|
175
|
-
<ModalSelect
|
|
176
|
-
v-model="chipValue"
|
|
177
|
-
:options="options"
|
|
178
|
-
label="Обычный chip"
|
|
179
|
-
:show-chip="true"
|
|
180
|
-
/>
|
|
181
|
-
<ModalSelect
|
|
182
|
-
v-model="multiValue"
|
|
183
|
-
:options="options"
|
|
184
|
-
label="Множественный chip"
|
|
185
|
-
:show-chip="true"
|
|
186
|
-
multiple
|
|
187
|
-
/>
|
|
188
|
-
</div>
|
|
189
|
-
`,
|
|
190
|
-
data() {
|
|
191
|
-
return {
|
|
192
|
-
options: SAMPLE_OPTIONS,
|
|
193
|
-
singleValue: 2,
|
|
194
|
-
multiValue: [1, 3],
|
|
195
|
-
chipValue: 4,
|
|
196
|
-
simpleValue: 5,
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
}),
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export const SearchAndCreate: Story = {
|
|
203
|
-
render: () => ({
|
|
204
|
-
components: { ModalSelect },
|
|
205
|
-
template: `
|
|
206
|
-
<div>
|
|
207
|
-
<ModalSelect
|
|
208
|
-
v-model="searchValue"
|
|
209
|
-
:options="options"
|
|
210
|
-
label="С поиском"
|
|
211
|
-
placeholder="Начните ввод..."
|
|
212
|
-
/>
|
|
213
|
-
<ModalSelect
|
|
214
|
-
v-model="createValue"
|
|
215
|
-
:options="localOptions"
|
|
216
|
-
label="Создание новых"
|
|
217
|
-
placeholder="Введите новое значение"
|
|
218
|
-
allow-create
|
|
219
|
-
@create="handleCreate"
|
|
220
|
-
/>
|
|
221
|
-
</div>
|
|
222
|
-
`,
|
|
223
|
-
setup() {
|
|
224
|
-
const options = SAMPLE_OPTIONS
|
|
225
|
-
const localOptions = ref([...options])
|
|
226
|
-
const searchValue = ref(null)
|
|
227
|
-
const createValue = ref(null)
|
|
228
|
-
|
|
229
|
-
const handleCreate = (newOption: any) => {
|
|
230
|
-
localOptions.value.push(newOption)
|
|
231
|
-
createValue.value = newOption.value
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
options,
|
|
236
|
-
localOptions,
|
|
237
|
-
searchValue,
|
|
238
|
-
createValue,
|
|
239
|
-
handleCreate,
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
}),
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
export const States: Story = {
|
|
246
|
-
render: () => ({
|
|
247
|
-
components: { ModalSelect },
|
|
248
|
-
template: `
|
|
249
|
-
<div>
|
|
250
|
-
<ModalSelect
|
|
251
|
-
v-model="disabledValue"
|
|
252
|
-
:options="options"
|
|
253
|
-
label="Отключено"
|
|
254
|
-
:is-disabled="true"
|
|
255
|
-
/>
|
|
256
|
-
<ModalSelect
|
|
257
|
-
v-model="loadingValue"
|
|
258
|
-
:options="options"
|
|
259
|
-
label="Загрузка"
|
|
260
|
-
:loading="true"
|
|
261
|
-
/>
|
|
262
|
-
<ModalSelect
|
|
263
|
-
v-model="requiredValue"
|
|
264
|
-
:options="options"
|
|
265
|
-
label="Обязательное"
|
|
266
|
-
:is-show-required="true"
|
|
267
|
-
simple
|
|
268
|
-
:rules="[v => !!v || 'Обязательно']"
|
|
269
|
-
/>
|
|
270
|
-
</div>
|
|
271
|
-
`,
|
|
272
|
-
data() {
|
|
273
|
-
return {
|
|
274
|
-
options: SAMPLE_OPTIONS,
|
|
275
|
-
normalValue: 1,
|
|
276
|
-
disabledValue: 2,
|
|
277
|
-
loadingValue: 3,
|
|
278
|
-
requiredValue: null,
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
}),
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export const WithSlots: Story = {
|
|
285
|
-
render: () => ({
|
|
286
|
-
components: { ModalSelect },
|
|
287
|
-
template: `
|
|
288
|
-
<ModalSelect
|
|
289
|
-
v-model="slotValue"
|
|
290
|
-
:options="options"
|
|
291
|
-
label="С кастомными опциями"
|
|
292
|
-
simple
|
|
293
|
-
>
|
|
294
|
-
<template #option="{ opt }">
|
|
295
|
-
<q-item>
|
|
296
|
-
<q-item-section avatar>
|
|
297
|
-
<q-icon name="folder" color="primary" />
|
|
298
|
-
</q-item-section>
|
|
299
|
-
<q-item-section>
|
|
300
|
-
<div style="font-weight: 600;">{{ opt.label }}</div>
|
|
301
|
-
<div style="font-size: 12px; color: #777;">ID: {{ opt.value }}</div>
|
|
302
|
-
</q-item-section>
|
|
303
|
-
</q-item>
|
|
304
|
-
</template>
|
|
305
|
-
<template #selected="{ opt }">
|
|
306
|
-
<q-chip
|
|
307
|
-
removable
|
|
308
|
-
text-color="secondary"
|
|
309
|
-
@remove="slotValue = null"
|
|
310
|
-
>
|
|
311
|
-
📁 {{ opt.label }}
|
|
312
|
-
</q-chip>
|
|
313
|
-
</template>
|
|
314
|
-
</ModalSelect>
|
|
315
|
-
`,
|
|
316
|
-
data() {
|
|
317
|
-
return {
|
|
318
|
-
options: SAMPLE_OPTIONS,
|
|
319
|
-
slotValue: 2,
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
}),
|
|
323
|
-
}
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import ModalSelect from './ModalSelect.vue'
|
|
3
|
+
import { ref } from 'vue'
|
|
4
|
+
|
|
5
|
+
const SAMPLE_OPTIONS = [
|
|
6
|
+
{ value: 1, label: 'Проект Альфа' },
|
|
7
|
+
{ value: 2, label: 'Ремонт №42' },
|
|
8
|
+
{ value: 3, label: 'Инструмент XYZ' },
|
|
9
|
+
{ value: 4, label: 'Объект "Центр"' },
|
|
10
|
+
{ value: 5, label: 'Статус: Готов' },
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
const meta: Meta<typeof ModalSelect> = {
|
|
14
|
+
title: 'Components/ModalSelect',
|
|
15
|
+
component: ModalSelect,
|
|
16
|
+
tags: ['autodocs'],
|
|
17
|
+
argTypes: {
|
|
18
|
+
modelValue: {
|
|
19
|
+
control: false,
|
|
20
|
+
description: 'Выбранное значение (или массив). Используется с v-model.',
|
|
21
|
+
table: { category: '🔤 Значение' },
|
|
22
|
+
},
|
|
23
|
+
options: {
|
|
24
|
+
control: false,
|
|
25
|
+
description: 'Массив опций. Каждая — объект с полями, указанными в optionLabel/optionValue.',
|
|
26
|
+
},
|
|
27
|
+
label: {
|
|
28
|
+
control: 'text',
|
|
29
|
+
description: 'Подпись над селектом.',
|
|
30
|
+
table: { category: '🔤 Текст' },
|
|
31
|
+
},
|
|
32
|
+
placeholder: {
|
|
33
|
+
control: 'text',
|
|
34
|
+
table: { category: '🔤 Текст' },
|
|
35
|
+
},
|
|
36
|
+
emptyText: {
|
|
37
|
+
control: 'text',
|
|
38
|
+
description: 'Текст, отображаемый, если опции не найдены.',
|
|
39
|
+
table: { category: '🔤 Текст' },
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
multiple: {
|
|
43
|
+
control: 'boolean',
|
|
44
|
+
description: 'Разрешить множественный выбор.',
|
|
45
|
+
table: { category: '⚙️ Поведение' },
|
|
46
|
+
},
|
|
47
|
+
hideSearch: {
|
|
48
|
+
control: 'boolean',
|
|
49
|
+
description: 'Скрыть поле поиска.',
|
|
50
|
+
table: { category: '⚙️ Поведение' },
|
|
51
|
+
},
|
|
52
|
+
allowCreate: {
|
|
53
|
+
control: 'boolean',
|
|
54
|
+
description: 'Разрешить создание новых опций из поиска.',
|
|
55
|
+
table: { category: '⚙️ Поведение' },
|
|
56
|
+
},
|
|
57
|
+
showChip: {
|
|
58
|
+
control: 'boolean',
|
|
59
|
+
description: 'Показывать выбранные значения как чипы (даже в single-режиме).',
|
|
60
|
+
table: { category: '⚙️ Поведение' },
|
|
61
|
+
},
|
|
62
|
+
simple: {
|
|
63
|
+
control: 'boolean',
|
|
64
|
+
description: 'Обычный: без chips, но с выбранным значением.',
|
|
65
|
+
table: { category: '⚙️ Поведение' },
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
loading: {
|
|
69
|
+
control: 'boolean',
|
|
70
|
+
description: 'Показывает индикатор загрузки в меню.',
|
|
71
|
+
table: { category: '⚡ Состояния' },
|
|
72
|
+
},
|
|
73
|
+
isDisabled: {
|
|
74
|
+
control: 'boolean',
|
|
75
|
+
description: 'Отключает селект.',
|
|
76
|
+
table: { category: '⚡ Состояния' },
|
|
77
|
+
},
|
|
78
|
+
isShowRequired: {
|
|
79
|
+
control: 'boolean',
|
|
80
|
+
description: 'Показывать звёздочку у лейбла, если есть правила валидации.',
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
chipColor: {
|
|
84
|
+
control: 'color',
|
|
85
|
+
description: 'Фон чипов при multiple-выборе (HEX/RGB).',
|
|
86
|
+
table: { category: '🎨 Стили' },
|
|
87
|
+
},
|
|
88
|
+
borderColor: {
|
|
89
|
+
control: 'color',
|
|
90
|
+
description: 'Цвет границы (HEX/RGB).',
|
|
91
|
+
table: { category: '🎨 Стили' },
|
|
92
|
+
},
|
|
93
|
+
borderRadius: {
|
|
94
|
+
control: 'text',
|
|
95
|
+
description: 'Скругление углов (например, "8px").',
|
|
96
|
+
table: { category: '🎨 Стили' },
|
|
97
|
+
},
|
|
98
|
+
height: {
|
|
99
|
+
control: 'text',
|
|
100
|
+
description: 'Высота поля (например, "50px").',
|
|
101
|
+
table: { category: '🎨 Стили' },
|
|
102
|
+
},
|
|
103
|
+
menuWidth: {
|
|
104
|
+
control: 'text',
|
|
105
|
+
description: 'Ширина выпадающего меню (например, "300px").',
|
|
106
|
+
table: { category: '🎨 Стили' },
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
optionLabel: {
|
|
110
|
+
control: 'text',
|
|
111
|
+
description: 'Ключ объекта опции для отображения (по умолчанию "label").',
|
|
112
|
+
table: { category: '📦 Опции' },
|
|
113
|
+
},
|
|
114
|
+
optionValue: {
|
|
115
|
+
control: 'text',
|
|
116
|
+
description: 'Ключ объекта опции для значения (по умолчанию "value").',
|
|
117
|
+
table: { category: '📦 Опции' },
|
|
118
|
+
},
|
|
119
|
+
popupContentStyle: {
|
|
120
|
+
control: 'text',
|
|
121
|
+
description: 'Дополнительные стили для выпадающего меню.',
|
|
122
|
+
table: { category: '🎨 Стили' },
|
|
123
|
+
},
|
|
124
|
+
rules: {
|
|
125
|
+
table: { disable: true },
|
|
126
|
+
description: 'Массив функций валидации.',
|
|
127
|
+
},
|
|
128
|
+
hideBottomSpace: {
|
|
129
|
+
table: { disable: true },
|
|
130
|
+
},
|
|
131
|
+
dataTest: {
|
|
132
|
+
table: { disable: true },
|
|
133
|
+
},
|
|
134
|
+
isSearch: {
|
|
135
|
+
table: { disable: true },
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
args: {
|
|
139
|
+
label: 'Выберите элемент',
|
|
140
|
+
placeholder: 'Начните ввод...',
|
|
141
|
+
emptyText: 'Ничего не найдено',
|
|
142
|
+
options: SAMPLE_OPTIONS,
|
|
143
|
+
multiple: false,
|
|
144
|
+
hideSearch: false,
|
|
145
|
+
allowCreate: false,
|
|
146
|
+
showChip: false,
|
|
147
|
+
simple: false,
|
|
148
|
+
loading: false,
|
|
149
|
+
isDisabled: false,
|
|
150
|
+
isShowRequired: false,
|
|
151
|
+
chipColor: '#e9eff9',
|
|
152
|
+
borderRadius: '8px',
|
|
153
|
+
optionLabel: 'label',
|
|
154
|
+
optionValue: 'value',
|
|
155
|
+
},
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export default meta
|
|
159
|
+
|
|
160
|
+
type Story = StoryObj<typeof ModalSelect>
|
|
161
|
+
|
|
162
|
+
export const Default: Story = {}
|
|
163
|
+
|
|
164
|
+
export const Modes: Story = {
|
|
165
|
+
render: () => ({
|
|
166
|
+
components: { ModalSelect },
|
|
167
|
+
template: `
|
|
168
|
+
<div>
|
|
169
|
+
<ModalSelect
|
|
170
|
+
v-model="simpleValue"
|
|
171
|
+
:options="options"
|
|
172
|
+
label="Обычный"
|
|
173
|
+
:simple="true"
|
|
174
|
+
/>
|
|
175
|
+
<ModalSelect
|
|
176
|
+
v-model="chipValue"
|
|
177
|
+
:options="options"
|
|
178
|
+
label="Обычный chip"
|
|
179
|
+
:show-chip="true"
|
|
180
|
+
/>
|
|
181
|
+
<ModalSelect
|
|
182
|
+
v-model="multiValue"
|
|
183
|
+
:options="options"
|
|
184
|
+
label="Множественный chip"
|
|
185
|
+
:show-chip="true"
|
|
186
|
+
multiple
|
|
187
|
+
/>
|
|
188
|
+
</div>
|
|
189
|
+
`,
|
|
190
|
+
data() {
|
|
191
|
+
return {
|
|
192
|
+
options: SAMPLE_OPTIONS,
|
|
193
|
+
singleValue: 2,
|
|
194
|
+
multiValue: [1, 3],
|
|
195
|
+
chipValue: 4,
|
|
196
|
+
simpleValue: 5,
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
}),
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export const SearchAndCreate: Story = {
|
|
203
|
+
render: () => ({
|
|
204
|
+
components: { ModalSelect },
|
|
205
|
+
template: `
|
|
206
|
+
<div>
|
|
207
|
+
<ModalSelect
|
|
208
|
+
v-model="searchValue"
|
|
209
|
+
:options="options"
|
|
210
|
+
label="С поиском"
|
|
211
|
+
placeholder="Начните ввод..."
|
|
212
|
+
/>
|
|
213
|
+
<ModalSelect
|
|
214
|
+
v-model="createValue"
|
|
215
|
+
:options="localOptions"
|
|
216
|
+
label="Создание новых"
|
|
217
|
+
placeholder="Введите новое значение"
|
|
218
|
+
allow-create
|
|
219
|
+
@create="handleCreate"
|
|
220
|
+
/>
|
|
221
|
+
</div>
|
|
222
|
+
`,
|
|
223
|
+
setup() {
|
|
224
|
+
const options = SAMPLE_OPTIONS
|
|
225
|
+
const localOptions = ref([...options])
|
|
226
|
+
const searchValue = ref(null)
|
|
227
|
+
const createValue = ref(null)
|
|
228
|
+
|
|
229
|
+
const handleCreate = (newOption: any) => {
|
|
230
|
+
localOptions.value.push(newOption)
|
|
231
|
+
createValue.value = newOption.value
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
options,
|
|
236
|
+
localOptions,
|
|
237
|
+
searchValue,
|
|
238
|
+
createValue,
|
|
239
|
+
handleCreate,
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
}),
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export const States: Story = {
|
|
246
|
+
render: () => ({
|
|
247
|
+
components: { ModalSelect },
|
|
248
|
+
template: `
|
|
249
|
+
<div>
|
|
250
|
+
<ModalSelect
|
|
251
|
+
v-model="disabledValue"
|
|
252
|
+
:options="options"
|
|
253
|
+
label="Отключено"
|
|
254
|
+
:is-disabled="true"
|
|
255
|
+
/>
|
|
256
|
+
<ModalSelect
|
|
257
|
+
v-model="loadingValue"
|
|
258
|
+
:options="options"
|
|
259
|
+
label="Загрузка"
|
|
260
|
+
:loading="true"
|
|
261
|
+
/>
|
|
262
|
+
<ModalSelect
|
|
263
|
+
v-model="requiredValue"
|
|
264
|
+
:options="options"
|
|
265
|
+
label="Обязательное"
|
|
266
|
+
:is-show-required="true"
|
|
267
|
+
simple
|
|
268
|
+
:rules="[v => !!v || 'Обязательно']"
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
271
|
+
`,
|
|
272
|
+
data() {
|
|
273
|
+
return {
|
|
274
|
+
options: SAMPLE_OPTIONS,
|
|
275
|
+
normalValue: 1,
|
|
276
|
+
disabledValue: 2,
|
|
277
|
+
loadingValue: 3,
|
|
278
|
+
requiredValue: null,
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
}),
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export const WithSlots: Story = {
|
|
285
|
+
render: () => ({
|
|
286
|
+
components: { ModalSelect },
|
|
287
|
+
template: `
|
|
288
|
+
<ModalSelect
|
|
289
|
+
v-model="slotValue"
|
|
290
|
+
:options="options"
|
|
291
|
+
label="С кастомными опциями"
|
|
292
|
+
simple
|
|
293
|
+
>
|
|
294
|
+
<template #option="{ opt }">
|
|
295
|
+
<q-item>
|
|
296
|
+
<q-item-section avatar>
|
|
297
|
+
<q-icon name="folder" color="primary" />
|
|
298
|
+
</q-item-section>
|
|
299
|
+
<q-item-section>
|
|
300
|
+
<div style="font-weight: 600;">{{ opt.label }}</div>
|
|
301
|
+
<div style="font-size: 12px; color: #777;">ID: {{ opt.value }}</div>
|
|
302
|
+
</q-item-section>
|
|
303
|
+
</q-item>
|
|
304
|
+
</template>
|
|
305
|
+
<template #selected="{ opt }">
|
|
306
|
+
<q-chip
|
|
307
|
+
removable
|
|
308
|
+
text-color="secondary"
|
|
309
|
+
@remove="slotValue = null"
|
|
310
|
+
>
|
|
311
|
+
📁 {{ opt.label }}
|
|
312
|
+
</q-chip>
|
|
313
|
+
</template>
|
|
314
|
+
</ModalSelect>
|
|
315
|
+
`,
|
|
316
|
+
data() {
|
|
317
|
+
return {
|
|
318
|
+
options: SAMPLE_OPTIONS,
|
|
319
|
+
slotValue: 2,
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
}),
|
|
323
|
+
}
|