From 8a98650af643f4ac1980999eaad023c61fac94ff Mon Sep 17 00:00:00 2001 From: Sensational Code Date: Sat, 27 Jul 2024 23:46:12 -0700 Subject: [PATCH 1/8] Run eslint fix on user portal --- src/ui/UserPortal/components/ChatInput.vue | 157 +++++++++++++----- src/ui/UserPortal/components/ChatMessage.vue | 27 +-- src/ui/UserPortal/components/ChatSidebar.vue | 8 +- src/ui/UserPortal/components/ChatThread.vue | 14 +- .../UserPortal/components/CodeBlockHeader.vue | 125 +++++++------- src/ui/UserPortal/components/NavBar.vue | 7 +- src/ui/UserPortal/js/api.ts | 96 ++++++----- src/ui/UserPortal/js/eventBus.ts | 10 +- src/ui/UserPortal/js/types/index.ts | 2 +- src/ui/UserPortal/pages/auth/index.vue | 8 +- src/ui/UserPortal/stores/appConfigStore.ts | 26 +-- src/ui/UserPortal/stores/appStore.ts | 34 ++-- 12 files changed, 314 insertions(+), 200 deletions(-) diff --git a/src/ui/UserPortal/components/ChatInput.vue b/src/ui/UserPortal/components/ChatInput.vue index 85cb6ae57b..a9ffc9c8df 100644 --- a/src/ui/UserPortal/components/ChatInput.vue +++ b/src/ui/UserPortal/components/ChatInput.vue @@ -1,21 +1,33 @@ @@ -82,12 +143,12 @@
-

+

Drag and drop files here
or
- Browse for files + Browse for files

