bfg-common 1.5.655 → 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 (25) hide show
  1. package/assets/localization/local_be.json +24 -1
  2. package/assets/localization/local_en.json +24 -1
  3. package/assets/localization/local_hy.json +24 -1
  4. package/assets/localization/local_kk.json +24 -1
  5. package/assets/localization/local_ru.json +24 -1
  6. package/assets/localization/local_zh.json +24 -1
  7. package/components/common/layout/theHeader/TheHeader.vue +38 -26
  8. package/components/common/layout/theHeader/TheHeaderNew.vue +8 -3
  9. package/components/common/layout/theHeader/TheHeaderOld.vue +8 -3
  10. package/components/common/layout/theHeader/userMenu/UserMenu.vue +8 -3
  11. package/components/common/layout/theHeader/userMenu/modals/preferences/Preferences.vue +10 -4
  12. package/components/common/layout/theHeader/userMenu/modals/preferences/PreferencesOld.vue +144 -141
  13. package/components/common/layout/theHeader/userMenu/modals/preferences/security/Old.vue +110 -20
  14. package/components/common/layout/theHeader/userMenu/modals/preferences/security/Security.vue +10 -2
  15. package/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces.ts +4 -0
  16. package/components/common/pages/backups/modals/createBackup/datastores/tableView/old/lib/config/table.ts +12 -0
  17. package/components/common/pages/backups/modals/createBackup/disks/tableView/old/lib/config/table.ts +9 -0
  18. package/components/common/pages/backups/modals/restore/disks/tableView/old/lib/config/table.ts +9 -0
  19. package/components/common/pages/licensing/listView/ListView.vue +13 -5
  20. package/components/common/pages/licensing/modals/assign/tableView/TableView.vue +3 -5
  21. package/components/common/pages/scheduledTasks/table/lib/config/scheduledTasksTable.ts +6 -0
  22. package/components/common/qrcode/Qrcode.vue +56 -0
  23. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +1 -1
  24. package/lib/models/interfaces.ts +1 -0
  25. package/package.json +3 -2
@@ -3741,6 +3741,29 @@
3741
3741
  },
3742
3742
  "myPreferences": {
3743
3743
  "twoFactorAuthentication": "Двухфактарная аўтэнтыфікацыя",
3744
- "securityLabel": "Дадайце дадатковы ўзровень бяпекі да вашага акаўнта"
3744
+ "securityLabel": "Дадайце дадатковы ўзровень бяпекі да вашага акаўнта",
3745
+ "enterOtpForDisabled": "Увядзіце 6-значны код і пацвердзіце, каб адключыць:",
3746
+ "enterOtpForEnabled": "Увядзіце 6-значны код і пацвердзіце:",
3747
+ "qrcodeDescription": "Скануйце гэты QR-код з дапамогай праграмы-аўтэнтыфікатара альбо ўвядзіце адзін з гэтых кодаў уручную. Пасля гэтага пацвердзіце дзеянне, увёўшы аднаразовы код ніжэй."
3748
+ },
3749
+ "ssoConfiguration": {
3750
+ "twoFactorPolicy": "Палітыка двухфактарнай аўтэнтыфікацыі",
3751
+ "twoFactorGracePeriodDays": "Дні льготнага перыяду для двухфактарнай аўтэнтыфікацыі",
3752
+ "maxIdenticalAdjacentCharacters": "Макс. колькасць аднолькавых суседніх сімвалаў",
3753
+ "maxLength": "Макс. даўжыня",
3754
+ "minLength": "Мін. даўжыня",
3755
+ "minAlphabeticCount": "Мін. колькасць літар",
3756
+ "minLowerCaseCount": "Мін. колькасць малых літар",
3757
+ "minUpperCaseCount": "Мін. колькасць вялікіх літар",
3758
+ "minNumericCount": "Мін. колькасць лічбаў",
3759
+ "minSpecialCharCount": "Мін. колькасць спецыяльных сімвалаў",
3760
+ "passwordLifeTimeDays": "Тэрмін дзеяння пароля ў днях",
3761
+ "prohibitedPreviousPasswordCount": "Колькасць забароненых папярэдніх пароляў",
3762
+ "maxFailedAttempts": "Максімальная колькасць няўдалых спроб",
3763
+ "failedAttemptIntervalSec": "Інтэрвал паміж няўдалымі спробамі (сек)",
3764
+ "autoUnlockIntervalSec": "Інтэрвал аўтаматычнай разблакіроўкі (сек)",
3765
+ "maxDurationSec": "Максімальная працягласць (сек)",
3766
+ "idleTimeoutSec": "Час бездзейнасці (сек)",
3767
+ "maxConcurrentSessions": "Макс. колькасць адначасовых сесій"
3745
3768
  }
3746
3769
  }
@@ -3745,6 +3745,29 @@
3745
3745
  },
