bfg-common 1.2.157 → 1.2.159

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.
@@ -113,7 +113,8 @@ form {
113
113
  }
114
114
  }
115
115
 
116
- /* _____SELECT DARK AND LIGHT MODE STYLES_____ */
116
+ /* _____SELECT DARK AND LIGHT MODE STY
117
+ LES_____ */
117
118
  //.clr-select-wrapper {
118
119
  select {
119
120
  background-color: transparent;
@@ -148,6 +149,22 @@ input[type='number'] {
148
149
  -moz-appearance: textfield;
149
150
  }
150
151
 
152
+ //html.dark-theme
153
+ html.light-theme {
154
+ .stack-block-expanded {
155
+ .input-text-color,
156
+ .input-text-color input {
157
+ color: var(--row-selected-text-color);
158
+ }
159
+ }
160
+ }
161
+
162
+ //.stack-block-expandable {
163
+ // .input-text-color {
164
+ // input {}
165
+ // }
166
+ //}
167
+
151
168
  .btn-trigger {
152
169
  width: 100%;
153
170
  @include flex($align: center);
@@ -0,0 +1,442 @@
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="modalFooter">
45
+ <button
46
+ :id="`${props.testId}-cancel-button`"
47
+ class="btn btn-link"
48
+ @click="onHide"
49
+ >
50
+ {{ props.localization.cancel }}
51
+ </button>
52
+ <button
53
+ v-if="!isFirstStep"
54
+ :id="`${props.testId}-back-button`"
55
+ class="btn btn-outline"
56
+ @click="onPreviousStep"
57
+ >
58
+ {{ props.localization.back }}
59
+ </button>
60
+ <button
61
+ v-if="isLastStep"
62
+ :id="`${props.testId}-finish-button`"
63
+ class="btn btn-success"
64
+ @click="emits('submit')"
65
+ >
66
+ {{ props.localization.finish }}
67
+ </button>
68
+ <button
69
+ v-else
70
+ :id="`${props.testId}-next-button`"
71
+ :disabled="props.isDisabledFinish"
72
+ class="btn btn-primary"
73
+ @click="onNextStep"
74
+ >
75
+ {{ props.localization.next }}
76
+ </button>
77
+ </slot>
78
+ </div>
79
+ </div>
80
+ </div>
81
+
82
+ <div v-show="props.isLoading" class="loader">
83
+ <i class="fa clr-tree-node-caret-icon spinner" />
84
+ <div v-if="props.loaderMessages.length" class="text">
85
+ <p v-for="message in props.loaderMessages" :key="message">
86
+ {{ message }}
87
+ </p>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ <div class="modal-backdrop" />
92
+ </div>
93
+ </template>
94
+
95
+ <script setup lang="ts">
96
+ import type { UI_I_Localization } from '~/models/interfaces'
97
+ import type {
98
+ UI_I_WizardStep,
99
+ UI_I_WizardStepNavigation,
100
+ } from '~/components/atoms/wizard/models/interfaces'
101
+ import { UI_E_WIZARD_STATUS } from '~/components/atoms/wizard/models/enums'
102
+
103
+ const props = withDefaults(
104
+ defineProps<{
105
+ title: string
106
+ show: boolean
107
+ steps: UI_I_WizardStep[]
108
+ selectedScheme: number[]
109
+ isLoading?: boolean
110
+ loaderMessages?: string[]
111
+ isDisabledNext?: boolean
112
+ isDisabledFinish?: boolean
113
+ localization?: UI_I_Localization
114
+ testId?: string
115
+ wasCompleted: boolean
116
+ }>(),
117
+ {
118
+ isLoading: false,
119
+ loaderMessages: () => [],
120
+ isDisabledNext: false,
121
+ isDisabledFinish: false,
122
+ localization: () => ({}),
123
+ testId: '',
124
+ }
125
+ )
126
+
127
+ const emits = defineEmits<{
128
+ (event: 'submit'): void
129
+ (event: 'hide'): void
130
+ (event: 'change-steps', value: UI_I_WizardStep[]): void
131
+ }>()
132
+
133
+ const steps = ref<UI_I_WizardStep[]>(
134
+ useDeepCopy(
135
+ props.steps.filter((step: UI_I_WizardStep) =>
136
+ props.selectedScheme.includes(step.id)
137
+ )
138
+ )
139
+ )
140
+
141
+ const onHide = (): void => {
142
+ emits('hide')
143
+ }
144
+
145
+ const isSelected = (status: UI_E_WIZARD_STATUS): boolean =>
146
+ status === UI_E_WIZARD_STATUS.SELECTED ||
147
+ status === UI_E_WIZARD_STATUS.INVALID_SELECTED
148
+
149
+ const isLastStep = computed<boolean>(() => {
150
+ const lastStepStatus = steps.value[steps.value.length - 1].status
151
+ return isSelected(lastStepStatus)
152
+ })
153
+
154
+ const isFirstStep = computed<boolean>(() => {
155
+ const firstStepStatus = steps.value[0].status
156
+ return isSelected(firstStepStatus)
157
+ })
158
+
159
+ const selectedStep = computed<UI_I_WizardStep>(
160
+ () =>
161
+ steps.value.find((step: UI_I_WizardStep) => isSelected(step.status)) ||
162
+ steps.value[0]
163
+ )
164
+
165
+ const onSelectStep = (step: UI_I_WizardStepNavigation): void => {
166
+ const index = steps.value.findIndex(
167
+ (st: UI_I_WizardStep) => st.id === step.id
168
+ )
169
+ const indexInactive = steps.value.findIndex(
170
+ (st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
171
+ )
172
+
173
+ const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
174
+ if (!st.isValid && index === i)
175
+ return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
176
+
177
+ if (index === i) return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
178
+
179
+ if (!st.isValid && index !== i)
180
+ return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
181
+
182
+ // 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
183
+ if (
184
+ (indexInactive - 1 === i && index !== indexInactive - 1) ||
185
+ (indexInactive < 0 && steps.value.length - 1 === i && index !== i)
186
+ )
187
+ return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
188
+
189
+ if (index !== i && st.status !== UI_E_WIZARD_STATUS.INACTIVE)
190
+ return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
191
+
192
+ return st
193
+ })
194
+
195
+ emits('change-steps', newSteps)
196
+ }
197
+
198
+ const onNextStep = (): void => {
199
+ const currentStepIndex: number = steps.value.findIndex(
200
+ (st: UI_I_WizardStep) => isSelected(st.status)
201
+ )
202
+ const stepIndex: number = currentStepIndex + 1
203
+ const step: UI_I_WizardStep = steps.value[stepIndex]
204
+
205
+ if (!step) return
206
+
207
+ const index = steps.value.findIndex(
208
+ (st: UI_I_WizardStep) => st.id === step.id
209
+ )
210
+
211
+ const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
212
+ if (!st.isValid && index === i)
213
+ return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
214
+
215
+ if (!st.isValid && index !== i)
216
+ return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
217
+
218
+ const indexInactive = steps.value.findIndex(
219
+ (st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
220
+ )
221
+
222
+ // If current step is not equal selected step, and it is not inactive or active, set it as completed
223
+ if (
224
+ index !== i &&
225
+ st.status !== UI_E_WIZARD_STATUS.INACTIVE &&
226
+ st.status !== UI_E_WIZARD_STATUS.ACTIVE
227
+ )
228
+ return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
229
+
230
+ if (index === i) {
231
+ return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
232
+ }
233
+
234
+ if (stepIndex !== indexInactive && indexInactive - 1 === i)
235
+ return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
236
+
237
+ return st
238
+ })
239
+
240
+ emits('change-steps', newSteps)
241
+ }
242
+
243
+ const onPreviousStep = (): void => {
244
+ const currentStepIndex: number = steps.value.findIndex(
245
+ (st: UI_I_WizardStep) => isSelected(st.status)
246
+ )
247
+ const stepIndex: number = currentStepIndex - 1
248
+ const step: UI_I_WizardStep = steps.value[stepIndex]
249
+
250
+ const indexInactive = steps.value.findIndex(
251
+ (st: UI_I_WizardStep) => st.status === UI_E_WIZARD_STATUS.INACTIVE
252
+ )
253
+
254
+ if (!step) return
255
+ const index = steps.value.findIndex(
256
+ (st: UI_I_WizardStep) => st.title === step.title
257
+ )
258
+
259
+ const newSteps = steps.value.map((st: UI_I_WizardStep, i: number) => {
260
+ if (!st.isValid && index === i)
261
+ return { ...st, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
262
+
263
+ if (index === i) return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
264
+
265
+ if (!st.isValid && index !== i)
266
+ return { ...st, status: UI_E_WIZARD_STATUS.INVALID }
267
+
268
+ // If current step is before first inactive, and it is not to be selected or hasn't inactive index, and it is last step
269
+ if (
270
+ (indexInactive - 1 === i && index !== indexInactive - 1) ||
271
+ (indexInactive < 0 && steps.value.length - 1 === i)
272
+ )
273
+ return { ...st, status: UI_E_WIZARD_STATUS.ACTIVE }
274
+
275
+ if (index !== i && st.status !== UI_E_WIZARD_STATUS.INACTIVE)
276
+ return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
277
+
278
+ return st
279
+ })
280
+
281
+ emits('change-steps', newSteps)
282
+ }
283
+
284
+ watch(
285
+ () => props.selectedScheme,
286
+ (newValue: number[]) => {
287
+ steps.value = props.steps.filter((_step: UI_I_WizardStep, index: number) =>
288
+ newValue.includes(index)
289
+ )
290
+ },
291
+ { deep: true, immediate: true }
292
+ )
293
+ watch(
294
+ () => props.steps,
295
+ (newValue: UI_I_WizardStep[]) => {
296
+ steps.value = newValue.filter((_step: UI_I_WizardStep, index: number) =>
297
+ props.selectedScheme.includes(index)
298
+ )
299
+ },
300
+ { deep: true, immediate: true }
301
+ )
302
+ </script>
303
+
304
+ <style scoped lang="scss">
305
+ .modal {
306
+ position: fixed;
307
+ top: 0;
308
+ bottom: 0;
309
+ right: 0;
310
+ left: 0;
311
+ z-index: 1050;
312
+ display: flex;
313
+ flex-direction: column;
314
+ justify-content: center;
315
+ align-items: center;
316
+ padding: 48px;
317
+ overflow-y: auto;
318
+
319
+ .modal-nav {
320
+ background-color: var(--block-view-bg-color4);
321
+ .clr-wizard-title {
322
+ color: var(--main-color-mode);
323
+ font-size: 22px;
324
+ padding: 24px 12px 24px 24px;
325
+ //line-height: 1.2rem;
326
+ }
327
+ }
328
+
329
+ .modal-content-wrapper {
330
+ position: relative;
331
+ -webkit-animation-name: animateTop;
332
+ -webkit-animation-duration: 0.4s;
333
+ animation-name: animateTop;
334
+ animation-duration: 0.4s;
335
+ }
336
+
337
+ .modal-content {
338
+ background-color: var(--modal-bg-color);
339
+
340
+ .modal-header--accessible {
341
+ display: flex;
342
+ justify-content: space-between;
343
+ align-items: flex-start;
344
+ width: 100%;
345
+ padding: 24px 19px 6px 24px;
346
+
347
+ .modal-title-text {
348
+ color: var(--main-color-mode);
349
+ font-size: 22px;
350
+ }
351
+
352
+ .close-icon {
353
+ fill: var(--close-icon);
354
+ width: 24px;
355
+ height: 24px;
356
+ }
357
+ }
358
+
359
+ .modal-body {
360
+ padding: 0 3px;
361
+ }
362
+
363
+ .modal-footer {
364
+ display: flex;
365
+ justify-content: flex-end;
366
+ padding: 24px;
367
+ flex: unset;
368
+ min-height: 0;
369
+ height: auto;
370
+ }
371
+ }
372
+
373
+ .loader {
374
+ position: absolute;
375
+ z-index: 1000;
376
+ left: 0;
377
+ right: 0;
378
+ bottom: 0;
379
+ top: 0;
380
+ display: flex;
381
+ align-items: center;
382
+ justify-content: center;
383
+ background-color: rgba(0, 0, 0, 0.3);
384
+
385
+ .spinner {
386
+ left: unset;
387
+ }
388
+
389
+ .text {
390
+ position: absolute;
391
+ top: calc(40% + 75px);
392
+ text-align: center;
393
+ background-color: rgba(0, 0, 0, 0.3);
394
+ padding: 5px 10px;
395
+ border-radius: 3px;
396
+
397
+ p {
398
+ color: white;
399
+ }
400
+ }
401
+ }
402
+
403
+ .modal-backdrop {
404
+ opacity: 1;
405
+ background-color: rgba(0, 0, 0, 0.6);
406
+ }
407
+ }
408
+ h1,
409
+ h2 {
410
+ // просмотреть если нигде не ломается переместит глобально
411
+ line-height: inherit;
412
+ }
413
+
414
+ .content-heading {
415
+ display: flex;
416
+ justify-content: space-between;
417
+ align-items: flex-start;
418
+ border-bottom: 1px solid #a6a6a6;
419
+
420
+ & > div h2 {
421
+ font-weight: 400;
422
+ font-size: 13px;
423
+ line-height: inherit;
424
+ color: var(--add-vm-context-sub-title);
425
+ }
426
+ }
427
+
428
+ :root.dark-theme {
429
+ .loader .text {
430
+ position: absolute;
431
+ top: calc(40% + 75px);
432
+ text-align: center;
433
+ background-color: rgba(250, 250, 250, 0.5);
434
+ padding: 5px 10px;
435
+ border-radius: 5px;
436
+
437
+ p {
438
+ color: black;
439
+ }
440
+ }
441
+ }
442
+ </style>
@@ -0,0 +1,8 @@
1
+ export enum UI_E_WIZARD_STATUS {
2
+ COMPLETED,
3
+ SELECTED,
4
+ INACTIVE,
5
+ ACTIVE,
6
+ INVALID,
7
+ INVALID_SELECTED,
8
+ }
@@ -0,0 +1,47 @@
1
+ import { UI_E_WIZARD_STATUS } from '~/components/atoms/wizard/models/enums'
2
+
3
+ export interface UI_I_ErrorFields {
4
+ alert: string
5
+ field: string
6
+ }
7
+
8
+ export interface UI_I_WizardStep {
9
+ id: number
10
+ stepName?: string
11
+ title: string
12
+ subTitle?: string
13
+ status: UI_E_WIZARD_STATUS
14
+ fields: {
15
+ [key: string]: UI_I_ErrorFields
16
+ }
17
+ isValid: boolean
18
+ }
19
+
20
+ export interface UI_I_WizardStepNavigation
21
+ extends Omit<UI_I_WizardStep, 'status'> {
22
+ status: {
23
+ disabled: boolean
24
+ active: boolean
25
+ error: boolean
26
+ complete: boolean
27
+ }
28
+ }
29
+
30
+ export interface UI_I_Loader {
31
+ status?: boolean
32
+ messages?: string[]
33
+ }
34
+
35
+ export interface UI_I_ValidationReturn {
36
+ stepHasError: boolean
37
+ stepShouldStop?: {
38
+ ifOnCurrentStep: boolean
39
+ ifFromAnyStep: boolean
40
+ stoppageStepId: number
41
+ }
42
+ newValue: UI_I_WizardStep[]
43
+ }
44
+
45
+ // export interface UI_I_WizardSlot {
46
+ // selectedStep: UI_I_WizardStep
47
+ // }
@@ -0,0 +1,112 @@
1
+ <template>
2
+ <div class="clr-wizard-stepnav">
3
+ <div class="clr-wizard-stepnav-list">
4
+ <div
5
+ v-for="(step, key) in steps"
6
+ :key="key"
7
+ :class="[
8
+ 'clr-wizard clr-wizard-stepnav-item clr-nav-link nav-item',
9
+ step.status,
10
+ ]"
11
+ >
12
+ <button
13
+ :id="`${props.testId}-step-button-${key}`"
14
+ class="btn btn-link clr-wizard-stepnav-link"
15
+ :style="{ 'margin-left': '8px' }"
16
+ :disabled="step.status.disabled"
17
+ @click="changeStep(step)"
18
+ >
19
+ <span class="clr-wizard-stepnav-link-title">
20
+ {{ step.stepName || step.title }}
21
+ </span>
22
+ </button>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import type {
30
+ UI_I_WizardStep,
31
+ UI_I_WizardStepNavigation,
32
+ } from '~/components/atoms/wizard/models/interfaces'
33
+ import { UI_E_WIZARD_STATUS } from '~/components/atoms/wizard/models/enums'
34
+
35
+ const props = withDefaults(
36
+ defineProps<{
37
+ steps: UI_I_WizardStep[]
38
+ wasCompleted: boolean
39
+ testId?: string
40
+ }>(),
41
+ { testId: 'ui-vertical-step' }
42
+ )
43
+
44
+ const steps = computed<UI_I_WizardStepNavigation[]>(() =>
45
+ props.steps.map((step: UI_I_WizardStep) => ({
46
+ ...step,
47
+ status: {
48
+ disabled: step.status === UI_E_WIZARD_STATUS.INACTIVE,
49
+ active:
50
+ step.status === UI_E_WIZARD_STATUS.SELECTED ||
51
+ step.status === UI_E_WIZARD_STATUS.INVALID_SELECTED,
52
+ error:
53
+ step.status === UI_E_WIZARD_STATUS.INVALID_SELECTED ||
54
+ step.status === UI_E_WIZARD_STATUS.INVALID,
55
+ complete:
56
+ step.status === UI_E_WIZARD_STATUS.COMPLETED ||
57
+ ((step.status === UI_E_WIZARD_STATUS.SELECTED ||
58
+ step.status === UI_E_WIZARD_STATUS.INVALID_SELECTED ||
59
+ step.status === UI_E_WIZARD_STATUS.INVALID) &&
60
+ props.wasCompleted),
61
+ },
62
+ }))
63
+ )
64
+
65
+ const emits = defineEmits<{
66
+ (event: 'change', step: UI_I_WizardStepNavigation): void
67
+ }>()
68
+
69
+ const changeStep = (step: UI_I_WizardStepNavigation): void => {
70
+ emits('change', step)
71
+ }
72
+ </script>
73
+
74
+ <style scoped lang="scss">
75
+ .clr-wizard-stepnav {
76
+ .clr-wizard-stepnav-item {
77
+ padding: 0.3rem 0 0.4rem;
78
+
79
+ &.active {
80
+ button:hover,
81
+ button {
82
+ color: var(--vertical-steps-active-color);
83
+ background-color: var(--vertical-steps-active-bg-color);
84
+ cursor: default;
85
+ span {
86
+ color: var(--checkbox-mark-color);
87
+ }
88
+ }
89
+ }
90
+ &.complete:not(&.active) {
91
+ button {
92
+ background: var(--block-view-bg-color3);
93
+ }
94
+ button:hover {
95
+ color: var(--vertical-steps-complete-color);
96
+ background-color: var(--vertical-steps-complete-bg-color);
97
+ border-bottom: 1px solid var(--vertical-steps-hover-border-color);
98
+ }
99
+ }
100
+ &.error {
101
+ box-shadow: 4px 0 0 #c21d00 inset;
102
+ transition: box-shadow 0.2s ease-in;
103
+ }
104
+ button {
105
+ color: var(--add-vm-context-title);
106
+ .clr-wizard-stepnav-link-title {
107
+ font-size: 14px;
108
+ }
109
+ }
110
+ }
111
+ }
112
+ </style>
@@ -0,0 +1,407 @@
1
+ import { ref, computed, Ref, ComputedRef } from 'vue'
2
+ import { useDeepCopy } from '~/composables/deepCopy'
3
+ import {
4
+ UI_I_ErrorFields,
5
+ UI_I_Loader,
6
+ UI_I_ValidationReturn,
7
+ UI_I_WizardStep,
8
+ } from '~/components/atoms/wizard/models/interfaces'
9
+ import { UI_E_WIZARD_STATUS } from '~/components/atoms/wizard/models/enums'
10
+
11
+ export default class Wizard {
12
+ private _initialSteps: Ref<UI_I_WizardStep[]>
13
+ private _initialStepsScheme: Ref<number[][]>
14
+ private _steps: Ref<UI_I_WizardStep[]>
15
+ private _stepsScheme: Ref<number[][]>
16
+ private _selectedSchemeId: Ref<number>
17
+ private _wizardLoader: Ref<UI_I_Loader>
18
+ selectedScheme: ComputedRef<number[]>
19
+ alertMessages: ComputedRef<string[][]>
20
+
21
+ constructor(steps: UI_I_WizardStep[], stepsSchemeInitial: number[][]) {
22
+ this._steps = ref<UI_I_WizardStep[]>(useDeepCopy(steps))
23
+ this._initialSteps = ref<UI_I_WizardStep[]>(useDeepCopy(steps))
24
+ this._stepsScheme = ref<number[][]>(useDeepCopy(stepsSchemeInitial))
25
+ this._initialStepsScheme = ref<number[][]>(useDeepCopy(stepsSchemeInitial))
26
+ this._selectedSchemeId = ref<number>(0)
27
+ this._wizardLoader = ref<UI_I_Loader>({
28
+ status: false,
29
+ messages: [],
30
+ })
31
+ this.selectedScheme = computed<number[]>(
32
+ () => this._stepsScheme.value[this._selectedSchemeId.value]
33
+ )
34
+ this.alertMessages = computed<string[][]>(() =>
35
+ this._steps.value.map((step: UI_I_WizardStep) =>
36
+ Object.values(step.fields).reduce(
37
+ (result: string[], obj: UI_I_ErrorFields) =>
38
+ obj.alert ? [...result, obj.alert] : result,
39
+ []
40
+ )
41
+ )
42
+ )
43
+ }
44
+
45
+ get steps(): UI_I_WizardStep[] {
46
+ return this._steps.value
47
+ }
48
+
49
+ set steps(newSteps: UI_I_WizardStep[]) {
50
+ this._steps.value = newSteps
51
+ }
52
+
53
+ set stepsScheme(newStepsScheme: number[][]) {
54
+ this._stepsScheme.value = newStepsScheme
55
+ }
56
+
57
+ get stepsScheme(): number[][] {
58
+ return this._stepsScheme.value
59
+ }
60
+
61
+ set selectedSchemeId(newSelectedSchemeId: number) {
62
+ this._selectedSchemeId.value = newSelectedSchemeId
63
+ }
64
+
65
+ get selectedSchemeId(): number {
66
+ return this._selectedSchemeId.value
67
+ }
68
+
69
+ get wizardLoader(): UI_I_Loader {
70
+ return this._wizardLoader.value
71
+ }
72
+
73
+ setLoader(status: boolean, messages?: string[]): void {
74
+ this._wizardLoader.value.status = status
75
+
76
+ if (!messages) return
77
+
78
+ messages.length > 0 && (this._wizardLoader.value.messages = messages)
79
+ }
80
+
81
+ changeScheme(schemeId: number): void {
82
+ this.selectedSchemeId = schemeId
83
+ this.resetAfterSelected()
84
+ }
85
+
86
+ goToFirstInvalidStep(): void {
87
+ const firstInvalidStep: UI_I_WizardStep | undefined = this.steps.find(
88
+ (step: UI_I_WizardStep) => this.isInvalid(step.status)
89
+ )
90
+
91
+ if (!firstInvalidStep) return
92
+
93
+ const firstInvalidStepId: number = firstInvalidStep.id
94
+
95
+ this.steps = this.steps.map((step: UI_I_WizardStep): UI_I_WizardStep => {
96
+ if (step.id === firstInvalidStepId) {
97
+ return { ...step, status: UI_E_WIZARD_STATUS.INVALID_SELECTED }
98
+ }
99
+ if (step.status === UI_E_WIZARD_STATUS.SELECTED) {
100
+ return { ...step, status: UI_E_WIZARD_STATUS.COMPLETED }
101
+ }
102
+
103
+ return step
104
+ })
105
+ }
106
+
107
+ goToFirstStoppageStep(stoppageStepId: number): void {
108
+ console.log('goToFirstStoppageStep', stoppageStepId)
109
+ }
110
+
111
+ hasMessage(stepId: number, field: string): boolean {
112
+ return (
113
+ !!this.steps[stepId].fields?.[field].field ||
114
+ !!this.steps[stepId].fields?.[field].alert
115
+ )
116
+ }
117
+
118
+ setValidationError(stepId: number, field: string, message: string): void {
119
+ const invalidStep: UI_I_WizardStep | undefined = this.steps.find(
120
+ (step: UI_I_WizardStep): boolean => step.id === stepId
121
+ )
122
+
123
+ if (!invalidStep) return
124
+
125
+ invalidStep.isValid = false
126
+ invalidStep.fields[field].field = message
127
+
128
+ if (this.isSelected(invalidStep.status)) {
129
+ invalidStep.status = UI_E_WIZARD_STATUS.INVALID_SELECTED
130
+ return
131
+ }
132
+
133
+ invalidStep.status = UI_E_WIZARD_STATUS.INVALID
134
+ }
135
+
136
+ setAlertMessage(stepId: number, field: string, message: string): void {
137
+ this.steps[stepId].fields[field].alert = message
138
+ }
139
+
140
+ removeAlertMessage(
141
+ stepId: number,
142
+ field: string,
143
+ value?: UI_I_WizardStep[]
144
+ ): UI_I_WizardStep[] {
145
+ const invalidStep: UI_I_WizardStep = this.steps[stepId]
146
+
147
+ invalidStep.fields[field].alert = ''
148
+ if (!value) return this.steps
149
+
150
+ return value.map(
151
+ (step: UI_I_WizardStep): UI_I_WizardStep =>
152
+ step.id === invalidStep.id ? invalidStep : step
153
+ )
154
+ }
155
+
156
+ hideAlertMessagesByStepId(stepId: number): UI_I_WizardStep[] {
157
+ const modifiedStep: UI_I_WizardStep = this.steps[stepId]
158
+
159
+ for (const field in modifiedStep.fields) {
160
+ modifiedStep.fields[field].alert = ''
161
+ }
162
+
163
+ return (this.steps = this.steps.map((step: UI_I_WizardStep) =>
164
+ step.id === stepId ? modifiedStep : step
165
+ ))
166
+ }
167
+
168
+ private removeValidationError(
169
+ stepId: number,
170
+ field: string,
171
+ nextStep: boolean,
172
+ value?: UI_I_WizardStep[]
173
+ ): UI_I_WizardStep[] {
174
+ const invalidStep: UI_I_WizardStep = this.steps[stepId]
175
+
176
+ if (!invalidStep) return this.steps
177
+
178
+ invalidStep.fields[field].field = ''
179
+
180
+ const messages: UI_I_ErrorFields[] = Object.values(
181
+ invalidStep.fields
182
+ ).filter((message: UI_I_ErrorFields): boolean => message.field !== '')
183
+
184
+ invalidStep.isValid = !messages.length
185
+
186
+ if (nextStep && invalidStep.isValid && this.isInvalid(invalidStep.status)) {
187
+ invalidStep.status = UI_E_WIZARD_STATUS.COMPLETED
188
+ }
189
+
190
+ if (
191
+ !nextStep &&
192
+ invalidStep.isValid &&
193
+ invalidStep.status === UI_E_WIZARD_STATUS.INVALID_SELECTED
194
+ ) {
195
+ invalidStep.status = UI_E_WIZARD_STATUS.SELECTED
196
+ }
197
+
198
+ if (nextStep) this.goToFirstInvalidStep()
199
+
200
+ if (!value) return this.steps
201
+
202
+ return value.map(
203
+ (step: UI_I_WizardStep): UI_I_WizardStep =>
204
+ step.id === invalidStep.id ? invalidStep : step
205
+ )
206
+ }
207
+
208
+ changeStep(value: UI_I_WizardStep[]): void {
209
+ this.steps = this.steps.map(
210
+ (step: UI_I_WizardStep): UI_I_WizardStep => ({
211
+ ...step,
212
+ ...(value.find(
213
+ (stepFind: UI_I_WizardStep): boolean => stepFind.id === step.id
214
+ ) || step),
215
+ })
216
+ )
217
+ }
218
+
219
+ isSelected(status: UI_E_WIZARD_STATUS): boolean {
220
+ return (
221
+ status === UI_E_WIZARD_STATUS.SELECTED ||
222
+ status === UI_E_WIZARD_STATUS.INVALID_SELECTED
223
+ )
224
+ }
225
+
226
+ isInvalid(status: UI_E_WIZARD_STATUS): boolean {
227
+ return (
228
+ status === UI_E_WIZARD_STATUS.INVALID ||
229
+ status === UI_E_WIZARD_STATUS.INVALID_SELECTED
230
+ )
231
+ }
232
+
233
+ get selectedStepId(): number {
234
+ const selectedStep: UI_I_WizardStep | undefined = this.steps.find(
235
+ (step: UI_I_WizardStep) =>
236
+ step.status === UI_E_WIZARD_STATUS.SELECTED ||
237
+ step.status === UI_E_WIZARD_STATUS.INVALID_SELECTED
238
+ )
239
+
240
+ return selectedStep !== undefined ? selectedStep.id : this.steps[0].id
241
+ }
242
+
243
+ async changeSteps(
244
+ value: UI_I_WizardStep[],
245
+ validationFunc: (
246
+ value: UI_I_WizardStep[],
247
+ currentStep: UI_I_WizardStep,
248
+ nextStep: UI_I_WizardStep
249
+ ) => Promise<UI_I_ValidationReturn>
250
+ ): Promise<void> {
251
+ const currentStep: UI_I_WizardStep | undefined = this.steps.find(
252
+ (step: UI_I_WizardStep) => this.isSelected(step.status)
253
+ )
254
+
255
+ const nextStep: UI_I_WizardStep | undefined = value.find(
256
+ (step: UI_I_WizardStep) => this.isSelected(step.status)
257
+ )
258
+
259
+ if (!currentStep || !nextStep) return
260
+ if (currentStep.id > nextStep.id) return this.changeStep(value)
261
+
262
+ if (validationFunc) {
263
+ const validation: UI_I_ValidationReturn = await validationFunc(
264
+ value,
265
+ currentStep,
266
+ nextStep
267
+ )
268
+
269
+ if (
270
+ validation.stepHasError ||
271
+ validation.stepShouldStop?.ifFromAnyStep ||
272
+ validation.stepShouldStop?.ifOnCurrentStep
273
+ ) {
274
+ validation.stepShouldStop?.ifFromAnyStep &&
275
+ currentStep.id < validation.stepShouldStop?.stoppageStepId &&
276
+ this.selectStepHard(validation.stepShouldStop?.stoppageStepId)
277
+
278
+ validation.stepShouldStop?.ifOnCurrentStep &&
279
+ this.selectStepHard(validation.stepShouldStop?.stoppageStepId)
280
+
281
+ validation.stepHasError && this.goToFirstInvalidStep()
282
+
283
+ return
284
+ } else {
285
+ currentStep.status = UI_E_WIZARD_STATUS.COMPLETED
286
+ }
287
+
288
+ this.changeStep(validation.newValue)
289
+
290
+ return
291
+ }
292
+
293
+ this.changeStep(value)
294
+ }
295
+
296
+ selectStepHard(stepId: number): void {
297
+ const newSteps = this.steps.map((st: UI_I_WizardStep) => {
298
+ console.log(st.id, stepId)
299
+ if (st.id < stepId) return { ...st, status: UI_E_WIZARD_STATUS.COMPLETED }
300
+ console.log(st.id, stepId)
301
+ if (st.id === stepId)
302
+ return { ...st, status: UI_E_WIZARD_STATUS.SELECTED }
303
+
304
+ return st
305
+ })
306
+
307
+ this.changeStep(newSteps)
308
+ }
309
+
310
+ isValidateForStep(
311
+ step: number,
312
+ currentStepId: number,
313
+ nextStepId: number
314
+ ): boolean {
315
+ return nextStepId > step && currentStepId <= step
316
+ }
317
+
318
+ setValidation(
319
+ stepId: number,
320
+ field: string,
321
+ message: {
322
+ fieldMessage?: string
323
+ alertMessage?: string
324
+ }
325
+ ): true {
326
+ message.fieldMessage &&
327
+ this.setValidationError(stepId, field, message.fieldMessage)
328
+ message.alertMessage &&
329
+ this.setAlertMessage(stepId, field, message.alertMessage)
330
+
331
+ return true
332
+ }
333
+
334
+ removeValidation(
335
+ stepId: number,
336
+ field: string,
337
+ value: UI_I_WizardStep[]
338
+ ): UI_I_WizardStep[] {
339
+ let newValue: UI_I_WizardStep[] = this.removeValidationError(
340
+ stepId,
341
+ field,
342
+ true,
343
+ value
344
+ )
345
+ newValue = this.removeAlertMessage(stepId, field, newValue)
346
+ return newValue
347
+ }
348
+
349
+ reset(): void {
350
+ this.steps = useDeepCopy(this._initialSteps.value)
351
+ this.stepsScheme = useDeepCopy(this._initialStepsScheme.value)
352
+ this.selectedSchemeId = 0
353
+ }
354
+
355
+ setEmptyErrorFields(fields: { [key: string]: UI_I_ErrorFields }): {
356
+ [key: string]: UI_I_ErrorFields
357
+ } {
358
+ const keys: string[] = Object.keys(fields)
359
+ const obj: { [key: string]: UI_I_ErrorFields } = {}
360
+
361
+ keys.forEach((key: string): void => {
362
+ obj[key] = {
363
+ alert: '',
364
+ field: '',
365
+ }
366
+ })
367
+
368
+ return obj
369
+ }
370
+
371
+ resetAfterSelected(): void {
372
+ this.steps = this.steps.map(
373
+ (step: UI_I_WizardStep): UI_I_WizardStep =>
374
+ step.id > this.selectedStepId
375
+ ? {
376
+ ...step,
377
+ status: UI_E_WIZARD_STATUS.INACTIVE,
378
+ isValid: true,
379
+ fields: this.setEmptyErrorFields(step.fields),
380
+ }
381
+ : step
382
+ )
383
+ }
384
+
385
+ activeStepId(): number {
386
+ return (
387
+ this.steps.find(
388
+ (step: UI_I_WizardStep) => step.status === UI_E_WIZARD_STATUS.ACTIVE
389
+ )?.id || 0
390
+ )
391
+ }
392
+
393
+ wasCompleted(): boolean {
394
+ return this.activeStepId() > this.selectedStepId
395
+ }
396
+
397
+ isLastStep(): boolean {
398
+ return (
399
+ this.selectedScheme.value[this.selectedScheme.value.length - 2] ===
400
+ this.selectedStepId
401
+ )
402
+ }
403
+
404
+ getStepIdByFieldName(fieldName: string): number {
405
+ return this.steps.find((step) => step.fields[fieldName])?.id || -1
406
+ }
407
+ }
@@ -1114,6 +1114,7 @@ const onHideAddNetworkingModal = (): void => {
1114
1114
  color: #fff;
1115
1115
  }
1116
1116
  }
1117
+ }
1117
1118
 
1118
1119
  .select-adapter-info span {
1119
1120
  color: var(--main-color-mode2);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bfg-common",
3
3
  "private": false,
4
- "version": "1.2.157",
4
+ "version": "1.2.159",
5
5
  "scripts": {
6
6
  "build": "nuxt build",
7
7
  "dev": "nuxt dev --port=3002",