diff --git a/frontend/src/component/App.tsx b/frontend/src/component/App.tsx
index d5b4f9162a..993faa9c12 100644
--- a/frontend/src/component/App.tsx
+++ b/frontend/src/component/App.tsx
@@ -19,6 +19,7 @@ import { useStyles } from './App.styles';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import useProjects from '../hooks/api/getters/useProjects/useProjects';
import { useLastViewedProject } from '../hooks/useLastViewedProject';
+import Maintenance from './maintenance/Maintenance';
const InitialRedirect = () => {
const { lastViewed } = useLastViewedProject();
@@ -57,7 +58,7 @@ export const App = () => {
const hasFetchedAuth = Boolean(authDetails || user);
const { classes: styles } = useStyles();
- const { isOss } = useUiConfig();
+ const { isOss, uiConfig } = useUiConfig();
const availableRoutes = isOss()
? routes.filter(route => !route.enterprise)
@@ -73,6 +74,12 @@ export const App = () => {
show={}
elseShow={
<>
+ }
+ />
diff --git a/frontend/src/component/maintenance/Maintenance.tsx b/frontend/src/component/maintenance/Maintenance.tsx
new file mode 100644
index 0000000000..2fbc0337aa
--- /dev/null
+++ b/frontend/src/component/maintenance/Maintenance.tsx
@@ -0,0 +1,35 @@
+import { styled } from '@mui/material';
+import { ErrorOutlineRounded } from '@mui/icons-material';
+
+const StyledErrorRoundedIcon = styled(ErrorOutlineRounded)(({ theme }) => ({
+ height: '20px',
+ width: '20px',
+ marginRight: theme.spacing(1),
+}));
+
+const StyledDiv = styled('div')(({ theme }) => ({
+ display: 'flex',
+ fontSize: theme.fontSizes.smallBody,
+ justifyContent: 'center',
+ alignItems: 'center',
+ color: theme.palette.error.main,
+ backgroundColor: theme.palette.error.light,
+ height: '65px',
+ borderBottom: `1px solid ${theme.palette.error.border}`,
+ whiteSpace: 'pre-wrap',
+}));
+
+const Maintenance = () => {
+ return (
+
+
+ Maintenance Mode!
+
+ Any changes you make during maintenance mode will not be saved.
+ We apologize for any inconvenience this may cause.
+
+
+ );
+};
+
+export default Maintenance;
diff --git a/frontend/src/hooks/api/getters/useAuth/useAuthEndpoint.ts b/frontend/src/hooks/api/getters/useAuth/useAuthEndpoint.ts
index 3e7cb15bb2..ca8abfc5f5 100644
--- a/frontend/src/hooks/api/getters/useAuth/useAuthEndpoint.ts
+++ b/frontend/src/hooks/api/getters/useAuth/useAuthEndpoint.ts
@@ -42,7 +42,7 @@ export interface IAuthSplash {
[key: string]: boolean;
}
-interface IUseAuthEndpointOutput {
+export interface IUseAuthEndpointOutput {
data?: AuthEndpointResponse;
refetchAuth: () => void;
loading: boolean;
diff --git a/frontend/src/hooks/api/getters/useAuth/useAuthPermissions.ts b/frontend/src/hooks/api/getters/useAuth/useAuthPermissions.ts
index ab35cbb1d3..084a113034 100644
--- a/frontend/src/hooks/api/getters/useAuth/useAuthPermissions.ts
+++ b/frontend/src/hooks/api/getters/useAuth/useAuthPermissions.ts
@@ -1,5 +1,7 @@
import { IPermission } from 'interfaces/user';
-import { useAuthEndpoint } from './useAuthEndpoint';
+import { IUseAuthEndpointOutput, useAuthEndpoint } from './useAuthEndpoint';
+import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
+import { IUiConfig } from 'interfaces/uiConfig';
interface IUseAuthPermissionsOutput {
permissions?: IPermission[];
@@ -8,13 +10,23 @@ interface IUseAuthPermissionsOutput {
error?: Error;
}
-export const useAuthPermissions = (): IUseAuthPermissionsOutput => {
- const auth = useAuthEndpoint();
- const permissions =
- auth.data && 'permissions' in auth.data
+const getPermissions = (
+ auth: IUseAuthEndpointOutput,
+ uiConfig: IUiConfig
+): IPermission[] | undefined => {
+ let permissions =
+ auth.data && 'permissions' in auth.data && !uiConfig?.flags?.maintenance
? auth.data.permissions
: undefined;
+ return permissions;
+};
+
+export const useAuthPermissions = (): IUseAuthPermissionsOutput => {
+ const auth = useAuthEndpoint();
+ const { uiConfig } = useUiConfig();
+ const permissions = getPermissions(auth, uiConfig);
+
return {
permissions,
refetchPermissions: auth.refetchAuth,
diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts
index c088e22d66..4592776ade 100644
--- a/frontend/src/interfaces/uiConfig.ts
+++ b/frontend/src/interfaces/uiConfig.ts
@@ -44,6 +44,7 @@ export interface IFlags {
variantsPerEnvironment?: boolean;
favorites?: boolean;
networkView?: boolean;
+ maintenance?: boolean;
}
export interface IVersionInfo {
diff --git a/src/lib/__snapshots__/create-config.test.ts.snap b/src/lib/__snapshots__/create-config.test.ts.snap
index e30a0f219d..a58f8af3f4 100644
--- a/src/lib/__snapshots__/create-config.test.ts.snap
+++ b/src/lib/__snapshots__/create-config.test.ts.snap
@@ -74,6 +74,7 @@ exports[`should create default config 1`] = `
"embedProxy": true,
"embedProxyFrontend": true,
"favorites": false,
+ "maintenance": false,
"networkView": false,
"proxyReturnAllToggles": false,
"responseTimeWithAppName": false,
@@ -89,6 +90,7 @@ exports[`should create default config 1`] = `
"embedProxy": true,
"embedProxyFrontend": true,
"favorites": false,
+ "maintenance": false,
"networkView": false,
"proxyReturnAllToggles": false,
"responseTimeWithAppName": false,
diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts
index d4d697a5a0..66b215f1d6 100644
--- a/src/lib/types/experimental.ts
+++ b/src/lib/types/experimental.ts
@@ -38,6 +38,10 @@ export const defaultExperimentalOptions = {
process.env.UNLEASH_EXPERIMENTAL_FAVORITES,
false,
),
+ maintenance: parseEnvVarBoolean(
+ process.env.UNLEASH_EXPERIMENTAL_MAINTENANCE,
+ false,
+ ),
networkView: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_NETWORK_VIEW,
false,
@@ -59,6 +63,7 @@ export interface IExperimentalOptions {
variantsPerEnvironment?: boolean;
favorites?: boolean;
networkView?: boolean;
+ maintenance?: boolean;
};
externalResolver: IExternalFlagResolver;
}
diff --git a/src/server-dev.ts b/src/server-dev.ts
index 1d4bbdf880..5116842781 100644
--- a/src/server-dev.ts
+++ b/src/server-dev.ts
@@ -42,6 +42,7 @@ process.nextTick(async () => {
changeRequests: true,
favorites: true,
variantsPerEnvironment: true,
+ maintenance: false,
},
},
authentication: {