UNPKG

@openinc/parse-server-opendash

Version:
353 lines (352 loc) 12.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.init = init; exports.getTicketMaterial = getTicketMaterial; exports.getTicketSource = getTicketSource; exports.arrayToDistinct = arrayToDistinct; const catchError_1 = require("../helper/catchError"); const types_1 = require("../types"); async function init(name) { Parse.Cloud.define(name, handleRequest, { requireUser: true, }); } async function handleRequest(request) { if (request.user === undefined) { return { success: false, error: "User not found" }; } console.log("openinc-openservice-ticket-data: Handling request with", request.params); try { const queries = []; for await (const config of request.params.config) { let ticketQuery = new Parse.Query(types_1.Maintenance_Ticket) .equalTo("enabled", true) .includeAll(); // apply filters defined in the filterQueryMap depending on the request if (config.filterBy?.filter.length) { const filterQueries = []; for await (const filter of config.filterBy.filter) { const query = new Parse.Query(types_1.Maintenance_Ticket).equalTo("enabled", true); await filterQueryMap[filter.attribute](query, filter.value); filterQueries.push(query); } if (config.filterBy.junction === "or") { ticketQuery = Parse.Query.or(...filterQueries); } else { ticketQuery = Parse.Query.and(...filterQueries); } } queries.push(ticketQuery); } let ticketQuery = request.params.junction === "or" ? Parse.Query.or(...queries) : Parse.Query.and(...queries); if (request.params.config[0].sortBy && request.params.config[0].order) { ticketQuery = ticketQuery.includeAll(); if (request.params.config[0].order === "asc") { ticketQuery = ticketQuery.ascending(request.params.config[0].sortBy); } else { ticketQuery = ticketQuery.descending(request.params.config[0].sortBy); } } // get total count of tickets before applying pagination const totalCount = await ticketQuery.count({ sessionToken: request.user.getSessionToken(), }); if (request.params.config[0].skip !== undefined && request.params.config[0].limit !== undefined) { ticketQuery = ticketQuery .skip(request.params.config[0].skip) .limit(request.params.config[0].limit); } const [ticketError, ticketsResult] = await (0, catchError_1.catchError)(ticketQuery.find({ sessionToken: request.user.getSessionToken() })); if (ticketError) { throw ticketError; } // fetch ticket data for those tickets const ticketData = await getTicketData(ticketsResult); return { success: true, data: ticketData, total: totalCount, }; } catch (error) { console.error("Error while fetching ticket data", error); return { success: false, error: error, }; } } async function getTicketData(tickets) { const ticketDataPromises = tickets.map(async (ticket) => { let assignedusers = []; let assignedroles = []; if (ticket.assignedusers !== undefined) { assignedusers = await ticket.assignedusers .query() .find({ useMasterKey: true }); } if (ticket.assignedroles !== undefined) { assignedroles = await ticket.assignedroles .query() .find({ useMasterKey: true }); } const downtimes = getDowntime(ticket); const duedate = getDueDate(ticket); const frequency = getFrequency(ticket); const restriction = getRestriction(ticket); const issuecategory = getIssueCategory(ticket); const priority = getPriority(ticket); const source = getTicketSource(ticket); const state = getState(ticket); const messages = getMessages(ticket); const material = getTicketMaterial(ticket); const project = (0, catchError_1.catchError)(ticket.get("project")?.fetch({ useMasterKey: true }) ?? new Promise((res) => res(undefined))); const dataPromises = await Promise.all([ downtimes, duedate, frequency, restriction, issuecategory, priority, source, state, messages, material, project, ]); return { ticket: ticket, downtime: dataPromises[0], duedate: dataPromises[1], frequency: dataPromises[2], restriction: dataPromises[3], issuecategory: dataPromises[4]?.get("issuecategory"), priority: dataPromises[5], source: dataPromises[6]?.get("source"), state: dataPromises[7]?.get("state"), messages: dataPromises[8]?.messages, todos: dataPromises[8]?.todos, assignedTo: [...assignedusers, ...assignedroles], material: dataPromises[9], project: dataPromises[10]?.[1], }; }); return await Promise.all(ticketDataPromises); } /** * Fetches the downtime for a ticket * @param ticket * @param ticketIds * @returns */ async function getDowntime(ticket) { return await new Parse.Query(types_1.Maintenance_Downtime) .descending("updatedAt") .equalTo("ticket", ticket) // .containedIn("ticket", ticketIds) // .limit(1_000_000) .first({ useMasterKey: true }); // .filter((downtime) => downtime.get("ticket").id === ticket.id, { // useMasterKey: true, // }); } /** * Fetches the duedate for a ticket * @param ticket * @param ticketIds * @returns */ async function getDueDate(ticket) { return await new Parse.Query(types_1.Maintenance_Duedate) .descending("updatedAt") .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Fetches the frequency for a ticket * @param ticket * @param ticketIds */ async function getFrequency(ticket) { return await new Parse.Query(types_1.Maintenance_Frequency) .descending("updatedAt") .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Fetches the restriction for a ticket * @param ticket * @param ticketIds */ async function getRestriction(ticket) { return await new Parse.Query(types_1.Maintenance_Restriction) .descending("updatedAt") .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Fetches the priority for a ticket * @param ticket * @param ticketIds * @returns */ async function getPriority(ticket) { return await new Parse.Query(types_1.Maintenance_Priority) .descending("updatedAt") .equalTo("ticket", ticket) .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Fetches the state for a ticket * @param ticket * @param ticketIds */ async function getState(ticket) { return await new Parse.Query(types_1.Maintenance_Ticket_Kanban_State_Current) .descending("updatedAt") .includeAll() .matchesQuery("ticket", new Parse.Query(types_1.Maintenance_Ticket).equalTo("objectId", ticket.id)) .first({ useMasterKey: true }); } /** * Fetches the messages for a ticket * @param ticket * @param ticketIds */ async function getMessages(ticket) { const allMessages = await new Parse.Query(types_1.Maintenance_Message) .descending("updatedAt") .equalTo("referencedObjectId", ticket.id) .find({ useMasterKey: true }); const messages = []; const todos = []; for (const msg of allMessages) { if (!msg.data) continue; if (msg.data.type !== "todo") { messages.push(msg); continue; } todos.push(msg); } return { messages, todos }; } /** * Fetches the issuecategory for a ticket * @param ticket * @param ticketIds * @returns */ async function getIssueCategory(ticket) { return await new Parse.Query(types_1.Maintenance_Ticket_Issuecategory) .includeAll() .descending("updatedAt") .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Fetches the material for a ticket * @param ticket */ async function getTicketMaterial(ticket) { return await new Parse.Query(types_1.Maintenance_Ticket_Material) .includeAll() .descending("updatedAt") .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Fetches the source for a ticket * @param ticket */ async function getTicketSource(ticket) { return await new Parse.Query(types_1.Maintenance_Ticket_Source) .includeAll() .descending("updatedAt") .equalTo("ticket", ticket) .first({ useMasterKey: true }); } /** * Used to filter tickets based on the filterBy attribute */ const filterQueryMap = { objectId: async (query, value) => { query.equalTo("objectId", value); }, state: async (query, value) => { const stateQuery = new Parse.Query(types_1.Maintenance_Ticket_Kanban_State_Current).equalTo("state", new types_1.Maintenance_Kanban_State({ objectId: value })); // @ts-ignore query.matchesKeyInQuery("objectId", "ticket.objectId", stateQuery); }, source: async (query, value) => { const allTicketSources = await new Parse.Query(types_1.Maintenance_Ticket_Source) .descending("createdAt") .matchesQuery("ticket", query) .includeAll() .find({ useMasterKey: true }); const filteredTicketSources = arrayToDistinct(allTicketSources, (ts) => ts?.get("ticket")?.id, (ts) => ts?.get("source")?.id === value); // @ts-ignore query.containedIn("objectId", filteredTicketSources.map((ts) => ts.get("ticket")?.id)); }, issuecategory: async (query, value) => { const ticketIssuecategories = await new Parse.Query(types_1.Maintenance_Ticket_Issuecategory) .matchesQuery("ticket", query) .descending("createdAt") .includeAll() .find({ useMasterKey: true }); const filteredTicketIssuecategories = arrayToDistinct(ticketIssuecategories, (tic) => tic.get("ticket")?.id, (tic) => tic.get("issuecategory")?.id === value && tic.get("ticket")?.id !== undefined); // @ts-ignore query.containedIn("objectId", filteredTicketIssuecategories.map((tic) => tic.get("ticket")?.id)); }, user: async (query, value) => { const userQuery = new Parse.Query(Parse.User).equalTo("objectId", value); query.matchesQuery("assignedusers", userQuery); }, role: async (query, value) => { const roleQuery = new Parse.Query(Parse.Role).equalTo("objectId", value); query.include("assignedroles").matchesQuery("assignedroles", roleQuery); }, userRole: async (query, value) => { const userQuery = new Parse.Query(Parse.User).equalTo("objectId", value); const roleQuery = new Parse.Query(Parse.Role) .include("users") .matchesQuery("users", userQuery); query.include("assignedroles").matchesQuery("assignedroles", roleQuery); }, createdUser: async (query, value) => { query.include("user"); query.equalTo("user", new Parse.User({ objectId: value })); }, project: async (query, value) => { query.include("project"); query.equalTo("project", new types_1.Maintenance_Project({ objectId: value })); }, title: async (query, value) => { query.matches("title", new RegExp(value, "i")); // case-insensitive match }, }; /** * Creates a distinct array based on the getId function and can afterwards filter the array * @param arr the array to get distinct values from * @param getId the identifier function to get the id of the item * @param filter the filter function to filter the array afterwards * @returns an array with distinct values based on the getId function */ function arrayToDistinct(arr, getId, filter) { const map = new Map(); arr.forEach((item) => { if (map.has(getId(item))) return; map.set(getId(item), item); }); const array = Array.from(map.values()); return filter ? array.filter(filter) : array; }