@@ -170,9 +231,9 @@ export default { agentListOpen: false, showFileUploadDialog: false, primaryButtonBg: this.$appConfigStore.primaryButtonBg, - primaryButtonText: this.$appConfigStore.primaryButtonText, + primaryButtonText: this.$appConfigStore.primaryButtonText, secondaryButtonBg: this.$appConfigStore.secondaryButtonBg, - secondaryButtonText: this.$appConfigStore.secondaryButtonText, + secondaryButtonText: this.$appConfigStore.secondaryButtonText, }; }, @@ -232,15 +293,23 @@ export default { async handleUpload(event: any) { try { const formData = new FormData(); - formData.append("file", event.files[0]); + formData.append('file', event.files[0]); const objectId = await this.$appStore.uploadAttachment(formData); console.log(`File uploaded: ObjectId: ${objectId}`); - this.$toast.add({ severity: 'success', summary: 'Success', detail: 'File uploaded successfully.' }); + this.$toast.add({ + severity: 'success', + summary: 'Success', + detail: 'File uploaded successfully.', + }); this.showFileUploadDialog = false; } catch (error) { - this.$toast.add({ severity: 'error', summary: 'Error', detail: `File upload failed. ${error.message}` }); + this.$toast.add({ + severity: 'error', + summary: 'Error', + detail: `File upload failed. ${error.message}`, + }); } }, @@ -265,10 +334,10 @@ export default { rejectProps: { label: 'Cancel', severity: 'secondary', - outlined: true + outlined: true, }, acceptProps: { - label: 'Upload' + label: 'Upload', }, accept: () => { uploadCallback(); @@ -276,7 +345,7 @@ export default { }, reject: () => { this.showFileUploadDialog = false; - } + }, }); } else { uploadCallback(); @@ -285,19 +354,19 @@ export default { }, formatSize(bytes) { - const k = 1024; - const dm = 3; - const sizes = this.$primevue.config.locale.fileSizeTypes; + const k = 1024; + const dm = 3; + const sizes = this.$primevue.config.locale.fileSizeTypes; - if (bytes === 0) { - return `0 ${sizes[0]}`; - } + if (bytes === 0) { + return `0 ${sizes[0]}`; + } - const i = Math.floor(Math.log(bytes) / Math.log(k)); - const formattedSize = parseFloat((bytes / Math.pow(k, i)).toFixed(dm)); + const i = Math.floor(Math.log(bytes) / Math.log(k)); + const formattedSize = parseFloat((bytes / Math.pow(k, i)).toFixed(dm)); - return `${formattedSize} ${sizes[i]}`; - } + return `${formattedSize} ${sizes[i]}`; + }, }, }; @@ -327,7 +396,7 @@ export default { } .chat-input .input-wrapper { - display: flex; + display: flex; align-items: stretch; width: 100%; } @@ -403,10 +472,10 @@ export default { .attached-files { display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - flex-wrap: nowrap; + flex-direction: row; + align-items: center; + justify-content: space-between; + flex-wrap: nowrap; } .file-remove { @@ -447,6 +516,6 @@ export default { width: 100%; text-align: center; font-size: 5rem; - color: #000; + color: #000; } diff --git a/src/ui/UserPortal/components/ChatMessage.vue b/src/ui/UserPortal/components/ChatMessage.vue index b812d3a916..4f32957f87 100644 --- a/src/ui/UserPortal/components/ChatMessage.vue +++ b/src/ui/UserPortal/components/ChatMessage.vue @@ -27,7 +27,9 @@ }, }" /> - {{ $filters.timeAgo(new Date(message.timeStamp)) }} + {{ + $filters.timeAgo(new Date(message.timeStamp)) + }} @@ -105,13 +107,14 @@

{{ prompt.prompt }}

@@ -166,7 +169,9 @@ function addCodeHeaderComponents(htmlString) { }); const html = doc.body.innerHTML; - const withVueCurlyBracesSanitized = html.replace(/{{/g, '{{').replace(/}}/g, '}}'); + const withVueCurlyBracesSanitized = html + .replace(/{{/g, '{{') + .replace(/}}/g, '}}'); return withVueCurlyBracesSanitized; } @@ -210,7 +215,7 @@ export default { components: { CodeBlockHeader, }, - }; + }; }, }, @@ -251,7 +256,7 @@ export default { hour: 'numeric', minute: 'numeric', second: 'numeric', - timeZoneName: 'short' + timeZoneName: 'short', }; return date.toLocaleString(undefined, options); }, diff --git a/src/ui/UserPortal/components/ChatSidebar.vue b/src/ui/UserPortal/components/ChatSidebar.vue index 5b04841d07..40eca75896 100644 --- a/src/ui/UserPortal/components/ChatSidebar.vue +++ b/src/ui/UserPortal/components/ChatSidebar.vue @@ -22,7 +22,13 @@ - + diff --git a/src/ui/UserPortal/stores/appConfigStore.ts b/src/ui/UserPortal/stores/appConfigStore.ts index f000ef9985..9bc8c9e2b9 100644 --- a/src/ui/UserPortal/stores/appConfigStore.ts +++ b/src/ui/UserPortal/stores/appConfigStore.ts @@ -42,14 +42,14 @@ export const useAppConfigStore = defineStore('appConfig', { actions: { async getConfigVariables() { const getConfigValueSafe = async (key: string, defaultValue: any = null) => { - try { - return await api.getConfigValue(key); - } catch (error) { - console.error(`Failed to get config value for key ${key}:`, error); - return defaultValue; - } - }; - + try { + return await api.getConfigValue(key); + } catch (error) { + console.error(`Failed to get config value for key ${key}:`, error); + return defaultValue; + } + }; + const [ apiUrl, isKioskMode, @@ -74,10 +74,10 @@ export const useAppConfigStore = defineStore('appConfig', { authInstance, authTenantId, authScopes, - authCallbackPath + authCallbackPath, ] = await Promise.all([ api.getConfigValue('FoundationaLLM:APIs:CoreAPI:APIUrl'), - + getConfigValueSafe('FoundationaLLM:Branding:KioskMode'), getConfigValueSafe('FoundationaLLM:Branding:PageTitle'), getConfigValueSafe('FoundationaLLM:Branding:FavIconUrl'), @@ -95,12 +95,12 @@ export const useAppConfigStore = defineStore('appConfig', { getConfigValueSafe('FoundationaLLM:Branding:SecondaryButtonBackgroundColor', '#70829a'), getConfigValueSafe('FoundationaLLM:Branding:SecondaryButtonTextColor', '#fff'), getConfigValueSafe('FoundationaLLM:Branding:FooterText'), - getConfigValueSafe('FoundationaLLM:Instance:Id','00000000-0000-0000-0000-000000000000'), + getConfigValueSafe('FoundationaLLM:Instance:Id', '00000000-0000-0000-0000-000000000000'), api.getConfigValue('FoundationaLLM:Chat:Entra:ClientId'), api.getConfigValue('FoundationaLLM:Chat:Entra:Instance'), api.getConfigValue('FoundationaLLM:Chat:Entra:TenantId'), api.getConfigValue('FoundationaLLM:Chat:Entra:Scopes'), - api.getConfigValue('FoundationaLLM:Chat:Entra:CallbackPath') + api.getConfigValue('FoundationaLLM:Chat:Entra:CallbackPath'), ]); this.apiUrl = apiUrl; @@ -123,7 +123,7 @@ export const useAppConfigStore = defineStore('appConfig', { this.secondaryButtonBg = secondaryButtonBg; this.secondaryButtonText = secondaryButtonText; this.footerText = footerText; - this.instanceId = instanceId + this.instanceId = instanceId; this.auth.clientId = authClientId; this.auth.instance = authInstance; diff --git a/src/ui/UserPortal/stores/appStore.ts b/src/ui/UserPortal/stores/appStore.ts index f6a32d2662..fdd0914368 100644 --- a/src/ui/UserPortal/stores/appStore.ts +++ b/src/ui/UserPortal/stores/appStore.ts @@ -15,7 +15,7 @@ export const useAppStore = defineStore('app', { selectedAgents: new Map(), lastSelectedAgent: null as ResourceProviderGetResult | null, attachments: [] as Attachment[], - longRunningOperations: new Map(), // sessionId -> operationId + longRunningOperations: new Map(), // sessionId -> operationId }), getters: {}, @@ -122,15 +122,17 @@ export const useAppStore = defineStore('app', { updateSessionAgentFromMessages(session: Session) { const lastAssistantMessage = this.currentMessages - .filter((message) => message.sender.toLowerCase() === 'assistant') - .pop(); + .filter((message) => message.sender.toLowerCase() === 'assistant') + .pop(); if (lastAssistantMessage) { - const agent = this.agents.find(agent => agent.resource.name === lastAssistantMessage.senderDisplayName); - if (agent) { - this.setSessionAgent(session, agent); - } + const agent = this.agents.find( + (agent) => agent.resource.name === lastAssistantMessage.senderDisplayName, + ); + if (agent) { + this.setSessionAgent(session, agent); + } } - }, + }, getSessionAgent(session: Session) { if (!session) return null; @@ -154,7 +156,7 @@ export const useAppStore = defineStore('app', { /** * Sends a message to the Core API. - * + * * @param text - The text of the message to send. * @returns A Promise that resolves when the message is sent. */ @@ -200,7 +202,7 @@ export const useAppStore = defineStore('app', { user_prompt: text, agent_name: agent.name, settings: null, - attachments: this.attachments.map(attachment => String(attachment.id)) + attachments: this.attachments.map((attachment) => String(attachment.id)), }); this.longRunningOperations.set(this.currentSession!.id, operationId); @@ -210,7 +212,7 @@ export const useAppStore = defineStore('app', { this.currentSession!.id, text, agent, - this.attachments.map(attachment => String(attachment.id)), + this.attachments.map((attachment) => String(attachment.id)), ); await this.getMessages(); } @@ -221,15 +223,15 @@ export const useAppStore = defineStore('app', { const { text: newSessionName } = await api.generateSessionName( this.currentSession!.id, sessionFullText, - ); + ); // the generate session name already renames the session in the backend this.currentSession!.name = newSessionName; } - }, + }, /** * Polls for the completion of a long-running operation. - * + * * @param sessionId - The session ID associated with the operation. * @param operationId - The ID of the operation to check for completion. */ @@ -242,7 +244,7 @@ export const useAppStore = defineStore('app', { await this.getMessages(); break; } - await new Promise(resolve => setTimeout(resolve, 2000)); // Poll every 2 seconds + await new Promise((resolve) => setTimeout(resolve, 2000)); // Poll every 2 seconds } }, @@ -293,7 +295,7 @@ export const useAppStore = defineStore('app', { const fileName = file.get('file')?.name; // this.attachments.push(id); // For now, we want to just replace the attachments with the new one. - this.attachments = [{ id, fileName}]; + this.attachments = [{ id, fileName }]; return id; } catch (error) { throw error; From 6b38d666272d04c71452e08cfccf4513ebdf4176 Mon Sep 17 00:00:00 2001 From: Sensational Code Date: Thu, 1 Aug 2024 00:21:58 -0700 Subject: [PATCH 2/8] Run eslint fix on user portal --- src/ui/UserPortal/components/ChatInput.vue | 116 ++++++++++++++++----- src/ui/UserPortal/stores/appConfigStore.ts | 26 ++--- src/ui/UserPortal/stores/appStore.ts | 45 ++++---- 3 files changed, 129 insertions(+), 58 deletions(-) diff --git a/src/ui/UserPortal/components/ChatInput.vue b/src/ui/UserPortal/components/ChatInput.vue index 906ac7291b..916c304116 100644 --- a/src/ui/UserPortal/components/ChatInput.vue +++ b/src/ui/UserPortal/components/ChatInput.vue @@ -1,21 +1,33 @@ @@ -82,12 +143,12 @@
-

+

Drag and drop files here
or
- Browse for files + Browse for files

@@ -178,7 +239,9 @@ export default { computed: { fileArrayFiltered() { - return this.$appStore.attachments.filter((attachment) => attachment.sessionId === this.$appStore.currentSession.sessionId); + return this.$appStore.attachments.filter( + (attachment) => attachment.sessionId === this.$appStore.currentSession.sessionId, + ); }, }, @@ -238,9 +301,12 @@ export default { async handleUpload(event: any) { try { const formData = new FormData(); - formData.append("file", event.files[0]); + formData.append('file', event.files[0]); - const objectId = await this.$appStore.uploadAttachment(formData, this.$appStore.currentSession.sessionId); + const objectId = await this.$appStore.uploadAttachment( + formData, + this.$appStore.currentSession.sessionId, + ); console.log(`File uploaded: ObjectId: ${objectId}`); this.$toast.add({ @@ -286,7 +352,7 @@ export default { acceptProps: { label: 'Cancel', severity: 'secondary', - outlined: true + outlined: true, }, accept: () => { this.showFileUploadDialog = false; @@ -294,7 +360,7 @@ export default { reject: () => { uploadCallback(); this.showFileUploadDialog = false; - } + }, }); } else { uploadCallback(); diff --git a/src/ui/UserPortal/stores/appConfigStore.ts b/src/ui/UserPortal/stores/appConfigStore.ts index 7399fb4cdf..d8b4615339 100644 --- a/src/ui/UserPortal/stores/appConfigStore.ts +++ b/src/ui/UserPortal/stores/appConfigStore.ts @@ -42,14 +42,14 @@ export const useAppConfigStore = defineStore('appConfig', { actions: { async getConfigVariables() { const getConfigValueSafe = async (key: string, defaultValue: any = null) => { - try { - return await api.getConfigValue(key); - } catch (error) { - console.error(`Failed to get config value for key ${key}:`, error); - return defaultValue; - } - }; - + try { + return await api.getConfigValue(key); + } catch (error) { + console.error(`Failed to get config value for key ${key}:`, error); + return defaultValue; + } + }; + const [ apiUrl, isKioskMode, @@ -74,10 +74,10 @@ export const useAppConfigStore = defineStore('appConfig', { authInstance, authTenantId, authScopes, - authCallbackPath + authCallbackPath, ] = await Promise.all([ api.getConfigValue('FoundationaLLM:APIEndpoints:CoreAPI:Essentials:APIUrl'), - + getConfigValueSafe('FoundationaLLM:Branding:KioskMode'), getConfigValueSafe('FoundationaLLM:Branding:PageTitle'), getConfigValueSafe('FoundationaLLM:Branding:FavIconUrl'), @@ -95,12 +95,12 @@ export const useAppConfigStore = defineStore('appConfig', { getConfigValueSafe('FoundationaLLM:Branding:SecondaryButtonBackgroundColor', '#70829a'), getConfigValueSafe('FoundationaLLM:Branding:SecondaryButtonTextColor', '#fff'), getConfigValueSafe('FoundationaLLM:Branding:FooterText'), - getConfigValueSafe('FoundationaLLM:Instance:Id','00000000-0000-0000-0000-000000000000'), + getConfigValueSafe('FoundationaLLM:Instance:Id', '00000000-0000-0000-0000-000000000000'), api.getConfigValue('FoundationaLLM:UserPortal:Authentication:Entra:ClientId'), api.getConfigValue('FoundationaLLM:UserPortal:Authentication:Entra:Instance'), api.getConfigValue('FoundationaLLM:UserPortal:Authentication:Entra:TenantId'), api.getConfigValue('FoundationaLLM:UserPortal:Authentication:Entra:Scopes'), - api.getConfigValue('FoundationaLLM:UserPortal:Authentication:Entra:CallbackPath') + api.getConfigValue('FoundationaLLM:UserPortal:Authentication:Entra:CallbackPath'), ]); this.apiUrl = apiUrl; @@ -123,7 +123,7 @@ export const useAppConfigStore = defineStore('appConfig', { this.secondaryButtonBg = secondaryButtonBg; this.secondaryButtonText = secondaryButtonText; this.footerText = footerText; - this.instanceId = instanceId + this.instanceId = instanceId; this.auth.clientId = authClientId; this.auth.instance = authInstance; diff --git a/src/ui/UserPortal/stores/appStore.ts b/src/ui/UserPortal/stores/appStore.ts index 7cc7ee71f7..698be10070 100644 --- a/src/ui/UserPortal/stores/appStore.ts +++ b/src/ui/UserPortal/stores/appStore.ts @@ -15,7 +15,7 @@ export const useAppStore = defineStore('app', { selectedAgents: new Map(), lastSelectedAgent: null as ResourceProviderGetResult | null, attachments: [] as Attachment[], - longRunningOperations: new Map(), // sessionId -> operationId + longRunningOperations: new Map(), // sessionId -> operationId }), getters: {}, @@ -122,15 +122,17 @@ export const useAppStore = defineStore('app', { updateSessionAgentFromMessages(session: Session) { const lastAssistantMessage = this.currentMessages - .filter((message) => message.sender.toLowerCase() === 'assistant') - .pop(); + .filter((message) => message.sender.toLowerCase() === 'assistant') + .pop(); if (lastAssistantMessage) { - const agent = this.agents.find(agent => agent.resource.name === lastAssistantMessage.senderDisplayName); - if (agent) { - this.setSessionAgent(session, agent); - } + const agent = this.agents.find( + (agent) => agent.resource.name === lastAssistantMessage.senderDisplayName, + ); + if (agent) { + this.setSessionAgent(session, agent); + } } - }, + }, getSessionAgent(session: Session) { if (!session) return null; @@ -154,7 +156,7 @@ export const useAppStore = defineStore('app', { /** * Sends a message to the Core API. - * + * * @param text - The text of the message to send. * @returns A Promise that resolves when the message is sent. */ @@ -162,8 +164,9 @@ export const useAppStore = defineStore('app', { if (!text) return; let sessionId = this.currentSession!.id; - let relevantAttachments = this.attachments.filter(attachment => attachment.sessionId === sessionId); - + let relevantAttachments = this.attachments.filter( + (attachment) => attachment.sessionId === sessionId, + ); const authStore = useAuthStore(); const tempUserMessage: Message = { @@ -204,7 +207,7 @@ export const useAppStore = defineStore('app', { user_prompt: text, agent_name: agent.name, settings: null, - attachments: relevantAttachments.map(attachment => String(attachment.id)) + attachments: relevantAttachments.map((attachment) => String(attachment.id)), }); this.longRunningOperations.set(this.currentSession!.id, operationId); @@ -214,7 +217,7 @@ export const useAppStore = defineStore('app', { this.currentSession!.id, text, agent, - relevantAttachments.map(attachment => String(attachment.id)), + relevantAttachments.map((attachment) => String(attachment.id)), ); await this.getMessages(); } @@ -225,15 +228,15 @@ export const useAppStore = defineStore('app', { const { text: newSessionName } = await api.generateSessionName( this.currentSession!.id, sessionFullText, - ); + ); // the generate session name already renames the session in the backend this.currentSession!.name = newSessionName; } - }, + }, /** * Polls for the completion of a long-running operation. - * + * * @param sessionId - The session ID associated with the operation. * @param operationId - The ID of the operation to check for completion. */ @@ -246,7 +249,7 @@ export const useAppStore = defineStore('app', { await this.getMessages(); break; } - await new Promise(resolve => setTimeout(resolve, 2000)); // Poll every 2 seconds + await new Promise((resolve) => setTimeout(resolve, 2000)); // Poll every 2 seconds } }, @@ -297,14 +300,16 @@ export const useAppStore = defineStore('app', { const fileName = file.get('file')?.name; const newAttachment = { id, fileName, sessionId }; - const existingIndex = this.attachments.findIndex(attachment => attachment.sessionId === sessionId); - + const existingIndex = this.attachments.findIndex( + (attachment) => attachment.sessionId === sessionId, + ); + if (existingIndex !== -1) { this.attachments.splice(existingIndex, 1, newAttachment); } else { this.attachments.push(newAttachment); } - + return id; } catch (error) { throw error; From 5e7a1a87cfa70f6bcbde6096ca985f15c6863cdc Mon Sep 17 00:00:00 2001 From: Sensational Code Date: Thu, 1 Aug 2024 00:22:27 -0700 Subject: [PATCH 3/8] Run eslint fix on management portal --- .../components/AccessControl.vue | 201 ++- .../components/ApiStatusCard.vue | 286 ++-- .../components/NavigationBox.vue | 161 +- .../components/RoleAssignmentsTable.vue | 590 +++---- .../ManagementPortal/components/Sidebar.vue | 4 +- .../directives/createChipOnBlur.ts | 66 +- src/ui/ManagementPortal/js/api.test.ts | 150 +- src/ui/ManagementPortal/js/api.ts | 1468 +++++++++-------- src/ui/ManagementPortal/js/mock.ts | 496 +++--- src/ui/ManagementPortal/js/types.ts | 36 +- src/ui/ManagementPortal/layouts/default.vue | 2 +- .../ManagementPortal/pages/agents/create.vue | 174 +- .../ManagementPortal/pages/agents/private.vue | 13 +- .../ManagementPortal/pages/agents/public.vue | 13 +- .../pages/data-sources/create.vue | 45 +- .../pages/data-sources/index.vue | 10 +- src/ui/ManagementPortal/pages/index/index.vue | 6 +- src/ui/ManagementPortal/pages/info.vue | 311 ++-- .../security/role-assignments/create.vue | 1284 +++++++------- .../edit/[roleAssignmentName].vue | 26 +- .../pages/security/role-assignments/index.vue | 66 +- src/ui/ManagementPortal/plugins/directives.ts | 12 +- .../ManagementPortal/server/api/api-status.ts | 52 +- .../ManagementPortal/stores/appConfigStore.ts | 4 +- src/ui/ManagementPortal/vitest.config.ts | 10 +- 25 files changed, 2823 insertions(+), 2663 deletions(-) diff --git a/src/ui/ManagementPortal/components/AccessControl.vue b/src/ui/ManagementPortal/components/AccessControl.vue index 4451957778..eef7276b4e 100644 --- a/src/ui/ManagementPortal/components/AccessControl.vue +++ b/src/ui/ManagementPortal/components/AccessControl.vue @@ -1,101 +1,100 @@ - - - \ No newline at end of file + + + diff --git a/src/ui/ManagementPortal/components/ApiStatusCard.vue b/src/ui/ManagementPortal/components/ApiStatusCard.vue index a6192efa25..101038deed 100644 --- a/src/ui/ManagementPortal/components/ApiStatusCard.vue +++ b/src/ui/ManagementPortal/components/ApiStatusCard.vue @@ -1,143 +1,143 @@ - - - - - + + + + + diff --git a/src/ui/ManagementPortal/components/NavigationBox.vue b/src/ui/ManagementPortal/components/NavigationBox.vue index 844b2649e8..c80a4ef9b7 100644 --- a/src/ui/ManagementPortal/components/NavigationBox.vue +++ b/src/ui/ManagementPortal/components/NavigationBox.vue @@ -1,80 +1,81 @@ - - - - - - \ No newline at end of file + + + + + diff --git a/src/ui/ManagementPortal/components/RoleAssignmentsTable.vue b/src/ui/ManagementPortal/components/RoleAssignmentsTable.vue index 4450bbc7b0..d07a49c93b 100644 --- a/src/ui/ManagementPortal/components/RoleAssignmentsTable.vue +++ b/src/ui/ManagementPortal/components/RoleAssignmentsTable.vue @@ -1,292 +1,298 @@ - - - - - + + + + + diff --git a/src/ui/ManagementPortal/components/Sidebar.vue b/src/ui/ManagementPortal/components/Sidebar.vue index b5e8f2a09c..7000add8ac 100644 --- a/src/ui/ManagementPortal/components/Sidebar.vue +++ b/src/ui/ManagementPortal/components/Sidebar.vue @@ -58,7 +58,9 @@ Security - Instance Access Control + Instance Access Control -