3746
3746
  "myPreferences": {
3747
3747
  "twoFactorAuthentication": "Two-Factor Authentication",
3748
- "securityLabel": "Add an extra layer of security to your account"
3748
+ "securityLabel": "Add an extra layer of security to your account",
3749
+ "enterOtpForDisabled": "Enter the 6-digit code and confirm to disable it:",
3750
+ "enterOtpForEnabled": "Enter the 6-digit code and confirm:",
3751
+ "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."
3752
+ },
3753
+ "ssoConfiguration": {
3754
+ "twoFactorPolicy": "Two-factor policy",
3755
+ "twoFactorGracePeriodDays": "Two factor grace period days",
3756
+ "maxIdenticalAdjacentCharacters": "Max identical adjacent characters",
3757
+ "maxLength": "Max length",
3758
+ "minLength": "Min length",
3759
+ "minAlphabeticCount": "Min alphabetic count",
3760
+ "minLowerCaseCount": "Min lower case count",
3761
+ "minUpperCaseCount": "Min upper case count",
3762
+ "minNumericCount": "Min numeric count",
3763
+ "minSpecialCharCount": "Min special character count",
3764
+ "passwordLifeTimeDays": "Password life time days",
3765
+ "prohibitedPreviousPasswordCount": "Prohibited previous password count",
3766
+ "maxFailedAttempts": "Max failed attempts",
3767
+ "failedAttemptIntervalSec": "Failed attempt interval sec",
3768
+ "autoUnlockIntervalSec": "Auto unlock interval sec",
3769
+ "maxDurationSec": "Max duration sec",
3770
+ "idleTimeoutSec": "Idle timeout sec",
3771
+ "maxConcurrentSessions": "Max concurrent sessions"
3749
3772
  }
3750
3773
  }
@@ -3745,6 +3745,29 @@
3745
3745
  },
3746
3746
  "myPreferences": {
3747
3747
  "twoFactorAuthentication": "Երկգործոն նույնականացում",
3748
- "securityLabel": "Ավելացրեք հաշվին անվտանգության լրացուցիչ շերտ"
3748
+ "securityLabel": "Ավելացրեք հաշվին անվտանգության լրացուցիչ շերտ",
3749
+ "enterOtpForDisabled": "Մուտքագրեք 6 նիշի կոդը և հաստատեք անջատելու համար.",
3750
+ "enterOtpForEnabled": "Մուտքագրեք 6 նիշի կոդը և հաստատեք.",
3751
+ "qrcodeDescription": "Սկանավորեք այս QR կոդը ձեր նույնականացման հավելվածով կամ մուտքագրեք այս կոդերից մեկը ձեռքով: Դրանից հետո հաստատեք գործողությունը՝ ներքևում մուտքագրելով միանգամյա կոդը:"
3752
+ },
3753
+ "ssoConfiguration": {
3754
+ "twoFactorPolicy": "Երկու գործոնի քաղաքականություն",
3755
+ "twoFactorGracePeriodDays": "Երկու գործոնի արտոնյալ ժամանակահատվածի օրերը",
3756
+ "maxIdenticalAdjacentCharacters": "Առավելագույն նույնական հաջորդական նիշեր",
3757
+ "maxLength": "Առավելագույն երկարություն",
3758
+ "minLength": "Նվազագույն երկարություն",
3759
+ "minAlphabeticCount": "Նվազագույն տառերի քանակ",
3760
+ "minLowerCaseCount": "Նվազագույն փոքրատառերի քանակ",
3761
+ "minUpperCaseCount": "Նվազագույն մեծատառերի քանակ",
3762
+ "minNumericCount": "Նվազագույն թվանշանների քանակ",
3763
+ "minSpecialCharCount": "Նվազագույն հատուկ նշանների քանակ",
3764
+ "passwordLifeTimeDays": "Գաղտնաբառի ժամկետը օրերով",
3765
+ "prohibitedPreviousPasswordCount": "Անթույլատրելի նախորդ գաղտնաբառերի քանակ",
3766
+ "maxFailedAttempts": "Ավտոմատ չհաջողված փորձերի առավելագույն թիվ",
3767
+ "failedAttemptIntervalSec": "Ասֆալտ չհաջողված փորձերի ինտերվալ (վայրկյան)",
3768
+ "autoUnlockIntervalSec": "Ավտոմատ ապակողպման ինտերվալ (վայրկյան)",
3769
+ "maxDurationSec": "Առավելագույն տևողություն (վայրկյան)",
3770
+ "idleTimeoutSec": "Անգործության ժամանակավոր պատուհան (վայրկյան)",
3771
+ "maxConcurrentSessions": "Առավելագույն համաժամանակյա սեսիաներ"
3749
3772
  }
3750
3773
  }
@@ -3744,6 +3744,29 @@
3744
3744
  },
