Skip to content

Commit

Permalink
chore: update to datagrid (#935)
Browse files Browse the repository at this point in the history
* wip: switch to datagrid

* chore: make container flex better, switch ad set list to datagrid

* fix: field mistake

* fix: adjust width settings

* fix: move clone and edit into datagrid table
  • Loading branch information
IanKrieger authored Oct 13, 2023
1 parent fd1d3f8 commit 7f6b46e
Show file tree
Hide file tree
Showing 24 changed files with 546 additions and 979 deletions.
99 changes: 57 additions & 42 deletions src/components/Campaigns/CloneCampaign.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import {
Box,
Button,
Chip,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
LinearProgress,
Tooltip,
} from "@mui/material";
import {
CampaignFragment,
CampaignSummaryFragment,
useCreateCampaignMutation,
useLoadCampaignLazyQuery,
} from "graphql/campaign.generated";
import { useHistory } from "react-router-dom";
import { useContext, useState } from "react";
Expand All @@ -21,20 +22,21 @@ import { useAdvertiser } from "auth/hooks/queries/useAdvertiser";
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import { useUser } from "auth/hooks/queries/useUser";
import { FilterContext } from "state/context";
import { CampaignFormat, CampaignSource } from "graphql/types";

interface Props {
campaignFragment?: CampaignFragment | null;
useChip?: boolean;
campaign?: CampaignSummaryFragment;
disabled?: boolean;
}

export function CloneCampaign({ campaignFragment, useChip, disabled }: Props) {
export function CloneCampaign({ campaign, disabled }: Props) {
const { advertiser } = useAdvertiser();
const { fromDate } = useContext(FilterContext);
const { userId } = useUser();
const history = useHistory();
const [open, setOpen] = useState(false);

const [getCampaign, { loading: getLoading }] = useLoadCampaignLazyQuery();
const [copyCampaign, { loading }] = useCreateCampaignMutation({
refetchQueries: [
{
Expand All @@ -54,59 +56,72 @@ export function CloneCampaign({ campaignFragment, useChip, disabled }: Props) {
},
});

const doClone = async () => {
if (campaign) {
getCampaign({
variables: { id: campaign.id },
onCompleted(data) {
if (data.campaign) {
copyCampaign({
variables: {
input: createCampaignFromFragment(data.campaign, userId),
},
});
} else {
alert("Unable to clone campaign");
}
},
});
}
};

const canClone =
campaign &&
campaign.source === CampaignSource.SelfServe &&
[CampaignFormat.PushNotification, CampaignFormat.NewsDisplayAd].includes(
campaign.format,
);
return (
<Box>
{useChip ? (
<Chip
color="primary"
label="Clone"
onClick={() => {
setOpen(true);
}}
disabled={loading || !campaignFragment || disabled}
icon={<ContentCopyIcon fontSize="small" />}
/>
) : (
<Button
color="primary"
variant="text"
size="small"
onClick={(e) => {
e.preventDefault();
setOpen(true);
}}
disabled={loading || !campaignFragment || disabled}
startIcon={<ContentCopyIcon />}
>
Clone Campaign
</Button>
)}
<Tooltip
title={
!campaign ? "Select one campaign to clone" : `Clone ${campaign.name}`
}
>
<span>
<Button
color="primary"
variant="text"
size="small"
onClick={(e) => {
e.preventDefault();
setOpen(true);
}}
disabled={!canClone || loading || getLoading || disabled}
startIcon={<ContentCopyIcon />}
>
Clone
</Button>
</span>
</Tooltip>
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>{`Copy campaign: "${campaignFragment?.name}"?`}</DialogTitle>
<DialogTitle>{`Copy campaign: "${campaign?.name}"?`}</DialogTitle>
<DialogContent>
<DialogContentText>
Cloning a campaign will take all properties including ad sets and
ads, and create a new draft campaign with them.
</DialogContentText>
{loading && <LinearProgress />}
{(loading || getLoading) && <LinearProgress />}
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} disabled={loading}>
Cancel
</Button>
<Button
disabled={loading}
disabled={loading || getLoading}
onClick={(e) => {
e.preventDefault();
if (campaignFragment) {
copyCampaign({
variables: {
input: createCampaignFromFragment(campaignFragment, userId),
},
});
} else {
alert("No campaign selected");
}
doClone();
}}
>
Clone
Expand Down
69 changes: 27 additions & 42 deletions src/components/Creatives/CreativeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,9 @@ import MiniSideBar from "components/Drawer/MiniSideBar";
import { Box, Link, List, Typography } from "@mui/material";
import { Status } from "components/Campaigns/Status";
import { Link as RouterLink } from "react-router-dom";
import {
DataGrid,
GridColDef,
GridToolbarColumnsButton,
GridToolbarContainer,
GridToolbarFilterButton,
GridToolbarQuickFilter,
} from "@mui/x-data-grid";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { CreativeStatusSwitch } from "components/Creatives/CreativeStatusSwitch";
import { CustomToolbar } from "components/Datagrid/CustomToolbar";

const ALLOWED_TYPES = ["notification_all_v1", "inline_content_all_v1"];
export function CreativeList() {
Expand Down Expand Up @@ -81,17 +75,6 @@ export function CreativeList() {
},
];

function CustomToolbar() {
return (
<GridToolbarContainer>
<GridToolbarColumnsButton />
<GridToolbarFilterButton />
<Box flex={1} />
<GridToolbarQuickFilter />
</GridToolbarContainer>
);
}

const creatives = [...(data?.advertiser?.creatives ?? [])].filter((c) =>
ALLOWED_TYPES.includes(c.type.code),
);
Expand All @@ -107,32 +90,34 @@ export function CreativeList() {
header="Creatives"
sx={{
flexGrow: 1,
mr: 2,
width: "100%",
overflowX: "auto",
mr: 1,
}}
>
<DataGrid
loading={loading}
rows={creatives}
columns={columns}
density="standard"
autoHeight
disableRowSelectionOnClick
hideFooterSelectedRowCount
rowHeight={60}
slots={{ toolbar: CustomToolbar }}
sx={{ borderStyle: "none" }}
initialState={{
sorting: {
sortModel: [{ field: "createdAt", sort: "desc" }],
},
pagination: {
paginationModel: {
pageSize: 10,
<Box>
<DataGrid
loading={loading}
rows={creatives}
columns={columns}
density="standard"
autoHeight
disableRowSelectionOnClick
hideFooterSelectedRowCount
rowHeight={60}
slots={{ toolbar: CustomToolbar }}
sx={{ borderStyle: "none" }}
initialState={{
sorting: {
sortModel: [{ field: "createdAt", sort: "desc" }],
},
},
}}
/>
pagination: {
paginationModel: {
pageSize: 10,
},
},
}}
/>
</Box>
</CardContainer>
</MiniSideBar>
);
Expand Down
20 changes: 20 additions & 0 deletions src/components/Datagrid/CustomToolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
GridToolbarColumnsButton,
GridToolbarContainer,
GridToolbarFilterButton,
GridToolbarQuickFilter,
} from "@mui/x-data-grid";
import { Box } from "@mui/material";
import { PropsWithChildren } from "react";

export function CustomToolbar({ children }: PropsWithChildren) {
return (
<GridToolbarContainer>
{children}
<GridToolbarColumnsButton />
<GridToolbarFilterButton />
<Box flex={1} />
<GridToolbarQuickFilter />
</GridToolbarContainer>
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Box, Tooltip } from "@mui/material";
import _ from "lodash";
import { format, formatDistanceToNow, parseISO } from "date-fns";
import { CellValue } from "./EnhancedTable";
import { ReactChild, ReactNode, useContext } from "react";
import { ReactElement, ReactNode, useContext } from "react";
import { formatInTimeZone } from "date-fns-tz";
import enUS from "date-fns/locale/en-US";
import {
Expand All @@ -12,18 +11,18 @@ import {
useUpdateCampaignMutation,
} from "graphql/campaign.generated";
import { useUpdateAdSetMutation } from "graphql/ad-set.generated";
import { OnOff } from "../Switch/OnOff";
import { OnOff } from "components/Switch/OnOff";
import { displayFromCampaignState } from "util/displayState";
import { CampaignExtras } from "user/adSet/AdSetList";
import { FilterContext } from "state/context";
import { refetchAdvertiserCampaignsQuery } from "graphql/advertiser.generated";
import { UpdateAdSetInput } from "graphql/types";

export type CellValueRenderer = (value: CellValue) => ReactNode;
export type CellValueRenderer = (value: any) => ReactNode;
const ADS_DEFAULT_TIMEZONE = "America/New_York";
const TOOLTIP_FORMAT = "E d LLL yyyy HH:mm:ss zzz";

function formatDateForTooltip(dt: Date): ReactChild {
function formatDateForTooltip(dt: Date): ReactElement {
return (
<>
<Box>
Expand Down
Loading

0 comments on commit 7f6b46e

Please sign in to comment.