mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-06 07:10:28 +00:00
[React] Settings state manager (#5687)
* Add interface definition for settings * Fetch global and user settings as state object * Cleanup dead code * Fetch settings when performing token login
This commit is contained in:
parent
bf7c1b43bd
commit
0925fbbad2
@ -16,7 +16,9 @@ import { PlaceholderPill } from '../items/Placeholder';
|
|||||||
|
|
||||||
export function MainMenu() {
|
export function MainMenu() {
|
||||||
const { classes, theme } = InvenTreeStyle();
|
const { classes, theme } = InvenTreeStyle();
|
||||||
const [username] = useUserState((state) => [state.user?.name]);
|
const [username] = useUserState((state) => [
|
||||||
|
state.user?.name ?? state.user?.username
|
||||||
|
]);
|
||||||
return (
|
return (
|
||||||
<Menu width={260} position="bottom-end">
|
<Menu width={260} position="bottom-end">
|
||||||
<Menu.Target>
|
<Menu.Target>
|
||||||
|
@ -7,6 +7,10 @@ import { api } from '../App';
|
|||||||
import { ApiPaths, url, useServerApiState } from '../states/ApiState';
|
import { ApiPaths, url, useServerApiState } from '../states/ApiState';
|
||||||
import { useLocalState } from '../states/LocalState';
|
import { useLocalState } from '../states/LocalState';
|
||||||
import { useSessionState } from '../states/SessionState';
|
import { useSessionState } from '../states/SessionState';
|
||||||
|
import {
|
||||||
|
useGlobalSettingsState,
|
||||||
|
useUserSettingsState
|
||||||
|
} from '../states/SettingsState';
|
||||||
import { useUserState } from '../states/UserState';
|
import { useUserState } from '../states/UserState';
|
||||||
|
|
||||||
export const doClassicLogin = async (username: string, password: string) => {
|
export const doClassicLogin = async (username: string, password: string) => {
|
||||||
@ -56,14 +60,19 @@ export const doSimpleLogin = async (email: string) => {
|
|||||||
return mail;
|
return mail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Perform a login using a token
|
||||||
export const doTokenLogin = (token: string) => {
|
export const doTokenLogin = (token: string) => {
|
||||||
const { setToken } = useSessionState.getState();
|
const { setToken } = useSessionState.getState();
|
||||||
const { fetchUserState } = useUserState.getState();
|
const { fetchUserState } = useUserState.getState();
|
||||||
const { fetchServerApiState } = useServerApiState.getState();
|
const { fetchServerApiState } = useServerApiState.getState();
|
||||||
|
const globalSettingsState = useGlobalSettingsState.getState();
|
||||||
|
const userSettingsState = useUserSettingsState.getState();
|
||||||
|
|
||||||
setToken(token);
|
setToken(token);
|
||||||
fetchUserState();
|
fetchUserState();
|
||||||
fetchServerApiState();
|
fetchServerApiState();
|
||||||
|
globalSettingsState.fetchSettings();
|
||||||
|
userSettingsState.fetchSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
export function handleReset(navigate: any, values: { email: string }) {
|
export function handleReset(navigate: any, values: { email: string }) {
|
||||||
|
@ -4,31 +4,6 @@ import { api } from '../App';
|
|||||||
import { emptyServerAPI } from '../defaults/defaults';
|
import { emptyServerAPI } from '../defaults/defaults';
|
||||||
import { ServerAPIProps, UserProps } from './states';
|
import { ServerAPIProps, UserProps } from './states';
|
||||||
|
|
||||||
interface UserStateProps {
|
|
||||||
user: UserProps | undefined;
|
|
||||||
setUser: (newUser: UserProps) => void;
|
|
||||||
fetchApiState: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Global user information state, using Zustand manager
|
|
||||||
*/
|
|
||||||
export const useApiState = create<UserStateProps>((set, get) => ({
|
|
||||||
user: undefined,
|
|
||||||
setUser: (newUser: UserProps) => set({ user: newUser }),
|
|
||||||
fetchApiState: async () => {
|
|
||||||
// Fetch user data
|
|
||||||
await api.get(url(ApiPaths.user_me)).then((response) => {
|
|
||||||
const user: UserProps = {
|
|
||||||
name: `${response.data.first_name} ${response.data.last_name}`,
|
|
||||||
email: response.data.email,
|
|
||||||
username: response.data.username
|
|
||||||
};
|
|
||||||
set({ user: user });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface ServerApiStateProps {
|
interface ServerApiStateProps {
|
||||||
server: ServerAPIProps;
|
server: ServerAPIProps;
|
||||||
setServer: (newServer: ServerAPIProps) => void;
|
setServer: (newServer: ServerAPIProps) => void;
|
||||||
@ -55,6 +30,8 @@ export enum ApiPaths {
|
|||||||
user_reset = 'api-user-reset',
|
user_reset = 'api-user-reset',
|
||||||
user_reset_set = 'api-user-reset-set',
|
user_reset_set = 'api-user-reset-set',
|
||||||
|
|
||||||
|
settings_global_list = 'api-settings-global-list',
|
||||||
|
settings_user_list = 'api-settings-user-list',
|
||||||
notifications_list = 'api-notifications-list',
|
notifications_list = 'api-notifications-list',
|
||||||
|
|
||||||
barcode = 'api-barcode',
|
barcode = 'api-barcode',
|
||||||
@ -102,6 +79,10 @@ export function endpoint(path: ApiPaths): string {
|
|||||||
return '/auth/password/reset/';
|
return '/auth/password/reset/';
|
||||||
case ApiPaths.user_reset_set:
|
case ApiPaths.user_reset_set:
|
||||||
return '/auth/password/reset/confirm/';
|
return '/auth/password/reset/confirm/';
|
||||||
|
case ApiPaths.settings_global_list:
|
||||||
|
return 'settings/global/';
|
||||||
|
case ApiPaths.settings_user_list:
|
||||||
|
return 'settings/user/';
|
||||||
case ApiPaths.notifications_list:
|
case ApiPaths.notifications_list:
|
||||||
return 'notifications/';
|
return 'notifications/';
|
||||||
case ApiPaths.barcode:
|
case ApiPaths.barcode:
|
||||||
|
49
src/frontend/src/states/SettingsState.tsx
Normal file
49
src/frontend/src/states/SettingsState.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* State management for remote (server side) settings
|
||||||
|
*/
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
import { api } from '../App';
|
||||||
|
import { ApiPaths, url } from './ApiState';
|
||||||
|
import { Setting } from './states';
|
||||||
|
|
||||||
|
interface SettingsStateProps {
|
||||||
|
settings: Setting[];
|
||||||
|
fetchSettings: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State management for global (server side) settings
|
||||||
|
*/
|
||||||
|
export const useGlobalSettingsState = create<SettingsStateProps>(
|
||||||
|
(set, get) => ({
|
||||||
|
settings: [],
|
||||||
|
fetchSettings: async () => {
|
||||||
|
await api
|
||||||
|
.get(url(ApiPaths.settings_global_list))
|
||||||
|
.then((response) => {
|
||||||
|
set({ settings: response.data });
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error fetching global settings:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State management for user (server side) settings
|
||||||
|
*/
|
||||||
|
export const useUserSettingsState = create<SettingsStateProps>((set, get) => ({
|
||||||
|
settings: [],
|
||||||
|
fetchSettings: async () => {
|
||||||
|
await api
|
||||||
|
.get(url(ApiPaths.settings_user_list))
|
||||||
|
.then((response) => {
|
||||||
|
set({ settings: response.data });
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error fetching user settings:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
@ -37,6 +37,8 @@ export const useUserState = create<UserStateProps>((set, get) => ({
|
|||||||
.get(url(ApiPaths.user_roles))
|
.get(url(ApiPaths.user_roles))
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const user: UserProps = get().user as UserProps;
|
const user: UserProps = get().user as UserProps;
|
||||||
|
|
||||||
|
// Update user with role data
|
||||||
user.roles = response.data.roles;
|
user.roles = response.data.roles;
|
||||||
user.is_staff = response.data.is_staff ?? false;
|
user.is_staff = response.data.is_staff ?? false;
|
||||||
user.is_superuser = response.data.is_superuser ?? false;
|
user.is_superuser = response.data.is_superuser ?? false;
|
||||||
|
@ -29,6 +29,41 @@ export interface ServerAPIProps {
|
|||||||
active_plugins: PluginProps[];
|
active_plugins: PluginProps[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type interface defining a single 'setting' object
|
||||||
|
export interface Setting {
|
||||||
|
pk: number;
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
type: SettingType;
|
||||||
|
units: string;
|
||||||
|
choices: SettingChoice[];
|
||||||
|
model_name: string | null;
|
||||||
|
api_url: string | null;
|
||||||
|
typ: SettingTyp;
|
||||||
|
plugin?: string;
|
||||||
|
method?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SettingChoice {
|
||||||
|
value: string;
|
||||||
|
display_name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SettingTyp {
|
||||||
|
Inventree = 'inventree',
|
||||||
|
Plugin = 'plugin',
|
||||||
|
User = 'user',
|
||||||
|
Notification = 'notification'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SettingType {
|
||||||
|
Boolean = 'boolean',
|
||||||
|
Integer = 'integer',
|
||||||
|
String = 'string'
|
||||||
|
}
|
||||||
|
|
||||||
export interface PluginProps {
|
export interface PluginProps {
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
|
@ -9,12 +9,23 @@ import { url_base } from '../main';
|
|||||||
import { routes } from '../router';
|
import { routes } from '../router';
|
||||||
import { useLocalState } from '../states/LocalState';
|
import { useLocalState } from '../states/LocalState';
|
||||||
import { useSessionState } from '../states/SessionState';
|
import { useSessionState } from '../states/SessionState';
|
||||||
|
import {
|
||||||
|
useGlobalSettingsState,
|
||||||
|
useUserSettingsState
|
||||||
|
} from '../states/SettingsState';
|
||||||
import { useUserState } from '../states/UserState';
|
import { useUserState } from '../states/UserState';
|
||||||
|
|
||||||
export default function DesktopAppView() {
|
export default function DesktopAppView() {
|
||||||
const [hostList] = useLocalState((state) => [state.hostList]);
|
const [hostList] = useLocalState((state) => [state.hostList]);
|
||||||
const [fetchUserState] = useUserState((state) => [state.fetchUserState]);
|
const [fetchUserState] = useUserState((state) => [state.fetchUserState]);
|
||||||
|
|
||||||
|
const [fetchGlobalSettings] = useGlobalSettingsState((state) => [
|
||||||
|
state.fetchSettings
|
||||||
|
]);
|
||||||
|
const [fetchUserSettings] = useUserSettingsState((state) => [
|
||||||
|
state.fetchSettings
|
||||||
|
]);
|
||||||
|
|
||||||
// Local state initialization
|
// Local state initialization
|
||||||
if (Object.keys(hostList).length === 0) {
|
if (Object.keys(hostList).length === 0) {
|
||||||
console.log('Loading default host list');
|
console.log('Loading default host list');
|
||||||
@ -30,6 +41,8 @@ export default function DesktopAppView() {
|
|||||||
if (token && !fetchedServerSession) {
|
if (token && !fetchedServerSession) {
|
||||||
setFetchedServerSession(true);
|
setFetchedServerSession(true);
|
||||||
fetchUserState();
|
fetchUserState();
|
||||||
|
fetchGlobalSettings();
|
||||||
|
fetchUserSettings();
|
||||||
}
|
}
|
||||||
}, [token, fetchedServerSession]);
|
}, [token, fetchedServerSession]);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user