Added formatting for jobs lists and jobs detail components
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Result } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { QUERY_JOB_BY_PK } from "../../../graphql/jobs.queries";
|
||||
import { selectSelectedJobId } from "../../../redux/application/application.selectors";
|
||||
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
|
||||
import JobsDetailDescriptionMolecule from "../../molecules/jobs-detail-description/jobs-detail-description.molecule";
|
||||
import JobsLinesTableMolecule from "../../molecules/jobs-lines-table/jobs-lines-table.molecule";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
selectedJobId: selectSelectedJobId,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export function JobsDetailOrganism({ selectedJobId }) {
|
||||
const { loading, error, data } = useQuery(QUERY_JOB_BY_PK, {
|
||||
variables: { jobId: selectedJobId },
|
||||
skip: !selectedJobId,
|
||||
});
|
||||
|
||||
if (!selectedJobId) return <Result title="No job selected." />;
|
||||
if (error)
|
||||
return (
|
||||
<ErrorResultAtom
|
||||
title="Error fetching Job details.."
|
||||
errorMessage={JSON.stringify(error)}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<JobsDetailDescriptionMolecule
|
||||
loading={loading}
|
||||
job={data ? data.jobs_by_pk : null}
|
||||
/>
|
||||
<JobsLinesTableMolecule
|
||||
loading={loading}
|
||||
jobLines={data ? data.jobs_by_pk.joblines : []}
|
||||
/>
|
||||
{selectedJobId}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailOrganism);
|
||||
135
src/components/organisms/jobs-table/jobs-table.organism.jsx
Normal file
135
src/components/organisms/jobs-table/jobs-table.organism.jsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { List, Space, Spin, Typography } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import InfiniteScroll from "react-infinite-scroller";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { QUERY_ALL_JOBS_PAGINATED } from "../../../graphql/jobs.queries";
|
||||
import { setSelectedJobId } from "../../../redux/application/application.actions";
|
||||
import { selectSelectedJobId } from "../../../redux/application/application.selectors";
|
||||
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
|
||||
import TimeAgoFormatter from "../../atoms/time-ago-formatter/time-ago-formatter.atom";
|
||||
import "./jobs-table.organism.styles.scss";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
selectedJobId: selectSelectedJobId,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setSelectedJobId: (jobId) => dispatch(setSelectedJobId(jobId)),
|
||||
});
|
||||
|
||||
const limit = 20;
|
||||
export function JobsTableOrganism({ selectedJobId, setSelectedJobId }) {
|
||||
const [state, setState] = useState({ hasMore: true });
|
||||
|
||||
const { loading, error, data, fetchMore } = useQuery(
|
||||
QUERY_ALL_JOBS_PAGINATED,
|
||||
{
|
||||
variables: {
|
||||
offset: 0,
|
||||
limit: limit,
|
||||
order: [{ updated_at: "desc" }],
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const handleInfiniteOnLoad = (page) => {
|
||||
fetchMore({
|
||||
variables: {
|
||||
offset: limit * page,
|
||||
},
|
||||
updateQuery: (prev, { fetchMoreResult }) => {
|
||||
if (!fetchMoreResult) {
|
||||
console.log("No more results. Fetch More was empty.");
|
||||
setState({ ...state, hasMore: false });
|
||||
return prev;
|
||||
}
|
||||
|
||||
const newCache = Object.assign({}, prev, {
|
||||
jobs: [...prev.jobs, ...fetchMoreResult.jobs],
|
||||
});
|
||||
|
||||
if (
|
||||
newCache.jobs.length >= data &&
|
||||
data.jobs_aggregate.aggregate.count
|
||||
) {
|
||||
console.log("No more results.");
|
||||
setState({ ...state, hasMore: false });
|
||||
}
|
||||
|
||||
return newCache;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleSelect = (jobId) => {
|
||||
setSelectedJobId(jobId);
|
||||
};
|
||||
|
||||
if (error)
|
||||
return (
|
||||
<ErrorResultAtom
|
||||
title="Error fetching Jobs data."
|
||||
errorMessage={JSON.stringify(error)}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="jobs-list-infinite-container">
|
||||
<InfiniteScroll
|
||||
pageStart={0}
|
||||
loadMore={handleInfiniteOnLoad}
|
||||
hasMore={!loading && state.hasMore}
|
||||
useWindow={false}
|
||||
>
|
||||
<List
|
||||
dataSource={data ? data.jobs : []}
|
||||
renderItem={(item) => (
|
||||
<List.Item
|
||||
className="jobs-list-item"
|
||||
key={item.id}
|
||||
onClick={() => handleSelect(item.id)}
|
||||
>
|
||||
<div
|
||||
className={`jobs-list-item-content ${
|
||||
item.id === selectedJobId
|
||||
? "jobs-list-item-content-selected"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Typography.Title level={4} style={{ flex: 1 }}>
|
||||
{`${item.clm_no}${
|
||||
item.ins_co_nm ? ` | ${item.ins_co_nm}` : ""
|
||||
}`}
|
||||
</Typography.Title>
|
||||
<span className="job-list-last-updated-time">
|
||||
<TimeAgoFormatter>{item.updated_at}</TimeAgoFormatter>
|
||||
</span>
|
||||
</div>
|
||||
<Space>
|
||||
<span>{`${item.ownr_fn} ${item.ownr_ln}`}</span>
|
||||
<span>
|
||||
{`${item.v_model_yr} ${item.v_makedesc} ${item.v_model} ${item.v_vin}`}
|
||||
</span>
|
||||
</Space>
|
||||
</div>
|
||||
</List.Item>
|
||||
)}
|
||||
>
|
||||
{loading && state.hasMore && (
|
||||
<div>
|
||||
<Spin />
|
||||
</div>
|
||||
)}
|
||||
</List>
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
{`${data ? data.jobs.length : 0} jobs loaded. ${
|
||||
data ? data.jobs_aggregate.aggregate.count : 0
|
||||
} total jobs.`}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsTableOrganism);
|
||||
@@ -0,0 +1,26 @@
|
||||
.jobs-list-infinite-container {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
height: 95vh;
|
||||
}
|
||||
|
||||
.jobs-list-item {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
.jobs-list-item-content {
|
||||
&-selected {
|
||||
border-left: 3px solid #1890ff;
|
||||
}
|
||||
|
||||
display: inline;
|
||||
margin: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user