diff --git a/client/src/components/alert/alert.component.jsx b/client/src/components/alert/alert.component.jsx
index e620c862b..5ba4768a9 100644
--- a/client/src/components/alert/alert.component.jsx
+++ b/client/src/components/alert/alert.component.jsx
@@ -2,6 +2,6 @@ import { Alert } from "antd";
import React from "react";
-export default function AlertComponent({ props }) {
+export default function AlertComponent(props) {
return ;
}
diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx
index 74fc26e47..e54eeb34d 100644
--- a/client/src/components/header/header.component.jsx
+++ b/client/src/components/header/header.component.jsx
@@ -3,50 +3,17 @@ import { Link } from "react-router-dom";
import { Menu, Icon } from "antd";
import "./header.styles.scss";
import SignOut from "../sign-out/sign-out.component";
-import { useQuery } from "react-apollo";
-import {
- GET_LANDING_NAV_ITEMS,
- GET_NAV_ITEMS
-} from "../../graphql/metadata.queries";
-import { GET_CURRENT_SELECTED_NAV_ITEM } from "../../graphql/local.queries";
-import LoadingSpinner from "../loading-spinner/loading-spinner.component";
-import AlertComponent from "../alert/alert.component";
import ManageSignInButton from "../manage-sign-in-button/manage-sign-in-button.component";
import { useApolloClient } from "@apollo/react-hooks";
import GlobalSearch from "../global-search/global-search.component";
-export default ({ landingHeader, signedIn }) => {
+export default ({ landingHeader, navItems, selectedNavItem }) => {
const apolloClient = useApolloClient();
- const hookSelectedNavItem = useQuery(GET_CURRENT_SELECTED_NAV_ITEM);
-
- let hookNavItems;
- if (landingHeader) {
- hookNavItems = useQuery(GET_LANDING_NAV_ITEMS, {
- fetchPolicy: "network-only"
- });
- } else {
- hookNavItems = useQuery(GET_NAV_ITEMS, {
- fetchPolicy: "network-only"
- });
- }
const handleClick = e => {
apolloClient.writeData({ data: { selectedNavItem: e.key } });
};
- if (hookNavItems.loading || hookSelectedNavItem.loading)
- return ;
- if (hookNavItems.error)
- return ;
- if (hookSelectedNavItem.error)
- return console.log(
- "Unable to load Selected Navigation Item.",
- hookSelectedNavItem.error
- );
-
- const { selectedNavItem } = hookSelectedNavItem.data;
- const navItems = JSON.parse(hookNavItems.data.masterdata_by_pk.value);
-
return (
+ );
+}
+
+export default Form.create({ name: "JobTombstone" })(JobTombstone);
diff --git a/client/src/components/jobs-list/jobs-list.component.jsx b/client/src/components/jobs-list/jobs-list.component.jsx
new file mode 100644
index 000000000..5730aa159
--- /dev/null
+++ b/client/src/components/jobs-list/jobs-list.component.jsx
@@ -0,0 +1,95 @@
+import React, { useState } from "react";
+import { Link } from "react-router-dom";
+import { Table, Divider, Icon } from "antd";
+import { alphaSort } from "../../utils/sorters";
+
+export default function JobsPage({ loading, jobs }) {
+ const [sortedInfo, setSortedInfo] = useState({});
+
+ const columns = [
+ {
+ title: "RO #",
+ dataIndex: "ro_number",
+ key: "ro_number",
+ sorter: (a, b) => alphaSort(a, b),
+ sortOrder: sortedInfo.columnKey === "ro_number" && sortedInfo.order,
+ ellipsis: true,
+ render: (text, record) => (
+
+ {record.ro_number}
+
+ )
+ },
+ {
+ title: "Est. #",
+ dataIndex: "est_number",
+ key: "est_number"
+ },
+ {
+ title: "Status",
+ dataIndex: "status",
+ key: "status",
+ sorter: (a, b) => alphaSort(a, b),
+ sortOrder: sortedInfo.columnKey === "status" && sortedInfo.order,
+ ellipsis: true
+ },
+ {
+ title: "Customer",
+ dataIndex: "customer",
+ key: "customer",
+ render: (text, record) => {
+ return record.owner ? (
+
+ {record.owner.first_name} {record.owner.last_name}
+
+ ) : (
+ "No Customer"
+ );
+ }
+ },
+ {
+ title: "Vehicle",
+ dataIndex: "vehicle",
+ key: "vehicle",
+ render: (text, record) => {
+ return record.vehicle ? (
+
+ {record.vehicle.v_model_yr} {record.vehicle.v_make_desc}{" "}
+ {record.vehicle.v_model_desc}
+
+ ) : (
+ "No Vehicle"
+ );
+ }
+ },
+ {
+ title: "Action",
+ key: "action",
+ render: (text, record) => (
+
+ Action 一 {record.ro_number}
+
+
+ More actions
+
+ )
+ }
+ ];
+
+ const handleChange = (pagination, filters, sorter) => {
+ setSortedInfo(sorter);
+ };
+
+ return (
+
+
({ ...item }))}
+ rowKey="id"
+ dataSource={jobs}
+ onChange={handleChange}
+ />
+
+ );
+}
diff --git a/client/src/components/with-inline-edit/with-inline-edit.component.jsx b/client/src/components/with-inline-edit/with-inline-edit.component.jsx
new file mode 100644
index 000000000..e995423ff
--- /dev/null
+++ b/client/src/components/with-inline-edit/with-inline-edit.component.jsx
@@ -0,0 +1,45 @@
+import React, { useState } from "react";
+
+export default WithInlineEdit = WrappedComponent => props => {
+ const [editing, setEditing] = useState(false);
+ const [modified, setModified] = useState(false);
+ const [originalValue, setOriginalValue] = useState(null);
+
+ const toggleEdit = () => {
+ setEditing(!editing);
+
+ if (editing) {
+ this.input.focus();
+ }
+ };
+
+ return editing ? (
+
+ {form.getFieldDecorator(dataIndex, {
+ rules: [
+ {
+ required: true,
+ message: `${title} is required.`
+ }
+ ],
+ initialValue: record[dataIndex]
+ })(
+ (this.input = node)}
+ onPressEnter={this.save}
+ onBlur={this.save}
+ />
+ )}
+
+ ) : (
+
+ {children}
+
+ );
+};
+
+export default WithInlineEdit;
diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js
index ed257ad75..60ff26078 100644
--- a/client/src/graphql/jobs.queries.js
+++ b/client/src/graphql/jobs.queries.js
@@ -46,3 +46,60 @@ export const SUBSCRIPTION_ALL_OPEN_JOBS = gql`
}
}
`;
+
+export const GET_JOB_BY_PK = gql`
+ query GET_JOB_BY_PK($id: uuid!) {
+ jobs_by_pk(id: $id) {
+ actual_completion
+ actual_delivery
+ actual_in
+ created_at
+ est_number
+ id
+ local_tax_rate
+ owner {
+ first_name
+ last_name
+ phone
+ }
+ rate_atp
+ rate_la1
+ rate_la2
+ rate_la3
+ rate_la4
+ rate_lab
+ rate_lad
+ rate_lae
+ rate_laf
+ rate_lag
+ rate_lam
+ rate_lar
+ rate_las
+ rate_lau
+ rate_ma2s
+ rate_ma2t
+ rate_mabl
+ rate_ma3s
+ rate_macs
+ rate_mahw
+ rate_mapa
+ rate_mash
+ rate_matd
+ regie_number
+ ro_number
+ scheduled_completion
+ scheduled_in
+ scheduled_delivery
+ status
+ updated_at
+ vehicle {
+ plate_no
+ v_vin
+ v_model_yr
+ v_model_desc
+ v_make_desc
+ v_color
+ }
+ }
+ }
+`;
diff --git a/client/src/pages/jobs-detail/jobs-detail.page.container.jsx b/client/src/pages/jobs-detail/jobs-detail.page.container.jsx
deleted file mode 100644
index 44fff921d..000000000
--- a/client/src/pages/jobs-detail/jobs-detail.page.container.jsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from "react";
-import JobsDetail from "./jobs-detail.page";
-
-export default function JobsDetailPageContainer({ match }) {
- const jobId = match.params.jobId;
- return ;
-}
diff --git a/client/src/pages/jobs-detail/jobs-detail.page.jsx b/client/src/pages/jobs-detail/jobs-detail.page.jsx
index 250195ded..a2ae67989 100644
--- a/client/src/pages/jobs-detail/jobs-detail.page.jsx
+++ b/client/src/pages/jobs-detail/jobs-detail.page.jsx
@@ -1,5 +1,29 @@
import React from "react";
+import { useSubscription } from "@apollo/react-hooks";
+import SpinComponent from "../../components/loading-spinner/loading-spinner.component";
+import AlertComponent from "../../components/alert/alert.component";
+import JobTombstone from "../../components/job-tombstone/job-tombstone.component";
+import { GET_JOB_BY_PK } from "../../graphql/jobs.queries";
+import { Breadcrumb } from "antd";
-export default function JobsDetail({ jobId }) {
- return Jobs Detail Page - Job ID {jobId}
;
+import Test from "./test";
+
+export default function JobsDetailPage({
+ match: { routes, params, children }
+}) {
+ const { jobId } = params;
+ const { loading, error, data } = useSubscription(GET_JOB_BY_PK, {
+ variables: { id: jobId },
+ fetchPolicy: "network-only"
+ });
+ if (loading) return ;
+ if (error) return ;
+
+ console.log('routes', routes)
+ return (
+
+
+
+
+ );
}
diff --git a/client/src/pages/jobs-detail/test.jsx b/client/src/pages/jobs-detail/test.jsx
new file mode 100644
index 000000000..712a2498c
--- /dev/null
+++ b/client/src/pages/jobs-detail/test.jsx
@@ -0,0 +1,219 @@
+import React from "react";
+import { Table, Input, Button, Popconfirm, Form } from "antd";
+
+const EditableContext = React.createContext();
+
+const EditableRow = ({ form, index, ...props }) => (
+
+
+
+);
+
+const EditableFormRow = Form.create()(EditableRow);
+
+class EditableCell extends React.Component {
+ state = {
+ editing: false
+ };
+
+ toggleEdit = () => {
+ const editing = !this.state.editing;
+ this.setState({ editing }, () => {
+ if (editing) {
+ this.input.focus();
+ }
+ });
+ };
+
+ save = e => {
+ const { record, handleSave } = this.props;
+ this.form.validateFields((error, values) => {
+ if (error && error[e.currentTarget.id]) {
+ return;
+ }
+ this.toggleEdit();
+ handleSave({ ...record, ...values });
+ });
+ };
+
+ renderCell = form => {
+ this.form = form;
+ const { children, dataIndex, record, title } = this.props;
+ const { editing } = this.state;
+ return editing ? (
+
+ {form.getFieldDecorator(dataIndex, {
+ rules: [
+ {
+ required: true,
+ message: `${title} is required.`
+ }
+ ],
+ initialValue: record[dataIndex]
+ })(
+ (this.input = node)}
+ onPressEnter={this.save}
+ onBlur={this.save}
+ />
+ )}
+
+ ) : (
+
+ {children}
+
+ );
+ };
+
+ render() {
+ const {
+ editable,
+ dataIndex,
+ title,
+ record,
+ index,
+ handleSave,
+ children,
+ ...restProps
+ } = this.props;
+ return (
+
+ {editable ? (
+ {this.renderCell}
+ ) : (
+ children
+ )}
+ |
+ );
+ }
+}
+
+export default class EditableTable extends React.Component {
+ constructor(props) {
+ super(props);
+ this.columns = [
+ {
+ title: "name",
+ dataIndex: "name",
+ width: "30%",
+ editable: true
+ },
+ {
+ title: "age",
+ dataIndex: "age"
+ },
+ {
+ title: "address",
+ dataIndex: "address"
+ },
+ {
+ title: "operation",
+ dataIndex: "operation",
+ render: (text, record) =>
+ this.state.dataSource.length >= 1 ? (
+ this.handleDelete(record.key)}
+ >
+ Delete
+
+ ) : null
+ }
+ ];
+
+ this.state = {
+ dataSource: [
+ {
+ key: "0",
+ name: "Edward King 0",
+ age: "32",
+ address: "London, Park Lane no. 0"
+ },
+ {
+ key: "1",
+ name: "Edward King 1",
+ age: "32",
+ address: "London, Park Lane no. 1"
+ }
+ ],
+ count: 2
+ };
+ }
+
+ handleDelete = key => {
+ const dataSource = [...this.state.dataSource];
+ this.setState({ dataSource: dataSource.filter(item => item.key !== key) });
+ };
+
+ handleAdd = () => {
+ const { count, dataSource } = this.state;
+ const newData = {
+ key: count,
+ name: `Edward King ${count}`,
+ age: 32,
+ address: `London, Park Lane no. ${count}`
+ };
+ this.setState({
+ dataSource: [...dataSource, newData],
+ count: count + 1
+ });
+ };
+
+ handleSave = row => {
+ const newData = [...this.state.dataSource];
+ const index = newData.findIndex(item => row.key === item.key);
+ const item = newData[index];
+ newData.splice(index, 1, {
+ ...item,
+ ...row
+ });
+ this.setState({ dataSource: newData });
+ };
+
+ render() {
+ const { dataSource } = this.state;
+ const components = {
+ body: {
+ row: EditableFormRow,
+ cell: EditableCell
+ }
+ };
+ const columns = this.columns.map(col => {
+ if (!col.editable) {
+ return col;
+ }
+ return {
+ ...col,
+ onCell: record => ({
+ record,
+ editable: col.editable,
+ dataIndex: col.dataIndex,
+ title: col.title,
+ handleSave: this.handleSave
+ })
+ };
+ });
+ return (
+
+
+
"editable-row"}
+ bordered
+ dataSource={dataSource}
+ columns={columns}
+ />
+
+ );
+ }
+}
diff --git a/client/src/pages/jobs/jobs.page.jsx b/client/src/pages/jobs/jobs.page.jsx
index 1134c8e22..833caa942 100644
--- a/client/src/pages/jobs/jobs.page.jsx
+++ b/client/src/pages/jobs/jobs.page.jsx
@@ -1,106 +1,17 @@
-import React, { useState } from "react";
+import React from "react";
import { useSubscription } from "@apollo/react-hooks";
import AlertComponent from "../../components/alert/alert.component";
-//import { GET_ALL_OPEN_JOBS } from "../../graphql/jobs.queries";
-import { Table, Divider, Icon } from "antd";
-import { alphaSort } from "../../utils/sorters";
import { SUBSCRIPTION_ALL_OPEN_JOBS } from "../../graphql/jobs.queries";
-//import { columns } from "./jobs.page.metadata";
+
+import JobsList from "../../components/jobs-list/jobs-list.component";
export default function JobsPage() {
- const [sortedInfo, setSortedInfo] = useState({});
-
const { loading, error, data } = useSubscription(SUBSCRIPTION_ALL_OPEN_JOBS, {
fetchPolicy: "network-only"
});
- const columns = [
- {
- title: "RO #",
- dataIndex: "ro_number",
- key: "ro_number",
- sorter: (a, b) => alphaSort(a, b),
- sortOrder: sortedInfo.columnKey === "ro_number" && sortedInfo.order,
- ellipsis: true
- },
- {
- title: "Est. #",
- dataIndex: "est_number",
- key: "est_number"
- },
- {
- title: "Status",
- dataIndex: "status",
- key: "status",
- sorter: (a, b) => alphaSort(a, b),
- sortOrder: sortedInfo.columnKey === "status" && sortedInfo.order,
- ellipsis: true
- },
- {
- title: "Customer",
- dataIndex: "customer",
- key: "customer",
- render: (text, record) => {
- return record.owner ? (
-
- {record.owner.first_name} {record.owner.last_name}
-
- ) : (
- "No Customer"
- );
- }
- },
- {
- title: "Vehicle",
- dataIndex: "vehicle",
- key: "vehicle",
- render: (text, record) => {
- return record.vehicle ? (
-
- {record.vehicle.v_model_yr} {record.vehicle.v_make_desc}{" "}
- {record.vehicle.v_model_desc}
-
- ) : (
- "No Vehicle"
- );
- }
- },
- {
- title: "Action",
- key: "action",
- render: (text, record) => (
-
- Action 一 {record.ro_number}
-
-
- More actions
-
- )
- }
- ];
-
- const handleChange = (pagination, filters, sorter) => {
- console.log("Various parameters", pagination, filters, sorter);
- // this.setState({
- // filteredInfo: filters,
- // sortedInfo: sorter,
- // });
- setSortedInfo(sorter);
- };
-
if (error) return ;
- return (
-
-
({ ...item }))}
- rowKey="id"
- dataSource={data ? data.jobs : null}
- onChange={handleChange}
- />
-
- );
+ return ;
}
diff --git a/client/src/pages/jobs/jobs.page.metadata.jsx b/client/src/pages/jobs/jobs.page.metadata.jsx
deleted file mode 100644
index cc5886629..000000000
--- a/client/src/pages/jobs/jobs.page.metadata.jsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import React from "react";
-import { Divider, Icon } from "antd";
-
-export const columns = [
- {
- title: "RO #",
- dataIndex: "ro_number",
- key: "ro_number",
- sorter: (a, b) => a.ro_number > b.ro_number,
- sortOrder: sortedInfo.columnKey === "ro_number" && sortedInfo.order,
- ellipsis: true
- },
- {
- title: "Est. #",
- dataIndex: "est_number",
- key: "est_number"
- },
- {
- title: "Status",
- dataIndex: "status",
- key: "status"
- },
- {
- title: "Customer",
- dataIndex: "customer",
- key: "customer",
- render: (text, record) => {
- return record.owner ? (
-
- {record.owner.first_name} {record.owner.last_name}
-
- ) : (
- "No Customer"
- );
- }
- },
- {
- title: "Vehicle",
- dataIndex: "vehicle",
- key: "vehicle",
- render: (text, record) => {
- return record.vehicle ? (
-
- {record.vehicle.v_model_yr} {record.vehicle.v_make_desc}{" "}
- {record.vehicle.v_model_desc}
-
- ) : (
- "No Vehicle"
- );
- }
- },
- {
- title: "Action",
- key: "action",
- render: (text, record) => (
-
- Action 一 {record.ro_number}
-
-
- More actions
-
- )
- }
-];
diff --git a/client/src/pages/landing/landing.page.jsx b/client/src/pages/landing/landing.page.jsx
index 4208fce4c..b9363db1a 100644
--- a/client/src/pages/landing/landing.page.jsx
+++ b/client/src/pages/landing/landing.page.jsx
@@ -1,16 +1,13 @@
import React from "react";
import { Typography } from "antd";
-import HeaderComponent from "../../components/header/header.component";
+import HeaderContainer from "../../components/header/header.container";
export default function LandingPage() {
return (
-
-
- Welcome to bodyshop.app.
-
+
+ Welcome to bodyshop.app.
);
}
-
diff --git a/client/src/pages/manage/manage.page.jsx b/client/src/pages/manage/manage.page.jsx
index d8038ed46..b4cf8133e 100644
--- a/client/src/pages/manage/manage.page.jsx
+++ b/client/src/pages/manage/manage.page.jsx
@@ -4,11 +4,11 @@ import { Route } from "react-router";
//Component Imports
import WhiteBoardPage from "../white-board/white-board.page";
import JobsPage from "../jobs/jobs.page";
-import JobsDetailPageContainer from "../jobs-detail/jobs-detail.page.container";
-import HeaderComponent from "../../components/header/header.component";
+import JobsDetailPage from "../jobs-detail/jobs-detail.page";
+import HeaderContainer from "../../components/header/header.container";
import FooterComponent from "../../components/footer/footer.component";
-import { Layout } from "antd";
+import { Layout, BackTop } from "antd";
const { Header, Content, Footer } = Layout;
//This page will handle all routing for the entire application.
@@ -16,22 +16,20 @@ export default function Manage({ match }) {
return (
-
+
+
);
}