Преглед изворни кода

feat(settings): add enable guest dashboard toggle

Nicolas Meienberger пре 1 година
родитељ
комит
c0723257e6

+ 27 - 1
src/app/(dashboard)/settings/components/SettingsForm/SettingsForm.tsx

@@ -4,10 +4,11 @@ import { IconAdjustmentsAlt, IconUser } from '@tabler/icons-react';
 import clsx from 'clsx';
 import clsx from 'clsx';
 import { useTranslations } from 'next-intl';
 import { useTranslations } from 'next-intl';
 import React, { useEffect } from 'react';
 import React, { useEffect } from 'react';
-import { useForm } from 'react-hook-form';
+import { Controller, useForm } from 'react-hook-form';
 import { Tooltip } from 'react-tooltip';
 import { Tooltip } from 'react-tooltip';
 import validator from 'validator';
 import validator from 'validator';
 import { Locale } from '@/shared/internationalization/locales';
 import { Locale } from '@/shared/internationalization/locales';
+import { Switch } from '@/components/ui/Switch';
 import { LanguageSelector } from '../../../../components/LanguageSelector';
 import { LanguageSelector } from '../../../../components/LanguageSelector';
 
 
 export type SettingsFormValues = {
 export type SettingsFormValues = {
@@ -17,6 +18,7 @@ export type SettingsFormValues = {
   domain?: string;
   domain?: string;
   storagePath?: string;
   storagePath?: string;
   localDomain?: string;
   localDomain?: string;
+  guestDashboard?: boolean;
 };
 };
 
 
 interface IProps {
 interface IProps {
@@ -62,6 +64,7 @@ export const SettingsForm = (props: IProps) => {
     handleSubmit,
     handleSubmit,
     setValue,
     setValue,
     setError,
     setError,
+    control,
     formState: { errors, isDirty },
     formState: { errors, isDirty },
   } = useForm<SettingsFormValues>();
   } = useForm<SettingsFormValues>();
 
 
@@ -113,6 +116,29 @@ export const SettingsForm = (props: IProps) => {
           <h2 className="text-2xl font-bold">{t('title')}</h2>
           <h2 className="text-2xl font-bold">{t('title')}</h2>
         </div>
         </div>
         <p className="mb-4">{t('subtitle')}</p>
         <p className="mb-4">{t('subtitle')}</p>
+        <div className="mb-3">
+          <Controller
+            control={control}
+            name="guestDashboard"
+            defaultValue={false}
+            render={({ field: { onChange, value, ref, ...rest } }) => (
+              <Switch
+                className="mb-3"
+                ref={ref}
+                checked={value}
+                onCheckedChange={onChange}
+                {...rest}
+                label={
+                  <>
+                    {t('guest-dashboard')}
+                    <Tooltip anchorSelect=".guest-dashboard-hint">{t('guest-dashboard-hint')}</Tooltip>
+                    <span className={clsx('ms-1 form-help guest-dashboard-hint')}>?</span>
+                  </>
+                }
+              />
+            )}
+          />
+        </div>
         <div className="mb-3">
         <div className="mb-3">
           <Input
           <Input
             {...register('domain')}
             {...register('domain')}

+ 3 - 0
src/app/actions/settings/update-settings.ts

@@ -4,6 +4,7 @@ import { action } from '@/lib/safe-action';
 import { getUserFromCookie } from '@/server/common/session.helpers';
 import { getUserFromCookie } from '@/server/common/session.helpers';
 import { settingsSchema } from '@runtipi/shared';
 import { settingsSchema } from '@runtipi/shared';
 import { setSettings } from '@/server/core/TipiConfig';
 import { setSettings } from '@/server/core/TipiConfig';
+import { revalidatePath } from 'next/cache';
 import { handleActionError } from '../utils/handle-action-error';
 import { handleActionError } from '../utils/handle-action-error';
 
 
 /**
 /**
@@ -19,6 +20,8 @@ export const updateSettingsAction = action(settingsSchema, async (settings) => {
 
 
     await setSettings(settings);
     await setSettings(settings);
 
 
+    revalidatePath('/');
+
     return { success: true };
     return { success: true };
   } catch (e) {
   } catch (e) {
     return handleActionError(e);
     return handleActionError(e);

+ 17 - 11
src/server/core/TipiConfig/TipiConfig.ts

@@ -42,24 +42,30 @@ export class TipiConfig {
       status: 'RUNNING',
       status: 'RUNNING',
       storagePath: conf.STORAGE_PATH,
       storagePath: conf.STORAGE_PATH,
       demoMode: conf.DEMO_MODE,
       demoMode: conf.DEMO_MODE,
+      guestDashboard: conf.GUEST_DASHBOARD,
       seePreReleaseVersions: false,
       seePreReleaseVersions: false,
     };
     };
 
 
+    const parsedConfig = envSchema.safeParse({ ...envConfig, ...this.getFileConfig() });
+    if (parsedConfig.success) {
+      this.config = parsedConfig.data;
+    } else {
+      const errors = formatErrors(parsedConfig.error.flatten());
+      Logger.error(`❌ Invalid env config ${JSON.stringify(errors)}`);
+    }
+  }
+
+  private getFileConfig() {
     const fileConfig = readJsonFile('/runtipi/state/settings.json') || {};
     const fileConfig = readJsonFile('/runtipi/state/settings.json') || {};
     const parsedFileConfig = envSchema.partial().safeParse(fileConfig);
     const parsedFileConfig = envSchema.partial().safeParse(fileConfig);
 
 
     if (parsedFileConfig.success) {
     if (parsedFileConfig.success) {
-      const parsedConfig = envSchema.safeParse({ ...envConfig, ...parsedFileConfig.data });
-      if (parsedConfig.success) {
-        this.config = parsedConfig.data;
-      } else {
-        const errors = formatErrors(parsedConfig.error.flatten());
-        Logger.error(`❌ Invalid env config ${JSON.stringify(errors)}`);
-      }
-    } else {
-      const errors = formatErrors(parsedFileConfig.error.flatten());
-      Logger.error(`❌ Invalid settings.json file: ${JSON.stringify(errors)}`);
+      return parsedFileConfig.data;
     }
     }
+
+    Logger.error(`❌ Invalid settings.json file: ${JSON.stringify(parsedFileConfig.error.flatten())}`);
+
+    return {};
   }
   }
 
 
   public static getInstance(): TipiConfig {
   public static getInstance(): TipiConfig {
@@ -70,7 +76,7 @@ export class TipiConfig {
   }
   }
 
 
   public getConfig() {
   public getConfig() {
-    return this.config;
+    return { ...this.config, ...this.getFileConfig() };
   }
   }
 
 
   public getSettings() {
   public getSettings() {