Skip to content

Commit

Permalink
Add page to manage settings of AI
Browse files Browse the repository at this point in the history
  • Loading branch information
Zorin95670 committed Oct 24, 2024
1 parent 9e4a03f commit e628709
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/components/drawer/ApplicationDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ const menuList = ref([
url: '/libraries',
name: 'libraries',
},
{
icon: t('ApplicationDrawer.icon.ai'),
label: t('ApplicationDrawer.text.ai'),
url: '/ai',
name: 'ai',
},
]);
</script>

Expand Down
9 changes: 9 additions & 0 deletions src/i18n/en-US/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ export default {
groups: 'User Groups',
libraries: 'Libraries',
roles: 'Roles',
ai: 'AI settings',
},
icon: {
users: 'fa-solid fa-user',
groups: 'fa-solid fa-users',
libraries: 'fa-solid fa-book-open',
roles: 'fa-solid fa-screwdriver-wrench',
ai: 'fa-solid fa-toolbox',
},
},
ApplicationFooter: {
Expand All @@ -36,6 +38,13 @@ export default {
title: 'Users',
},
},
AISettingsPage: {
text: {
title: 'AI settings',
configurationsTab: 'Configuration',
secretsTab: 'Secrets',
},
},
GroupsPage: {
text: {
title: 'User Groups',
Expand Down
10 changes: 10 additions & 0 deletions src/layouts/MainLayout.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<template>
<q-layout view="hHh lpR fFf">
<application-header />

<application-drawer />

<q-page-container>
<router-view />
</q-page-container>

<application-footer />

<add-secret-dialog />
<remove-library-dialog />
<remove-user-dialog />
<remove-group-dialog />
<remove-role-dialog />
<remove-secret-dialog />
<detach-group-from-user-dialog />
<detach-user-from-group-dialog />
<detach-role-from-user-dialog />
Expand All @@ -23,6 +29,7 @@
<attach-access-control-to-another-dialog />
<attach-permission-to-role-dialog />
<redirect-dialog />
<update-secret-dialog />
</q-layout>
</template>
<script setup>
Expand All @@ -46,4 +53,7 @@ import AttachUserToRoleDialog from 'components/dialog/AttachUserToRoleDialog.vue
import AttachAccessControlToAnotherDialog from 'components/dialog/AttachAccessControlToAnotherDialog.vue';
import AttachPermissionToRoleDialog from 'components/dialog/AttachPermissionToRoleDialog.vue';
import RedirectDialog from 'components/dialog/RedirectDialog.vue';
import RemoveSecretDialog from 'components/dialog/RemoveSecretDialog.vue';
import AddSecretDialog from 'components/dialog/AddSecretDialog.vue';
import UpdateSecretDialog from 'components/dialog/UpdateSecretDialog.vue';
</script>
95 changes: 95 additions & 0 deletions src/pages/AISettingsPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<q-page class="column bg-grey-1">
<q-card class="no-border-radius">
<q-card-section class="q-py-none q-pt-md">
<h4
class="q-mx-none q-mt-md q-mb-sm"
data-cy="page_ai-settings_title"
>
{{ $t('AISettingsPage.text.title') }}
</h4>
</q-card-section>
<q-card-section class="q-pa-none">
<q-tabs
:model-value="currentTab"
no-caps
active-color="primary"
align="left"
@update:model-value="updateUrl"
>
<q-tab
name="configurations"
:label="$t('AISettingsPage.text.configurationsTab')"
data-cy="page_ai-settings_configurations_tab"
/>
<q-tab
name="secrets"
:label="$t('AISettingsPage.text.secretsTab')"
data-cy="page_ai-settings_secrets_tab"
/>
</q-tabs>
</q-card-section>
<q-linear-progress
v-if="loading"
indeterminate
color="primary"
data-cy="page_ai-settings_loading"
/>
</q-card>
<q-tab-panels
:model-value="currentTab"
animated
transition-prev="jump-up"
transition-next="jump-down"
class="bg-grey-1"
@update:model-value="updateUrl"
>

Check warning on line 46 in src/pages/AISettingsPage.vue

View workflow job for this annotation

GitHub Actions / Code style

Expected 1 line break after opening tag (`<q-tab-panels>`), but 2 line breaks found

<configurations-tab-panel
name="configurations"
@update:configurations-query="(v) => setTabsQuery('configurations', v)"
/>
<secrets-tab-panel
name="secrets"
@update:secrets-query="(v) => setTabsQuery('secrets', v)"
/>
</q-tab-panels>
</q-page>
</template>

<script setup>
import { computed, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import ConfigurationsTabPanel from 'components/tab-panel/ConfigurationsTabPanel.vue';
import SecretsTabPanel from 'components/tab-panel/SecretsTabPanel.vue';
const route = useRoute();
const router = useRouter();
const loading = ref(false);
const tabsQuery = ref({
configurations: {},
secrets: {},
});
const currentTab = computed(() => route.query.tab || 'configurations');
/**
* Update url with current tab query params.
* @param {string} tab - Tab Name.
*/
function updateUrl(tab) {
const query = { tab, ...tabsQuery.value[tab] };
const queryString = new URLSearchParams(query).toString();
router.push(`/ai?${queryString}`);
}
/**
* Set tabsQuery and call updateUrl.
* @param {string} tab - Tab name.
* @param {object} query - Query params object emitted from corresponding tab.
*/
function setTabsQuery(tab, query) {
tabsQuery.value[tab] = query;
updateUrl(tab);
}
</script>
10 changes: 10 additions & 0 deletions src/router/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ const routes = [
{ path: '/add-library', component: () => import('pages/AddLibraryPage.vue') },
],
},
{
path: '/ai',
meta: {
name: 'ai',
},
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('pages/AISettingsPage.vue') },
],
},
{
path: '/:catchAll(.*)*',
component: () => import('pages/ErrorNotFound.vue'),
Expand Down
76 changes: 76 additions & 0 deletions tests/unit/pages/AISettingsPage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-vitest';
import { shallowMount } from '@vue/test-utils';
import AISettingsPage from 'pages/AISettingsPage.vue';
import { Notify } from 'quasar';
import { vi } from 'vitest';
import { useRoute, useRouter } from 'vue-router';

installQuasarPlugin({
plugins: [Notify],
});

vi.mock('vue-router');

describe('Test component: AISettingsPage', () => {
let wrapper;
let push;

beforeEach(() => {
Notify.create = vi.fn();
push = vi.fn();

useRoute.mockImplementation(() => ({
query: {
tab: 'secrets',
},
}));

useRouter.mockImplementation(() => ({ push }));

wrapper = shallowMount(AISettingsPage);
});

describe('Test computed: currentTab', () => {
it('should be "secrets"', () => {
expect(wrapper.vm.currentTab).toBe('secrets');
});

it('should be "configurations" when route.query.tab is undefined', () => {
useRoute.mockImplementation(() => ({
params: { login: 'id1' },
query: {},
}));

wrapper = shallowMount(AISettingsPage);

expect(wrapper.vm.currentTab).toBe('configurations');
});
});

describe('Test function: updateUrl', () => {
it('should update the URL with current tab query params', () => {
wrapper.vm.tabsQuery = { secrets: { page: 1 } };

wrapper.vm.updateUrl('secrets');

expect(push).toBeCalledWith('/ai?tab=secrets&page=1');
});
});

describe('Test function: setTabsQuery', () => {
it('should set tabsQuery and call updateUrl', () => {
wrapper.vm.tabsQuery = {
configurations: {},
secrets: {},
};

wrapper.vm.setTabsQuery('secrets', { page: 1 });

expect(wrapper.vm.tabsQuery).toEqual({
configurations: {},
secrets: { page: 1 },
});
expect(push).toBeCalledWith('/ai?tab=secrets&page=1');
});
});
});

0 comments on commit e628709

Please sign in to comment.