mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-19 01:17:18 +02:00

202 lines
7.0 KiB
TypeScript
202 lines
7.0 KiB
TypeScript
import { useMemo } from 'react';
|
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
import { Search } from 'component/common/Search/Search';
|
|
import { Box, useMediaQuery } from '@mui/material';
|
|
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
|
import { PaginatedTable, TablePlaceholder } from 'component/common/Table';
|
|
import theme from 'themes/theme';
|
|
import {
|
|
encodeQueryParams,
|
|
NumberParam,
|
|
StringParam,
|
|
withDefault,
|
|
} from 'use-query-params';
|
|
import { usePersistentTableState } from 'hooks/usePersistentTableState';
|
|
import useLoading from 'hooks/useLoading';
|
|
import { createColumnHelper, useReactTable } from '@tanstack/react-table';
|
|
import { withTableState } from 'utils/withTableState';
|
|
import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell';
|
|
import { ProjectApplicationSchema } from 'openapi';
|
|
import mapValues from 'lodash.mapvalues';
|
|
import {
|
|
DEFAULT_PAGE_LIMIT,
|
|
useProjectApplications,
|
|
} from 'hooks/api/getters/useProjectApplications/useProjectApplications';
|
|
import { StringArrayCell } from 'component/common/Table/cells/StringArrayCell';
|
|
import { SdkCell } from './SdkCell';
|
|
|
|
const columnHelper = createColumnHelper<ProjectApplicationSchema>();
|
|
|
|
export const ProjectApplications = () => {
|
|
const projectId = useRequiredPathParam('projectId');
|
|
|
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
|
|
|
const stateConfig = {
|
|
offset: withDefault(NumberParam, 0),
|
|
limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT),
|
|
query: StringParam,
|
|
sortBy: withDefault(StringParam, 'createdAt'),
|
|
sortOrder: withDefault(StringParam, 'desc'),
|
|
};
|
|
const [tableState, setTableState] = usePersistentTableState(
|
|
`project-applications-table-${projectId}`,
|
|
stateConfig,
|
|
);
|
|
|
|
const {
|
|
applications = [],
|
|
total,
|
|
loading,
|
|
} = useProjectApplications(
|
|
mapValues(encodeQueryParams(stateConfig, tableState), (value) =>
|
|
value ? `${value}` : undefined,
|
|
),
|
|
projectId,
|
|
);
|
|
|
|
const setSearchValue = (query = '') => {
|
|
setTableState({ query });
|
|
};
|
|
|
|
const bodyLoadingRef = useLoading(loading);
|
|
|
|
const { offset, limit, query, sortBy, sortOrder, ...filterState } =
|
|
tableState;
|
|
|
|
const columns = useMemo(
|
|
() => [
|
|
columnHelper.accessor('name', {
|
|
header: 'Name',
|
|
cell: ({ row }) => (
|
|
<LinkCell
|
|
title={row.original.name}
|
|
to={`/applications/${row.original.name}`}
|
|
/>
|
|
),
|
|
meta: {
|
|
width: '25%',
|
|
},
|
|
}),
|
|
columnHelper.accessor('environments', {
|
|
header: 'Environments',
|
|
cell: ({ row }) => (
|
|
<StringArrayCell
|
|
row={row.original}
|
|
field={'environments'}
|
|
singularLabel={'environment'}
|
|
/>
|
|
),
|
|
enableSorting: false,
|
|
meta: {
|
|
width: '25%',
|
|
},
|
|
}),
|
|
columnHelper.accessor('instances', {
|
|
header: 'Instances',
|
|
cell: ({ row }) => (
|
|
<StringArrayCell
|
|
row={row.original}
|
|
field={'instances'}
|
|
singularLabel={'instance'}
|
|
/>
|
|
),
|
|
enableSorting: false,
|
|
meta: {
|
|
width: '25%',
|
|
},
|
|
}),
|
|
columnHelper.accessor('sdks', {
|
|
header: 'SDK',
|
|
cell: SdkCell,
|
|
enableSorting: false,
|
|
meta: {
|
|
width: '25%',
|
|
},
|
|
}),
|
|
],
|
|
[],
|
|
);
|
|
|
|
const table = useReactTable(
|
|
withTableState(tableState, setTableState, {
|
|
columns,
|
|
data: applications,
|
|
}),
|
|
);
|
|
|
|
const rows = table.getRowModel().rows;
|
|
|
|
return (
|
|
<PageContent
|
|
disableLoading={true}
|
|
bodyClass='no-padding'
|
|
header={
|
|
<PageHeader
|
|
title='Project applications'
|
|
actions={
|
|
<>
|
|
<ConditionallyRender
|
|
condition={!isSmallScreen}
|
|
show={
|
|
<>
|
|
<Search
|
|
placeholder='Search'
|
|
expandable
|
|
initialValue={query || ''}
|
|
onChange={setSearchValue}
|
|
/>
|
|
<PageHeader.Divider />
|
|
</>
|
|
}
|
|
/>
|
|
</>
|
|
}
|
|
>
|
|
<ConditionallyRender
|
|
condition={isSmallScreen}
|
|
show={
|
|
<Search
|
|
initialValue={query || ''}
|
|
onChange={setSearchValue}
|
|
/>
|
|
}
|
|
/>
|
|
</PageHeader>
|
|
}
|
|
>
|
|
<SearchHighlightProvider value={query || ''}>
|
|
<div ref={bodyLoadingRef}>
|
|
<PaginatedTable tableInstance={table} totalItems={total} />
|
|
</div>
|
|
</SearchHighlightProvider>
|
|
<ConditionallyRender
|
|
condition={rows.length === 0}
|
|
show={
|
|
<Box sx={(theme) => ({ padding: theme.spacing(0, 2, 2) })}>
|
|
<ConditionallyRender
|
|
condition={(query || '')?.length > 0}
|
|
show={
|
|
<TablePlaceholder>
|
|
No applications found matching “
|
|
{query}
|
|
”
|
|
</TablePlaceholder>
|
|
}
|
|
elseShow={
|
|
<TablePlaceholder>
|
|
No applications found matching your
|
|
criteria.
|
|
</TablePlaceholder>
|
|
}
|
|
/>
|
|
</Box>
|
|
}
|
|
/>
|
|
</PageContent>
|
|
);
|
|
};
|