Skip to content

Commit

Permalink
feat: add 'tableProps' to core item list views
Browse files Browse the repository at this point in the history
  • Loading branch information
trevor-anderson committed Mar 3, 2023
1 parent 9854952 commit f1546be
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 56 deletions.
13 changes: 13 additions & 0 deletions src/pages/Contacts/ListView/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ export const ContactsListItem = ({
onClick={onClick}
itemID={contact.id}
divider={false}
sx={({ palette }) => ({
...(palette.mode === "dark"
? {
backgroundColor: palette.background.paper
}
: {
border: `2px solid ${palette.divider}`
}),
borderRadius: "0.5rem",
"& .MuiButtonBase-root": {
borderRadius: "0.5rem"
}
})}
{...props}
>
<ListItemText
Expand Down
11 changes: 8 additions & 3 deletions src/pages/Contacts/ListView/ListView.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useQuery } from "@apollo/client/react/hooks";
import { ContactsListItem } from "./ListItem";
import { Loading, Error } from "@components";
import { QUERIES } from "@graphql";
import { CoreItemsListView, type ListViewRenderItemFn } from "@layouts";
import { ContactsListItem } from "./ListItem";
import { contactTableProps } from "./tableProps";
import { MOCK_CONTACTS } from "@/__tests__/mockItems"; // FIXME rm import, use only in test files

export const ContactsListView = () => {
Expand All @@ -26,11 +27,15 @@ export const ContactsListView = () => {
viewBasePath="/home/contacts"
lists={[{ items: Object.values(MOCK_CONTACTS) as any }]}
renderItem={renderContactsListItem}
tableProps={{
...contactTableProps,
rows: Object.values(MOCK_CONTACTS)
}}
sx={{
"& ul.core-items-list": {
"& .MuiList-root": {
width: "100%",
display: "grid",
gridGap: "0.5rem",
gridGap: "1rem",
gridTemplateColumns: "repeat( auto-fit, minmax( 16rem, 1fr ))",
gridTemplateRows: "repeat( auto-fit, 1fr )"
}
Expand Down
52 changes: 52 additions & 0 deletions src/pages/Contacts/ListView/tableProps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { DataGrid } from "@mui/x-data-grid";
import { ContactAvatar } from "@components";
import { prettifyStr } from "@utils";
import type { Contact } from "@types";

type ColumnFieldKeys = "contact" | keyof Contact;
type ColumnConfig = React.ComponentProps<typeof DataGrid>["columns"][number];

const COLUMNS = Object.fromEntries(
Object.entries(
{
contact: {
headerName: "Contact",
valueGetter: ({ row: contact }) => contact?.profile?.displayName || contact.handle,
valueFormatter: ({ value }) => value, // <-- necessary for export/print on cols with renderCell
renderCell: ({ row: contact }) => (
<ContactAvatar contact={contact as any} viewContactOnClick={false} />
)
},
handle: {
headerName: "Handle"
},
email: {
headerName: "Email"
},
phone: {
headerName: "Phone",
valueFormatter: ({ value }) => prettifyStr.phone(value),
valueParser: (value) => prettifyStr.phone(value),
minWidth: 125,
headerAlign: "center",
align: "center"
}
} as Record<ColumnFieldKeys, Partial<ColumnConfig>>
// Map each column entry to an object with "field" and some defaults:
).map(([columnFieldKey, columnConfig]) => [
columnFieldKey,
{
field: columnFieldKey,
type: "string",
editable: false,
flex: 1,
minWidth: columnConfig.type === "date" ? 100 : columnConfig.type === "dateTime" ? 160 : 150,
maxWidth: 600,
...columnConfig // <-- explicit configs override above defaults
}
])
) as Record<ColumnFieldKeys, ColumnConfig>;

export const contactTableProps: Omit<React.ComponentProps<typeof DataGrid>, "rows"> = {
columns: Object.values(COLUMNS)
};
20 changes: 6 additions & 14 deletions src/pages/Invoices/ListView/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import { formatNum } from "@utils";
import type { Invoice } from "@types";

export const InvoicesListItem = ({
parentListName,
listName,
item,
onClick,
...props
}: {
parentListName?: "Inbox" | "Sent";
listName?: "Inbox" | "Sent";
item?: Invoice;
onClick?: React.ComponentProps<typeof CoreListItemLayout>["onClick"];
}) => {
if (!parentListName || !item || !onClick) return null;
if (!listName || !item || !onClick) return null;

const isInboxList = parentListName === "Inbox";
const isInboxList = listName === "Inbox";
const { createdBy, assignedTo, status, amount, workOrder, createdAt } = item;
const userToDisplay = isInboxList ? createdBy : assignedTo;
const prettyCreatedAt = createdAt.toLocaleDateString("en-us", { day: "numeric", month: "short" });
Expand All @@ -36,7 +36,7 @@ export const InvoicesListItem = ({
user={userToDisplay}
onClick={handleClickDiv}
itemID={item.id}
parentListName={parentListName}
listName={listName}
{...props}
>
<ListItemText
Expand All @@ -61,15 +61,7 @@ export const InvoicesListItem = ({
/>
<StyledRightSideListItemTextContainer
width="5rem"
primary={
<Text
style={{
marginTop: "1px"
}}
>
{formatNum.toCurrencyStr(amount)}
</Text>
}
primary={<Text style={{ marginTop: "1px" }}>{formatNum.toCurrencyStr(amount)}</Text>}
/>
<StyledRightSideListItemTextContainer
width="4.75rem"
Expand Down
32 changes: 16 additions & 16 deletions src/pages/Invoices/ListView/ListView.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { useQuery } from "@apollo/client/react/hooks";
import { InvoicesListItem } from "./ListItem";
import { Loading, Error } from "@components";
import { QUERIES } from "@graphql";
import {
CoreItemsListView,
InboxListVisToggleBtns,
useInboxListVisToggleBtns,
type ListViewRenderItemFn
} from "@layouts";
import { CoreItemsListView, type ListViewRenderItemFn } from "@layouts";
import { InvoicesListItem } from "./ListItem";
import { invoiceTableProps } from "./tableProps";
import { MOCK_INVOICES } from "@/__tests__/mockItems"; // FIXME rm import, use only in test files

export const InvoicesListView = () => {
Expand All @@ -16,7 +12,6 @@ export const InvoicesListView = () => {
notifyOnNetworkStatusChange: true,
skip: true // TODO <-- skip for now, turn off later
});
const [listVisibility, handleChangeListVisibility] = useInboxListVisToggleBtns();

// FIXME
// const { createdByUser, assignedToUser } = invoiceListSettingsStore.useFilterAndSort(
Expand All @@ -30,25 +25,30 @@ export const InvoicesListView = () => {
<CoreItemsListView
viewHeader="Invoices"
viewBasePath="/home/invoices"
headerRowListControlComponents={
<InboxListVisToggleBtns
listVisibility={listVisibility}
onChange={handleChangeListVisibility}
/>
}
lists={[
{
listName: "Inbox",
isListVisible: listVisibility.isInboxVisible,
items: MOCK_INVOICES.myInvoices.assignedToUser as any
},
{
listName: "Sent",
isListVisible: listVisibility.isSentVisible,
items: MOCK_INVOICES.myInvoices.createdByUser as any
}
]}
renderItem={renderInvoicesListItem}
tableProps={{
...invoiceTableProps,
rows: [
...MOCK_INVOICES.myInvoices.createdByUser.map((inv) => ({
isItemOwnedByUser: true,
...inv
})),
...MOCK_INVOICES.myInvoices.assignedToUser.map((inv) => ({
isItemOwnedByUser: false,
...inv
}))
]
}}
/>
);
};
Expand Down
96 changes: 96 additions & 0 deletions src/pages/Invoices/ListView/tableProps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { DataGrid } from "@mui/x-data-grid";
import { Link } from "@components";
import { getDateAndTime, formatNum } from "@utils";
import type { Invoice } from "@types";

type ColumnFieldKeys = "listName" | keyof Invoice;
type ColumnConfig = React.ComponentProps<typeof DataGrid>["columns"][number];

const COLUMNS = Object.fromEntries(
Object.entries(
{
listName: {
headerName: "Sent/Received",
valueGetter: ({ row }) => (row.isItemOwnedByUser === true ? "Sent" : "Received"),
minWidth: 115,
headerAlign: "left",
align: "center"
},
createdBy: {
headerName: "Created By",
valueGetter: ({ row }) => row.createdBy.profile?.displayName || row.createdBy.handle,
flex: 1,
minWidth: 175
},
assignedTo: {
headerName: "Assigned To",
valueGetter: ({ row }) => row.assignedTo.profile?.displayName || row.assignedTo.handle,
flex: 1,
minWidth: 175
},
amount: {
headerName: "Amount",
valueFormatter: ({ value }) => formatNum.toCurrencyStr(value),
flex: 0.5,
minWidth: 100,
headerAlign: "right",
align: "right"
},
status: {
headerName: "Status",
flex: 0.5,
minWidth: 115,
headerAlign: "center",
align: "center"
},
workOrder: {
headerName: "Work Order",
flex: 0.5,
align: "center",
headerAlign: "center",
valueGetter: ({ row }) => row?.workOrder?.id,
valueFormatter: ({ value }) => value, // <-- necessary for export/print on cols with renderCell
renderCell: ({ value: workOrderID, row }) =>
workOrderID && (
<Link
to={`/home/workorders/${encodeURIComponent(workOrderID)}`}
onClick={(event: React.MouseEvent<HTMLAnchorElement>) => event.stopPropagation()}
state={{
isItemOwnedByUser: row.isItemOwnedByUser // Invoice INBOX = WorkOrder SENT
}}
style={{ fontSize: "0.925rem", lineHeight: "1.25rem" }}
>
View Work Order
</Link>
)
},
createdAt: {
headerName: "Created",
type: "dateTime",
valueFormatter: ({ value }) => getDateAndTime(value),
flex: 1
},
updatedAt: {
headerName: "Last Updated",
type: "dateTime",
valueFormatter: ({ value }) => getDateAndTime(value),
flex: 1
}
} as Record<ColumnFieldKeys, Partial<ColumnConfig>>
// Map each column entry to an object with "field" and some defaults:
).map(([columnFieldKey, columnConfig]) => [
columnFieldKey,
{
field: columnFieldKey,
type: "string",
editable: false,
minWidth: columnConfig.type === "date" ? 100 : columnConfig.type === "dateTime" ? 160 : 150,
maxWidth: 600,
...columnConfig // <-- explicit configs override above defaults
}
])
) as Record<ColumnFieldKeys, ColumnConfig>;

export const invoiceTableProps: Omit<React.ComponentProps<typeof DataGrid>, "rows"> = {
columns: Object.values(COLUMNS)
};
10 changes: 5 additions & 5 deletions src/pages/WorkOrders/ListView/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import { CoreListItemLayout } from "@layouts";
import type { WorkOrder } from "@types";

export const WorkOrdersListItem = ({
parentListName,
listName,
item,
onClick,
...props
}: {
parentListName?: "Inbox" | "Sent";
listName?: "Inbox" | "Sent";
item?: WorkOrder;
onClick?: React.ComponentProps<typeof CoreListItemLayout>["onClick"];
}) => {
if (!parentListName || !item || !onClick) return null;
if (!listName || !item || !onClick) return null;

const isInboxList = parentListName === "Inbox";
const isInboxList = listName === "Inbox";
const { createdBy, assignedTo, status, location, description, createdAt } = item;
const userToDisplay = isInboxList ? createdBy : assignedTo;
const prettyCreatedAt = createdAt.toLocaleDateString("en-us", { day: "numeric", month: "short" });
Expand All @@ -27,7 +27,7 @@ export const WorkOrdersListItem = ({
user={userToDisplay}
onClick={onClick}
itemID={item.id}
parentListName={parentListName}
listName={listName}
{...props}
>
<StyledMiddleContentContainer>
Expand Down
Loading

0 comments on commit f1546be

Please sign in to comment.