From 65165906d42cc4b5b8474d5f3608d885f8575082 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 19 Oct 2020 10:42:41 -0700 Subject: [PATCH] Added shop settings form to update groups. --- electron/main.js | 2 - .../down.yaml | 21 +++ .../up.yaml | 23 ++++ hasura/migrations/metadata.yaml | 2 + .../form-list-move-arrows.atom.jsx | 22 +++ .../layout-form-row/layout-form-row.atom.jsx | 60 +++++++++ .../layout-form-row.styles.scss | 20 +++ .../price-diff-pc-formatter.atom.jsx | 2 +- .../target-price-diff-pc.atom.jsx | 2 +- .../shop-settings-form.molecule.jsx | 127 ++++++++++++++++++ .../shop-settings/shop-settings.organism.jsx | 72 ++++++++++ .../pages/settings/settings.page.jsx | 2 + src/graphql/bodyshop.queries.js | 12 ++ 13 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/down.yaml create mode 100644 hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/up.yaml create mode 100644 src/components/atoms/form-list-move-arrows/form-list-move-arrows.atom.jsx create mode 100644 src/components/atoms/layout-form-row/layout-form-row.atom.jsx create mode 100644 src/components/atoms/layout-form-row/layout-form-row.styles.scss create mode 100644 src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx create mode 100644 src/components/organisms/shop-settings/shop-settings.organism.jsx diff --git a/electron/main.js b/electron/main.js index 9b4edeb..6e01a3d 100644 --- a/electron/main.js +++ b/electron/main.js @@ -19,8 +19,6 @@ if (isDev) { REACT_DEVELOPER_TOOLS = devTools.REACT_DEVELOPER_TOOLS; } -console.log(`${__dirname}/preload.js`); - let mainWindow; let tray = null; function createWindow() { diff --git a/hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/down.yaml new file mode 100644 index 0000000..a23038f --- /dev/null +++ b/hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/down.yaml @@ -0,0 +1,21 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_update_permission +- args: + permission: + columns: + - targets + filter: + associations: + user: + authid: + _eq: X-Hasura-User-Id + set: {} + role: user + table: + name: bodyshops + schema: public + type: create_update_permission diff --git a/hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/up.yaml new file mode 100644 index 0000000..b8ad060 --- /dev/null +++ b/hasura/migrations/1603128778624_update_permission_user_public_table_bodyshops/up.yaml @@ -0,0 +1,23 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_update_permission +- args: + permission: + columns: + - accepted_ins_co + - shopname + - targets + filter: + associations: + user: + authid: + _eq: X-Hasura-User-Id + set: {} + role: user + table: + name: bodyshops + schema: public + type: create_update_permission diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index 35df80b..3ab3d59 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -57,6 +57,8 @@ tables: - role: user permission: columns: + - accepted_ins_co + - shopname - targets filter: associations: diff --git a/src/components/atoms/form-list-move-arrows/form-list-move-arrows.atom.jsx b/src/components/atoms/form-list-move-arrows/form-list-move-arrows.atom.jsx new file mode 100644 index 0000000..5e01d5b --- /dev/null +++ b/src/components/atoms/form-list-move-arrows/form-list-move-arrows.atom.jsx @@ -0,0 +1,22 @@ +import React from "react"; +import { UpOutlined, DownOutlined } from "@ant-design/icons"; + +export default function FormListMoveArrows({ move, index, total }) { + const upDisabled = index === 0; + const downDisabled = index === total - 1; + + const handleUp = () => { + move(index, index - 1); + }; + + const handleDown = () => { + move(index, index - 1); + }; + + return ( +
+ + +
+ ); +} diff --git a/src/components/atoms/layout-form-row/layout-form-row.atom.jsx b/src/components/atoms/layout-form-row/layout-form-row.atom.jsx new file mode 100644 index 0000000..94b1b1a --- /dev/null +++ b/src/components/atoms/layout-form-row/layout-form-row.atom.jsx @@ -0,0 +1,60 @@ +import React from "react"; +import { Row, Col, Typography } from "antd"; +import "./layout-form-row.styles.scss"; + +export default function LayoutFormRow({ + header, + children, + grow = false, + ...restProps +}) { + if (!!!children.length) { + //We have only one element. It's going to get the whole thing. + return ( +
+ {header ? ( + {header} + ) : null} + {children} +
+ ); + } + const rowGutter = { gutter: [16, 16] }; + + const colSpan = (spanOverride) => { + if (spanOverride) return { span: spanOverride }; + return { + xs: { + span: !grow ? 24 : Math.max(12, 24 / children.length), + }, + sm: { + span: !grow ? 12 : Math.max(12, 24 / children.length), + }, + md: { + span: !grow ? 8 : Math.max(8, 24 / children.length), + }, + lg: { + span: !grow ? 6 : Math.max(6, 24 / children.length), + }, + xl: { + span: !grow ? 4 : Math.max(4, 24 / children.length), + }, + }; + }; + + return ( +
+ {header ? {header} : null} + + {children.map( + (c, idx) => + c && ( + + {c} + + ) + )} + +
+ ); +} diff --git a/src/components/atoms/layout-form-row/layout-form-row.styles.scss b/src/components/atoms/layout-form-row/layout-form-row.styles.scss new file mode 100644 index 0000000..faf24cc --- /dev/null +++ b/src/components/atoms/layout-form-row/layout-form-row.styles.scss @@ -0,0 +1,20 @@ +//Override Antd Row margin to save space on forms. +.imex-form-row { + .ant-row { + margin-bottom: 0rem; + + .ant-form-item-label { + padding: 0rem; + } + + label { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; + display: inline-block; + padding: 0rem; + margin: 0rem; + } + } +} diff --git a/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx b/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx index 0225585..7d9655b 100644 --- a/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx +++ b/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx @@ -18,7 +18,7 @@ export function PriceDiffPcFormatterAtom({ v_age, }) { const metTarget = useMemo(() => { - const targetsForGroup = bodyshop.targets[group]; + const targetsForGroup = bodyshop.targets.filter((t) => t.group === group); if (!targetsForGroup) return 0; const targetPc = targetsForGroup.filter( (t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true) diff --git a/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx b/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx index 41ad786..1bf467e 100644 --- a/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx +++ b/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx @@ -13,7 +13,7 @@ const mapDispatchToProps = (dispatch) => ({ export function PriceDiffPcFormatterAtom({ bodyshop, group, v_age }) { const metTarget = useMemo(() => { - const targetsForGroup = bodyshop.targets[group]; + const targetsForGroup = bodyshop.targets.filter((t) => t.group === group); if (!targetsForGroup) return 0; const targetPc = targetsForGroup.filter( (t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true) diff --git a/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx b/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx new file mode 100644 index 0000000..d900058 --- /dev/null +++ b/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx @@ -0,0 +1,127 @@ +import { Button, Input, Form, Select, InputNumber } from "antd"; +import FormListMoveArrows from "../../atoms/form-list-move-arrows/form-list-move-arrows.atom"; +import React from "react"; +import LayoutFormRow from "../../atoms/layout-form-row/layout-form-row.atom"; +import { DeleteFilled } from "@ant-design/icons"; + +export default function ShopSettingsFormMolecule({ form, saveLoading }) { + return ( +
+ + + + + + + + + + + + + + + + + + + +
+ { + remove(field.name); + }} + /> + +
+ + + ))} + + + +
+ ); + }} + + + ); +} diff --git a/src/components/organisms/shop-settings/shop-settings.organism.jsx b/src/components/organisms/shop-settings/shop-settings.organism.jsx new file mode 100644 index 0000000..981ef37 --- /dev/null +++ b/src/components/organisms/shop-settings/shop-settings.organism.jsx @@ -0,0 +1,72 @@ +import { useMutation, useQuery } from "@apollo/client"; +import { Form, notification, Skeleton } from "antd"; +import React, { useEffect, useState } from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { QUERY_BODYSHOP, UPDATE_SHOP } from "../../../graphql/bodyshop.queries"; +import { setBodyshop } from "../../../redux/user/user.actions"; +import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; +import ShopSettingsFormMolecule from "../../molecules/shop-settings-form/shop-settings-form.molecule"; + +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) + setBodyshop: (shop) => dispatch(setBodyshop(shop)), +}); +export default connect( + mapStateToProps, + mapDispatchToProps +)(ShopSettingsOrganism); + +export function ShopSettingsOrganism({ setBodyshop }) { + const { loading, error, data } = useQuery(QUERY_BODYSHOP); + const [form] = Form.useForm(); + const [updateBodyshop] = useMutation(UPDATE_SHOP); + const [saveLoading, setSaveLoading] = useState(false); + + useEffect(() => { + if (data) form.resetFields(); + }, [form, data]); + + const handleFinish = async (values) => { + setSaveLoading(true); + + const result = await updateBodyshop({ + variables: { id: data.bodyshops[0].id, shop: values }, + }); + + if (!result.errors) { + notification["success"]({ message: "Settings saved successfully." }); + // console.log("r", result.data.update_bodyshops.returning[0]); + setBodyshop(result.data.update_bodyshops.returning[0]); + form.resetFields(); + } else { + notification["error"]({ + message: "Error while saving settings " + error, + }); + } + setSaveLoading(false); + }; + + return ( +
+
+ {loading && } + {error && } + + +
+ ); +} diff --git a/src/components/pages/settings/settings.page.jsx b/src/components/pages/settings/settings.page.jsx index 2f2c555..8045b72 100644 --- a/src/components/pages/settings/settings.page.jsx +++ b/src/components/pages/settings/settings.page.jsx @@ -1,11 +1,13 @@ import React from "react"; import FilePathsListOrganism from "../../organisms/filepaths-list/filepaths-list.organism"; +import ShopSettingsOrganism from "../../organisms/shop-settings/shop-settings.organism"; import WatcherManagerOrganism from "../../organisms/watcher-manager/watcher-manager.organism"; export default function SettingsPage() { return (
+
); } diff --git a/src/graphql/bodyshop.queries.js b/src/graphql/bodyshop.queries.js index 6e69a35..d36e62d 100644 --- a/src/graphql/bodyshop.queries.js +++ b/src/graphql/bodyshop.queries.js @@ -9,3 +9,15 @@ export const QUERY_BODYSHOP = gql` } } `; +export const UPDATE_SHOP = gql` + mutation UPDATE_SHOP($id: uuid, $shop: bodyshops_set_input!) { + update_bodyshops(where: { id: { _eq: $id } }, _set: $shop) { + returning { + id + shopname + targets + accepted_ins_co + } + } + } +`;