@things-factory/worklist 10.1.29 → 10.1.31

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.
Files changed (64) hide show
  1. package/dist-client/pages/work-door/door-words.d.ts +41 -0
  2. package/dist-client/pages/work-door/door-words.js +54 -0
  3. package/dist-client/pages/work-door/door-words.js.map +1 -0
  4. package/dist-client/pages/work-door/work-doors-page.d.ts +37 -0
  5. package/dist-client/pages/work-door/work-doors-page.js +369 -0
  6. package/dist-client/pages/work-door/work-doors-page.js.map +1 -0
  7. package/dist-client/route.d.ts +1 -1
  8. package/dist-client/route.js +3 -0
  9. package/dist-client/route.js.map +1 -1
  10. package/dist-client/tsconfig.tsbuildinfo +1 -1
  11. package/dist-server/service/activity/index.d.ts +1 -1
  12. package/dist-server/service/activity-instance/index.d.ts +1 -1
  13. package/dist-server/service/activity-template/index.d.ts +1 -1
  14. package/dist-server/service/activity-thread/index.d.ts +1 -1
  15. package/dist-server/service/index.d.ts +3 -3
  16. package/dist-server/service/index.js +5 -2
  17. package/dist-server/service/index.js.map +1 -1
  18. package/dist-server/service/work-door/activity-lookup.d.ts +70 -0
  19. package/dist-server/service/work-door/activity-lookup.js +110 -0
  20. package/dist-server/service/work-door/activity-lookup.js.map +1 -0
  21. package/dist-server/service/work-door/approval-line-standing.d.ts +92 -0
  22. package/dist-server/service/work-door/approval-line-standing.js +47 -0
  23. package/dist-server/service/work-door/approval-line-standing.js.map +1 -0
  24. package/dist-server/service/work-door/index.d.ts +15 -0
  25. package/dist-server/service/work-door/index.js +20 -0
  26. package/dist-server/service/work-door/index.js.map +1 -0
  27. package/dist-server/service/work-door/pass-work-door.d.ts +74 -0
  28. package/dist-server/service/work-door/pass-work-door.js +45 -0
  29. package/dist-server/service/work-door/pass-work-door.js.map +1 -0
  30. package/dist-server/service/work-door/work-door-declaration.d.ts +114 -0
  31. package/dist-server/service/work-door/work-door-declaration.js +67 -0
  32. package/dist-server/service/work-door/work-door-declaration.js.map +1 -0
  33. package/dist-server/service/work-door/work-door-event.d.ts +20 -0
  34. package/dist-server/service/work-door/work-door-event.js +25 -0
  35. package/dist-server/service/work-door/work-door-event.js.map +1 -0
  36. package/dist-server/service/work-door/work-door-journal-service.d.ts +47 -0
  37. package/dist-server/service/work-door/work-door-journal-service.js +75 -0
  38. package/dist-server/service/work-door/work-door-journal-service.js.map +1 -0
  39. package/dist-server/service/work-door/work-door-journal.d.ts +30 -0
  40. package/dist-server/service/work-door/work-door-journal.js +94 -0
  41. package/dist-server/service/work-door/work-door-journal.js.map +1 -0
  42. package/dist-server/service/work-door/work-door-not-used.d.ts +39 -0
  43. package/dist-server/service/work-door/work-door-not-used.js +86 -0
  44. package/dist-server/service/work-door/work-door-not-used.js.map +1 -0
  45. package/dist-server/service/work-door/work-door-resolver.d.ts +29 -0
  46. package/dist-server/service/work-door/work-door-resolver.js +127 -0
  47. package/dist-server/service/work-door/work-door-resolver.js.map +1 -0
  48. package/dist-server/service/work-door/work-door-service.d.ts +29 -0
  49. package/dist-server/service/work-door/work-door-service.js +126 -0
  50. package/dist-server/service/work-door/work-door-service.js.map +1 -0
  51. package/dist-server/service/work-door/work-door-type.d.ts +49 -0
  52. package/dist-server/service/work-door/work-door-type.js +122 -0
  53. package/dist-server/service/work-door/work-door-type.js.map +1 -0
  54. package/dist-server/service/work-door/work-door.d.ts +138 -0
  55. package/dist-server/service/work-door/work-door.js +156 -0
  56. package/dist-server/service/work-door/work-door.js.map +1 -0
  57. package/dist-server/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +10 -10
  59. package/tests/pass-work-door.test.ts +133 -0
  60. package/translations/en.json +12 -1
  61. package/translations/ja.json +12 -1
  62. package/translations/ko.json +12 -1
  63. package/translations/ms.json +12 -1
  64. package/translations/zh.json +12 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/worklist",
