From dbaa386697a01144654c2220f6f4d09a8b0a73c8 Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:25:38 +0200 Subject: [PATCH] feat: Edge integration page (#4657) ## About the changes ![image](https://github.com/Unleash/unleash/assets/2625371/6f4dcf7f-c3cf-45a2-9525-2965c31b6d89) --- .../IntegrationForm/IntegrationForm.tsx | 2 + .../IntegrationHowToSection.tsx | 35 +++++ .../AvailableIntegrations.tsx | 2 +- .../EdgeIntegration/EdgeIntegration.tsx | 145 ++++++++++++++++-- .../assets/edge-daisy-chaining.svg | 48 ++++++ .../EdgeIntegration/assets/edge-mode.svg | 22 +++ .../EdgeIntegration/assets/edge-offline.svg | 19 +++ .../JiraIntegration/JiraIntegration.tsx | 43 ++---- .../JiraIntegration/assets}/connect.png | Bin .../JiraIntegration/assets}/cr.png | Bin .../JiraIntegration/assets}/manage.png | Bin .../src/openapi/models/addonTypeSchema.ts | 2 + src/lib/addons/datadog-definition.ts | 1 + src/lib/addons/teams-definition.ts | 1 + src/lib/addons/webhook-definition.ts | 1 + 15 files changed, 272 insertions(+), 49 deletions(-) create mode 100644 frontend/src/component/integrations/IntegrationHowToSection/IntegrationHowToSection.tsx create mode 100644 frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-daisy-chaining.svg create mode 100644 frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-mode.svg create mode 100644 frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-offline.svg rename frontend/src/{assets/img/jira => component/integrations/ViewIntegration/JiraIntegration/assets}/connect.png (100%) rename frontend/src/{assets/img/jira => component/integrations/ViewIntegration/JiraIntegration/assets}/cr.png (100%) rename frontend/src/{assets/img/jira => component/integrations/ViewIntegration/JiraIntegration/assets}/manage.png (100%) diff --git a/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx b/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx index 51769430dd..7066ecf492 100644 --- a/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx +++ b/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx @@ -44,6 +44,7 @@ import { IntegrationDelete } from './IntegrationDelete/IntegrationDelete'; import { IntegrationStateSwitch } from './IntegrationStateSwitch/IntegrationStateSwitch'; import { capitalizeFirst } from 'utils/capitalizeFirst'; import { useUiFlag } from 'hooks/useUiFlag'; +import { IntegrationHowToSection } from '../IntegrationHowToSection/IntegrationHowToSection'; type IntegrationFormProps = { provider?: AddonTypeSchema; @@ -305,6 +306,7 @@ export const IntegrationForm: VFC = ({ hidden={true} variant="outlined" /> + ; + title?: string; +} + +export const IntegrationHowToSection: VFC = ({ + provider, + title = 'How does it work?', +}) => { + if (!provider?.name || !provider?.howTo) return null; + + return ( + + ({ + display: 'flex', + alignItems: 'center', + marginBottom: theme.spacing(1), + })} + > + {title} + + {provider!.howTo || ''} + + ); +}; diff --git a/frontend/src/component/integrations/IntegrationList/AvailableIntegrations/AvailableIntegrations.tsx b/frontend/src/component/integrations/IntegrationList/AvailableIntegrations/AvailableIntegrations.tsx index 36568a19e3..d95ac45546 100644 --- a/frontend/src/component/integrations/IntegrationList/AvailableIntegrations/AvailableIntegrations.tsx +++ b/frontend/src/component/integrations/IntegrationList/AvailableIntegrations/AvailableIntegrations.tsx @@ -106,7 +106,7 @@ export const AvailableIntegrations: VFC = ({ diff --git a/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/EdgeIntegration.tsx b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/EdgeIntegration.tsx index 6f0bf6e8a9..c335032e30 100644 --- a/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/EdgeIntegration.tsx +++ b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/EdgeIntegration.tsx @@ -1,9 +1,11 @@ import FormTemplate from 'component/common/FormTemplate/FormTemplate'; -import { styled } from '@mui/material'; - -import { IntegrationIcon } from '../../IntegrationList/IntegrationIcon/IntegrationIcon'; -import { ReactMarkdown } from 'react-markdown/lib/react-markdown'; +import { Divider, Typography, styled } from '@mui/material'; +import edgeMode from './assets/edge-mode.svg'; +import offlineMode from './assets/edge-offline.svg'; +import edgeChaining from './assets/edge-daisy-chaining.svg'; import LaunchIcon from '@mui/icons-material/Launch'; +import { IntegrationHowToSection } from 'component/integrations/IntegrationHowToSection/IntegrationHowToSection'; +import { formatAssetPath } from 'utils/formatPath'; const StyledContainer = styled('div')(({ theme }) => ({ display: 'flex', @@ -11,6 +13,12 @@ const StyledContainer = styled('div')(({ theme }) => ({ gap: theme.spacing(2), })); +const StyledDescription = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(3), +})); + const StyledGrayContainer = styled('div')(({ theme }) => ({ backgroundColor: theme.palette.background.elevation1, borderRadius: theme.shape.borderRadiusLarge, @@ -20,15 +28,31 @@ const StyledGrayContainer = styled('div')(({ theme }) => ({ gap: theme.spacing(1), })); -const StyledIconLine = styled('div')(({ theme }) => ({ - display: 'flex', - alignItems: 'center', +const StyledDescriptionHeader = styled(Typography)(({ theme }) => ({ + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), })); const StyledLink = styled('a')({ textDecoration: 'none', }); +const StyledFigure = styled('figure')(({ theme }) => ({ + display: 'flex', + marginLeft: 0, + marginRight: 0, + marginTop: theme.spacing(1.5), + marginBottom: theme.spacing(3), + gap: theme.spacing(1), + flexDirection: 'column', +})); + +const StyledFigcaption = styled('figcaption')(({ theme }) => ({ + fontSize: theme.typography.body2.fontSize, + color: theme.palette.text.secondary, + textAlign: 'center', +})); + export const EDGE_INFO = { name: 'unleash', displayName: 'Unleash Edge', @@ -41,8 +65,7 @@ Unleash Edge offers two important features: }; export const EdgeIntegration = () => { - const { name, displayName, description, documentationUrl, howTo } = - EDGE_INFO; + const { displayName, description, documentationUrl } = EDGE_INFO; return ( { documentationLinkLabel="Unleash Edge documentation" > - - - How does it work? - - {howTo} - + { /> + ({ + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), + })} + /> + +
+ + Modes + + + Edge currently supports 2 different modes:{' '} +
    +
  • + + Edge + {' '} + Edge – Connection to upstream node + (Unleash instance or another Edge). Supports + dynamic tokens, metrics and other advanced + features; +
  • +
  • + + Offline + {' '} + – No connection to upstream node. Full + control of data and tokens; +
  • +
+
+
+
+ + Edge + + + Edge mode is the "standard" mode for Unleash Edge + and the one you should default to in most cases. It + connects to an upstream node, such as your Unleash + instance, and uses that as the source of truth for + feature toggles. + + + test + Edge mode + + + Other than connecting Edge directly to your Unleash + instance, it's also possible to connect to another + Edge instance (daisy chaining). You can have as many + Edge nodes as you'd like between the Edge node your + clients are accessing and the Unleash server, and + it's also possible for multiple nodes to connect to + a single upstream one. + + + test + + Edge daisy chaining + + +
+
+ + Offline + + + Offline mode is useful when there is no connection + to an upstream node, such as your Unleash instance + or another Edge instance, or as a tool to make + working with Unleash easier during development. + + + test + Edge offline + +
+
); diff --git a/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-daisy-chaining.svg b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-daisy-chaining.svg new file mode 100644 index 0000000000..5395c2dccc --- /dev/null +++ b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-daisy-chaining.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-mode.svg b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-mode.svg new file mode 100644 index 0000000000..18fa0e5f84 --- /dev/null +++ b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-mode.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-offline.svg b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-offline.svg new file mode 100644 index 0000000000..b6879963f9 --- /dev/null +++ b/frontend/src/component/integrations/ViewIntegration/EdgeIntegration/assets/edge-offline.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/frontend/src/component/integrations/ViewIntegration/JiraIntegration/JiraIntegration.tsx b/frontend/src/component/integrations/ViewIntegration/JiraIntegration/JiraIntegration.tsx index 4a21776619..5a6a985cc3 100644 --- a/frontend/src/component/integrations/ViewIntegration/JiraIntegration/JiraIntegration.tsx +++ b/frontend/src/component/integrations/ViewIntegration/JiraIntegration/JiraIntegration.tsx @@ -1,11 +1,11 @@ import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import { Divider, styled } from '@mui/material'; -import { IntegrationIcon } from '../../IntegrationList/IntegrationIcon/IntegrationIcon'; -import cr from 'assets/img/jira/cr.png'; -import connect from 'assets/img/jira/connect.png'; -import manage from 'assets/img/jira/manage.png'; +import cr from './assets/cr.png'; +import connect from './assets/connect.png'; +import manage from './assets/manage.png'; import { JiraImageContainer } from './JiraImageContainer'; +import { IntegrationHowToSection } from 'component/integrations/IntegrationHowToSection/IntegrationHowToSection'; const StyledContainer = styled('div')(({ theme }) => ({ display: 'flex', @@ -22,12 +22,6 @@ const StyledGrayContainer = styled('div')(({ theme }) => ({ gap: theme.spacing(1), })); -const StyledIconLine = styled('div')(({ theme }) => ({ - display: 'flex', - marginLeft: theme.spacing(1), - alignItems: 'center', -})); - const StyledLink = styled('a')({ textDecoration: 'none', }); @@ -39,10 +33,14 @@ export const JIRA_INFO = { 'Create, connect, manage, and approve Unleash feature flags directly from Jira', documentationUrl: 'https://docs.getunleash.io/reference/integrations/jira-cloud-plugin-installation', + howTo: ` - Create a new feature flag directly within Jira, or connect existing flags to any Jira issue. + - Keep track of your flag status for each environment. + - Activate/deactivate feature flags directly within Jira. + - Initiate change requests when guarded flags are activated/deactivated within Jira.`, }; export const JiraIntegration = () => { - const { name, displayName, description, documentationUrl } = JIRA_INFO; + const { displayName, description, documentationUrl } = JIRA_INFO; return ( { documentationLinkLabel="Jira documentation" > - - - How does it work? - -
    -
  • - Create a new feature flag directly within Jira, or - connect existing flags to any Jira issue. -
  • -
  • - Keep track of your flag status for each environment. -
  • -
  • - Activate/deactivate feature flags directly within - Jira. -
  • -
  • - Initiate change requests when guarded flags are - activated/deactivated within Jira. -
  • -
-
+