Skip to content

Commit

Permalink
feat(releases): bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
abhinandan13jan committed Mar 12, 2024
1 parent 22428e7 commit 886e304
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 156 deletions.
Original file line number Diff line number Diff line change
@@ -1,115 +1,42 @@
import * as React from 'react';
import {
Button,
ButtonType,
DatePicker,
Form,
InputGroup,
InputGroupItem,
ModalVariant,
Stack,
StackItem,
Text,
TextContent,
TextVariants,
} from '@patternfly/react-core';
import { Formik, useFormikContext, useField } from 'formik';
import { InputField, TextAreaField, DropdownField } from '../../../../../shared';
import { ComponentProps, createModalLauncher } from '../../../../modal/createModalLauncher';
import { Button, Modal, ModalVariant } from '@patternfly/react-core';
import { Formik } from 'formik';
import * as yup from 'yup';
import { ComponentProps } from '../../../../modal/createModalLauncher';
import BugFormContent from './BugFormContent';

type AddBugModalProps = ComponentProps & {
obj?: any;
bugArrayHelper: (values) => void;
};

type AddBugFormValues = {
issueKey: string;
url: string;
uploadDate: string;
status: string;
};

const dropdownItems = [
{ key: 'inProgress', value: 'In progress' },
{ key: 'closed', value: 'Closed' },
{ key: 'resolved', value: 'Resolved' },
];

type StatusDropdownProps = Omit<
React.ComponentProps<typeof DropdownField>,
'items' | 'label' | 'placeholder'
>;

export const StatusDropdown: React.FC<React.PropsWithChildren<StatusDropdownProps>> = (props) => {
const [, , { setValue }] = useField<string>(props.name);

return (
<DropdownField
{...props}
label="Release plan"
placeholder="Select status of bug"
items={dropdownItems}
onChange={(app: string) => setValue(app)}
/>
);
};

const BugFormModal = () => {
const { handleSubmit, isSubmitting } = useFormikContext<AddBugFormValues>();
const formRef = React.useRef<HTMLDivElement>();

return (
<Form>
<div ref={formRef}>
<Stack hasGutter>
<StackItem>
<TextContent>
<Text component={TextVariants.p}>
Provide information about a Bug that has already been resolved.
</Text>
</TextContent>
</StackItem>
<StackItem>
<InputField label="Bug issue key" name="issueKey" required />
</StackItem>
<StackItem>
<InputField label="URL" name="url" required />
</StackItem>
<StackItem>
<InputGroup>
<InputGroupItem>
<DatePicker appendTo={formRef.current} />
</InputGroupItem>
</InputGroup>
</StackItem>
<StackItem>
<StatusDropdown name="status" />
</StackItem>
<StackItem>
<TextAreaField name="summary" label="Summary" />
</StackItem>
<StackItem>
<Button
type={ButtonType.submit}
isLoading={isSubmitting}
data-testid="update-resource"
onClick={(e) => {
e.preventDefault(), handleSubmit();
}}
>
Add Bug
</Button>
</StackItem>
</Stack>
</div>
</Form>
);
};
const bugFormSchema = yup.object({
issueKey: yup.string().required('Required'),
url: yup.string().required('Required'),
});

