mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
fix: avoid erasing previous environments data on refetch (#990)
* refactor: avoid duplicate useLoading call * fix: avoid erasing previous environments data on refetch * refactor: keep mutataion logic within useEnvironments
This commit is contained in:
parent
159c54ed37
commit
98b6214c28
@ -26,7 +26,8 @@ const EnvironmentList = () => {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
protected: false,
|
protected: false,
|
||||||
};
|
};
|
||||||
const { environments, refetchEnvironments } = useEnvironments();
|
const { environments, mutateEnvironments, refetchEnvironments } =
|
||||||
|
useEnvironments();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const { refetch: refetchProjectRolePermissions } =
|
const { refetch: refetchProjectRolePermissions } =
|
||||||
useProjectRolePermissions();
|
useProjectRolePermissions();
|
||||||
@ -52,7 +53,7 @@ const EnvironmentList = () => {
|
|||||||
const item = newEnvList.splice(dragIndex, 1)[0];
|
const item = newEnvList.splice(dragIndex, 1)[0];
|
||||||
|
|
||||||
newEnvList.splice(hoverIndex, 0, item);
|
newEnvList.splice(hoverIndex, 0, item);
|
||||||
refetchEnvironments({ environments: newEnvList }, false);
|
mutateEnvironments(newEnvList);
|
||||||
return newEnvList;
|
return newEnvList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,28 +1,23 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './ProjectEnvironment.styles';
|
import { useStyles } from './ProjectEnvironment.styles';
|
||||||
|
|
||||||
import useLoading from 'hooks/useLoading';
|
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
|
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
|
||||||
|
|
||||||
import ApiError from 'component/common/ApiError/ApiError';
|
import ApiError from 'component/common/ApiError/ApiError';
|
||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
|
import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
|
||||||
import useProject from 'hooks/api/getters/useProject/useProject';
|
import useProject from 'hooks/api/getters/useProject/useProject';
|
||||||
import { FormControlLabel, FormGroup } from '@mui/material';
|
import { FormControlLabel, FormGroup, Alert } from '@mui/material';
|
||||||
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
|
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
|
||||||
import EnvironmentDisableConfirm from './EnvironmentDisableConfirm/EnvironmentDisableConfirm';
|
import EnvironmentDisableConfirm from './EnvironmentDisableConfirm/EnvironmentDisableConfirm';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Alert } from '@mui/material';
|
|
||||||
import PermissionSwitch from 'component/common/PermissionSwitch/PermissionSwitch';
|
import PermissionSwitch from 'component/common/PermissionSwitch/PermissionSwitch';
|
||||||
import { IProjectEnvironment } from 'interfaces/environments';
|
import { IProjectEnvironment } from 'interfaces/environments';
|
||||||
import { getEnabledEnvs } from './helpers';
|
import { getEnabledEnvs } from './helpers';
|
||||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||||
import { useThemeStyles } from 'themes/themeStyles';
|
import { useThemeStyles } from 'themes/themeStyles';
|
||||||
import { isDescendantOrSelf } from '@testing-library/user-event/dist/types/utils';
|
|
||||||
|
|
||||||
interface IProjectEnvironmentListProps {
|
interface IProjectEnvironmentListProps {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
@ -45,7 +40,6 @@ const ProjectEnvironmentList = ({
|
|||||||
// local state
|
// local state
|
||||||
const [selectedEnv, setSelectedEnv] = useState<IProjectEnvironment>();
|
const [selectedEnv, setSelectedEnv] = useState<IProjectEnvironment>();
|
||||||
const [confirmName, setConfirmName] = useState('');
|
const [confirmName, setConfirmName] = useState('');
|
||||||
const ref = useLoading(loading);
|
|
||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const { isOss } = useUiConfig();
|
const { isOss } = useUiConfig();
|
||||||
|
|
||||||
@ -179,40 +173,35 @@ const ProjectEnvironmentList = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref}>
|
|
||||||
<PageContent
|
<PageContent
|
||||||
header={
|
header={
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={`Configure environments for "${project?.name}" project`}
|
title={`Configure environments for "${project?.name}" project`}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
isLoading={loading}
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={uiConfig.flags.E}
|
condition={uiConfig.flags.E}
|
||||||
show={
|
show={
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={error}
|
condition={Boolean(error)}
|
||||||
show={renderError()}
|
show={renderError()}
|
||||||
/>
|
/>
|
||||||
<Alert
|
<Alert severity="info" style={{ marginBottom: '20px' }}>
|
||||||
severity="info"
|
<b>Important!</b> In order for your application to
|
||||||
style={{ marginBottom: '20px' }}
|
retrieve configured activation strategies for a
|
||||||
>
|
specific environment, the application
|
||||||
<b>Important!</b> In order for your application
|
<br /> must use an environment specific API key. You
|
||||||
to retrieve configured activation strategies for
|
can look up the environment-specific API keys{' '}
|
||||||
a specific environment, the application
|
<Link to="/admin/api">here.</Link>
|
||||||
<br /> must use an environment specific API key.
|
|
||||||
You can look up the environment-specific API
|
|
||||||
keys <Link to="/admin/api">here.</Link>
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
Your administrator can configure an
|
Your administrator can configure an
|
||||||
environment-specific API key to be used in the
|
environment-specific API key to be used in the SDK.
|
||||||
SDK. If you are an administrator you can{' '}
|
If you are an administrator you can{' '}
|
||||||
<Link to="/admin/api">
|
<Link to="/admin/api">create a new API key.</Link>
|
||||||
create a new API key.
|
|
||||||
</Link>
|
|
||||||
</Alert>
|
</Alert>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={environments.length < 1 && !loading}
|
condition={environments.length < 1 && !loading}
|
||||||
@ -222,9 +211,7 @@ const ProjectEnvironmentList = ({
|
|||||||
<EnvironmentDisableConfirm
|
<EnvironmentDisableConfirm
|
||||||
env={selectedEnv}
|
env={selectedEnv}
|
||||||
open={Boolean(selectedEnv)}
|
open={Boolean(selectedEnv)}
|
||||||
handleDisableEnvironment={
|
handleDisableEnvironment={handleDisableEnvironment}
|
||||||
handleDisableEnvironment
|
|
||||||
}
|
|
||||||
handleCancelDisableEnvironment={
|
handleCancelDisableEnvironment={
|
||||||
handleCancelDisableEnvironment
|
handleCancelDisableEnvironment
|
||||||
}
|
}
|
||||||
@ -240,7 +227,6 @@ const ProjectEnvironmentList = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</PageContent>
|
</PageContent>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,35 +1,49 @@
|
|||||||
import useSWR, { mutate } from 'swr';
|
import useSWR from 'swr';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useMemo, useCallback } from 'react';
|
||||||
import { IEnvironmentResponse } from 'interfaces/environments';
|
import { IEnvironmentResponse, IEnvironment } from 'interfaces/environments';
|
||||||
import { formatApiPath } from 'utils/formatPath';
|
import { formatApiPath } from 'utils/formatPath';
|
||||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||||
|
|
||||||
const PATH = formatApiPath(`api/admin/environments`);
|
interface IUseEnvironmentsOutput {
|
||||||
|
environments: IEnvironment[];
|
||||||
|
loading: boolean;
|
||||||
|
error?: Error;
|
||||||
|
mutateEnvironments: (environments: IEnvironment[]) => Promise<void>;
|
||||||
|
refetchEnvironments: () => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export const useEnvironments = () => {
|
export const useEnvironments = (): IUseEnvironmentsOutput => {
|
||||||
const { data, error } = useSWR<IEnvironmentResponse>(PATH, fetcher);
|
const { data, error, mutate } = useSWR<IEnvironmentResponse>(
|
||||||
|
formatApiPath(`api/admin/environments`),
|
||||||
const refetchEnvironments = useCallback(
|
fetcher
|
||||||
(data?: IEnvironmentResponse, revalidate?: boolean) => {
|
|
||||||
mutate(PATH, data, revalidate).catch(console.warn);
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const environments = useMemo(() => {
|
const environments = useMemo(() => {
|
||||||
return data?.environments || [];
|
return data?.environments || [];
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const refetchEnvironments = useCallback(async () => {
|
||||||
|
await mutate();
|
||||||
|
}, [mutate]);
|
||||||
|
|
||||||
|
const mutateEnvironments = useCallback(
|
||||||
|
async (environments: IEnvironment[]) => {
|
||||||
|
await mutate({ environments }, false);
|
||||||
|
},
|
||||||
|
[mutate]
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
environments,
|
environments,
|
||||||
refetchEnvironments,
|
refetchEnvironments,
|
||||||
|
mutateEnvironments,
|
||||||
loading: !error && !data,
|
loading: !error && !data,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetcher = (): Promise<IEnvironmentResponse> => {
|
const fetcher = (path: string): Promise<IEnvironmentResponse> => {
|
||||||
return fetch(PATH)
|
return fetch(path)
|
||||||
.then(handleErrorResponses('Environments'))
|
.then(handleErrorResponses('Environments'))
|
||||||
.then(res => res.json());
|
.then(res => res.json());
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user