Skip to content
Snippets Groups Projects
Commit 8f9a5fee authored by Alexander Madsen's avatar Alexander Madsen
Browse files

Merge branch 'ce-1948-convert-recordtable' into 'develop'

CE-1948 - Convert RecordTable

See merge request !328
parents ae9ec006 d3e18b9f
No related branches found
No related tags found
2 merge requests!407CE-2141: 3.0.0,!328CE-1948 - Convert RecordTable
Pipeline #158221 passed
import React from "react";
import { List, ListItem, Paper } from "@mui/material";
import { Link } from "react-router-dom";
import { RecordBadge } from "./RecordBadge";
export function RecordListItem({ record }) {
return (
<Paper>
<ListItem
button
component={Link}
to={record.url}
>
<RecordBadge record={record} />
</ListItem>
</Paper>
);
}
export function RecordList({ records }) {
return (
<List>
{records &&
records.map((record) => {
record.url = `/records/${record.name}`;
return (
<RecordListItem
key={record.name}
record={record}
/>
);
})}
</List>
);
}
import React from "react";
import { CustomTable } from "../common/table/CustomTable";
import { Table } from "@ess-ics/ce-ui-common";
import { RecordStatusIcon } from "./RecordIcons";
import { Grid, Tooltip, Typography } from "@mui/material";
import { useRedirect } from "../../hooks/Redirect";
import { noWrapText } from "../common/Helper";
const recordsColumns = [
{ id: "bulb", label: "Status", width: "5ch", textAlign: "center" },
{ id: "name", label: "Record", width: "15ch" },
{ id: "description", label: "Description", width: "15ch" },
{ id: "iocName", label: "IOC name", width: "10ch" },
{ id: "hostName", label: "Host", width: "10ch" }
{
field: "bulb",
headerName: "Status",
flex: 0,
headerAlign: "center",
align: "center"
},
{ field: "name", headerName: "Record", width: "15ch", sortable: false },
{
field: "description",
headerName: "Description",
width: "20ch",
sortable: false
},
{ field: "iocName", headerName: "IOC name", width: "10ch", sortable: false },
{ field: "hostName", headerName: "Host", width: "10ch", sortable: false }
];
const iocDetailsColumns = [
{ id: "bulb", label: "Status", width: "5ch", textAlign: "center" },
{ id: "name", label: "Record", width: "15ch" },
{ id: "iocVersion", label: "Version", width: "15ch" }
{
field: "bulb",
headerName: "Status",
flex: 0,
headerAlign: "center",
align: "center"
},
{ field: "name", headerName: "Record", width: "15ch", sortable: false },
{ field: "iocVersion", headerName: "Version", width: "15ch", sortable: false }
];
function createRecordDescription(description) {
......@@ -57,7 +75,7 @@ export function createRecordsRow(record) {
<RecordStatusIcon record={record} />
</Grid>
),
name: record.name,
name: noWrapText(record.name),
description: createRecordDescription(record.description),
iocName: record.iocName,
hostName: record.hostName
......@@ -85,42 +103,32 @@ export function createIocDetailsRow(record) {
export function RecordTable({
records,
rowType = "records",
lazyParams,
setLazyParams,
rowsPerPage,
loading
loading,
pagination,
onPage
}) {
const tableTypeSpecifics = {
records: [recordsColumns, createRecordsRow],
iocDetails: [iocDetailsColumns, createIocDetailsRow]
};
const [columns, createRow] = tableTypeSpecifics[rowType];
const redirect = useRedirect();
const [columns, createRow] = tableTypeSpecifics[rowType];
const rows = (records?.recordList ?? []).map((record) => createRow(record));
const itemLink = (name) => `/records/${encodeURIComponent(name)}`;
const onRowClicked = (id) => {
redirect(itemLink(id));
const onRowClick = (record) => {
redirect(itemLink(record?.id));
};
return (
<CustomTable
<Table
columns={columns}
rows={records.recordList.map((record) => createRow(record))}
// Total count must be practically infinity for now (till total count can be retrieved from API)
totalCount={
records.listSize < records.limit
? records.listSize + records.limit * records.pageNumber
: 1000000
}
lazyParams={lazyParams}
setLazyParams={setLazyParams}
rowsPerPage={rowsPerPage}
rows={rows}
onRowClick={onRowClick}
pagination={pagination}
onPage={onPage}
loading={loading}
paginatorTemplate="FirstPageLink PrevPageLink NextPageLink RowsPerPageDropdown"
handleRowClick={onRowClicked}
/>
);
}
import React, { useContext, useEffect } from "react";
import { Paper, Grid } from "@mui/material";
import { GlobalAppBarContext } from "@ess-ics/ce-ui-common";
import { RootContainer } from "../../components/common/Container/RootContainer";
import { RecordSearch } from "../../components/records/RecordSearch";
import { applicationTitle } from "../../components/common/Helper";
import React, {
useState,
useMemo,
useCallback,
useContext,
useEffect
} from "react";
import { useRecordSearch } from "../../api/SwaggerApi";
import {
Container,
Grid,
useMediaQuery,
Tabs,
Tab,
Typography
} from "@mui/material";
import { GlobalAppBarContext, RootPaper } from "@ess-ics/ce-ui-common";
import {
applicationTitle,
initRequestParams
} from "../../components/common/Helper";
import { SearchBar } from "../../components/common/SearchBar/SearchBar";
import useUrlState from "@ahooksjs/use-url-state";
import {
serialize,
deserialize
} from "../../components/common/URLState/URLState";
import { RecordTable } from "../../components/records/RecordTable";
import { RecordList } from "../../components/records/RecordList";
import { usePagination } from "../../hooks/pagination";
export function RecordListView() {
const { setTitle } = useContext(GlobalAppBarContext);
useEffect(() => setTitle(applicationTitle("Records")), [setTitle]);
const [records, getRecords /* reset*/, , loading] = useRecordSearch();
const [urlState, setUrlState] = useUrlState(
{
tab: "0",
rows: "20",
page: "0",
query: ""
},
{ navigateMode: "replace" }
);
const [recordFilter, setRecordFilter] = useState();
const handleTabChange = useCallback(
(event, tab) => {
setUrlState((s) =>
serialize(s.tab) === serialize(tab)
? { tab: serialize(tab) }
: { tab: serialize(tab), page: "0" }
);
changeTab(tab);
},
[setUrlState]
);
const changeTab = (tab) => {
if (tab === 0) {
setRecordFilter(null);
} else if (tab === 1) {
setRecordFilter("ACTIVE");
} else if (tab === 2) {
setRecordFilter("INACTIVE");
}
};
useEffect(() => {
urlState.tab && changeTab(deserialize(urlState.tab));
}, [urlState]);
const urlPagination = useMemo(() => {
return {
rows: deserialize(urlState.rows),
page: deserialize(urlState.page)
};
}, [urlState.rows, urlState.page]);
const setUrlPagination = useCallback(
({ rows, page }) => {
setUrlState({
rows: serialize(rows),
page: serialize(page)
});
},
[setUrlState]
);
const rowsPerPage = [20, 50];
const { pagination, setPagination } = usePagination({
rowsPerPageOptions: rowsPerPage,
initLimit: urlPagination.rows ?? rowsPerPage[0],
initPage: urlPagination.page ?? 0
});
// update pagination whenever search result total pages change
useEffect(() => {
setPagination({ totalCount: records.totalCount ?? 0 });
}, [setPagination, records.totalCount]);
// whenever url state changes, update pagination
useEffect(() => {
setPagination({ ...urlPagination });
}, [setPagination, urlPagination]);
// whenever table pagination internally changes (user clicks next page etc)
// update the row params
useEffect(() => {
setUrlPagination(pagination);
}, [pagination, setUrlPagination]);
// Request new search results whenever search or pagination changes
useEffect(() => {
let requestParams = initRequestParams(
pagination,
deserialize(urlState.query)
);
requestParams.filter = recordFilter;
getRecords(requestParams);
}, [getRecords, recordFilter, urlState.query, pagination]);
// Callback for searchbar, called whenever user updates search
const setSearch = useCallback(
(query) => {
setUrlState({ query: serialize(query) });
},
[setUrlState]
);
// Invoked by Table on change to pagination
const onPage = (params) => {
setPagination(params);
};
const smUp = useMediaQuery((theme) => theme.breakpoints.up("sm"));
const smDown = useMediaQuery((theme) => theme.breakpoints.down("sm"));
let content = (
<SearchBar
search={setSearch}
query={deserialize(urlState.query)}
loading={loading}
placeholder="Search in Record"
>
{smDown ? <RecordList records={records} /> : null}
{smUp ? (
<RecordTable
records={records}
loading={loading}
pagination={pagination}
onPage={onPage}
/>
) : null}
</SearchBar>
);
return (
<RootContainer>
<Paper>
<RootPaper>
<Grid
container
spacing={1}
>
<Grid
container
spacing={1}
component={Container}
justifyContent="space-between"
alignItems="center"
style={{ display: "flex" }}
>
<Grid
item
xs={12}
md={12}
>
<RecordSearch />
<Grid item>
<Tabs
value={deserialize(urlState.tab)}
onChange={handleTabChange}
>
<Tab label={<Typography variant="h5">All</Typography>} />
<Tab label={<Typography variant="h5">Only active</Typography>} />
<Tab
label={<Typography variant="h5">Only inactive</Typography>}
/>
</Tabs>
</Grid>
</Grid>
</Paper>
</RootContainer>
<Grid
item
xs={12}
md={12}
>
{content}
</Grid>
</Grid>
</RootPaper>
);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment