Skip to content

Commit

Permalink
Merge pull request #203 from atlassian/ARC-2677-set-up-guide
Browse files Browse the repository at this point in the history
Arc-2677 set up guide
  • Loading branch information
rachellerathbone authored Nov 22, 2023
2 parents 88b298f + 24c7f97 commit f8d25b0
Show file tree
Hide file tree
Showing 5 changed files with 359 additions and 8 deletions.
1 change: 1 addition & 0 deletions app/jenkins-for-jira-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@atlaskit/avatar": "20.5.10",
"@atlaskit/button": "16.10.1",
"@atlaskit/css-reset": "6.5.4",
"@atlaskit/drawer": "^7.6.5",
"@atlaskit/dropdown-menu": "11.14.2",
"@atlaskit/dynamic-table": "14.11.6",
"@atlaskit/empty-state": "7.6.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export const connectionPanelMainContainer = css`
}
}
#connection-panel-tabs-1-tab {
padding-left: ${token('space.0')};
}
[role=tablist] {
&:first-of-type {
::before {
Expand Down Expand Up @@ -101,3 +105,93 @@ export const notConnectedStateParagraph = css`
margin-bottom: ${token('space.300')}
}
`;

// Set up guide
export const setUpGuideContainer = css`
line-height: 20px;
margin: ${token('space.200')} 0 ${token('space.300')};
#setup-step-one-instruction {
margin: ${token('space.050')} 0 ${token('space.300')} ${token('space.200')};
}
`;

export const setUpGuideParagraph = css`
margin-bottom: ${token('space.300')};
`;

export const setUpGuideOrderedList = css`
padding-left: ${token('space.200')};
list-style: none;
counter-reset: item;
#nested-list {
margin-top: ${token('space.0')};
}
`;

export const setUpGuideOrderedListItem = css`
margin-bottom: ${token('space.200')};
padding-left: ${token('space.200')};
counter-increment: item;
margin-bottom: ${token('space.075')};
::before {
background: #F7F8F9;
border-radius: 50%;
content: counter(item);
display: inline-block;
font-weight: bold;
height: ${token('space.400')};
line-height: ${token('space.400')};
margin: 0 ${token('space.200')} 0 ${token('space.negative.400')};
text-align: center;
width: ${token('space.400')};
}
`;

export const setUpGuideNestedOrderedList = css`
counter-reset: item;
margin-top: 0 !important;
padding-left: ${token('space.400')};
p:first-of-type {
margin-top: ${token('space.100')};;
}
p:not(:first-of-type) {
margin-top: ${token('space.075')};;
}
`;

export const setUpGuideNestedOrderedListItem = css`
margin-bottom: ${token('space.400')};
`;

export const setUpGuideOrderListItemHeader = css`
font-weight: bold;
margin-bottom: ${token('space.200')};
`;

export const setUpGuideLink = css`
background-color: inherit;
border: none;
color: ${token('color.link')};
padding: ${token('space.0')}
`;

export const setUpGuideInfoPanel = css`
background-color: #F7F8F9;
display: flex;
margin-left: ${token('space.100')};
padding: ${token('space.250')};
[role=img] {
margin-right: ${token('space.100')};
}
p {
margin-top: ${token('space.0')};
}
`;
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import React, { ReactNode } from 'react';
import { cx } from '@emotion/css';
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
import { connectionPanelMainContainer, connectionPanelMainTabs } from './ConnectionPanel.styles';
import { connectionPanelMainContainer, connectionPanelMainTabs, setUpGuideContainer } from './ConnectionPanel.styles';
import { ConnectedState } from '../StatusLabel/StatusLabel';
import { NotConnectedState } from './NotConnectedState';
import { SetUpGuide } from './SetUpGuide';

export const Panel = ({
children,
testId
'data-testid': testid
}: {
children: ReactNode;
testId?: string;
'data-testid'?: string;
}) => (
<div className={cx(connectionPanelMainTabs)} data-testid={testId}>
<div className={cx(testid === 'setUpGuidePanel'
? setUpGuideContainer : connectionPanelMainTabs)} data-testid={testid }>
{children}
</div>
);
Expand All @@ -36,12 +38,14 @@ const ConnectionPanelMain = ({ connectedState }: ConnectionPanelMainProps): JSX.
<TabPanel>
{
connectedState === ConnectedState.CONNECTED
? <Panel>List of servers goes here</Panel>
: <Panel><NotConnectedState connectedState={connectedState} /></Panel>
? <Panel data-testid="connectedServersPanel">List of servers goes here</Panel>
: <Panel data-testid="notConnectedPanel"><NotConnectedState connectedState={connectedState} /></Panel>
}
</TabPanel>
<TabPanel>
<Panel>Set up guide info to go here</Panel>
<Panel data-testid="setUpGuidePanel">
<SetUpGuide />
</Panel>
</TabPanel>
</Tabs>
}
Expand Down
172 changes: 172 additions & 0 deletions app/jenkins-for-jira-ui/src/components/ConnectionPanel/SetUpGuide.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import React, { useEffect, useState } from 'react';
import { cx } from '@emotion/css';
import Drawer from '@atlaskit/drawer';
import PeopleGroup from '@atlaskit/icon/glyph/people-group';
import {
setUpGuideLink,
setUpGuideInfoPanel,
setUpGuideNestedOrderedList,
setUpGuideNestedOrderedListItem,
setUpGuideOrderedList,
setUpGuideOrderedListItem,
setUpGuideOrderListItemHeader,
setUpGuideParagraph,
setUpGuideContainer
} from './ConnectionPanel.styles';

type SetUpGuideLinkProps = {
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void,
label: string,
};

const SetUpGuideLink = ({ onClick, label }: SetUpGuideLinkProps): JSX.Element => {
return (
<button className={cx(setUpGuideLink)} onClick={onClick}>
{label}
</button>
);
};

type SetUpGuidePipelineStepInstructionProps = {
eventType: string,
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void,
pipelineStepLabel: string
};

const SetUpGuidePipelineStepInstruction = ({
eventType,
onClick,
pipelineStepLabel
}: SetUpGuidePipelineStepInstructionProps): JSX.Element => {
return (
<p>Add a &nbsp;
<SetUpGuideLink onClick={onClick} label={pipelineStepLabel} />&nbsp;
step to the end of {eventType} stages.
</p>
);
};

enum PipelineEventType {
BUILD = 'build',
DEPLOYMENT = 'deployment'
}

type SetUpGuideInstructionsProps = {
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void,
eventType: PipelineEventType,
globalSettings: boolean,
buildFilters: boolean
};

const SetUpGuideInstructions = ({
onClick,
eventType,
globalSettings,
buildFilters
}: SetUpGuideInstructionsProps): JSX.Element => {
const pipelineStepLabel = eventType === PipelineEventType.BUILD ? 'jiraSendBuildInfo' : 'jiraSendDeploymentInfo';

return (
<li className={cx(setUpGuideNestedOrderedListItem)}>
Set up what {eventType} events are sent to Jira:
{
!globalSettings
? <SetUpGuidePipelineStepInstruction
eventType={eventType}
onClick={onClick}
pipelineStepLabel={pipelineStepLabel}
/>
: <>
{
!buildFilters && eventType === PipelineEventType.BUILD
? <p><SetUpGuideLink onClick={onClick} label="No setup required" /></p>
: <>
<SetUpGuidePipelineStepInstruction
eventType={eventType}
onClick={onClick}
pipelineStepLabel={pipelineStepLabel}
/>
<p><strong>OR</strong></p>
<p>Use &nbsp;
<SetUpGuideLink onClick={onClick} label="&lt;regex&gt;" />&nbsp;
in the names of the {eventType} stages.
</p>
</>
}
</>
}
</li>
);
};

const SetUpGuide = (): JSX.Element => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [areGlobalSettingsOn, setAreGlobalSettingsOn] = useState(false);
const [hasBuildFilters, setHasBuildFilters] = useState(false);

useEffect(() => {
// TODO - update global settings based on new data received from Jenkins plugin
setAreGlobalSettingsOn(false);
setHasBuildFilters(false);
}, []);

const openDrawer = () => {
setIsDrawerOpen(true);
};

const onClose = () => {
setIsDrawerOpen(false);
};

return (
<div className={cx(setUpGuideContainer)}>
<Drawer
onClose={onClose}
isOpen={isDrawerOpen}
width="wide"
label="Basic drawer"
>
{/* TODO - update this to render content for the 'link' clicked */}
<div>Add content here for each link item</div>
</Drawer>
<p className={cx(setUpGuideParagraph)}>To receive build and deployment data from this server:</p>

<ol className={cx(setUpGuideOrderedList)}>
<li className={cx(setUpGuideOrderedListItem)}>
<strong className={cx(setUpGuideOrderListItemHeader)}>Developers in your project teams</strong>
<p id="setup-step-one-instruction">Must enter their Jira issue keys
(e.g. <SetUpGuideLink onClick={openDrawer} label="JIRA-1234" />)
into their branch names and commit message.
</p>
</li>

<li className={cx(setUpGuideOrderedListItem)}><strong>The person setting up your Jenkinsfile</strong>
<ol className={cx(setUpGuideNestedOrderedList)} type="A" id="nested-list">
<SetUpGuideInstructions
onClick={openDrawer}
eventType={PipelineEventType.BUILD}
globalSettings={areGlobalSettingsOn}
buildFilters={hasBuildFilters}
/>
<SetUpGuideInstructions
onClick={openDrawer}
eventType={PipelineEventType.DEPLOYMENT}
globalSettings={areGlobalSettingsOn}
buildFilters={hasBuildFilters}
/>
</ol>
</li>
</ol>

<div className={cx(setUpGuideInfoPanel)}>
<PeopleGroup label="people-group" />
<p>
Not sure who should use this guide? It depends how your teams use Jenkins.&nbsp;
<SetUpGuideLink onClick={openDrawer} label="Here’s what you need to know." />
</p>
</div>
</div>
);
};

export { SetUpGuide };
Loading

0 comments on commit f8d25b0

Please sign in to comment.