Consolidate logic to show No Result (#223)

* Add no result search view into repo listing view

* Consolidate logic to show No Result
This commit is contained in:
Tan Nhu 2023-01-17 16:11:39 -08:00 committed by GitHub
parent 1aa1123bd2
commit eed7b2c29b
13 changed files with 121 additions and 89 deletions

View File

@ -0,0 +1,5 @@
.main {
> div {
height: calc(100vh - var(--page-header-height, 64px) - 120px) !important;
}
}

View File

@ -0,0 +1,6 @@
/* eslint-disable */
// this is an auto-generated file
declare const styles: {
readonly main: string
}
export default styles

View File

@ -0,0 +1,51 @@
import React from 'react'
import { Button, Container, ButtonVariation, NoDataCard, IconName } from '@harness/uicore'
import { noop } from 'lodash-es'
import { CodeIcon } from 'utils/GitUtils'
import { useStrings } from 'framework/strings'
import emptyStateImage from 'images/empty-state.svg'
import css from './NoResultCard.module.scss'
interface NoResultCardProps {
showWhen: () => boolean
forSearch: boolean
message?: string
buttonText?: string
buttonIcon?: IconName
onButtonClick?: () => void
}
export const NoResultCard: React.FC<NoResultCardProps> = ({
showWhen,
forSearch,
message,
buttonText = '',
buttonIcon = CodeIcon.Add,
onButtonClick = noop
}) => {
const { getString } = useStrings()
if (!showWhen()) {
return null
}
return (
<Container className={css.main}>
<NoDataCard
image={emptyStateImage}
messageTitle={forSearch ? getString('noResultTitle') : undefined}
message={forSearch ? getString('noResultMessage') : message || getString('noResultMessage')}
button={
forSearch ? undefined : (
<Button
variation={ButtonVariation.PRIMARY}
text={buttonText}
icon={buttonIcon as IconName}
onClick={onButtonClick}
/>
)
}
/>
</Container>
)
}

View File

@ -117,6 +117,8 @@ export interface StringsMap {
newRepo: string newRepo: string
next: string next: string
noAccount: string noAccount: string
noResultMessage: string
noResultTitle: string
noWebHooks: string noWebHooks: string
none: string none: string
off: string off: string

View File

@ -60,6 +60,8 @@ searchBranches: Search branches
updated: Updated updated: Updated
cloneHTTPS: Clone with HTTPS cloneHTTPS: Clone with HTTPS
nameYourFile: Name your file... nameYourFile: Name your file...
noResultTitle: Sorry, no result found
noResultMessage: What you searched was unfortunately not found or doesnt exist
repos: repos:
name: Repo Name name: Repo Name
data: Repo Data data: Repo Data

View File

@ -18,10 +18,6 @@
align-items: center; align-items: center;
} }
} }
.noData > div {
height: calc(100vh - var(--page-header-height, 64px) - 120px) !important;
}
} }
.rowImg { .rowImg {

View File

@ -6,7 +6,6 @@ declare const styles: {
readonly row: string readonly row: string
readonly title: string readonly title: string
readonly titleRow: string readonly titleRow: string
readonly noData: string
readonly rowImg: string readonly rowImg: string
readonly open: string readonly open: string
readonly merged: string readonly merged: string

View File

@ -1,31 +1,20 @@
import React, { useMemo, useState } from 'react' import React, { useMemo, useState } from 'react'
import { import { Container, PageBody, Text, Color, TableV2, Layout, StringSubstitute } from '@harness/uicore'
Button,
Container,
ButtonVariation,
PageBody,
Text,
Color,
TableV2,
Layout,
StringSubstitute,
NoDataCard
} from '@harness/uicore'
import cx from 'classnames' import cx from 'classnames'
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
import { useGet } from 'restful-react' import { useGet } from 'restful-react'
import type { CellProps, Column } from 'react-table' import type { CellProps, Column } from 'react-table'
import ReactTimeago from 'react-timeago' import ReactTimeago from 'react-timeago'
import { CodeIcon, makeDiffRefs, PullRequestFilterOption } from 'utils/GitUtils' import { makeDiffRefs, PullRequestFilterOption } from 'utils/GitUtils'
import { useAppContext } from 'AppContext' import { useAppContext } from 'AppContext'
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
import { useStrings } from 'framework/strings' import { useStrings } from 'framework/strings'
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
import { voidFn, getErrorMessage, LIST_FETCHING_LIMIT } from 'utils/Utils' import { voidFn, getErrorMessage, LIST_FETCHING_LIMIT } from 'utils/Utils'
import emptyStateImage from 'images/empty-state.svg'
import { usePageIndex } from 'hooks/usePageIndex' import { usePageIndex } from 'hooks/usePageIndex'
import type { TypesPullReq } from 'services/code' import type { TypesPullReq } from 'services/code'
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination' import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
import { PullRequestsContentHeader } from './PullRequestsContentHeader/PullRequestsContentHeader' import { PullRequestsContentHeader } from './PullRequestsContentHeader/PullRequestsContentHeader'
import prImgOpen from './pull-request-open.svg' import prImgOpen from './pull-request-open.svg'
import prImgMerged from './pull-request-merged.svg' import prImgMerged from './pull-request-merged.svg'
@ -143,29 +132,20 @@ export default function PullRequests() {
<ResourceListingPagination response={response} page={page} setPage={setPage} /> <ResourceListingPagination response={response} page={page} setPage={setPage} />
</> </>
)} )}
{data?.length === 0 && ( <NoResultCard
<Container className={css.noData}> showWhen={() => data?.length === 0}
<NoDataCard forSearch={!!searchTerm}
image={emptyStateImage} message={getString('pullRequestEmpty')}
message={getString('pullRequestEmpty')} buttonText={getString('newPullRequest')}
button={ onButtonClick={() =>
<Button history.push(
variation={ButtonVariation.PRIMARY} routes.toCODECompare({
text={getString('newPullRequest')} repoPath: repoMetadata?.path as string,
icon={CodeIcon.Add} diffRefs: makeDiffRefs(repoMetadata?.default_branch as string, '')
onClick={() => { })
history.push( )
routes.toCODECompare({ }
repoPath: repoMetadata?.path as string, />
diffRefs: makeDiffRefs(repoMetadata?.default_branch as string, '')
})
)
}}
/>
}
/>
</Container>
)}
</Container> </Container>
</Layout.Vertical> </Layout.Vertical>
)} )}

