bfg-common 1.5.833 → 1.5.834
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/assets/localization/local_be.json +2 -1
- package/assets/localization/local_en.json +2 -1
- package/assets/localization/local_hy.json +2 -1
- package/assets/localization/local_kk.json +2 -1
- package/assets/localization/local_zh.json +2 -1
- package/components/common/layout/theHeader/Old.vue +258 -258
- package/components/common/layout/theHeader/userMenu/modals/preferences/Old.vue +156 -156
- package/components/common/layout/theHeader/userMenu/modals/preferences/security/Old.vue +196 -196
- package/package.json +1 -1
|
@@ -3916,7 +3916,8 @@
|
|
|
3916
3916
|
"qrcodeDescription": "Скануйце гэты QR-код з дапамогай праграмы-аўтэнтыфікатара альбо ўвядзіце адзін з гэтых кодаў уручную. Пасля гэтага пацвердзіце дзеянне, увёўшы аднаразовы код ніжэй.",
|
|
3917
3917
|
"showNotification": "Паказваць апавяшчэнне",
|
|
3918
3918
|
"showNotificationDescription": "Паказваць апавяшчэнне, калі нешта ідзе не так",
|
|
3919
|
-
"twoFactorMustBeEnabled": "Неабходна падключыць двухфактарную аўтэнтыфікацыю (2FA), інакш ваш акаўнт будзе заблакаваны."
|
|
3919
|
+
"twoFactorMustBeEnabled": "Неабходна падключыць двухфактарную аўтэнтыфікацыю (2FA), інакш ваш акаўнт будзе заблакаваны.",
|
|
3920
|
+
"twoFactorMustWarning": "Вам засталося {0} дзён, каб падключыць двухфактарную аўтэнтыфікацыю (2FA), інакш ваш акаўнт будзе заблакаваны (адключаны)."
|
|
3920
3921
|
},
|
|
3921
3922
|
"ssoConfiguration": {
|
|
3922
3923
|
"twoFactorPolicy": "Палітыка двухфактарнай аўтэнтыфікацыі",
|
|
@@ -3920,7 +3920,8 @@
|
|
|
3920
3920
|
"qrcodeDescription": "Scan this QR code with your authenticator app, or enter one of these codes manually. After that, confirm the action by entering the one-time code below.",
|
|
3921
3921
|
"showNotification": "Show a notification",
|
|
3922
3922
|
"showNotificationDescription": "Show a notification when something goes wrong",
|
|
3923
|
-
"twoFactorMustBeEnabled": "Two-factor authentication (2FA) must be enabled, otherwise your account will be blocked."
|
|
3923
|
+
"twoFactorMustBeEnabled": "Two-factor authentication (2FA) must be enabled, otherwise your account will be blocked.",
|
|
3924
|
+
"twoFactorMustWarning": "You have {0} days left to enable two-factor authentication (2FA), otherwise your account will be blocked (disabled)."
|
|
3924
3925
|
},
|
|
3925
3926
|
"ssoConfiguration": {
|
|
3926
3927
|
"twoFactorPolicy": "Two-factor policy",
|
|
@@ -3920,7 +3920,8 @@
|
|
|
3920
3920
|
"qrcodeDescription": "Սկանավորեք այս QR կոդը ձեր նույնականացման հավելվածով կամ մուտքագրեք այս կոդերից մեկը ձեռքով: Դրանից հետո հաստատեք գործողությունը՝ ներքևում մուտքագրելով միանգամյա կոդը:",
|
|
3921
3921
|
"showNotification": "Ցուցադրել ծանուցում",
|
|
3922
3922
|
"showNotificationDescription": "Ցուցադրել ծանուցում, երբ ինչ-որ բան սխալ է ընթանում",
|
|
3923
|
-
"twoFactorMustBeEnabled": "Անհրաժեշտ է միացնել երկգործոն նույնականացում (2FA), հակառակ դեպքում ձեր հաշիվը կարգելափակվի:"
|
|
3923
|
+
"twoFactorMustBeEnabled": "Անհրաժեշտ է միացնել երկգործոն նույնականացում (2FA), հակառակ դեպքում ձեր հաշիվը կարգելափակվի:",
|
|
3924
|
+
"twoFactorMustWarning": "Ձեր տրամադրված ժամանակը՝ {0} օր է երկգործոն նույնականացումը (2FA) միացնելու համար, հակառակ դեպքում ձեր հաշիվը կարգելափակվի (անջատվելի):"
|
|
3924
3925
|
},
|
|
3925
3926
|
"ssoConfiguration": {
|
|
3926
3927
|
"twoFactorPolicy": "Երկու գործոնի քաղաքականություն",
|
|
@@ -3920,7 +3920,8 @@
|
|
|
3920
3920
|
"qrcodeDescription": "Бұл QR-кодты аутентификатор қолданбасымен сканерлеңіз немесе осы кодтардың бірін қолмен енгізіңіз. Содан кейін әрекетті төмендегі бір реттік кодты енгізу арқылы растаңыз.",
|
|
3921
3921
|
"showNotification": "Хабарландыруды көрсету",
|
|
3922
3922
|
"showNotificationDescription": "Бірдеңе дұрыс емес болған кезде хабарландыруды көрсету",
|
|
3923
|
-
"twoFactorMustBeEnabled": "Екі факторлы аутентификацияны (2FA) қосу қажет, әйтпесе сіздің аккаунтыңыз бұғатталады."
|
|
3923
|
+
"twoFactorMustBeEnabled": "Екі факторлы аутентификацияны (2FA) қосу қажет, әйтпесе сіздің аккаунтыңыз бұғатталады.",
|
|
3924
|
+
"twoFactorMustWarning": "Екі факторлы аутентификацияны (2FA) қосу үшін сізде {0} күн қалды, әйтпесе сіздің аккаунтыңыз бұғатталады (өшіріледі)."
|
|
3924
3925
|
},
|
|
3925
3926
|
"ssoConfiguration": {
|
|
3926
3927
|
"twoFactorPolicy": "Екі факторлы саясат",
|
|
@@ -3917,7 +3917,8 @@
|
|
|
3917
3917
|
"qrcodeDescription": "使用您的身份验证器应用程序扫描此QR码,或手动输入其中一个代码。然后,通过输入下面的一次性代码来确认操作。",
|
|
3918
3918
|
"showNotification": "显示通知",
|
|
3919
3919
|
"showNotificationDescription": "当出现问题时显示通知",
|
|
3920
|
-
"twoFactorMustBeEnabled": "必须启用双因素认证(2FA),否则您的账户将被锁定。"
|
|
3920
|
+
"twoFactorMustBeEnabled": "必须启用双因素认证(2FA),否则您的账户将被锁定。",
|
|
3921
|
+
"twoFactorMustWarning": "您还剩 {0} 天时间来启用双因素认证(2FA),否则您的账户将被锁定(停用)。"
|
|
3921
3922
|
},
|
|
3922
3923
|
"ssoConfiguration": {
|
|
3923
3924
|
"twoFactorPolicy": "双因素策略",
|
|
@@ -1,258 +1,258 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="main-nav">
|
|
3
|
-
<header class="header header-7">
|
|
4
|
-
<div class="header-nav">
|
|
5
|
-
<div class="nav-link">
|
|
6
|
-
<button
|
|
7
|
-
id="inventory-menu-trigger"
|
|
8
|
-
data-id="inventory-menu-toggle-button"
|
|
9
|
-
class="inventory-menu-trigger"
|
|
10
|
-
@click="emits('toggle-main-menu')"
|
|
11
|
-
>
|
|
12
|
-
<span class="inventory-menu-link">
|
|
13
|
-
<span class="nav-icon">
|
|
14
|
-
<atoms-the-icon class="menu-icon" name="menu" />
|
|
15
|
-
</span>
|
|
16
|
-
</span>
|
|
17
|
-
</button>
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
<div class="branding">
|
|
21
|
-
<nuxt-link
|
|
22
|
-
id="header-shortcuts-link"
|
|
23
|
-
data-id="header-shortcuts-link"
|
|
24
|
-
to="/shortcuts"
|
|
25
|
-
>
|
|
26
|
-
<span class="title pointer"
|
|
27
|
-
>{{ props.companyName }}<sup><b>®</b></sup>
|
|
28
|
-
{{ props.projectName }}</span
|
|
29
|
-
>
|
|
30
|
-
</nuxt-link>
|
|
31
|
-
</div>
|
|
32
|
-
<form style="width: 100%; height: 100%" @click="onTemp">
|
|
33
|
-
<atoms-input-search />
|
|
34
|
-
</form>
|
|
35
|
-
|
|
36
|
-
<div class="settings header-actions">
|
|
37
|
-
<div class="divider" />
|
|
38
|
-
<a
|
|
39
|
-
id="global-refresh-button"
|
|
40
|
-
data-id="global-refresh-button"
|
|
41
|
-
class="nav-link tid-global-refresh-button"
|
|
42
|
-
@click="emits('global-refresh')"
|
|
43
|
-
>
|
|
44
|
-
<span class="nav-icon">
|
|
45
|
-
<atoms-the-icon
|
|
46
|
-
v-show="!props.globalRefreshLoading"
|
|
47
|
-
class="reset-icon"
|
|
48
|
-
name="reset"
|
|
49
|
-
/>
|
|
50
|
-
<span
|
|
51
|
-
:class="[
|
|
52
|
-
'spinner spinner-inline spinner-inverse global-refresh-active',
|
|
53
|
-
{ 'spinner-paused': !props.globalRefreshLoading },
|
|
54
|
-
]"
|
|
55
|
-
></span>
|
|
56
|
-
</span>
|
|
57
|
-
</a>
|
|
58
|
-
<div class="divider" />
|
|
59
|
-
|
|
60
|
-
<common-layout-the-header-user-menu
|
|
61
|
-
v-model:security="security"
|
|
62
|
-
v-model:is-show-notification="isShowNotification"
|
|
63
|
-
v-model:new-view-local="newViewLocal"
|
|
64
|
-
v-model:time-format="timeFormat"
|
|
65
|
-
v-model:console-value="consoleValue"
|
|
66
|
-
v-model:vm-in-hosts-clusters="vmInHostsClusters"
|
|
67
|
-
v-model:is-dark-theme="isDarkTheme"
|
|
68
|
-
:hostname="props.hostname"
|
|
69
|
-
:is-preference="props.isPreference"
|
|
70
|
-
:selected-language-type="props.selectedLanguageType"
|
|
71
|
-
:selected-language="props.selectedLang.value"
|
|
72
|
-
:new-view="props.newView"
|
|
73
|
-
:project="props.project"
|
|
74
|
-
:security-loader="props.securityLoader"
|
|
75
|
-
:recovery="props.recovery"
|
|
76
|
-
@show-preference="emits('show-preference')"
|
|
77
|
-
@hide-preference="emits('hide-preference')"
|
|
78
|
-
@update-language="onUpdateLanguage"
|
|
79
|
-
@update-is-browser="emits('update-is-browser', $event)"
|
|
80
|
-
@security-confirm="emits('security-confirm', $event)"
|
|
81
|
-
@submit-preferences="emits('submit-preferences')"
|
|
82
|
-
/>
|
|
83
|
-
|
|
84
|
-
<div class="divider" />
|
|
85
|
-
|
|
86
|
-
<common-layout-the-header-feedback
|
|
87
|
-
:is-show-feedback="isShowFeedback"
|
|
88
|
-
@show="isShowFeedback = true"
|
|
89
|
-
@hide="isShowFeedback = false"
|
|
90
|
-
/>
|
|
91
|
-
|
|
92
|
-
<div class="divider" />
|
|
93
|
-
|
|
94
|
-
<common-layout-the-header-help-menu :project-name="props.projectName" />
|
|
95
|
-
|
|
96
|
-
<div class="divider" />
|
|
97
|
-
</div>
|
|
98
|
-
</header>
|
|
99
|
-
</div>
|
|
100
|
-
</template>
|
|
101
|
-
|
|
102
|
-
<script setup lang="ts">
|
|
103
|
-
import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
|
|
104
|
-
import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
|
|
105
|
-
import type { UI_T_Project } from '~/lib/models/types'
|
|
106
|
-
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
107
|
-
import { findInLocals } from '~/components/common/selectLanguage/lib/utils/utils'
|
|
108
|
-
|
|
109
|
-
const security = defineModel<boolean>('security')
|
|
110
|
-
const isShowNotification = defineModel<boolean>('isShowNotification')
|
|
111
|
-
const newViewLocal = defineModel<boolean>('newViewLocal')
|
|
112
|
-
const timeFormat = defineModel<UI_T_TimeValue>('timeFormat')
|
|
113
|
-
const consoleValue = defineModel<string>('consoleValue')
|
|
114
|
-
const vmInHostsClusters = defineModel<boolean>('vmInHostsClusters')
|
|
115
|
-
const isDarkTheme = defineModel<boolean>('isDarkTheme')
|
|
116
|
-
|
|
117
|
-
const props = defineProps<{
|
|
118
|
-
companyName: string
|
|
119
|
-
betaText: string
|
|
120
|
-
globalRefreshLoading: boolean
|
|
121
|
-
project: UI_T_Project
|
|
122
|
-
projectName: string
|
|
123
|
-
hostname: string
|
|
124
|
-
isPreference: boolean
|
|
125
|
-
selectedLanguageType: string
|
|
126
|
-
selectedLang: UI_I_Dropdown
|
|
127
|
-
newView: boolean
|
|
128
|
-
securityLoader: boolean // для Сферы
|
|
129
|
-
recovery: UI_I_Recovery | null // для Сферы
|
|
130
|
-
}>()
|
|
131
|
-
|
|
132
|
-
const emits = defineEmits<{
|
|
133
|
-
(event: 'toggle-main-menu'): void
|
|
134
|
-
(event: 'global-refresh'): void
|
|
135
|
-
(event: 'show-preference'): void
|
|
136
|
-
(event: 'hide-preference'): void
|
|
137
|
-
(event: 'update-language', value: UI_I_Dropdown): void
|
|
138
|
-
(event: 'update-is-browser', value: string): void
|
|
139
|
-
(event: 'security-confirm', value: boolean): void
|
|
140
|
-
(event: 'submit-preferences'): void
|
|
141
|
-
}>()
|
|
142
|
-
|
|
143
|
-
const onUpdateLanguage = (language: string): void => {
|
|
144
|
-
const languageObj = findInLocals(language)
|
|
145
|
-
emits('update-language', languageObj)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const isShowFeedback = ref<boolean>(false)
|
|
149
|
-
|
|
150
|
-
const onTemp = (): void => {
|
|
151
|
-
useLocalStorage('temp', true)
|
|
152
|
-
}
|
|
153
|
-
</script>
|
|
154
|
-
|
|
155
|
-
<style scoped lang="scss">
|
|
156
|
-
.main-nav {
|
|
157
|
-
position: relative;
|
|
158
|
-
left: 0;
|
|
159
|
-
|
|
160
|
-
header {
|
|
161
|
-
height: 62px;
|
|
162
|
-
align-items: center;
|
|
163
|
-
padding-left: 0;
|
|
164
|
-
|
|
165
|
-
.nav-link::before,
|
|
166
|
-
.nav-link::after {
|
|
167
|
-
display: none !important;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.inventory-menu-trigger {
|
|
171
|
-
padding: 0 0 0 60px;
|
|
172
|
-
background: transparent;
|
|
173
|
-
border: none;
|
|
174
|
-
cursor: pointer;
|
|
175
|
-
position: relative;
|
|
176
|
-
outline: none;
|
|
177
|
-
|
|
178
|
-
.nav-icon {
|
|
179
|
-
padding: 0;
|
|
180
|
-
width: auto;
|
|
181
|
-
font-size: inherit;
|
|
182
|
-
display: flex;
|
|
183
|
-
align-items: center;
|
|
184
|
-
background: transparent;
|
|
185
|
-
border: none;
|
|
186
|
-
|
|
187
|
-
.menu-icon {
|
|
188
|
-
position: absolute;
|
|
189
|
-
top: 50%;
|
|
190
|
-
left: 50%;
|
|
191
|
-
transform: translate(-50%, -50%);
|
|
192
|
-
height: 24px;
|
|
193
|
-
width: 24px;
|
|
194
|
-
fill: #fafafa;
|
|
195
|
-
display: inline-block;
|
|
196
|
-
margin: 0;
|
|
197
|
-
vertical-align: middle;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
.branding {
|
|
203
|
-
width: auto;
|
|
204
|
-
min-width: auto;
|
|
205
|
-
padding-left: 9px;
|
|
206
|
-
padding-right: 20px;
|
|
207
|
-
|
|
208
|
-
a {
|
|
209
|
-
position: relative;
|
|
210
|
-
padding-right: 4px;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.settings {
|
|
215
|
-
align-items: center;
|
|
216
|
-
|
|
217
|
-
a.nav-link {
|
|
218
|
-
display: flex;
|
|
219
|
-
padding: 0;
|
|
220
|
-
cursor: pointer;
|
|
221
|
-
|
|
222
|
-
.reset-icon {
|
|
223
|
-
width: 24px;
|
|
224
|
-
height: 24px;
|
|
225
|
-
position: absolute;
|
|
226
|
-
top: 50%;
|
|
227
|
-
left: 50%;
|
|
228
|
-
transform: translate(-50%, -50%);
|
|
229
|
-
fill: #fafafa;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
.spinner {
|
|
233
|
-
line-height: 24px;
|
|
234
|
-
vertical-align: middle;
|
|
235
|
-
height: 24px;
|
|
236
|
-
width: 24px;
|
|
237
|
-
min-height: 24px;
|
|
238
|
-
min-width: 24px;
|
|
239
|
-
z-index: var(--z-fixed);
|
|
240
|
-
|
|
241
|
-
&.spinner-paused {
|
|
242
|
-
animation-play-state: paused;
|
|
243
|
-
display: none;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
.divider {
|
|
248
|
-
height: 40px;
|
|
249
|
-
display: flex;
|
|
250
|
-
flex: 0 0 auto;
|
|
251
|
-
width: 1px;
|
|
252
|
-
background: #fafafa;
|
|
253
|
-
opacity: 0.15;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="main-nav">
|
|
3
|
+
<header class="header header-7">
|
|
4
|
+
<div class="header-nav">
|
|
5
|
+
<div class="nav-link">
|
|
6
|
+
<button
|
|
7
|
+
id="inventory-menu-trigger"
|
|
8
|
+
data-id="inventory-menu-toggle-button"
|
|
9
|
+
class="inventory-menu-trigger"
|
|
10
|
+
@click="emits('toggle-main-menu')"
|
|
11
|
+
>
|
|
12
|
+
<span class="inventory-menu-link">
|
|
13
|
+
<span class="nav-icon">
|
|
14
|
+
<atoms-the-icon class="menu-icon" name="menu" />
|
|
15
|
+
</span>
|
|
16
|
+
</span>
|
|
17
|
+
</button>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="branding">
|
|
21
|
+
<nuxt-link
|
|
22
|
+
id="header-shortcuts-link"
|
|
23
|
+
data-id="header-shortcuts-link"
|
|
24
|
+
to="/shortcuts"
|
|
25
|
+
>
|
|
26
|
+
<span class="title pointer"
|
|
27
|
+
>{{ props.companyName }}<sup><b>®</b></sup>
|
|
28
|
+
{{ props.projectName }}</span
|
|
29
|
+
>
|
|
30
|
+
</nuxt-link>
|
|
31
|
+
</div>
|
|
32
|
+
<form style="width: 100%; height: 100%" @click="onTemp">
|
|
33
|
+
<atoms-input-search />
|
|
34
|
+
</form>
|
|
35
|
+
|
|
36
|
+
<div class="settings header-actions">
|
|
37
|
+
<div class="divider" />
|
|
38
|
+
<a
|
|
39
|
+
id="global-refresh-button"
|
|
40
|
+
data-id="global-refresh-button"
|
|
41
|
+
class="nav-link tid-global-refresh-button"
|
|
42
|
+
@click="emits('global-refresh')"
|
|
43
|
+
>
|
|
44
|
+
<span class="nav-icon">
|
|
45
|
+
<atoms-the-icon
|
|
46
|
+
v-show="!props.globalRefreshLoading"
|
|
47
|
+
class="reset-icon"
|
|
48
|
+
name="reset"
|
|
49
|
+
/>
|
|
50
|
+
<span
|
|
51
|
+
:class="[
|
|
52
|
+
'spinner spinner-inline spinner-inverse global-refresh-active',
|
|
53
|
+
{ 'spinner-paused': !props.globalRefreshLoading },
|
|
54
|
+
]"
|
|
55
|
+
></span>
|
|
56
|
+
</span>
|
|
57
|
+
</a>
|
|
58
|
+
<div class="divider" />
|
|
59
|
+
|
|
60
|
+
<common-layout-the-header-user-menu
|
|
61
|
+
v-model:security="security"
|
|
62
|
+
v-model:is-show-notification="isShowNotification"
|
|
63
|
+
v-model:new-view-local="newViewLocal"
|
|
64
|
+
v-model:time-format="timeFormat"
|
|
65
|
+
v-model:console-value="consoleValue"
|
|
66
|
+
v-model:vm-in-hosts-clusters="vmInHostsClusters"
|
|
67
|
+
v-model:is-dark-theme="isDarkTheme"
|
|
68
|
+
:hostname="props.hostname"
|
|
69
|
+
:is-preference="props.isPreference"
|
|
70
|
+
:selected-language-type="props.selectedLanguageType"
|
|
71
|
+
:selected-language="props.selectedLang.value"
|
|
72
|
+
:new-view="props.newView"
|
|
73
|
+
:project="props.project"
|
|
74
|
+
:security-loader="props.securityLoader"
|
|
75
|
+
:recovery="props.recovery"
|
|
76
|
+
@show-preference="emits('show-preference')"
|
|
77
|
+
@hide-preference="emits('hide-preference')"
|
|
78
|
+
@update-language="onUpdateLanguage"
|
|
79
|
+
@update-is-browser="emits('update-is-browser', $event)"
|
|
80
|
+
@security-confirm="emits('security-confirm', $event)"
|
|
81
|
+
@submit-preferences="emits('submit-preferences')"
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<div class="divider" />
|
|
85
|
+
|
|
86
|
+
<common-layout-the-header-feedback
|
|
87
|
+
:is-show-feedback="isShowFeedback"
|
|
88
|
+
@show="isShowFeedback = true"
|
|
89
|
+
@hide="isShowFeedback = false"
|
|
90
|
+
/>
|
|
91
|
+
|
|
92
|
+
<div class="divider" />
|
|
93
|
+
|
|
94
|
+
<common-layout-the-header-help-menu :project-name="props.projectName" />
|
|
95
|
+
|
|
96
|
+
<div class="divider" />
|
|
97
|
+
</div>
|
|
98
|
+
</header>
|
|
99
|
+
</div>
|
|
100
|
+
</template>
|
|
101
|
+
|
|
102
|
+
<script setup lang="ts">
|
|
103
|
+
import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
|
|
104
|
+
import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
|
|
105
|
+
import type { UI_T_Project } from '~/lib/models/types'
|
|
106
|
+
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
107
|
+
import { findInLocals } from '~/components/common/selectLanguage/lib/utils/utils'
|
|
108
|
+
|
|
109
|
+
const security = defineModel<boolean>('security')
|
|
110
|
+
const isShowNotification = defineModel<boolean>('isShowNotification')
|
|
111
|
+
const newViewLocal = defineModel<boolean>('newViewLocal')
|
|
112
|
+
const timeFormat = defineModel<UI_T_TimeValue>('timeFormat')
|
|
113
|
+
const consoleValue = defineModel<string>('consoleValue')
|
|
114
|
+
const vmInHostsClusters = defineModel<boolean>('vmInHostsClusters')
|
|
115
|
+
const isDarkTheme = defineModel<boolean>('isDarkTheme')
|
|
116
|
+
|
|
117
|
+
const props = defineProps<{
|
|
118
|
+
companyName: string
|
|
119
|
+
betaText: string
|
|
120
|
+
globalRefreshLoading: boolean
|
|
121
|
+
project: UI_T_Project
|
|
122
|
+
projectName: string
|
|
123
|
+
hostname: string
|
|
124
|
+
isPreference: boolean
|
|
125
|
+
selectedLanguageType: string
|
|
126
|
+
selectedLang: UI_I_Dropdown
|
|
127
|
+
newView: boolean
|
|
128
|
+
securityLoader: boolean // для Сферы
|
|
129
|
+
recovery: UI_I_Recovery | null // для Сферы
|
|
130
|
+
}>()
|
|
131
|
+
|
|
132
|
+
const emits = defineEmits<{
|
|
133
|
+
(event: 'toggle-main-menu'): void
|
|
134
|
+
(event: 'global-refresh'): void
|
|
135
|
+
(event: 'show-preference'): void
|
|
136
|
+
(event: 'hide-preference'): void
|
|
137
|
+
(event: 'update-language', value: UI_I_Dropdown): void
|
|
138
|
+
(event: 'update-is-browser', value: string): void
|
|
139
|
+
(event: 'security-confirm', value: boolean): void
|
|
140
|
+
(event: 'submit-preferences'): void
|
|
141
|
+
}>()
|
|
142
|
+
|
|
143
|
+
const onUpdateLanguage = (language: string): void => {
|
|
144
|
+
const languageObj = findInLocals(language)
|
|
145
|
+
emits('update-language', languageObj)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const isShowFeedback = ref<boolean>(false)
|
|
149
|
+
|
|
150
|
+
const onTemp = (): void => {
|
|
151
|
+
useLocalStorage('temp', true)
|
|
152
|
+
}
|
|
153
|
+
</script>
|
|
154
|
+
|
|
155
|
+
<style scoped lang="scss">
|
|
156
|
+
.main-nav {
|
|
157
|
+
position: relative;
|
|
158
|
+
left: 0;
|
|
159
|
+
|
|
160
|
+
header {
|
|
161
|
+
height: 62px;
|
|
162
|
+
align-items: center;
|
|
163
|
+
padding-left: 0;
|
|
164
|
+
|
|
165
|
+
.nav-link::before,
|
|
166
|
+
.nav-link::after {
|
|
167
|
+
display: none !important;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.inventory-menu-trigger {
|
|
171
|
+
padding: 0 0 0 60px;
|
|
172
|
+
background: transparent;
|
|
173
|
+
border: none;
|
|
174
|
+
cursor: pointer;
|
|
175
|
+
position: relative;
|
|
176
|
+
outline: none;
|
|
177
|
+
|
|
178
|
+
.nav-icon {
|
|
179
|
+
padding: 0;
|
|
180
|
+
width: auto;
|
|
181
|
+
font-size: inherit;
|
|
182
|
+
display: flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
background: transparent;
|
|
185
|
+
border: none;
|
|
186
|
+
|
|
187
|
+
.menu-icon {
|
|
188
|
+
position: absolute;
|
|
189
|
+
top: 50%;
|
|
190
|
+
left: 50%;
|
|
191
|
+
transform: translate(-50%, -50%);
|
|
192
|
+
height: 24px;
|
|
193
|
+
width: 24px;
|
|
194
|
+
fill: #fafafa;
|
|
195
|
+
display: inline-block;
|
|
196
|
+
margin: 0;
|
|
197
|
+
vertical-align: middle;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.branding {
|
|
203
|
+
width: auto;
|
|
204
|
+
min-width: auto;
|
|
205
|
+
padding-left: 9px;
|
|
206
|
+
padding-right: 20px;
|
|
207
|
+
|
|
208
|
+
a {
|
|
209
|
+
position: relative;
|
|
210
|
+
padding-right: 4px;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.settings {
|
|
215
|
+
align-items: center;
|
|
216
|
+
|
|
217
|
+
a.nav-link {
|
|
218
|
+
display: flex;
|
|
219
|
+
padding: 0;
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
|
|
222
|
+
.reset-icon {
|
|
223
|
+
width: 24px;
|
|
224
|
+
height: 24px;
|
|
225
|
+
position: absolute;
|
|
226
|
+
top: 50%;
|
|
227
|
+
left: 50%;
|
|
228
|
+
transform: translate(-50%, -50%);
|
|
229
|
+
fill: #fafafa;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.spinner {
|
|
233
|
+
line-height: 24px;
|
|
234
|
+
vertical-align: middle;
|
|
235
|
+
height: 24px;
|
|
236
|
+
width: 24px;
|
|
237
|
+
min-height: 24px;
|
|
238
|
+
min-width: 24px;
|
|
239
|
+
z-index: var(--z-fixed);
|
|
240
|
+
|
|
241
|
+
&.spinner-paused {
|
|
242
|
+
animation-play-state: paused;
|
|
243
|
+
display: none;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
.divider {
|
|
248
|
+
height: 40px;
|
|
249
|
+
display: flex;
|
|
250
|
+
flex: 0 0 auto;
|
|
251
|
+
width: 1px;
|
|
252
|
+
background: #fafafa;
|
|
253
|
+
opacity: 0.15;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
</style>
|
|
@@ -1,156 +1,156 @@
|
|
|
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
|
-
v-model:time-format="timeFormat"
|
|
21
|
-
:new-view="props.newView"
|
|
22
|
-
/>
|
|
23
|
-
|
|
24
|
-
<common-layout-the-header-user-menu-modals-preferences-change-language
|
|
25
|
-
v-if="selectedTab === 'language-tab'"
|
|
26
|
-
:new-view="props.newView"
|
|
27
|
-
:selected-type="props.selectedLanguageType"
|
|
28
|
-
:selected-language="props.selectedLanguage"
|
|
29
|
-
@update-language="emits('update-language', $event)"
|
|
30
|
-
@update-is-browser="emits('update-is-browser', $event)"
|
|
31
|
-
/>
|
|
32
|
-
|
|
33
|
-
<common-layout-the-header-user-menu-modals-preferences-inventory
|
|
34
|
-
v-if="selectedTab === 'inventory-tab' && isSphere"
|
|
35
|
-
v-model="vmInHostsClusters"
|
|
36
|
-
:new-view="props.newView"
|
|
37
|
-
/>
|
|
38
|
-
|
|
39
|
-
<common-layout-the-header-user-menu-modals-preferences-default-console
|
|
40
|
-
v-if="selectedTab === 'console-tab' && isSphere"
|
|
41
|
-
v-model="consoleValue"
|
|
42
|
-
:new-view="props.newView"
|
|
43
|
-
/>
|
|
44
|
-
|
|
45
|
-
<common-layout-the-header-user-menu-modals-preferences-security
|
|
46
|
-
v-if="selectedTab === 'security-tab'"
|
|
47
|
-
v-model:security="security"
|
|
48
|
-
:recovery="props.recovery"
|
|
49
|
-
:is-on-fa-important="isOn2FaImportant"
|
|
50
|
-
@confirm="emits('security-confirm', $event)"
|
|
51
|
-
/>
|
|
52
|
-
|
|
53
|
-
<common-layout-the-header-user-menu-modals-preferences-view
|
|
54
|
-
v-if="selectedTab === 'view-tab'"
|
|
55
|
-
v-model:new-view-local="newViewLocal"
|
|
56
|
-
v-model:is-show-notification="isShowNotification"
|
|
57
|
-
:new-view="props.newView"
|
|
58
|
-
/>
|
|
59
|
-
</template>
|
|
60
|
-
|
|
61
|
-
<template #modalFooter>
|
|
62
|
-
<button
|
|
63
|
-
id="user-preferences-cancel-button"
|
|
64
|
-
data-id="user-preferences-cancel-button"
|
|
65
|
-
class="btn btn-outline"
|
|
66
|
-
@click="onHide"
|
|
67
|
-
>
|
|
68
|
-
{{ localization.common.cancel }}
|
|
69
|
-
</button>
|
|
70
|
-
<button
|
|
71
|
-
id="user-preferences-apply-button"
|
|
72
|
-
data-id="user-preferences-apply-button"
|
|
73
|
-
class="btn btn-primary"
|
|
74
|
-
@click="onSubmit"
|
|
75
|
-
>
|
|
76
|
-
{{ localization.common.save }}
|
|
77
|
-
</button>
|
|
78
|
-
</template>
|
|
79
|
-
</atoms-modal>
|
|
80
|
-
</template>
|
|
81
|
-
|
|
82
|
-
<script setup lang="ts">
|
|
83
|
-
import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
|
|
84
|
-
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
85
|
-
import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
|
|
86
|
-
import type { UI_T_UserPreferenceTab } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types'
|
|
87
|
-
import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
|
|
88
|
-
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
89
|
-
import { UI_E_TopNotificationActionId } from '~/components/common/layout/topNotification/lib/models/enums'
|
|
90
|
-
import { preferencesTabs } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/config/preferencesTabs'
|
|
91
|
-
|
|
92
|
-
const security = defineModel<boolean>('security')
|
|
93
|
-
const isShowNotification = defineModel<boolean>('isShowNotification')
|
|
94
|
-
const newViewLocal = defineModel<boolean>('newViewLocal')
|
|
95
|
-
const timeFormat = defineModel<UI_T_TimeValue>('timeFormat')
|
|
96
|
-
const consoleValue = defineModel<string>('consoleValue')
|
|
97
|
-
const vmInHostsClusters = defineModel<boolean>('vmInHostsClusters')
|
|
98
|
-
|
|
99
|
-
const props = defineProps<{
|
|
100
|
-
project: UI_T_Project
|
|
101
|
-
selectedLanguage: UI_T_LangValue
|
|
102
|
-
selectedLanguageType: UI_T_LangValue
|
|
103
|
-
newView: boolean
|
|
104
|
-
securityLoader: boolean // для Сферы
|
|
105
|
-
recovery: UI_I_Recovery | null // для Сферы
|
|
106
|
-
}>()
|
|
107
|
-
const emits = defineEmits<{
|
|
108
|
-
(event: 'hide'): void
|
|
109
|
-
(event: 'update-language', value: string): void
|
|
110
|
-
(event: 'update-is-browser', value: string): void
|
|
111
|
-
(event: 'security-confirm', value: boolean): void
|
|
112
|
-
(event: 'submit'): void
|
|
113
|
-
}>()
|
|
114
|
-
|
|
115
|
-
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
116
|
-
|
|
117
|
-
const isLoading = ref<boolean>(false)
|
|
118
|
-
|
|
119
|
-
const isSphere = ref<boolean>(props.project === 'sphere')
|
|
120
|
-
const selectedTab = ref<UI_T_UserPreferenceTab>('time-tab')
|
|
121
|
-
|
|
122
|
-
const tabsItems = computed<UI_I_CollapseNavItem[]>(() =>
|
|
123
|
-
preferencesTabs(localization.value, props.project)
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
const onSubmit = (): void => {
|
|
127
|
-
isLoading.value = true
|
|
128
|
-
emits('submit')
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const onHide = (): void => {
|
|
132
|
-
emits('hide')
|
|
133
|
-
|
|
134
|
-
if (isSphere.value) {
|
|
135
|
-
selectedTab.value = 'time-tab'
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// TODO refactoring
|
|
140
|
-
const { $store }: any = useNuxtApp()
|
|
141
|
-
const topNotifications = computed<number>(
|
|
142
|
-
() => $store.getters['main/getTopNotificationActionId']
|
|
143
|
-
)
|
|
144
|
-
const isOn2FaImportant = ref<boolean>(false)
|
|
145
|
-
watch(
|
|
146
|
-
topNotifications,
|
|
147
|
-
(newValue) => {
|
|
148
|
-
if (newValue === UI_E_TopNotificationActionId.on2Fa || newValue === UI_E_TopNotificationActionId.on2FaImportant) {
|
|
149
|
-
isOn2FaImportant.value = newValue === UI_E_TopNotificationActionId.on2FaImportant
|
|
150
|
-
selectedTab.value = 'security-tab'
|
|
151
|
-
$store.dispatch('main/A_SET_TOP_NOTIFICATION_ACTION_ID', -1)
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
{ immediate: true }
|
|
155
|
-
)
|
|
156
|
-
</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
|
+
v-model:time-format="timeFormat"
|
|
21
|
+
:new-view="props.newView"
|
|
22
|
+
/>
|
|
23
|
+
|
|
24
|
+
<common-layout-the-header-user-menu-modals-preferences-change-language
|
|
25
|
+
v-if="selectedTab === 'language-tab'"
|
|
26
|
+
:new-view="props.newView"
|
|
27
|
+
:selected-type="props.selectedLanguageType"
|
|
28
|
+
:selected-language="props.selectedLanguage"
|
|
29
|
+
@update-language="emits('update-language', $event)"
|
|
30
|
+
@update-is-browser="emits('update-is-browser', $event)"
|
|
31
|
+
/>
|
|
32
|
+
|
|
33
|
+
<common-layout-the-header-user-menu-modals-preferences-inventory
|
|
34
|
+
v-if="selectedTab === 'inventory-tab' && isSphere"
|
|
35
|
+
v-model="vmInHostsClusters"
|
|
36
|
+
:new-view="props.newView"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<common-layout-the-header-user-menu-modals-preferences-default-console
|
|
40
|
+
v-if="selectedTab === 'console-tab' && isSphere"
|
|
41
|
+
v-model="consoleValue"
|
|
42
|
+
:new-view="props.newView"
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
<common-layout-the-header-user-menu-modals-preferences-security
|
|
46
|
+
v-if="selectedTab === 'security-tab'"
|
|
47
|
+
v-model:security="security"
|
|
48
|
+
:recovery="props.recovery"
|
|
49
|
+
:is-on-fa-important="isOn2FaImportant"
|
|
50
|
+
@confirm="emits('security-confirm', $event)"
|
|
51
|
+
/>
|
|
52
|
+
|
|
53
|
+
<common-layout-the-header-user-menu-modals-preferences-view
|
|
54
|
+
v-if="selectedTab === 'view-tab'"
|
|
55
|
+
v-model:new-view-local="newViewLocal"
|
|
56
|
+
v-model:is-show-notification="isShowNotification"
|
|
57
|
+
:new-view="props.newView"
|
|
58
|
+
/>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<template #modalFooter>
|
|
62
|
+
<button
|
|
63
|
+
id="user-preferences-cancel-button"
|
|
64
|
+
data-id="user-preferences-cancel-button"
|
|
65
|
+
class="btn btn-outline"
|
|
66
|
+
@click="onHide"
|
|
67
|
+
>
|
|
68
|
+
{{ localization.common.cancel }}
|
|
69
|
+
</button>
|
|
70
|
+
<button
|
|
71
|
+
id="user-preferences-apply-button"
|
|
72
|
+
data-id="user-preferences-apply-button"
|
|
73
|
+
class="btn btn-primary"
|
|
74
|
+
@click="onSubmit"
|
|
75
|
+
>
|
|
76
|
+
{{ localization.common.save }}
|
|
77
|
+
</button>
|
|
78
|
+
</template>
|
|
79
|
+
</atoms-modal>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<script setup lang="ts">
|
|
83
|
+
import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
|
|
84
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
85
|
+
import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
|
|
86
|
+
import type { UI_T_UserPreferenceTab } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types'
|
|
87
|
+
import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
|
|
88
|
+
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
89
|
+
import { UI_E_TopNotificationActionId } from '~/components/common/layout/topNotification/lib/models/enums'
|
|
90
|
+
import { preferencesTabs } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/config/preferencesTabs'
|
|
91
|
+
|
|
92
|
+
const security = defineModel<boolean>('security')
|
|
93
|
+
const isShowNotification = defineModel<boolean>('isShowNotification')
|
|
94
|
+
const newViewLocal = defineModel<boolean>('newViewLocal')
|
|
95
|
+
const timeFormat = defineModel<UI_T_TimeValue>('timeFormat')
|
|
96
|
+
const consoleValue = defineModel<string>('consoleValue')
|
|
97
|
+
const vmInHostsClusters = defineModel<boolean>('vmInHostsClusters')
|
|
98
|
+
|
|
99
|
+
const props = defineProps<{
|
|
100
|
+
project: UI_T_Project
|
|
101
|
+
selectedLanguage: UI_T_LangValue
|
|
102
|
+
selectedLanguageType: UI_T_LangValue
|
|
103
|
+
newView: boolean
|
|
104
|
+
securityLoader: boolean // для Сферы
|
|
105
|
+
recovery: UI_I_Recovery | null // для Сферы
|
|
106
|
+
}>()
|
|
107
|
+
const emits = defineEmits<{
|
|
108
|
+
(event: 'hide'): void
|
|
109
|
+
(event: 'update-language', value: string): void
|
|
110
|
+
(event: 'update-is-browser', value: string): void
|
|
111
|
+
(event: 'security-confirm', value: boolean): void
|
|
112
|
+
(event: 'submit'): void
|
|
113
|
+
}>()
|
|
114
|
+
|
|
115
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
116
|
+
|
|
117
|
+
const isLoading = ref<boolean>(false)
|
|
118
|
+
|
|
119
|
+
const isSphere = ref<boolean>(props.project === 'sphere')
|
|
120
|
+
const selectedTab = ref<UI_T_UserPreferenceTab>('time-tab')
|
|
121
|
+
|
|
122
|
+
const tabsItems = computed<UI_I_CollapseNavItem[]>(() =>
|
|
123
|
+
preferencesTabs(localization.value, props.project)
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
const onSubmit = (): void => {
|
|
127
|
+
isLoading.value = true
|
|
128
|
+
emits('submit')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const onHide = (): void => {
|
|
132
|
+
emits('hide')
|
|
133
|
+
|
|
134
|
+
if (isSphere.value) {
|
|
135
|
+
selectedTab.value = 'time-tab'
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// TODO refactoring
|
|
140
|
+
const { $store }: any = useNuxtApp()
|
|
141
|
+
const topNotifications = computed<number>(
|
|
142
|
+
() => $store.getters['main/getTopNotificationActionId']
|
|
143
|
+
)
|
|
144
|
+
const isOn2FaImportant = ref<boolean>(false)
|
|
145
|
+
watch(
|
|
146
|
+
topNotifications,
|
|
147
|
+
(newValue) => {
|
|
148
|
+
if (newValue === UI_E_TopNotificationActionId.on2Fa || newValue === UI_E_TopNotificationActionId.on2FaImportant) {
|
|
149
|
+
isOn2FaImportant.value = newValue === UI_E_TopNotificationActionId.on2FaImportant
|
|
150
|
+
selectedTab.value = 'security-tab'
|
|
151
|
+
$store.dispatch('main/A_SET_TOP_NOTIFICATION_ACTION_ID', -1)
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{ immediate: true }
|
|
155
|
+
)
|
|
156
|
+
</script>
|
|
@@ -1,196 +1,196 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<form id="security-form" class="compact" @submit.prevent>
|
|
3
|
-
<!-- TODO new view-->
|
|
4
|
-
<div v-if="props.isOnFaImportant">
|
|
5
|
-
<atoms-alert
|
|
6
|
-
:hide-close-icon="true"
|
|
7
|
-
:items="[localization.myPreferences.twoFactorMustBeEnabled]"
|
|
8
|
-
status="alert-warning"
|
|
9
|
-
class="mb-1"
|
|
10
|
-
test-id="on-2-fa-alert"
|
|
11
|
-
/>
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
<div class="description">
|
|
15
|
-
{{ localization.myPreferences.twoFactorAuthentication }}
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<div class="flex-align-center">
|
|
19
|
-
<label for="security">{{
|
|
20
|
-
localization.myPreferences.securityLabel
|
|
21
|
-
}}</label>
|
|
22
|
-
<input id="security" v-model="security" type="checkbox" class="switch" />
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<div
|
|
26
|
-
v-if="
|
|
27
|
-
props.recovery &&
|
|
28
|
-
security &&
|
|
29
|
-
!props.initialSecurity &&
|
|
30
|
-
!props.otpEnabledSuccess
|
|
31
|
-
"
|
|
32
|
-
class="recovery-codes-wrap"
|
|
33
|
-
>
|
|
34
|
-
<p>
|
|
35
|
-
{{ localization.myPreferences.enterOtpForEnabled }}
|
|
36
|
-
</p>
|
|
37
|
-
|
|
38
|
-
<div class="recovery-codes">
|
|
39
|
-
<common-qr :qr-code-url="props.recovery.qr_code_url" />
|
|
40
|
-
|
|
41
|
-
<span>{{ localization.common.or }}</span>
|
|
42
|
-
|
|
43
|
-
<ul class="recovery-codes-list">
|
|
44
|
-
<li
|
|
45
|
-
v-for="item in props.recovery.recovery_codes"
|
|
46
|
-
:key="item"
|
|
47
|
-
class="recovery-codes-list-item"
|
|
48
|
-
>
|
|
49
|
-
{{ item }}
|
|
50
|
-
</li>
|
|
51
|
-
</ul>
|
|
52
|
-
</div>
|
|
53
|
-
<section class="form-block">
|
|
54
|
-
<div class="form-group">
|
|
55
|
-
<label for="otp">{{
|
|
56
|
-
localization.myPreferences.enterOtpForEnabled
|
|
57
|
-
}}</label>
|
|
58
|
-
<input id="otp" v-model="otp" type="text" />
|
|
59
|
-
<button class="btn btn-sm btn-primary" @click="emits('confirm')">
|
|
60
|
-
{{ localization.common.confirm }}
|
|
61
|
-
</button>
|
|
62
|
-
<atoms-loader
|
|
63
|
-
v-if="props.isOtpLoading"
|
|
64
|
-
test-id="2fa-enabled-loader"
|
|
65
|
-
/>
|
|
66
|
-
</div>
|
|
67
|
-
</section>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<div v-if="!security && props.initialSecurity && !props.otpDisabledSuccess">
|
|
71
|
-
<section class="form-block">
|
|
72
|
-
<div class="form-group">
|
|
73
|
-
<label for="otp">{{
|
|
74
|
-
localization.myPreferences.enterOtpForDisabled
|
|
75
|
-
}}</label>
|
|
76
|
-
<input id="otp" v-model="otp" type="text" />
|
|
77
|
-
<button class="btn btn-sm btn-primary" @click="emits('disabled')">
|
|
78
|
-
{{ localization.common.confirm }}
|
|
79
|
-
</button>
|
|
80
|
-
<atoms-loader
|
|
81
|
-
v-if="props.isOtpLoading"
|
|
82
|
-
test-id="2fa-disabled-loader"
|
|
83
|
-
/>
|
|
84
|
-
</div>
|
|
85
|
-
</section>
|
|
86
|
-
</div>
|
|
87
|
-
</form>
|
|
88
|
-
</template>
|
|
89
|
-
|
|
90
|
-
<script setup lang="ts">
|
|
91
|
-
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
92
|
-
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
93
|
-
|
|
94
|
-
const security = defineModel<boolean>('security')
|
|
95
|
-
const otp = defineModel<string>('otp')
|
|
96
|
-
|
|
97
|
-
const props = defineProps<{
|
|
98
|
-
initialSecurity: boolean
|
|
99
|
-
isOtpLoading: boolean
|
|
100
|
-
otpEnabledSuccess: boolean
|
|
101
|
-
otpDisabledSuccess: boolean
|
|
102
|
-
recovery: UI_I_Recovery | null
|
|
103
|
-
isOnFaImportant: boolean
|
|
104
|
-
}>()
|
|
105
|
-
const emits = defineEmits<{
|
|
106
|
-
(event: 'confirm'): void
|
|
107
|
-
(event: 'disabled'): void
|
|
108
|
-
}>()
|
|
109
|
-
|
|
110
|
-
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
111
|
-
</script>
|
|
112
|
-
|
|
113
|
-
<style lang="scss" scoped>
|
|
114
|
-
.description {
|
|
115
|
-
margin-bottom: 10px;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.recovery-codes-wrap {
|
|
119
|
-
margin: 10px 0;
|
|
120
|
-
|
|
121
|
-
.recovery-codes {
|
|
122
|
-
display: flex;
|
|
123
|
-
align-items: center;
|
|
124
|
-
justify-content: space-evenly;
|
|
125
|
-
|
|
126
|
-
.recovery-codes-list-item {
|
|
127
|
-
font-size: 12px;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
label {
|
|
133
|
-
margin-right: 6px;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// TODO повторяется в ../view, необходимо вынести глобально
|
|
137
|
-
input[type='checkbox'] {
|
|
138
|
-
--active: var(--checkbox-value-active-color);
|
|
139
|
-
--active-inner: var(--checkbox-mark-color);
|
|
140
|
-
--border: var(--checkbox-mark-color);
|
|
141
|
-
--background: var(--checkbox-mark-background-color);
|
|
142
|
-
-webkit-appearance: none;
|
|
143
|
-
-moz-appearance: none;
|
|
144
|
-
height: 20px;
|
|
145
|
-
outline: none;
|
|
146
|
-
display: inline-block;
|
|
147
|
-
vertical-align: top;
|
|
148
|
-
position: relative;
|
|
149
|
-
margin: 0;
|
|
150
|
-
cursor: pointer;
|
|
151
|
-
border: 1px solid var(--bc, var(--border));
|
|
152
|
-
background: var(--b, var(--background));
|
|
153
|
-
transition: background 0.3s, border-color 0.3s, box-shadow 0.2s;
|
|
154
|
-
&:after {
|
|
155
|
-
content: '';
|
|
156
|
-
display: block;
|
|
157
|
-
left: 0;
|
|
158
|
-
top: 0;
|
|
159
|
-
position: absolute;
|
|
160
|
-
transition: transform var(--d-t, 0.3s) var(--d-t-e, ease),
|
|
161
|
-
opacity var(--d-o, 0.2s);
|
|
162
|
-
}
|
|
163
|
-
&:checked {
|
|
164
|
-
--b: var(--active);
|
|
165
|
-
--bc: var(--active);
|
|
166
|
-
--d-o: 0.3s;
|
|
167
|
-
--d-t: 0.6s;
|
|
168
|
-
--d-t-e: cubic-bezier(0.2, 0.85, 0.32, 1.2);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
input[type='checkbox'] {
|
|
172
|
-
&.switch {
|
|
173
|
-
width: 35px;
|
|
174
|
-
border-radius: 11px;
|
|
175
|
-
&:after {
|
|
176
|
-
left: 2px;
|
|
177
|
-
top: 2px;
|
|
178
|
-
bottom: 2px;
|
|
179
|
-
border-radius: 50%;
|
|
180
|
-
width: 14px;
|
|
181
|
-
height: 14px;
|
|
182
|
-
border: 1px solid var(--bc, var(--border));
|
|
183
|
-
background: var(--ab, var(--border));
|
|
184
|
-
transform: translateX(var(--x, 0));
|
|
185
|
-
}
|
|
186
|
-
&:checked {
|
|
187
|
-
--ab: var(--active-inner);
|
|
188
|
-
--x: 14px;
|
|
189
|
-
}
|
|
190
|
-
&:disabled {
|
|
191
|
-
cursor: not-allowed;
|
|
192
|
-
opacity: 0.5;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<form id="security-form" class="compact" @submit.prevent>
|
|
3
|
+
<!-- TODO new view-->
|
|
4
|
+
<div v-if="props.isOnFaImportant">
|
|
5
|
+
<atoms-alert
|
|
6
|
+
:hide-close-icon="true"
|
|
7
|
+
:items="[localization.myPreferences.twoFactorMustBeEnabled]"
|
|
8
|
+
status="alert-warning"
|
|
9
|
+
class="mb-1"
|
|
10
|
+
test-id="on-2-fa-alert"
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="description">
|
|
15
|
+
{{ localization.myPreferences.twoFactorAuthentication }}
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="flex-align-center">
|
|
19
|
+
<label for="security">{{
|
|
20
|
+
localization.myPreferences.securityLabel
|
|
21
|
+
}}</label>
|
|
22
|
+
<input id="security" v-model="security" type="checkbox" class="switch" />
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
v-if="
|
|
27
|
+
props.recovery &&
|
|
28
|
+
security &&
|
|
29
|
+
!props.initialSecurity &&
|
|
30
|
+
!props.otpEnabledSuccess
|
|
31
|
+
"
|
|
32
|
+
class="recovery-codes-wrap"
|
|
33
|
+
>
|
|
34
|
+
<p>
|
|
35
|
+
{{ localization.myPreferences.enterOtpForEnabled }}
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<div class="recovery-codes">
|
|
39
|
+
<common-qr :qr-code-url="props.recovery.qr_code_url" />
|
|
40
|
+
|
|
41
|
+
<span>{{ localization.common.or }}</span>
|
|
42
|
+
|
|
43
|
+
<ul class="recovery-codes-list">
|
|
44
|
+
<li
|
|
45
|
+
v-for="item in props.recovery.recovery_codes"
|
|
46
|
+
:key="item"
|
|
47
|
+
class="recovery-codes-list-item"
|
|
48
|
+
>
|
|
49
|
+
{{ item }}
|
|
50
|
+
</li>
|
|
51
|
+
</ul>
|
|
52
|
+
</div>
|
|
53
|
+
<section class="form-block">
|
|
54
|
+
<div class="form-group">
|
|
55
|
+
<label for="otp">{{
|
|
56
|
+
localization.myPreferences.enterOtpForEnabled
|
|
57
|
+
}}</label>
|
|
58
|
+
<input id="otp" v-model="otp" type="text" />
|
|
59
|
+
<button class="btn btn-sm btn-primary" @click="emits('confirm')">
|
|
60
|
+
{{ localization.common.confirm }}
|
|
61
|
+
</button>
|
|
62
|
+
<atoms-loader
|
|
63
|
+
v-if="props.isOtpLoading"
|
|
64
|
+
test-id="2fa-enabled-loader"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
</section>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div v-if="!security && props.initialSecurity && !props.otpDisabledSuccess">
|
|
71
|
+
<section class="form-block">
|
|
72
|
+
<div class="form-group">
|
|
73
|
+
<label for="otp">{{
|
|
74
|
+
localization.myPreferences.enterOtpForDisabled
|
|
75
|
+
}}</label>
|
|
76
|
+
<input id="otp" v-model="otp" type="text" />
|
|
77
|
+
<button class="btn btn-sm btn-primary" @click="emits('disabled')">
|
|
78
|
+
{{ localization.common.confirm }}
|
|
79
|
+
</button>
|
|
80
|
+
<atoms-loader
|
|
81
|
+
v-if="props.isOtpLoading"
|
|
82
|
+
test-id="2fa-disabled-loader"
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
</section>
|
|
86
|
+
</div>
|
|
87
|
+
</form>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<script setup lang="ts">
|
|
91
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
92
|
+
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
93
|
+
|
|
94
|
+
const security = defineModel<boolean>('security')
|
|
95
|
+
const otp = defineModel<string>('otp')
|
|
96
|
+
|
|
97
|
+
const props = defineProps<{
|
|
98
|
+
initialSecurity: boolean
|
|
99
|
+
isOtpLoading: boolean
|
|
100
|
+
otpEnabledSuccess: boolean
|
|
101
|
+
otpDisabledSuccess: boolean
|
|
102
|
+
recovery: UI_I_Recovery | null
|
|
103
|
+
isOnFaImportant: boolean
|
|
104
|
+
}>()
|
|
105
|
+
const emits = defineEmits<{
|
|
106
|
+
(event: 'confirm'): void
|
|
107
|
+
(event: 'disabled'): void
|
|
108
|
+
}>()
|
|
109
|
+
|
|
110
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
111
|
+
</script>
|
|
112
|
+
|
|
113
|
+
<style lang="scss" scoped>
|
|
114
|
+
.description {
|
|
115
|
+
margin-bottom: 10px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.recovery-codes-wrap {
|
|
119
|
+
margin: 10px 0;
|
|
120
|
+
|
|
121
|
+
.recovery-codes {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
justify-content: space-evenly;
|
|
125
|
+
|
|
126
|
+
.recovery-codes-list-item {
|
|
127
|
+
font-size: 12px;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
label {
|
|
133
|
+
margin-right: 6px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// TODO повторяется в ../view, необходимо вынести глобально
|
|
137
|
+
input[type='checkbox'] {
|
|
138
|
+
--active: var(--checkbox-value-active-color);
|
|
139
|
+
--active-inner: var(--checkbox-mark-color);
|
|
140
|
+
--border: var(--checkbox-mark-color);
|
|
141
|
+
--background: var(--checkbox-mark-background-color);
|
|
142
|
+
-webkit-appearance: none;
|
|
143
|
+
-moz-appearance: none;
|
|
144
|
+
height: 20px;
|
|
145
|
+
outline: none;
|
|
146
|
+
display: inline-block;
|
|
147
|
+
vertical-align: top;
|
|
148
|
+
position: relative;
|
|
149
|
+
margin: 0;
|
|
150
|
+
cursor: pointer;
|
|
151
|
+
border: 1px solid var(--bc, var(--border));
|
|
152
|
+
background: var(--b, var(--background));
|
|
153
|
+
transition: background 0.3s, border-color 0.3s, box-shadow 0.2s;
|
|
154
|
+
&:after {
|
|
155
|
+
content: '';
|
|
156
|
+
display: block;
|
|
157
|
+
left: 0;
|
|
158
|
+
top: 0;
|
|
159
|
+
position: absolute;
|
|
160
|
+
transition: transform var(--d-t, 0.3s) var(--d-t-e, ease),
|
|
161
|
+
opacity var(--d-o, 0.2s);
|
|
162
|
+
}
|
|
163
|
+
&:checked {
|
|
164
|
+
--b: var(--active);
|
|
165
|
+
--bc: var(--active);
|
|
166
|
+
--d-o: 0.3s;
|
|
167
|
+
--d-t: 0.6s;
|
|
168
|
+
--d-t-e: cubic-bezier(0.2, 0.85, 0.32, 1.2);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
input[type='checkbox'] {
|
|
172
|
+
&.switch {
|
|
173
|
+
width: 35px;
|
|
174
|
+
border-radius: 11px;
|
|
175
|
+
&:after {
|
|
176
|
+
left: 2px;
|
|
177
|
+
top: 2px;
|
|
178
|
+
bottom: 2px;
|
|
179
|
+
border-radius: 50%;
|
|
180
|
+
width: 14px;
|
|
181
|
+
height: 14px;
|
|
182
|
+
border: 1px solid var(--bc, var(--border));
|
|
183
|
+
background: var(--ab, var(--border));
|
|
184
|
+
transform: translateX(var(--x, 0));
|
|
185
|
+
}
|
|
186
|
+
&:checked {
|
|
187
|
+
--ab: var(--active-inner);
|
|
188
|
+
--x: 14px;
|
|
189
|
+
}
|
|
190
|
+
&:disabled {
|
|
191
|
+
cursor: not-allowed;
|
|
192
|
+
opacity: 0.5;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
</style>
|