mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
Integrations - frontend adjustments (#4527)
## About the changes - [x] Create a feature flag - [x] Rename page title - [x] Rename menu item - [x] Update frontend URL (add redirect from old one) https://linear.app/unleash/issue/1-1263/integrations-frontend-adjustments
This commit is contained in:
parent
8a3889d570
commit
573518e48d
@ -1,19 +0,0 @@
|
||||
import React from 'react';
|
||||
import { ConfiguredAddons } from './ConfiguredAddons/ConfiguredAddons';
|
||||
import { AvailableAddons } from './AvailableAddons/AvailableAddons';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import useAddons from 'hooks/api/getters/useAddons/useAddons';
|
||||
|
||||
export const AddonList = () => {
|
||||
const { providers, addons, loading } = useAddons();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConditionallyRender
|
||||
condition={addons.length > 0}
|
||||
show={<ConfiguredAddons />}
|
||||
/>
|
||||
<AvailableAddons loading={loading} providers={providers} />
|
||||
</>
|
||||
);
|
||||
};
|
@ -0,0 +1,19 @@
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||
|
||||
export const AddonRedirect = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
navigate(`/integrations${location.pathname.replace('/addons', '')}`);
|
||||
}, [location.pathname, navigate]);
|
||||
|
||||
return (
|
||||
<PageContent>
|
||||
Addons where renamed to{' '}
|
||||
<Link to="/integrations">/integrations</Link>
|
||||
</PageContent>
|
||||
);
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
import useAddons from 'hooks/api/getters/useAddons/useAddons';
|
||||
import { AddonForm } from '../AddonForm/AddonForm';
|
||||
import { IntegrationForm } from '../IntegrationForm/IntegrationForm';
|
||||
import cloneDeep from 'lodash.clonedeep';
|
||||
import { IAddon } from 'interfaces/addons';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
@ -14,7 +14,7 @@ export const DEFAULT_DATA = {
|
||||
environments: [],
|
||||
} as unknown as IAddon; // TODO: improve type
|
||||
|
||||
export const CreateAddon = () => {
|
||||
export const CreateIntegration = () => {
|
||||
const providerId = useRequiredPathParam('providerId');
|
||||
const { providers, refetchAddons } = useAddons();
|
||||
|
||||
@ -29,7 +29,7 @@ export const CreateAddon = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AddonForm
|
||||
<IntegrationForm
|
||||
editMode={editMode}
|
||||
provider={provider}
|
||||
fetch={refetchAddons}
|
@ -1,11 +1,11 @@
|
||||
import useAddons from 'hooks/api/getters/useAddons/useAddons';
|
||||
import { AddonForm } from '../AddonForm/AddonForm';
|
||||
import { IntegrationForm } from '../IntegrationForm/IntegrationForm';
|
||||
import cloneDeep from 'lodash.clonedeep';
|
||||
import { IAddon } from 'interfaces/addons';
|
||||
import { DEFAULT_DATA } from '../CreateAddon/CreateAddon';
|
||||
import { DEFAULT_DATA } from '../CreateIntegration/CreateIntegration';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
|
||||
export const EditAddon = () => {
|
||||
export const EditIntegration = () => {
|
||||
const addonId = useRequiredPathParam('addonId');
|
||||
const { providers, addons, refetchAddons } = useAddons();
|
||||
|
||||
@ -18,7 +18,7 @@ export const EditAddon = () => {
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<AddonForm
|
||||
<IntegrationForm
|
||||
editMode={editMode}
|
||||
provider={provider}
|
||||
fetch={refetchAddons}
|
@ -16,8 +16,8 @@ import {
|
||||
import produce from 'immer';
|
||||
import { trim } from 'component/common/util';
|
||||
import { IAddon, IAddonProvider } from 'interfaces/addons';
|
||||
import { AddonParameters } from './AddonParameters/AddonParameters';
|
||||
import { AddonInstall } from './AddonInstall/AddonInstall';
|
||||
import { IntegrationParameters } from './IntegrationParameters/IntegrationParameters';
|
||||
import { IntegrationInstall } from './IntegrationInstall/IntegrationInstall';
|
||||
import cloneDeep from 'lodash.clonedeep';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import useAddonsApi from 'hooks/api/actions/useAddonsApi/useAddonsApi';
|
||||
@ -25,7 +25,7 @@ import useToast from 'hooks/useToast';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||
import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
|
||||
import { AddonMultiSelector } from './AddonMultiSelector/AddonMultiSelector';
|
||||
import { IntegrationMultiSelector } from './IntegrationMultiSelector/IntegrationMultiSelector';
|
||||
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
|
||||
@ -42,7 +42,7 @@ import {
|
||||
StyledContainer,
|
||||
StyledButtonContainer,
|
||||
StyledButtonSection,
|
||||
} from './AddonForm.styles';
|
||||
} from './IntegrationForm.styles';
|
||||
import { useTheme } from '@mui/system';
|
||||
import { GO_BACK } from 'constants/navigate';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
@ -54,7 +54,7 @@ interface IAddonFormProps {
|
||||
editMode: boolean;
|
||||
}
|
||||
|
||||
export const AddonForm: VFC<IAddonFormProps> = ({
|
||||
export const IntegrationForm: VFC<IAddonFormProps> = ({
|
||||
editMode,
|
||||
provider,
|
||||
addon: initialValues,
|
||||
@ -272,7 +272,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
|
||||
<ConditionallyRender
|
||||
condition={Boolean(installation)}
|
||||
show={() => (
|
||||
<AddonInstall
|
||||
<IntegrationInstall
|
||||
url={installation!.url}
|
||||
title={installation!.title}
|
||||
helpText={installation!.helpText}
|
||||
@ -321,7 +321,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
|
||||
</StyledFormSection>
|
||||
|
||||
<StyledFormSection>
|
||||
<AddonMultiSelector
|
||||
<IntegrationMultiSelector
|
||||
options={selectableEvents || []}
|
||||
selectedItems={formValues.events}
|
||||
onChange={setEventValues}
|
||||
@ -333,7 +333,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
|
||||
/>
|
||||
</StyledFormSection>
|
||||
<StyledFormSection>
|
||||
<AddonMultiSelector
|
||||
<IntegrationMultiSelector
|
||||
options={selectableProjects}
|
||||
selectedItems={formValues.projects || []}
|
||||
onChange={setProjects}
|
||||
@ -342,7 +342,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
|
||||
/>
|
||||
</StyledFormSection>
|
||||
<StyledFormSection>
|
||||
<AddonMultiSelector
|
||||
<IntegrationMultiSelector
|
||||
options={selectableEnvironments}
|
||||
selectedItems={formValues.environments || []}
|
||||
onChange={setEnvironments}
|
||||
@ -351,7 +351,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
|
||||
/>
|
||||
</StyledFormSection>
|
||||
<StyledFormSection>
|
||||
<AddonParameters
|
||||
<IntegrationParameters
|
||||
provider={provider}
|
||||
config={formValues}
|
||||
parametersErrors={errors.parameters}
|
@ -3,7 +3,7 @@ import {
|
||||
StyledFormSection,
|
||||
StyledHelpText,
|
||||
StyledTitle,
|
||||
} from '../AddonForm.styles';
|
||||
} from '../IntegrationForm.styles';
|
||||
import { Button } from '@mui/material';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
@ -13,7 +13,7 @@ export interface IAddonInstallProps {
|
||||
helpText?: string;
|
||||
}
|
||||
|
||||
export const AddonInstall = ({
|
||||
export const IntegrationInstall = ({
|
||||
url,
|
||||
title = 'Install addon',
|
||||
helpText = 'Click this button to install this addon.',
|
@ -4,15 +4,15 @@ import { screen, waitFor, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render } from 'utils/testRenderer';
|
||||
import {
|
||||
IAddonMultiSelectorProps,
|
||||
AddonMultiSelector,
|
||||
} from './AddonMultiSelector';
|
||||
IIntegrationMultiSelectorProps,
|
||||
IntegrationMultiSelector,
|
||||
} from './IntegrationMultiSelector';
|
||||
import { testServerRoute, testServerSetup } from 'utils/testServer';
|
||||
|
||||
const onChange = vi.fn();
|
||||
const onFocus = vi.fn();
|
||||
|
||||
const mockProps: IAddonMultiSelectorProps = {
|
||||
const mockProps: IIntegrationMultiSelectorProps = {
|
||||
options: [
|
||||
{ label: 'Project1', value: 'project1' },
|
||||
{ label: 'Project2', value: 'project2' },
|
||||
@ -35,7 +35,9 @@ describe('AddonMultiSelector', () => {
|
||||
});
|
||||
|
||||
it('renders with default state', () => {
|
||||
render(<AddonMultiSelector {...mockProps} selectedItems={['*']} />);
|
||||
render(
|
||||
<IntegrationMultiSelector {...mockProps} selectedItems={['*']} />
|
||||
);
|
||||
|
||||
const checkbox = screen.getByLabelText(
|
||||
/all current and future projects/i
|
||||
@ -49,7 +51,9 @@ describe('AddonMultiSelector', () => {
|
||||
|
||||
it('can toggle "ALL" checkbox', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<AddonMultiSelector {...mockProps} selectedItems={['*']} />);
|
||||
render(
|
||||
<IntegrationMultiSelector {...mockProps} selectedItems={['*']} />
|
||||
);
|
||||
|
||||
await user.click(screen.getByTestId('select-all-projects'));
|
||||
|
||||
@ -70,7 +74,10 @@ describe('AddonMultiSelector', () => {
|
||||
|
||||
it('renders with autocomplete enabled if default value is not a wildcard', () => {
|
||||
render(
|
||||
<AddonMultiSelector {...mockProps} selectedItems={['project1']} />
|
||||
<IntegrationMultiSelector
|
||||
{...mockProps}
|
||||
selectedItems={['project1']}
|
||||
/>
|
||||
);
|
||||
|
||||
const checkbox = screen.getByLabelText(
|
||||
@ -87,7 +94,7 @@ describe('AddonMultiSelector', () => {
|
||||
it("doesn't show up for less than 3 options", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<AddonMultiSelector
|
||||
<IntegrationMultiSelector
|
||||
{...mockProps}
|
||||
selectedItems={[]}
|
||||
options={[
|
||||
@ -108,7 +115,7 @@ describe('AddonMultiSelector', () => {
|
||||
it('can filter options', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<AddonMultiSelector
|
||||
<IntegrationMultiSelector
|
||||
{...mockProps}
|
||||
selectedItems={[]}
|
||||
options={[
|
@ -22,9 +22,9 @@ import {
|
||||
StyledHelpText,
|
||||
StyledSelectAllFormControlLabel,
|
||||
StyledTitle,
|
||||
} from '../AddonForm.styles';
|
||||
} from '../IntegrationForm.styles';
|
||||
|
||||
export interface IAddonMultiSelectorProps {
|
||||
export interface IIntegrationMultiSelectorProps {
|
||||
options: IAutocompleteBoxOption[];
|
||||
selectedItems: string[];
|
||||
onChange: (value: string[]) => void;
|
||||
@ -44,7 +44,7 @@ const StyledCheckbox = styled(Checkbox)(() => ({
|
||||
|
||||
const CustomPaper = ({ ...props }) => <Paper elevation={8} {...props} />;
|
||||
|
||||
export const AddonMultiSelector: VFC<IAddonMultiSelectorProps> = ({
|
||||
export const IntegrationMultiSelector: VFC<IIntegrationMultiSelectorProps> = ({
|
||||
options,
|
||||
selectedItems,
|
||||
onChange,
|
||||
@ -138,9 +138,9 @@ export const AddonMultiSelector: VFC<IAddonMultiSelectorProps> = ({
|
||||
|
||||
const DefaultHelpText = () => (
|
||||
<StyledHelpText>
|
||||
Selecting {entityName}(s) here will filter events so that your addon
|
||||
will only receive events that are tagged with one of your{' '}
|
||||
{entityName}s.
|
||||
Selecting {entityName}(s) here will filter events so that your
|
||||
integration will only receive events that are tagged with one of
|
||||
your {entityName}s.
|
||||
</StyledHelpText>
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { TextField, Typography } from '@mui/material';
|
||||
import { IAddonConfig, IAddonProviderParams } from 'interfaces/addons';
|
||||
import { ChangeEventHandler } from 'react';
|
||||
import { StyledAddonParameterContainer } from '../../AddonForm.styles';
|
||||
import { StyledAddonParameterContainer } from '../../IntegrationForm.styles';
|
||||
|
||||
const resolveType = ({ type = 'text', sensitive = false }, value: string) => {
|
||||
if (sensitive && value === MASKED_VALUE) {
|
||||
@ -15,19 +15,19 @@ const resolveType = ({ type = 'text', sensitive = false }, value: string) => {
|
||||
|
||||
const MASKED_VALUE = '*****';
|
||||
|
||||
export interface IAddonParameterProps {
|
||||
export interface IIntegrationParameterProps {
|
||||
parametersErrors: Record<string, string>;
|
||||
definition: IAddonProviderParams;
|
||||
setParameterValue: (param: string) => ChangeEventHandler<HTMLInputElement>;
|
||||
config: IAddonConfig;
|
||||
}
|
||||
|
||||
export const AddonParameter = ({
|
||||
export const IntegrationParameter = ({
|
||||
definition,
|
||||
config,
|
||||
parametersErrors,
|
||||
setParameterValue,
|
||||
}: IAddonParameterProps) => {
|
||||
}: IIntegrationParameterProps) => {
|
||||
const value = config.parameters[definition.name] || '';
|
||||
const type = resolveType(definition, value);
|
||||
const error = parametersErrors[definition.name];
|
@ -1,26 +1,26 @@
|
||||
import React from 'react';
|
||||
import { IAddonProvider } from 'interfaces/addons';
|
||||
import {
|
||||
AddonParameter,
|
||||
IAddonParameterProps,
|
||||
} from './AddonParameter/AddonParameter';
|
||||
import { StyledTitle } from '../AddonForm.styles';
|
||||
IntegrationParameter,
|
||||
IIntegrationParameterProps,
|
||||
} from './IntegrationParameter/IntegrationParameter';
|
||||
import { StyledTitle } from '../IntegrationForm.styles';
|
||||
|
||||
interface IAddonParametersProps {
|
||||
interface IIntegrationParametersProps {
|
||||
provider?: IAddonProvider;
|
||||
parametersErrors: IAddonParameterProps['parametersErrors'];
|
||||
parametersErrors: IIntegrationParameterProps['parametersErrors'];
|
||||
editMode: boolean;
|
||||
setParameterValue: IAddonParameterProps['setParameterValue'];
|
||||
config: IAddonParameterProps['config'];
|
||||
setParameterValue: IIntegrationParameterProps['setParameterValue'];
|
||||
config: IIntegrationParameterProps['config'];
|
||||
}
|
||||
|
||||
export const AddonParameters = ({
|
||||
export const IntegrationParameters = ({
|
||||
provider,
|
||||
config,
|
||||
parametersErrors,
|
||||
setParameterValue,
|
||||
editMode,
|
||||
}: IAddonParametersProps) => {
|
||||
}: IIntegrationParametersProps) => {
|
||||
if (!provider) return null;
|
||||
return (
|
||||
<React.Fragment>
|
||||
@ -33,7 +33,7 @@ export const AddonParameters = ({
|
||||
</p>
|
||||
) : null}
|
||||
{provider.parameters.map(parameter => (
|
||||
<AddonParameter
|
||||
<IntegrationParameter
|
||||
key={parameter.name}
|
||||
definition={parameter}
|
||||
parametersErrors={parametersErrors}
|
@ -16,10 +16,11 @@ import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||
import { sortTypes } from 'utils/sortTypes';
|
||||
import { IconCell } from 'component/common/Table/cells/IconCell/IconCell';
|
||||
import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell';
|
||||
import { ConfigureAddonButton } from './ConfigureAddonButton/ConfigureAddonButton';
|
||||
import { AddonIcon } from '../AddonIcon/AddonIcon';
|
||||
import { AddonNameCell } from '../AddonNameCell/AddonNameCell';
|
||||
import { ConfigureAddonsButton } from './ConfigureAddonButton/ConfigureAddonsButton';
|
||||
import { IntegrationIcon } from '../IntegrationIcon/IntegrationIcon';
|
||||
import { IntegrationNameCell } from '../IntegrationNameCell/IntegrationNameCell';
|
||||
import { IAddonInstallation } from 'interfaces/addons';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
interface IProvider {
|
||||
name: string;
|
||||
@ -37,6 +38,9 @@ interface IAvailableAddonsProps {
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Remove when integrationsRework flag is removed
|
||||
*/
|
||||
export const AvailableAddons = ({
|
||||
providers,
|
||||
loading,
|
||||
@ -70,7 +74,9 @@ export const AvailableAddons = ({
|
||||
},
|
||||
}: any) => {
|
||||
return (
|
||||
<IconCell icon={<AddonIcon name={name as string} />} />
|
||||
<IconCell
|
||||
icon={<IntegrationIcon name={name as string} />}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
@ -79,7 +85,7 @@ export const AvailableAddons = ({
|
||||
accessor: 'name',
|
||||
width: '90%',
|
||||
Cell: ({ row: { original } }: any) => (
|
||||
<AddonNameCell provider={original} />
|
||||
<IntegrationNameCell provider={original} />
|
||||
),
|
||||
sortType: 'alphanumeric',
|
||||
},
|
||||
@ -88,7 +94,7 @@ export const AvailableAddons = ({
|
||||
align: 'center',
|
||||
Cell: ({ row: { original } }: any) => (
|
||||
<ActionCell>
|
||||
<ConfigureAddonButton provider={original} />
|
||||
<ConfigureAddonsButton provider={original} />
|
||||
</ActionCell>
|
||||
),
|
||||
width: 150,
|
@ -3,13 +3,16 @@ import { CREATE_ADDON } from 'component/providers/AccessProvider/permissions';
|
||||
import { IAddonProvider } from 'interfaces/addons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
interface IConfigureAddonButtonProps {
|
||||
interface IConfigureAddonsButtonProps {
|
||||
provider: IAddonProvider;
|
||||
}
|
||||
|
||||
export const ConfigureAddonButton = ({
|
||||
/**
|
||||
* @deprecated Remove when integrationsRework flag is removed
|
||||
*/
|
||||
export const ConfigureAddonsButton = ({
|
||||
provider,
|
||||
}: IConfigureAddonButtonProps) => {
|
||||
}: IConfigureAddonsButtonProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
@ -0,0 +1,8 @@
|
||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||
import { VFC } from 'react';
|
||||
|
||||
interface IAvailableIntegrationsProps {}
|
||||
|
||||
export const AvailableIntegrations: VFC<IAvailableIntegrationsProps> = () => {
|
||||
return <PageContent>Available integrations</PageContent>;
|
||||
};
|
@ -13,10 +13,13 @@ import { useTable, useSortBy } from 'react-table';
|
||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||
import { SortableTableHeader, TablePlaceholder } from 'component/common/Table';
|
||||
import { IconCell } from 'component/common/Table/cells/IconCell/IconCell';
|
||||
import { AddonIcon } from '../AddonIcon/AddonIcon';
|
||||
import { IntegrationIcon } from '../IntegrationIcon/IntegrationIcon';
|
||||
import { ConfiguredAddonsActionsCell } from './ConfiguredAddonsActionCell/ConfiguredAddonsActionsCell';
|
||||
import { AddonNameCell } from '../AddonNameCell/AddonNameCell';
|
||||
import { IntegrationNameCell } from '../IntegrationNameCell/IntegrationNameCell';
|
||||
|
||||
/**
|
||||
* @deprecated Remove when integrationsRework flag is removed
|
||||
*/
|
||||
export const ConfiguredAddons = () => {
|
||||
const { refetchAddons, addons, providers, loading } = useAddons();
|
||||
const { updateAddon, removeAddon } = useAddonsApi();
|
||||
@ -73,7 +76,9 @@ export const ConfiguredAddons = () => {
|
||||
original: { provider },
|
||||
},
|
||||
}: any) => (
|
||||
<IconCell icon={<AddonIcon name={provider as string} />} />
|
||||
<IconCell
|
||||
icon={<IntegrationIcon name={provider as string} />}
|
||||
/>
|
||||
),
|
||||
disableSortBy: true,
|
||||
},
|
||||
@ -86,7 +91,7 @@ export const ConfiguredAddons = () => {
|
||||
original: { provider, description },
|
||||
},
|
||||
}: any) => (
|
||||
<AddonNameCell
|
||||
<IntegrationNameCell
|
||||
provider={{
|
||||
...(providers.find(
|
||||
({ name }) => name === provider
|
@ -18,6 +18,9 @@ interface IConfiguredAddonsActionsCellProps {
|
||||
setDeletedAddon: React.Dispatch<React.SetStateAction<IAddon>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Remove when integrationsRework flag is removed
|
||||
*/
|
||||
export const ConfiguredAddonsActionsCell = ({
|
||||
toggleAddon,
|
||||
setShowDelete,
|
@ -14,11 +14,11 @@ const style: React.CSSProperties = {
|
||||
marginRight: '16px',
|
||||
};
|
||||
|
||||
interface IAddonIconProps {
|
||||
interface IIntegrationIconProps {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const AddonIcon = ({ name }: IAddonIconProps) => {
|
||||
export const IntegrationIcon = ({ name }: IIntegrationIconProps) => {
|
||||
switch (name) {
|
||||
case 'slack':
|
||||
case 'slack-app':
|
@ -0,0 +1,28 @@
|
||||
import { ConfiguredAddons } from './ConfiguredAddons/ConfiguredAddons';
|
||||
import { AvailableAddons } from './AvailableAddons/AvailableAddons';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import useAddons from 'hooks/api/getters/useAddons/useAddons';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { AvailableIntegrations } from './AvailableIntegrations/AvailableIntegrations';
|
||||
|
||||
export const IntegrationList = () => {
|
||||
const { providers, addons, loading } = useAddons();
|
||||
const { uiConfig } = useUiConfig();
|
||||
const integrationsRework = uiConfig?.flags?.integrationsRework || false;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConditionallyRender
|
||||
condition={addons.length > 0}
|
||||
show={<ConfiguredAddons />}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={integrationsRework}
|
||||
show={<AvailableIntegrations />}
|
||||
elseShow={
|
||||
<AvailableAddons loading={loading} providers={providers} />
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
@ -10,14 +10,19 @@ const StyledBadge = styled(Badge)(({ theme }) => ({
|
||||
marginLeft: theme.spacing(1),
|
||||
}));
|
||||
|
||||
interface IAddonNameCellProps {
|
||||
interface IIntegrationNameCellProps {
|
||||
provider: Pick<
|
||||
IAddonProvider,
|
||||
'displayName' | 'description' | 'deprecated'
|
||||
>;
|
||||
}
|
||||
|
||||
export const AddonNameCell = ({ provider }: IAddonNameCellProps) => (
|
||||
/**
|
||||
* @deprecated Remove when integrationsRework flag is removed
|
||||
*/
|
||||
export const IntegrationNameCell = ({
|
||||
provider,
|
||||
}: IIntegrationNameCellProps) => (
|
||||
<HighlightCell
|
||||
value={provider.displayName}
|
||||
subtitle={provider.description}
|
@ -317,6 +317,34 @@ exports[`returns all baseRoutes 1`] = `
|
||||
"title": "Addons",
|
||||
"type": "protected",
|
||||
},
|
||||
{
|
||||
"component": [Function],
|
||||
"menu": {},
|
||||
"parent": "/integrations",
|
||||
"path": "/integrations/create/:providerId",
|
||||
"title": "Create",
|
||||
"type": "protected",
|
||||
},
|
||||
{
|
||||
"component": [Function],
|
||||
"menu": {},
|
||||
"parent": "/integrations",
|
||||
"path": "/integrations/edit/:addonId",
|
||||
"title": "Edit",
|
||||
"type": "protected",
|
||||
},
|
||||
{
|
||||
"component": [Function],
|
||||
"flag": "integrationsRework",
|
||||
"hidden": false,
|
||||
"menu": {
|
||||
"advanced": true,
|
||||
"mobile": true,
|
||||
},
|
||||
"path": "/integrations",
|
||||
"title": "Integrations",
|
||||
"type": "protected",
|
||||
},
|
||||
{
|
||||
"component": [Function],
|
||||
"flag": "SE",
|
||||
|
@ -2,7 +2,7 @@ import { FeatureToggleListTable } from 'component/feature/FeatureToggleList/Feat
|
||||
import { StrategyView } from 'component/strategies/StrategyView/StrategyView';
|
||||
import { StrategiesList } from 'component/strategies/StrategiesList/StrategiesList';
|
||||
import { TagTypeList } from 'component/tags/TagTypeList/TagTypeList';
|
||||
import { AddonList } from 'component/addons/AddonList/AddonList';
|
||||
import { IntegrationList } from 'component/integrations/IntegrationList/IntegrationList';
|
||||
import Login from 'component/user/Login/Login';
|
||||
import { EEA, P, SE } from 'component/common/flags';
|
||||
import { NewUser } from 'component/user/NewUser/NewUser';
|
||||
@ -21,8 +21,8 @@ import EditFeature from 'component/feature/EditFeature/EditFeature';
|
||||
import { ApplicationEdit } from 'component/application/ApplicationEdit/ApplicationEdit';
|
||||
import ContextList from 'component/context/ContextList/ContextList/ContextList';
|
||||
import RedirectFeatureView from 'component/feature/RedirectFeatureView/RedirectFeatureView';
|
||||
import { CreateAddon } from 'component/addons/CreateAddon/CreateAddon';
|
||||
import { EditAddon } from 'component/addons/EditAddon/EditAddon';
|
||||
import { CreateIntegration } from 'component/integrations/CreateIntegration/CreateIntegration';
|
||||
import { EditIntegration } from 'component/integrations/EditIntegration/EditIntegration';
|
||||
import { CopyFeatureToggle } from 'component/feature/CopyFeature/CopyFeature';
|
||||
import { EventPage } from 'component/events/EventPage/EventPage';
|
||||
import { CreateStrategy } from 'component/strategies/CreateStrategy/CreateStrategy';
|
||||
@ -300,12 +300,13 @@ export const routes: IRoute[] = [
|
||||
menu: { mobile: true, advanced: true },
|
||||
},
|
||||
|
||||
// Addons
|
||||
// Integrations
|
||||
{
|
||||
path: '/addons/create/:providerId',
|
||||
parent: '/addons',
|
||||
title: 'Create',
|
||||
component: CreateAddon,
|
||||
component: CreateIntegration,
|
||||
// TODO: use AddonRedirect after removing `integrationsRework` menu flag
|
||||
type: 'protected',
|
||||
menu: {},
|
||||
},
|
||||
@ -313,17 +314,45 @@ export const routes: IRoute[] = [
|
||||
path: '/addons/edit/:addonId',
|
||||
parent: '/addons',
|
||||
title: 'Edit',
|
||||
component: EditAddon,
|
||||
component: EditIntegration,
|
||||
// TODO: use AddonRedirect after removing `integrationsRework` menu flag
|
||||
type: 'protected',
|
||||
menu: {},
|
||||
},
|
||||
{
|
||||
path: '/addons',
|
||||
title: 'Addons',
|
||||
component: AddonList,
|
||||
component: IntegrationList,
|
||||
// TODO: use AddonRedirect after removing `integrationsRework` menu flag
|
||||
hidden: false,
|
||||
type: 'protected',
|
||||
menu: { mobile: true, advanced: true },
|
||||
// TODO: remove 'addons' from menu after removing `integrationsRework` menu flag
|
||||
},
|
||||
{
|
||||
path: '/integrations/create/:providerId',
|
||||
parent: '/integrations',
|
||||
title: 'Create',
|
||||
component: CreateIntegration,
|
||||
type: 'protected',
|
||||
menu: {},
|
||||
},
|
||||
{
|
||||
path: '/integrations/edit/:addonId',
|
||||
parent: '/integrations',
|
||||
title: 'Edit',
|
||||
component: EditIntegration,
|
||||
type: 'protected',
|
||||
menu: {},
|
||||
},
|
||||
{
|
||||
path: '/integrations',
|
||||
title: 'Integrations',
|
||||
component: IntegrationList,
|
||||
hidden: false,
|
||||
type: 'protected',
|
||||
menu: { mobile: true, advanced: true },
|
||||
flag: 'integrationsRework',
|
||||
},
|
||||
|
||||
// Segments
|
||||
|
@ -58,6 +58,7 @@ export interface IFlags {
|
||||
changeRequestReject?: boolean;
|
||||
lastSeenByEnvironment?: boolean;
|
||||
newApplicationList?: boolean;
|
||||
integrationsRework?: boolean;
|
||||
}
|
||||
|
||||
export interface IVersionInfo {
|
||||
|
@ -82,6 +82,7 @@ exports[`should create default config 1`] = `
|
||||
"filterInvalidClientMetrics": false,
|
||||
"frontendNavigationUpdate": false,
|
||||
"googleAuthEnabled": false,
|
||||
"integrationsRework": false,
|
||||
"lastSeenByEnvironment": false,
|
||||
"maintenanceMode": false,
|
||||
"messageBanner": {
|
||||
@ -118,6 +119,7 @@ exports[`should create default config 1`] = `
|
||||
"filterInvalidClientMetrics": false,
|
||||
"frontendNavigationUpdate": false,
|
||||
"googleAuthEnabled": false,
|
||||
"integrationsRework": false,
|
||||
"lastSeenByEnvironment": false,
|
||||
"maintenanceMode": false,
|
||||
"messageBanner": {
|
||||
|
@ -29,7 +29,8 @@ export type IFlagKey =
|
||||
| 'segmentChangeRequests'
|
||||
| 'changeRequestReject'
|
||||
| 'customRootRolesKillSwitch'
|
||||
| 'newApplicationList';
|
||||
| 'newApplicationList'
|
||||
| 'integrationsRework';
|
||||
|
||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||
|
||||
@ -133,6 +134,10 @@ const flags: IFlags = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_CUSTOM_ROOT_ROLES_KILL_SWITCH,
|
||||
false,
|
||||
),
|
||||
integrationsRework: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_INTEGRATIONS,
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||
|
@ -13,6 +13,7 @@ yarn install
|
||||
```console
|
||||
yarn generate
|
||||
```
|
||||
|
||||
Generate the Open API docs that live at Reference documentation > APIs > OpenAPI
|
||||
|
||||
## Local Development
|
||||
@ -21,7 +22,7 @@ Generate the Open API docs that live at Reference documentation > APIs > OpenAPI
|
||||
yarn start
|
||||
```
|
||||
|
||||
Start a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
Start a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
## Build
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user