Skip to content

Commit

Permalink
feat: Scaffolding Updates React (#228)
Browse files Browse the repository at this point in the history
* Extract Empty component Dashboard Page

* Extract Dashboard Component

* Extract DashboardItem

* Extract TitleModal
  • Loading branch information
keydunov committed Oct 9, 2019
1 parent 6692442 commit 552fd9c
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 193 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react";
import RGL, { WidthProvider } from "react-grid-layout";
import { useMutation } from "@apollo/react-hooks";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
import { UPDATE_DASHBOARD_ITEM } from "../graphql/mutations";

const ReactGridLayout = WidthProvider(RGL);

const Dashboard = ({ children, dashboardItems }) => {
const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, {
refetchQueries: [
{
query: GET_DASHBOARD_ITEMS
}
]
});

const onLayoutChange = newLayout => {
newLayout.forEach(l => {
const item = dashboardItems.find(i => i.id.toString() === l.i);
const toUpdate = JSON.stringify({
x: l.x,
y: l.y,
w: l.w,
h: l.h
});

if (item && toUpdate !== item.layout) {
updateDashboardItem({
variables: {
id: item.id,
input: {
layout: toUpdate
}
}
});
}
});
};

return (
<ReactGridLayout cols={12} rowHeight={50} onLayoutChange={onLayoutChange}>
{children}
</ReactGridLayout>
);
};

export default Dashboard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from "react";
import { Card, Menu, Button, Dropdown, Modal } from "antd";
import { useMutation } from "@apollo/react-hooks";
import { Link } from "react-router-dom";
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
import { DELETE_DASHBOARD_ITEM } from "../graphql/mutations";

const DashboardItemDropdown = ({ itemId }) => {
const [removeDashboardItem] = useMutation(DELETE_DASHBOARD_ITEM, {
refetchQueries: [
{
query: GET_DASHBOARD_ITEMS
}
]
});
const dashboardItemDropdownMenu = (
<Menu>
<Menu.Item>
<Link to={`/explore?itemId=${itemId}`}>Edit</Link>
</Menu.Item>
<Menu.Item
onClick={() =>
Modal.confirm({
title: "Are you sure you want to delete this item?",
okText: "Yes",
okType: "danger",
cancelText: "No",

onOk() {
removeDashboardItem({
variables: {
id: itemId
}
});
}
})
}
>
Delete
</Menu.Item>
</Menu>
);
return (
<Dropdown
overlay={dashboardItemDropdownMenu}
placement="bottomLeft"
trigger={["click"]}
>
<Button shape="circle" icon="menu" />
</Dropdown>
);
};

const DashboardItem = ({ itemId, children, title }) => (
<Card
title={title}
style={{
height: "100%",
width: "100%"
}}
extra={<DashboardItemDropdown itemId={itemId} />}
>
{children}
</Card>
);

export default DashboardItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from "react";
import { Modal, Input } from "antd";
import { useMutation } from "@apollo/react-hooks";
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
import {
CREATE_DASHBOARD_ITEM,
UPDATE_DASHBOARD_ITEM
} from "../graphql/mutations";

const TitleModal = ({
history,
itemId,
titleModalVisible,
setTitleModalVisible,
setAddingToDashboard,
finalVizState,
setTitle,
finalTitle
}) => {
const [addDashboardItem] = useMutation(CREATE_DASHBOARD_ITEM, {
refetchQueries: [
{
query: GET_DASHBOARD_ITEMS
}
]
});
const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, {
refetchQueries: [
{
query: GET_DASHBOARD_ITEMS
}
]
});

return (
<Modal
key="modal"
title="Save Chart"
visible={titleModalVisible}
onOk={async () => {
setTitleModalVisible(false);
setAddingToDashboard(true);

try {
await (itemId ? updateDashboardItem : addDashboardItem)({
variables: {
id: itemId,
input: {
vizState: JSON.stringify(finalVizState),
name: finalTitle
}
}
});
history.push("/");
} finally {
setAddingToDashboard(false);
}
}}
onCancel={() => setTitleModalVisible(false)}
>
<Input
placeholder="Dashboard Item Name"
value={finalTitle}
onChange={e => setTitle(e.target.value)}
/>
</Modal>
)
};