View File

@ -24,6 +24,7 @@ import { usePageIndex } from 'hooks/usePageIndex'
import { useGetSpaceParam } from 'hooks/useGetSpaceParam' import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
import { SearchInputWithSpinner } from 'components/SearchInputWithSpinner/SearchInputWithSpinner' import { SearchInputWithSpinner } from 'components/SearchInputWithSpinner/SearchInputWithSpinner'
import { useAppContext } from 'AppContext' import { useAppContext } from 'AppContext'
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination' import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
import emptyStateImage from './empty-state.svg' import emptyStateImage from './empty-state.svg'
import css from './RepositoriesListing.module.scss' import css from './RepositoriesListing.module.scss'
@ -141,14 +142,19 @@ export default function RepositoriesListing() {
<SearchInputWithSpinner loading={loading} query={searchTerm} setQuery={setSearchTerm} /> <SearchInputWithSpinner loading={loading} query={searchTerm} setQuery={setSearchTerm} />
</Layout.Horizontal> </Layout.Horizontal>
<Container margin={{ top: 'medium' }}> <Container margin={{ top: 'medium' }}>
<Table<TypesRepository> {!!repositories?.length && (
className={css.table} <Table<TypesRepository>
columns={columns} className={css.table}
data={repositories || []} columns={columns}
onRowClick={repoInfo => { data={repositories || []}
history.push(routes.toCODERepository({ repoPath: repoInfo.path as string })) onRowClick={repoInfo => history.push(routes.toCODERepository({ repoPath: repoInfo.path as string }))}
}} getRowClassName={row => cx(css.row, !row.original.description && css.noDesc)}
getRowClassName={row => cx(css.row, !row.original.description && css.noDesc)} />
)}
<NoResultCard
showWhen={() => !!repositories && repositories.length === 0 && !!searchTerm?.length}
forSearch={true}
/> />
</Container> </Container>
<ResourceListingPagination response={response} page={page} setPage={setPage} /> <ResourceListingPagination response={response} page={page} setPage={setPage} />

View File

@ -1,3 +1,7 @@
.resourceContent { .resourceContent {
background-color: var(--primary-bg); background-color: var(--primary-bg);
.noData > div {
height: calc(100vh - var(--page-header-height, 64px) - 120px) !important;
}
} }

View File

@ -2,5 +2,6 @@
// this is an auto-generated file // this is an auto-generated file
declare const styles: { declare const styles: {
readonly resourceContent: string readonly resourceContent: string
readonly noData: string
} }
export default styles export default styles

View File

@ -9,6 +9,7 @@ import { useAppContext } from 'AppContext'
import type { GitInfoProps } from 'utils/GitUtils' import type { GitInfoProps } from 'utils/GitUtils'
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination' import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
import { useShowRequestError } from 'hooks/useShowRequestError' import { useShowRequestError } from 'hooks/useShowRequestError'
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
import { BranchesContentHeader } from './BranchesContentHeader/BranchesContentHeader' import { BranchesContentHeader } from './BranchesContentHeader/BranchesContentHeader'
import { BranchesContent } from './BranchesContent/BranchesContent' import { BranchesContent } from './BranchesContent/BranchesContent'
import css from './RepositoryBranchesContent.module.scss' import css from './RepositoryBranchesContent.module.scss'
@ -68,6 +69,8 @@ export function RepositoryBranchesContent({ repoMetadata }: Pick<GitInfoProps, '
/> />
)} )}
<NoResultCard showWhen={() => !!branches && branches.length === 0 && !!searchTerm?.length} forSearch={true} />
<ResourceListingPagination response={response} page={page} setPage={setPage} /> <ResourceListingPagination response={response} page={page} setPage={setPage} />
</Container> </Container>
) )

