Skip to content

Commit

Permalink
feat: add filters to history page
Browse files Browse the repository at this point in the history
  • Loading branch information
RRanath committed Dec 10, 2024
1 parent 8107ae0 commit 13d5dea
Show file tree
Hide file tree
Showing 13 changed files with 589 additions and 140 deletions.
7 changes: 2 additions & 5 deletions app/components/Analyst/CBC/History/CbcHistoryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,11 @@ const HistoryContent = ({
updatedAt,
prevJson,
json,
givenName,
user,
changeReason,
familyName,
op,
tableName,
}) => {
const fullName = `${givenName} ${familyName}`;

const createdAtFormatted =
op === 'UPDATE'
? DateTime.fromJSDate(new Date(updatedAt)).toLocaleString(
Expand All @@ -59,7 +56,7 @@ const HistoryContent = ({
<>
<StyledContent data-testid="cbc-data-updater-and-timestamp">
<span>
{fullName} {op === 'UPDATE' ? 'updated' : 'created'} the CBC data on{' '}
{user} {op === 'UPDATE' ? 'updated' : 'created'} the CBC data on{' '}
{createdAtFormatted}
</span>
</StyledContent>
Expand Down
9 changes: 3 additions & 6 deletions app/components/Analyst/CBC/History/CbcHistoryRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ interface Props {
tableName: string;
updatedAt: string;
createdAt: string;
givenName: string;
familyName: string;
user: string;
op: string;
}

Expand All @@ -42,8 +41,7 @@ const CbcHistoryRow: React.FC<Props> = ({
changeReason,
tableName,
createdAt,
givenName,
familyName,
user,
updatedAt,
op,
}) => {
Expand All @@ -58,8 +56,7 @@ const CbcHistoryRow: React.FC<Props> = ({
prevJson={prevJson}
createdAt={createdAt}
updatedAt={updatedAt}
familyName={familyName}
givenName={givenName}
user={user}
tableName={tableName}
changeReason={changeReason}
op={op}
Expand Down
103 changes: 72 additions & 31 deletions app/components/Analyst/CBC/History/CbcHistoryTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { CbcHistoryTable_query$key } from '__generated__/CbcHistoryTable_query.graphql';
import React from 'react';
import React, { useMemo, useState } from 'react';
import { useFragment, graphql } from 'react-relay';
import styled from 'styled-components';
import HistoryFilter, {
filterByType,
filterByUser,
getTypeOptions,
getUserOptions,
} from 'components/Analyst/History/HistoryFilter';
import CbcHistoryRow from './CbcHistoryRow';

const StyledTable = styled.table`
Expand Down Expand Up @@ -29,7 +35,7 @@ interface Props {
}

const CbcHistoryTable: React.FC<Props> = ({ query }) => {
const queryFragment = useFragment<CbcHistoryTable_query$key>(
const { cbcByRowId } = useFragment<CbcHistoryTable_query$key>(
graphql`
fragment CbcHistoryTable_query on Query {
cbcByRowId(rowId: $rowId) {
Expand All @@ -53,38 +59,73 @@ const CbcHistoryTable: React.FC<Props> = ({ query }) => {
query
);

const { cbcByRowId } = queryFragment;
const { history } = cbcByRowId;
const [filters, setFilters] = useState({ types: [], users: [] });

const historyItems = useMemo(
() =>
history?.nodes?.map((item) => ({
...item,
user: `${item.ccbcUserByCreatedBy.givenName} ${item.ccbcUserByCreatedBy.familyName}`,
})) ?? [],
[history?.nodes]
);

const typeOptions = useMemo(
() => getTypeOptions(historyItems, filters),
[historyItems, filters]
);

const userOptions = useMemo(
() => getUserOptions(historyItems, filters),
[historyItems, filters]
);

const filteredHistory = useMemo(
() =>
historyItems.filter(
(historyItem) =>
filterByType(historyItem, filters) &&
filterByUser(historyItem, filters)
),
[historyItems, filters]
);

return (
<StyledTable>
<tbody>
{history.nodes.map((historyItem) => (
<CbcHistoryRow
key={historyItem.rowId}
json={{
...historyItem.record?.json_data,
project_number: historyItem.record?.project_number,
locations: {
added: historyItem.record?.added_communities,
removed: historyItem.record?.deleted_communities,
},
}}
prevJson={{
...historyItem.oldRecord?.json_data,
project_number: historyItem.oldRecord?.project_number,
}}
changeReason={historyItem.record?.change_reason}
tableName={historyItem.tableName}
createdAt={historyItem.createdAt}
updatedAt={historyItem.record?.updated_at}
givenName={historyItem.ccbcUserByCreatedBy.givenName}
familyName={historyItem.ccbcUserByCreatedBy.familyName}
op={historyItem.op}
/>
))}
</tbody>
</StyledTable>
<>
<HistoryFilter
filterOptions={{ typeOptions, userOptions }}
onFilterChange={setFilters}
filters={filters}
/>
<StyledTable>
<tbody>
{filteredHistory.map((historyItem) => (
<CbcHistoryRow
key={historyItem.rowId}
json={{
...historyItem.record?.json_data,
project_number: historyItem.record?.project_number,
locations: {
added: historyItem.record?.added_communities,
removed: historyItem.record?.deleted_communities,
},
}}
prevJson={{
...historyItem.oldRecord?.json_data,
project_number: historyItem.oldRecord?.project_number,
}}
changeReason={historyItem.record?.change_reason}
tableName={historyItem.tableName}
createdAt={historyItem.createdAt}
updatedAt={historyItem.record?.updated_at}
user={historyItem.user}
op={historyItem.op}
/>
))}
</tbody>
</StyledTable>
</>
);
};

Expand Down
74 changes: 74 additions & 0 deletions app/components/Analyst/History/HistoryFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import { FormBase } from 'components/Form';
import { historyFilter } from 'formSchema/analyst';
import historyFilterUiSchema from 'formSchema/uiSchema/history/historyFilterUiSchema';
import transformToTitleCase from 'utils/formatString';

interface HistoryFilterProps {
filterOptions: { typeOptions: string[]; userOptions: string[] };
filters: any;
onFilterChange: (newFilters: any) => void;
}

export const filterByType = (historyItem: any, filters: any) =>
!filters?.types?.length || filters?.types?.includes(historyItem.tableName);

export const filterByUser = (historyItem: any, filters: any) =>
!filters?.users?.length || filters?.users?.includes(historyItem.user);

export const getTypeOptions = (historyItems: any[], filters: any) => {
return [
...new Set(
historyItems
.filter(
(item) =>
!filters?.users?.length || filters?.users?.includes(item.user)
)
.map((item) => item.tableName)
),
];
};

export const getUserOptions = (historyItems: any[], filters: any) => {
return [
...new Set(
historyItems
.filter(
(item) =>
!filters?.types?.length || filters?.types?.includes(item.tableName)
)
.map((item) => item.user)
),
];
};

const HistoryFilter: React.FC<HistoryFilterProps> = ({
filterOptions,
filters,
onFilterChange,
}) => {
const { typeOptions, userOptions } = filterOptions;

const formattedTypeOptions = typeOptions
.filter((type) => type !== 'attachment')
.map((type) => ({
value: type,
label: transformToTitleCase(type),
}));

const filterSchema = historyFilter(formattedTypeOptions, userOptions);

return (
<FormBase
schema={filterSchema as any}
uiSchema={historyFilterUiSchema as any}
formData={filters}
onChange={(e) => onFilterChange(e.formData)}
formContext={{ skipUnsavedWarning: true }}
// eslint-disable-next-line react/no-children-prop
children
/>
);
};

export default HistoryFilter;
Loading

0 comments on commit 13d5dea

Please sign in to comment.