- Default sorts!

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-02-20 19:07:23 -05:00
parent 6b7b34ae79
commit 83d702f12b
5 changed files with 59 additions and 14 deletions

View File

@@ -148,3 +148,20 @@ query gendoc_hours_sold_detail_open($starttz: timestamptz!, $endtz: timestamptz!
## Sorters
- Sorters follow the same schema as filters, however, they do not do square bracket wrapping to indicate level hoisting, a filter added on `job.md_status` would be added at the top level, and a filter added on `jobs.joblines.mod_lb_hrs` would be added at the `joblines` level.
- Most of the reports currently do sorting on a template level, this will need to change to actually see the results using the sorters.
### Default Sorters
- A sorter can be given a default object containing a `order` and `direction` key value. This will be used to sort the report if the user does not select any of the sorters themselves.
- The `order` key is the order in which the sorters are applied, and the `direction` key is the direction of the sort, either `asc` or `desc`.
```json
{
"name": "jobs.joblines.mod_lb_hrs",
"translation": "jobs.joblines.mod_lb_hrs_1",
"label": "mod_lb_hrs_1",
"type": "number",
"default": {
"order": 1,
"direction": "asc"
}
}
```

View File

@@ -304,14 +304,29 @@ function RenderFilters({templateId, form, bodyshop}) {
// Reset all the filters and Sorters.
form.resetFields(['filters']);
form.resetFields(['sorters']);
form.resetFields(['defaultSorters']);
setIsLoading(true);
const data = await fetchFilterData({name: templateId});
// We have Success
if (data?.success) {
if (data?.data?.sorters && data?.data?.sorters.length > 0) {
const defaultSorters = data?.data?.sorters.filter((sorter) => sorter.hasOwnProperty('default')).map((sorter) => {
return {
field: sorter.name,
direction: sorter.default.direction
};
}).sort((a, b) => a.default.order - b.default.order);
form.setFieldValue('defaultSorters', JSON.stringify(defaultSorters));
}
// Set the state
setState(data.data);
} else {
}
// Something went wrong fetching filter data
else {
setState(null);
}
setIsLoading(false);

View File

@@ -16,7 +16,7 @@ import EmployeeSearchSelect from "../employee-search-select/employee-search-sele
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
import "./report-center-modal.styles.scss";
import ReportCenterModalFiltersSortersComponent from "./report-center-modal-filters-sorters-component";
import {selectBodyshop } from "../../redux/user/user.selectors";
import {selectBodyshop} from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
reportCenterModal: selectReportCenter,
@@ -66,22 +66,28 @@ export function ReportCenterModalComponent({reportCenterModal, bodyshop}) {
const end = values.dates ? values.dates[1] : null;
const { id } = values;
await GenerateDocument(
{
const templateConfig = {
name: values.key,
variables: {
...(start
? { start: moment(start).startOf("day").format("YYYY-MM-DD") }
: {}),
...(end ? { end: moment(end).endOf("day").format("YYYY-MM-DD") } : {}),
...(start ? { starttz: moment(start).startOf("day") } : {}),
...(end ? { endtz: moment(end).endOf("day") } : {}),
...(start
? {start: moment(start).startOf("day").format("YYYY-MM-DD")}
: {}),
...(end ? {end: moment(end).endOf("day").format("YYYY-MM-DD")} : {}),
...(start ? {starttz: moment(start).startOf("day")} : {}),
...(end ? {endtz: moment(end).endOf("day")} : {}),
...(id ? { id: id } : {}),
...(id ? {id: id} : {}),
},
filters: values.filters,
sorters: values.sorters,
},
};
if (_.isString(values.defaultSorters) && !_.isEmpty(values.defaultSorters)) {
templateConfig.defaultSorters = JSON.parse(values.defaultSorters);
}
await GenerateDocument(
templateConfig,
{
to: values.to,
subject: Templates[values.key]?.subject,
@@ -119,7 +125,8 @@ export function ReportCenterModalComponent({reportCenterModal, bodyshop}) {
onChange={(e) => setSearch(e.target.value)}
value={search}
/>
<Form.Item
<Form.Item name="defaultSorters" hidden/>
<Form.Item
name="key"
label={t("reportcenter.labels.key")}
// className="radio-group-columns"

View File

@@ -77,6 +77,7 @@ export default async function RenderTemplate(
bodyshop: bodyshop,
filters: templateObject?.filters,
sorters: templateObject?.sorters,
defaultSorters: templateObject?.defaultSorters,
offset: bodyshop.timezone, //dayjs().utcOffset(),
},
};
@@ -406,9 +407,12 @@ const fetchContextData = async (templateObject, jsrAuth) => {
// console.log('Unmodified Query');
// console.dir(templateQueryToExecute);
const hasFilters = templateObject?.filters?.length > 0;
const hasSorters = templateObject?.sorters?.length > 0;
const hasDefaultSorters = templateObject?.defaultSorters?.length > 0;
// We have no template filters or sorters, so we can just execute the query and return the data
if (!(templateObject?.filters?.length || templateObject?.sorters?.length)) {
if (!hasFilters && !hasSorters && !hasDefaultSorters) {
let contextData = {};
if (templateQueryToExecute) {
const {data} = await client.query({

View File

@@ -87,6 +87,8 @@ export async function generateTemplate(templateQueryToExecute, templateObject, u
if (templateObject?.sorters && templateObject?.sorters?.length) {
applySorters(ast, templateObject.sorters);
} else if (templateObject?.defaultSorters && templateObject?.defaultSorters?.length) {
applySorters(ast, templateObject.defaultSorters);
}
const finalQuery = printQuery(ast);