@things-factory/worklist 10.1.258 → 10.1.260
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/chip-counts.d.ts +13 -0
- package/dist-client/chip-counts.js +11 -0
- package/dist-client/chip-counts.js.map +1 -1
- package/dist-client/chip-filters.d.ts +29 -0
- package/dist-client/chip-filters.js +17 -1
- package/dist-client/chip-filters.js.map +1 -1
- package/dist-client/pages/approval-progress/approval-progress-page.d.ts +0 -4
- package/dist-client/pages/approval-progress/approval-progress-page.js +37 -31
- package/dist-client/pages/approval-progress/approval-progress-page.js.map +1 -1
- package/dist-client/pages/todo/approval-pending-list-page.d.ts +2 -3
- package/dist-client/pages/todo/approval-pending-list-page.js +33 -47
- package/dist-client/pages/todo/approval-pending-list-page.js.map +1 -1
- package/dist-client/pages/todo/draft-list-page.js +13 -10
- package/dist-client/pages/todo/draft-list-page.js.map +1 -1
- package/dist-client/pages/todo/todo-list-page.d.ts +0 -3
- package/dist-client/pages/todo/todo-list-page.js +30 -42
- package/dist-client/pages/todo/todo-list-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/activity-installation/activity-installation-controller.js +1 -0
- package/dist-server/controllers/activity-installation/activity-installation-controller.js.map +1 -1
- package/dist-server/controllers/activity-installation/installable-to-activity.d.ts +10 -0
- package/dist-server/controllers/activity-installation/installable-to-activity.js +22 -1
- package/dist-server/controllers/activity-installation/installable-to-activity.js.map +1 -1
- package/dist-server/controllers/activity-instance/assign.js +7 -2
- package/dist-server/controllers/activity-instance/assign.js.map +1 -1
- package/dist-server/controllers/activity-instance/complete.d.ts +13 -0
- package/dist-server/controllers/activity-instance/complete.js +58 -0
- package/dist-server/controllers/activity-instance/complete.js.map +1 -0
- package/dist-server/controllers/activity-instance/index.d.ts +1 -0
- package/dist-server/controllers/activity-instance/index.js +1 -0
- package/dist-server/controllers/activity-instance/index.js.map +1 -1
- package/dist-server/service/activity-approval/activity-approval.d.ts +3 -0
- package/dist-server/service/activity-approval/activity-approval.js +8 -0
- package/dist-server/service/activity-approval/activity-approval.js.map +1 -1
- package/dist-server/service/activity-instance/event-subscriber.d.ts +1 -0
- package/dist-server/service/activity-instance/event-subscriber.js +11 -0
- package/dist-server/service/activity-instance/event-subscriber.js.map +1 -1
- package/dist-server/service/approval-notice/approval-notice.js +3 -2
- package/dist-server/service/approval-notice/approval-notice.js.map +1 -1
- package/dist-server/service/approval-progress/approval-progress-query.js +4 -0
- package/dist-server/service/approval-progress/approval-progress-query.js.map +1 -1
- package/dist-server/service/approval-progress/approval-progress-rule.d.ts +4 -0
- package/dist-server/service/approval-progress/approval-progress-rule.js +8 -0
- package/dist-server/service/approval-progress/approval-progress-rule.js.map +1 -1
- package/dist-server/service/approval-progress/approval-progress-type.d.ts +1 -0
- package/dist-server/service/approval-progress/approval-progress-type.js +4 -0
- package/dist-server/service/approval-progress/approval-progress-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/tests/assign-role-pool.test.ts +27 -1
- package/tests/complete-db.test.ts +62 -0
- package/translations/en.json +3 -2
- package/translations/es.json +3 -2
- package/translations/ja.json +3 -2
- package/translations/ko.json +3 -2
- package/translations/ms.json +3 -2
- package/translations/zh.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-progress-query.js","sourceRoot":"","sources":["../../../server/service/approval-progress/approval-progress-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Query, Resolver } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { Employee } from '@things-factory/organization'\nimport { getRepository, Pagination } from '@things-factory/shell'\n\nimport { ActivityApproval } from '../activity-approval/activity-approval.js'\nimport { activityTKey } from '../activity/decision-key-declaration.js'\nimport {\n APPROVAL_PROGRESS_STATES,\n countsOf,\n inProgressOrder,\n passes,\n progressOf,\n ProgressLine\n} from './approval-progress-rule.js'\nimport { ApprovalProgress, ApprovalProgressFilter, ApprovalProgressList } from './approval-progress-type.js'\nimport { namesWaitedOn } from './waiting-on.js'\n\n/**\n * 결재 현황 — the domain's every approval case and where it stands, whatever its kind (ADR-0183).\n *\n * Read by whoever reads every case (`activity-instance` query, the rule `assert-may-read.ts` names): a line shows\n * the headline and the requester of a case the reader may already open.\n *\n * A case is one activity instance with a deciding approval row. Its state, step and waiting are read from the rows\n * by `progressOf`; the filter and the counts run on those lines, so a count says what the list would show.\n */\n@Resolver()\nexport class ApprovalProgressQuery {\n @Directive('@privilege(category: \"activity-instance\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => ApprovalProgressList, { description: 'The approvals of this domain, every kind, and where each stands.' })\n async approvalProgress(\n @Arg('filter', type => ApprovalProgressFilter, { nullable: true }) filter: ApprovalProgressFilter,\n @Arg('pagination', type => Pagination, { nullable: true }) pagination: Pagination,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalProgressList> {\n const { domain } = context.state\n filter = filter || {}\n\n const rows = await getRepository(ActivityApproval)\n .createQueryBuilder('ap')\n .innerJoinAndSelect('ap.activityThread', 'at')\n .innerJoinAndSelect('at.activityInstance', 'ai')\n .leftJoinAndSelect('ai.activity', 'act')\n .where('ap.domain = :domainId', { domainId: domain.id })\n .getMany()\n\n const cases = new Map<string, ActivityApproval[]>()\n for (const row of rows) {\n const id = row.activityThread.activityInstance.id\n cases.set(id, [...(cases.get(id) || []), row])\n }\n\n const requesterOf = (approvals: ActivityApproval[]) => {\n const thread = approvals[0].activityThread\n return thread.assigneeId || thread.activityInstance.creatorId\n }\n\n const requesterIds = [...new Set([...cases.values()].map(requesterOf).filter(Boolean))]\n const employees = requesterIds.length\n ? await getRepository(Employee)\n .createQueryBuilder('e')\n .leftJoinAndSelect('e.user', 'u')\n .leftJoinAndSelect('e.department', 'd')\n .where('e.domain = :domainId', { domainId: domain.id })\n .andWhere('u.id IN (:...requesterIds)', { requesterIds })\n .getMany()\n : []\n const employeeOf = new Map(employees.map(one => [one.user?.id, one]))\n const users = requesterIds.length\n ? await getRepository(User).createQueryBuilder('u').where('u.id IN (:...requesterIds)', { requesterIds }).getMany()\n : []\n const userName = new Map(users.map(one => [one.id, one.name]))\n\n const lines: (ProgressLine & { id: string; approvals: ActivityApproval[] })[] = []\n for (const [id, approvals] of cases) {\n /* A case seated only for references is not an approval. */\n if (!approvals.some(row => row.participation !== 'reference')) continue\n\n const instance = approvals[0].activityThread.activityInstance\n const requesterId = requesterOf(approvals)\n const employee = employeeOf.get(requesterId)\n\n lines.push({\n id,\n approvals,\n activityName: instance.activity?.name ?? '',\n headline: instance.name ?? '',\n requesterName: employee?.name || userName.get(requesterId),\n departmentId: employee?.department?.id,\n progress: progressOf({\n instanceState: instance.state,\n dueAt: instance.dueAt,\n approvalLine: instance.approvalLine as any,\n approvals\n })\n })\n }\n\n const passing = lines.filter(line => passes(line, filter)).sort(inProgressOrder)\n const { states, overdue } = countsOf(lines, filter)\n\n const limit = pagination?.limit || 50\n const page = pagination?.page || 1\n const pageLines = passing.slice((page - 1) * limit, page * limit)\n\n const items: ApprovalProgress[] = []\n for (const line of pageLines) {\n const instance = line.approvals[0].activityThread.activityInstance\n const { names, roleName } = await namesWaitedOn(getRepository(ActivityApproval).manager, line.progress.waiting)\n const employee = employeeOf.get(requesterOf(line.approvals))\n\n items.push({\n id: line.id,\n activityName: line.activityName,\n activityLabel: instance.activity?.label || line.activityName,\n activityLabelTKey: line.activityName ? activityTKey(line.activityName, 'label') : undefined,\n headline: line.headline,\n requesterName: line.requesterName,\n departmentName: employee?.department?.name,\n state: line.progress.state,\n step: line.progress.step,\n steps: line.progress.steps,\n waitingOn: names,\n waitingRole: roleName,\n waitingSince: line.progress.waitingSince,\n dueAt: instance.dueAt,\n overdue: line.progress.overdue,\n raisedAt: line.progress.raisedAt,\n endedAt: line.progress.endedAt\n })\n }\n\n /* The kinds that have a case here - what the kind filter offers. */\n const kinds = new Map<string, { name: string; label: string; labelTKey: string }>()\n for (const line of lines) {\n const activity = line.approvals[0].activityThread.activityInstance.activity\n if (line.activityName && !kinds.has(line.activityName))\n kinds.set(line.activityName, { name: line.activityName, label: activity?.label || line.activityName, labelTKey: activityTKey(line.activityName, 'label') })\n }\n\n return {\n items,\n kinds: [...kinds.values()].sort((a, b) => a.label.localeCompare(b.label)),\n total: passing.length,\n counts: APPROVAL_PROGRESS_STATES.map(state => ({ state, count: states[state] })),\n overdue\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"approval-progress-query.js","sourceRoot":"","sources":["../../../server/service/approval-progress/approval-progress-query.ts"],"names":[],"mappings":";;;;AAAA,qCAA4B;AAC5B,+CAAmE;AAEnE,yDAAgD;AAChD,+DAAuD;AACvD,iDAAiE;AAEjE,oFAA4E;AAC5E,yFAAsE;AACtE,2EAOoC;AACpC,2EAA4G;AAC5G,mDAA+C;AAE/C;;;;;;;;GAQG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAG1B,AAAN,KAAK,CAAC,gBAAgB,CAC+C,MAA8B,EACtC,UAAsB,EAC1E,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAChC,MAAM,GAAG,MAAM,IAAI,EAAE,CAAA;QAErB,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,uCAAgB,CAAC;aAC/C,kBAAkB,CAAC,IAAI,CAAC;aACxB,kBAAkB,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC7C,kBAAkB,CAAC,qBAAqB,EAAE,IAAI,CAAC;aAC/C,iBAAiB,CAAC,aAAa,EAAE,KAAK,CAAC;aACvC,KAAK,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;aACvD,OAAO,EAAE,CAAA;QAEZ,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAA;QACnD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,GAAG,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,CAAA;YACjD,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QAChD,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,SAA6B,EAAE,EAAE;YACpD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAA;YAC1C,OAAO,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAA;QAC/D,CAAC,CAAA;QAED,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACvF,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM;YACnC,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,uBAAQ,CAAC;iBAC1B,kBAAkB,CAAC,GAAG,CAAC;iBACvB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC;iBAChC,iBAAiB,CAAC,cAAc,EAAE,GAAG,CAAC;iBACtC,KAAK,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;iBACtD,QAAQ,CAAC,4BAA4B,EAAE,EAAE,YAAY,EAAE,CAAC;iBACxD,OAAO,EAAE;YACd,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;QACrE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM;YAC/B,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,4BAA4B,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE;YACnH,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE9D,MAAM,KAAK,GAAqE,EAAE,CAAA;QAClF,KAAK,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC;YACpC,2DAA2D;YAC3D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,KAAK,WAAW,CAAC;gBAAE,SAAQ;YAEvE,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAA;YAC7D,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YAC1C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YAE5C,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE;gBACF,SAAS;gBACT,YAAY,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE;gBAC3C,QAAQ,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;gBAC7B,aAAa,EAAE,QAAQ,EAAE,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC;gBAC1D,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;gBACtC,QAAQ,EAAE,IAAA,sCAAU,EAAC;oBACnB,aAAa,EAAE,QAAQ,CAAC,KAAK;oBAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,YAAY,EAAE,QAAQ,CAAC,YAAmB;oBAC1C,SAAS;iBACV,CAAC;aACH,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAA,kCAAM,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,2CAAe,CAAC,CAAA;QAChF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,oCAAQ,EAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAEnD,MAAM,KAAK,GAAG,UAAU,EAAE,KAAK,IAAI,EAAE,CAAA;QACrC,MAAM,IAAI,GAAG,UAAU,EAAE,IAAI,IAAI,CAAC,CAAA;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,CAAC,CAAA;QAEjE,MAAM,KAAK,GAAuB,EAAE,CAAA;QACpC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAA;YAClE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAA,6BAAa,EAAC,IAAA,qBAAa,EAAC,uCAAgB,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC/G,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;YAC5D,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAa,CAAA;YACjI,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;YAE3G,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,aAAa,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,IAAI,CAAC,YAAY;gBAC5D,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAA,0CAAY,EAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC3F,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI;gBAC1C,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;gBAC1B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;gBAC1B,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;gBACxC,WAAW,EAAE,QAAQ;gBACrB,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY;gBACxC,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO;gBAC9B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ;gBAChC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO;aAC/B,CAAC,CAAA;QACJ,CAAC;QAED,oEAAoE;QACpE,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8D,CAAA;QACnF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,QAAQ,CAAA;YAC3E,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;gBACpD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,IAAA,0CAAY,EAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;QAC/J,CAAC;QAED,OAAO;YACL,KAAK;YACL,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACzE,KAAK,EAAE,OAAO,CAAC,MAAM;YACrB,MAAM,EAAE,oDAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAChF,OAAO;SACR,CAAA;IACH,CAAC;CACF,CAAA;AA5HY,sDAAqB;AAG1B;IAFL,IAAA,wBAAS,EAAC,yFAAyF,CAAC;IACpG,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,gDAAoB,EAAE,EAAE,WAAW,EAAE,kEAAkE,EAAE,CAAC;IAEzH,mBAAA,IAAA,kBAAG,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,kDAAsB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACjE,mBAAA,IAAA,kBAAG,EAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,kBAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACzD,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAFqE,kDAAsB;QAC1B,kBAAU;;6DAsHlF;gCA3HU,qBAAqB;IADjC,IAAA,uBAAQ,GAAE;GACE,qBAAqB,CA4HjC","sourcesContent":["import { In } from 'typeorm'\nimport { Arg, Ctx, Directive, Query, Resolver } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { Employee } from '@things-factory/organization'\nimport { getRepository, Pagination } from '@things-factory/shell'\n\nimport { ActivityApproval } from '../activity-approval/activity-approval.js'\nimport { activityTKey } from '../activity/decision-key-declaration.js'\nimport {\n APPROVAL_PROGRESS_STATES,\n countsOf,\n inProgressOrder,\n passes,\n progressOf,\n ProgressLine\n} from './approval-progress-rule.js'\nimport { ApprovalProgress, ApprovalProgressFilter, ApprovalProgressList } from './approval-progress-type.js'\nimport { namesWaitedOn } from './waiting-on.js'\n\n/**\n * 결재 현황 — the domain's every approval case and where it stands, whatever its kind (ADR-0183).\n *\n * Read by whoever reads every case (`activity-instance` query, the rule `assert-may-read.ts` names): a line shows\n * the headline and the requester of a case the reader may already open.\n *\n * A case is one activity instance with a deciding approval row. Its state, step and waiting are read from the rows\n * by `progressOf`; the filter and the counts run on those lines, so a count says what the list would show.\n */\n@Resolver()\nexport class ApprovalProgressQuery {\n @Directive('@privilege(category: \"activity-instance\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => ApprovalProgressList, { description: 'The approvals of this domain, every kind, and where each stands.' })\n async approvalProgress(\n @Arg('filter', type => ApprovalProgressFilter, { nullable: true }) filter: ApprovalProgressFilter,\n @Arg('pagination', type => Pagination, { nullable: true }) pagination: Pagination,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalProgressList> {\n const { domain } = context.state\n filter = filter || {}\n\n const rows = await getRepository(ActivityApproval)\n .createQueryBuilder('ap')\n .innerJoinAndSelect('ap.activityThread', 'at')\n .innerJoinAndSelect('at.activityInstance', 'ai')\n .leftJoinAndSelect('ai.activity', 'act')\n .where('ap.domain = :domainId', { domainId: domain.id })\n .getMany()\n\n const cases = new Map<string, ActivityApproval[]>()\n for (const row of rows) {\n const id = row.activityThread.activityInstance.id\n cases.set(id, [...(cases.get(id) || []), row])\n }\n\n const requesterOf = (approvals: ActivityApproval[]) => {\n const thread = approvals[0].activityThread\n return thread.assigneeId || thread.activityInstance.creatorId\n }\n\n const requesterIds = [...new Set([...cases.values()].map(requesterOf).filter(Boolean))]\n const employees = requesterIds.length\n ? await getRepository(Employee)\n .createQueryBuilder('e')\n .leftJoinAndSelect('e.user', 'u')\n .leftJoinAndSelect('e.department', 'd')\n .where('e.domain = :domainId', { domainId: domain.id })\n .andWhere('u.id IN (:...requesterIds)', { requesterIds })\n .getMany()\n : []\n const employeeOf = new Map(employees.map(one => [one.user?.id, one]))\n const users = requesterIds.length\n ? await getRepository(User).createQueryBuilder('u').where('u.id IN (:...requesterIds)', { requesterIds }).getMany()\n : []\n const userName = new Map(users.map(one => [one.id, one.name]))\n\n const lines: (ProgressLine & { id: string; approvals: ActivityApproval[] })[] = []\n for (const [id, approvals] of cases) {\n /* A case seated only for references is not an approval. */\n if (!approvals.some(row => row.participation !== 'reference')) continue\n\n const instance = approvals[0].activityThread.activityInstance\n const requesterId = requesterOf(approvals)\n const employee = employeeOf.get(requesterId)\n\n lines.push({\n id,\n approvals,\n activityName: instance.activity?.name ?? '',\n headline: instance.name ?? '',\n requesterName: employee?.name || userName.get(requesterId),\n departmentId: employee?.department?.id,\n progress: progressOf({\n instanceState: instance.state,\n dueAt: instance.dueAt,\n approvalLine: instance.approvalLine as any,\n approvals\n })\n })\n }\n\n const passing = lines.filter(line => passes(line, filter)).sort(inProgressOrder)\n const { states, overdue } = countsOf(lines, filter)\n\n const limit = pagination?.limit || 50\n const page = pagination?.page || 1\n const pageLines = passing.slice((page - 1) * limit, page * limit)\n\n const items: ApprovalProgress[] = []\n for (const line of pageLines) {\n const instance = line.approvals[0].activityThread.activityInstance\n const { names, roleName } = await namesWaitedOn(getRepository(ActivityApproval).manager, line.progress.waiting)\n const employee = employeeOf.get(requesterOf(line.approvals))\n const deciderIds = [...new Set(line.progress.decided.map(row => row.terminatorId || row.approverId).filter(Boolean))] as string[]\n const deciders = deciderIds.length ? await getRepository(User).find({ where: { id: In(deciderIds) } }) : []\n\n items.push({\n id: line.id,\n activityName: line.activityName,\n activityLabel: instance.activity?.label || line.activityName,\n activityLabelTKey: line.activityName ? activityTKey(line.activityName, 'label') : undefined,\n headline: line.headline,\n requesterName: line.requesterName,\n departmentName: employee?.department?.name,\n state: line.progress.state,\n step: line.progress.step,\n steps: line.progress.steps,\n waitingOn: names,\n decidedBy: deciders.map(one => one.name),\n waitingRole: roleName,\n waitingSince: line.progress.waitingSince,\n dueAt: instance.dueAt,\n overdue: line.progress.overdue,\n raisedAt: line.progress.raisedAt,\n endedAt: line.progress.endedAt\n })\n }\n\n /* The kinds that have a case here - what the kind filter offers. */\n const kinds = new Map<string, { name: string; label: string; labelTKey: string }>()\n for (const line of lines) {\n const activity = line.approvals[0].activityThread.activityInstance.activity\n if (line.activityName && !kinds.has(line.activityName))\n kinds.set(line.activityName, { name: line.activityName, label: activity?.label || line.activityName, labelTKey: activityTKey(line.activityName, 'label') })\n }\n\n return {\n items,\n kinds: [...kinds.values()].sort((a, b) => a.label.localeCompare(b.label)),\n total: passing.length,\n counts: APPROVAL_PROGRESS_STATES.map(state => ({ state, count: states[state] })),\n overdue\n }\n }\n}\n"]}
|
|
@@ -9,6 +9,8 @@ export interface ProgressApprovalRow {
|
|
|
9
9
|
terminatedAt?: Date | null;
|
|
10
10
|
approverId?: string | null;
|
|
11
11
|
approverRoleId?: string | null;
|
|
12
|
+
/** Who judged the row - the person, also when the seat was a role's. */
|
|
13
|
+
terminatorId?: string | null;
|
|
12
14
|
}
|
|
13
15
|
export interface ProgressFacts {
|
|
14
16
|
instanceState?: string | null;
|
|
@@ -26,6 +28,8 @@ export interface Progress {
|
|
|
26
28
|
steps: number;
|
|
27
29
|
/** The rows of the step waited on now — whom it waits on. */
|
|
28
30
|
waiting: ProgressApprovalRow[];
|
|
31
|
+
/** The rows that decided it - the last approval of an approved case, the rejection of a rejected one. */
|
|
32
|
+
decided: ProgressApprovalRow[];
|
|
29
33
|
/** Since when the step waited on now has waited — its row is made when the step before it is approved. */
|
|
30
34
|
waitingSince?: Date;
|
|
31
35
|
/** When it was first put up for approval. */
|
|
@@ -45,11 +45,19 @@ function progressOf(facts, now = new Date()) {
|
|
|
45
45
|
const step = state === 'PENDING' ? (0, approval_step_js_1.currentStepOf)(approvals) : undefined;
|
|
46
46
|
const waiting = state === 'PENDING' ? (0, approval_step_js_1.currentStepRows)(approvals) : [];
|
|
47
47
|
const dueAt = timeOf(facts.dueAt);
|
|
48
|
+
const approved = thisRound.filter(row => row.judgment === 'approved');
|
|
49
|
+
const lastOrder = Math.max(0, ...approved.map(row => Number(row.order) || 0));
|
|
50
|
+
const decided = state === 'APPROVED'
|
|
51
|
+
? approved.filter(row => (Number(row.order) || 0) === lastOrder)
|
|
52
|
+
: state === 'REJECTED'
|
|
53
|
+
? thisRound.filter(row => row.judgment === 'rejected')
|
|
54
|
+
: [];
|
|
48
55
|
return {
|
|
49
56
|
state,
|
|
50
57
|
step: step ? (orders.indexOf(step.order) + 1 || step.order) : undefined,
|
|
51
58
|
steps: orders.length,
|
|
52
59
|
waiting,
|
|
60
|
+
decided,
|
|
53
61
|
waitingSince: earliest(waiting.map(row => row.createdAt)),
|
|
54
62
|
raisedAt: earliest(approvals.filter(deciding).map(row => row.createdAt)),
|
|
55
63
|
endedAt: state === 'PENDING' ? undefined : latest(thisRound.map(row => row.terminatedAt)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-progress-rule.js","sourceRoot":"","sources":["../../../server/service/approval-progress/approval-progress-rule.ts"],"names":[],"mappings":"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","sourcesContent":["import { currentStepOf, currentStepRows, latestRound } from '../../../shared/approval-step.js'\n\n/*\n * 결재 현황의 규칙 — 결재 한 건의 줄 하나를 결재 행에서 읽는다(ADR-0183 결정 1). DB 도 화면도 가져오지 않는다:\n * 질의가 행을 모아 넘기고, 시험이 같은 함수를 부른다.\n */\n\nexport type ApprovalProgressState = 'PENDING' | 'APPROVED' | 'REJECTED' | 'ABORTED'\n\nexport const APPROVAL_PROGRESS_STATES: readonly ApprovalProgressState[] = ['PENDING', 'APPROVED', 'REJECTED', 'ABORTED']\n\nexport interface ProgressApprovalRow {\n round?: number | null\n order?: number | null\n judgment?: string | null\n participation?: string | null\n createdAt?: Date | null\n terminatedAt?: Date | null\n approverId?: string | null\n approverRoleId?: string | null\n}\n\nexport interface ProgressFacts {\n instanceState?: string | null\n dueAt?: Date | null\n approvalLine?: { participation?: string }[] | null\n approvals: ProgressApprovalRow[]\n}\n\nexport interface Progress {\n state: ApprovalProgressState\n /** The step waited on now, counted among the deciding steps (references skipped) — 1 for the first approver. */\n step?: number\n /** How many deciding steps the line has. */\n steps: number\n /** The rows of the step waited on now — whom it waits on. */\n waiting: ProgressApprovalRow[]\n /** Since when the step waited on now has waited — its row is made when the step before it is approved. */\n waitingSince?: Date\n /** When it was first put up for approval. */\n raisedAt?: Date\n /** When it ended, for what is no longer waiting. */\n endedAt?: Date\n overdue: boolean\n}\n\nconst deciding = (row: ProgressApprovalRow) => row.participation !== 'reference'\nconst timeOf = (value?: Date | null) => (value ? new Date(value).getTime() : undefined)\nconst earliest = (values: (Date | null | undefined)[]) => {\n const times = values.map(timeOf).filter((one): one is number => one !== undefined)\n return times.length ? new Date(Math.min(...times)) : undefined\n}\nconst latest = (values: (Date | null | undefined)[]) => {\n const times = values.map(timeOf).filter((one): one is number => one !== undefined)\n return times.length ? new Date(Math.max(...times)) : undefined\n}\n\n/** The orders of the deciding steps of the line — a reference takes a place in the line and is not a step. */\nfunction decidingOrders(facts: ProgressFacts): number[] {\n const line = facts.approvalLine || []\n if (line.length) {\n return line.map((item, index) => (item?.participation === 'reference' ? 0 : index + 1)).filter(Boolean)\n }\n\n /* A case with no line kept on it: the orders its deciding rows carry. */\n return [...new Set(facts.approvals.filter(deciding).map(row => Number(row.order) || 0))].sort((a, b) => a - b)\n}\n\nexport function progressOf(facts: ProgressFacts, now: Date = new Date()): Progress {\n const approvals = facts.approvals || []\n const round = latestRound(approvals)\n const thisRound = approvals.filter(row => (Number(row.round) || 0) === round && deciding(row))\n const orders = decidingOrders(facts)\n\n /*\n * 반려가 중단보다 먼저다. Office 의 문은 반려되면 업무를 닫는다(`rejectionIsFinal`) — 그 건은 aborted 이고\n * 그 차수에 rejected 가 남는다. 중단을 먼저 읽으면 반려된 결재가 「중단」으로 보인다.\n */\n const state: ApprovalProgressState = thisRound.some(row => row.judgment === 'rejected')\n ? 'REJECTED'\n : facts.instanceState === 'aborted'\n ? 'ABORTED'\n : currentStepOf(approvals)\n ? 'PENDING'\n : 'APPROVED'\n\n const step = state === 'PENDING' ? currentStepOf(approvals) : undefined\n const waiting = state === 'PENDING' ? currentStepRows(approvals) : []\n const dueAt = timeOf(facts.dueAt)\n\n return {\n state,\n step: step ? (orders.indexOf(step.order) + 1 || step.order) : undefined,\n steps: orders.length,\n waiting,\n waitingSince: earliest(waiting.map(row => row.createdAt)),\n raisedAt: earliest(approvals.filter(deciding).map(row => row.createdAt)),\n endedAt: state === 'PENDING' ? undefined : latest(thisRound.map(row => row.terminatedAt)),\n overdue: state === 'PENDING' && dueAt !== undefined && dueAt < now.getTime()\n }\n}\n\nexport interface ProgressFilter {\n activityNames?: string[] | null\n states?: string[] | null\n departmentIds?: string[] | null\n /** The first day raised, inclusive. */\n from?: Date | null\n /** The last moment raised, exclusive. */\n to?: Date | null\n overdueOnly?: boolean | null\n search?: string | null\n}\n\nexport interface ProgressLine {\n activityName: string\n headline: string\n requesterName?: string\n departmentId?: string\n progress: Progress\n}\n\n/** Whether a line passes the filter. `ignore` leaves out the conditions a count is taken across. */\nexport function passes(line: ProgressLine, filter: ProgressFilter, ignore: { state?: boolean; overdue?: boolean } = {}): boolean {\n const { progress } = line\n if (filter.activityNames?.length && !filter.activityNames.includes(line.activityName)) return false\n if (!ignore.state && filter.states?.length && !filter.states.includes(progress.state)) return false\n if (filter.departmentIds?.length && !filter.departmentIds.includes(line.departmentId ?? '')) return false\n const raised = timeOf(progress.raisedAt)\n if (filter.from && (raised === undefined || raised < new Date(filter.from).getTime())) return false\n if (filter.to && (raised === undefined || raised >= new Date(filter.to).getTime())) return false\n if (!ignore.overdue && filter.overdueOnly && !progress.overdue) return false\n const search = filter.search?.trim().toLowerCase()\n if (search && ![line.headline, line.requesterName ?? ''].some(text => text.toLowerCase().includes(search))) return false\n return true\n}\n\n/** What waits stands first, the longest waiting at the top; what ended follows, the latest first. */\nexport function inProgressOrder(a: ProgressLine, b: ProgressLine): number {\n const pendingA = a.progress.state === 'PENDING'\n const pendingB = b.progress.state === 'PENDING'\n if (pendingA !== pendingB) return pendingA ? -1 : 1\n if (pendingA) return (timeOf(a.progress.waitingSince) ?? 0) - (timeOf(b.progress.waitingSince) ?? 0)\n return (timeOf(b.progress.endedAt ?? b.progress.raisedAt) ?? 0) - (timeOf(a.progress.endedAt ?? a.progress.raisedAt) ?? 0)\n}\n\n/** How many lines stand in each state, and how many are overdue — under the filter's other conditions. */\nexport function countsOf(lines: ProgressLine[], filter: ProgressFilter): { states: Record<ApprovalProgressState, number>; overdue: number } {\n const states = Object.fromEntries(APPROVAL_PROGRESS_STATES.map(state => [state, 0])) as Record<ApprovalProgressState, number>\n let overdue = 0\n for (const line of lines) {\n if (passes(line, filter, { state: true, overdue: true })) states[line.progress.state]++\n if (passes(line, filter, { overdue: true }) && line.progress.overdue) overdue++\n }\n return { states, overdue }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"approval-progress-rule.js","sourceRoot":"","sources":["../../../server/service/approval-progress/approval-progress-rule.ts"],"names":[],"mappings":"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","sourcesContent":["import { currentStepOf, currentStepRows, latestRound } from '../../../shared/approval-step.js'\n\n/*\n * 결재 현황의 규칙 — 결재 한 건의 줄 하나를 결재 행에서 읽는다(ADR-0183 결정 1). DB 도 화면도 가져오지 않는다:\n * 질의가 행을 모아 넘기고, 시험이 같은 함수를 부른다.\n */\n\nexport type ApprovalProgressState = 'PENDING' | 'APPROVED' | 'REJECTED' | 'ABORTED'\n\nexport const APPROVAL_PROGRESS_STATES: readonly ApprovalProgressState[] = ['PENDING', 'APPROVED', 'REJECTED', 'ABORTED']\n\nexport interface ProgressApprovalRow {\n round?: number | null\n order?: number | null\n judgment?: string | null\n participation?: string | null\n createdAt?: Date | null\n terminatedAt?: Date | null\n approverId?: string | null\n approverRoleId?: string | null\n /** Who judged the row - the person, also when the seat was a role's. */\n terminatorId?: string | null\n}\n\nexport interface ProgressFacts {\n instanceState?: string | null\n dueAt?: Date | null\n approvalLine?: { participation?: string }[] | null\n approvals: ProgressApprovalRow[]\n}\n\nexport interface Progress {\n state: ApprovalProgressState\n /** The step waited on now, counted among the deciding steps (references skipped) — 1 for the first approver. */\n step?: number\n /** How many deciding steps the line has. */\n steps: number\n /** The rows of the step waited on now — whom it waits on. */\n waiting: ProgressApprovalRow[]\n /** The rows that decided it - the last approval of an approved case, the rejection of a rejected one. */\n decided: ProgressApprovalRow[]\n /** Since when the step waited on now has waited — its row is made when the step before it is approved. */\n waitingSince?: Date\n /** When it was first put up for approval. */\n raisedAt?: Date\n /** When it ended, for what is no longer waiting. */\n endedAt?: Date\n overdue: boolean\n}\n\nconst deciding = (row: ProgressApprovalRow) => row.participation !== 'reference'\nconst timeOf = (value?: Date | null) => (value ? new Date(value).getTime() : undefined)\nconst earliest = (values: (Date | null | undefined)[]) => {\n const times = values.map(timeOf).filter((one): one is number => one !== undefined)\n return times.length ? new Date(Math.min(...times)) : undefined\n}\nconst latest = (values: (Date | null | undefined)[]) => {\n const times = values.map(timeOf).filter((one): one is number => one !== undefined)\n return times.length ? new Date(Math.max(...times)) : undefined\n}\n\n/** The orders of the deciding steps of the line — a reference takes a place in the line and is not a step. */\nfunction decidingOrders(facts: ProgressFacts): number[] {\n const line = facts.approvalLine || []\n if (line.length) {\n return line.map((item, index) => (item?.participation === 'reference' ? 0 : index + 1)).filter(Boolean)\n }\n\n /* A case with no line kept on it: the orders its deciding rows carry. */\n return [...new Set(facts.approvals.filter(deciding).map(row => Number(row.order) || 0))].sort((a, b) => a - b)\n}\n\nexport function progressOf(facts: ProgressFacts, now: Date = new Date()): Progress {\n const approvals = facts.approvals || []\n const round = latestRound(approvals)\n const thisRound = approvals.filter(row => (Number(row.round) || 0) === round && deciding(row))\n const orders = decidingOrders(facts)\n\n /*\n * 반려가 중단보다 먼저다. Office 의 문은 반려되면 업무를 닫는다(`rejectionIsFinal`) — 그 건은 aborted 이고\n * 그 차수에 rejected 가 남는다. 중단을 먼저 읽으면 반려된 결재가 「중단」으로 보인다.\n */\n const state: ApprovalProgressState = thisRound.some(row => row.judgment === 'rejected')\n ? 'REJECTED'\n : facts.instanceState === 'aborted'\n ? 'ABORTED'\n : currentStepOf(approvals)\n ? 'PENDING'\n : 'APPROVED'\n\n const step = state === 'PENDING' ? currentStepOf(approvals) : undefined\n const waiting = state === 'PENDING' ? currentStepRows(approvals) : []\n const dueAt = timeOf(facts.dueAt)\n const approved = thisRound.filter(row => row.judgment === 'approved')\n const lastOrder = Math.max(0, ...approved.map(row => Number(row.order) || 0))\n const decided =\n state === 'APPROVED'\n ? approved.filter(row => (Number(row.order) || 0) === lastOrder)\n : state === 'REJECTED'\n ? thisRound.filter(row => row.judgment === 'rejected')\n : []\n\n return {\n state,\n step: step ? (orders.indexOf(step.order) + 1 || step.order) : undefined,\n steps: orders.length,\n waiting,\n decided,\n waitingSince: earliest(waiting.map(row => row.createdAt)),\n raisedAt: earliest(approvals.filter(deciding).map(row => row.createdAt)),\n endedAt: state === 'PENDING' ? undefined : latest(thisRound.map(row => row.terminatedAt)),\n overdue: state === 'PENDING' && dueAt !== undefined && dueAt < now.getTime()\n }\n}\n\nexport interface ProgressFilter {\n activityNames?: string[] | null\n states?: string[] | null\n departmentIds?: string[] | null\n /** The first day raised, inclusive. */\n from?: Date | null\n /** The last moment raised, exclusive. */\n to?: Date | null\n overdueOnly?: boolean | null\n search?: string | null\n}\n\nexport interface ProgressLine {\n activityName: string\n headline: string\n requesterName?: string\n departmentId?: string\n progress: Progress\n}\n\n/** Whether a line passes the filter. `ignore` leaves out the conditions a count is taken across. */\nexport function passes(line: ProgressLine, filter: ProgressFilter, ignore: { state?: boolean; overdue?: boolean } = {}): boolean {\n const { progress } = line\n if (filter.activityNames?.length && !filter.activityNames.includes(line.activityName)) return false\n if (!ignore.state && filter.states?.length && !filter.states.includes(progress.state)) return false\n if (filter.departmentIds?.length && !filter.departmentIds.includes(line.departmentId ?? '')) return false\n const raised = timeOf(progress.raisedAt)\n if (filter.from && (raised === undefined || raised < new Date(filter.from).getTime())) return false\n if (filter.to && (raised === undefined || raised >= new Date(filter.to).getTime())) return false\n if (!ignore.overdue && filter.overdueOnly && !progress.overdue) return false\n const search = filter.search?.trim().toLowerCase()\n if (search && ![line.headline, line.requesterName ?? ''].some(text => text.toLowerCase().includes(search))) return false\n return true\n}\n\n/** What waits stands first, the longest waiting at the top; what ended follows, the latest first. */\nexport function inProgressOrder(a: ProgressLine, b: ProgressLine): number {\n const pendingA = a.progress.state === 'PENDING'\n const pendingB = b.progress.state === 'PENDING'\n if (pendingA !== pendingB) return pendingA ? -1 : 1\n if (pendingA) return (timeOf(a.progress.waitingSince) ?? 0) - (timeOf(b.progress.waitingSince) ?? 0)\n return (timeOf(b.progress.endedAt ?? b.progress.raisedAt) ?? 0) - (timeOf(a.progress.endedAt ?? a.progress.raisedAt) ?? 0)\n}\n\n/** How many lines stand in each state, and how many are overdue — under the filter's other conditions. */\nexport function countsOf(lines: ProgressLine[], filter: ProgressFilter): { states: Record<ApprovalProgressState, number>; overdue: number } {\n const states = Object.fromEntries(APPROVAL_PROGRESS_STATES.map(state => [state, 0])) as Record<ApprovalProgressState, number>\n let overdue = 0\n for (const line of lines) {\n if (passes(line, filter, { state: true, overdue: true })) states[line.progress.state]++\n if (passes(line, filter, { overdue: true }) && line.progress.overdue) overdue++\n }\n return { states, overdue }\n}\n"]}
|
|
@@ -84,6 +84,10 @@ tslib_1.__decorate([
|
|
|
84
84
|
(0, type_graphql_1.Field)(type => [String], { description: 'Whom the step waited on now waits on - people, and a role as its holders.' }),
|
|
85
85
|
tslib_1.__metadata("design:type", Array)
|
|
86
86
|
], ApprovalProgress.prototype, "waitingOn", void 0);
|
|
87
|
+
tslib_1.__decorate([
|
|
88
|
+
(0, type_graphql_1.Field)(type => [String], { description: 'Who decided it - the last approver of an approved case, who rejected a rejected one.' }),
|
|
89
|
+
tslib_1.__metadata("design:type", Array)
|
|
90
|
+
], ApprovalProgress.prototype, "decidedBy", void 0);
|
|
87
91
|
tslib_1.__decorate([
|
|
88
92
|
(0, type_graphql_1.Field)({ nullable: true, description: 'The role the step waited on now is seated by, if any.' }),
|
|
89
93
|
tslib_1.__metadata("design:type", String)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-progress-type.js","sourceRoot":"","sources":["../../../server/service/approval-progress/approval-progress-type.ts"],"names":[],"mappings":";;;;AAAA,+CAAoE;AAG7D,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;CAqBlC,CAAA;AArBY,wDAAsB;AAEjC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC;;6DACjG;AAGxB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,oDAAoD,EAAE,CAAC;;sDAC9F;AAGjB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;;6DAChF;AAGxB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC;sCACnE,IAAI;oDAAA;AAGX;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;sCAChE,IAAI;kDAAA;AAGT;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;;2DAC9D;AAGrB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;;sDACxE;iCApBJ,sBAAsB;IADlC,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,sEAAsE,EAAE,CAAC;GACtF,sBAAsB,CAqBlC;AAGM,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;
|
|
1
|
+
{"version":3,"file":"approval-progress-type.js","sourceRoot":"","sources":["../../../server/service/approval-progress/approval-progress-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'\n\n@InputType({ description: 'What the approval progress list shows - every condition is optional.' })\nexport class ApprovalProgressFilter {\n @Field(type => [String], { nullable: true, description: 'The kinds - activity names (an office door is its activity).' })\n activityNames?: string[]\n\n @Field(type => [String], { nullable: true, description: 'The states - PENDING, APPROVED, REJECTED, ABORTED.' })\n states?: string[]\n\n @Field(type => [String], { nullable: true, description: \"The requester's departments (organization).\" })\n departmentIds?: string[]\n\n @Field({ nullable: true, description: 'Raised on or after this moment.' })\n from?: Date\n\n @Field({ nullable: true, description: 'Raised before this moment.' })\n to?: Date\n\n @Field({ nullable: true, description: 'Only what still waits past its due time.' })\n overdueOnly?: boolean\n\n @Field({ nullable: true, description: 'Words in the headline or the requester name.' })\n search?: string\n}\n\n@ObjectType({ description: 'One approval case and where it stands.' })\nexport class ApprovalProgress {\n @Field(type => ID, { description: 'The activity instance.' })\n id: string\n\n @Field({ description: 'The kind - the activity name.' })\n activityName: string\n\n @Field({ nullable: true, description: 'The kind as a person reads it - the activity label.' })\n activityLabel?: string\n\n @Field({ nullable: true, description: 'The i18n key the kind label is translated from.' })\n activityLabelTKey?: string\n\n @Field({ description: 'What the approver reads first - the instance name.' })\n headline: string\n\n @Field({ nullable: true, description: 'Who put it up for approval.' })\n requesterName?: string\n\n @Field({ nullable: true, description: \"The requester's department now.\" })\n departmentName?: string\n\n @Field({ description: 'PENDING, APPROVED, REJECTED or ABORTED.' })\n state: string\n\n @Field(type => Int, { nullable: true, description: 'The deciding step waited on now, from 1.' })\n step?: number\n\n @Field(type => Int, { description: 'How many deciding steps the line has.' })\n steps: number\n\n @Field(type => [String], { description: 'Whom the step waited on now waits on - people, and a role as its holders.' })\n waitingOn: string[]\n\n @Field(type => [String], { description: 'Who decided it - the last approver of an approved case, who rejected a rejected one.' })\n decidedBy: string[]\n\n @Field({ nullable: true, description: 'The role the step waited on now is seated by, if any.' })\n waitingRole?: string\n\n @Field({ nullable: true, description: 'Since when the step waited on now has waited.' })\n waitingSince?: Date\n\n @Field({ nullable: true, description: 'When it is due.' })\n dueAt?: Date\n\n @Field({ description: 'Still waiting past its due time.' })\n overdue: boolean\n\n @Field({ nullable: true, description: 'When it was first put up for approval.' })\n raisedAt?: Date\n\n @Field({ nullable: true, description: 'When it ended.' })\n endedAt?: Date\n}\n\n@ObjectType({ description: 'How many approvals stand in one state.' })\nexport class ApprovalProgressStateCount {\n @Field({ description: 'The state.' })\n state: string\n\n @Field(type => Int, { description: 'How many, under the other conditions.' })\n count: number\n}\n\n@ObjectType({ description: 'A kind of approval that has a case in this domain.' })\nexport class ApprovalProgressKind {\n @Field({ description: 'The activity name.' })\n name: string\n\n @Field({ description: 'The activity label.' })\n label: string\n\n @Field({ description: 'The i18n key the label is translated from.' })\n labelTKey: string\n}\n\n@ObjectType({ description: 'The approvals of a domain and where each stands.' })\nexport class ApprovalProgressList {\n @Field(type => [ApprovalProgress], { description: 'The page asked for.' })\n items: ApprovalProgress[]\n\n @Field(type => [ApprovalProgressKind], { description: 'The kinds with a case here, whatever the filter.' })\n kinds: ApprovalProgressKind[]\n\n @Field(type => Int, { description: 'How many pass the filter.' })\n total: number\n\n @Field(type => [ApprovalProgressStateCount], { description: 'How many stand in each state, under the other conditions.' })\n counts: ApprovalProgressStateCount[]\n\n @Field(type => Int, { description: 'How many still wait past their due time, under the other conditions.' })\n overdue: number\n}\n"]}
|