3745
3745
  "myPreferences": {
3746
3746
  "twoFactorAuthentication": "Екі факторлы аутентификация",
3747
- "securityLabel": "Аккаунтыңызға қауіпсіздіктің қосымша қабатын қосыңыз"
3747
+ "securityLabel": "Аккаунтыңызға қауіпсіздіктің қосымша қабатын қосыңыз",
3748
+ "enterOtpForDisabled": "Өшіру үшін 6 таңбалы кодты енгізіп, растаңыз:",
3749
+ "enterOtpForEnabled": "6 таңбалы кодты енгізіп, растаңыз:",
3750
+ "qrcodeDescription": "Бұл QR-кодты аутентификатор қолданбасымен сканерлеңіз немесе осы кодтардың бірін қолмен енгізіңіз. Содан кейін әрекетті төмендегі бір реттік кодты енгізу арқылы растаңыз."
3751
+ },
3752
+ "ssoConfiguration": {
3753
+ "twoFactorPolicy": "Екі факторлы саясат",
3754
+ "twoFactorGracePeriodDays": "Екі факторлы жеңілдік мерзімінің күндері",
3755
+ "maxIdenticalAdjacentCharacters": "Қатар тұрған бірдей таңбалардың макс. саны",
3756
+ "maxLength": "Максималды ұзындық",
3757
+ "minLength": "Минималды ұзындық",
3758
+ "minAlphabeticCount": "Әріптердің мин. саны",
3759
+ "minLowerCaseCount": "Кіші әріптердің мин. саны",
3760
+ "minUpperCaseCount": "Бас әріптердің мин. саны",
3761
+ "minNumericCount": "Сандық таңбалардың мин. саны",
3762
+ "minSpecialCharCount": "Арнайы таңбалардың мин. саны",
3763
+ "passwordLifeTimeDays": "Құпия сөздің жарамдылық мерзімі (күнмен)",
3764
+ "prohibitedPreviousPasswordCount": "Алдыңғы парольдерді қолдануға тыйым салынған сан",
3765
+ "maxFailedAttempts": "Максималды сәтсіз әрекеттер саны",
3766
+ "failedAttemptIntervalSec": "Сәтсіз әрекеттер арасындағы интервал (сек)",
3767
+ "autoUnlockIntervalSec": "Автоматты ашу аралығы (сек)",
3768
+ "maxDurationSec": "Максималды ұзақтық (сек)",
3769
+ "idleTimeoutSec": "Босқа тұрған уақыт (сек)",
3770
+ "maxConcurrentSessions": "Максималды бір уақытта қосылған сессиялар"
3748
3771
  }
3749
3772
  }
@@ -3744,6 +3744,29 @@
3744
3744
  },
3745
3745
  "myPreferences": {
3746
3746
  "twoFactorAuthentication": "Двухфакторная аутентификация",
3747
- "securityLabel": "Добавьте дополнительный уровень защиты к вашему аккаунту"
3747
+ "securityLabel": "Добавьте дополнительный уровень защиты к вашему аккаунту",
3748
+ "enterOtpForDisabled": "Введите 6-значный код и подтвердите, чтобы отключить:",
3749
+ "enterOtpForEnabled": "Введите 6-значный код и подтвердите:",
3750
+ "qrcodeDescription": "Отсканируйте этот QR-код с помощью приложения-аутентификатора или введите один из этих кодов вручную. После этого подтвердите действие, введя одноразовый код ниже."
3751
+ },
3752
+ "ssoConfiguration": {
3753
+ "twoFactorPolicy": "Политика двухфакторной аутентификации",
3754
+ "twoFactorGracePeriodDays": "Дни льготного периода для двухфакторной аутентификации",
3755
+ "maxIdenticalAdjacentCharacters": "Макс. количество одинаковых соседних символов",
3756
+ "maxLength": "Максимальная длина",
3757
+ "minLength": "Минимальная длина",
3758
+ "minAlphabeticCount": "Мин. количество букв",
3759
+ "minLowerCaseCount": "Мин. количество строчных букв",
3760
+ "minUpperCaseCount": "Мин. количество прописных букв",
3761
+ "minNumericCount": "Мин. количество цифр",
3762
+ "minSpecialCharCount": "Мин. количество специальных символов",
3763
+ "passwordLifeTimeDays": "Срок действия пароля в днях",
3764
+ "prohibitedPreviousPasswordCount": "Количество запрещённых предыдущих паролей",
3765
+ "maxFailedAttempts": "Макс. количество неудачных попыток",
3766
+ "failedAttemptIntervalSec": "Интервал между неудачными попытками (сек)",
3767
+ "autoUnlockIntervalSec": "Интервал авторазблокировки (сек)",
3768
+ "maxDurationSec": "Максимальная продолжительность (сек)",
3769
+ "idleTimeoutSec": "Время простоя (сек)",
3770
+ "maxConcurrentSessions": "Макс. количество одновременных сессий"
3748
3771
  }
3749
3772
  }
@@ -3742,6 +3742,29 @@
3742
3742
  },
3743
3743
  "myPreferences": {
3744
3744
  "twoFactorAuthentication": "双因素认证",
3745
- "securityLabel": "为您的账户添加额外的安全层"
3745
+ "securityLabel": "为您的账户添加额外的安全层",
3746
+ "enterOtpForDisabled": "输入6位代码并确认以禁用它:",
3747
+ "enterOtpForEnabled": "输入6位代码并确认:",
3748
+ "qrcodeDescription": "使用您的身份验证器应用程序扫描此QR码,或手动输入其中一个代码。然后,通过输入下面的一次性代码来确认操作。"
3749
+ },
3750
+ "ssoConfiguration": {
3751
+ "twoFactorPolicy": "双因素策略",
3752
+ "twoFactorGracePeriodDays": "双因素宽限期天数",
3753
+ "maxIdenticalAdjacentCharacters": "最大相同相邻字符数",
3754
+ "maxLength": "最大长度",
3755
+ "minLength": "最小长度",
3756
+ "minAlphabeticCount": "最小字母数量",
3757
+ "minLowerCaseCount": "最小小写字母数量",
3758
+ "minUpperCaseCount": "最大小写字母数量",
3759
+ "minNumericCount": "最小数字数量",
3760
+ "minSpecialCharCount": "最小特殊字符数量",
3761
+ "passwordLifeTimeDays": "密码有效期(天)",
3762
+ "prohibitedPreviousPasswordCount": "禁用的以前密码数量",
3763
+ "maxFailedAttempts": "最大失败尝试次数",
3764
+ "failedAttemptIntervalSec": "失败尝试间隔(秒)",
3765
+ "autoUnlockIntervalSec": "自动解锁间隔(秒)",
3766
+ "maxDurationSec": "最长持续时间(秒)",
3767
+ "idleTimeoutSec": "空闲超时(秒)",
3768
+ "maxConcurrentSessions": "最大并发会话数"
3746
3769
  }