3
- "version": "10.1.29",
3
+ "version": "10.1.31",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -37,14 +37,14 @@
37
37
  "@operato/moment-timezone-es": "^10.0.0",
38
38
  "@operato/p13n": "^10.0.0",
39
39
  "@operato/popup": "^10.15.0",
40
- "@things-factory/attachment-base": "^10.1.29",
41
- "@things-factory/auth-base": "^10.1.29",
42
- "@things-factory/board-service": "^10.1.29",
43
- "@things-factory/context-ui": "^10.1.29",
44
- "@things-factory/organization": "^10.1.29",
45
- "@things-factory/personalization": "^10.1.29",
46
- "@things-factory/scheduler-client": "^10.1.29",
47
- "@things-factory/shell": "^10.1.29"
40
+ "@things-factory/attachment-base": "^10.1.31",
41
+ "@things-factory/auth-base": "^10.1.31",
42
+ "@things-factory/board-service": "^10.1.31",
43
+ "@things-factory/context-ui": "^10.1.31",
44
+ "@things-factory/organization": "^10.1.31",
45
+ "@things-factory/personalization": "^10.1.31",
46
+ "@things-factory/scheduler-client": "^10.1.31",
47
+ "@things-factory/shell": "^10.1.31"
48
48
  },
49
- "gitHead": "e6bf9dec003fe5e794746aaeb5852b3b50478232"
49
+ "gitHead": "5213e6f9913b40ea2618a2111d9884b792dbaa01"
50
50
  }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Which way a work door goes when its approval line is empty, and what gets written down.
