Skip to content

Commit

Permalink
set up algolia
Browse files Browse the repository at this point in the history
  • Loading branch information
rachellerathbone committed Dec 11, 2023
1 parent bc823f6 commit 6609d07
Show file tree
Hide file tree
Showing 9 changed files with 3,443 additions and 143 deletions.
2 changes: 2 additions & 0 deletions app/jenkins-for-jira-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@atlaskit/dynamic-table": "14.11.6",
"@atlaskit/empty-state": "7.6.3",
"@atlaskit/form": "8.11.13",
"@atlaskit/help": "^7.2.16",
"@atlaskit/icon": "21.12.7",
"@atlaskit/logo": "13.14.8",
"@atlaskit/modal-dialog": "12.6.10",
Expand All @@ -36,6 +37,7 @@
"@types/react-dom": "17.0.20",
"@types/react-router": "5.1.20",
"@types/uuid": "8.3.4",
"algoliasearch": "^4.20.0",
"eslint-plugin-react-hooks": "4.6.0",
"launchdarkly-react-client-sdk": "^3.0.8",
"moment": "2.29.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { NotConnectedState } from './NotConnectedState';
import { JenkinsServer } from '../../../../src/common/types';
import { ConnectedJenkinsServers } from './ConnectedJenkinsServers';
import { SetUpGuide, UpdateAvailable } from './SetUpGuide';
import { InProductHelpDrawer } from '../InProductHelpDrawer/InProductHelpDrawer';
import { ConnectionPanelContent } from './ConnectionPanelContent';