3747
3770
  }
@@ -19,7 +19,7 @@
19
19
  :remote-console="props.remoteConsole"
20
20
  :vm-cluster="props.vmCluster"
21
21
  :security-loader="props.securityLoader"
22
- :recovery-codes="props.recoveryCodes"
22
+ :recovery="props.recovery"
23
23
  @toggle-main-menu="emits('toggle-main-menu')"
24
24
  @show-preference="emits('show-preference')"
25
25
  @reset-preference="emits('reset-preference')"
@@ -32,6 +32,7 @@
32
32
  @update-is-new-view="emits('update-is-new-view', $event)"
33
33
  @update-remote-console="emits('update-remote-console', $event)"
34
34
  @update-vm-clusters="emits('update-vm-clusters', $event)"
35
+ @security-confirm="emits('security-confirm', $event)"
35
36
  @submit-preferences="emits('submit-preferences')"
36
37
  />
37
38
  <common-layout-the-header-old
@@ -52,7 +53,7 @@
52
53
  :remote-console="props.remoteConsole"
53
54
  :vm-cluster="props.vmCluster"
54
55
  :security-loader="props.securityLoader"
55
- :recovery-codes="props.recoveryCodes"
56
+ :recovery="props.recovery"
56
57
  @toggle-main-menu="emits('toggle-main-menu')"
57
58
  @show-preference="emits('show-preference')"
58
59
  @hide-preference="emits('hide-preference')"
@@ -64,6 +65,7 @@
64
65
  @update-is-new-view="emits('update-is-new-view', $event)"
65
66
  @update-remote-console="emits('update-remote-console', $event)"
66
67
  @update-vm-clusters="emits('update-vm-clusters', $event)"
68
+ @security-confirm="emits('security-confirm', $event)"
67
69
  @submit-preferences="emits('submit-preferences')"
68
70
  />
69
71
 
@@ -75,34 +77,43 @@
75
77
  import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
76
78
  import type { UI_T_Project } from '~/lib/models/types'
77
79
  import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
80
+ import type {
81
+ UI_I_Recovery
82
+ } from "~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces";
78
83
  import { checkIsTokenExpired } from '~/lib/utils/token'
79
84
 
80
85
  const security = defineModel<boolean>('security')
81
86
 
82
- const props = defineProps<{
83
- isShowMainMenu: boolean
84
- companyName: string
85
- betaText: string
86
- globalRefreshLoading: boolean
87
- project: UI_T_Project
88
- projectName: string
89
- hostname: string
90
- isPreference: boolean
91
- selectedLanguageType: string
92
- selectedLang: UI_I_Dropdown
93
- remoteConsole: string
94
- vmCluster: boolean
95
- newView: boolean
96
- newViewLocal: boolean
97
- timeFormat: string
98
- isDarkTheme: boolean
99
- isPauseReconnect: boolean
100
- expireTimeFromState: number
101
- isShowReconnectModal: boolean
102
- isShowRedirectLoginModal: boolean
103
- securityLoader?: boolean // для Сферы
104
- recoveryCodes?: string[] // для Сферы
105
- }>()
87
+ const props = withDefaults(
88
+ defineProps<{
89
+ isShowMainMenu: boolean
90
+ companyName: string
91
+ betaText: string
92
+ globalRefreshLoading: boolean
93
+ project: UI_T_Project
94
+ projectName: string
95
+ hostname: string
96
+ isPreference: boolean
97
+ selectedLanguageType: string
98
+ selectedLang: UI_I_Dropdown
99
+ remoteConsole: string
100
+ vmCluster: boolean
101
+ newView: boolean
102
+ newViewLocal: boolean
103
+ timeFormat: string
104
+ isDarkTheme: boolean
105
+ isPauseReconnect: boolean
106
+ expireTimeFromState: number
107
+ isShowReconnectModal: boolean
108
+ isShowRedirectLoginModal: boolean
109
+ securityLoader?: boolean // для Сферы
110
+ recovery?: UI_I_Recovery | null // для Сферы
111
+ }>(),
112
+ {
113
+ securityLoader: false,
114
+ recovery: null
115
+ }
116
+ )
106
117
 
