Browse Source

change metrics settings in admin panel

pull/1655/head
Bernd Storath 6 months ago
parent
commit
a377532d22
  1. 2
      src/app/components/form/DateField.vue
  2. 26
      src/app/components/form/NullTextField.vue
  3. 1
      src/app/pages/admin.vue
  4. 14
      src/app/pages/admin/index.vue
  5. 3
      src/app/pages/admin/metrics.vue
  6. 23
      src/app/pages/me.vue
  7. 10
      src/app/pages/setup/1.vue
  8. 6
      src/server/api/admin/general.get.ts
  9. 30
      src/server/database/repositories/general/service.ts
  10. 9
      src/server/database/repositories/general/types.ts

2
src/app/components/form/DateField.vue

@ -14,7 +14,7 @@
<script lang="ts" setup>
defineProps<{ id: string; label: string }>();
const [data] = defineModel<string | null>({
const data = defineModel<string | null>({
set(value) {
const temp = value?.trim() ?? null;
if (temp === '') {

26
src/app/components/form/NullTextField.vue

@ -0,0 +1,26 @@
<template>
<Label :for="id" class="font-semibold md:align-middle md:leading-10">
{{ label }}
</Label>
<input
:id="id"
v-model.trim="data"
:name="id"
type="text"
class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/>
</template>
<script lang="ts" setup>
defineProps<{ id: string; label: string }>();
const data = defineModel<string | null>({
set(value) {
const temp = value?.trim() ?? null;
if (temp === '') {
return null;
}
return temp;
},
});
</script>

1
src/app/pages/admin.vue

@ -45,7 +45,6 @@ const menuItems = [
{ id: 'config', name: 'Config' },
{ id: 'interface', name: 'Interface' },
{ id: 'hooks', name: 'Hooks' },
{ id: 'metrics', name: 'Metrics' },
];
const activeMenuItem = computed(() => {

14
src/app/pages/admin/index.vue

@ -8,6 +8,20 @@
label="Session Timeout"
/>
</FormGroup>
<FormGroup>
<FormHeading>Metrics</FormHeading>
<FormNullTextField
id="password"
v-model="data.metricsPassword"
label="Password"
/>
<FormSwitchField
id="Prometheus"
v-model="data.metricsPrometheus"
label="Prometheus"
/>
<FormSwitchField id="JSON" v-model="data.metricsJson" label="JSON" />
</FormGroup>
<FormGroup>
<FormHeading>Actions</FormHeading>
<FormActionField type="submit" label="Save" />

3
src/app/pages/admin/metrics.vue

@ -1,3 +0,0 @@
<template><div></div></template>
<script lang="ts" setup></script>

23
src/app/pages/me.vue

@ -9,7 +9,11 @@
<FormGroup>
<FormHeading>{{ $t('me.sectionGeneral') }}</FormHeading>
<FormTextField id="name" v-model="name" :label="$t('name')" />
<FormTextField id="email" v-model="email" :label="$t('email')" />
<FormNullTextField
id="email"
v-model="email"
:label="$t('email')"
/>
<FormActionField type="submit" :label="$t('save')" />
</FormGroup>
</FormElement>
@ -49,20 +53,7 @@ authStore.update();
const toast = useToast();
const name = ref(authStore.userData?.name);
const rawEmail = ref(authStore.userData?.email);
const email = computed({
get: () => rawEmail.value ?? undefined,
set: (value) => {
const temp = value?.trim() ?? null;
if (temp === '') {
rawEmail.value = null;
return;
}
rawEmail.value = temp;
return;
},
});
const email = ref(authStore.userData?.email);
async function submit() {
try {
@ -70,7 +61,7 @@ async function submit() {
method: 'post',
body: {
name: name.value,
email: rawEmail.value,
email: email.value,
},
});
toast.showToast({

10
src/app/pages/setup/1.vue

@ -6,7 +6,9 @@
<div class="mb-8 flex justify-center">
<UiChooseLang />
</div>
<div><BaseButton @click="nextStep">Continue</BaseButton></div>
<div>
<NuxtLink to="/setup/2"><BaseButton>Continue</BaseButton></NuxtLink>
</div>
</div>
</template>
@ -17,10 +19,4 @@ definePageMeta({
const setupStore = useSetupStore();
setupStore.setStep(1);
const router = useRouter();
async function nextStep() {
router.push('/setup/2');
}
</script>

6
src/server/api/admin/general.get.ts

@ -1,6 +1,4 @@
export default definePermissionEventHandler(actions.ADMIN, async () => {
const sessionConfig = await Database.general.getSessionConfig();
return {
sessionTimeout: sessionConfig.sessionTimeout,
};
const generalConfig = await Database.general.getConfig();
return generalConfig;
});

30
src/server/database/repositories/general/service.ts

@ -29,25 +29,31 @@ function createPreparedStatement(db: DBType) {
},
})
.prepare(),
updateSetupStep: db
.update(general)
.set({
setupStep: sql.placeholder('setupStep') as never as number,
getConfig: db.query.general
.findFirst({
columns: {
sessionTimeout: true,
metricsPrometheus: true,
metricsJson: true,
metricsPassword: true,
},
})
.prepare(),
update: db
updateSetupStep: db
.update(general)
.set({
sessionTimeout: sql.placeholder('sessionTimeout') as never as number,
setupStep: sql.placeholder('setupStep') as never as number,
})
.prepare(),
};
}
export class GeneralService {
#db: DBType;
#statements: ReturnType<typeof createPreparedStatement>;
constructor(db: DBType) {
this.#db = db;
this.#statements = createPreparedStatement(db);
}
@ -102,6 +108,16 @@ export class GeneralService {
}
update(data: GeneralUpdateType) {
return this.#statements.update.execute(data);
return this.#db.update(general).set(data).execute();
}
async getConfig() {
const result = await this.#statements.getConfig.execute();
if (!result) {
throw new Error('General Config not found');
}
return result;
}
}

9
src/server/database/repositories/general/types.ts

@ -5,9 +5,18 @@ import z from 'zod';
export type GeneralType = InferSelectModel<typeof general>;
const sessionTimeout = z.number({ message: 'zod.general.sessionTimeout' });
const metricsEnabled = z.boolean({ message: 'zod.general.metricsEnabled' });
const metricsPassword = z
.string({ message: 'zod.general.metricsPassword' })
.min(1, { message: 'zod.general.metricsPasswordMin' })
// TODO: validate argon2 regex?
.nullable();
export const GeneralUpdateSchema = z.object({
sessionTimeout: sessionTimeout,
metricsPrometheus: metricsEnabled,
metricsJson: metricsEnabled,
metricsPassword: metricsPassword,
});
export type GeneralUpdateType = z.infer<typeof GeneralUpdateSchema>;

Loading…
Cancel
Save