Skip to content

Commit

Permalink
Integrations - frontend adjustments (#4527)
Browse files Browse the repository at this point in the history
## 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
  • Loading branch information
Tymek authored Aug 22, 2023
1 parent 8a3889d commit 573518e
Show file tree
Hide file tree
Showing 25 changed files with 225 additions and 94 deletions.
19 changes: 0 additions & 19 deletions frontend/src/component/addons/AddonList/AddonList.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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>
);
};
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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();

Expand All @@ -29,7 +29,7 @@ export const CreateAddon = () => {
};

return (
<AddonForm
<IntegrationForm
editMode={editMode}
provider={provider}
fetch={refetchAddons}
Expand Down
Original file line number Diff line number Diff line change
@@ -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();

Expand All @@ -18,7 +18,7 @@ export const EditAddon = () => {
: undefined;

return (
<AddonForm
<IntegrationForm
editMode={editMode}
provider={provider}
fetch={refetchAddons}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ 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';
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';
Expand All @@ -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';
Expand All @@ -54,7 +54,7 @@ interface IAddonFormProps {
editMode: boolean;
}

export const AddonForm: VFC<IAddonFormProps> = ({
export const IntegrationForm: VFC<IAddonFormProps> = ({
editMode,
provider,
addon: initialValues,
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -321,7 +321,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
</StyledFormSection>

<StyledFormSection>
<AddonMultiSelector
<IntegrationMultiSelector
options={selectableEvents || []}
selectedItems={formValues.events}
onChange={setEventValues}
Expand All @@ -333,7 +333,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
/>
</StyledFormSection>
<StyledFormSection>
<AddonMultiSelector
<IntegrationMultiSelector
options={selectableProjects}
selectedItems={formValues.projects || []}
onChange={setProjects}
Expand All @@ -342,7 +342,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
/>
</StyledFormSection>
<StyledFormSection>
<AddonMultiSelector
<IntegrationMultiSelector
options={selectableEnvironments}
selectedItems={formValues.environments || []}
onChange={setEnvironments}
Expand All @@ -351,7 +351,7 @@ export const AddonForm: VFC<IAddonFormProps> = ({
/>
</StyledFormSection>
<StyledFormSection>
<AddonParameters
<IntegrationParameters
provider={provider}
config={formValues}
parametersErrors={errors.parameters}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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' },
Expand All @@ -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
Expand All @@ -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'));

Expand All @@ -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(
Expand All @@ -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={[
Expand All @@ -108,7 +115,7 @@ describe('AddonMultiSelector', () => {
it('can filter options', async () => {
const user = userEvent.setup();
render(
<AddonMultiSelector
<IntegrationMultiSelector
{...mockProps}
selectedItems={[]}
options={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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];
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -33,7 +33,7 @@ export const AddonParameters = ({
</p>
) : null}
{provider.parameters.map(parameter => (
<AddonParameter
<IntegrationParameter
key={parameter.name}
definition={parameter}
parametersErrors={parametersErrors}
Expand Down
Loading

0 comments on commit 573518e

Please sign in to comment.