From da3f2d246990475dd99c90a027a5b91b3b12b792 Mon Sep 17 00:00:00 2001 From: MilanPospisil Date: Tue, 21 Feb 2023 15:26:54 +0100 Subject: [PATCH] Refactor components to functional from start to namespace form2 (#3224) * Collection filter No-Issue * Prettier * Collection list-item * collection list * confirm modal, date component, delete collection modal * delete execution environment modal * delete modal && empty state folder * Apply rebase changes --- .../collection-list/collection-filter.tsx | 136 ++++++------- .../collection-list/collection-list-item.tsx | 184 +++++++++--------- .../collection-list/collection-list.tsx | 90 ++++----- .../confirm-modal/confirm-modal.tsx | 74 ++++--- .../date-component/date-component.tsx | 22 +-- .../delete-modal/delete-collection-modal.tsx | 127 ++++++------ .../delete-execution-environment-modal.tsx | 150 +++++++------- src/components/delete-modal/delete-modal.tsx | 84 ++++---- .../empty-state/empty-state-custom.tsx | 41 ++-- .../empty-state/empty-state-filter.tsx | 34 ++-- .../empty-state/empty-state-no-data.tsx | 22 +-- .../empty-state/empty-state-unauthorized.tsx | 34 ++-- 12 files changed, 472 insertions(+), 526 deletions(-) diff --git a/src/components/collection-list/collection-filter.tsx b/src/components/collection-list/collection-filter.tsx index 1bfab5d695..095eb4a108 100644 --- a/src/components/collection-list/collection-filter.tsx +++ b/src/components/collection-list/collection-filter.tsx @@ -6,9 +6,10 @@ import { ToolbarItem, } from '@patternfly/react-core'; import * as React from 'react'; +import { useEffect, useState } from 'react'; import { AppliedFilters, CompoundFilter } from 'src/components'; import { Constants } from 'src/constants'; -import { AppContext } from 'src/loaders/app-context'; +import { useContext } from 'src/loaders/app-context'; import './collection-filter.scss'; interface IProps { @@ -23,86 +24,71 @@ interface IProps { updateParams: (p) => void; } -interface IState { - inputText: string; -} - -export class CollectionFilter extends React.Component { - static contextType = AppContext; - - constructor(props) { - super(props); +export const CollectionFilter = (props: IProps) => { + const context = useContext(); + const [inputText, setInputText] = useState(props.params.keywords || ''); - this.state = { - inputText: props.params.keywords || '', - }; - } + useEffect(() => { + setInputText(props.params['keywords'] || ''); + }, [props.params.keywords]); - componentDidUpdate(prevProps) { - if (prevProps.params.keywords !== this.props.params['keywords']) { - this.setState({ inputText: this.props.params['keywords'] || '' }); - } - } + const { ignoredParams, params, updateParams } = props; + const { display_signatures } = context.featureFlags; + const display_tags = ignoredParams.includes('tags') === false; - render() { - const { ignoredParams, params, updateParams } = this.props; - const { display_signatures } = this.context.featureFlags; - const display_tags = ignoredParams.includes('tags') === false; + const filterConfig = [ + { + id: 'keywords', + title: t`Keywords`, + }, + display_tags && { + id: 'tags', + title: t`Tag`, + inputType: 'multiple' as const, + options: Constants.COLLECTION_FILTER_TAGS.map((tag) => ({ + id: tag, + title: tag, + })), + }, + display_signatures && { + id: 'sign_state', + title: t`Sign state`, + inputType: 'select' as const, + options: [ + { id: 'signed', title: t`Signed` }, + { id: 'unsigned', title: t`Unsigned` }, + ], + }, + ].filter(Boolean); - const filterConfig = [ - { - id: 'keywords', - title: t`Keywords`, - }, - display_tags && { - id: 'tags', - title: t`Tag`, - inputType: 'multiple' as const, - options: Constants.COLLECTION_FILTER_TAGS.map((tag) => ({ - id: tag, - title: tag, - })), - }, - display_signatures && { - id: 'sign_state', - title: t`Sign state`, - inputType: 'select' as const, - options: [ - { id: 'signed', title: t`Signed` }, - { id: 'unsigned', title: t`Unsigned` }, - ], - }, - ].filter(Boolean); - - return ( - - - + return ( + + + + + setInputText(text)} + updateParams={updateParams} + params={params} + filterConfig={filterConfig} + /> - this.setState({ inputText: text })} + - - - - - - - ); - } -} + + + + + ); +}; diff --git a/src/components/collection-list/collection-list-item.tsx b/src/components/collection-list/collection-list-item.tsx index 2b38bc2c06..8693994963 100644 --- a/src/components/collection-list/collection-list-item.tsx +++ b/src/components/collection-list/collection-list-item.tsx @@ -31,105 +31,103 @@ interface IProps extends CollectionListType { repo?: string; } -export class CollectionListItem extends React.Component { - render() { - const { - name, - latest_version, - namespace, - showNamespace, - controls, - deprecated, - displaySignatures, - repo, - sign_state, - } = this.props; +export const CollectionListItem = (props: IProps) => { + const { + name, + latest_version, + namespace, + showNamespace, + controls, + deprecated, + displaySignatures, + repo, + sign_state, + } = props; - const cells = []; + const cells = []; - const company = namespace.company || namespace.name; - - if (showNamespace) { - cells.push( - - - , - ); - } - - const contentSummary = convertContentSummaryCounts(latest_version.metadata); + const company = namespace.company || namespace.name; + if (showNamespace) { cells.push( - -
- - {name} - - {deprecated && } - {showNamespace ? ( - - - Provided by {company} - - - ) : null} -
-
{latest_version.metadata.description}
-
- {Object.keys(contentSummary.contents).map((type) => ( -
- -
- ))} -
-
- - {latest_version.metadata.tags.map((tag, index) => ( - {tag} - ))} - -
+ + , ); + } - cells.push( - - {controls ?
{controls}
: null} -
- - Updated - -
-
v{latest_version.version}
- {displaySignatures ? ( - + const contentSummary = convertContentSummaryCounts(latest_version.metadata); + + cells.push( + +
+ + {name} + + {deprecated && } + {showNamespace ? ( + + + Provided by {company} + + ) : null} - , - ); +
+
{latest_version.metadata.description}
+
+ {Object.keys(contentSummary.contents).map((type) => ( +
+ +
+ ))} +
+
+ + {latest_version.metadata.tags.map((tag, index) => ( + {tag} + ))} + +
+
, + ); - return ( - - - - - - ); - } -} + cells.push( + + {controls ?
{controls}
: null} +
+ + Updated + +
+
v{latest_version.version}
+ {displaySignatures ? ( + + ) : null} +
, + ); + + return ( + + + + + + ); +}; diff --git a/src/components/collection-list/collection-list.tsx b/src/components/collection-list/collection-list.tsx index 9786565957..616b929d12 100644 --- a/src/components/collection-list/collection-list.tsx +++ b/src/components/collection-list/collection-list.tsx @@ -27,52 +27,48 @@ interface IProps { } // only used in namespace detail, collections uses individual items -export class CollectionList extends React.Component { - render() { - const { - collections, - displaySignatures, - params, - updateParams, - ignoredParams, - itemCount, - showControls, - repo, - } = this.props; +export const CollectionList = (props: IProps) => { + const { + collections, + displaySignatures, + params, + updateParams, + ignoredParams, + itemCount, + showControls, + repo, + } = props; - return ( - - - {collections.length > 0 ? ( - collections.map((c) => ( - - )) - ) : ( - { - ParamHelper.clearAllFilters({ - params, - ignoredParams, - updateParams, - }); - }} + return ( + + + {collections.length > 0 ? ( + collections.map((c) => ( + - )} - - updateParams(p)} - count={itemCount} - /> - - ); - } -} + )) + ) : ( + { + ParamHelper.clearAllFilters({ + params, + ignoredParams, + updateParams, + }); + }} + /> + )} + + updateParams(p)} + count={itemCount} + /> + + ); +}; diff --git a/src/components/confirm-modal/confirm-modal.tsx b/src/components/confirm-modal/confirm-modal.tsx index dfb3b49f80..af71b9dd6d 100644 --- a/src/components/confirm-modal/confirm-modal.tsx +++ b/src/components/confirm-modal/confirm-modal.tsx @@ -12,42 +12,40 @@ interface IProps { confirmButtonTitle?: string; } -export class ConfirmModal extends React.Component { - render() { - const { - cancelAction, - children, - confirmAction, - isDisabled, - title, - spinner, - confirmButtonTitle, - } = this.props; +export const ConfirmModal = (props: IProps) => { + const { + cancelAction, + children, + confirmAction, + isDisabled, + title, + spinner, + confirmButtonTitle, + } = props; - return ( - - {confirmButtonTitle ? confirmButtonTitle : t`Yes`} - {spinner && } - , - , - ]} - isOpen={true} - onClose={cancelAction} - title={title} - titleIconVariant='warning' - variant='small' - > - {children} - - ); - } -} + return ( + + {confirmButtonTitle ? confirmButtonTitle : t`Yes`} + {spinner && } + , + , + ]} + isOpen={true} + onClose={cancelAction} + title={title} + titleIconVariant='warning' + variant='small' + > + {children} + + ); +}; diff --git a/src/components/date-component/date-component.tsx b/src/components/date-component/date-component.tsx index 9d1b5e39a4..6e44295eea 100644 --- a/src/components/date-component/date-component.tsx +++ b/src/components/date-component/date-component.tsx @@ -6,16 +6,14 @@ interface IProps { date: string; } -export class DateComponent extends React.Component { - render() { - const { date } = this.props; +export const DateComponent = (props: IProps) => { + const { date } = props; - return ( - date && ( - - {moment(date).fromNow()} - - ) - ); - } -} + return ( + date && ( + + {moment(date).fromNow()} + + ) + ); +}; diff --git a/src/components/delete-modal/delete-collection-modal.tsx b/src/components/delete-modal/delete-collection-modal.tsx index 87cfff0e0b..224b098a73 100644 --- a/src/components/delete-modal/delete-collection-modal.tsx +++ b/src/components/delete-modal/delete-collection-modal.tsx @@ -14,69 +14,66 @@ interface IProps { setConfirmDelete: (val) => void; } -export class DeleteCollectionModal extends React.Component { - render() { - const { - deleteCollection, - isDeletionPending, - confirmDelete, - collectionVersion, - cancelAction, - deleteAction, - setConfirmDelete, - } = this.props; +export const DeleteCollectionModal = (props: IProps) => { + const { + deleteCollection, + isDeletionPending, + confirmDelete, + collectionVersion, + cancelAction, + deleteAction, + setConfirmDelete, + } = props; - return ( - deleteCollection && ( - cancelAction()} - deleteAction={() => deleteAction()} - isDisabled={!confirmDelete || isDeletionPending} - title={ - collectionVersion - ? t`Delete collection version?` - : t`Delete collection?` - } - > - - {collectionVersion ? ( - <> - {(deleteCollection as CollectionDetailType).all_versions - .length === 1 ? ( - - Deleting{' '} - - {deleteCollection.name} v{collectionVersion} - {' '} - and its data will be lost and this will cause the entire - collection to be deleted. - - ) : ( - - Deleting{' '} - - {deleteCollection.name} v{collectionVersion} - {' '} - and its data will be lost. - - )} - - ) : ( - - Deleting {deleteCollection.name} and its data will be - lost. - - )} - - - - ) - ); - } -} + return ( + deleteCollection && ( + cancelAction()} + deleteAction={() => deleteAction()} + isDisabled={!confirmDelete || isDeletionPending} + title={ + collectionVersion + ? t`Delete collection version?` + : t`Delete collection?` + } + > + + {collectionVersion ? ( + <> + {(deleteCollection as CollectionDetailType).all_versions + .length === 1 ? ( + + Deleting{' '} + + {deleteCollection.name} v{collectionVersion} + {' '} + and its data will be lost and this will cause the entire + collection to be deleted. + + ) : ( + + Deleting{' '} + + {deleteCollection.name} v{collectionVersion} + {' '} + and its data will be lost. + + )} + + ) : ( + + Deleting {deleteCollection.name} and its data will be lost. + + )} + + + + ) + ); +}; diff --git a/src/components/delete-modal/delete-execution-environment-modal.tsx b/src/components/delete-modal/delete-execution-environment-modal.tsx index c41c3a5542..ad7b629452 100644 --- a/src/components/delete-modal/delete-execution-environment-modal.tsx +++ b/src/components/delete-modal/delete-execution-environment-modal.tsx @@ -1,16 +1,11 @@ import { Trans, t } from '@lingui/macro'; import { Checkbox, Text } from '@patternfly/react-core'; -import * as React from 'react'; +import React, { useState } from 'react'; import { ExecutionEnvironmentAPI } from 'src/api'; import { DeleteModal } from 'src/components/delete-modal/delete-modal'; import { waitForTask } from 'src/utilities'; import { errorMessage } from 'src/utilities'; -interface IState { - confirmDelete: boolean; - isDeletionPending: boolean; -} - interface IProps { closeAction: () => void; selectedItem: string; @@ -18,81 +13,78 @@ interface IProps { afterDelete: () => void; } -export class DeleteExecutionEnvironmentModal extends React.Component< - IProps, - IState -> { - constructor(props) { - super(props); +export const DeleteExecutionEnvironmentModal = (props: IProps) => { + const [confirmDelete, setConfirmDelete] = useState(false); + const [isDeletionPending, setIsDeletionPending] = useState(false); - this.state = { - confirmDelete: false, - isDeletionPending: false, - }; - } + const { selectedItem, closeAction } = props; - render() { - const { selectedItem, closeAction } = this.props; - const { isDeletionPending, confirmDelete } = this.state; + return ( + closeAction()} + deleteAction={() => + deleteContainer( + selectedItem, + props, + setConfirmDelete, + setIsDeletionPending, + ) + } + isDisabled={!confirmDelete || isDeletionPending} + > + + + Deleting {selectedItem} and its data will be lost. + + + setConfirmDelete(value)} + label={t`I understand that this action cannot be undone.`} + id='delete_confirm' + /> + + ); +}; - return ( - closeAction()} - deleteAction={() => this.deleteContainer(selectedItem)} - isDisabled={!confirmDelete || isDeletionPending} - > - - - Deleting {selectedItem} and its data will be lost. - - - this.setState({ confirmDelete: value })} - label={t`I understand that this action cannot be undone.`} - id='delete_confirm' - /> - - ); - } +function deleteContainer( + selectedItem: string, + props, + setConfirmDelete, + setIsDeletionPending, +) { + const { addAlert, closeAction, afterDelete } = props; - deleteContainer(selectedItem: string) { - const { addAlert, closeAction, afterDelete } = this.props; - this.setState({ isDeletionPending: true }, () => - ExecutionEnvironmentAPI.deleteExecutionEnvironment(selectedItem) - .then((result) => { - const taskId = result.data.task.split('tasks/')[1].replace('/', ''); - waitForTask(taskId).then(() => { - this.setState({ - confirmDelete: false, - isDeletionPending: false, - }); - closeAction(); - addAlert( - - Execution environment "{selectedItem}" has been - successfully deleted. - , - 'success', - ); - afterDelete(); - }); - }) - .catch((e) => { - const { status, statusText } = e.response; - this.setState({ - confirmDelete: false, - isDeletionPending: false, - }); - addAlert( - t`Execution environment "${selectedItem}" could not be deleted.`, - 'danger', - errorMessage(status, statusText), - ); - closeAction(); - }), - ); - } + setIsDeletionPending(true); + + ExecutionEnvironmentAPI.deleteExecutionEnvironment(selectedItem) + .then((result) => { + const taskId = result.data.task.split('tasks/')[1].replace('/', ''); + waitForTask(taskId).then(() => { + setConfirmDelete(false); + setIsDeletionPending(false); + closeAction(); + addAlert( + + Execution environment "{selectedItem}" has been + successfully deleted. + , + 'success', + ); + afterDelete(); + }); + }) + .catch((e) => { + const { status, statusText } = e.response; + setConfirmDelete(false); + setIsDeletionPending(false); + addAlert( + t`Execution environment "${selectedItem}" could not be deleted.`, + 'danger', + errorMessage(status, statusText), + ); + closeAction(); + }); } diff --git a/src/components/delete-modal/delete-modal.tsx b/src/components/delete-modal/delete-modal.tsx index fab2f02d41..2c618c23e4 100644 --- a/src/components/delete-modal/delete-modal.tsx +++ b/src/components/delete-modal/delete-modal.tsx @@ -13,49 +13,41 @@ export interface IProps { variant?: ModalProps['variant']; } -export class DeleteModal extends React.Component { - static defaultProps = { - variant: 'small', - }; - - render() { - const { - cancelAction, - children, - deleteAction, - isDisabled, - title, - spinner, - variant, - } = this.props; - - return ( - - - , - , - ]} - isOpen={true} - onClose={cancelAction} - title={title} - titleIconVariant='warning' - variant={variant} - data-cy='modal_checkbox' - > - {children} - - ); - } -} +export const DeleteModal = ({ + cancelAction, + children, + deleteAction, + isDisabled, + title, + spinner, + variant = 'small', +}: IProps) => { + return ( + + + , + , + ]} + isOpen={true} + onClose={cancelAction} + title={title} + titleIconVariant='warning' + variant={variant} + data-cy='modal_checkbox' + > + {children} + + ); +}; diff --git a/src/components/empty-state/empty-state-custom.tsx b/src/components/empty-state/empty-state-custom.tsx index ffd8d8b860..9d1897ce7f 100644 --- a/src/components/empty-state/empty-state-custom.tsx +++ b/src/components/empty-state/empty-state-custom.tsx @@ -18,26 +18,21 @@ interface IProps { variant?: 'xs' | 'small' | 'large' | 'xl' | 'full'; } -export class EmptyStateCustom extends React.Component { - static defaultProps = { - variant: 'small', - }; - - render() { - return ( - - - - {this.props.title} - - {this.props.description} - {this.props.button && ( - {this.props.button} - )} - - ); - } -} +export const EmptyStateCustom = ({ + icon, + title, + description, + button, + variant = 'small', +}: IProps) => { + return ( + + + + {title} + + {description} + {button && {button}} + + ); +}; diff --git a/src/components/empty-state/empty-state-filter.tsx b/src/components/empty-state/empty-state-filter.tsx index 8eeb98f301..e5438444e3 100644 --- a/src/components/empty-state/empty-state-filter.tsx +++ b/src/components/empty-state/empty-state-filter.tsx @@ -8,21 +8,19 @@ interface IProps { clearAllFilters?: () => void; } -export class EmptyStateFilter extends React.Component { - render() { - return ( - - {t`Clear all filters`} - - ) : null - } - /> - ); - } -} +export const EmptyStateFilter = (props: IProps) => { + return ( + + {t`Clear all filters`} + + ) : null + } + /> + ); +}; diff --git a/src/components/empty-state/empty-state-no-data.tsx b/src/components/empty-state/empty-state-no-data.tsx index 6362380738..7aa58bfa92 100644 --- a/src/components/empty-state/empty-state-no-data.tsx +++ b/src/components/empty-state/empty-state-no-data.tsx @@ -9,15 +9,13 @@ interface IProps { description: ReactNode; } -export class EmptyStateNoData extends React.Component { - render() { - return ( - - ); - } -} +export const EmptyStateNoData = (props: IProps) => { + return ( + + ); +}; diff --git a/src/components/empty-state/empty-state-unauthorized.tsx b/src/components/empty-state/empty-state-unauthorized.tsx index 93fd1a97b7..d9a7617c55 100644 --- a/src/components/empty-state/empty-state-unauthorized.tsx +++ b/src/components/empty-state/empty-state-unauthorized.tsx @@ -4,21 +4,19 @@ import * as React from 'react'; import { LoginLink } from 'src/components'; import { EmptyStateCustom } from './empty-state-custom'; -export class EmptyStateUnauthorized extends React.Component { - render() { - return ( - - {t`Contact your organization administrator for more information.`} -
-
- - - } - /> - ); - } -} +export const EmptyStateUnauthorized = () => { + return ( + + {t`Contact your organization administrator for more information.`} +
+
+ + + } + /> + ); +};