type PanelProps = {
Expand Down Expand Up @@ -54,13 +53,8 @@ const ConnectionPanelMain = ({
jenkinsServer,
refreshServers
}: ConnectionPanelMainProps): JSX.Element => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [selectedTabIndex, setSelectedTabIndex] = useState(0);

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

const handleClickSetupGuide = () => {
setSelectedTabIndex(1);
};
Expand All @@ -75,7 +69,6 @@ const ConnectionPanelMain = ({

return (
<div className={cx(connectionPanelMainContainer)}>
<InProductHelpDrawer isDrawerOpen={isDrawerOpen} setIsDrawerOpen={setIsDrawerOpen} />
{
connectedState === ConnectedState.DUPLICATE
? <NotConnectedState
Expand Down Expand Up @@ -134,12 +127,11 @@ const ConnectionPanelMain = ({
? <Panel data-testid="setUpGuidePanel">
<SetUpGuide
pluginConfig={jenkinsServer.pluginConfig}
openDrawer={openDrawer}
/>
</Panel>
: <Panel data-testid="updateAvailable">
<div className={cx(setUpGuideUpdateAvailableContainer)}>
<UpdateAvailable openDrawer={openDrawer} />
<UpdateAvailable />
</div>
</Panel>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ import { render } from '@testing-library/react';
import { PipelineEventType, SetUpGuideInstructions } from './SetUpGuide';

describe('SetUpGuideInstructions', () => {
const onClickMock = jest.fn();

test('renders SetUpGuideInstructions with BUILD eventType, globalSettings, and regex', () => {
const { getByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.BUILD}
globalSettings
regex="^build$"
Expand All @@ -23,7 +20,6 @@ describe('SetUpGuideInstructions', () => {
test('renders SetUpGuideInstructions with BUILD eventType, globalSettings, and no regex', () => {
const { getByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.BUILD}
globalSettings
/>
Expand All @@ -35,7 +31,6 @@ describe('SetUpGuideInstructions', () => {
test('renders SetUpGuideInstructions with DEPLOYMENT eventType, globalSettings, and regex', () => {
const { getByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.DEPLOYMENT}
globalSettings
regex="^deploy to (?<envName>.*)$"
Expand All @@ -50,7 +45,6 @@ describe('SetUpGuideInstructions', () => {
test('renders SetUpGuideInstructions with DEPLOYMENT eventType, globalSettings set to false', () => {
const { getByText, queryByText } = render(
<SetUpGuideInstructions
onClick={onClickMock}
eventType={PipelineEventType?.DEPLOYMENT}
globalSettings={false}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ import { JenkinsPluginConfig } from '../../../../src/common/types';
import { UpdateAvailableIcon } from '../icons/UpdateAvailableIcon';
import { InProductHelpAction, InProductHelpActionType } from '../InProductHelpDrawer/InProductHelpAction';

type UpdateAvailableProps = {
openDrawer(): void
};

export const UpdateAvailable = ({ openDrawer }: UpdateAvailableProps): JSX.Element => {
export const UpdateAvailable = (): JSX.Element => {
return (
<>
<UpdateAvailableIcon containerClassName={setUpGuideUpdateAvailableIconContainer} />
Expand All @@ -33,7 +29,12 @@ export const UpdateAvailable = ({ openDrawer }: UpdateAvailableProps): JSX.Eleme
<p className={cx(setUpGuideUpdateAvailableContent)}>To access features like this set up guide,
a Jenkins admin must log into this server and update the plugin.</p>
<div className={cx(setUpGuideUpdateAvailableButtonContainer)}>
<InProductHelpAction onClick={openDrawer} label="Learn more" type={InProductHelpActionType.HelpButton} appearance="primary" />
<InProductHelpAction
label="Learn more"
type={InProductHelpActionType.HelpButton}
appearance="primary"
indexName="learn-more"
/>
{/* TODO - ARC-2738 */}
<Button>Refresh</Button>
</div>
Expand All @@ -43,22 +44,20 @@ export const UpdateAvailable = ({ openDrawer }: UpdateAvailableProps): JSX.Eleme

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;
<InProductHelpAction
onClick={onClick}
label={pipelineStepLabel}
type={InProductHelpActionType.HelpLink}
appearance="link"
indexName={pipelineStepLabel}
/>&nbsp;
step to the end of {eventType} stages.
</p>
Expand All @@ -71,14 +70,12 @@ export enum PipelineEventType {
}

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

export const SetUpGuideInstructions = ({
onClick,
eventType,
globalSettings,
regex
Expand All @@ -99,7 +96,6 @@ export const SetUpGuideInstructions = ({
<>
<SetUpGuidePipelineStepInstruction
eventType={eventType}
onClick={onClick}
pipelineStepLabel={pipelineStepLabel}
/>
<p>
Expand All @@ -108,10 +104,10 @@ export const SetUpGuideInstructions = ({
<p>
Use &nbsp;
<InProductHelpAction
onClick={onClick}
label={regex || '<regex>'}
type={InProductHelpActionType.HelpLink}
appearance="link"
indexName={regex || '<regex>'}
/>
&nbsp; in the names of the {eventType} stages.
</p>
Expand All @@ -120,13 +116,17 @@ export const SetUpGuideInstructions = ({
} else if (eventType === PipelineEventType.BUILD && globalSettings && !regex?.length) {
contentToRender =
<p>
<InProductHelpAction onClick={onClick} label="No setup required" type={InProductHelpActionType.HelpLink} appearance="link" />
<InProductHelpAction
label="No setup required"
type={InProductHelpActionType.HelpLink}
appearance="link"
indexName="no-set-up-required"
/>
</p>;
} else {
contentToRender = (
<SetUpGuidePipelineStepInstruction
eventType={eventType}
onClick={onClick}
pipelineStepLabel={pipelineStepLabel}
/>
);
Expand All @@ -141,13 +141,11 @@ export const SetUpGuideInstructions = ({
};

type SetUpGuideProps = {
pluginConfig?: JenkinsPluginConfig,
openDrawer(): void
pluginConfig?: JenkinsPluginConfig
};

const SetUpGuide = ({
pluginConfig,
openDrawer
pluginConfig
}: SetUpGuideProps): JSX.Element => {
return (
<>
Expand All @@ -159,21 +157,24 @@ const SetUpGuide = ({
Developers in your project teams
</strong>
<p id="setup-step-one-instruction">Must enter their Jira issue keys
(e.g. <InProductHelpAction onClick={openDrawer} label="JIRA-1234" type={InProductHelpActionType.HelpLink} appearance="link" />)
(e.g. <InProductHelpAction
label="JIRA-1234"
type={InProductHelpActionType.HelpLink}
appearance="link"
indexName="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={pluginConfig?.autoBuildEnabled}
regex={pluginConfig?.autoBuildRegex}
/>
<SetUpGuideInstructions
onClick={openDrawer}
eventType={PipelineEventType.DEPLOYMENT}
globalSettings={pluginConfig?.autoDeploymentsEnabled}
regex={pluginConfig?.autoDeploymentsRegex}
Expand All @@ -186,7 +187,12 @@ const SetUpGuide = ({
<PeopleGroup label="people-group" />
<p>
Not sure who should use this guide? It depends how your teams use Jenkins.&nbsp;
<InProductHelpAction onClick={openDrawer} label="Here’s what you need to know." type={InProductHelpActionType.HelpLink} appearance="link" />
<InProductHelpAction
label="Here’s what you need to know."
type={InProductHelpActionType.HelpLink}
appearance="link"
indexName="need-to-know"
/>
</p>
</div>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,70 @@
import React from 'react';
import React, { useState } from 'react';
import { cx } from '@emotion/css';
import Button, { Appearance } from '@atlaskit/button';
import { KeyboardOrMouseEvent } from '@atlaskit/modal-dialog';
import { inProductHelpActionLink } from './InProductHelp.styles';
import { InProductHelpDrawer } from './InProductHelpDrawer';
import useAlgolia, { Hit } from '../../hooks/useAlgolia';

export enum InProductHelpActionType {
HelpLink = 'link',
HelpButton = 'button'
}

type InProductHelpActionProps = {
onClick(e: KeyboardOrMouseEvent): void,
handleOpenDrawer?(e: KeyboardOrMouseEvent): void,
label: string,
type: InProductHelpActionType,
appearance: Appearance
appearance: Appearance,
indexName: string
};

export const InProductHelpAction = ({
onClick,
label,
type,
appearance
appearance,
indexName
}: InProductHelpActionProps): JSX.Element => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [hits, setHits] = useState<Hit[]>([]);

const inProductHelpTypeClassName =
type === InProductHelpActionType.HelpLink ? inProductHelpActionLink : '';

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

const handleSearch = async () => {
try {
const { hits: searchResults } = await useAlgolia({ indexName });
setHits(searchResults);
setIsDrawerOpen(true);
} catch (error) {
console.error('Error searching Algolia index:', error);
}
};

return (
<Button
className={cx(inProductHelpTypeClassName)}
onClick={onClick}
appearance={appearance}
>
{label}
</Button>
<>
<Button
className={cx(inProductHelpTypeClassName)}
onClick={(e) => {
e.preventDefault();
handleSearch().then(() => {
openDrawer();
});
}}
appearance={appearance}
>
{label}
</Button>
<InProductHelpDrawer
isDrawerOpen={isDrawerOpen}
setIsDrawerOpen={setIsDrawerOpen}
hits={hits}
indexName={indexName}
/>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ describe('InProductHelpAction', () => {

test('renders InProductHelpAction with label', () => {
const { getByText } = render(
<InProductHelpAction onClick={onClickMock} label="build" type={InProductHelpActionType.HelpButton} appearance="primary" />
<InProductHelpAction
handleOpenDrawer={onClickMock}
label="build"
type={InProductHelpActionType.HelpButton}
appearance="primary"
indexName="test-iph"
/>
);

expect(getByText('build')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import React from 'react';
import Drawer from '@atlaskit/drawer';
import { Hit } from '../../hooks/useAlgolia';

type InProductHelpDrawerProps = {
export type InProductHelpDrawerProps = {
isDrawerOpen: boolean,
setIsDrawerOpen(isDrawerOpen: boolean): void
setIsDrawerOpen(isDrawerOpen: boolean): void,
hits: Hit[],
indexName?: string
};

export const InProductHelpDrawer = ({ isDrawerOpen, setIsDrawerOpen }: InProductHelpDrawerProps): JSX.Element => {
export const InProductHelpDrawer = ({
isDrawerOpen,
setIsDrawerOpen,
hits,
indexName
}: InProductHelpDrawerProps): JSX.Element => {
const closeDrawer = () => {
setIsDrawerOpen(false);
};

console.log(hits);

return (
<Drawer
onClose={closeDrawer}
Expand All @@ -19,7 +29,7 @@ export const InProductHelpDrawer = ({ isDrawerOpen, setIsDrawerOpen }: InProduct
label="Basic drawer"
>
{/* TODO - ARC-2737 Algolia implementation */}
<div>Add content here for each link item</div>
<div>Add content here for each link item {indexName}</div>
</Drawer>
);
};
Loading

0 comments on commit 6609d07

Please sign in to comment.