From 79db2455411b5796c972a16777d0e5c53465e21e Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Mon, 13 Nov 2023 13:50:45 +1100 Subject: [PATCH 01/10] wip - getting ff --- .../JenkinsServerList/JenkinsServerList.tsx | 24 ++++++++++++++++++- .../src/hooks/useFeatureFlag.tsx | 4 ++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index 975d9872..251b2f8a 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -17,27 +17,49 @@ import { AnalyticsUiEventsEnum } from '../../common/analytics/analytics-events'; import { redirectFromGetStarted } from '../../api/redirectFromGetStarted'; +import { FeatureFlags } from '../../hooks/useFeatureFlag'; +import { fetchCloudId } from '../../api/fetchCloudId'; +import { fetchFeatureFlagFromBackend } from '../../api/fetchFeatureFlagFromBackend'; const JenkinsServerList = (): JSX.Element => { const history = useHistory(); const analyticsClient = new AnalyticsClient(); const [jenkinsServers, setJenkinsServers] = useState(); const [moduleKey, setModuleKey] = useState(); + const [cloudId, setCloudId] = useState(); + const fetchAllJenkinsServers = async () => { const servers = await getAllJenkinsServers() || []; setJenkinsServers(servers); }; + const getCloudId = async () => { + const id = await fetchCloudId(); + setCloudId(id); + }; + const redirectToAdminPage = useCallback(async () => { const currentModuleKey = await redirectFromGetStarted(); setModuleKey(currentModuleKey); }, []); + const fetchFeatureFlag = useCallback(async () => { + const renovatedJenkinsFeatureFlag = await fetchFeatureFlagFromBackend( + FeatureFlags.RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW + ); + console.log('renovatedJenkinsFeatureFlag:', renovatedJenkinsFeatureFlag); + }, []); + useEffect(() => { fetchAllJenkinsServers(); redirectToAdminPage(); - }, [redirectToAdminPage]); + getCloudId(); + fetchFeatureFlag(); + }, [redirectToAdminPage, cloudId, fetchFeatureFlag]); + + console.log('CLOUD ID: ', cloudId); + // Use the useFeatureFlag hook to get the value of RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW if (!jenkinsServers || !moduleKey || (moduleKey === 'jenkins-for-jira-ui-admin-page' && !jenkinsServers?.length)) { return ; } diff --git a/app/jenkins-for-jira-ui/src/hooks/useFeatureFlag.tsx b/app/jenkins-for-jira-ui/src/hooks/useFeatureFlag.tsx index 7c593e42..4051462d 100644 --- a/app/jenkins-for-jira-ui/src/hooks/useFeatureFlag.tsx +++ b/app/jenkins-for-jira-ui/src/hooks/useFeatureFlag.tsx @@ -3,7 +3,7 @@ import { useFlags } from 'launchdarkly-react-client-sdk'; export type FeatureFlagValue = string | boolean | number; export enum FeatureFlags { - SERVER_SECRET_GENERATION = 'server-secret-generation' + RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW = 'renovated_jenkins_for_jira_config_flow' } export const useFeatureFlag = ( @@ -13,7 +13,7 @@ export const useFeatureFlag = ( const flags = useFlags(); const defaultValues = { - [FeatureFlags.SERVER_SECRET_GENERATION]: defaultValue !== undefined ? defaultValue : false + [FeatureFlags.RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW]: defaultValue !== undefined ? defaultValue : false // Add more flags here } as Record; From 3824fd0f84ca3df0f4a3411f4b7e70748406901d Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Mon, 13 Nov 2023 17:48:24 +1100 Subject: [PATCH 02/10] update header and add new component if renovate flag is on --- .../JenkinsServerList/JenkinsServerList.tsx | 21 ++++++++----- .../TopPanel/TopPanel.styles.tsx | 31 +++++++++++++++++++ .../JenkinsServerList/TopPanel/TopPanel.tsx | 30 ++++++++++++++++++ 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx create mode 100644 app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index 251b2f8a..197cb8de 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -20,6 +20,7 @@ import { redirectFromGetStarted } from '../../api/redirectFromGetStarted'; import { FeatureFlags } from '../../hooks/useFeatureFlag'; import { fetchCloudId } from '../../api/fetchCloudId'; import { fetchFeatureFlagFromBackend } from '../../api/fetchFeatureFlagFromBackend'; +import { TopPanel } from './TopPanel/TopPanel'; const JenkinsServerList = (): JSX.Element => { const history = useHistory(); @@ -27,6 +28,7 @@ const JenkinsServerList = (): JSX.Element => { const [jenkinsServers, setJenkinsServers] = useState(); const [moduleKey, setModuleKey] = useState(); const [cloudId, setCloudId] = useState(); + const [renovateConfigFlag, setRenovateConfigFlag] = useState(false); const fetchAllJenkinsServers = async () => { const servers = await getAllJenkinsServers() || []; @@ -47,7 +49,7 @@ const JenkinsServerList = (): JSX.Element => { const renovatedJenkinsFeatureFlag = await fetchFeatureFlagFromBackend( FeatureFlags.RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW ); - console.log('renovatedJenkinsFeatureFlag:', renovatedJenkinsFeatureFlag); + setRenovateConfigFlag(renovatedJenkinsFeatureFlag); }, []); useEffect(() => { @@ -57,8 +59,6 @@ const JenkinsServerList = (): JSX.Element => { fetchFeatureFlag(); }, [redirectToAdminPage, cloudId, fetchFeatureFlag]); - console.log('CLOUD ID: ', cloudId); - // Use the useFeatureFlag hook to get the value of RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW if (!jenkinsServers || !moduleKey || (moduleKey === 'jenkins-for-jira-ui-admin-page' && !jenkinsServers?.length)) { return ; @@ -81,25 +81,32 @@ const JenkinsServerList = (): JSX.Element => { const pageHeaderActions = ( + {/* TODO - add onClick event */} + {renovateConfigFlag && } ); + const headerText = renovateConfigFlag ? 'Jenkins for Jira' : 'Jenkins configuration'; + let contentToRender; if (jenkinsServers?.length && moduleKey === 'jenkins-for-jira-ui-admin-page') { contentToRender = ( <>
- Jenkins configuration + {headerText}
- + + {!renovateConfigFlag && After you connect your Jenkins server to Jira and send a deployment event from your CI/CD tool, you will be able to view development information within your linked Jira issue and view deployment pipelines over a timeline with insights. - + } + + {renovateConfigFlag && } ); diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx new file mode 100644 index 00000000..7c655284 --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx @@ -0,0 +1,31 @@ +import { css } from '@emotion/css'; + +export const TopPanelContainer = css` + align-items: center; + border-radius: 8px; + box-shadow: 0px 2px 4px 0px #091E4240; + display: flex; + max-height: 164px; + padding: 24px; + margin: 2em auto 2em 0.1em; + width: 936px; +`; + +export const TopPanelContentHeader = css` + font-size: 20px; + line-height: 24px; +`; + +export const TopPanelContent = css` + font-size: 14px; + line-height: 20px; + margin: 1em auto 1em 0; +`; + +export const TopPanelImgContainer = css` + flex: 1; +`; + +export const TopPanelImg = css` + max-width: 65%; +`; diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx new file mode 100644 index 00000000..180f2bf7 --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { cx } from '@emotion/css'; +import { + TopPanelContainer, + TopPanelContent, + TopPanelContentHeader, + TopPanelImg, + TopPanelImgContainer +} from './TopPanel.styles'; +import PlugInImage from '../../assets/PlugIn.svg'; + +const TopPanel = () => { + return ( +
+
+

Server management

+

Jenkins for Jira lets your teams keep track of code + they build and deploy on Jenkins
servers.

+ {/* TODO - add link */} +

Follow the set up guide for each server to + receive build and deployment data.

+
+
+ Connect Jenkins with Jira +
+
+ ); +}; + +export { TopPanel }; From 249cec98fc2a463c18108fe8f267590f40465aef Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Mon, 13 Nov 2023 17:56:24 +1100 Subject: [PATCH 03/10] add tests --- .../JenkinsServerList/JenkinsServerList.tsx | 1 - .../TopPanel/TopPanel.test.tsx | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index 197cb8de..03db9adf 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -59,7 +59,6 @@ const JenkinsServerList = (): JSX.Element => { fetchFeatureFlag(); }, [redirectToAdminPage, cloudId, fetchFeatureFlag]); - // Use the useFeatureFlag hook to get the value of RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW if (!jenkinsServers || !moduleKey || (moduleKey === 'jenkins-for-jira-ui-admin-page' && !jenkinsServers?.length)) { return ; } diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx new file mode 100644 index 00000000..13f6c7f6 --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { TopPanel } from './TopPanel'; + +describe('TopPanel Component', () => { + test('renders without errors', () => { + render(); + }); + + test('renders correct header text', () => { + const { getByText } = render(); + const headerElement = getByText('Server management'); + expect(headerElement).toBeInTheDocument(); + }); + + test('renders set up guide link', () => { + const { getByText } = render(); + const linkElement = getByText('set up guide'); + expect(linkElement).toBeInTheDocument(); + }); + + test('renders strong tag for "set up guide"', () => { + const { getByText } = render(); + const strongElement = getByText('set up guide'); + expect(strongElement.tagName).toBe('STRONG'); + }); + + test('renders image with alt text', () => { + const { getByAltText } = render(); + const imageElement = getByAltText('Connect Jenkins with Jira'); + expect(imageElement).toBeInTheDocument(); + }); +}); From 5453690ea4505afd2b388a9c72a8aa650353efc8 Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Mon, 13 Nov 2023 22:07:26 +1100 Subject: [PATCH 04/10] wip --- .../src/api/fetchFeatureFlagFromBackend.ts | 4 +++- .../components/JenkinsServerList/JenkinsServerList.tsx | 9 ++++++++- app/src/config/feature-flags.ts | 6 ++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts b/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts index 831ddd9c..89597161 100644 --- a/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts +++ b/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts @@ -1,5 +1,7 @@ import { invoke } from '@forge/bridge'; export const fetchFeatureFlagFromBackend = async (featureFlag: string): Promise => { - return invoke('fetchFeatureFlagFromBackend', { featureFlag }); + const featureFlagStatus: boolean = await invoke('fetchFeatureFlagFromBackend', { featureFlag }); + console.log('featureFlagStatus: ', featureFlagStatus); + return featureFlagStatus; }; diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index 03db9adf..88f9d55b 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -59,7 +59,11 @@ const JenkinsServerList = (): JSX.Element => { fetchFeatureFlag(); }, [redirectToAdminPage, cloudId, fetchFeatureFlag]); - if (!jenkinsServers || !moduleKey || (moduleKey === 'jenkins-for-jira-ui-admin-page' && !jenkinsServers?.length)) { + console.log('renovateConfigFlag: ', renovateConfigFlag); + console.log('jenkinsServers: ', jenkinsServers); + console.log('moduleKey: ', moduleKey); + + if (!jenkinsServers || !moduleKey) { return ; } @@ -92,6 +96,7 @@ const JenkinsServerList = (): JSX.Element => { let contentToRender; if (jenkinsServers?.length && moduleKey === 'jenkins-for-jira-ui-admin-page') { + console.log('in configured'); contentToRender = ( <>
@@ -110,6 +115,7 @@ const JenkinsServerList = (): JSX.Element => { ); } else if (moduleKey === 'get-started-page') { + console.log('in get started'); contentToRender = ( <>
@@ -119,6 +125,7 @@ const JenkinsServerList = (): JSX.Element => { ); } else { + console.log('in empty'); contentToRender = ( <>
diff --git a/app/src/config/feature-flags.ts b/app/src/config/feature-flags.ts index c9793e38..95fc7d8a 100644 --- a/app/src/config/feature-flags.ts +++ b/app/src/config/feature-flags.ts @@ -119,6 +119,7 @@ export const launchDarklyService = { }; export const fetchFeatureFlag = async (featureFlagKey: string, cloudId?: string): Promise => { + console.log('backend'); try { // custom env var as Forge overrides NODE_ENV in every environment with production // left NODE_ENV as a fallback as it's needed for tests and pipelines @@ -127,13 +128,18 @@ export const fetchFeatureFlag = async (featureFlagKey: string, cloudId?: string) const envData = featureFlag.environments[environment]; if (cloudId && envData.targets) { + console.log('cloudId: ', cloudId); const values = envData.targets.flatMap((target) => target.values); + console.log('cloudId: ', cloudId); if (values.includes(cloudId)) { + console.log('FEATURE FLAG IS ON!!!'); // If the cloudId is in any of the values within the targets, set the value to true return true; } } + console.log('nah it is off: ', envData.on); + // If the cloudId is not in the targets or no cloudId is provided, use the "on" value return envData.on || false; } catch (error) { From 14dd5fbbb537b90d8e60bb8ba788b9af07ddcd06 Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Mon, 13 Nov 2023 22:48:42 +1100 Subject: [PATCH 05/10] wip --- .../src/api/fetchFeatureFlagFromBackend.ts | 1 - .../components/JenkinsServerList/JenkinsServerList.tsx | 9 +-------- app/src/config/feature-flags.ts | 6 ------ 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts b/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts index 89597161..022538bf 100644 --- a/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts +++ b/app/jenkins-for-jira-ui/src/api/fetchFeatureFlagFromBackend.ts @@ -2,6 +2,5 @@ import { invoke } from '@forge/bridge'; export const fetchFeatureFlagFromBackend = async (featureFlag: string): Promise => { const featureFlagStatus: boolean = await invoke('fetchFeatureFlagFromBackend', { featureFlag }); - console.log('featureFlagStatus: ', featureFlagStatus); return featureFlagStatus; }; diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index 88f9d55b..3f2396b3 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -59,11 +59,7 @@ const JenkinsServerList = (): JSX.Element => { fetchFeatureFlag(); }, [redirectToAdminPage, cloudId, fetchFeatureFlag]); - console.log('renovateConfigFlag: ', renovateConfigFlag); - console.log('jenkinsServers: ', jenkinsServers); - console.log('moduleKey: ', moduleKey); - - if (!jenkinsServers || !moduleKey) { + if (!jenkinsServers || !moduleKey || moduleKey === 'get-started-page') { return ; } @@ -96,7 +92,6 @@ const JenkinsServerList = (): JSX.Element => { let contentToRender; if (jenkinsServers?.length && moduleKey === 'jenkins-for-jira-ui-admin-page') { - console.log('in configured'); contentToRender = ( <>
@@ -115,7 +110,6 @@ const JenkinsServerList = (): JSX.Element => { ); } else if (moduleKey === 'get-started-page') { - console.log('in get started'); contentToRender = ( <>
@@ -125,7 +119,6 @@ const JenkinsServerList = (): JSX.Element => { ); } else { - console.log('in empty'); contentToRender = ( <>
diff --git a/app/src/config/feature-flags.ts b/app/src/config/feature-flags.ts index 95fc7d8a..c9793e38 100644 --- a/app/src/config/feature-flags.ts +++ b/app/src/config/feature-flags.ts @@ -119,7 +119,6 @@ export const launchDarklyService = { }; export const fetchFeatureFlag = async (featureFlagKey: string, cloudId?: string): Promise => { - console.log('backend'); try { // custom env var as Forge overrides NODE_ENV in every environment with production // left NODE_ENV as a fallback as it's needed for tests and pipelines @@ -128,18 +127,13 @@ export const fetchFeatureFlag = async (featureFlagKey: string, cloudId?: string) const envData = featureFlag.environments[environment]; if (cloudId && envData.targets) { - console.log('cloudId: ', cloudId); const values = envData.targets.flatMap((target) => target.values); - console.log('cloudId: ', cloudId); if (values.includes(cloudId)) { - console.log('FEATURE FLAG IS ON!!!'); // If the cloudId is in any of the values within the targets, set the value to true return true; } } - console.log('nah it is off: ', envData.on); - // If the cloudId is not in the targets or no cloudId is provided, use the "on" value return envData.on || false; } catch (error) { From 396af2dd1a7505ec345dce684b7e4e9a8dae36ed Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Tue, 14 Nov 2023 13:50:49 +1100 Subject: [PATCH 06/10] pull flag check up to top level --- app/jenkins-for-jira-ui/src/App.tsx | 21 +++++++++++-- .../JenkinsServerList/JenkinsServerList.tsx | 27 +++------------- .../src/components/MainPage/MainPage.tsx | 31 +++++++++++++++++++ 3 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx diff --git a/app/jenkins-for-jira-ui/src/App.tsx b/app/jenkins-for-jira-ui/src/App.tsx index d4c0e88a..72e6a7b9 100644 --- a/app/jenkins-for-jira-ui/src/App.tsx +++ b/app/jenkins-for-jira-ui/src/App.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { Router, Switch, @@ -16,6 +16,9 @@ import { JenkinsSpinner } from './components/JenkinsSpinner/JenkinsSpinner'; import { PendingDeploymentState } from './components/JenkinsServerList/PendingDeploymentState/PendingDeploymentState'; import { CreateServer } from './components/ConnectJenkins/CreateServer/CreateServer'; import envVars, { Environment } from './common/env'; +import { fetchFeatureFlagFromBackend } from './api/fetchFeatureFlagFromBackend'; +import { FeatureFlags } from './hooks/useFeatureFlag'; +import { MainPage } from './components/MainPage/MainPage'; const { LAUNCHDARKLY_TEST_CLIENT_ID, @@ -54,12 +57,21 @@ const AppContainer = styled.div` const App: React.FC = () => { const [history, setHistory] = useState(null); + const [renovateConfigFlag, setRenovateConfigFlag] = useState(false); + + const fetchFeatureFlag = useCallback(async () => { + const renovatedJenkinsFeatureFlag = await fetchFeatureFlagFromBackend( + FeatureFlags.RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW + ); + setRenovateConfigFlag(renovatedJenkinsFeatureFlag); + }, []); useEffect(() => { view.createHistory().then((historyUpdates) => { setHistory(historyUpdates); }); - }, []); + fetchFeatureFlag(); + }, [fetchFeatureFlag]); if (!history) { return ; @@ -70,7 +82,10 @@ const App: React.FC = () => { - + {renovateConfigFlag + ? + : + } diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index 3f2396b3..f2e4e911 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -17,10 +17,7 @@ import { AnalyticsUiEventsEnum } from '../../common/analytics/analytics-events'; import { redirectFromGetStarted } from '../../api/redirectFromGetStarted'; -import { FeatureFlags } from '../../hooks/useFeatureFlag'; import { fetchCloudId } from '../../api/fetchCloudId'; -import { fetchFeatureFlagFromBackend } from '../../api/fetchFeatureFlagFromBackend'; -import { TopPanel } from './TopPanel/TopPanel'; const JenkinsServerList = (): JSX.Element => { const history = useHistory(); @@ -28,7 +25,6 @@ const JenkinsServerList = (): JSX.Element => { const [jenkinsServers, setJenkinsServers] = useState(); const [moduleKey, setModuleKey] = useState(); const [cloudId, setCloudId] = useState(); - const [renovateConfigFlag, setRenovateConfigFlag] = useState(false); const fetchAllJenkinsServers = async () => { const servers = await getAllJenkinsServers() || []; @@ -45,19 +41,11 @@ const JenkinsServerList = (): JSX.Element => { setModuleKey(currentModuleKey); }, []); - const fetchFeatureFlag = useCallback(async () => { - const renovatedJenkinsFeatureFlag = await fetchFeatureFlagFromBackend( - FeatureFlags.RENOVATED_JENKINS_FOR_JIRA_CONFIG_FLOW - ); - setRenovateConfigFlag(renovatedJenkinsFeatureFlag); - }, []); - useEffect(() => { fetchAllJenkinsServers(); redirectToAdminPage(); getCloudId(); - fetchFeatureFlag(); - }, [redirectToAdminPage, cloudId, fetchFeatureFlag]); + }, [redirectToAdminPage, cloudId]); if (!jenkinsServers || !moduleKey || moduleKey === 'get-started-page') { return ; @@ -80,32 +68,27 @@ const JenkinsServerList = (): JSX.Element => { const pageHeaderActions = ( - {/* TODO - add onClick event */} - {renovateConfigFlag && } ); - const headerText = renovateConfigFlag ? 'Jenkins for Jira' : 'Jenkins configuration'; - let contentToRender; if (jenkinsServers?.length && moduleKey === 'jenkins-for-jira-ui-admin-page') { contentToRender = ( <>
- {headerText} + Jenkins configuration
- {!renovateConfigFlag && + After you connect your Jenkins server to Jira and send a deployment event from your CI/CD tool, you will be able to view development information within your linked Jira issue and view deployment pipelines over a timeline with insights. - } + - {renovateConfigFlag && } ); diff --git a/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx new file mode 100644 index 00000000..8670537c --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import PageHeader from '@atlaskit/page-header'; +import { ButtonGroup } from '@atlaskit/button'; +import Button from '@atlaskit/button/standard-button'; +import { headerContainer } from '../JenkinsServerList/JenkinsServerList.styles'; +import { TopPanel } from '../JenkinsServerList/TopPanel/TopPanel'; + +const MainPage = () => { + const pageHeaderActions = ( + + {/* TODO - add onClick event */} + + {/* TODO - add onClick event */} + + + ); + + return ( + <> +
+ Jenkins for Jira +
+ + + + ); +}; + +export { MainPage }; From cf7d8d210b581a40ac2a6140db9d575dae093a79 Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Tue, 14 Nov 2023 13:51:54 +1100 Subject: [PATCH 07/10] add return type --- .../src/components/JenkinsServerList/TopPanel/TopPanel.tsx | 2 +- app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx index 180f2bf7..d07789a7 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx @@ -9,7 +9,7 @@ import { } from './TopPanel.styles'; import PlugInImage from '../../assets/PlugIn.svg'; -const TopPanel = () => { +const TopPanel = (): JSX.Element => { return (
diff --git a/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx index 8670537c..275acee6 100644 --- a/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx +++ b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx @@ -5,7 +5,7 @@ import Button from '@atlaskit/button/standard-button'; import { headerContainer } from '../JenkinsServerList/JenkinsServerList.styles'; import { TopPanel } from '../JenkinsServerList/TopPanel/TopPanel'; -const MainPage = () => { +const MainPage = (): JSX.Element => { const pageHeaderActions = ( {/* TODO - add onClick event */} From afc9bc2ef795c9f4f469e8dd8fbd90b106a316ef Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Tue, 14 Nov 2023 13:53:29 +1100 Subject: [PATCH 08/10] revert jsl changes --- .../JenkinsServerList/JenkinsServerList.tsx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx index f2e4e911..a3b63623 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx +++ b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/JenkinsServerList.tsx @@ -17,25 +17,17 @@ import { AnalyticsUiEventsEnum } from '../../common/analytics/analytics-events'; import { redirectFromGetStarted } from '../../api/redirectFromGetStarted'; -import { fetchCloudId } from '../../api/fetchCloudId'; const JenkinsServerList = (): JSX.Element => { const history = useHistory(); const analyticsClient = new AnalyticsClient(); const [jenkinsServers, setJenkinsServers] = useState(); const [moduleKey, setModuleKey] = useState(); - const [cloudId, setCloudId] = useState(); - const fetchAllJenkinsServers = async () => { const servers = await getAllJenkinsServers() || []; setJenkinsServers(servers); }; - const getCloudId = async () => { - const id = await fetchCloudId(); - setCloudId(id); - }; - const redirectToAdminPage = useCallback(async () => { const currentModuleKey = await redirectFromGetStarted(); setModuleKey(currentModuleKey); @@ -44,8 +36,7 @@ const JenkinsServerList = (): JSX.Element => { useEffect(() => { fetchAllJenkinsServers(); redirectToAdminPage(); - getCloudId(); - }, [redirectToAdminPage, cloudId]); + }, [redirectToAdminPage]); if (!jenkinsServers || !moduleKey || moduleKey === 'get-started-page') { return ; @@ -81,14 +72,12 @@ const JenkinsServerList = (): JSX.Element => {
Jenkins configuration
- After you connect your Jenkins server to Jira and send a deployment event from your CI/CD tool, you will be able to view development information within your linked Jira issue and view deployment pipelines over a timeline with insights. - ); From e10c5c5d8dbf48347c07ebdf5eb2cd81ce41bb08 Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Thu, 16 Nov 2023 11:47:35 +1100 Subject: [PATCH 09/10] clean up --- app/jenkins-for-jira-ui/src/App.tsx | 2 +- .../TopPanel/TopPanel.styles.tsx | 31 ---- .../JenkinsServerList/TopPanel/TopPanel.tsx | 30 ---- .../components/MainPage/MainPage.styles.tsx | 41 +++++ .../src/components/MainPage/MainPage.tsx | 7 +- .../TopPanel/TopPanel.test.tsx | 13 +- .../components/MainPage/TopPanel/TopPanel.tsx | 29 ++++ .../src/components/icons/PluginIcon.tsx | 154 ++++++++++++++++++ 8 files changed, 230 insertions(+), 77 deletions(-) delete mode 100644 app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx delete mode 100644 app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx create mode 100644 app/jenkins-for-jira-ui/src/components/MainPage/MainPage.styles.tsx rename app/jenkins-for-jira-ui/src/components/{JenkinsServerList => MainPage}/TopPanel/TopPanel.test.tsx (60%) create mode 100644 app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.tsx create mode 100644 app/jenkins-for-jira-ui/src/components/icons/PluginIcon.tsx diff --git a/app/jenkins-for-jira-ui/src/App.tsx b/app/jenkins-for-jira-ui/src/App.tsx index 72e6a7b9..242063df 100644 --- a/app/jenkins-for-jira-ui/src/App.tsx +++ b/app/jenkins-for-jira-ui/src/App.tsx @@ -52,7 +52,7 @@ export const environmentSettings = { const AppContainer = styled.div` color: #172B4D; - margin: 24px 24px 24px 0; + margin: 24px 36px 24px 0; `; const App: React.FC = () => { diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx deleted file mode 100644 index 7c655284..00000000 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.styles.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { css } from '@emotion/css'; - -export const TopPanelContainer = css` - align-items: center; - border-radius: 8px; - box-shadow: 0px 2px 4px 0px #091E4240; - display: flex; - max-height: 164px; - padding: 24px; - margin: 2em auto 2em 0.1em; - width: 936px; -`; - -export const TopPanelContentHeader = css` - font-size: 20px; - line-height: 24px; -`; - -export const TopPanelContent = css` - font-size: 14px; - line-height: 20px; - margin: 1em auto 1em 0; -`; - -export const TopPanelImgContainer = css` - flex: 1; -`; - -export const TopPanelImg = css` - max-width: 65%; -`; diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx b/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx deleted file mode 100644 index d07789a7..00000000 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { cx } from '@emotion/css'; -import { - TopPanelContainer, - TopPanelContent, - TopPanelContentHeader, - TopPanelImg, - TopPanelImgContainer -} from './TopPanel.styles'; -import PlugInImage from '../../assets/PlugIn.svg'; - -const TopPanel = (): JSX.Element => { - return ( -
-
-

Server management

-

Jenkins for Jira lets your teams keep track of code - they build and deploy on Jenkins
servers.

- {/* TODO - add link */} -

Follow the set up guide for each server to - receive build and deployment data.

-
-
- Connect Jenkins with Jira -
-
- ); -}; - -export { TopPanel }; diff --git a/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.styles.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.styles.tsx new file mode 100644 index 00000000..c5ec01bd --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.styles.tsx @@ -0,0 +1,41 @@ +import { css } from '@emotion/css'; + +export const mainPageContainer = css` + margin: 0 auto; + max-width: 936px; +`; + +// Top panel +export const topPanelContainer = css` + align-items: center; + border-radius: 8px; + box-shadow: 0px 2px 4px 0px #091E4240; + display: flex; + max-height: 164px; + padding: 1.5em; + margin: 2em auto 2em 0.1em; +`; + +export const topPanelContentHeaderContainer = css` + flex-direction: column; +`; + +export const topPanelContentHeader = css` + font-size: 20px; + line-height: 24px; +`; + +export const topPanelContent = css` + font-size: 14px; + line-height: 20px; + margin: 1em auto 1em 0; +`; + +export const topPanelImgContainer = css` + text-align: right; + width: 42%; +`; + +export const topPanelImg = css` + width: 75%; +`; diff --git a/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx index 275acee6..3eb2141d 100644 --- a/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx +++ b/app/jenkins-for-jira-ui/src/components/MainPage/MainPage.tsx @@ -3,7 +3,8 @@ import PageHeader from '@atlaskit/page-header'; import { ButtonGroup } from '@atlaskit/button'; import Button from '@atlaskit/button/standard-button'; import { headerContainer } from '../JenkinsServerList/JenkinsServerList.styles'; -import { TopPanel } from '../JenkinsServerList/TopPanel/TopPanel'; +import { TopPanel } from './TopPanel/TopPanel'; +import { mainPageContainer } from './MainPage.styles'; const MainPage = (): JSX.Element => { const pageHeaderActions = ( @@ -18,13 +19,13 @@ const MainPage = (): JSX.Element => { ); return ( - <> +
Jenkins for Jira
- +
); }; diff --git a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx similarity index 60% rename from app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx rename to app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx index 13f6c7f6..f3b5c93a 100644 --- a/app/jenkins-for-jira-ui/src/components/JenkinsServerList/TopPanel/TopPanel.test.tsx +++ b/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx @@ -17,18 +17,7 @@ describe('TopPanel Component', () => { test('renders set up guide link', () => { const { getByText } = render(); const linkElement = getByText('set up guide'); + expect(linkElement.tagName).toBe('STRONG'); expect(linkElement).toBeInTheDocument(); }); - - test('renders strong tag for "set up guide"', () => { - const { getByText } = render(); - const strongElement = getByText('set up guide'); - expect(strongElement.tagName).toBe('STRONG'); - }); - - test('renders image with alt text', () => { - const { getByAltText } = render(); - const imageElement = getByAltText('Connect Jenkins with Jira'); - expect(imageElement).toBeInTheDocument(); - }); }); diff --git a/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.tsx new file mode 100644 index 00000000..6b5b5147 --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { cx } from '@emotion/css'; +import { + topPanelContainer, + topPanelContent, + topPanelContentHeader, + topPanelContentHeaderContainer, + topPanelImgContainer, + topPanelImg +} from '../MainPage.styles'; +import { PluginIcon } from '../../icons/PluginIcon'; + +const TopPanel = (): JSX.Element => { + return ( +
+
+

Server management

+

Jenkins for Jira lets your teams keep track of code + they build and deploy on Jenkins servers.

+ {/* TODO - add link */} +

Follow the set up guide for each server to + receive build and deployment data.

+
+ +
+ ); +}; + +export { TopPanel }; diff --git a/app/jenkins-for-jira-ui/src/components/icons/PluginIcon.tsx b/app/jenkins-for-jira-ui/src/components/icons/PluginIcon.tsx new file mode 100644 index 00000000..7b891ea1 --- /dev/null +++ b/app/jenkins-for-jira-ui/src/components/icons/PluginIcon.tsx @@ -0,0 +1,154 @@ +import React from 'react'; +import { cx } from '@emotion/css'; + +type PluginIconProps = { + containerClassName: string, + svgClassName: string +}; + +export function PluginIcon({ containerClassName, svgClassName }: PluginIconProps): JSX.Element { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} From 97b7c523a1457fd69016099082ace77aa2b72c78 Mon Sep 17 00:00:00 2001 From: Rachelle Rathbone Date: Thu, 16 Nov 2023 13:46:19 +1100 Subject: [PATCH 10/10] Delete app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx Deleted this locally and pushed but changes aren't showing up. Guessing wifi issues? --- .../MainPage/TopPanel/TopPanel.test.tsx | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx diff --git a/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx b/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx deleted file mode 100644 index f3b5c93a..00000000 --- a/app/jenkins-for-jira-ui/src/components/MainPage/TopPanel/TopPanel.test.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; -import { TopPanel } from './TopPanel'; - -describe('TopPanel Component', () => { - test('renders without errors', () => { - render(); - }); - - test('renders correct header text', () => { - const { getByText } = render(); - const headerElement = getByText('Server management'); - expect(headerElement).toBeInTheDocument(); - }); - - test('renders set up guide link', () => { - const { getByText } = render(); - const linkElement = getByText('set up guide'); - expect(linkElement.tagName).toBe('STRONG'); - expect(linkElement).toBeInTheDocument(); - }); -});