bfg-common 1.5.656 → 1.5.657

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.
Files changed (115) hide show
  1. package/CODE_STYLE.md +109 -109
  2. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  3. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  4. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  5. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  6. package/assets/localization/local_be.json +4 -1
  7. package/assets/localization/local_en.json +4 -1
  8. package/assets/localization/local_hy.json +4 -1
  9. package/assets/localization/local_kk.json +4 -1
  10. package/assets/localization/local_ru.json +4 -1
  11. package/assets/localization/local_zh.json +4 -1
  12. package/components/atoms/TheIcon3.vue +50 -50
  13. package/components/atoms/collapse/CollapseNav.vue +170 -170
  14. package/components/atoms/perPage/PerPage.vue +58 -58
  15. package/components/atoms/table/dataGrid/DataGrid.vue +1718 -1718
  16. package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
  17. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  18. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  19. package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
  20. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  21. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  22. package/components/common/diagramMain/port/Port.vue +580 -580
  23. package/components/common/layout/theHeader/TheHeader.vue +38 -26
  24. package/components/common/layout/theHeader/TheHeaderNew.vue +315 -310
  25. package/components/common/layout/theHeader/TheHeaderOld.vue +262 -257
  26. package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
  27. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
  28. package/components/common/layout/theHeader/userMenu/UserMenu.vue +8 -3
  29. package/components/common/layout/theHeader/userMenu/modals/changePassword/ChangePassword.vue +99 -99
  30. package/components/common/layout/theHeader/userMenu/modals/changePassword/New.vue +193 -193
  31. package/components/common/layout/theHeader/userMenu/modals/preferences/Preferences.vue +10 -4
  32. package/components/common/layout/theHeader/userMenu/modals/preferences/PreferencesOld.vue +144 -141
  33. package/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types.ts +7 -7
  34. package/components/common/layout/theHeader/userMenu/modals/preferences/security/Old.vue +210 -120
  35. package/components/common/layout/theHeader/userMenu/modals/preferences/security/Security.vue +31 -23
  36. package/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces.ts +4 -0
  37. package/components/common/pages/backups/DetailView.vue +52 -52
  38. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  39. package/components/common/pages/backups/modals/Modals.vue +243 -243
  40. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  41. package/components/common/pages/backups/modals/createBackup/datastores/tableView/old/lib/config/table.ts +12 -0
  42. package/components/common/pages/backups/modals/createBackup/disks/tableView/old/lib/config/table.ts +9 -0
  43. package/components/common/pages/backups/modals/createBackup/lib/config/readyToCompleteOptions.ts +69 -69
  44. package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
  45. package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
  46. package/components/common/pages/backups/modals/restore/disks/tableView/old/lib/config/table.ts +9 -0
  47. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  48. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  49. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  50. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  51. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  52. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  53. package/components/common/pages/licensing/listView/ListView.vue +13 -5
  54. package/components/common/pages/licensing/modals/assign/tableView/TableView.vue +3 -5
  55. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  56. package/components/common/pages/scheduledTasks/table/lib/config/scheduledTasksTable.ts +6 -0
  57. package/components/common/qrcode/Qrcode.vue +56 -0
  58. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  59. package/components/common/select/radio/RadioGroup.vue +137 -137
  60. package/components/common/spiceConsole/Drawer.vue +420 -420
  61. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  62. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  63. package/components/common/tools/Actions.vue +207 -207
  64. package/components/common/treeView/TreeView.vue +52 -52
  65. package/components/common/vm/actions/clone/lib/config/steps.ts +295 -295
  66. package/components/common/vm/actions/clone/new/New.vue +438 -438
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +1 -1
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +283 -283
  70. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +156 -156
  71. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  72. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  73. package/components/common/vm/actions/common/select/options/New.vue +264 -264
  74. package/components/common/vm/actions/common/select/options/Old.vue +110 -110
  75. package/components/common/vm/actions/common/select/options/Options.vue +58 -58
  76. package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
  77. package/components/common/vm/actions/common/select/storage/new/New.vue +311 -311
  78. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  79. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  80. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  81. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  82. package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
  83. package/components/common/wizards/common/compatibility/New.vue +99 -99
  84. package/components/common/wizards/common/compatibility/Old.vue +53 -53
  85. package/components/common/wizards/common/steps/computeResource/New.vue +93 -93
  86. package/components/common/wizards/common/steps/name/Name.vue +178 -178
  87. package/components/common/wizards/common/steps/name/New.vue +221 -221
  88. package/components/common/wizards/common/steps/name/Old.vue +121 -121
  89. package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
  90. package/components/common/wizards/common/steps/name/location/New.vue +40 -40
  91. package/components/common/wizards/datastore/add/Add.vue +228 -228
  92. package/components/common/wizards/datastore/add/lib/utils.ts +85 -85
  93. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  94. package/composables/useAppVersion.ts +21 -21
  95. package/composables/useLocal.ts +6 -6
  96. package/composables/useLocalCommon.ts +39 -39
  97. package/package.json +3 -2
  98. package/plugins/console.ts +21 -21
  99. package/plugins/mouse.ts +21 -21
  100. package/plugins/panelStates.ts +70 -70
  101. package/plugins/text.ts +59 -59
  102. package/public/spice-console/application/clientgui.js +854 -854
  103. package/public/spice-console/application/packetfactory.js +211 -211
  104. package/public/spice-console/application/virtualmouse.js +147 -147
  105. package/public/spice-console/lib/images/bitmap.js +203 -203
  106. package/public/spice-console/network/spicechannel.js +440 -440
  107. package/public/spice-console/process/cursorprocess.js +128 -128
  108. package/public/spice-console/process/inputprocess.js +227 -227
  109. package/public/spice-console/process/mainprocess.js +212 -212
  110. package/public/spice-console/run.js +210 -210
  111. package/store/main/mutations.ts +7 -7
  112. package/store/main/state.ts +7 -7
  113. package/store/tasks/actions.ts +165 -165
  114. package/store/tasks/mappers/recentTasks.ts +123 -123
  115. package/store/tasks/mutations.ts +82 -82