3
+ *
4
+ * ── Why each of these ─────────────────────────────────────────────────────
5
+ * The branch itself was never in one place before: eight doors in operato-plant each read the line
6
+ * and decided, and none of them wrote anything, so a step skipped for want of an approver left no
7
+ * trace at all. Joined here, `run` cannot happen without the line being written - so the test that
8
+ * matters most is that the `run` branch writes exactly one row, with the reason that applies.
9
+ *
10
+ * The transaction check is not ceremony: a plain manager commits the row on its own, and then the
11
+ * log says something happened that the failing work never did.
12
+ */
13
+
14
+ /*
15
+ * The entity is stood in for. Its decorators need `emitDecoratorMetadata`, which babel does not
16
+ * give jest (the repository's jest config says so, and says to test the pure logic on its own). The
17
+ * branch under test never reads the class - it only names the repository to save into.
18
+ */
19
+ jest.mock('../server/service/work-door/work-door-journal.js', () => ({ WorkDoorJournal: class WorkDoorJournal {} }))
20
+
21
+ import { WorkDoorEvent } from '../server/service/work-door/work-door-event.js'
22
+ import { passWorkDoor } from '../server/service/work-door/pass-work-door.js'
23
+
24
+ const domain = { id: 'd1' } as any
25
+
26
+ /** A manager that looks transactional and remembers what was saved. */
27
+ function openTx() {
28
+ const saved: any[] = []
29
+
30
+ return {
31
+ saved,
32
+ queryRunner: { isTransactionActive: true },
33
+ getRepository: () => ({ save: async (row: any) => ((saved.push(row), { ...row, id: 'j1' }) as any) })
34
+ } as any
35
+ }
36
+
37
+ const seatsThatStand = { roleHasMembers: async () => true, personIsHere: async () => true }
38
+
39
+ const approvalDoor = (over: any = {}): any =>
40
+ ({ name: 'lot-hold-release', labelKey: 'activity.lot-hold-release.label', kind: 'approval', whenNoLine: 'run', ...over } as any)
41
+
42
+ const subject = { kind: 'lot', id: 'LOT-1' }
43
+
44
+ describe('passWorkDoor', () => {
45
+ it('refuses to run outside a transaction - the row would commit on its own', async () => {
46
+ const loose = { getRepository: () => ({ save: async (r: any) => r }) } as any
47
+
48
+ await expect(
49
+ passWorkDoor({ door: approvalDoor(), subject }, { tx: loose, domain, seats: seatsThatStand })
50
+ ).rejects.toThrow(/transaction/)
51
+ })
52
+
53
+ it('will not judge an assignment door - it waits for a role, not for a line', async () => {
54
+ const door = { name: 'job-order-dispatch', labelKey: 'k', kind: 'assignment' } as any
55
+
56
+ await expect(passWorkDoor({ door, subject }, { tx: openTx(), domain, seats: seatsThatStand })).rejects.toThrow(
57
+ /assignment door/
58
+ )
59
+ })
60
+
61
+ it('raises when the line stands, and writes nothing - the instance is the record', async () => {
62
+ const tx = openTx()
63
+ const activity = { approvalLine: [{ type: 'Role', value: 'r1' }] }
64
+
65
+ const verdict = await passWorkDoor({ door: approvalDoor(), activity, subject }, { tx, domain, seats: seatsThatStand })
66
+
67
+ expect(verdict.go).toBe('raise')
68
+ expect(tx.saved).toHaveLength(0)
69
+ })
70
+
71
+ it('runs with an empty line, and that is written down once', async () => {
72
+ const tx = openTx()
73
+
74
+ const verdict = await passWorkDoor({ door: approvalDoor(), subject }, { tx, domain, seats: seatsThatStand })
75
+
76
+ expect(verdict).toMatchObject({ go: 'run', because: WorkDoorEvent.RanWithoutLine })
77
+ expect(tx.saved).toHaveLength(1)
78
+ expect(tx.saved[0]).toMatchObject({
79
+ kind: WorkDoorEvent.RanWithoutLine,
80
+ door: 'lot-hold-release',
81
+ subjectKind: 'lot',
82
+ subjectId: 'LOT-1'
83
+ })
84
+ })
85
+
86
+ it('says so differently when the door was declared unused - the administrator has nothing to fix', async () => {
87
+ const tx = openTx()
88
+
89
+ const verdict = await passWorkDoor({ door: approvalDoor(), subject, notUsed: true }, { tx, domain, seats: seatsThatStand })
90
+
91
+ expect(verdict).toMatchObject({ go: 'run', because: WorkDoorEvent.RanNotUsed })
92
+ expect(tx.saved[0].kind).toBe(WorkDoorEvent.RanNotUsed)
93
+ })
94
+
95
+ it('refuses with the line\'s own reason where the door refuses, and writes nothing', async () => {
96
+ const tx = openTx()
97
+ const door = approvalDoor({ whenNoLine: 'refuse', because: 'irreversible' } as any)
98
+
99
+ const verdict: any = await passWorkDoor({ door, subject }, { tx, domain, seats: seatsThatStand })
100
+
101
+ expect(verdict.go).toBe('refuse')
102
+ expect(verdict.refusal.code).toBe('approval-line-missing')
103
+ expect(tx.saved).toHaveLength(0)
104
+ })
105
+
106
+ describe('as-established - the row decides, not the door', () => {
107
+ const door = approvalDoor({ name: 'non-working-withdrawal', whenNoLine: 'as-established', because: 'approval-is-the-act' } as any)
108
+
109
+ it('refuses when the row was established through approval', async () => {
110
+ const tx = openTx()
111
+
112
+ const verdict: any = await passWorkDoor(
113
+ { door, subject, establishedByApproval: true },
114
+ { tx, domain, seats: seatsThatStand }
115
+ )
116
+
117
+ expect(verdict.go).toBe('refuse')
118
+ expect(tx.saved).toHaveLength(0)
119
+ })
120
+
121
+ it('runs when it stood without approval', async () => {
122
+ const tx = openTx()
123
+
124
+ const verdict: any = await passWorkDoor(
125
+ { door, subject, establishedByApproval: false },
126
+ { tx, domain, seats: seatsThatStand }
127
+ )
128
+
129
+ expect(verdict.go).toBe('run')
130
+ expect(tx.saved).toHaveLength(1)
131
+ })
132
+ })
133
+ })
@@ -41,6 +41,8 @@
41
41
  "error.approval line names a person who cannot be found": "{seats}: the person named for that step cannot be found. name another approver.",