View File

@ -1,33 +1,18 @@
import React, { useMemo, useState } from 'react' import React, { useMemo, useState } from 'react'
import { import { Container, PageBody, Text, Color, TableV2, Layout, Icon, Utils, useToaster, IconName } from '@harness/uicore'
Button,
Container,
ButtonVariation,
PageBody,
Text,
Color,
TableV2,
Layout,
Icon,
Utils,
useToaster,
IconName,
NoDataCard
} from '@harness/uicore'
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
import { useGet, useMutate } from 'restful-react' import { useGet, useMutate } from 'restful-react'
import type { CellProps, Column } from 'react-table' import type { CellProps, Column } from 'react-table'
import { CodeIcon } from 'utils/GitUtils'
import { useAppContext } from 'AppContext' import { useAppContext } from 'AppContext'
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
import { useStrings } from 'framework/strings' import { useStrings } from 'framework/strings'
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader' import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
import { voidFn, getErrorMessage, LIST_FETCHING_LIMIT } from 'utils/Utils' import { voidFn, getErrorMessage, LIST_FETCHING_LIMIT } from 'utils/Utils'
import emptyStateImage from 'images/empty-state.svg'
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton' import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
import { useConfirmAct } from 'hooks/useConfirmAction' import { useConfirmAct } from 'hooks/useConfirmAction'
import { usePageIndex } from 'hooks/usePageIndex' import { usePageIndex } from 'hooks/usePageIndex'
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination' import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
import type { OpenapiWebhookType } from 'services/code' import type { OpenapiWebhookType } from 'services/code'
import { WebhooksHeader } from './WebhooksHeader/WebhooksHeader' import { WebhooksHeader } from './WebhooksHeader/WebhooksHeader'
import css from './Webhooks.module.scss' import css from './Webhooks.module.scss'
@ -176,28 +161,20 @@ export default function Webhooks() {
<ResourceListingPagination response={response} page={page} setPage={setPage} /> <ResourceListingPagination response={response} page={page} setPage={setPage} />
</> </>
)} )}
{webhooks?.length === 0 && (
<Container className={css.noData}> <NoResultCard
<NoDataCard showWhen={() => webhooks?.length === 0}
image={emptyStateImage} forSearch={!!searchTerm}
message={getString('webhookEmpty')} message={getString('webhookEmpty')}
button={ buttonText={getString('createWebhook')}
<Button onButtonClick={() =>
variation={ButtonVariation.PRIMARY} history.push(
text={getString('createWebhook')} routes.toCODEWebhookNew({
icon={CodeIcon.Add} repoPath: repoMetadata?.path as string
onClick={() => { })
history.push( )
routes.toCODEWebhookNew({ }
repoPath: repoMetadata?.path as string />
})
)
}}
/>
}
/>
</Container>
)}
</Container> </Container>
</Layout.Vertical> </Layout.Vertical>
)} )}