Skip to content

Commit

Permalink
feat: ✨ upsert settings in db
Browse files Browse the repository at this point in the history
  • Loading branch information
clairenollet committed Sep 17, 2024
1 parent 1d1ba40 commit 204ef98
Show file tree
Hide file tree
Showing 17 changed files with 236 additions and 220 deletions.
26 changes: 14 additions & 12 deletions apps/client/cypress/e2e/specs/admin/system-settings.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SystemSettings } from '@cpn-console/shared'
import { type SystemSettings, SystemSettingsSchema } from '@cpn-console/shared'
import { getModel } from '../../support/func.js'

describe('Administration system settings', () => {
Expand All @@ -7,7 +7,7 @@ describe('Administration system settings', () => {
beforeEach(() => {
cy.intercept('GET', 'api/v1/system/settings?key=maintenance').as('listMaintenanceSetting')
cy.intercept('GET', 'api/v1/system/settings').as('listSystemSettings')
cy.intercept('POST', 'api/v1/system/settings').as('upsertSystemSetting')
cy.intercept('POST', 'api/v1/system/settings').as('upsertSystemSettings')

cy.kcLogin('tcolin')
cy.visit('/admin/system-settings')
Expand All @@ -29,12 +29,13 @@ describe('Administration system settings', () => {
cy.getByDataTestid(`toggle-maintenance`)
.find('input')
.check({ force: true })
cy.wait('@upsertSystemSetting').its('response').then(($response) => {

cy.getByDataTestid('button-submit')
.click()

cy.wait('@upsertSystemSettings').its('response').then(($response) => {
expect($response?.statusCode).to.match(/^20\d$/)
expect(JSON.stringify($response?.body)).to.equal(JSON.stringify({
key: 'maintenance',
value: 'on',
}))
expect(JSON.stringify($response?.body)).to.equal(JSON.stringify(SystemSettingsSchema.parse({})))
})

cy.visit('/projects')
Expand Down Expand Up @@ -83,12 +84,13 @@ describe('Administration system settings', () => {
cy.getByDataTestid(`toggle-maintenance`)
.find('input')
.uncheck({ force: true })
cy.wait('@upsertSystemSetting').its('response').then(($response) => {

cy.getByDataTestid('button-submit')
.click()

cy.wait('@upsertSystemSettings').its('response').then(($response) => {
expect($response?.statusCode).to.match(/^20\d$/)
expect(JSON.stringify($response?.body)).to.equal(JSON.stringify({
key: 'maintenance',
value: 'off',
}))
expect(JSON.stringify($response?.body)).to.equal(JSON.stringify(SystemSettingsSchema.parse({})))
})

cy.visit('/projects')
Expand Down
11 changes: 5 additions & 6 deletions apps/client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,18 @@ watch(label, (label: string) => {
const systemSettings = ref<SystemSettings>()
const serviceStore = useServiceStore()
onBeforeMount(() => {
serviceStore.startHealthPolling()
serviceStore.checkServicesHealth()
systemStore.listSystemSettings()
onBeforeMount(async () => {
await serviceStore.startHealthPolling()
await serviceStore.checkServicesHealth()
await systemStore.listSystemSettings()
systemSettings.value = systemStore.systemSettings
})
</script>

<template>
<DsfrHeader
:service-title="systemSettings?.appName ?? 'Console Cloud π Native'"
:logo-text="systemSettings?.appSubTitle ?? ['Ministère', 'de l’intérieur', 'et des outre-mer']"
:logo-text="systemSettings?.appSubTitle.split(',') ?? ['Ministère', 'de l’intérieur', 'et des outre-mer']"
:quick-links="quickLinks"
/>
<DsfrNotice
Expand Down
40 changes: 14 additions & 26 deletions apps/client/src/stores/system-settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { apiClient } from '../api/xhr-client.js'
import { useSystemSettingsStore } from './system-settings.js'

const listSystemSettings = vi.spyOn(apiClient.SystemSettings, 'listSystemSettings')
const upsertSystemSetting = vi.spyOn(apiClient.SystemSettings, 'upsertSystemSetting')
const upsertSystemSettings = vi.spyOn(apiClient.SystemSettings, 'upsertSystemSettings')

describe('system Settings Store', () => {
beforeEach(() => {
Expand All @@ -15,41 +15,29 @@ describe('system Settings Store', () => {
})

it('should get system settings list by api call', async () => {
const data = [
{ key: 'maintenace', value: 'on' },
{ key: 'theme', value: 'dsfr' },
{ key: 'organisation', value: 'miom' },
]
listSystemSettings.mockReturnValueOnce(Promise.resolve({ status: 200, body: data }))
const sytemSettings = { maintenace: 'on', theme: 'dsfr', organisation: 'miom' }
// @ts-expect-error TS2345
listSystemSettings.mockReturnValueOnce(Promise.resolve({ status: 200, body: sytemSettings }))
const systemSettingsStore = useSystemSettingsStore()

await systemSettingsStore.listSystemSettings()

expect(systemSettingsStore.systemSettings).toEqual(data)
expect(systemSettingsStore.systemSettings).toEqual(sytemSettings)
expect(listSystemSettings).toHaveBeenCalledTimes(1)
})

it('should upsert a system setting by api call', async () => {
const data = [
{ key: 'maintenace', value: 'on' },
{ key: 'theme', value: 'dsfr' },
{ key: 'organisation', value: 'miom' },
]
const newSystemSetting = { key: 'organisation', value: 'mj' }
const newData = [
{ key: 'maintenace', value: 'on' },
{ key: 'theme', value: 'dsfr' },
{ key: 'organisation', value: 'mj' },
]

upsertSystemSetting.mockReturnValueOnce(Promise.resolve({ status: 201, body: newSystemSetting }))
const sytemSettings = { maintenace: 'on', theme: 'dsfr', organisation: 'miom' }
const newSystemSettings = { maintenace: 'on', theme: 'dsfr', organisation: 'mj' }

// @ts-expect-error TS2345
upsertSystemSettings.mockReturnValueOnce(Promise.resolve({ status: 201, body: newSystemSettings }))
const systemSettingsStore = useSystemSettingsStore()
systemSettingsStore.systemSettings = data
systemSettingsStore.systemSettings = sytemSettings

const res = await systemSettingsStore.upsertSystemSetting(data)
await systemSettingsStore.upsertSystemSettings(sytemSettings)

expect(res).toEqual(newSystemSetting)
expect(systemSettingsStore.systemSettings).toEqual(newData)
expect(upsertSystemSetting).toHaveBeenCalledTimes(1)
expect(systemSettingsStore.systemSettings).toEqual(newSystemSettings)
expect(upsertSystemSettings).toHaveBeenCalledTimes(1)
})
})
15 changes: 6 additions & 9 deletions apps/client/src/stores/system-settings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import type {
SystemSettings,
UpsertSystemSettingsBody,
} from '@cpn-console/shared'
import { apiClient, extractData } from '@/api/xhr-client.js'

Expand All @@ -12,18 +13,14 @@ export const useSystemSettingsStore = defineStore('systemSettings', () => {
.then(response => extractData(response, 200))
}

// const upsertSystemSetting = async (newSystemSetting: UpsertSystemSettingBody) => {
// const res = await apiClient.SystemSettings.upsertSystemSetting({ body: newSystemSetting })
// .then(response => extractData(response, 201))
// systemSettings.value = systemSettings.value
// .toSpliced(systemSettings.value
// .findIndex(systemSetting => systemSetting.key === res.key), 1, res)
// return res
// }
const upsertSystemSettings = async (newSystemSetting: UpsertSystemSettingsBody) => {
systemSettings.value = await apiClient.SystemSettings.upsertSystemSettings({ body: newSystemSetting })
.then(response => extractData(response, 201))
}

return {
systemSettings,
listSystemSettings,
// upsertSystemSetting,
upsertSystemSettings,
}
})
90 changes: 50 additions & 40 deletions apps/client/src/views/admin/SystemSettings.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script lang="ts" setup>
import type { SystemSettings } from '@cpn-console/shared'
import { useSystemSettingsStore } from '@/stores/system-settings.js'
import { useSnackbarStore } from '@/stores/snackbar.js'
const systemStore = useSystemSettingsStore()
const updated = ref<Record<string, Record<string, string>>>({})
// permet de definir quel input choisir ??
// function refTheValues(settings: SystemSetting[]) {
// return settings.map((setting) => {
Expand All @@ -18,63 +17,74 @@ const updated = ref<Record<string, Record<string, string>>>({})
const systemSettings = ref<SystemSettings>()
// reload les settings
async function reload() {
onBeforeMount(async () => {
await systemStore.listSystemSettings()
systemSettings.value = systemStore.systemSettings
})
updated.value = {}
function updateMaintenance(value: boolean) {
if (!systemSettings.value) return
systemSettings.value.maintenance = value ? 'on' : 'off'
}
onBeforeMount(async () => {
// await systemStore.listSystemSettings()
reload()
})
// A modifié pour save les settings dynamiquement
async function upsertSystemSetting(key: string, value: boolean) {
// await systemStore.upsertSystemSetting({ key, value: value ? 'on' : 'off' })
console.log(key + value)
async function upsertSystemSetting() {
if (!systemSettings.value) return
await systemStore.upsertSystemSettings(systemSettings.value)
systemSettings.value = systemStore.systemSettings
useSnackbarStore().setMessage('Réglages mis à jour', 'success')
}
</script>

<template>
<h1>Réglages de la console Cloud π Native</h1>
<DsfrNotice
v-if="!systemSettings"
title="Aucun réglage à configurer."
/>
<div
class="flex <md:flex-col items-center justify-between gap-2 mt-8"
v-else
>
<!-- {{ systemSettings }} -->
<DsfrToggleSwitch
:model-value="systemSettings.maintenance === 'on'"
:label="`${systemSettings.maintenance === 'on' ? 'Désactiver' : 'Activer'} le mode maintenance`"
data-testid="toggle-maintenance"
@update:model-value="(event: boolean) => upsertSystemSetting('maintenance', event)"
/>
<DsfrInput
v-model="systemSettings.appName"
data-testid="input-appName"
label="appName"
label-visible
/>
<DsfrInput
v-model="systemSettings.contactMail"
data-testid="input-contactMail"
label="contactMail"
label-visible
/>
<DsfrInput
v-model="systemSettings.appSubTitle"
data-testid="input-appSubTitle"
label="appSubTitle"
label-visible
<div
class="flex flex-col gap-2 my-8"
>
<DsfrToggleSwitch
:model-value="systemSettings.maintenance === 'on'"
:label="`${systemSettings.maintenance === 'on' ? 'Désactiver' : 'Activer'} le mode maintenance`"
data-testid="toggle-maintenance"
@update:model-value="(event: boolean) => updateMaintenance(event)"
/>
<DsfrInput
v-model="systemSettings.appName"
data-testid="input-appName"
label="appName"
label-visible
/>
<DsfrInput
v-model="systemSettings.contactMail"
data-testid="input-contactMail"
label="contactMail"
label-visible
/>
<DsfrInput
v-model="systemSettings.appSubTitle"
data-testid="input-appSubTitle"
label="appSubTitle"
label-visible
/>
</div>
<DsfrButton
label="Enregistrer"
data-testid="button-submit"
secondary
@click="upsertSystemSetting()"
/>
</div>
</template>

<!-- <template>
<h1>Réglages de la console Cloud π Native</h1>
<div
v-if="!systemStore.systemSettings.length"
v-if="!systemStore.systemSettings?.length"
class="flex <md:flex-col-reverse items-center justify-between gap-2 mt-8"
>
<div> -->
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ vi.mock('./models/user.js', () => getModel('getUserModel'))
vi.mock('./models/users-projects.js', () => getModel('getRolesModel'))
vi.mock('./models/organization.js', () => getModel('getOrganizationModel'))
vi.mock('./models/zone.js', () => getModel('getZoneModel'))
vi.mock('./models/system-setting.js', () => getModel('getSystemSetting'))
vi.mock('./prisma.js')

vi.spyOn(app, 'listen')
Expand Down
15 changes: 11 additions & 4 deletions apps/server/src/resources/system/settings/business.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import type { UpsertSystemSettingsBody } from '@cpn-console/shared'
import type { SystemSettings, UpsertSystemSettingsBody } from '@cpn-console/shared'
import { upsertSystemSetting as upsertSystemSettingQuery } from './queries.js'

import { config } from '@/utils/config.js'
import { getConfig } from '@/utils/config.js'

export function getSystemSettings(key?: keyof typeof config) {
export async function getSystemSettings(key?: keyof SystemSettings) {
const config = await getConfig()
if (key) {
return { [key]: config[key] }
} else {
return config
}
}

export const upsertSystemSettings = (newSystemSetting: UpsertSystemSettingsBody) => upsertSystemSettingQuery(newSystemSetting)
export async function upsertSystemSettings(newSystemSettings: UpsertSystemSettingsBody) {
if (!newSystemSettings) return getSystemSettings()
for (const [key, value] of Object.entries(newSystemSettings)) {
await upsertSystemSettingQuery({ key, value })
}
return getSystemSettings()
}
14 changes: 13 additions & 1 deletion apps/server/src/resources/system/settings/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,16 @@ export function upsertSystemSetting(newSystemSetting: SystemSetting) {
})
}

export const getSystemSettings = (where?: Prisma.SystemSettingWhereInput) => prisma.systemSetting.findMany({ where })
export async function getSystemSettings(where?: Prisma.SystemSettingWhereInput) {
const res = await prisma.systemSetting.findMany({ where })
if (res === undefined || typeof res != 'object') {
return {}
} else {
res.reduce((acc, curr) => {
return {
...acc,
[curr.key]: curr.value,
}
}, {})
}
}
Loading

0 comments on commit 204ef98

Please sign in to comment.