42
42
  "error.approval line names a role that nobody holds": "{seats}: nobody holds the role named for that step. add someone to that role.",
43
43
  "error.not authorized to handle this task": "you are not authorized to perform this task.",
44
+ "error.work-door-not-used-reason-missing": "enter why this task is not used.",
45
+ "error.work-door-unknown": "unknown task \"{name}\". use a task name from the status screen.",
44
46
  "field.activity-type": "activity type",
45
47
  "field.approval-changed-at": "last change",
46
48
  "field.approval-drafter": "submitted by",
@@ -202,6 +204,7 @@
202
204
  "label.what-changes": "what changes on approval",
203
205
  "label.what-it-was-judged-from": "what it was judged from",
204
206
  "label.yes": "yes",
207
+ "menu.work-doors": "approval and assignment forms",
205
208
  "text.activity-activated": "{name} is now on for this domain.",
206
209
  "text.activity-change-failed": "{name} was not changed: {why}",
207
210
  "text.activity-change-not-allowed": "you are not allowed to change {name}. ask an administrator for the activity privilege.",
@@ -228,6 +231,8 @@
228
231
  "text.copy-failed": "could not copy",
229
232
  "text.copy-payload": "copy this value as raw json",
230
233
  "text.decision-keys-count": "{n} decision key(s)",
234
+ "text.door-filled-from": "set in {name}",
235
+ "text.door-form-from": "{name}'s form — it cannot be changed from here",
231
236
  "text.draft": "draft",
232
237
  "text.due-just-passed": "just passed",
233
238
  "text.due-left-in": "{span} left",
@@ -283,6 +288,10 @@
283
288
  "text.task_is_saved_successfully": "task is saved successfully",
284
289
  "text.task_is_started_successfully": "task is started successfully.",
285
290
  "text.timeline-count": "{count} entries",
291
+ "text.work-doors-lead": "shows whether each approval and assignment step has approvers or receivers. without them, an approval completes as soon as it is raised and an assignment reaches nobody.",
292
+ "text.work-doors-next-line": "set an approval line on {count} work forms —",
293
+ "text.work-doors-next-seats": "{standing} of {offered} roles are set up. set up roles first to use them in approval lines —",
294
+ "text.work-doors-read-failed": "could not read the approval forms.",
286
295
  "text.write-your-comment-as-reference": "write your comment.",
287
296
  "title.activity": "activity",
288
297
  "title.activity application": "activity application",
@@ -324,5 +333,7 @@
324
333
  "title.my workspace": "my workspace",
325
334
  "title.pick activity": "pick an activity to handle",
326
335
  "title.todo list": "to do",
336
+ "title.work-doors": "approval and assignment forms in this plant",
337
+ "title.work-doors-next": "What to do next",
327
338
  "title.worklist dashboard": "worklist dashboard"
328
- }
339
+ }
@@ -41,6 +41,8 @@
41
41
  "error.approval line names a person who cannot be found": "{seats} の段階に指定した人が見つかりません。承認者を指定し直してください。",
42
42
  "error.approval line names a role that nobody holds": "{seats} の段階に指定した役割に人がいません。その役割に人を追加してください。",
43
43
  "error.not authorized to handle this task": "このタスクを処理する権限がありません。",
44
+ "error.work-door-not-used-reason-missing": "使用しない理由を入力してください。",
45
+ "error.work-door-unknown": "「{name}」は不明な業務です。状況画面の業務名を使用してください。",
44
46
  "field.activity-type": "業務タイプ",
45
47
  "field.approval-changed-at": "最終変更",
46
48
  "field.approval-drafter": "起案者",
@@ -202,6 +204,7 @@
202
204
  "label.what-changes": "承認すると変わること",
203
205
  "label.what-it-was-judged-from": "判断の根拠",
204
206
  "label.yes": "はい",
207
+ "menu.work-doors": "承認・割当様式の状況",
205
208
  "text.activity-activated": "{name} をこのドメインで使用するようにしました。",
206
209
  "text.activity-change-failed": "{name} を変更できませんでした: {why}",