export const AddBugModal: React.FC<React.PropsWithChildren<AddBugModalProps>> = ({
onClose,
bugArrayHelper,
}) => {
const [isModalOpen, setIsModalOpen] = React.useState(false);
const [isTimePickerOpen, setIsTimePickerOpen] = React.useState(false);
const dateRef = React.useRef(null);

const handleModalToggle = () => {
setIsModalOpen(!isModalOpen);
};

const onEscapePress = (event: KeyboardEvent) => {
if (dateRef && dateRef.current && dateRef.current.isCalendarOpen) {
dateRef.current.toggleCalendar(false, event.key);
} else if (isTimePickerOpen) {
setIsTimePickerOpen(false);
} else {
handleModalToggle();
}
};

const setValues = React.useCallback(
(fields) => {
bugArrayHelper(fields);
Expand All @@ -119,17 +46,26 @@ export const AddBugModal: React.FC<React.PropsWithChildren<AddBugModalProps>> =
);

return (
<Formik
onSubmit={setValues}
initialValues={{ issueKey: '', url: '', summary: '', uploadDate: '' }}
>
<BugFormModal />
</Formik>
<>
<Button variant="primary" onClick={handleModalToggle}>
Add a bug
</Button>
<Modal
id="date-time-picker-modal"
variant={ModalVariant.medium}
title="Add a bug fix"
isOpen={isModalOpen}
onEscapePress={onEscapePress}
onClose={handleModalToggle}
>
<Formik
onSubmit={setValues}
initialValues={{ issueKey: '', url: '', summary: '', uploadDate: '' }}
validationSchema={bugFormSchema}
>
<BugFormContent modalToggle={handleModalToggle} />
</Formik>
</Modal>
</>
);
};

export const createAddBugModal = createModalLauncher(AddBugModal, {
'data-testid': `trigger-release-modal`,
variant: ModalVariant.medium,
title: `Add bug modal`,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.add-bug-section {
&__emptyMsg {
padding: 0;
margin: 0;
padding-top: var(--pf-v5-global--spacer--sm);
width: 100%;
text-align: center;
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import * as React from 'react';
import {
Button,
EmptyState,
EmptyStateBody,
SearchInput,
TextContent,
TextVariants,
Toolbar,
ToolbarContent,
ToolbarGroup,
ToolbarItem,
Text,
} from '@patternfly/react-core';
import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';
import { FieldArray, useField } from 'formik';
import { debounce } from 'lodash-es';
import { useModalLauncher } from '../../../../../components/modal/ModalProvider';
import { useSearchParam } from '../../../../../hooks/useSearchParam';
import ActionMenu from '../../../../../shared/components/action-menu/ActionMenu';
import FilteredEmptyState from '../../../../../shared/components/empty-state/FilteredEmptyState';
import { createAddBugModal } from './AddBugModal';
import { AddBugModal } from './AddBugModal';

import './AddBugSection.scss';

interface AddBugSectionProps {
field: string;
Expand All @@ -26,14 +29,22 @@ export interface BugsObject {
issueKey: string;
summary: string;
url?: string;
last_updated?: string;
uploadDate?: string;
status?: string;
}

export const bugsTableColumnClass = {
issueKey: 'pf-m-width-15 wrap-column',
url: 'pf-m-width-30 pf-m-width-25-on-lg',
summary: 'pf-m-width-20 pf-m-width-20-on-lg pf-m-width-15-on-xl',
uploadDate: 'pf-m-hidden pf-m-visible-on-xl pf-m-width-20',
status: 'pf-m-hidden pf-m-visible-on-xl pf-m-width-15',
kebab: 'pf-v5-c-table__action',
};

const AddBugSection: React.FC<React.PropsWithChildren<AddBugSectionProps>> = ({ field }) => {
const [nameFilter, setNameFilter] = useSearchParam('name', '');
const [{ value: issues }, ,] = useField<BugsObject[]>(field);
const showModal = useModalLauncher();

const [onLoadName, setOnLoadName] = React.useState(nameFilter);
React.useEffect(() => {
Expand All @@ -43,8 +54,12 @@ const AddBugSection: React.FC<React.PropsWithChildren<AddBugSectionProps>> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const filteredBugs = issues?.filter(
(bug) => !nameFilter || bug.issueKey.indexOf(nameFilter) >= 0,
const filteredBugs = React.useMemo(
() =>
issues && Array.isArray(issues)
? issues?.filter((bug) => !nameFilter || bug.issueKey.indexOf(nameFilter) >= 0)
: [],
[issues, nameFilter],
);

const onClearFilters = () => {
Expand All @@ -61,8 +76,8 @@ const AddBugSection: React.FC<React.PropsWithChildren<AddBugSectionProps>> = ({
nameFilter ? (
<FilteredEmptyState onClearFilters={onClearFilters} />
) : (
<EmptyState>
<EmptyStateBody>No Bugs found</EmptyStateBody>
<EmptyState className="pf-v5-u-m-0 pf-v5-u-p-">
<EmptyStateBody className="pf-v5-u-m-0 pf-v5-u-p-0">No Bugs found</EmptyStateBody>
</EmptyState>
);

Expand All @@ -76,6 +91,11 @@ const AddBugSection: React.FC<React.PropsWithChildren<AddBugSectionProps>> = ({

return (
<>
<TextContent className="pf-v5-u-mt-xs">
<Text component={TextVariants.h4} className="pf-v5-u-mt-0 pf-v5-u-pt-0">
Are there any bug fixes you would like to add to this release?
</Text>
</TextContent>
<Toolbar
data-test="pipelinerun-list-toolbar"
clearAllFilters={onClearFilters}
Expand All @@ -95,41 +115,38 @@ const AddBugSection: React.FC<React.PropsWithChildren<AddBugSectionProps>> = ({
/>
</ToolbarItem>
<ToolbarItem>
<Button
onClick={() => showModal(createAddBugModal({ bugArrayHelper: addNewBug }))}
data-test="edit-param-button"
>
Add a Bug
</Button>
<AddBugModal bugArrayHelper={addNewBug} />
</ToolbarItem>
</ToolbarGroup>
</ToolbarContent>
</Toolbar>
<Table
aria-label="Simple table"
variant="compact"
borders
className="pf-v5-u-mt-0 pf-v5-u-pt-0"
>
<Thead>
<Tr>
<Th>Bug issue key</Th>
<Th>URL</Th>
<Th>Summary</Th>
<Th>Last updated</Th>
<Th>Status</Th>
</Tr>
</Thead>
<Tbody>
{Array.isArray(filteredBugs) && filteredBugs.length > 0
? filteredBugs.map((bug, i) => (
<div className="pf-v5-u-mb-md">
<Table
aria-label="Simple table"
variant="compact"
borders
className="pf-v5-u-m-0 pf-v5-u-p-0"
>
<Thead>
<Tr>
<Th className={bugsTableColumnClass.issueKey}>Bug issue key</Th>
<Th className={bugsTableColumnClass.url}>URL</Th>
<Th className={bugsTableColumnClass.summary}>Summary</Th>
<Th className={bugsTableColumnClass.uploadDate}>Last updated</Th>
<Th className={bugsTableColumnClass.status}>Status</Th>
</Tr>
</Thead>

{Array.isArray(filteredBugs) && filteredBugs.length > 0 && (
<Tbody>
{filteredBugs.map((bug, i) => (
<Tr key={bug.issueKey}>
<Td>{bug.issueKey}</Td>
<Td>{bug.url}</Td>
<Td>{bug.summary}</Td>
<Td>{bug.last_updated}</Td>
<Td>{bug.status}</Td>
<Td>
<Td className={bugsTableColumnClass.issueKey}>{bug.issueKey}</Td>
<Td className={bugsTableColumnClass.url}>{bug.url}</Td>
<Td className={bugsTableColumnClass.summary}>{bug.summary}</Td>
<Td className={bugsTableColumnClass.uploadDate}>{bug.uploadDate}</Td>
<Td className={bugsTableColumnClass.status}>{bug.status}</Td>
<Td className={bugsTableColumnClass.kebab}>
<ActionMenu
actions={[
{
Expand All @@ -141,10 +158,15 @@ const AddBugSection: React.FC<React.PropsWithChildren<AddBugSectionProps>> = ({
/>
</Td>
</Tr>
))
: EmptyMsg()}
</Tbody>
</Table>
))}
</Tbody>
)}
</Table>
</div>
{!filteredBugs ||
(filteredBugs?.length === 0 && (
<div className="add-bug-section__emptyMsg">{EmptyMsg()}</div>
))}
</>
);
}}
Expand Down
Loading

0 comments on commit 886e304

Please sign in to comment.