107
118
  const emits = defineEmits<{
108
119
  (event: 'toggle-main-menu'): void
@@ -117,6 +128,7 @@ const emits = defineEmits<{
117
128
  (event: 'update-is-new-view', value: boolean): void
118
129
  (event: 'update-remote-console', value: string): void
119
130
  (event: 'update-vm-clusters', value: boolean): void
131
+ (event: 'security-confirm', value: boolean): void
120
132
  (event: 'submit-preferences'): void
121
133
  (event: 'show-redirect-login-modal', value: boolean): void
122
134
  (event: 'show-reconnect-modal', value: boolean): void
@@ -113,7 +113,7 @@
113
113
  :remote-console="props.remoteConsole"
114
114
  :vm-cluster="props.vmCluster"
115
115
  :security-loader="props.securityLoader"
116
- :recovery-codes="props.recoveryCodes"
116
+ :recovery="props.recovery"
117
117
  @show-preference="emits('show-preference')"
118
118
  @reset-preference="emits('reset-preference')"
119
119
  @hide-preference="emits('hide-preference')"
@@ -124,6 +124,7 @@
124
124
  @update-is-new-view="emits('update-is-new-view', $event)"
125
125
  @update-remote-console="emits('update-remote-console', $event)"
126
126
  @update-vm-clusters="emits('update-vm-clusters', $event)"
127
+ @security-confirm="emits('security-confirm', $event)"
127
128
  @submit-preferences="emits('submit-preferences')"
128
129
  />
129
130
  </div>
@@ -137,6 +138,9 @@ import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropd
137
138
  import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
138
139
  import type { UI_T_Project } from '~/lib/models/types'
139
140
  import type { UI_I_Localization } from '~/lib/models/interfaces'
141
+ import type {
142
+ UI_I_Recovery
143
+ } from "~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces";
140
144
 
141
145
  const security = defineModel<boolean>('security')
142
146
 
@@ -157,8 +161,8 @@ const props = defineProps<{
157
161
  newViewLocal: boolean
158
162
  timeFormat: string
159
163
  isDarkTheme: boolean
160
- securityLoader?: boolean // для Сферы
161
- recoveryCodes?: string[] // для Сферы
164
+ securityLoader: boolean // для Сферы
165
+ recovery: UI_I_Recovery | null // для Сферы
162
166
  }>()
163
167
 
164
168
  const emits = defineEmits<{
@@ -174,6 +178,7 @@ const emits = defineEmits<{
174
178
  (event: 'update-is-new-view', value: boolean): void
175
179
  (event: 'update-remote-console', value: string): void
176
180
  (event: 'update-vm-clusters', value: boolean): void
181
+ (event: 'security-confirm', value: boolean): void
177
182
  (event: 'submit-preferences'): void
178
183
  }>()
179
184
 
@@ -70,7 +70,7 @@
70
70
  :remote-console="props.remoteConsole"
71
71
  :vm-cluster="props.vmCluster"
72
72
  :security-loader="props.securityLoader"
73
- :recovery-codes="props.recoveryCodes"
73
+ :recovery="props.recovery"
74
74
  @show-preference="emits('show-preference')"
75
75
  @hide-preference="emits('hide-preference')"
76
76
  @change-theme-mode="emits('change-theme-mode')"
@@ -80,6 +80,7 @@
80
80
  @update-is-new-view="emits('update-is-new-view', $event)"
81
81
  @update-remote-console="emits('update-remote-console', $event)"
82
82
  @update-vm-clusters="emits('update-vm-clusters', $event)"
83
+ @security-confirm="emits('security-confirm', $event)"
83
84
  @submit-preferences="emits('submit-preferences')"
84
85
  />
85
86
 
@@ -105,6 +106,9 @@
105
106
  import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
106
107
  import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
107
108
  import type { UI_T_Project } from '~/lib/models/types'
109
+ import type {
110
+ UI_I_Recovery
111
+ } from "~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces";
108
112
  import { findInLocals } from '~/components/common/selectLanguage/lib/utils/utils'
109
113
 
110
114
  const security = defineModel<boolean>('security')
@@ -124,8 +128,8 @@ const props = defineProps<{
124
128
  newView: boolean
125
129
  newViewLocal: boolean
126
130
  timeFormat: string
127
- securityLoader?: boolean // для Сферы
128
- recoveryCodes?: string[] // для Сферы
131
+ securityLoader: boolean // для Сферы
132
+ recovery: UI_I_Recovery | null // для Сферы
129
133
  }>()
130
134
 
131
135
  const emits = defineEmits<{
@@ -140,6 +144,7 @@ const emits = defineEmits<{
140
144
  (event: 'update-is-new-view', value: boolean): void
141
145
  (event: 'update-remote-console', value: string): void
142
146
  (event: 'update-vm-clusters', value: boolean): void
147
+ (event: 'security-confirm', value: boolean): void
143
148
  (event: 'submit-preferences'): void
144
149
  }>()
145
150
 
@@ -30,7 +30,7 @@
30
30
  :remote-console="props.remoteConsole"
31
31
  :vm-cluster="props.vmCluster"
32
32
  :security-loader="props.securityLoader"
33
- :recovery-codes="props.recoveryCodes"
33
+ :recovery="props.recovery"
34
34
  @hide="emits('hide-preference')"
35
35
  @reset="emits('reset-preference')"
36
36
  @update-time-format="emits('update-time-format', $event)"
@@ -39,6 +39,7 @@
39
39
  @update-is-new-view="emits('update-is-new-view', $event)"
40
40
  @update-remote-console="emits('update-remote-console', $event)"
41
41
  @update-vm-clusters="emits('update-vm-clusters', $event)"
42
+ @security-confirm="emits('security-confirm', $event)"
42
43
  @submit="emits('submit-preferences')"
43
44
  />
44
45
  </Teleport>
@@ -48,6 +49,9 @@
48
49
  import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
49
50
  import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
50
51
  import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
52
+ import type {
53
+ UI_I_Recovery
54
+ } from "~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces";
51
55
 
52
56
  const security = defineModel<boolean>('security')
53
57
 
@@ -62,8 +66,8 @@ const props = defineProps<{
62
66
  selectedLanguage: UI_I_Dropdown | string
63
67
  remoteConsole: string
64
68
  vmCluster: boolean
65
- securityLoader?: boolean // для Сферы
66
- recoveryCodes?: string[] // для Сферы
69
+ securityLoader: boolean // для Сферы
70
+ recovery: UI_I_Recovery | null // для Сферы
67
71
  }>()
68
72
  const emits = defineEmits<{
69
73
  (event: 'show-preference'): void
@@ -76,6 +80,7 @@ const emits = defineEmits<{
76
80
  (event: 'update-is-new-view', value: boolean): void
77
81
  (event: 'update-remote-console', value: string): void
78
82
  (event: 'update-vm-clusters', value: boolean): void
83
+ (event: 'security-confirm', value: boolean): void
79
84
  (event: 'submit-preferences'): void
80
85
  }>()
81
86
 
@@ -11,7 +11,7 @@
11
11
  :remote-console="props.remoteConsole"
12
12
  :vm-cluster="props.vmCluster"
13
13
  :security-loader="props.securityLoader"
14
- :recovery-codes="props.recoveryCodes"
14
+ :recovery="props.recovery"
15
15
  @hide="emits('hide')"
16
16
  @reset="emits('reset')"
17
17
  @update-time-format="emits('update-time-format', $event)"
@@ -20,6 +20,7 @@
20
20
  @update-is-new-view="emits('update-is-new-view', $event)"
21
21
  @update-remote-console="emits('update-remote-console', $event)"
22
22
  @update-vm-clusters="emits('update-vm-clusters', $event)"
23
+ @security-confirm="emits('security-confirm', $event)"
23
24
  @submit="emits('submit')"
24
25
  />
25
26
  <common-layout-the-header-user-menu-modals-preferences-old
@@ -34,7 +35,7 @@
34
35
  :remote-console="props.remoteConsole"
35
36
  :vm-cluster="props.vmCluster"
36
37
  :security-loader="props.securityLoader"
37
- :recovery-codes="props.recoveryCodes"
38
+ :recovery="props.recovery"
38
39
  @hide="emits('hide')"
39
40
  @update-time-format="emits('update-time-format', $event)"
40
41
  @update-language="emits('update-language', $event)"
@@ -42,6 +43,7 @@
42
43
  @update-is-new-view="emits('update-is-new-view', $event)"
43
44
  @update-remote-console="emits('update-remote-console', $event)"
44
45
  @update-vm-clusters="emits('update-vm-clusters', $event)"
46
+ @security-confirm="emits('security-confirm', $event)"
45
47
  @submit="emits('submit')"
46
48
  />
47
49
  </template>
@@ -50,6 +52,9 @@
50
52
  import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
51
53
  import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
52
54
  import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
55
+ import type {
56
+ UI_I_Recovery
57
+ } from "~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces";
53
58
 
54
59
  const security = defineModel<boolean>('security')
55
60
 
@@ -62,8 +67,8 @@ const props = defineProps<{
62
67
  selectedLanguage: UI_I_Dropdown | string
63
68
  remoteConsole: string
64
69
  vmCluster: boolean
65
- securityLoader?: boolean // для Сферы
66
- recoveryCodes?: string[] // для Сферы
70
+ securityLoader: boolean // для Сферы
71
+ recovery: UI_I_Recovery | null // для Сферы
67
72
  }>()
68
73
 
69
74
  const emits = defineEmits<{
@@ -75,6 +80,7 @@ const emits = defineEmits<{
75
80
  (event: 'update-is-new-view', value: boolean): void
76
81
  (event: 'update-remote-console', value: string): void
77
82
  (event: 'update-vm-clusters', value: boolean): void
83
+ (event: 'security-confirm', value: boolean): void
78
84
  (event: 'submit'): void
79
85
  }>()
80
86
  </script>
@@ -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,5 +1,5 @@
1
1
  <template>
2
- <form id="security-form" class="compact">
2
+ <form id="security-form" class="compact" @submit.prevent>
3
3
  <div class="description">
4
4
  {{ localization.myPreferences.twoFactorAuthentication }}
5
5
  </div>
@@ -11,32 +11,117 @@
11
11
  <input id="security" v-model="security" type="checkbox" class="switch" />
12
12
  </div>
13
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>
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>
26
64
  </div>
27
65
  </form>
28
66
  </template>
29
67
 
30
68
  <script setup lang="ts">
31
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')
32
73
 
33
74
  const props = defineProps<{
34
- recoveryCodes: string[]
75
+ recovery?: UI_I_Recovery
76
+ }>()
77
+ const emits = defineEmits<{
78
+ (event: 'confirm', value: boolean): void
35
79
  }>()
36
80
 
37
81
  const localization = computed<UI_I_Localization>(() => useLocal())
38
82
 
39
- const security = defineModel<boolean>('security')
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
+ }
40
125
  </script>
41
126
 
42
127
  <style lang="scss" scoped>
@@ -44,12 +129,17 @@ const security = defineModel<boolean>('security')
44
129
  margin-bottom: 10px;
45
130
  }
46
131
 
47
- .recovery-codes {
48
- display: flex;
49
- margin-top: 10px;
132
+ .recovery-codes-wrap {
133
+ margin: 10px 0;
50
134
 
51
- .recovery-codes-list-item {
52
- font-size: 12px;
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
+ }
53
143
  }
54
144
  }
55
145
 
@@ -2,13 +2,21 @@
2
2
  <component
3
3
  v-model:security="security"
4
4
  :is="currentComponent"
5
- :recovery-codes="props.recoveryCodes"
5
+ :recovery="props.recovery"
6
+ @confirm="emits('confirm', $event)"
6
7
  />
7
8
  </template>
8
9
 
9
10
  <script setup lang="ts">
11
+ import type {
12
+ UI_I_Recovery
13
+ } from "~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces";
14
+
10
15
  const props = defineProps<{
11
- recoveryCodes: string[]
16
+ recovery: UI_I_Recovery | null
17
+ }>()
18
+ const emits = defineEmits<{
19
+ (event: 'confirm', value: boolean): void
12
20
  }>()
13
21
 
14
22
  const security = defineModel<boolean>('security')
@@ -0,0 +1,4 @@
1
+ export interface UI_I_Recovery {
2
+ qr_code_url: string
3
+ recovery_codes: string[]
4
+ }
@@ -86,6 +86,9 @@ export const bodyItems = (
86
86
  text: $binary.round(datastore.capacity[tableKeys[2]], false, lang),
87
87
  id: datastore.id,
88
88
  testId: `backup-datastore-table-item-${datastore.id}`,
89
+ data: {
90
+ sortValue: datastore.capacity[tableKeys[2]],
91
+ }
89
92
  },
90
93
  {
91
94
  key: 'col3',
@@ -96,18 +99,27 @@ export const bodyItems = (
96
99
  ),
97
100
  id: datastore.id,
98
101
  testId: `backup-datastore-table-item-${datastore.id}`,
102
+ data: {
103
+ sortValue: datastore.capacity[tableKeys[3]],
104
+ }
99
105
  },
100
106
  {
101
107
  key: 'col4',
102
108
  text: $binary.round(datastore.capacity[tableKeys[4]], false, lang),
103
109
  id: datastore.id,
104
110
  testId: `backup-datastore-table-item-${datastore.id}`,
111
+ data: {
112
+ sortValue: datastore.capacity[tableKeys[4]],
113
+ }
105
114
  },
106
115
  {
107
116
  key: 'col5',
108
117
  text: $binary.round(datastore.capacity[tableKeys[5]], false, lang),
109
118
  id: datastore.id,
110
119
  testId: `backup-datastore-table-item-${datastore.id}`,
120
+ data: {
121
+ sortValue: datastore.capacity[tableKeys[5]],
122
+ }
111
123
  },
112
124
  {
113
125
  key: 'col6',
@@ -96,6 +96,9 @@ export const bodyItems = (
96
96
  text: $binary.round(disk[tableKeys[4]], false, lang),
97
97
  id: disk.source,
98
98
  testId: `disk-table-item-${key}`,
99
+ data: {
100
+ sortValue: disk[tableKeys[4]],
101
+ }
99
102
  },
100
103
  {
101
104
  key: 'col5',
@@ -106,12 +109,18 @@ export const bodyItems = (
106
109
  ),
107
110
  id: disk.source,
108
111
  testId: `disk-table-item-${key}`,
112
+ data: {
113
+ sortValue: disk[tableKeys[4]] - disk[tableKeys[6]],
114
+ }
109
115
  },
110
116
  {
111
117
  key: 'col6',
112
118
  text: $binary.round(disk[tableKeys[6]], false, lang),
113
119
  id: disk.source,
114
120
  testId: `disk-table-item-${key}`,
121
+ data: {
122
+ sortValue: disk[tableKeys[6]],
123
+ }
115
124
  },
116
125
  {
117
126
  key: 'col7',
@@ -91,6 +91,9 @@ export const bodyItems = (
91
91
  key: 'col4',
92
92
  text: $binary.round(disk[tableKeys[4]], false, lang),
93
93
  id: disk.source,
94
+ data: {
95
+ sortValue: disk[tableKeys[4]]
96
+ }
94
97
  },
95
98
  {
96
99
  key: 'col5',
@@ -100,11 +103,17 @@ export const bodyItems = (
100
103
  lang
101
104
  ),
102
105
  id: disk.source,
106
+ data: {
107
+ sortValue: disk[tableKeys[4]] - disk[tableKeys[6]]
108
+ }
103
109
  },
104
110
  {
105
111
  key: 'col6',
106
112
  text: $binary.round(disk[tableKeys[6]], false, lang),
107
113
  id: disk.source,
114
+ data: {
115
+ sortValue: disk[tableKeys[6]]
116
+ }
108
117
  },
109
118
  {
110
119
  key: 'col7',
@@ -2,8 +2,16 @@
2
2
  <form id="system-licensing-list-view-form">
3
3
  <section v-if="listItems.length" class="form-block">
4
4
  <div v-for="(item, index) in listItems" :key="index" class="form-group">
5
- <label :data-id="`system-licensing-list-view-label-${index}`">{{ item.label }}</label>
6
- <span :class="['word-break-all form-value', { expired: item.data?.isExpired }]" :data-id="`system-licensing-list-view-${index}`">
5
+ <label :data-id="`system-licensing-list-view-label-${index}`">
6
+ {{ item.label }}
7
+ </label>
8
+ <span
9
+ :class="[
10
+ 'word-break-all form-value',
11
+ { expired: item.data?.isExpired },
12
+ ]"
13
+ :data-id="`system-licensing-list-view-${index}`"
14
+ >
7
15
  <atoms-the-icon v-if="item.icon" :name="item.icon" class="icon" />
8
16
  {{ item.value || '--' }}
9
17
  </span>
@@ -17,9 +25,9 @@
17
25
 
18
26
  <script lang="ts" setup>
19
27
  import type { UI_I_Localization } from '~/lib/models/interfaces'
20
- import type { UI_I_SystemLicense} from "~/components/common/pages/licensing/lib/models/interfaces";
21
- import type { UI_I_LicensingInfoView} from "~/components/common/pages/licensing/listView/lib/models/interfaces";
22
- import { systemLicenseViewFunc} from "~/components/common/pages/licensing/listView/lib/config/list";
28
+ import type { UI_I_SystemLicense } from '~/components/common/pages/licensing/lib/models/interfaces'
29
+ import type { UI_I_LicensingInfoView } from '~/components/common/pages/licensing/listView/lib/models/interfaces'
30
+ import { systemLicenseViewFunc } from '~/components/common/pages/licensing/listView/lib/config/list'
23
31
 
24
32
  const props = defineProps<{
25
33
  license: UI_I_SystemLicense | null
@@ -77,11 +77,9 @@ const props = defineProps<{
77
77
 
78
78
  const localization = computed<UI_I_Localization>(() => useLocal())
79
79
 
80
- const activeLicense = computed<UI_I_SystemLicense | null>(() => {
81
- return (
82
- props.dataTable.find((item) => item.id === selectedActiveKey.value) || null
83
- )
84
- })
80
+ const activeLicense = computed<UI_I_SystemLicense | null>(() =>
81
+ props.dataTable.find((item) => item.id === selectedActiveKey.value) || null
82
+ )
85
83
 
86
84
  const headItems = computed<UI_I_HeadItem[]>(() =>
87
85
  table.headItems(localization.value)
@@ -109,6 +109,9 @@ export const bodyItems = (
109
109
  text: formattedLastRun,
110
110
  id: task.rid,
111
111
  testId: `adapter-table-${key}-row-item`,
112
+ data: {
113
+ sortValue: lastRun || 0
114
+ }
112
115
  },
113
116
  {
114
117
  key: 'icon',
@@ -122,6 +125,9 @@ export const bodyItems = (
122
125
  text: formattedNextRun,
123
126
  id: task.rid,
124
127
  testId: `adapter-table-${key}-row-item`,
128
+ data: {
129
+ sortValue: task[scheduledTaskTableItemsKeys[4]]
130
+ }
125
131
  },
126
132
  ])
127
133
  })
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <div class="qrcode">
3
+ <img v-if="qrDataUrl" :src="qrDataUrl" alt="QR Code" class="qr-image" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import QRCode from 'qrcode'
9
+
10
+ const props = defineProps<{
11
+ qrCodeUrl: string
12
+ }>()
13
+
14
+ const qrDataUrl = ref<string>('')
15
+ const generateQRCode = async (): Promise<void> => {
16
+ try {
17
+ qrDataUrl.value = await QRCode.toDataURL(props.qrCodeUrl, {
18
+ width: 150,
19
+ margin: 2,
20
+ })
21
+ } catch (error) {
22
+ console.error('Error generating QR code:', error)
23
+ }
24
+ }
25
+
26
+ watch(
27
+ () => props.qrCodeUrl,
28
+ (newValue) => {
29
+ newValue && generateQRCode()
30
+ },
31
+ { immediate: true }
32
+ )
33
+ </script>
34
+
35
+ <style scoped lang="scss">
36
+ .qr-code-display {
37
+ text-align: center;
38
+ max-width: 400px;
39
+ margin: 0 auto;
40
+ }
41
+
42
+ .qr-wrapper {
43
+ margin: 20px 0;
44
+ padding: 20px;
45
+ background: white;
46
+ border-radius: 12px;
47
+ border: 1px solid #e0e0e0;
48
+ display: inline-block;
49
+ }
50
+
51
+ .qr-canvas,
52
+ .qr-image {
53
+ width: 150px;
54
+ height: 150px;
55
+ }
56
+ </style>
@@ -100,7 +100,7 @@ watch(
100
100
  }
101
101
 
102
102
  maxCpuInvalid.value = false
103
- model.value.cpu.max_vcpus = 1
103
+ model.value.cpu.max_vcpus = capabilities.value.maxCpus
104
104
  }
105
105
  )
106
106
 
@@ -52,6 +52,7 @@ export interface UI_I_Localization {
52
52
  role: UI_I_ArbitraryObject<string>
53
53
  backup: UI_I_ArbitraryObject<string>
54
54
  ssoUsers: UI_I_ArbitraryObject<string>
55
+ ssoConfiguration: UI_I_ArbitraryObject<string>
55
56
  vmt: UI_I_ArbitraryObject<string>
56
57
  passwordRule: UI_I_ArbitraryObject<string>
57
58
  identityProvider: UI_I_ArbitraryObject<string>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bfg-common",
3
3
  "private": false,
4
- "version": "1.5.655",
4
+ "version": "1.5.657",
5
5
  "scripts": {
6
6
  "build": "nuxt build",
7
7
  "dev": "nuxt dev --port=3002",
@@ -38,6 +38,7 @@
38
38
  "@nuxtjs/eslint-config-typescript": "^12.0.0",
39
39
  "@vueuse/components": "^10.1.2",
40
40
  "html2canvas": "^1.4.1",
41
- "prettier-eslint": "^15.0.1"
41
+ "prettier-eslint": "^15.0.1",
42
+ "qrcode": "^1.5.4"
42
43
  }
43
44
  }