export default TitleModal;
129 changes: 12 additions & 117 deletions packages/cubejs-playground/src/scaffolding/react/pages/DashboardPage.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import React from "react";
import {
Card, Spin, Button, Menu, Dropdown, Alert, Modal
} from "antd";
import { Spin, Button, Alert } from "antd";
import { Link } from "react-router-dom";
import { useQuery, useMutation } from "@apollo/react-hooks";
import RGL, { WidthProvider } from "react-grid-layout";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
import {
GET_DASHBOARD_ITEMS
} from "../graphql/queries";
import {
UPDATE_DASHBOARD_ITEM,
DELETE_DASHBOARD_ITEM
} from "../graphql/mutations";
import { useQuery } from "@apollo/react-hooks";
import { GET_DASHBOARD_ITEMS } from "../graphql/queries";
import ChartRenderer from "../components/ChartRenderer";

const ReactGridLayout = WidthProvider(RGL);
import Dashboard from "../components/Dashboard";
import DashboardItem from "../components/DashboardItem";

const deserializeItem = i => ({
...i,
Expand All @@ -33,102 +22,6 @@ const defaultLayout = i => ({
minH: 8
});

const Dashboard = ({ children, dashboardItems }) => {
const [updateDashboardItem] = useMutation(UPDATE_DASHBOARD_ITEM, {
refetchQueries: [
{
query: GET_DASHBOARD_ITEMS
}
]
});

const onLayoutChange = newLayout => {
newLayout.forEach(l => {
const item = dashboardItems.find(i => i.id.toString() === l.i);
const toUpdate = JSON.stringify({
x: l.x,
y: l.y,
w: l.w,
h: l.h
});

if (item && toUpdate !== item.layout) {
updateDashboardItem({
variables: {
id: item.id,
input: { layout: toUpdate }
}
});
}
});
};

return (
<ReactGridLayout cols={12} rowHeight={50} onLayoutChange={onLayoutChange}>
{children}
</ReactGridLayout>
);
};

const DashboardItemDropdown = ({ itemId }) => {
const [removeDashboardItem] = useMutation(DELETE_DASHBOARD_ITEM, {
refetchQueries: [
{
query: GET_DASHBOARD_ITEMS
}
]
});
const dashboardItemDropdownMenu = (
<Menu>
<Menu.Item>
<Link to={`/explore?itemId=${itemId}`}>Edit</Link>
</Menu.Item>
<Menu.Item
onClick={() =>
Modal.confirm({
title: "Are you sure you want to delete this item?",
okText: "Yes",
okType: "danger",
cancelText: "No",

onOk() {
removeDashboardItem({
variables: {
id: itemId
}
});
}
})
}
>
Delete
</Menu.Item>
</Menu>
);
return (
<Dropdown
overlay={dashboardItemDropdownMenu}
placement="bottomLeft"
trigger={["click"]}
>
<Button shape="circle" icon="menu" />
</Dropdown>
);
};

const DashboardItem = ({ itemId, children, title }) => (
<Card
title={title}
style={{
height: "100%",
width: "100%"
}}
extra={<DashboardItemDropdown itemId={itemId} />}
>
{children}
</Card>
);

const DashboardPage = ({ cubejsApi }) => {
const { loading, error, data } = useQuery(GET_DASHBOARD_ITEMS);

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

return !data || data.dashboardItems.length ? (
<Dashboard dashboardItems={data && data.dashboardItems}>
{data && data.dashboardItems.map(deserializeItem).map(dashboardItem)}
</Dashboard>
) : (
const Empty = () => (
<div
style={{
textAlign: "center",
Expand All @@ -173,6 +62,12 @@ const DashboardPage = ({ cubejsApi }) => {
</Link>
</div>
);

return !data || data.dashboardItems.length ? (
<Dashboard dashboardItems={data && data.dashboardItems}>
{data && data.dashboardItems.map(deserializeItem).map(dashboardItem)}
</Dashboard>
) : <Empty />;
};

export default DashboardPage;
Loading

0 comments on commit 552fd9c

Please sign in to comment.