Skip to content

Commit 552fd9c

Browse files
authored
feat: Scaffolding Updates React (#228)
* Extract Empty component Dashboard Page * Extract Dashboard Component * Extract DashboardItem * Extract TitleModal
1 parent 6692442 commit 552fd9c

File tree

5 files changed

+230
-193
lines changed

5 files changed

+230
-193
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from "react";
2+
import RGL, { WidthProvider } from "react-grid-layout";
3+
import { useMutation } from "@apollo/react-hooks";
4+
import "react-grid-layout/css/styles.css";
5+
import "react-resizable/css/styles.css";
6+
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
7+
import { UPDATE_DASHBOARD_ITEM } from "../graphql/mutations";
8+
9+
const ReactGridLayout = WidthProvider(RGL);
10+
11+
const Dashboard = ({ children, dashboardItems }) => {
12+
const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, {
13+
refetchQueries: [
14+
{
15+
query: GET_DASHBOARD_ITEMS
16+
}
17+
]
18+
});
19+
20+
const onLayoutChange = newLayout => {
21+
newLayout.forEach(l => {
22+
const item = dashboardItems.find(i => i.id.toString() === l.i);
23+
const toUpdate = JSON.stringify({
24+
x: l.x,
25+
y: l.y,
26+
w: l.w,
27+
h: l.h
28+
});
29+
30+
if (item && toUpdate !== item.layout) {
31+
updateDashboardItem({
32+
variables: {
33+
id: item.id,
34+
input: {
35+
layout: toUpdate
36+
}
37+
}
38+
});
39+
}
40+
});
41+
};
42+
43+
return (
44+
<ReactGridLayout cols={12} rowHeight={50} onLayoutChange={onLayoutChange}>
45+
{children}
46+
</ReactGridLayout>
47+
);
48+
};
49+
50+
export default Dashboard;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React from "react";
2+
import { Card, Menu, Button, Dropdown, Modal } from "antd";
3+
import { useMutation } from "@apollo/react-hooks";
4+
import { Link } from "react-router-dom";
5+
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
6+
import { DELETE_DASHBOARD_ITEM } from "../graphql/mutations";
7+
8+
const DashboardItemDropdown = ({ itemId }) => {
9+
const [removeDashboardItem] = useMutation(DELETE_DASHBOARD_ITEM, {
10+
refetchQueries: [
11+
{
12+
query: GET_DASHBOARD_ITEMS
13+
}
14+
]
15+
});
16+
const dashboardItemDropdownMenu = (
17+
<Menu>
18+
<Menu.Item>
19+
<Link to={`/explore?itemId=${itemId}`}>Edit</Link>
20+
</Menu.Item>
21+
<Menu.Item
22+
onClick={() =>
23+
Modal.confirm({
24+
title: "Are you sure you want to delete this item?",
25+
okText: "Yes",
26+
okType: "danger",
27+
cancelText: "No",
28+
29+
onOk() {
30+
removeDashboardItem({
31+
variables: {
32+
id: itemId
33+
}
34+
});
35+
}
36+
})
37+
}
38+
>
39+
Delete
40+
</Menu.Item>
41+
</Menu>
42+
);
43+
return (
44+
<Dropdown
45+
overlay={dashboardItemDropdownMenu}
46+
placement="bottomLeft"
47+
trigger={["click"]}
48+
>
49+
<Button shape="circle" icon="menu" />
50+
</Dropdown>
51+
);
52+
};
53+
54+
const DashboardItem = ({ itemId, children, title }) => (
55+
<Card
56+
title={title}
57+
style={{
58+
height: "100%",
59+
width: "100%"
60+
}}
61+
extra={<DashboardItemDropdown itemId={itemId} />}
62+
>
63+
{children}
64+
</Card>
65+
);
66+
67+
export default DashboardItem;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React from "react";
2+
import { Modal, Input } from "antd";
3+
import { useMutation } from "@apollo/react-hooks";
4+
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
5+
import {
6+
CREATE_DASHBOARD_ITEM,
7+
UPDATE_DASHBOARD_ITEM
8+
} from "../graphql/mutations";
9+
10+
const TitleModal = ({
11+
history,
12+
itemId,
13+
titleModalVisible,
14+
setTitleModalVisible,
15+
setAddingToDashboard,
16+
finalVizState,
17+
setTitle,
18+
finalTitle
19+
}) => {
20+
const [addDashboardItem] = useMutation(CREATE_DASHBOARD_ITEM, {
21+
refetchQueries: [
22+
{
23+
query: GET_DASHBOARD_ITEMS
24+
}
25+
]
26+
});
27+
const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, {
28+
refetchQueries: [
29+
{
30+
query: GET_DASHBOARD_ITEMS
31+
}
32+
]
33+
});
34+
35+
return (
36+
<Modal
37+
key="modal"
38+
title="Save Chart"
39+
visible={titleModalVisible}
40+
onOk={async () => {
41+
setTitleModalVisible(false);
42+
setAddingToDashboard(true);
43+
44+
try {
45+
await (itemId ? updateDashboardItem : addDashboardItem)({
46+
variables: {
47+
id: itemId,
48+
input: {
49+
vizState: JSON.stringify(finalVizState),
50+
name: finalTitle
51+
}
52+
}
53+
});
54+
history.push("/");
55+
} finally {
56+
setAddingToDashboard(false);
57+
}
58+
}}
59+
onCancel={() => setTitleModalVisible(false)}
60+
>
61+
<Input
62+
placeholder="Dashboard Item Name"
63+
value={finalTitle}
64+
onChange={e => setTitle(e.target.value)}
65+
/>
66+
</Modal>
67+
)
68+
};
69+
70+
export default TitleModal;
Lines changed: 12 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
import React from "react";
2-
import {
3-
Card, Spin, Button, Menu, Dropdown, Alert, Modal
4-
} from "antd";
2+
import { Spin, Button, Alert } from "antd";
53
import { Link } from "react-router-dom";
6-
import { useQuery, useMutation } from "@apollo/react-hooks";
7-
import RGL, { WidthProvider } from "react-grid-layout";
8-
import "react-grid-layout/css/styles.css";
9-
import "react-resizable/css/styles.css";
10-
import {
11-
GET_DASHBOARD_ITEMS
12-
} from "../graphql/queries";
13-
import {
14-
UPDATE_DASHBOARD_ITEM,
15-
DELETE_DASHBOARD_ITEM
16-
} from "../graphql/mutations";
4+
import { useQuery } from "@apollo/react-hooks";
5+
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
176
import ChartRenderer from "../components/ChartRenderer";
18-
19-
const ReactGridLayout = WidthProvider(RGL);
7+
import Dashboard from "../components/Dashboard";
8+
import DashboardItem from "../components/DashboardItem";
209