207
210
  "text.activity-change-not-allowed": "{name} を変更する権限がありません。管理者に業務活動の権限を依頼してください。",
@@ -228,6 +231,8 @@
228
231
  "text.copy-failed": "コピーできません",
229
232
  "text.copy-payload": "この値を原文(JSON)でコピーします",
230
233
  "text.decision-keys-count": "判断項目 {n}件",
234
+ "text.door-filled-from": "{name} で設定されています",
235
+ "text.door-form-from": "{name} のフォームです — ここでは変更できません",
231
236
  "text.draft": "ドラフト保存",
232
237
  "text.due-just-passed": "過ぎたところ",
233
238
  "text.due-left-in": "残り{span}",
@@ -283,6 +288,10 @@
283
288
  "text.task_is_saved_successfully": "業務が正常に保存されました。",
284
289
  "text.task_is_started_successfully": "業務が正常に開始されました。",
285
290
  "text.timeline-count": "{count}件",
291
+ "text.work-doors-lead": "承認・割当の各段階で承認者と受取人が決まっているかを表示します。決めていないと、承認は申請と同時に承認され、割当は誰にも届きません。",
292
+ "text.work-doors-next-line": "業務様式 {count}件に承認ラインを指定してください —",
293
+ "text.work-doors-next-seats": "ロール {offered}件中 {standing}件が設定されています。承認ラインに使うロールを先に設定してください —",
294
+ "text.work-doors-read-failed": "承認様式の状況を読み込めませんでした。",
286
295
  "text.write-your-comment-as-reference": "ご意見をご記入ください。",
287
296
  "title.activity": "業務",
288
297
  "title.activity application": "業務申込書作成",
@@ -324,5 +333,7 @@
324
333
  "title.my workspace": "私の仕事の空間",
325
334
  "title.pick activity": "担当する業務を選択",
326
335
  "title.todo list": "やること",
336
+ "title.work-doors": "この工場の承認・割当様式",
337
+ "title.work-doors-next": "次にすること",
327
338
  "title.worklist dashboard": "ワークリストダッシュボード"
328
- }
339
+ }
@@ -41,6 +41,8 @@
41
41
  "error.approval line names a person who cannot be found": "{seats} 단계에 지정한 사람을 찾을 수 없습니다. 결재자를 다시 지정하십시오.",
42
42
  "error.approval line names a role that nobody holds": "{seats} 단계에 지정한 역할에 사람이 없습니다. 그 역할에 사람을 추가하십시오.",
43
43
  "error.not authorized to handle this task": "이 작업을 수행할 권한이 없습니다.",
44
+ "error.work-door-not-used-reason-missing": "쓰지 않는 이유를 입력하십시오.",
45
+ "error.work-door-unknown": "\"{name}\" 은(는) 알 수 없는 업무입니다. 현황 화면의 업무 이름을 쓰십시오.",
44
46
  "field.activity-type": "업무 타입",
45
47
  "field.approval-changed-at": "최근 변경",
46
48
  "field.approval-drafter": "기안자",
@@ -202,6 +204,7 @@
202
204
  "label.what-changes": "승인하면 달라지는 것",
203
205
  "label.what-it-was-judged-from": "판단 근거",
204
206
  "label.yes": "예",
207
+ "menu.work-doors": "결재·배정 양식 현황",
205
208
  "text.activity-activated": "{name} 을 이 도메인에서 쓰도록 켰습니다.",
206
209
  "text.activity-change-failed": "{name} 을 바꾸지 못했습니다: {why}",
207
210
  "text.activity-change-not-allowed": "{name} 을 바꿀 권한이 없습니다. 관리자에게 업무 활동 권한을 요청하십시오.",
@@ -228,6 +231,8 @@
228
231
  "text.copy-failed": "복사할 수 없습니다",
229
232
  "text.copy-payload": "이 값을 원문(JSON)으로 복사합니다",
230
233
  "text.decision-keys-count": "판단 항목 {n}개",
234
+ "text.door-filled-from": "{name} 에서 정했습니다",
235
+ "text.door-form-from": "{name} 의 양식입니다 — 여기서는 못 고칩니다",
231
236
  "text.draft": "초안저장",
232
237
  "text.due-just-passed": "방금 지남",
233
238
  "text.due-left-in": "{span} 남음",