@@ -1,141 +1,144 @@
1
- <template>
2
- <atoms-modal
3
- :title="localization.common.preferences"
4
- :modal-loading="isLoading || props.securityLoader"
5
- test-id="user-preferences-modal"
6
- width="580px"
7
- height="345px"
8
- show
9
- @hide="onHide"
10
- >
11
- <template #modalBody>
12
- <atoms-nav-bar
13
- v-model="selectedTab"
14
- :items="tabsItems"
15
- test-id="user-preferences-nav-bar"
16
- />
17
-
18
- <common-layout-the-header-user-menu-modals-preferences-time-format
19
- v-if="selectedTab === 'time-tab'"
20
- :new-view="props.newView"
21
- :time-format="props.timeFormat"
22
- @update-time-format="emits('update-time-format', $event)"
23
- />
24
-
25
- <common-layout-the-header-user-menu-modals-preferences-change-language
26
- v-if="selectedTab === 'language-tab'"
27
- :new-view="props.newView"
28
- :selected-type="props.selectedLanguageType"
29
- :selected-language="props.selectedLanguage"
30
- @update-language="emits('update-language', $event)"
31
- @update-is-browser="emits('update-is-browser', $event)"
32
- />
33
-
34
- <common-layout-the-header-user-menu-modals-preferences-inventory
35
- v-if="selectedTab === 'inventory-tab' && isSphere"
36
- :new-view="props.newView"
37
- :vm-cluster="props.vmCluster"
38
- @update-vm-clusters="emits('update-vm-clusters', $event)"
39
- />
40
-
41
- <common-layout-the-header-user-menu-modals-preferences-default-console
42
- v-if="selectedTab === 'console-tab' && isSphere"
43
- :new-view="props.newView"
44
- :remote-console="props.remoteConsole"
45
- @update-remote-console="emits('update-remote-console', $event)"
46
- />
47
-
48
- <common-layout-the-header-user-menu-modals-preferences-security
49
- v-if="selectedTab === 'security-tab'"
50
- v-model:security="security"
51
- :recovery-codes="props.recoveryCodes"
52
- />
53
-
54
- <common-layout-the-header-user-menu-modals-preferences-view
55
- v-if="selectedTab === 'view-tab'"
56
- :new-view="props.newView"
57
- :new-view-local="props.newViewLocal"
58
- @update-is-new-view="emits('update-is-new-view', $event)"
59
- />
60
- </template>
61
-
62
- <template #modalFooter>
63
- <button
64
- id="user-preferences-cancel-button"
65
- data-id="user-preferences-cancel-button"
66
- class="btn btn-outline"
67
- @click="onHide"
68
- >
69
- {{ localization.common.cancel }}
70
- </button>
71
- <button
72
- id="user-preferences-apply-button"
73
- data-id="user-preferences-apply-button"
74
- class="btn btn-primary"
75
- @click="onSubmit"
76
- >
77
- {{ localization.common.save }}
78
- </button>
79
- </template>
80
- </atoms-modal>
81
- </template>
82
-
83
- <script setup lang="ts">
84
- import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
85
- import type { UI_I_Localization } from '~/lib/models/interfaces'
86
- import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
87
- import type { UI_T_UserPreferenceTab } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types'
88
- import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
89
- import { preferencesTabs } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/config/preferencesTabs'
90
-
91
- const security = defineModel<boolean>('security')
92
-
93
- const props = defineProps<{
94
- project: UI_T_Project
95
- timeFormat: UI_T_TimeValue
96
- selectedLanguage: UI_T_LangValue
97
- selectedLanguageType: UI_T_LangValue
98
- newView: boolean
99
- newViewLocal: boolean
100
- remoteConsole: string
101
- vmCluster: boolean
102
- securityLoader?: boolean // для Сферы
103
- recoveryCodes?: string[] // для Сферы
104
- }>()
105
- const emits = defineEmits<{
106
- (event: 'hide'): void
107
- (event: 'update-time-format', value: UI_T_TimeValue): void
108
- (event: 'update-language', value: string): void
109
- (event: 'update-is-browser', value: string): void
110
- (event: 'update-is-new-view', value: boolean): void
111
- (event: 'update-remote-console', value: string): void
112
- (event: 'update-vm-clusters', value: boolean): void
113
- (event: 'submit'): void
114
- }>()
115
-
116
- // const { $store }: any = useNuxtApp()
117
-
118
- const localization = computed<UI_I_Localization>(() => useLocal())
119
-
120
- const isLoading = ref<boolean>(false)
121
-
122
- const isSphere = ref<boolean>(props.project === 'sphere')
123
- const selectedTab = ref<UI_T_UserPreferenceTab>('time-tab')
124
-
125
- const tabsItems = computed<UI_I_CollapseNavItem[]>(() =>
126
- preferencesTabs(localization.value, props.project)
127
- )
128
-
129
- const onSubmit = (): void => {
130
- isLoading.value = true
131
- emits('submit')
132
- }
133
-
134
- const onHide = (): void => {
135
- emits('hide')
136
-
137
- if (isSphere.value) {
138
- selectedTab.value = 'time-tab'
139
- }
140
- }
141
- </script>
1
+ <template>
2
+ <atoms-modal
3
+ :title="localization.common.preferences"
4
+ :modal-loading="isLoading || props.securityLoader"
5
+ test-id="user-preferences-modal"
6
+ width="580px"
7
+ height="420px"
8
+ show
9
+ @hide="onHide"
10
+ >
11
+ <template #modalBody>
12
+ <atoms-nav-bar
13
+ v-model="selectedTab"
14
+ :items="tabsItems"
15
+ test-id="user-preferences-nav-bar"
16
+ />
17
+
18
+ <common-layout-the-header-user-menu-modals-preferences-time-format
19
+ v-if="selectedTab === 'time-tab'"
20
+ :new-view="props.newView"
21
+ :time-format="props.timeFormat"
22
+ @update-time-format="emits('update-time-format', $event)"
23
+ />
24
+
25
+ <common-layout-the-header-user-menu-modals-preferences-change-language
26
+ v-if="selectedTab === 'language-tab'"
27
+ :new-view="props.newView"
28
+ :selected-type="props.selectedLanguageType"
29
+ :selected-language="props.selectedLanguage"
30
+ @update-language="emits('update-language', $event)"
31
+ @update-is-browser="emits('update-is-browser', $event)"
32
+ />
33
+
34
+ <common-layout-the-header-user-menu-modals-preferences-inventory
35
+ v-if="selectedTab === 'inventory-tab' && isSphere"
36
+ :new-view="props.newView"
37
+ :vm-cluster="props.vmCluster"
38
+ @update-vm-clusters="emits('update-vm-clusters', $event)"
39
+ />
40
+
41
+ <common-layout-the-header-user-menu-modals-preferences-default-console
42
+ v-if="selectedTab === 'console-tab' && isSphere"
43
+ :new-view="props.newView"
44
+ :remote-console="props.remoteConsole"
45
+ @update-remote-console="emits('update-remote-console', $event)"
46
+ />
47
+
48
+ <common-layout-the-header-user-menu-modals-preferences-security
49
+ v-if="selectedTab === 'security-tab'"
50
+ v-model:security="security"
51
+ :recovery="props.recovery"
52
+ @confirm="emits('security-confirm', $event)"
53
+ />
54
+
55
+ <common-layout-the-header-user-menu-modals-preferences-view
56
+ v-if="selectedTab === 'view-tab'"
57
+ :new-view="props.newView"
58
+ :new-view-local="props.newViewLocal"
59
+ @update-is-new-view="emits('update-is-new-view', $event)"
60
+ />
61
+ </template>
62
+
63
+ <template #modalFooter>
64
+ <button
65
+ id="user-preferences-cancel-button"
66
+ data-id="user-preferences-cancel-button"
67
+ class="btn btn-outline"
68
+ @click="onHide"
69
+ >
70
+ {{ localization.common.cancel }}
71
+ </button>
72
+ <button
73
+ id="user-preferences-apply-button"
74
+ data-id="user-preferences-apply-button"
75
+ class="btn btn-primary"
76
+ @click="onSubmit"
77
+ >
78
+ {{ localization.common.save }}
79
+ </button>
80
+ </template>
81
+ </atoms-modal>
82
+ </template>
83
+
84
+ <script setup lang="ts">
85
+ import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
86
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
87
+ import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
88
+ import type { UI_T_UserPreferenceTab } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types'
89
+ import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
90
+ import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
91
+ import { preferencesTabs } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/config/preferencesTabs'
92
+
93
+ const security = defineModel<boolean>('security')
94
+
95
+ const props = defineProps<{
96
+ project: UI_T_Project
97
+ timeFormat: UI_T_TimeValue
98
+ selectedLanguage: UI_T_LangValue
99
+ selectedLanguageType: UI_T_LangValue
100
+ newView: boolean
101
+ newViewLocal: boolean
102
+ remoteConsole: string
103
+ vmCluster: boolean
104
+ securityLoader: boolean // для Сферы
105
+ recovery: UI_I_Recovery | null // для Сферы
106
+ }>()
107
+ const emits = defineEmits<{
108
+ (event: 'hide'): void
109
+ (event: 'update-time-format', value: UI_T_TimeValue): void
110
+ (event: 'update-language', value: string): void
111
+ (event: 'update-is-browser', value: string): void
112
+ (event: 'update-is-new-view', value: boolean): void
113
+ (event: 'update-remote-console', value: string): void
114
+ (event: 'update-vm-clusters', value: boolean): void
115
+ (event: 'security-confirm', value: boolean): void
116
+ (event: 'submit'): void
117
+ }>()
118
+
119
+ // const { $store }: any = useNuxtApp()
120
+
121
+ const localization = computed<UI_I_Localization>(() => useLocal())
122
+
123
+ const isLoading = ref<boolean>(false)
124
+
125
+ const isSphere = ref<boolean>(props.project === 'sphere')
126
+ const selectedTab = ref<UI_T_UserPreferenceTab>('time-tab')
127
+
128
+ const tabsItems = computed<UI_I_CollapseNavItem[]>(() =>
129
+ preferencesTabs(localization.value, props.project)
130
+ )
131
+
132
+ const onSubmit = (): void => {
133
+ isLoading.value = true
134
+ emits('submit')
135
+ }
136
+
137
+ const onHide = (): void => {
138
+ emits('hide')
139
+
140
+ if (isSphere.value) {
141
+ selectedTab.value = 'time-tab'
142
+ }
143
+ }
144
+ </script>
@@ -1,7 +1,7 @@
1
- export type UI_T_UserPreferenceTab =
2
- | 'time-tab'
3
- | 'language-tab'
4
- | 'console-tab'
5
- | 'inventory-tab'
6
- | 'security-tab'
7
- | 'view-tab'
1
+ export type UI_T_UserPreferenceTab =
2
+ | 'time-tab'
3
+ | 'language-tab'
4
+ | 'console-tab'
5
+ | 'inventory-tab'
6
+ | 'security-tab'
7
+ | 'view-tab'
@@ -1,120 +1,210 @@
1
- <template>
2
- <form id="security-form" class="compact">
3
- <div class="description">
4
- {{ localization.myPreferences.twoFactorAuthentication }}
5
- </div>
6
-
7
- <div class="flex-align-center">
8
- <label for="security">{{
9
- localization.myPreferences.securityLabel
10
- }}</label>
11
- <input id="security" v-model="security" type="checkbox" class="switch" />
12
- </div>
13
-
14
- <div v-if="props.recoveryCodes.length" class="recovery-codes">
15
- <!-- TODO-->
16
- <label>Recovery codes:</label>
17
- <ul class="recovery-codes-list">
18
- <li
19
- v-for="item in props.recoveryCodes"
20
- :key="item"
21
- class="recovery-codes-list-item"
22
- >
23
- {{ item }}
24
- </li>
25
- </ul>
26
- </div>
27
- </form>
28
- </template>
29
-
30
- <script setup lang="ts">
31
- import type { UI_I_Localization } from '~/lib/models/interfaces'
32
-
33
- const props = defineProps<{
34
- recoveryCodes: string[]
35
- }>()
36
-
37
- const localization = computed<UI_I_Localization>(() => useLocal())
38
-
39
- const security = defineModel<boolean>('security')
40
- </script>
41
-
42
- <style lang="scss" scoped>
43
- .description {
44
- margin-bottom: 10px;
45
- }
46
-
47
- .recovery-codes {
48
- display: flex;
49
- margin-top: 10px;
50
-
51
- .recovery-codes-list-item {
52
- font-size: 12px;
53
- }
54
- }
55
-
56
- label {
57
- margin-right: 6px;
58
- }
59
-
60
- // TODO повторяется в ../view, необходимо вынести глобально
61
- input[type='checkbox'] {
62
- --active: var(--checkbox-value-active-color);
63
- --active-inner: var(--checkbox-mark-color);
64
- --border: var(--checkbox-mark-color);
65
- --background: var(--checkbox-mark-background-color);
66
- -webkit-appearance: none;
67
- -moz-appearance: none;
68
- height: 20px;
69
- outline: none;
70
- display: inline-block;
71
- vertical-align: top;
72
- position: relative;
73
- margin: 0;
74
- cursor: pointer;
75
- border: 1px solid var(--bc, var(--border));
76
- background: var(--b, var(--background));
77
- transition: background 0.3s, border-color 0.3s, box-shadow 0.2s;
78
- &:after {
79
- content: '';
80
- display: block;
81
- left: 0;
82
- top: 0;
83
- position: absolute;
84
- transition: transform var(--d-t, 0.3s) var(--d-t-e, ease),
85
- opacity var(--d-o, 0.2s);
86
- }
87
- &:checked {
88
- --b: var(--active);
89
- --bc: var(--active);
90
- --d-o: 0.3s;
91
- --d-t: 0.6s;
92
- --d-t-e: cubic-bezier(0.2, 0.85, 0.32, 1.2);
93
- }
94
- }
95
- input[type='checkbox'] {
96
- &.switch {
97
- width: 35px;
98
- border-radius: 11px;
99
- &:after {
100
- left: 2px;
101
- top: 2px;
102
- bottom: 2px;
103
- border-radius: 50%;
104
- width: 14px;
105
- height: 14px;
106
- border: 1px solid var(--bc, var(--border));
107
- background: var(--ab, var(--border));
108
- transform: translateX(var(--x, 0));
109
- }
110
- &:checked {
111
- --ab: var(--active-inner);
112
- --x: 14px;
113
- }
114
- &:disabled {
115
- cursor: not-allowed;
116
- opacity: 0.5;
117
- }
118
- }
119
- }
120
- </style>
1
+ <template>
2
+ <form id="security-form" class="compact" @submit.prevent>
3
+ <div class="description">
4
+ {{ localization.myPreferences.twoFactorAuthentication }}
5
+ </div>
6
+
7
+ <div class="flex-align-center">
8
+ <label for="security">{{
9
+ localization.myPreferences.securityLabel
10
+ }}</label>
11
+ <input id="security" v-model="security" type="checkbox" class="switch" />
12
+ </div>
13
+
14
+ <div
15
+ v-if="
16
+ props.recovery && security && !initialSecurity && !otpEnabledSuccess
17
+ "
18
+ class="recovery-codes-wrap"
19
+ >
20
+ <p>
21
+ {{ localization.myPreferences.enterOtpForEnabled }}
22
+ </p>
23
+
24
+ <div class="recovery-codes">
25
+ <common-qrcode :qr-code-url="props.recovery.qr_code_url" />
26
+
27
+ <span>{{ localization.common.or }}</span>
28
+
29
+ <ul class="recovery-codes-list">
30
+ <li
31
+ v-for="item in props.recovery.recovery_codes"
32
+ :key="item"
33
+ class="recovery-codes-list-item"
34
+ >
35
+ {{ item }}
36
+ </li>
37
+ </ul>
38
+ </div>
39
+ <section class="form-block">
40
+ <div class="form-group">
41
+ <label for="otp">{{ localization.myPreferences.enterOtpForEnabled }}</label>
42
+ <input id="otp" v-model="otp" type="text" />
43
+ <button class="btn btn-sm btn-primary" @click="onConfirm">
44
+ {{ localization.common.confirm }}
45
+ </button>
46
+ <atoms-loader v-if="isOtpLoading" test-id="2fa-enabled-loader" />
47
+ </div>
48
+ </section>
49
+ </div>
50
+
51
+ <div v-if="!security && initialSecurity && !otpDisabledSuccess">
52
+ <section class="form-block">
53
+ <div class="form-group">
54
+ <label for="otp"
55
+ >{{ localization.myPreferences.enterOtpForDisabled }}</label
56
+ >
57
+ <input id="otp" v-model="otp" type="text" />
58
+ <button class="btn btn-sm btn-primary" @click="onDisabled">
59
+ {{ localization.common.confirm }}
60
+ </button>
61
+ <atoms-loader v-if="isOtpLoading" test-id="2fa-disabled-loader"/>
62
+ </div>
63
+ </section>
64
+ </div>
65
+ </form>
66
+ </template>
67
+
68
+ <script setup lang="ts">
69
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
70
+ import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
71
+
72
+ const security = defineModel<boolean>('security')
73
+
74
+ const props = defineProps<{
75
+ recovery?: UI_I_Recovery
76
+ }>()
77
+ const emits = defineEmits<{
78
+ (event: 'confirm', value: boolean): void
79
+ }>()
80
+
81
+ const localization = computed<UI_I_Localization>(() => useLocal())
82
+
83
+ const initialSecurity = ref<boolean>(security.value || false)
84
+
85
+ // TODO refactoring and move to Sphere
86
+ const otp = ref<string>('')
87
+ const isOtpLoading = ref<boolean>(false)
88
+
89
+ const otpEnabledSuccess = ref<boolean>(false)
90
+ const onConfirm = async (): Promise<void> => {
91
+ isOtpLoading.value = true
92
+ const { data } = await useMyFetch<any, any>('ui/auth/2fa/confirm', {
93
+ method: 'POST',
94
+ body: {
95
+ otp: otp.value,
96
+ },
97
+ })
98
+ if (data.value) {
99
+ otpEnabledSuccess.value = true
100
+ otpDisabledSuccess.value = false
101
+ emits('confirm', true)
102
+ }
103
+ isOtpLoading.value = false
104
+ }
105
+
106
+ const otpDisabledSuccess = ref<boolean>(false)
107
+ const onDisabled = async (): Promise<void> => {
108
+ isOtpLoading.value = true
109
+ const { data } = await useMyFetch<any, I_ErrorResponse>(
110
+ 'ui/auth/2fa/disable',
111
+ {
112
+ method: 'POST',
113
+ body: {
114
+ otp: otp.value,
115
+ },
116
+ }
117
+ )
118
+ if (data.value) {
119
+ otpDisabledSuccess.value = true
120
+ otpEnabledSuccess.value = false
121
+ emits('confirm', false)
122
+ }
123
+ isOtpLoading.value = false
124
+ }
125
+ </script>
126
+
127
+ <style lang="scss" scoped>
128
+ .description {
129
+ margin-bottom: 10px;
130
+ }
131
+
132
+ .recovery-codes-wrap {
133
+ margin: 10px 0;
134
+
135
+ .recovery-codes {
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-evenly;
139
+
140
+ .recovery-codes-list-item {
141
+ font-size: 12px;
142
+ }
143
+ }
144
+ }
145
+
146
+ label {
147
+ margin-right: 6px;
148
+ }
149
+
150
+ // TODO повторяется в ../view, необходимо вынести глобально
151
+ input[type='checkbox'] {
152
+ --active: var(--checkbox-value-active-color);
153
+ --active-inner: var(--checkbox-mark-color);
154
+ --border: var(--checkbox-mark-color);
155
+ --background: var(--checkbox-mark-background-color);
156
+ -webkit-appearance: none;
157
+ -moz-appearance: none;
158
+ height: 20px;
159
+ outline: none;
160
+ display: inline-block;
161
+ vertical-align: top;
162
+ position: relative;
163
+ margin: 0;
164
+ cursor: pointer;
165
+ border: 1px solid var(--bc, var(--border));
166
+ background: var(--b, var(--background));
167
+ transition: background 0.3s, border-color 0.3s, box-shadow 0.2s;
168
+ &:after {
169
+ content: '';
170
+ display: block;
171
+ left: 0;
172
+ top: 0;
173
+ position: absolute;
174
+ transition: transform var(--d-t, 0.3s) var(--d-t-e, ease),
175
+ opacity var(--d-o, 0.2s);
176
+ }
177
+ &:checked {
178
+ --b: var(--active);
179
+ --bc: var(--active);
180
+ --d-o: 0.3s;
181
+ --d-t: 0.6s;
182
+ --d-t-e: cubic-bezier(0.2, 0.85, 0.32, 1.2);
183
+ }
184
+ }
185
+ input[type='checkbox'] {
186
+ &.switch {
187
+ width: 35px;
188
+ border-radius: 11px;
189
+ &:after {
190
+ left: 2px;
191
+ top: 2px;
192
+ bottom: 2px;
193
+ border-radius: 50%;
194
+ width: 14px;
195
+ height: 14px;
196
+ border: 1px solid var(--bc, var(--border));
197
+ background: var(--ab, var(--border));
198
+ transform: translateX(var(--x, 0));
199
+ }
200
+ &:checked {
201
+ --ab: var(--active-inner);
202
+ --x: 14px;
203
+ }
204
+ &:disabled {
205
+ cursor: not-allowed;
206
+ opacity: 0.5;
207
+ }
208
+ }
209
+ }
210
+ </style>