2110
const deserializeItem = i => ({
2211
...i,
@@ -33,102 +22,6 @@ const defaultLayout = i => ({
3322
minH: 8
3423
});
3524

36-
const Dashboard = ({ children, dashboardItems }) => {
37-
const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, {
38-
refetchQueries: [
39-
{
40-
query: GET_DASHBOARD_ITEMS
41-
}
42-
]
43-
});
44-
45-
const onLayoutChange = newLayout => {
46-
newLayout.forEach(l => {
47-
const item = dashboardItems.find(i => i.id.toString() === l.i);
48-
const toUpdate = JSON.stringify({
49-
x: l.x,
50-
y: l.y,
51-
w: l.w,
52-
h: l.h
53-
});
54-
55-
if (item && toUpdate !== item.layout) {
56-
updateDashboardItem({
57-
variables: {
58-
id: item.id,
59-
input: { layout: toUpdate }
60-
}
61-
});
62-
}
63-
});
64-
};
65-
66-
return (
67-
<ReactGridLayout cols={12} rowHeight={50} onLayoutChange={onLayoutChange}>
68-
{children}
69-
</ReactGridLayout>
70-
);
71-
};
72-
73-
const DashboardItemDropdown = ({ itemId }) => {
74-
const [removeDashboardItem] = useMutation(DELETE_DASHBOARD_ITEM, {
75-
refetchQueries: [
76-
{
77-
query: GET_DASHBOARD_ITEMS
78-
}
79-
]
80-
});
81-
const dashboardItemDropdownMenu = (
82-
<Menu>
83-
<Menu.Item>
84-
<Link to={`/explore?itemId=${itemId}`}>Edit</Link>
85-
</Menu.Item>
86-
<Menu.Item
87-
onClick={() =>
88-
Modal.confirm({
89-
title: "Are you sure you want to delete this item?",
90-
okText: "Yes",
91-
okType: "danger",
92-
cancelText: "No",
93-
94-
onOk() {
95-
removeDashboardItem({
96-
variables: {
97-
id: itemId
98-
}
99-
});
100-
}
101-
})
102-
}
103-
>
104-
Delete
105-
</Menu.Item>
106-
</Menu>
107-
);
108-
return (
109-
<Dropdown
110-
overlay={dashboardItemDropdownMenu}
111-
placement="bottomLeft"
112-
trigger={["click"]}
113-
>
114-
<Button shape="circle" icon="menu" />
115-
</Dropdown>
116-
);
117-
};
118-
119-
const DashboardItem = ({ itemId, children, title }) => (
120-
<Card
121-
title={title}
122-
style={{
123-
height: "100%",
124-
width: "100%"
125-
}}
126-
extra={<DashboardItemDropdown itemId={itemId} />}
127-
>
128-
{children}
129-
</Card>
130-
);
131-
13225
const DashboardPage = ({ cubejsApi }) => {
13326
const { loading, error, data } = useQuery(GET_DASHBOARD_ITEMS);
13427

@@ -154,11 +47,7 @@ const DashboardPage = ({ cubejsApi }) => {
15447
</div>
15548
);
15649

157-
return !data || data.dashboardItems.length ? (
158-
<Dashboard dashboardItems={data && data.dashboardItems}>
159-
{data && data.dashboardItems.map(deserializeItem).map(dashboardItem)}
160-
</Dashboard>
161-
) : (
50+
const Empty = () => (
16251
<div
16352
style={{
16453
textAlign: "center",
@@ -173,6 +62,12 @@ const DashboardPage = ({ cubejsApi }) => {
17362
</Link>
17463
</div>
17564
);
65+
66+
return !data || data.dashboardItems.length ? (
67+
<Dashboard dashboardItems={data && data.dashboardItems}>
68+
{data && data.dashboardItems.map(deserializeItem).map(dashboardItem)}
69+
</Dashboard>
70+
) : <Empty />;
17671
};
17772

17873
export default DashboardPage;

0 commit comments

Comments
 (0)