bfg-common 1.2.201 → 1.2.202
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.
|
@@ -1,443 +1,443 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-if="props.show" class="modal clr-wizard wizard-xl">
|
|
3
|
-
<div class="modal-dialog modal-xl relative">
|
|
4
|
-
<div class="modal-content-wrapper">
|
|
5
|
-
<nav class="modal-nav clr-wizard-stepnav-wrapper">
|
|
6
|
-
<h1 class="clr-wizard-title">
|
|
7
|
-
{{ props.title }}
|
|
8
|
-
</h1>
|
|
9
|
-
<atoms-wizard-step
|
|
10
|
-
:test-id="props.testId"
|
|
11
|
-
:steps="steps"
|
|
12
|
-
:was-completed="props.wasCompleted"
|
|
13
|
-
@change="onSelectStep"
|
|
14
|
-
/>
|
|
15
|
-
</nav>
|
|
16
|
-
<div class="modal-content">
|
|
17
|
-
<div class="modal-header--accessible">
|
|
18
|
-
<slot name="contentHeading">
|
|
19
|
-
<div class="modal-title-wrapper">
|
|
20
|
-
<h2 class="modal-title">
|
|
21
|
-
<span class="modal-title-text">
|
|
22
|
-
{{ selectedStep.title }}
|
|
23
|
-
</span>
|
|
24
|
-
</h2>
|
|
25
|
-
</div>
|
|
26
|
-
</slot>
|
|
27
|
-
<button
|
|
28
|
-
:id="`${props.testId}-close-icon`"
|
|
29
|
-
class="close"
|
|
30
|
-
@click="onHide"
|
|
31
|
-
>
|
|
32
|
-
<atoms-the-icon class="close-icon" name="close" />
|
|
33
|
-
</button>
|
|
34
|
-
</div>
|
|
35
|
-
<div class="modal-body" style="padding: 16px 15px 10px 10px">
|
|
36
|
-
<div v-if="selectedStep.subTitle" class="content-heading">
|
|
37
|
-
<div>
|
|
38
|
-
<h2>{{ selectedStep.subTitle }}</h2>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
<slot name="modalBody" :selected-step="selectedStep" />
|
|
42
|
-
</div>
|
|
43
|
-
<div class="modal-footer">
|
|
44
|
-
<slot name="
|
|
45
|
-
|
|
46
|
-
<button
|
|
47
|
-
:id="`${props.testId}-cancel-button`"
|
|
48
|
-
class="btn btn-link"
|
|
49
|
-
@click="onHide"
|
|
50
|
-
>
|
|
51
|
-
{{ props.localization.cancel }}
|
|
52
|
-
</button>
|
|
53
|
-
<button
|
|
54
|
-
v-if="!isFirstStep"
|
|
55
|
-
:id="`${props.testId}-back-button`"
|
|
56
|
-
class="btn btn-outline"
|
|
57
|
-
@click="onPreviousStep"
|
|
58
|
-
>
|
|
59
|
-
{{ props.localization.back }}
|
|
60
|
-
</button>
|
|
61
|
-
<button
|
|
62
|
-
v-if="isLastStep"
|
|
63
|
-
:id="`${props.testId}-finish-button`"
|
|
64
|
-
class="btn btn-success"
|
|
65
|
-
@click="emits('submit')"
|
|
66
|
-
>
|
|
67
|
-
{{ props.localization.finish }}
|
|
68
|
-
</button>
|
|
69
|
-
<button
|
|
70
|
-
v-else
|
|
71
|
-
:id="`${props.testId}-next-button`"
|
|
72
|
-
:disabled="props.isDisabledFinish"
|
|
73
|
-
class="btn btn-primary"
|
|
74
|
-
@click="onNextStep"
|
|
75
|
-
>
|
|
76
|
-
{{ props.localization.next }}
|
|
77
|
-
</button>
|
|
78
|
-
</slot>
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
|
|
83
|
-
<div v-show="props.isLoading" class="loader">
|
|
84
|
-
<i class="fa clr-tree-node-caret-icon spinner" />
|
|
85
|
-
<div v-if="props.loaderMessages.length" class="text">
|
|
86
|
-
<p v-for="message in props.loaderMessages" :key="message">
|
|
87
|
-
{{ message }}
|
|
88
|
-
</p>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
<div class="modal-backdrop" />
|
|
93
|
-
</div>
|
|
94
|
-
</template>
|
|
95
|
-
|
|
96
|
-
<script setup lang="ts">
|
|
97
|
-
import type { UI_I_Localization } from '~/models/interfaces'
|
|
98
|
-
import type {
|
|
99
|
-
UI_I_WizardStep,
|
|
100
|
-
UI_I_WizardStepNavigation,
|
|
101
|
-
} from '~/components/atoms/wizard/models/interfaces'
|
|
102
|
-
import { UI_E_WIZARD_STATUS } from '~/components/atoms/wizard/models/enums'
|
|
103
|
-
|
|
104
|
-
const props = withDefaults(
|
|
105
|
-
defineProps<{
|
|
106
|
-
title: string
|
|
107
|
-
show: boolean
|
|
108
|
-
steps: UI_I_WizardStep[]
|
|
109
|
-
selectedScheme: number[]
|
|
110
|
-
isLoading?: boolean
|
|
111
|
-
loaderMessages?: string[]
|
|
112
|
-
isDisabledNext?: boolean
|
|
113
|
-
isDisabledFinish?: boolean
|
|
114
|
-
localization?: UI_I_Localization
|
|
115
|
-
testId?: string
|
|
116
|
-
wasCompleted: boolean
|
|
117
|
-
}>(),
|
|
118
|
-
{
|
|
119
|
-
isLoading: false,
|
|
120
|
-
loaderMessages: () => [],
|
|
121
|
-
isDisabledNext: false,
|
|
122
|
-
isDisabledFinish: false,
|
|
123
|
-
localization: () => ({}),
|
|
124
|
-
testId: '',
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
const emits = defineEmits<{
|
|
129
|
-
(event: 'submit'): void
|
|
130
|
-
(event: 'hide'): void
|
|
131
|
-
(event: 'change-steps', value: UI_I_WizardStep[]): void
|
|
132
|
-
}>()
|
|
133
|
-
|
|
134
|
-
const steps = ref<UI_I_WizardStep[]>(
|
|
135
|
-
useDeepCopy(
|
|
136
|
-
props.steps.filter((step: UI_I_WizardStep) =>
|
|
137
|
-
props.selectedScheme.includes(step.id)
|
|
138
|
-
)
|
|
139
|
-
)
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
const onHide = (): void => {
|
|
143
|
-
emits('hide')
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const isSelected = (status: UI_E_WIZARD_STATUS): boolean =>
|
|
147
|
-
status === UI_E_WIZARD_STATUS.SELECTED ||
|
|
148
|
-
status === UI_E_WIZARD_STATUS.INVALID_SELECTED
|
|
149
|
-
|
|
150
|
-
const isLastStep = computed<boolean>(() => {
|
|
151
|
-
const lastStepStatus = steps.value[steps.value.length - 1].status
|
|
152
|
-
return isSelected(lastStepStatus)
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
const isFirstStep = computed<boolean>(() => {
|
|
156
|
-
const firstStepStatus = steps.value[0].status
|
|
157
|
-
return isSelected(firstStepStatus)
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
const selectedStep = computed<UI_I_WizardStep>(
|
|
161
|
-
() =>
|
|
162
|
-
steps.value.find((step: UI_I_WizardStep) => isSelected(step.status)) ||
|
|
163
|
-
steps.value[0]
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
const onSelectStep = (step: UI_I_WizardStepNavigation): void => {
|
|
167
|
-
const index = steps.value.findIndex(
|
|
168
|
-
(st: UI_I_WizardStep) => st.id === step.id
|
|
169
|
-
)
|
|
170
|
-
const indexInactive = steps.value.findIndex(
|
|
171
|
-
(st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
|
|
175
|
-
if (!st.isValid && index === i)
|
|
176
|
-
return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
|
|
177
|
-
|
|
178
|
-
if (index === i) return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
|
|
179
|
-
|
|
180
|
-
if (!st.isValid && index !== i)
|
|
181
|
-
return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
|
|
182
|
-
|
|
183
|
-
// If current step is before first inactive, and it is not to be selected or hasn't inactive index, and it is last step, but it is not to be selected, set it as active
|
|
184
|
-
if (
|
|
185
|
-
(indexInactive - 1 === i && index !== indexInactive - 1) ||
|
|
186
|
-
(indexInactive < 0 && steps.value.length - 1 === i && index !== i)
|
|
187
|
-
)
|
|
188
|
-
return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
|
|
189
|
-
|
|
190
|
-
if (index !== i && st.status !== UI_E_WIZARD_STATUS.INACTIVE)
|
|
191
|
-
return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
|
|
192
|
-
|
|
193
|
-
return st
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
emits('change-steps', newSteps)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const onNextStep = (): void => {
|
|
200
|
-
const currentStepIndex: number = steps.value.findIndex(
|
|
201
|
-
(st: UI_I_WizardStep) => isSelected(st.status)
|
|
202
|
-
)
|
|
203
|
-
const stepIndex: number = currentStepIndex + 1
|
|
204
|
-
const step: UI_I_WizardStep = steps.value[stepIndex]
|
|
205
|
-
|
|
206
|
-
if (!step) return
|
|
207
|
-
|
|
208
|
-
const index = steps.value.findIndex(
|
|
209
|
-
(st: UI_I_WizardStep) => st.id === step.id
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
|
|
213
|
-
if (!st.isValid && index === i)
|
|
214
|
-
return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
|
|
215
|
-
|
|
216
|
-
if (!st.isValid && index !== i)
|
|
217
|
-
return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
|
|
218
|
-
|
|
219
|
-
const indexInactive = steps.value.findIndex(
|
|
220
|
-
(st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
// If current step is not equal selected step, and it is not inactive or active, set it as completed
|
|
224
|
-
if (
|
|
225
|
-
index !== i &&
|
|
226
|
-
st.status !== UI_E_WIZARD_STATUS.INACTIVE &&
|
|
227
|
-
st.status !== UI_E_WIZARD_STATUS.ACTIVE
|
|
228
|
-
)
|
|
229
|
-
return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
|
|
230
|
-
|
|
231
|
-
if (index === i) {
|
|
232
|
-
return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (stepIndex !== indexInactive && indexInactive - 1 === i)
|
|
236
|
-
return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
|
|
237
|
-
|
|
238
|
-
return st
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
emits('change-steps', newSteps)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const onPreviousStep = (): void => {
|
|
245
|
-
const currentStepIndex: number = steps.value.findIndex(
|
|
246
|
-
(st: UI_I_WizardStep) => isSelected(st.status)
|
|
247
|
-
)
|
|
248
|
-
const stepIndex: number = currentStepIndex - 1
|
|
249
|
-
const step: UI_I_WizardStep = steps.value[stepIndex]
|
|
250
|
-
|
|
251
|
-
const indexInactive = steps.value.findIndex(
|
|
252
|
-
(st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
if (!step) return
|
|
256
|
-
const index = steps.value.findIndex(
|
|
257
|
-
(st: UI_I_WizardStep) => st.title === step.title
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
|
|
261
|
-
if (!st.isValid && index === i)
|
|
262
|
-
return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
|
|
263
|
-
|
|
264
|
-
if (index === i) return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
|
|
265
|
-
|
|
266
|
-
if (!st.isValid && index !== i)
|
|
267
|
-
return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
|
|
268
|
-
|
|
269
|
-
// If current step is before first inactive, and it is not to be selected or hasn't inactive index, and it is last step
|
|
270
|
-
if (
|
|
271
|
-
(indexInactive - 1 === i && index !== indexInactive - 1) ||
|
|
272
|
-
(indexInactive < 0 && steps.value.length - 1 === i)
|
|
273
|
-
)
|
|
274
|
-
return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
|
|
275
|
-
|
|
276
|
-
if (index !== i && st.status !== UI_E_WIZARD_STATUS.INACTIVE)
|
|
277
|
-
return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
|
|
278
|
-
|
|
279
|
-
return st
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
emits('change-steps', newSteps)
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
watch(
|
|
286
|
-
() => props.selectedScheme,
|
|
287
|
-
(newValue: number[]) => {
|
|
288
|
-
steps.value = props.steps.filter((step: UI_I_WizardStep) =>
|
|
289
|
-
newValue.includes(step.id)
|
|
290
|
-
)
|
|
291
|
-
},
|
|
292
|
-
{ deep: true, immediate: true }
|
|
293
|
-
)
|
|
294
|
-
watch(
|
|
295
|
-
() => props.steps,
|
|
296
|
-
(newValue: UI_I_WizardStep[]) => {
|
|
297
|
-
steps.value = newValue.filter((step: UI_I_WizardStep) =>
|
|
298
|
-
props.selectedScheme.includes(step.id)
|
|
299
|
-
)
|
|
300
|
-
},
|
|
301
|
-
{ deep: true, immediate: true }
|
|
302
|
-
)
|
|
303
|
-
</script>
|
|
304
|
-
|
|
305
|
-
<style scoped lang="scss">
|
|
306
|
-
.modal {
|
|
307
|
-
position: fixed;
|
|
308
|
-
top: 0;
|
|
309
|
-
bottom: 0;
|
|
310
|
-
right: 0;
|
|
311
|
-
left: 0;
|
|
312
|
-
z-index: 1050;
|
|
313
|
-
display: flex;
|
|
314
|
-
flex-direction: column;
|
|
315
|
-
justify-content: center;
|
|
316
|
-
align-items: center;
|
|
317
|
-
padding: 48px;
|
|
318
|
-
overflow-y: auto;
|
|
319
|
-
|
|
320
|
-
.modal-nav {
|
|
321
|
-
background-color: var(--block-view-bg-color4);
|
|
322
|
-
.clr-wizard-title {
|
|
323
|
-
color: var(--main-color-mode);
|
|
324
|
-
font-size: 22px;
|
|
325
|
-
padding: 24px 12px 24px 24px;
|
|
326
|
-
//line-height: 1.2rem;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
.modal-content-wrapper {
|
|
331
|
-
position: relative;
|
|
332
|
-
-webkit-animation-name: animateTop;
|
|
333
|
-
-webkit-animation-duration: 0.4s;
|
|
334
|
-
animation-name: animateTop;
|
|
335
|
-
animation-duration: 0.4s;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
.modal-content {
|
|
339
|
-
background-color: var(--modal-bg-color);
|
|
340
|
-
|
|
341
|
-
.modal-header--accessible {
|
|
342
|
-
display: flex;
|
|
343
|
-
justify-content: space-between;
|
|
344
|
-
align-items: flex-start;
|
|
345
|
-
width: 100%;
|
|
346
|
-
padding: 24px 19px 6px 24px;
|
|
347
|
-
|
|
348
|
-
.modal-title-text {
|
|
349
|
-
color: var(--main-color-mode);
|
|
350
|
-
font-size: 22px;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
.close-icon {
|
|
354
|
-
fill: var(--close-icon);
|
|
355
|
-
width: 24px;
|
|
356
|
-
height: 24px;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
.modal-body {
|
|
361
|
-
padding: 0 3px;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
.modal-footer {
|
|
365
|
-
display: flex;
|
|
366
|
-
justify-content: flex-end;
|
|
367
|
-
padding: 24px;
|
|
368
|
-
flex: unset;
|
|
369
|
-
min-height: 0;
|
|
370
|
-
height: auto;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
.loader {
|
|
375
|
-
position: absolute;
|
|
376
|
-
z-index: 1000;
|
|
377
|
-
left: 0;
|
|
378
|
-
right: 0;
|
|
379
|
-
bottom: 0;
|
|
380
|
-
top: 0;
|
|
381
|
-
display: flex;
|
|
382
|
-
align-items: center;
|
|
383
|
-
justify-content: center;
|
|
384
|
-
background-color: rgba(0, 0, 0, 0.3);
|
|
385
|
-
|
|
386
|
-
.spinner {
|
|
387
|
-
left: unset;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
.text {
|
|
391
|
-
position: absolute;
|
|
392
|
-
top: calc(40% + 75px);
|
|
393
|
-
text-align: center;
|
|
394
|
-
background-color: rgba(0, 0, 0, 0.3);
|
|
395
|
-
padding: 5px 10px;
|
|
396
|
-
border-radius: 3px;
|
|
397
|
-
|
|
398
|
-
p {
|
|
399
|
-
color: white;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
.modal-backdrop {
|
|
405
|
-
opacity: 1;
|
|
406
|
-
background-color: rgba(0, 0, 0, 0.6);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
h1,
|
|
410
|
-
h2 {
|
|
411
|
-
// просмотреть если нигде не ломается переместит глобально
|
|
412
|
-
line-height: inherit;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
.content-heading {
|
|
416
|
-
display: flex;
|
|
417
|
-
justify-content: space-between;
|
|
418
|
-
align-items: flex-start;
|
|
419
|
-
border-bottom: 1px solid #a6a6a6;
|
|
420
|
-
|
|
421
|
-
& > div h2 {
|
|
422
|
-
font-weight: 400;
|
|
423
|
-
font-size: 13px;
|
|
424
|
-
line-height: inherit;
|
|
425
|
-
color: var(--add-vm-context-sub-title);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
:root.dark-theme {
|
|
430
|
-
.loader .text {
|
|
431
|
-
position: absolute;
|
|
432
|
-
top: calc(40% + 75px);
|
|
433
|
-
text-align: center;
|
|
434
|
-
background-color: rgba(250, 250, 250, 0.5);
|
|
435
|
-
padding: 5px 10px;
|
|
436
|
-
border-radius: 5px;
|
|
437
|
-
|
|
438
|
-
p {
|
|
439
|
-
color: black;
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="props.show" class="modal clr-wizard wizard-xl">
|
|
3
|
+
<div class="modal-dialog modal-xl relative">
|
|
4
|
+
<div class="modal-content-wrapper">
|
|
5
|
+
<nav class="modal-nav clr-wizard-stepnav-wrapper">
|
|
6
|
+
<h1 class="clr-wizard-title">
|
|
7
|
+
{{ props.title }}
|
|
8
|
+
</h1>
|
|
9
|
+
<atoms-wizard-step
|
|
10
|
+
:test-id="props.testId"
|
|
11
|
+
:steps="steps"
|
|
12
|
+
:was-completed="props.wasCompleted"
|
|
13
|
+
@change="onSelectStep"
|
|
14
|
+
/>
|
|
15
|
+
</nav>
|
|
16
|
+
<div class="modal-content">
|
|
17
|
+
<div class="modal-header--accessible">
|
|
18
|
+
<slot name="contentHeading">
|
|
19
|
+
<div class="modal-title-wrapper">
|
|
20
|
+
<h2 class="modal-title">
|
|
21
|
+
<span class="modal-title-text">
|
|
22
|
+
{{ selectedStep.title }}
|
|
23
|
+
</span>
|
|
24
|
+
</h2>
|
|
25
|
+
</div>
|
|
26
|
+
</slot>
|
|
27
|
+
<button
|
|
28
|
+
:id="`${props.testId}-close-icon`"
|
|
29
|
+
class="close"
|
|
30
|
+
@click="onHide"
|
|
31
|
+
>
|
|
32
|
+
<atoms-the-icon class="close-icon" name="close" />
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="modal-body" style="padding: 16px 15px 10px 10px">
|
|
36
|
+
<div v-if="selectedStep.subTitle" class="content-heading">
|
|
37
|
+
<div>
|
|
38
|
+
<h2>{{ selectedStep.subTitle }}</h2>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<slot name="modalBody" :selected-step="selectedStep" />
|
|
42
|
+
</div>
|
|
43
|
+
<div class="modal-footer">
|
|
44
|
+
<slot name="modalFooterContent"></slot>
|
|
45
|
+
<slot name="modalFooter">
|
|
46
|
+
<button
|
|
47
|
+
:id="`${props.testId}-cancel-button`"
|
|
48
|
+
class="btn btn-link"
|
|
49
|
+
@click="onHide"
|
|
50
|
+
>
|
|
51
|
+
{{ props.localization.cancel }}
|
|
52
|
+
</button>
|
|
53
|
+
<button
|
|
54
|
+
v-if="!isFirstStep"
|
|
55
|
+
:id="`${props.testId}-back-button`"
|
|
56
|
+
class="btn btn-outline"
|
|
57
|
+
@click="onPreviousStep"
|
|
58
|
+
>
|
|
59
|
+
{{ props.localization.back }}
|
|
60
|
+
</button>
|
|
61
|
+
<button
|
|
62
|
+
v-if="isLastStep"
|
|
63
|
+
:id="`${props.testId}-finish-button`"
|
|
64
|
+
class="btn btn-success"
|
|
65
|
+
@click="emits('submit')"
|
|
66
|
+
>
|
|
67
|
+
{{ props.localization.finish }}
|
|
68
|
+
</button>
|
|
69
|
+
<button
|
|
70
|
+
v-else
|
|
71
|
+
:id="`${props.testId}-next-button`"
|
|
72
|
+
:disabled="props.isDisabledFinish"
|
|
73
|
+
class="btn btn-primary"
|
|
74
|
+
@click="onNextStep"
|
|
75
|
+
>
|
|
76
|
+
{{ props.localization.next }}
|
|
77
|
+
</button>
|
|
78
|
+
</slot>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div v-show="props.isLoading" class="loader">
|
|
84
|
+
<i class="fa clr-tree-node-caret-icon spinner" />
|
|
85
|
+
<div v-if="props.loaderMessages.length" class="text">
|
|
86
|
+
<p v-for="message in props.loaderMessages" :key="message">
|
|
87
|
+
{{ message }}
|
|
88
|
+
</p>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="modal-backdrop" />
|
|
93
|
+
</div>
|
|
94
|
+
</template>
|
|
95
|
+
|
|
96
|
+
<script setup lang="ts">
|
|
97
|
+
import type { UI_I_Localization } from '~/models/interfaces'
|
|
98
|
+
import type {
|
|
99
|
+
UI_I_WizardStep,
|
|
100
|
+
UI_I_WizardStepNavigation,
|
|
101
|
+
} from '~/components/atoms/wizard/models/interfaces'
|
|
102
|
+
import { UI_E_WIZARD_STATUS } from '~/components/atoms/wizard/models/enums'
|
|
103
|
+
|
|
104
|
+
const props = withDefaults(
|
|
105
|
+
defineProps<{
|
|
106
|
+
title: string
|
|
107
|
+
show: boolean
|
|
108
|
+
steps: UI_I_WizardStep[]
|
|
109
|
+
selectedScheme: number[]
|
|
110
|
+
isLoading?: boolean
|
|
111
|
+
loaderMessages?: string[]
|
|
112
|
+
isDisabledNext?: boolean
|
|
113
|
+
isDisabledFinish?: boolean
|
|
114
|
+
localization?: UI_I_Localization
|
|
115
|
+
testId?: string
|
|
116
|
+
wasCompleted: boolean
|
|
117
|
+
}>(),
|
|
118
|
+
{
|
|
119
|
+
isLoading: false,
|
|
120
|
+
loaderMessages: () => [],
|
|
121
|
+
isDisabledNext: false,
|
|
122
|
+
isDisabledFinish: false,
|
|
123
|
+
localization: () => ({}),
|
|
124
|
+
testId: '',
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
const emits = defineEmits<{
|
|
129
|
+
(event: 'submit'): void
|
|
130
|
+
(event: 'hide'): void
|
|
131
|
+
(event: 'change-steps', value: UI_I_WizardStep[]): void
|
|
132
|
+
}>()
|
|
133
|
+
|
|
134
|
+
const steps = ref<UI_I_WizardStep[]>(
|
|
135
|
+
useDeepCopy(
|
|
136
|
+
props.steps.filter((step: UI_I_WizardStep) =>
|
|
137
|
+
props.selectedScheme.includes(step.id)
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
const onHide = (): void => {
|
|
143
|
+
emits('hide')
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const isSelected = (status: UI_E_WIZARD_STATUS): boolean =>
|
|
147
|
+
status === UI_E_WIZARD_STATUS.SELECTED ||
|
|
148
|
+
status === UI_E_WIZARD_STATUS.INVALID_SELECTED
|
|
149
|
+
|
|
150
|
+
const isLastStep = computed<boolean>(() => {
|
|
151
|
+
const lastStepStatus = steps.value[steps.value.length - 1].status
|
|
152
|
+
return isSelected(lastStepStatus)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
const isFirstStep = computed<boolean>(() => {
|
|
156
|
+
const firstStepStatus = steps.value[0].status
|
|
157
|
+
return isSelected(firstStepStatus)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
const selectedStep = computed<UI_I_WizardStep>(
|
|
161
|
+
() =>
|
|
162
|
+
steps.value.find((step: UI_I_WizardStep) => isSelected(step.status)) ||
|
|
163
|
+
steps.value[0]
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
const onSelectStep = (step: UI_I_WizardStepNavigation): void => {
|
|
167
|
+
const index = steps.value.findIndex(
|
|
168
|
+
(st: UI_I_WizardStep) => st.id === step.id
|
|
169
|
+
)
|
|
170
|
+
const indexInactive = steps.value.findIndex(
|
|
171
|
+
(st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
|
|
175
|
+
if (!st.isValid && index === i)
|
|
176
|
+
return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
|
|
177
|
+
|
|
178
|
+
if (index === i) return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
|
|
179
|
+
|
|
180
|
+
if (!st.isValid && index !== i)
|
|
181
|
+
return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
|
|
182
|
+
|
|
183
|
+
// If current step is before first inactive, and it is not to be selected or hasn't inactive index, and it is last step, but it is not to be selected, set it as active
|
|
184
|
+
if (
|
|
185
|
+
(indexInactive - 1 === i && index !== indexInactive - 1) ||
|
|
186
|
+
(indexInactive < 0 && steps.value.length - 1 === i && index !== i)
|
|
187
|
+
)
|
|
188
|
+
return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
|
|
189
|
+
|
|
190
|
+
if (index !== i && st.status !== UI_E_WIZARD_STATUS.INACTIVE)
|
|
191
|
+
return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
|
|
192
|
+
|
|
193
|
+
return st
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
emits('change-steps', newSteps)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const onNextStep = (): void => {
|
|
200
|
+
const currentStepIndex: number = steps.value.findIndex(
|
|
201
|
+
(st: UI_I_WizardStep) => isSelected(st.status)
|
|
202
|
+
)
|
|
203
|
+
const stepIndex: number = currentStepIndex + 1
|
|
204
|
+
const step: UI_I_WizardStep = steps.value[stepIndex]
|
|
205
|
+
|
|
206
|
+
if (!step) return
|
|
207
|
+
|
|
208
|
+
const index = steps.value.findIndex(
|
|
209
|
+
(st: UI_I_WizardStep) => st.id === step.id
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
|
|
213
|
+
if (!st.isValid && index === i)
|
|
214
|
+
return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
|
|
215
|
+
|
|
216
|
+
if (!st.isValid && index !== i)
|
|
217
|
+
return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
|
|
218
|
+
|
|
219
|
+
const indexInactive = steps.value.findIndex(
|
|
220
|
+
(st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
// If current step is not equal selected step, and it is not inactive or active, set it as completed
|
|
224
|
+
if (
|
|
225
|
+
index !== i &&
|
|
226
|
+
st.status !== UI_E_WIZARD_STATUS.INACTIVE &&
|
|
227
|
+
st.status !== UI_E_WIZARD_STATUS.ACTIVE
|
|
228
|
+
)
|
|
229
|
+
return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
|
|
230
|
+
|
|
231
|
+
if (index === i) {
|
|
232
|
+
return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (stepIndex !== indexInactive && indexInactive - 1 === i)
|
|
236
|
+
return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
|
|
237
|
+
|
|
238
|
+
return st
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
emits('change-steps', newSteps)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const onPreviousStep = (): void => {
|
|
245
|
+
const currentStepIndex: number = steps.value.findIndex(
|
|
246
|
+
(st: UI_I_WizardStep) => isSelected(st.status)
|
|
247
|
+
)
|
|
248
|
+
const stepIndex: number = currentStepIndex - 1
|
|
249
|
+
const step: UI_I_WizardStep = steps.value[stepIndex]
|
|
250
|
+
|
|
251
|
+
const indexInactive = steps.value.findIndex(
|
|
252
|
+
(st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
if (!step) return
|
|
256
|
+
const index = steps.value.findIndex(
|
|
257
|
+
(st: UI_I_WizardStep) => st.title === step.title
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
|
|
261
|
+
if (!st.isValid && index === i)
|
|
262
|
+
return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
|
|
263
|
+
|
|
264
|
+
if (index === i) return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
|
|
265
|
+
|
|
266
|
+
if (!st.isValid && index !== i)
|
|
267
|
+
return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
|
|
268
|
+
|
|
269
|
+
// If current step is before first inactive, and it is not to be selected or hasn't inactive index, and it is last step
|
|
270
|
+
if (
|
|
271
|
+
(indexInactive - 1 === i && index !== indexInactive - 1) ||
|
|
272
|
+
(indexInactive < 0 && steps.value.length - 1 === i)
|
|
273
|
+
)
|
|
274
|
+
return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
|
|
275
|
+
|
|
276
|
+
if (index !== i && st.status !== UI_E_WIZARD_STATUS.INACTIVE)
|
|
277
|
+
return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
|
|
278
|
+
|
|
279
|
+
return st
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
emits('change-steps', newSteps)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
watch(
|
|
286
|
+
() => props.selectedScheme,
|
|
287
|
+
(newValue: number[]) => {
|
|
288
|
+
steps.value = props.steps.filter((step: UI_I_WizardStep) =>
|
|
289
|
+
newValue.includes(step.id)
|
|
290
|
+
)
|
|
291
|
+
},
|
|
292
|
+
{ deep: true, immediate: true }
|
|
293
|
+
)
|
|
294
|
+
watch(
|
|
295
|
+
() => props.steps,
|
|
296
|
+
(newValue: UI_I_WizardStep[]) => {
|
|
297
|
+
steps.value = newValue.filter((step: UI_I_WizardStep) =>
|
|
298
|
+
props.selectedScheme.includes(step.id)
|
|
299
|
+
)
|
|
300
|
+
},
|
|
301
|
+
{ deep: true, immediate: true }
|
|
302
|
+
)
|
|
303
|
+
</script>
|
|
304
|
+
|
|
305
|
+
<style scoped lang="scss">
|
|
306
|
+
.modal {
|
|
307
|
+
position: fixed;
|
|
308
|
+
top: 0;
|
|
309
|
+
bottom: 0;
|
|
310
|
+
right: 0;
|
|
311
|
+
left: 0;
|
|
312
|
+
z-index: 1050;
|
|
313
|
+
display: flex;
|
|
314
|
+
flex-direction: column;
|
|
315
|
+
justify-content: center;
|
|
316
|
+
align-items: center;
|
|
317
|
+
padding: 48px;
|
|
318
|
+
overflow-y: auto;
|
|
319
|
+
|
|
320
|
+
.modal-nav {
|
|
321
|
+
background-color: var(--block-view-bg-color4);
|
|
322
|
+
.clr-wizard-title {
|
|
323
|
+
color: var(--main-color-mode);
|
|
324
|
+
font-size: 22px;
|
|
325
|
+
padding: 24px 12px 24px 24px;
|
|
326
|
+
//line-height: 1.2rem;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.modal-content-wrapper {
|
|
331
|
+
position: relative;
|
|
332
|
+
-webkit-animation-name: animateTop;
|
|
333
|
+
-webkit-animation-duration: 0.4s;
|
|
334
|
+
animation-name: animateTop;
|
|
335
|
+
animation-duration: 0.4s;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.modal-content {
|
|
339
|
+
background-color: var(--modal-bg-color);
|
|
340
|
+
|
|
341
|
+
.modal-header--accessible {
|
|
342
|
+
display: flex;
|
|
343
|
+
justify-content: space-between;
|
|
344
|
+
align-items: flex-start;
|
|
345
|
+
width: 100%;
|
|
346
|
+
padding: 24px 19px 6px 24px;
|
|
347
|
+
|
|
348
|
+
.modal-title-text {
|
|
349
|
+
color: var(--main-color-mode);
|
|
350
|
+
font-size: 22px;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.close-icon {
|
|
354
|
+
fill: var(--close-icon);
|
|
355
|
+
width: 24px;
|
|
356
|
+
height: 24px;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.modal-body {
|
|
361
|
+
padding: 0 3px;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.modal-footer {
|
|
365
|
+
display: flex;
|
|
366
|
+
justify-content: flex-end;
|
|
367
|
+
padding: 24px;
|
|
368
|
+
flex: unset;
|
|
369
|
+
min-height: 0;
|
|
370
|
+
height: auto;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.loader {
|
|
375
|
+
position: absolute;
|
|
376
|
+
z-index: 1000;
|
|
377
|
+
left: 0;
|
|
378
|
+
right: 0;
|
|
379
|
+
bottom: 0;
|
|
380
|
+
top: 0;
|
|
381
|
+
display: flex;
|
|
382
|
+
align-items: center;
|
|
383
|
+
justify-content: center;
|
|
384
|
+
background-color: rgba(0, 0, 0, 0.3);
|
|
385
|
+
|
|
386
|
+
.spinner {
|
|
387
|
+
left: unset;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.text {
|
|
391
|
+
position: absolute;
|
|
392
|
+
top: calc(40% + 75px);
|
|
393
|
+
text-align: center;
|
|
394
|
+
background-color: rgba(0, 0, 0, 0.3);
|
|
395
|
+
padding: 5px 10px;
|
|
396
|
+
border-radius: 3px;
|
|
397
|
+
|
|
398
|
+
p {
|
|
399
|
+
color: white;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.modal-backdrop {
|
|
405
|
+
opacity: 1;
|
|
406
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
h1,
|
|
410
|
+
h2 {
|
|
411
|
+
// просмотреть если нигде не ломается переместит глобально
|
|
412
|
+
line-height: inherit;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.content-heading {
|
|
416
|
+
display: flex;
|
|
417
|
+
justify-content: space-between;
|
|
418
|
+
align-items: flex-start;
|
|
419
|
+
border-bottom: 1px solid #a6a6a6;
|
|
420
|
+
|
|
421
|
+
& > div h2 {
|
|
422
|
+
font-weight: 400;
|
|
423
|
+
font-size: 13px;
|
|
424
|
+
line-height: inherit;
|
|
425
|
+
color: var(--add-vm-context-sub-title);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
:root.dark-theme {
|
|
430
|
+
.loader .text {
|
|
431
|
+
position: absolute;
|
|
432
|
+
top: calc(40% + 75px);
|
|
433
|
+
text-align: center;
|
|
434
|
+
background-color: rgba(250, 250, 250, 0.5);
|
|
435
|
+
padding: 5px 10px;
|
|
436
|
+
border-radius: 5px;
|
|
437
|
+
|
|
438
|
+
p {
|
|
439
|
+
color: black;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
</style>
|
|
@@ -117,21 +117,19 @@
|
|
|
117
117
|
compatibilityInfo
|
|
118
118
|
}}</span>
|
|
119
119
|
</div>
|
|
120
|
+
</template>
|
|
120
121
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
</template>
|
|
133
|
-
</div>
|
|
134
|
-
</template>
|
|
122
|
+
<template #modalFooterContent>
|
|
123
|
+
<div v-if="isShowPowerOn" class="power-on-by-default-wrap">
|
|
124
|
+
<input
|
|
125
|
+
id="power-on-by-default"
|
|
126
|
+
v-model="isPowerOnByDefault"
|
|
127
|
+
type="checkbox"
|
|
128
|
+
/>
|
|
129
|
+
<label for="power-on-by-default" class="label-text-normal">{{
|
|
130
|
+
localization.powerOnByDefault
|
|
131
|
+
}}</label>
|
|
132
|
+
</div>
|
|
135
133
|
</template>
|
|
136
134
|
</atoms-wizard>
|
|
137
135
|
</div>
|
|
@@ -238,6 +236,8 @@ const wasCompleted = computed<boolean>(() => wizard.wasCompleted())
|
|
|
238
236
|
const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
|
|
239
237
|
const alertMessages = computed<string[][]>(() => wizard.alertMessages.value)
|
|
240
238
|
|
|
239
|
+
const isShowPowerOn = computed<boolean>(() => wizard.selectedStepId > 8)
|
|
240
|
+
|
|
241
241
|
const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
|
|
242
242
|
wizard.changeSteps(value, validationFunc, validateSendData)
|
|
243
243
|
}
|
|
@@ -560,6 +560,7 @@ const onHideModal = (): void => {
|
|
|
560
560
|
.power-on-by-default-wrap {
|
|
561
561
|
display: flex;
|
|
562
562
|
align-items: center;
|
|
563
|
+
margin-right: auto;
|
|
563
564
|
|
|
564
565
|
input {
|
|
565
566
|
margin-right: 6px;
|