@@ -283,6 +288,10 @@
283
288
  "text.task_is_saved_successfully": "업무가 성공적으로 저장되었습니다.",
284
289
  "text.task_is_started_successfully": "업무가 성공적으로 시작되었습니다.",
285
290
  "text.timeline-count": "{count}건",
291
+ "text.work-doors-lead": "승인·배정 단계마다 결재자와 받는 사람이 정해졌는지 보여 줍니다. 정하지 않으면 결재는 올리는 즉시 승인되고, 배정은 아무에게도 가지 않습니다.",
292
+ "text.work-doors-next-line": "업무 양식 {count}개에 결재선을 지정하십시오 —",
293
+ "text.work-doors-next-seats": "역할 {offered}개 중 {standing}개가 설정되어 있습니다. 결재선에 쓸 역할을 먼저 설정하십시오 —",
294
+ "text.work-doors-read-failed": "결재 양식 현황을 읽지 못했습니다.",
286
295
  "text.write-your-comment-as-reference": "의견을 적어 주십시오.",
287
296
  "title.activity": "업무",
288
297
  "title.activity application": "업무 신청서 작성",
@@ -324,5 +333,7 @@
324
333
  "title.my workspace": "나의 업무 공간",
325
334
  "title.pick activity": "담당할 업무 선택",
326
335
  "title.todo list": "할 일",
336
+ "title.work-doors": "이 공장의 결재·배정 양식",
337
+ "title.work-doors-next": "다음에 할 일",
327
338
  "title.worklist dashboard": "업무실적 대시보드"
328
- }
339
+ }
@@ -41,6 +41,8 @@
41
41
  "error.approval line names a person who cannot be found": "{seats}: orang yang dinamakan untuk langkah itu tidak ditemui. namakan pelulus lain.",
42
42
  "error.approval line names a role that nobody holds": "{seats}: tiada sesiapa memegang peranan untuk langkah itu. tambah seseorang pada peranan itu.",
43
43
  "error.not authorized to handle this task": "Anda tidak mempunyai kebenaran untuk melaksanakan tugas ini.",
44
+ "error.work-door-not-used-reason-missing": "masukkan sebab tugas ini tidak digunakan.",
45
+ "error.work-door-unknown": "tugas \"{name}\" tidak diketahui. gunakan nama tugas daripada skrin status.",
44
46
  "field.activity-type": "jenis aktiviti",
45
47
  "field.approval-changed-at": "perubahan terakhir",
46
48
  "field.approval-drafter": "dihantar oleh",
@@ -202,6 +204,7 @@
202
204
  "label.what-changes": "apa yang berubah selepas kelulusan",
203
205
  "label.what-it-was-judged-from": "dasar penilaian",
204
206
  "label.yes": "ya",
207
+ "menu.work-doors": "borang kelulusan dan tugasan",
205
208
  "text.activity-activated": "{name} kini dihidupkan untuk domain ini.",
206
209
  "text.activity-change-failed": "{name} tidak diubah: {why}",
207
210
  "text.activity-change-not-allowed": "anda tiada keizinan untuk mengubah {name}. minta keizinan aktiviti daripada pentadbir.",
@@ -228,6 +231,8 @@
228
231
  "text.copy-failed": "tidak dapat menyalin",
229
232
  "text.copy-payload": "salin nilai ini sebagai json asal",
230
233
  "text.decision-keys-count": "{n} kunci keputusan",
234
+ "text.door-filled-from": "ditetapkan di {name}",
235
+ "text.door-form-from": "Borang {name} — tidak boleh diubah dari sini",
231
236
  "text.draft": "draf",
232
237
  "text.due-just-passed": "baru lewat",
233
238
  "text.due-left-in": "tinggal {span}",
@@ -283,6 +288,10 @@
283
288
  "text.task_is_saved_successfully": "tugas berjaya disimpan",
284
289
  "text.task_is_started_successfully": "tugas berjaya bermula.",
285
290
  "text.timeline-count": "{count} rekod",
