From ffa41825dddac0c365ccebfed5d26a1458c03d4a Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Sat, 4 Apr 2026 18:01:22 +0530 Subject: [PATCH] react-openapi and react-auth cleanup. index.ts for react-openapi --- react-auth/authClient.ts | 32 -- react-auth/props.ts | 0 react-openapi/Admin.tsx | 12 +- react-openapi/config.ts | 7 +- react-openapi/shared-theme/AppTheme.tsx | 53 --- .../shared-theme/ColorModeIconDropdown.tsx | 89 ---- .../shared-theme/ColorModeSelect.tsx | 28 -- .../customizations/dataDisplay.tsx | 233 --------- .../shared-theme/customizations/feedback.tsx | 46 -- .../shared-theme/customizations/inputs.tsx | 445 ------------------ .../customizations/navigation.tsx | 279 ----------- .../shared-theme/customizations/surfaces.ts | 113 ----- react-openapi/shared-theme/themePrimitives.ts | 403 ---------------- react-openapi/utils/openapi_loader.ts | 10 +- src/main.jsx | 9 +- 15 files changed, 26 insertions(+), 1733 deletions(-) delete mode 100644 react-auth/authClient.ts delete mode 100644 react-auth/props.ts delete mode 100644 react-openapi/shared-theme/AppTheme.tsx delete mode 100644 react-openapi/shared-theme/ColorModeIconDropdown.tsx delete mode 100644 react-openapi/shared-theme/ColorModeSelect.tsx delete mode 100644 react-openapi/shared-theme/customizations/dataDisplay.tsx delete mode 100644 react-openapi/shared-theme/customizations/feedback.tsx delete mode 100644 react-openapi/shared-theme/customizations/inputs.tsx delete mode 100644 react-openapi/shared-theme/customizations/navigation.tsx delete mode 100644 react-openapi/shared-theme/customizations/surfaces.ts delete mode 100644 react-openapi/shared-theme/themePrimitives.ts diff --git a/react-auth/authClient.ts b/react-auth/authClient.ts deleted file mode 100644 index bfcc0e4..0000000 --- a/react-auth/authClient.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { createApiClient } from "./axios"; -import { tokenStore } from "./token"; - -// @ts-ignore -const authApi = createApiClient(import.meta.env.VITE_AUTH_BASE_URL); - -export const authClient = { - async login(username: string, password: string) { - const res = await authApi.post("/login", { username, password }); - const { access_token } = res.data; - - if (!access_token) { - throw new Error("No access token returned"); - } - - tokenStore.set(access_token); - return this.getIdentity(); - }, - - logout() { - tokenStore.clear(); - }, - - async getIdentity() { - const res = await authApi.get("/me"); - return res.data; - }, - - isAuthenticated() { - return !!tokenStore.get(); - }, -}; diff --git a/react-auth/props.ts b/react-auth/props.ts deleted file mode 100644 index e69de29..0000000 diff --git a/react-openapi/Admin.tsx b/react-openapi/Admin.tsx index 5fd9bc6..e1ae5c2 100644 --- a/react-openapi/Admin.tsx +++ b/react-openapi/Admin.tsx @@ -113,15 +113,21 @@ function ResourceRouteWrapper() { return ; } -export default function Admin({ basePath = "/admin" }: { basePath?: string }) { +interface AdminProps { + basePath?: string; + resourceOverrides?: Record; + profileConfig?: any; +} + +export default function Admin({ basePath = "/admin", resourceOverrides = {}, profileConfig = {} }: AdminProps) { const [config, setConfig] = React.useState(null); React.useEffect(() => { - getAppConfig().then((cfg) => { + getAppConfig(resourceOverrides, profileConfig).then((cfg) => { initializeApiClients(cfg.baseUrl, cfg.authBaseUrl); setConfig(cfg); }); - }, []); + }, [resourceOverrides, profileConfig]); if (!config) { return ( diff --git a/react-openapi/config.ts b/react-openapi/config.ts index a78fe5c..d628a7e 100644 --- a/react-openapi/config.ts +++ b/react-openapi/config.ts @@ -1,13 +1,16 @@ import { AppConfig } from "./types/config"; import { loadConfigFromOpenApi } from "./utils/openapi_loader"; -export async function getAppConfig(): Promise { +export async function getAppConfig( + resourceOverrides: Record = {}, + profileConfig: any = {} +): Promise { // @ts-ignore const baseUrl = import.meta.env.VITE_API_BASE_URL // @ts-ignore const authBaseUrl = import.meta.env.VITE_AUTH_BASE_URL - const config = await loadConfigFromOpenApi(baseUrl); + const config = await loadConfigFromOpenApi(baseUrl, resourceOverrides, profileConfig); // You can still apply overrides here return { diff --git a/react-openapi/shared-theme/AppTheme.tsx b/react-openapi/shared-theme/AppTheme.tsx deleted file mode 100644 index a4a512c..0000000 --- a/react-openapi/shared-theme/AppTheme.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react'; -import { ThemeProvider, createTheme } from '@mui/material/styles'; -import type { ThemeOptions } from '@mui/material/styles'; -import { inputsCustomizations } from './customizations/inputs'; -import { dataDisplayCustomizations } from './customizations/dataDisplay'; -import { feedbackCustomizations } from './customizations/feedback'; -import { navigationCustomizations } from './customizations/navigation'; -import { surfacesCustomizations } from './customizations/surfaces'; -import { colorSchemes, typography, shadows, shape } from './themePrimitives'; - -interface AppThemeProps { - children: React.ReactNode; - /** - * This is for the docs site. You can ignore it or remove it. - */ - disableCustomTheme?: boolean; - themeComponents?: ThemeOptions['components']; -} - -export default function AppTheme(props: AppThemeProps) { - const { children, disableCustomTheme, themeComponents } = props; - const theme = React.useMemo(() => { - return disableCustomTheme - ? {} - : createTheme({ - // For more details about CSS variables configuration, see https://mui.com/material-ui/customization/css-theme-variables/configuration/ - cssVariables: { - colorSchemeSelector: 'data-mui-color-scheme', - cssVarPrefix: 'template', - }, - colorSchemes, // Recently added in v6 for building light & dark mode app, see https://mui.com/material-ui/customization/palette/#color-schemes - typography, - shadows, - shape, - components: { - ...inputsCustomizations, - ...dataDisplayCustomizations, - ...feedbackCustomizations, - ...navigationCustomizations, - ...surfacesCustomizations, - ...themeComponents, - }, - }); - }, [disableCustomTheme, themeComponents]); - if (disableCustomTheme) { - return {children}; - } - return ( - - {children} - - ); -} diff --git a/react-openapi/shared-theme/ColorModeIconDropdown.tsx b/react-openapi/shared-theme/ColorModeIconDropdown.tsx deleted file mode 100644 index 3af1e07..0000000 --- a/react-openapi/shared-theme/ColorModeIconDropdown.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import * as React from 'react'; -import DarkModeIcon from '@mui/icons-material/DarkModeRounded'; -import LightModeIcon from '@mui/icons-material/LightModeRounded'; -import Box from '@mui/material/Box'; -import IconButton, { IconButtonOwnProps } from '@mui/material/IconButton'; -import Menu from '@mui/material/Menu'; -import MenuItem from '@mui/material/MenuItem'; -import { useColorScheme } from '@mui/material/styles'; - -export default function ColorModeIconDropdown(props: IconButtonOwnProps) { - const { mode, systemMode, setMode } = useColorScheme(); - const [anchorEl, setAnchorEl] = React.useState(null); - const open = Boolean(anchorEl); - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - const handleClose = () => { - setAnchorEl(null); - }; - const handleMode = (targetMode: 'system' | 'light' | 'dark') => () => { - setMode(targetMode); - handleClose(); - }; - if (!mode) { - return ( - ({ - verticalAlign: 'bottom', - display: 'inline-flex', - width: '2.25rem', - height: '2.25rem', - borderRadius: (theme.vars || theme).shape.borderRadius, - border: '1px solid', - borderColor: (theme.vars || theme).palette.divider, - })} - /> - ); - } - const resolvedMode = (systemMode || mode) as 'light' | 'dark'; - const icon = { - light: , - dark: , - }[resolvedMode]; - return ( - - - {icon} - - - - System - - - Light - - - Dark - - - - ); -} diff --git a/react-openapi/shared-theme/ColorModeSelect.tsx b/react-openapi/shared-theme/ColorModeSelect.tsx deleted file mode 100644 index 6e71b9b..0000000 --- a/react-openapi/shared-theme/ColorModeSelect.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { useColorScheme } from '@mui/material/styles'; -import MenuItem from '@mui/material/MenuItem'; -import Select, { SelectProps } from '@mui/material/Select'; - -export default function ColorModeSelect(props: SelectProps) { - const { mode, setMode } = useColorScheme(); - if (!mode) { - return null; - } - return ( - - ); -} diff --git a/react-openapi/shared-theme/customizations/dataDisplay.tsx b/react-openapi/shared-theme/customizations/dataDisplay.tsx deleted file mode 100644 index b6b2b46..0000000 --- a/react-openapi/shared-theme/customizations/dataDisplay.tsx +++ /dev/null @@ -1,233 +0,0 @@ -import { Theme, alpha, Components } from '@mui/material/styles'; -import { svgIconClasses } from '@mui/material/SvgIcon'; -import { typographyClasses } from '@mui/material/Typography'; -import { buttonBaseClasses } from '@mui/material/ButtonBase'; -import { chipClasses } from '@mui/material/Chip'; -import { iconButtonClasses } from '@mui/material/IconButton'; -import { gray, red, green } from '../themePrimitives'; - -/* eslint-disable import/prefer-default-export */ -export const dataDisplayCustomizations: Components = { - MuiList: { - styleOverrides: { - root: { - padding: '8px', - display: 'flex', - flexDirection: 'column', - gap: 0, - }, - }, - }, - MuiListItem: { - styleOverrides: { - root: ({ theme }) => ({ - [`& .${svgIconClasses.root}`]: { - width: '1rem', - height: '1rem', - color: (theme.vars || theme).palette.text.secondary, - }, - [`& .${typographyClasses.root}`]: { - fontWeight: 500, - }, - [`& .${buttonBaseClasses.root}`]: { - display: 'flex', - gap: 8, - padding: '2px 8px', - borderRadius: (theme.vars || theme).shape.borderRadius, - opacity: 0.7, - '&.Mui-selected': { - opacity: 1, - backgroundColor: alpha(theme.palette.action.selected, 0.3), - [`& .${svgIconClasses.root}`]: { - color: (theme.vars || theme).palette.text.primary, - }, - '&:focus-visible': { - backgroundColor: alpha(theme.palette.action.selected, 0.3), - }, - '&:hover': { - backgroundColor: alpha(theme.palette.action.selected, 0.5), - }, - }, - '&:focus-visible': { - backgroundColor: 'transparent', - }, - }, - }), - }, - }, - MuiListItemText: { - styleOverrides: { - primary: ({ theme }) => ({ - fontSize: theme.typography.body2.fontSize, - fontWeight: 500, - lineHeight: theme.typography.body2.lineHeight, - }), - secondary: ({ theme }) => ({ - fontSize: theme.typography.caption.fontSize, - lineHeight: theme.typography.caption.lineHeight, - }), - }, - }, - MuiListSubheader: { - styleOverrides: { - root: ({ theme }) => ({ - backgroundColor: 'transparent', - padding: '4px 8px', - fontSize: theme.typography.caption.fontSize, - fontWeight: 500, - lineHeight: theme.typography.caption.lineHeight, - }), - }, - }, - MuiListItemIcon: { - styleOverrides: { - root: { - minWidth: 0, - }, - }, - }, - MuiChip: { - defaultProps: { - size: 'small', - }, - styleOverrides: { - root: ({ theme }) => ({ - border: '1px solid', - borderRadius: '999px', - [`& .${chipClasses.label}`]: { - fontWeight: 600, - }, - variants: [ - { - props: { - color: 'default', - }, - style: { - borderColor: gray[200], - backgroundColor: gray[100], - [`& .${chipClasses.label}`]: { - color: gray[500], - }, - [`& .${chipClasses.icon}`]: { - color: gray[500], - }, - ...theme.applyStyles('dark', { - borderColor: gray[700], - backgroundColor: gray[800], - [`& .${chipClasses.label}`]: { - color: gray[300], - }, - [`& .${chipClasses.icon}`]: { - color: gray[300], - }, - }), - }, - }, - { - props: { - color: 'success', - }, - style: { - borderColor: green[200], - backgroundColor: green[50], - [`& .${chipClasses.label}`]: { - color: green[500], - }, - [`& .${chipClasses.icon}`]: { - color: green[500], - }, - ...theme.applyStyles('dark', { - borderColor: green[800], - backgroundColor: green[900], - [`& .${chipClasses.label}`]: { - color: green[300], - }, - [`& .${chipClasses.icon}`]: { - color: green[300], - }, - }), - }, - }, - { - props: { - color: 'error', - }, - style: { - borderColor: red[100], - backgroundColor: red[50], - [`& .${chipClasses.label}`]: { - color: red[500], - }, - [`& .${chipClasses.icon}`]: { - color: red[500], - }, - ...theme.applyStyles('dark', { - borderColor: red[800], - backgroundColor: red[900], - [`& .${chipClasses.label}`]: { - color: red[200], - }, - [`& .${chipClasses.icon}`]: { - color: red[300], - }, - }), - }, - }, - { - props: { size: 'small' }, - style: { - maxHeight: 20, - [`& .${chipClasses.label}`]: { - fontSize: theme.typography.caption.fontSize, - }, - [`& .${svgIconClasses.root}`]: { - fontSize: theme.typography.caption.fontSize, - }, - }, - }, - { - props: { size: 'medium' }, - style: { - [`& .${chipClasses.label}`]: { - fontSize: theme.typography.caption.fontSize, - }, - }, - }, - ], - }), - }, - }, - MuiTablePagination: { - styleOverrides: { - actions: { - display: 'flex', - gap: 8, - marginRight: 6, - [`& .${iconButtonClasses.root}`]: { - minWidth: 0, - width: 36, - height: 36, - }, - }, - }, - }, - MuiIcon: { - defaultProps: { - fontSize: 'small', - }, - styleOverrides: { - root: { - variants: [ - { - props: { - fontSize: 'small', - }, - style: { - fontSize: '1rem', - }, - }, - ], - }, - }, - }, -}; diff --git a/react-openapi/shared-theme/customizations/feedback.tsx b/react-openapi/shared-theme/customizations/feedback.tsx deleted file mode 100644 index 6d475c9..0000000 --- a/react-openapi/shared-theme/customizations/feedback.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Theme, alpha, Components } from '@mui/material/styles'; -import { gray, orange } from '../themePrimitives'; - -/* eslint-disable import/prefer-default-export */ -export const feedbackCustomizations: Components = { - MuiAlert: { - styleOverrides: { - root: ({ theme }) => ({ - borderRadius: 10, - backgroundColor: orange[100], - color: (theme.vars || theme).palette.text.primary, - border: `1px solid ${alpha(orange[300], 0.5)}`, - '& .MuiAlert-icon': { - color: orange[500], - }, - ...theme.applyStyles('dark', { - backgroundColor: `${alpha(orange[900], 0.5)}`, - border: `1px solid ${alpha(orange[800], 0.5)}`, - }), - }), - }, - }, - MuiDialog: { - styleOverrides: { - root: ({ theme }) => ({ - '& .MuiDialog-paper': { - borderRadius: '10px', - border: '1px solid', - borderColor: (theme.vars || theme).palette.divider, - }, - }), - }, - }, - MuiLinearProgress: { - styleOverrides: { - root: ({ theme }) => ({ - height: 8, - borderRadius: 8, - backgroundColor: gray[200], - ...theme.applyStyles('dark', { - backgroundColor: gray[800], - }), - }), - }, - }, -}; diff --git a/react-openapi/shared-theme/customizations/inputs.tsx b/react-openapi/shared-theme/customizations/inputs.tsx deleted file mode 100644 index b384563..0000000 --- a/react-openapi/shared-theme/customizations/inputs.tsx +++ /dev/null @@ -1,445 +0,0 @@ -import * as React from 'react'; -import { alpha, Theme, Components } from '@mui/material/styles'; -import { outlinedInputClasses } from '@mui/material/OutlinedInput'; -import { svgIconClasses } from '@mui/material/SvgIcon'; -import { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup'; -import { toggleButtonClasses } from '@mui/material/ToggleButton'; -import CheckBoxOutlineBlankRoundedIcon from '@mui/icons-material/CheckBoxOutlineBlankRounded'; -import CheckRoundedIcon from '@mui/icons-material/CheckRounded'; -import RemoveRoundedIcon from '@mui/icons-material/RemoveRounded'; -import { gray, brand } from '../themePrimitives'; - -/* eslint-disable import/prefer-default-export */ -export const inputsCustomizations: Components = { - MuiButtonBase: { - defaultProps: { - disableTouchRipple: true, - disableRipple: true, - }, - styleOverrides: { - root: ({ theme }) => ({ - boxSizing: 'border-box', - transition: 'all 100ms ease-in', - '&:focus-visible': { - outline: `3px solid ${alpha(theme.palette.primary.main, 0.5)}`, - outlineOffset: '2px', - }, - }), - }, - }, - MuiButton: { - styleOverrides: { - root: ({ theme }) => ({ - boxShadow: 'none', - borderRadius: (theme.vars || theme).shape.borderRadius, - textTransform: 'none', - variants: [ - { - props: { - size: 'small', - }, - style: { - height: '2.25rem', - padding: '8px 12px', - }, - }, - { - props: { - size: 'medium', - }, - style: { - height: '2.5rem', // 40px - }, - }, - { - props: { - color: 'primary', - variant: 'contained', - }, - style: { - color: 'white', - backgroundColor: gray[900], - backgroundImage: `linear-gradient(to bottom, ${gray[700]}, ${gray[800]})`, - boxShadow: `inset 0 1px 0 ${gray[600]}, inset 0 -1px 0 1px hsl(220, 0%, 0%)`, - border: `1px solid ${gray[700]}`, - '&:hover': { - backgroundImage: 'none', - backgroundColor: gray[700], - boxShadow: 'none', - }, - '&:active': { - backgroundColor: gray[800], - }, - ...theme.applyStyles('dark', { - color: 'black', - backgroundColor: gray[50], - backgroundImage: `linear-gradient(to bottom, ${gray[100]}, ${gray[50]})`, - boxShadow: 'inset 0 -1px 0 hsl(220, 30%, 80%)', - border: `1px solid ${gray[50]}`, - '&:hover': { - backgroundImage: 'none', - backgroundColor: gray[300], - boxShadow: 'none', - }, - '&:active': { - backgroundColor: gray[400], - }, - }), - }, - }, - { - props: { - color: 'secondary', - variant: 'contained', - }, - style: { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', - }, - '&:active': { - backgroundColor: brand[700], - backgroundImage: 'none', - }, - }, - }, - { - props: { - variant: 'outlined', - }, - style: { - color: (theme.vars || theme).palette.text.primary, - border: '1px solid', - borderColor: gray[200], - backgroundColor: alpha(gray[50], 0.3), - '&:hover': { - backgroundColor: gray[100], - borderColor: gray[300], - }, - '&:active': { - backgroundColor: gray[200], - }, - ...theme.applyStyles('dark', { - backgroundColor: gray[800], - borderColor: gray[700], - - '&:hover': { - backgroundColor: gray[900], - borderColor: gray[600], - }, - '&:active': { - backgroundColor: gray[900], - }, - }), - }, - }, - { - props: { - color: 'secondary', - variant: 'outlined', - }, - style: { - color: brand[700], - border: '1px solid', - borderColor: brand[200], - backgroundColor: brand[50], - '&:hover': { - backgroundColor: brand[100], - borderColor: brand[400], - }, - '&:active': { - backgroundColor: alpha(brand[200], 0.7), - }, - ...theme.applyStyles('dark', { - color: brand[50], - border: '1px solid', - borderColor: brand[900], - backgroundColor: alpha(brand[900], 0.3), - '&:hover': { - borderColor: brand[700], - backgroundColor: alpha(brand[900], 0.6), - }, - '&:active': { - backgroundColor: alpha(brand[900], 0.5), - }, - }), - }, - }, - { - props: { - variant: 'text', - }, - style: { - color: gray[600], - '&:hover': { - backgroundColor: gray[100], - }, - '&:active': { - backgroundColor: gray[200], - }, - ...theme.applyStyles('dark', { - color: gray[50], - '&:hover': { - backgroundColor: gray[700], - }, - '&:active': { - backgroundColor: alpha(gray[700], 0.7), - }, - }), - }, - }, - { - props: { - color: 'secondary', - variant: 'text', - }, - style: { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[100], 0.5), - }, - '&:active': { - backgroundColor: alpha(brand[200], 0.7), - }, - ...theme.applyStyles('dark', { - color: brand[100], - '&:hover': { - backgroundColor: alpha(brand[900], 0.5), - }, - '&:active': { - backgroundColor: alpha(brand[900], 0.3), - }, - }), - }, - }, - ], - }), - }, - }, - MuiIconButton: { - styleOverrides: { - root: ({ theme }) => ({ - boxShadow: 'none', - borderRadius: (theme.vars || theme).shape.borderRadius, - textTransform: 'none', - fontWeight: theme.typography.fontWeightMedium, - letterSpacing: 0, - color: (theme.vars || theme).palette.text.primary, - border: '1px solid ', - borderColor: gray[200], - backgroundColor: alpha(gray[50], 0.3), - '&:hover': { - backgroundColor: gray[100], - borderColor: gray[300], - }, - '&:active': { - backgroundColor: gray[200], - }, - ...theme.applyStyles('dark', { - backgroundColor: gray[800], - borderColor: gray[700], - '&:hover': { - backgroundColor: gray[900], - borderColor: gray[600], - }, - '&:active': { - backgroundColor: gray[900], - }, - }), - variants: [ - { - props: { - size: 'small', - }, - style: { - width: '2.25rem', - height: '2.25rem', - padding: '0.25rem', - [`& .${svgIconClasses.root}`]: { fontSize: '1rem' }, - }, - }, - { - props: { - size: 'medium', - }, - style: { - width: '2.5rem', - height: '2.5rem', - }, - }, - ], - }), - }, - }, - MuiToggleButtonGroup: { - styleOverrides: { - root: ({ theme }) => ({ - borderRadius: '10px', - boxShadow: `0 4px 16px ${alpha(gray[400], 0.2)}`, - [`& .${toggleButtonGroupClasses.selected}`]: { - color: brand[500], - }, - ...theme.applyStyles('dark', { - [`& .${toggleButtonGroupClasses.selected}`]: { - color: '#fff', - }, - boxShadow: `0 4px 16px ${alpha(brand[700], 0.5)}`, - }), - }), - }, - }, - MuiToggleButton: { - styleOverrides: { - root: ({ theme }) => ({ - padding: '12px 16px', - textTransform: 'none', - borderRadius: '10px', - fontWeight: 500, - ...theme.applyStyles('dark', { - color: gray[400], - boxShadow: '0 4px 16px rgba(0, 0, 0, 0.5)', - [`&.${toggleButtonClasses.selected}`]: { - color: brand[300], - }, - }), - }), - }, - }, - MuiCheckbox: { - defaultProps: { - disableRipple: true, - icon: ( - - ), - checkedIcon: , - indeterminateIcon: , - }, - styleOverrides: { - root: ({ theme }) => ({ - margin: 10, - height: 16, - width: 16, - borderRadius: 5, - border: '1px solid ', - borderColor: alpha(gray[300], 0.8), - boxShadow: '0 0 0 1.5px hsla(210, 0%, 0%, 0.04) inset', - backgroundColor: alpha(gray[100], 0.4), - transition: 'border-color, background-color, 120ms ease-in', - '&:hover': { - borderColor: brand[300], - }, - '&.Mui-focusVisible': { - outline: `3px solid ${alpha(brand[500], 0.5)}`, - outlineOffset: '2px', - borderColor: brand[400], - }, - '&.Mui-checked': { - color: 'white', - backgroundColor: brand[500], - borderColor: brand[500], - boxShadow: `none`, - '&:hover': { - backgroundColor: brand[600], - }, - }, - ...theme.applyStyles('dark', { - borderColor: alpha(gray[700], 0.8), - boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', - backgroundColor: alpha(gray[900], 0.8), - '&:hover': { - borderColor: brand[300], - }, - '&.Mui-focusVisible': { - borderColor: brand[400], - outline: `3px solid ${alpha(brand[500], 0.5)}`, - outlineOffset: '2px', - }, - }), - }), - }, - }, - MuiInputBase: { - styleOverrides: { - root: { - border: 'none', - }, - input: { - '&::placeholder': { - opacity: 0.7, - color: gray[500], - }, - }, - }, - }, - MuiOutlinedInput: { - styleOverrides: { - input: { - padding: 0, - }, - root: ({ theme }) => ({ - padding: '8px 12px', - color: (theme.vars || theme).palette.text.primary, - borderRadius: (theme.vars || theme).shape.borderRadius, - border: `1px solid ${(theme.vars || theme).palette.divider}`, - backgroundColor: (theme.vars || theme).palette.background.default, - transition: 'border 120ms ease-in', - '&:hover': { - borderColor: gray[400], - }, - [`&.${outlinedInputClasses.focused}`]: { - outline: `3px solid ${alpha(brand[500], 0.5)}`, - borderColor: brand[400], - }, - ...theme.applyStyles('dark', { - '&:hover': { - borderColor: gray[500], - }, - }), - variants: [ - { - props: { - size: 'small', - }, - style: { - height: '2.25rem', - }, - }, - { - props: { - size: 'medium', - }, - style: { - height: '2.5rem', - }, - }, - ], - }), - notchedOutline: { - border: 'none', - }, - }, - }, - MuiInputAdornment: { - styleOverrides: { - root: ({ theme }) => ({ - color: (theme.vars || theme).palette.grey[500], - ...theme.applyStyles('dark', { - color: (theme.vars || theme).palette.grey[400], - }), - }), - }, - }, - MuiFormLabel: { - styleOverrides: { - root: ({ theme }) => ({ - typography: theme.typography.caption, - marginBottom: 8, - }), - }, - }, -}; diff --git a/react-openapi/shared-theme/customizations/navigation.tsx b/react-openapi/shared-theme/customizations/navigation.tsx deleted file mode 100644 index 3cb9713..0000000 --- a/react-openapi/shared-theme/customizations/navigation.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import * as React from 'react'; -import { Theme, alpha, Components } from '@mui/material/styles'; -import { SvgIconProps } from '@mui/material/SvgIcon'; -import { buttonBaseClasses } from '@mui/material/ButtonBase'; -import { dividerClasses } from '@mui/material/Divider'; -import { menuItemClasses } from '@mui/material/MenuItem'; -import { selectClasses } from '@mui/material/Select'; -import { tabClasses } from '@mui/material/Tab'; -import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; -import { gray, brand } from '../themePrimitives'; - -/* eslint-disable import/prefer-default-export */ -export const navigationCustomizations: Components = { - MuiMenuItem: { - styleOverrides: { - root: ({ theme }) => ({ - borderRadius: (theme.vars || theme).shape.borderRadius, - padding: '6px 8px', - [`&.${menuItemClasses.focusVisible}`]: { - backgroundColor: 'transparent', - }, - [`&.${menuItemClasses.selected}`]: { - [`&.${menuItemClasses.focusVisible}`]: { - backgroundColor: alpha(theme.palette.action.selected, 0.3), - }, - }, - }), - }, - }, - MuiMenu: { - styleOverrides: { - list: { - gap: '0px', - [`&.${dividerClasses.root}`]: { - margin: '0 -8px', - }, - }, - paper: ({ theme }) => ({ - marginTop: '4px', - borderRadius: (theme.vars || theme).shape.borderRadius, - border: `1px solid ${(theme.vars || theme).palette.divider}`, - backgroundImage: 'none', - background: 'hsl(0, 0%, 100%)', - boxShadow: - 'hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px', - [`& .${buttonBaseClasses.root}`]: { - '&.Mui-selected': { - backgroundColor: alpha(theme.palette.action.selected, 0.3), - }, - }, - ...theme.applyStyles('dark', { - background: gray[900], - boxShadow: - 'hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px', - }), - }), - }, - }, - MuiSelect: { - defaultProps: { - IconComponent: React.forwardRef((props, ref) => ( - - )), - }, - styleOverrides: { - root: ({ theme }) => ({ - borderRadius: (theme.vars || theme).shape.borderRadius, - border: '1px solid', - borderColor: gray[200], - backgroundColor: (theme.vars || theme).palette.background.paper, - boxShadow: `inset 0 1px 0 1px hsla(220, 0%, 100%, 0.6), inset 0 -1px 0 1px hsla(220, 35%, 90%, 0.5)`, - '&:hover': { - borderColor: gray[300], - backgroundColor: (theme.vars || theme).palette.background.paper, - boxShadow: 'none', - }, - [`&.${selectClasses.focused}`]: { - outlineOffset: 0, - borderColor: gray[400], - }, - '&:before, &:after': { - display: 'none', - }, - - ...theme.applyStyles('dark', { - borderRadius: (theme.vars || theme).shape.borderRadius, - borderColor: gray[700], - backgroundColor: (theme.vars || theme).palette.background.paper, - boxShadow: `inset 0 1px 0 1px ${alpha(gray[700], 0.15)}, inset 0 -1px 0 1px hsla(220, 0%, 0%, 0.7)`, - '&:hover': { - borderColor: alpha(gray[700], 0.7), - backgroundColor: (theme.vars || theme).palette.background.paper, - boxShadow: 'none', - }, - [`&.${selectClasses.focused}`]: { - outlineOffset: 0, - borderColor: gray[900], - }, - '&:before, &:after': { - display: 'none', - }, - }), - }), - select: ({ theme }) => ({ - display: 'flex', - alignItems: 'center', - ...theme.applyStyles('dark', { - display: 'flex', - alignItems: 'center', - '&:focus-visible': { - backgroundColor: gray[900], - }, - }), - }), - }, - }, - MuiLink: { - defaultProps: { - underline: 'none', - }, - styleOverrides: { - root: ({ theme }) => ({ - color: (theme.vars || theme).palette.text.primary, - fontWeight: 500, - position: 'relative', - textDecoration: 'none', - width: 'fit-content', - '&::before': { - content: '""', - position: 'absolute', - width: '100%', - height: '1px', - bottom: 0, - left: 0, - backgroundColor: (theme.vars || theme).palette.text.secondary, - opacity: 0.3, - transition: 'width 0.3s ease, opacity 0.3s ease', - }, - '&:hover::before': { - width: 0, - }, - '&:focus-visible': { - outline: `3px solid ${alpha(brand[500], 0.5)}`, - outlineOffset: '4px', - borderRadius: '2px', - }, - }), - }, - }, - MuiDrawer: { - styleOverrides: { - paper: ({ theme }) => ({ - backgroundColor: (theme.vars || theme).palette.background.default, - }), - }, - }, - MuiPaginationItem: { - styleOverrides: { - root: ({ theme }) => ({ - '&.Mui-selected': { - color: 'white', - backgroundColor: (theme.vars || theme).palette.grey[900], - }, - ...theme.applyStyles('dark', { - '&.Mui-selected': { - color: 'black', - backgroundColor: (theme.vars || theme).palette.grey[50], - }, - }), - }), - }, - }, - MuiTabs: { - styleOverrides: { - root: { minHeight: 'fit-content' }, - indicator: ({ theme }) => ({ - backgroundColor: (theme.vars || theme).palette.grey[800], - ...theme.applyStyles('dark', { - backgroundColor: (theme.vars || theme).palette.grey[200], - }), - }), - }, - }, - MuiTab: { - styleOverrides: { - root: ({ theme }) => ({ - padding: '6px 8px', - marginBottom: '8px', - textTransform: 'none', - minWidth: 'fit-content', - minHeight: 'fit-content', - color: (theme.vars || theme).palette.text.secondary, - borderRadius: (theme.vars || theme).shape.borderRadius, - border: '1px solid', - borderColor: 'transparent', - ':hover': { - color: (theme.vars || theme).palette.text.primary, - backgroundColor: gray[100], - borderColor: gray[200], - }, - [`&.${tabClasses.selected}`]: { - color: gray[900], - }, - ...theme.applyStyles('dark', { - ':hover': { - color: (theme.vars || theme).palette.text.primary, - backgroundColor: gray[800], - borderColor: gray[700], - }, - [`&.${tabClasses.selected}`]: { - color: '#fff', - }, - }), - }), - }, - }, - MuiStepConnector: { - styleOverrides: { - line: ({ theme }) => ({ - borderTop: '1px solid', - borderColor: (theme.vars || theme).palette.divider, - flex: 1, - borderRadius: '99px', - }), - }, - }, - MuiStepIcon: { - styleOverrides: { - root: ({ theme }) => ({ - color: 'transparent', - border: `1px solid ${gray[400]}`, - width: 12, - height: 12, - borderRadius: '50%', - '& text': { - display: 'none', - }, - '&.Mui-active': { - border: 'none', - color: (theme.vars || theme).palette.primary.main, - }, - '&.Mui-completed': { - border: 'none', - color: (theme.vars || theme).palette.success.main, - }, - ...theme.applyStyles('dark', { - border: `1px solid ${gray[700]}`, - '&.Mui-active': { - border: 'none', - color: (theme.vars || theme).palette.primary.light, - }, - '&.Mui-completed': { - border: 'none', - color: (theme.vars || theme).palette.success.light, - }, - }), - variants: [ - { - props: { completed: true }, - style: { - width: 12, - height: 12, - }, - }, - ], - }), - }, - }, - MuiStepLabel: { - styleOverrides: { - label: ({ theme }) => ({ - '&.Mui-completed': { - opacity: 0.6, - ...theme.applyStyles('dark', { opacity: 0.5 }), - }, - }), - }, - }, -}; diff --git a/react-openapi/shared-theme/customizations/surfaces.ts b/react-openapi/shared-theme/customizations/surfaces.ts deleted file mode 100644 index f47a6d8..0000000 --- a/react-openapi/shared-theme/customizations/surfaces.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { alpha, Theme, Components } from '@mui/material/styles'; -import { gray } from '../themePrimitives'; - -/* eslint-disable import/prefer-default-export */ -export const surfacesCustomizations: Components = { - MuiAccordion: { - defaultProps: { - elevation: 0, - disableGutters: true, - }, - styleOverrides: { - root: ({ theme }) => ({ - padding: 4, - overflow: 'clip', - backgroundColor: (theme.vars || theme).palette.background.default, - border: '1px solid', - borderColor: (theme.vars || theme).palette.divider, - ':before': { - backgroundColor: 'transparent', - }, - '&:not(:last-of-type)': { - borderBottom: 'none', - }, - '&:first-of-type': { - borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, - borderTopRightRadius: (theme.vars || theme).shape.borderRadius, - }, - '&:last-of-type': { - borderBottomLeftRadius: (theme.vars || theme).shape.borderRadius, - borderBottomRightRadius: (theme.vars || theme).shape.borderRadius, - }, - }), - }, - }, - MuiAccordionSummary: { - styleOverrides: { - root: ({ theme }) => ({ - border: 'none', - borderRadius: 8, - '&:hover': { backgroundColor: gray[50] }, - '&:focus-visible': { backgroundColor: 'transparent' }, - ...theme.applyStyles('dark', { - '&:hover': { backgroundColor: gray[800] }, - }), - }), - }, - }, - MuiAccordionDetails: { - styleOverrides: { - root: { mb: 20, border: 'none' }, - }, - }, - MuiPaper: { - defaultProps: { - elevation: 0, - }, - }, - MuiCard: { - styleOverrides: { - root: ({ theme }) => { - return { - padding: 16, - gap: 16, - transition: 'all 100ms ease', - backgroundColor: gray[50], - borderRadius: (theme.vars || theme).shape.borderRadius, - border: `1px solid ${(theme.vars || theme).palette.divider}`, - boxShadow: 'none', - ...theme.applyStyles('dark', { - backgroundColor: gray[800], - }), - variants: [ - { - props: { - variant: 'outlined', - }, - style: { - border: `1px solid ${(theme.vars || theme).palette.divider}`, - boxShadow: 'none', - background: 'hsl(0, 0%, 100%)', - ...theme.applyStyles('dark', { - background: alpha(gray[900], 0.4), - }), - }, - }, - ], - }; - }, - }, - }, - MuiCardContent: { - styleOverrides: { - root: { - padding: 0, - '&:last-child': { paddingBottom: 0 }, - }, - }, - }, - MuiCardHeader: { - styleOverrides: { - root: { - padding: 0, - }, - }, - }, - MuiCardActions: { - styleOverrides: { - root: { - padding: 0, - }, - }, - }, -}; diff --git a/react-openapi/shared-theme/themePrimitives.ts b/react-openapi/shared-theme/themePrimitives.ts deleted file mode 100644 index 97b2c3d..0000000 --- a/react-openapi/shared-theme/themePrimitives.ts +++ /dev/null @@ -1,403 +0,0 @@ -import { createTheme, alpha, PaletteMode, Shadows } from '@mui/material/styles'; - -declare module '@mui/material/Paper' { - interface PaperPropsVariantOverrides { - highlighted: true; - } -} -declare module '@mui/material/styles' { - interface ColorRange { - 50: string; - 100: string; - 200: string; - 300: string; - 400: string; - 500: string; - 600: string; - 700: string; - 800: string; - 900: string; - } - - interface PaletteColor extends ColorRange {} - - interface Palette { - baseShadow: string; - } -} - -const defaultTheme = createTheme(); - -const customShadows: Shadows = [...defaultTheme.shadows]; - -export const brand = { - 50: 'hsl(210, 100%, 95%)', - 100: 'hsl(210, 100%, 92%)', - 200: 'hsl(210, 100%, 80%)', - 300: 'hsl(210, 100%, 65%)', - 400: 'hsl(210, 98%, 48%)', - 500: 'hsl(210, 98%, 42%)', - 600: 'hsl(210, 98%, 55%)', - 700: 'hsl(210, 100%, 35%)', - 800: 'hsl(210, 100%, 16%)', - 900: 'hsl(210, 100%, 21%)', -}; - -export const gray = { - 50: 'hsl(220, 35%, 97%)', - 100: 'hsl(220, 30%, 94%)', - 200: 'hsl(220, 20%, 88%)', - 300: 'hsl(220, 20%, 80%)', - 400: 'hsl(220, 20%, 65%)', - 500: 'hsl(220, 20%, 42%)', - 600: 'hsl(220, 20%, 35%)', - 700: 'hsl(220, 20%, 25%)', - 800: 'hsl(220, 30%, 6%)', - 900: 'hsl(220, 35%, 3%)', -}; - -export const green = { - 50: 'hsl(120, 80%, 98%)', - 100: 'hsl(120, 75%, 94%)', - 200: 'hsl(120, 75%, 87%)', - 300: 'hsl(120, 61%, 77%)', - 400: 'hsl(120, 44%, 53%)', - 500: 'hsl(120, 59%, 30%)', - 600: 'hsl(120, 70%, 25%)', - 700: 'hsl(120, 75%, 16%)', - 800: 'hsl(120, 84%, 10%)', - 900: 'hsl(120, 87%, 6%)', -}; - -export const orange = { - 50: 'hsl(45, 100%, 97%)', - 100: 'hsl(45, 92%, 90%)', - 200: 'hsl(45, 94%, 80%)', - 300: 'hsl(45, 90%, 65%)', - 400: 'hsl(45, 90%, 40%)', - 500: 'hsl(45, 90%, 35%)', - 600: 'hsl(45, 91%, 25%)', - 700: 'hsl(45, 94%, 20%)', - 800: 'hsl(45, 95%, 16%)', - 900: 'hsl(45, 93%, 12%)', -}; - -export const red = { - 50: 'hsl(0, 100%, 97%)', - 100: 'hsl(0, 92%, 90%)', - 200: 'hsl(0, 94%, 80%)', - 300: 'hsl(0, 90%, 65%)', - 400: 'hsl(0, 90%, 40%)', - 500: 'hsl(0, 90%, 30%)', - 600: 'hsl(0, 91%, 25%)', - 700: 'hsl(0, 94%, 18%)', - 800: 'hsl(0, 95%, 12%)', - 900: 'hsl(0, 93%, 6%)', -}; - -export const getDesignTokens = (mode: PaletteMode) => { - customShadows[1] = - mode === 'dark' - ? 'hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px' - : 'hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px'; - - return { - palette: { - mode, - primary: { - light: brand[200], - main: brand[400], - dark: brand[700], - contrastText: brand[50], - ...(mode === 'dark' && { - contrastText: brand[50], - light: brand[300], - main: brand[400], - dark: brand[700], - }), - }, - info: { - light: brand[100], - main: brand[300], - dark: brand[600], - contrastText: gray[50], - ...(mode === 'dark' && { - contrastText: brand[300], - light: brand[500], - main: brand[700], - dark: brand[900], - }), - }, - warning: { - light: orange[300], - main: orange[400], - dark: orange[800], - ...(mode === 'dark' && { - light: orange[400], - main: orange[500], - dark: orange[700], - }), - }, - error: { - light: red[300], - main: red[400], - dark: red[800], - ...(mode === 'dark' && { - light: red[400], - main: red[500], - dark: red[700], - }), - }, - success: { - light: green[300], - main: green[400], - dark: green[800], - ...(mode === 'dark' && { - light: green[400], - main: green[500], - dark: green[700], - }), - }, - grey: { - ...gray, - }, - divider: mode === 'dark' ? alpha(gray[700], 0.6) : alpha(gray[300], 0.4), - background: { - default: 'hsl(0, 0%, 99%)', - paper: 'hsl(220, 35%, 97%)', - ...(mode === 'dark' && { default: gray[900], paper: 'hsl(220, 30%, 7%)' }), - }, - text: { - primary: gray[800], - secondary: gray[600], - warning: orange[400], - ...(mode === 'dark' && { primary: 'hsl(0, 0%, 100%)', secondary: gray[400] }), - }, - action: { - hover: alpha(gray[200], 0.2), - selected: `${alpha(gray[200], 0.3)}`, - ...(mode === 'dark' && { - hover: alpha(gray[600], 0.2), - selected: alpha(gray[600], 0.3), - }), - }, - }, - typography: { - fontFamily: 'Inter, sans-serif', - h1: { - fontSize: defaultTheme.typography.pxToRem(48), - fontWeight: 600, - lineHeight: 1.2, - letterSpacing: -0.5, - }, - h2: { - fontSize: defaultTheme.typography.pxToRem(36), - fontWeight: 600, - lineHeight: 1.2, - }, - h3: { - fontSize: defaultTheme.typography.pxToRem(30), - lineHeight: 1.2, - }, - h4: { - fontSize: defaultTheme.typography.pxToRem(24), - fontWeight: 600, - lineHeight: 1.5, - }, - h5: { - fontSize: defaultTheme.typography.pxToRem(20), - fontWeight: 600, - }, - h6: { - fontSize: defaultTheme.typography.pxToRem(18), - fontWeight: 600, - }, - subtitle1: { - fontSize: defaultTheme.typography.pxToRem(18), - }, - subtitle2: { - fontSize: defaultTheme.typography.pxToRem(14), - fontWeight: 500, - }, - body1: { - fontSize: defaultTheme.typography.pxToRem(14), - }, - body2: { - fontSize: defaultTheme.typography.pxToRem(14), - fontWeight: 400, - }, - caption: { - fontSize: defaultTheme.typography.pxToRem(12), - fontWeight: 400, - }, - }, - shape: { - borderRadius: 8, - }, - shadows: customShadows, - }; -}; - -export const colorSchemes = { - light: { - palette: { - primary: { - light: brand[200], - main: brand[400], - dark: brand[700], - contrastText: brand[50], - }, - info: { - light: brand[100], - main: brand[300], - dark: brand[600], - contrastText: gray[50], - }, - warning: { - light: orange[300], - main: orange[400], - dark: orange[800], - }, - error: { - light: red[300], - main: red[400], - dark: red[800], - }, - success: { - light: green[300], - main: green[400], - dark: green[800], - }, - grey: { - ...gray, - }, - divider: alpha(gray[300], 0.4), - background: { - default: 'hsl(0, 0%, 99%)', - paper: 'hsl(220, 35%, 97%)', - }, - text: { - primary: gray[800], - secondary: gray[600], - warning: orange[400], - }, - action: { - hover: alpha(gray[200], 0.2), - selected: `${alpha(gray[200], 0.3)}`, - }, - baseShadow: - 'hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px', - }, - }, - dark: { - palette: { - primary: { - contrastText: brand[50], - light: brand[300], - main: brand[400], - dark: brand[700], - }, - info: { - contrastText: brand[300], - light: brand[500], - main: brand[700], - dark: brand[900], - }, - warning: { - light: orange[400], - main: orange[500], - dark: orange[700], - }, - error: { - light: red[400], - main: red[500], - dark: red[700], - }, - success: { - light: green[400], - main: green[500], - dark: green[700], - }, - grey: { - ...gray, - }, - divider: alpha(gray[700], 0.6), - background: { - default: gray[900], - paper: 'hsl(220, 30%, 7%)', - }, - text: { - primary: 'hsl(0, 0%, 100%)', - secondary: gray[400], - }, - action: { - hover: alpha(gray[600], 0.2), - selected: alpha(gray[600], 0.3), - }, - baseShadow: - 'hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px', - }, - }, -}; - -export const typography = { - fontFamily: 'Inter, sans-serif', - h1: { - fontSize: defaultTheme.typography.pxToRem(48), - fontWeight: 600, - lineHeight: 1.2, - letterSpacing: -0.5, - }, - h2: { - fontSize: defaultTheme.typography.pxToRem(36), - fontWeight: 600, - lineHeight: 1.2, - }, - h3: { - fontSize: defaultTheme.typography.pxToRem(30), - lineHeight: 1.2, - }, - h4: { - fontSize: defaultTheme.typography.pxToRem(24), - fontWeight: 600, - lineHeight: 1.5, - }, - h5: { - fontSize: defaultTheme.typography.pxToRem(20), - fontWeight: 600, - }, - h6: { - fontSize: defaultTheme.typography.pxToRem(18), - fontWeight: 600, - }, - subtitle1: { - fontSize: defaultTheme.typography.pxToRem(18), - }, - subtitle2: { - fontSize: defaultTheme.typography.pxToRem(14), - fontWeight: 500, - }, - body1: { - fontSize: defaultTheme.typography.pxToRem(14), - }, - body2: { - fontSize: defaultTheme.typography.pxToRem(14), - fontWeight: 400, - }, - caption: { - fontSize: defaultTheme.typography.pxToRem(12), - fontWeight: 400, - }, -}; - -export const shape = { - borderRadius: 8, -}; - -// @ts-ignore -const defaultShadows: Shadows = [ - 'none', - 'var(--template-palette-baseShadow)', - ...defaultTheme.shadows.slice(2), -]; -export const shadows = defaultShadows; diff --git a/react-openapi/utils/openapi_loader.ts b/react-openapi/utils/openapi_loader.ts index c40571f..c99ca42 100644 --- a/react-openapi/utils/openapi_loader.ts +++ b/react-openapi/utils/openapi_loader.ts @@ -1,6 +1,5 @@ import SwaggerParser from "@apidevtools/swagger-parser"; import { AppConfig, ResourceConfig, ResourceField, FieldType } from "../types/config"; -import { configuration, profileConfiguration } from "../../src/openapi-config"; /** * Maps OpenAPI property types to our internal FieldType @@ -40,7 +39,8 @@ function mapOpenApiType(prop: any): FieldType { function parseSchemaFields( schema: any, resourceName: string, - schemaToResourceMap: Map + schemaToResourceMap: Map, + configuration: Record = {} ): Record { const fields: Record = {}; const properties = schema.properties || {}; @@ -84,7 +84,7 @@ function parseSchemaFields( // Recursively parse nested objects (only if not a relation) if (fields[key].type === "object" && prop.properties && !relation) { - fields[key].schema = parseSchemaFields(prop, resourceName, schemaToResourceMap); + fields[key].schema = parseSchemaFields(prop, resourceName, schemaToResourceMap, configuration); } } @@ -94,7 +94,7 @@ function parseSchemaFields( /** * Scans paths to identify resources and their basic configuration */ -export async function loadConfigFromOpenApi(baseUrl: string): Promise { +export async function loadConfigFromOpenApi(baseUrl: string, configuration: Record = {}, profileConfiguration: any = {}): Promise { // Use SwaggerParser to dereference the spec. // Dereferencing preserves object identity for $ref targets. const api = await SwaggerParser.dereference( @@ -150,7 +150,7 @@ export async function loadConfigFromOpenApi(baseUrl: string): Promise const label = name.charAt(0).toUpperCase() + name.slice(1, -1); const pluralLabel = name.charAt(0).toUpperCase() + name.slice(1); - const fields = parseSchemaFields(schema, name, schemaToResourceMap); + const fields = parseSchemaFields(schema, name, schemaToResourceMap, configuration); const resourceOverride = configuration[name] || {}; diff --git a/src/main.jsx b/src/main.jsx index c27071a..fae4cae 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -11,7 +11,8 @@ import { Toolbar } from "@mui/material"; import Home from './Home'; -import Admin from '../react-openapi/Admin'; +import { Admin, initializeApiClients } from '../react-openapi'; +import { configuration, profileConfiguration } from './openapi-config'; import { Buffer } from 'buffer'; import process from 'process'; import { AuthProvider } from "../react-auth"; @@ -25,8 +26,12 @@ window.process = process; const rootElement = document.getElementById('root'); const root = createRoot(rootElement); +const API_BASE = import.meta.env.VITE_API_BASE_URL; const AUTH_BASE = import.meta.env.VITE_AUTH_BASE_URL; +// Initialize global API clients so all components across khata-ui have generic API access +initializeApiClients(API_BASE, AUTH_BASE); + const routerMapping = [ { path: "/", component: Home, headerTitle: "Home" }, { path: "/home", component: Home, headerTitle: "Home" }, @@ -50,7 +55,7 @@ root.render( path={path} element={ path.startsWith("/admin") ? ( - + ) : ( )