18
.editorconfig
Normal file
18
.editorconfig
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
||||||
@@ -23,7 +23,7 @@ function RenderFilters({ templateId }) {
|
|||||||
const fetch = async () => {
|
const fetch = async () => {
|
||||||
const data = await fetchFilterData({ name: templateId });
|
const data = await fetchFilterData({ name: templateId });
|
||||||
console.log("🚀 ~ fetch ~ data:", data);
|
console.log("🚀 ~ fetch ~ data:", data);
|
||||||
setState(JSON.parse(data));
|
setState(data.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("🚀 ~ useEffect ~ templateId:", templateId);
|
console.log("🚀 ~ useEffect ~ templateId:", templateId);
|
||||||
@@ -79,7 +79,20 @@ function RenderFilters({ templateId }) {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Select />
|
<Select
|
||||||
|
options={[
|
||||||
|
{ value: "_eq", label: "Equals" },
|
||||||
|
{ value: "_ne", label: "Not Equals" },
|
||||||
|
{ value: "_gt", label: "Greater Than" },
|
||||||
|
{ value: "_lt", label: "Less Than" },
|
||||||
|
{ value: "_gte", label: "Greater Than or Equal To" },
|
||||||
|
{ value: "_lte", label: "Less Than or Equal To" },
|
||||||
|
{ value: "_in", label: "In" },
|
||||||
|
{ value: "_nin", label: "Not In" },
|
||||||
|
{ value: "_contains", label: "Contains" },
|
||||||
|
{ value: "_ncontains", label: "Does Not Contain" },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {gql} from "@apollo/client";
|
import {gql} from "@apollo/client";
|
||||||
|
import {parse, print, visit, Kind} from "graphql";
|
||||||
import jsreport from "@jsreport/browser-client";
|
import jsreport from "@jsreport/browser-client";
|
||||||
import {notification} from "antd";
|
import {notification} from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@@ -16,6 +17,120 @@ jsreport.serverUrl = server;
|
|||||||
|
|
||||||
const Templates = TemplateList();
|
const Templates = TemplateList();
|
||||||
|
|
||||||
|
|
||||||
|
function applyFilters(ast, filters) {
|
||||||
|
const struct = filters.field.split('.');
|
||||||
|
|
||||||
|
return visit(ast, {
|
||||||
|
OperationDefinition: {
|
||||||
|
enter(node) {
|
||||||
|
// Traverse through the operation definitions to find the correct query and its arguments
|
||||||
|
node.selectionSet.selections.forEach((selection) => {
|
||||||
|
if (selection.name.value ===struct[0]) {
|
||||||
|
// Find the existing 'where' argument, if it exists
|
||||||
|
let whereArg = selection.arguments.find(arg => arg.name.value === 'where');
|
||||||
|
|
||||||
|
if (!whereArg) {
|
||||||
|
// If 'where' argument doesn't exist, create it with an _and structure
|
||||||
|
whereArg = {
|
||||||
|
kind: Kind.ARGUMENT,
|
||||||
|
name: { kind: Kind.NAME, value: 'where' },
|
||||||
|
value: {
|
||||||
|
kind: Kind.OBJECT,
|
||||||
|
fields: [{
|
||||||
|
kind: Kind.OBJECT_FIELD,
|
||||||
|
name: { kind: Kind.NAME, value: '_and' },
|
||||||
|
value: { kind: Kind.LIST, values: [] } // Initialize an empty list for '_and' conditions
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
selection.arguments.push(whereArg); // Add 'where' argument to the 'jobs' field
|
||||||
|
} else {
|
||||||
|
// Ensure the _and structure exists if the where argument already exists
|
||||||
|
let andField = whereArg.value.fields.find(field => field.name.value === '_and');
|
||||||
|
if (!andField) {
|
||||||
|
andField = {
|
||||||
|
kind: Kind.OBJECT_FIELD,
|
||||||
|
name: { kind: Kind.NAME, value: '_and' },
|
||||||
|
value: { kind: Kind.LIST, values: [] }
|
||||||
|
};
|
||||||
|
whereArg.value.fields.push(andField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the filter condition to be added to the _and list
|
||||||
|
const filterConditions = filters.map(filter => ({
|
||||||
|
kind: Kind.OBJECT,
|
||||||
|
fields: [{
|
||||||
|
kind: Kind.OBJECT_FIELD,
|
||||||
|
name: { kind: Kind.NAME, value: struct[1] },
|
||||||
|
value: {
|
||||||
|
kind: Kind.OBJECT,
|
||||||
|
fields: [{
|
||||||
|
kind: Kind.OBJECT_FIELD,
|
||||||
|
name: { kind: Kind.NAME, value: filter.operator }, // Adjust based on filter.operator if necessary
|
||||||
|
value: { kind: Kind.STRING, value: filter.value } // Adjust based on the type of filter.value
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Locate the _and field and add the filter conditions
|
||||||
|
const andField = whereArg.value.fields.find(field => field.name.value === '_and');
|
||||||
|
andField.value.values.push(...filterConditions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// function applyFilters(ast, filters) {
|
||||||
|
// return filters.reduce((modifiedAst, filter) => {
|
||||||
|
// const struct = filter.field.split('.');
|
||||||
|
//
|
||||||
|
// return visit(modifiedAst, {
|
||||||
|
// OperationDefinition: {
|
||||||
|
// enter(node) {
|
||||||
|
// // Traverse through the operation definitions to find the correct query and its arguments
|
||||||
|
// node.selectionSet.selections.forEach((selection) => {
|
||||||
|
// if (selection.name.value === struct[0]) {
|
||||||
|
// // Find the existing 'where' argument, if it exists
|
||||||
|
// let whereArg = selection.arguments.find(arg => arg.name.value === 'where');
|
||||||
|
//
|
||||||
|
// if (!whereArg) {
|
||||||
|
// // If 'where' argument doesn't exist, create it
|
||||||
|
// whereArg = {
|
||||||
|
// kind: Kind.ARGUMENT,
|
||||||
|
// name: { kind: Kind.NAME, value: 'where' },
|
||||||
|
// value: { kind: Kind.OBJECT, fields: [] } // Initialize an empty object for 'where' clause
|
||||||
|
// };
|
||||||
|
// selection.arguments.push(whereArg); // Add 'where' argument to the 'jobs' field
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Assuming the filter should be added to the 'where' clause
|
||||||
|
// const filterField = {
|
||||||
|
// kind: Kind.OBJECT_FIELD,
|
||||||
|
// name: { kind: Kind.NAME, value: struct[1] },
|
||||||
|
// value: {
|
||||||
|
// kind: Kind.OBJECT,
|
||||||
|
// fields: [{
|
||||||
|
// kind: Kind.OBJECT_FIELD,
|
||||||
|
// name: { kind: Kind.NAME, value: filter.operator }, // Assuming equality operator; adjust as necessary
|
||||||
|
// value: { kind: Kind.STRING, value: filter.value }
|
||||||
|
// }]
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// // Add the filter to the 'where' argument's value
|
||||||
|
// whereArg.value.fields.push(filterField);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }, ast);
|
||||||
|
// }
|
||||||
export default async function RenderTemplate(
|
export default async function RenderTemplate(
|
||||||
templateObject,
|
templateObject,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
@@ -23,6 +138,7 @@ export default async function RenderTemplate(
|
|||||||
renderAsExcel = false,
|
renderAsExcel = false,
|
||||||
renderAsText = false
|
renderAsText = false
|
||||||
) {
|
) {
|
||||||
|
console.log(' RENDER TEMPLATE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
||||||
if (window.jsr3) {
|
if (window.jsr3) {
|
||||||
jsreport.serverUrl = "https://reports3.test.imex.online/";
|
jsreport.serverUrl = "https://reports3.test.imex.online/";
|
||||||
}
|
}
|
||||||
@@ -147,6 +263,7 @@ export async function RenderTemplates(
|
|||||||
templateObjects.forEach((template) => {
|
templateObjects.forEach((template) => {
|
||||||
proms.push(
|
proms.push(
|
||||||
(async () => {
|
(async () => {
|
||||||
|
console.log(' RENDER TEMPLATE 2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
||||||
let {contextData, useShopSpecificTemplate} = await fetchContextData(
|
let {contextData, useShopSpecificTemplate} = await fetchContextData(
|
||||||
template,
|
template,
|
||||||
jsrAuth
|
jsrAuth
|
||||||
@@ -306,49 +423,50 @@ export const GenerateDocuments = async (templates) => {
|
|||||||
await RenderTemplates(templates, bodyshop);
|
await RenderTemplates(templates, bodyshop);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchFilterData = async ({ name }) => {
|
export const fetchFilterData = async ({name}) => {
|
||||||
const bodyshop = store.getState().user.bodyshop;
|
const bodyshop = store.getState().user.bodyshop;
|
||||||
const jsrAuth = (await axios.post("/utils/jsr")).data;
|
const jsrAuth = (await axios.post("/utils/jsr")).data;
|
||||||
jsreport.headers["FirebaseAuthorization"] =
|
jsreport.headers["FirebaseAuthorization"] =
|
||||||
"Bearer " + (await auth.currentUser.getIdToken());
|
"Bearer " + (await auth.currentUser.getIdToken());
|
||||||
|
|
||||||
const folders = await cleanAxios.get(`${server}/odata/folders`, {
|
const folders = await cleanAxios.get(`${server}/odata/folders`, {
|
||||||
headers: { Authorization: jsrAuth },
|
headers: {Authorization: jsrAuth},
|
||||||
});
|
});
|
||||||
const shopSpecificFolder = folders.data.value.find(
|
const shopSpecificFolder = folders.data.value.find(
|
||||||
(f) => f.name === bodyshop.imexshopid
|
(f) => f.name === bodyshop.imexshopid
|
||||||
);
|
|
||||||
|
|
||||||
const jsReportFilters = await cleanAxios.get(
|
|
||||||
`${server}/odata/assets?$filter=name eq '${name}.filters'`,
|
|
||||||
{ headers: { Authorization: jsrAuth } }
|
|
||||||
);
|
|
||||||
console.log("🚀 ~ fetchFilterData ~ jsReportFilters:", jsReportFilters);
|
|
||||||
|
|
||||||
let parsedFilterData;
|
|
||||||
let useShopSpecificTemplate = false;
|
|
||||||
// let shopSpecificTemplate;
|
|
||||||
|
|
||||||
if (shopSpecificFolder) {
|
|
||||||
let shopSpecificTemplate = jsReportFilters.data.value.find(
|
|
||||||
(f) => f?.folder?.shortid === shopSpecificFolder.shortid
|
|
||||||
);
|
);
|
||||||
if (shopSpecificTemplate) {
|
|
||||||
useShopSpecificTemplate = true;
|
const jsReportFilters = await cleanAxios.get(
|
||||||
parsedFilterData = atob(shopSpecificTemplate.content);
|
`${server}/odata/assets?$filter=name eq '${name}.filters'`,
|
||||||
|
{headers: {Authorization: jsrAuth}}
|
||||||
|
);
|
||||||
|
console.log("🚀 ~ fetchFilterData ~ jsReportFilters:", jsReportFilters);
|
||||||
|
|
||||||
|
let parsedFilterData;
|
||||||
|
let useShopSpecificTemplate = false;
|
||||||
|
// let shopSpecificTemplate;
|
||||||
|
|
||||||
|
if (shopSpecificFolder) {
|
||||||
|
let shopSpecificTemplate = jsReportFilters.data.value.find(
|
||||||
|
(f) => f?.folder?.shortid === shopSpecificFolder.shortid
|
||||||
|
);
|
||||||
|
if (shopSpecificTemplate) {
|
||||||
|
useShopSpecificTemplate = true;
|
||||||
|
parsedFilterData = atob(shopSpecificTemplate.content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!parsedFilterData) {
|
if (!parsedFilterData) {
|
||||||
const generalTemplate = jsReportFilters.data.value.find((f) => !f.folder);
|
const generalTemplate = jsReportFilters.data.value.find((f) => !f.folder);
|
||||||
useShopSpecificTemplate = false;
|
useShopSpecificTemplate = false;
|
||||||
if (generalTemplate) parsedFilterData = atob(generalTemplate.content);
|
if (generalTemplate) parsedFilterData = atob(generalTemplate.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsedFilterData;
|
return { data: JSON.parse(parsedFilterData), useShopSpecificTemplate};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchContextData = async (templateObject, jsrAuth) => {
|
const fetchContextData = async (templateObject, jsrAuth) => {
|
||||||
|
console.log(' FETCH CONTEXT DATA !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
||||||
const bodyshop = store.getState().user.bodyshop;
|
const bodyshop = store.getState().user.bodyshop;
|
||||||
|
|
||||||
jsreport.headers["FirebaseAuthorization"] =
|
jsreport.headers["FirebaseAuthorization"] =
|
||||||
@@ -388,11 +506,19 @@ const fetchContextData = async (templateObject, jsrAuth) => {
|
|||||||
|
|
||||||
// TODO: REPORT UPDATE
|
// TODO: REPORT UPDATE
|
||||||
//TemplateQueryToExecute needs to get modified based on sorters/filters set by user from modal.
|
//TemplateQueryToExecute needs to get modified based on sorters/filters set by user from modal.
|
||||||
|
console.log(' RENDER TEMPLATE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
|
||||||
|
console.dir(templateQueryToExecute);
|
||||||
|
console.dir(templateObject);
|
||||||
|
|
||||||
|
|
||||||
|
const ast = applyFilters(parse(templateQueryToExecute), templateObject.filters);
|
||||||
|
const finalQuery = print(ast);
|
||||||
|
console.log(finalQuery);
|
||||||
|
|
||||||
let contextData = {};
|
let contextData = {};
|
||||||
if (templateQueryToExecute) {
|
if (templateQueryToExecute) {
|
||||||
const {data} = await client.query({
|
const {data} = await client.query({
|
||||||
query: gql(templateQueryToExecute),
|
query: gql(finalQuery),
|
||||||
variables: {...templateObject.variables},
|
variables: {...templateObject.variables},
|
||||||
});
|
});
|
||||||
contextData = data;
|
contextData = data;
|
||||||
|
|||||||
Reference in New Issue
Block a user