291
+ "text.work-doors-lead": "menunjukkan sama ada setiap langkah kelulusan dan tugasan mempunyai pelulus atau penerima. tanpanya, kelulusan selesai sebaik dihantar dan tugasan tidak sampai kepada sesiapa.",
292
+ "text.work-doors-next-line": "tetapkan laluan kelulusan pada {count} borang kerja —",
293
+ "text.work-doors-next-seats": "{standing} daripada {offered} peranan telah ditetapkan. tetapkan peranan dahulu untuk digunakan dalam laluan kelulusan —",
294
+ "text.work-doors-read-failed": "tidak dapat membaca borang kelulusan.",
286
295
  "text.write-your-comment-as-reference": "tuliskan komen anda.",
287
296
  "title.activity": "perniagaan",
288
297
  "title.activity application": "permohonan aktiviti",
@@ -324,5 +333,7 @@
324
333
  "title.my workspace": "ruang kerja saya",
325
334
  "title.pick activity": "pilih aktiviti untuk dikendalikan",
326
335
  "title.todo list": "untuk dibuat",
336
+ "title.work-doors": "borang kelulusan dan tugasan di kilang ini",
337
+ "title.work-doors-next": "Apa yang perlu dilakukan",
327
338
  "title.worklist dashboard": "papan pemantauan senarai kerja"
328
- }
339
+ }
@@ -41,6 +41,8 @@
41
41
  "error.approval line names a person who cannot be found": "找不到 {seats} 步骤指定的人员。请重新指定审批人。",
42
42
  "error.approval line names a role that nobody holds": "{seats} 步骤指定的角色中没有人员。请为该角色添加人员。",
43
43
  "error.not authorized to handle this task": "您无权执行此任务。",
44
+ "error.work-door-not-used-reason-missing": "请填写不使用此业务的原因。",
45
+ "error.work-door-unknown": "\"{name}\"是未知的业务。请使用状况画面中的业务名称。",
44
46
  "field.activity-type": "业务类型",
45
47
  "field.approval-changed-at": "最近变更",
46
48
  "field.approval-drafter": "起草人",
@@ -202,6 +204,7 @@
202
204
  "label.what-changes": "批准后将发生的变化",
203
205
  "label.what-it-was-judged-from": "判断依据",
204
206
  "label.yes": "是",
207
+ "menu.work-doors": "审批与分配表单状态",
205
208
  "text.activity-activated": "已在此域中启用 {name}。",
206
209
  "text.activity-change-failed": "无法更改 {name}:{why}",
207
210
  "text.activity-change-not-allowed": "您无权更改 {name}。请向管理员申请业务活动权限。",
@@ -228,6 +231,8 @@
228
231
  "text.copy-failed": "无法复制",
229
232
  "text.copy-payload": "以原始 JSON 复制此值",
230
233
  "text.decision-keys-count": "判断项 {n} 个",
234
+ "text.door-filled-from": "在 {name} 中设定",
235
+ "text.door-form-from": "{name} 的表单 — 此处无法修改",
231
236
  "text.draft": "草稿",
232
237
  "text.due-just-passed": "刚刚超期",
233
238
  "text.due-left-in": "剩余{span}",
@@ -283,6 +288,10 @@
283
288
  "text.task_is_saved_successfully": "任务已成功保存。",
284
289
  "text.task_is_started_successfully": "任务已成功开始。",
285
290
  "text.timeline-count": "{count}条",
291
+ "text.work-doors-lead": "显示每个审批与分配环节是否已指定审批人和接收人。未指定时,审批在提交时即完成,分配不会送达任何人。",
292
+ "text.work-doors-next-line": "请为 {count} 个业务表单指定审批线 —",
293
+ "text.work-doors-next-seats": "{offered} 个角色中已设置 {standing} 个。请先设置用于审批线的角色 —",
294
+ "text.work-doors-read-failed": "无法读取审批表单状态。",
286
295
  "text.write-your-comment-as-reference": "请填写您的意见。",
287
296
  "title.activity": "业务",
288
297
  "title.activity application": "业务申请",
@@ -324,5 +333,7 @@
324
333
  "title.my workspace": "我的工作空间",
325
334
  "title.pick activity": "选择要负责的任务",
326
335
  "title.todo list": "待办",
336
+ "title.work-doors": "本工厂的审批与分配表单",
337
+ "title.work-doors-next": "接下来要做的",
327
338
  "title.worklist dashboard": "工作清单仪表板"
328
- }
339
+ }