mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
fix: load config on runtime
This commit is contained in:
parent
d2555d9f94
commit
aa05fe1704
@ -16,6 +16,11 @@ services:
|
|||||||
- ../api/migrations:/app/migrations
|
- ../api/migrations:/app/migrations
|
||||||
#- ../api/node_modules:/app/node_modules
|
#- ../api/node_modules:/app/node_modules
|
||||||
command: ["npm", "run", "start:debug"]
|
command: ["npm", "run", "start:debug"]
|
||||||
|
|
||||||
|
hexabot-frontend:
|
||||||
|
build:
|
||||||
|
context: ../
|
||||||
|
dockerfile: ./frontend/Dockerfile
|
||||||
|
|
||||||
mongo-express:
|
mongo-express:
|
||||||
container_name: mongoUi
|
container_name: mongoUi
|
||||||
|
@ -30,7 +30,6 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
database-init:
|
database-init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: "wget --spider http://localhost:3000"
|
test: "wget --spider http://localhost:3000"
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@ -40,12 +39,7 @@ services:
|
|||||||
|
|
||||||
hexabot-frontend:
|
hexabot-frontend:
|
||||||
container_name: frontend
|
container_name: frontend
|
||||||
build:
|
image: hexabot-ui:latest
|
||||||
context: ../
|
|
||||||
dockerfile: ./frontend/Dockerfile
|
|
||||||
args:
|
|
||||||
- NEXT_PUBLIC_API_ORIGIN=${NEXT_PUBLIC_API_ORIGIN}
|
|
||||||
- NEXT_PUBLIC_SSO_ENABLED=${NEXT_PUBLIC_SSO_ENABLED}
|
|
||||||
env_file: .env
|
env_file: .env
|
||||||
ports:
|
ports:
|
||||||
- ${APP_FRONTEND_PORT}:8080
|
- ${APP_FRONTEND_PORT}:8080
|
||||||
|
@ -21,14 +21,6 @@ RUN \
|
|||||||
|
|
||||||
# Rebuild the source code only when needed
|
# Rebuild the source code only when needed
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
ARG NEXT_PUBLIC_API_ORIGIN
|
|
||||||
ENV NEXT_PUBLIC_API_ORIGIN=${NEXT_PUBLIC_API_ORIGIN}
|
|
||||||
ARG NEXT_PUBLIC_SSO_ENABLED
|
|
||||||
ENV NEXT_PUBLIC_SSO_ENABLED=${NEXT_PUBLIC_SSO_ENABLED}
|
|
||||||
|
|
||||||
ENV REACT_APP_WIDGET_API_URL=${NEXT_PUBLIC_API_ORIGIN}
|
|
||||||
ENV REACT_APP_WIDGET_CHANNEL=test
|
|
||||||
ENV REACT_APP_WIDGET_TOKEN=test
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@ -57,10 +49,6 @@ ENV NODE_ENV production
|
|||||||
# Uncomment the following line in case you want to disable telemetry during runtime.
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
# Set the environment variable API_ORIGIN
|
|
||||||
ENV NEXT_PUBLIC_API_ORIGIN ${NEXT_PUBLIC_API_ORIGIN:-"http://localhost:3000"}
|
|
||||||
ENV NEXT_PUBLIC_SSO_ENABLED ${NEXT_PUBLIC_SSO_ENABLED:-"false"}
|
|
||||||
|
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 nextjs
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
@ -4,6 +4,14 @@ import withTM from "next-transpile-modules";
|
|||||||
const apiUrl = process.env.NEXT_PUBLIC_API_ORIGIN || "http://localhost:4000/";
|
const apiUrl = process.env.NEXT_PUBLIC_API_ORIGIN || "http://localhost:4000/";
|
||||||
const url = new URL(apiUrl);
|
const url = new URL(apiUrl);
|
||||||
const nextConfig = withTM(["hexabot-widget"])({
|
const nextConfig = withTM(["hexabot-widget"])({
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: "/config",
|
||||||
|
destination: "/api/config",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
webpack(config, _options) {
|
webpack(config, _options) {
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
50
frontend/src/hooks/useConfig.tsx
Normal file
50
frontend/src/hooks/useConfig.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { createContext, useContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
const ConfigContext = createContext(null);
|
||||||
|
|
||||||
|
export interface IConfig {
|
||||||
|
NEXT_PUBLIC_API_ORIGIN: string;
|
||||||
|
NEXT_PUBLIC_SSO_ENABLED: boolean;
|
||||||
|
REACT_APP_WIDGET_API_URL: string;
|
||||||
|
REACT_APP_WIDGET_CHANNEL: string;
|
||||||
|
REACT_APP_WIDGET_TOKEN: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConfigProvider = ({ children }) => {
|
||||||
|
const [config, setConfig] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchConfig = async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch("/config");
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
setConfig(data);
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error("Failed to fetch configuration:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchConfig();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!config) {
|
||||||
|
// You can return a loader here if you want
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useConfig = () => {
|
||||||
|
const context = useContext(ConfigContext);
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
throw new Error("useConfig must be used within a ConfigProvider");
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
};
|
@ -20,6 +20,7 @@ import { ReactQueryDevtools } from "react-query/devtools";
|
|||||||
import { SnackbarCloseButton } from "@/app-components/displays/Toast/CloseButton";
|
import { SnackbarCloseButton } from "@/app-components/displays/Toast/CloseButton";
|
||||||
import { ApiClientProvider } from "@/hooks/useApiClient";
|
import { ApiClientProvider } from "@/hooks/useApiClient";
|
||||||
import { AuthProvider } from "@/hooks/useAuth";
|
import { AuthProvider } from "@/hooks/useAuth";
|
||||||
|
import { ConfigProvider } from "@/hooks/useConfig";
|
||||||
import { PermissionProvider } from "@/hooks/useHasPermission";
|
import { PermissionProvider } from "@/hooks/useHasPermission";
|
||||||
import { SettingsProvider } from "@/hooks/useSetting";
|
import { SettingsProvider } from "@/hooks/useSetting";
|
||||||
import { ToastProvider } from "@/hooks/useToast";
|
import { ToastProvider } from "@/hooks/useToast";
|
||||||
@ -69,33 +70,35 @@ const App = ({ Component, pageProps }: TAppPropsWithLayout) => {
|
|||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
<main className={roboto.className}>
|
<main className={roboto.className}>
|
||||||
<ThemeProvider theme={theme}>
|
<ConfigProvider>
|
||||||
<ToastProvider
|
<ThemeProvider theme={theme}>
|
||||||
maxSnack={3}
|
<ToastProvider
|
||||||
anchorOrigin={{ vertical: "top", horizontal: "center" }}
|
maxSnack={3}
|
||||||
action={(snackbarKey) => (
|
anchorOrigin={{ vertical: "top", horizontal: "center" }}
|
||||||
<SnackbarCloseButton snackbarKey={snackbarKey} />
|
action={(snackbarKey) => (
|
||||||
)}
|
<SnackbarCloseButton snackbarKey={snackbarKey} />
|
||||||
>
|
)}
|
||||||
<StyledEngineProvider injectFirst>
|
>
|
||||||
<QueryClientProvider client={queryClient}>
|
<StyledEngineProvider injectFirst>
|
||||||
<CssBaseline />
|
<QueryClientProvider client={queryClient}>
|
||||||
<ApiClientProvider>
|
<CssBaseline />
|
||||||
<AuthProvider>
|
<ApiClientProvider>
|
||||||
<PermissionProvider>
|
<AuthProvider>
|
||||||
<SettingsProvider>
|
<PermissionProvider>
|
||||||
<SocketProvider>
|
<SettingsProvider>
|
||||||
{getLayout(<Component {...pageProps} />)}
|
<SocketProvider>
|
||||||
</SocketProvider>
|
{getLayout(<Component {...pageProps} />)}
|
||||||
</SettingsProvider>
|
</SocketProvider>
|
||||||
</PermissionProvider>
|
</SettingsProvider>
|
||||||
</AuthProvider>
|
</PermissionProvider>
|
||||||
</ApiClientProvider>
|
</AuthProvider>
|
||||||
<ReactQueryDevtools initialIsOpen={false} />
|
</ApiClientProvider>
|
||||||
</QueryClientProvider>
|
<ReactQueryDevtools initialIsOpen={false} />
|
||||||
</StyledEngineProvider>
|
</QueryClientProvider>
|
||||||
</ToastProvider>
|
</StyledEngineProvider>
|
||||||
</ThemeProvider>
|
</ToastProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</ConfigProvider>
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
16
frontend/src/pages/api/config.ts
Normal file
16
frontend/src/pages/api/config.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
type ResponseData = {
|
||||||
|
apiUrl: string;
|
||||||
|
ssoEnabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse<ResponseData>,
|
||||||
|
) {
|
||||||
|
res.status(200).json({
|
||||||
|
apiUrl: process.env.NEXT_PUBLIC_API_ORIGIN || "http://localhost:3000",
|
||||||
|
ssoEnabled: process.env.NEXT_PUBLIC_SSO_ENABLED === "true" || false,
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user