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}
-
-
-
- );
-}
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") ? (
-
+
) : (
)