@things-factory/worklist 10.1.202 → 10.1.203
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/pages/activity/activity-list-page.d.ts +3 -0
- package/dist-client/pages/activity/activity-list-page.js +25 -13
- package/dist-client/pages/activity/activity-list-page.js.map +1 -1
- package/dist-client/pages/activity/activity-partial-view.js +1 -1
- package/dist-client/pages/activity/activity-partial-view.js.map +1 -1
- package/dist-client/pages/activity/assignee-roles-cell.d.ts +32 -0
- package/dist-client/pages/activity/assignee-roles-cell.js +26 -0
- package/dist-client/pages/activity/assignee-roles-cell.js.map +1 -0
- package/dist-client/pages/activity-catalog/activity-catalog-page.js +1 -1
- package/dist-client/pages/activity-catalog/activity-catalog-page.js.map +1 -1
- package/dist-client/pages/work-door/door-sentence.d.ts +1 -1
- package/dist-client/pages/work-door/door-sentence.js +2 -2
- package/dist-client/pages/work-door/door-sentence.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/types/activity-instance-type.d.ts +2 -2
- package/dist-client/types/activity-instance-type.js.map +1 -1
- package/dist-client/types/activity-instance.d.ts +1 -1
- package/dist-client/types/activity-instance.js.map +1 -1
- package/dist-client/types/activity.d.ts +1 -1
- package/dist-client/types/activity.js.map +1 -1
- package/dist-server/controllers/activity-approval/resolve-judgeable-seats.d.ts +2 -2
- package/dist-server/controllers/activity-approval/resolve-judgeable-seats.js +2 -2
- package/dist-server/controllers/activity-approval/resolve-judgeable-seats.js.map +1 -1
- package/dist-server/controllers/activity-instance/abort.js +1 -1
- package/dist-server/controllers/activity-instance/abort.js.map +1 -1
- package/dist-server/controllers/activity-instance/assign.d.ts +2 -1
- package/dist-server/controllers/activity-instance/assign.js +104 -2
- package/dist-server/controllers/activity-instance/assign.js.map +1 -1
- package/dist-server/controllers/activity-instance/assignee-input.d.ts +25 -0
- package/dist-server/controllers/activity-instance/assignee-input.js +28 -0
- package/dist-server/controllers/activity-instance/assignee-input.js.map +1 -0
- package/dist-server/controllers/activity-instance/draft.js +7 -2
- package/dist-server/controllers/activity-instance/draft.js.map +1 -1
- package/dist-server/controllers/activity-instance/end.js +1 -1
- package/dist-server/controllers/activity-instance/end.js.map +1 -1
- package/dist-server/controllers/activity-instance/entitlement.d.ts +1 -1
- package/dist-server/controllers/activity-instance/entitlement.js +7 -5
- package/dist-server/controllers/activity-instance/entitlement.js.map +1 -1
- package/dist-server/controllers/activity-instance/issue.js +28 -7
- package/dist-server/controllers/activity-instance/issue.js.map +1 -1
- package/dist-server/controllers/activity-instance/pick.js +22 -3
- package/dist-server/controllers/activity-instance/pick.js.map +1 -1
- package/dist-server/controllers/activity-read/assert-may-read.js +2 -1
- package/dist-server/controllers/activity-read/assert-may-read.js.map +1 -1
- package/dist-server/controllers/activity-read/participates.d.ts +2 -2
- package/dist-server/controllers/activity-read/participates.js +2 -2
- package/dist-server/controllers/activity-read/participates.js.map +1 -1
- package/dist-server/controllers/activity-thread/check-authority.js +22 -4
- package/dist-server/controllers/activity-thread/check-authority.js.map +1 -1
- package/dist-server/controllers/common.js +17 -12
- package/dist-server/controllers/common.js.map +1 -1
- package/dist-server/service/activity/activity-history.d.ts +1 -2
- package/dist-server/service/activity/activity-history.js +4 -8
- package/dist-server/service/activity/activity-history.js.map +1 -1
- package/dist-server/service/activity/activity-mutation.js +39 -8
- package/dist-server/service/activity/activity-mutation.js.map +1 -1
- package/dist-server/service/activity/activity-query.d.ts +1 -1
- package/dist-server/service/activity/activity-query.js +9 -9
- package/dist-server/service/activity/activity-query.js.map +1 -1
- package/dist-server/service/activity/activity-type.d.ts +2 -2
- package/dist-server/service/activity/activity-type.js +12 -6
- package/dist-server/service/activity/activity-type.js.map +1 -1
- package/dist-server/service/activity/activity.d.ts +2 -2
- package/dist-server/service/activity/activity.js +15 -7
- package/dist-server/service/activity/activity.js.map +1 -1
- package/dist-server/service/activity/event-subscriber.js.map +1 -1
- package/dist-server/service/activity-instance/activity-instance-history.d.ts +1 -2
- package/dist-server/service/activity-instance/activity-instance-history.js +4 -8
- package/dist-server/service/activity-instance/activity-instance-history.js.map +1 -1
- package/dist-server/service/activity-instance/activity-instance-mutation.d.ts +1 -1
- package/dist-server/service/activity-instance/activity-instance-mutation.js +10 -5
- package/dist-server/service/activity-instance/activity-instance-mutation.js.map +1 -1
- package/dist-server/service/activity-instance/activity-instance-query.d.ts +1 -2
- package/dist-server/service/activity-instance/activity-instance-query.js +16 -25
- package/dist-server/service/activity-instance/activity-instance-query.js.map +1 -1
- package/dist-server/service/activity-instance/activity-instance-type.d.ts +2 -2
- package/dist-server/service/activity-instance/activity-instance-type.js +12 -6
- package/dist-server/service/activity-instance/activity-instance-type.js.map +1 -1
- package/dist-server/service/activity-instance/activity-instance.d.ts +2 -2
- package/dist-server/service/activity-instance/activity-instance.js +15 -7
- package/dist-server/service/activity-instance/activity-instance.js.map +1 -1
- package/dist-server/service/activity-instance/assignee-pool.d.ts +59 -0
- package/dist-server/service/activity-instance/assignee-pool.js +99 -0
- package/dist-server/service/activity-instance/assignee-pool.js.map +1 -0
- package/dist-server/service/activity-instance/event-subscriber.d.ts +9 -1
- package/dist-server/service/activity-instance/event-subscriber.js +20 -4
- package/dist-server/service/activity-instance/event-subscriber.js.map +1 -1
- package/dist-server/service/activity-summary/activity-summary-query.js +3 -3
- package/dist-server/service/activity-summary/activity-summary-query.js.map +1 -1
- package/dist-server/service/activity-thread/my-open-threads.d.ts +1 -1
- package/dist-server/service/activity-thread/my-open-threads.js +4 -3
- package/dist-server/service/activity-thread/my-open-threads.js.map +1 -1
- package/dist-server/service/subscription/subscription-filters.d.ts +3 -2
- package/dist-server/service/subscription/subscription-filters.js +6 -3
- package/dist-server/service/subscription/subscription-filters.js.map +1 -1
- package/dist-server/service/work-door/work-door-service.js +9 -6
- package/dist-server/service/work-door/work-door-service.js.map +1 -1
- package/dist-server/service/work-door/work-door-type.d.ts +1 -1
- package/dist-server/service/work-door/work-door-type.js +4 -4
- package/dist-server/service/work-door/work-door-type.js.map +1 -1
- package/dist-server/service/work-door/work-door.d.ts +3 -3
- package/dist-server/service/work-door/work-door.js +2 -2
- package/dist-server/service/work-door/work-door.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/tests/assign-role-pool.test.ts +508 -0
- package/tests/assignee-pool-history.test.ts +81 -0
- package/tests/may-read-case.test.ts +3 -2
- package/tests/org-member-domain.test.ts +10 -4
- package/tests/pick-race.pg.test.ts +2 -2
- package/tests/published-shape.test.ts +2 -2
- package/tests/role-pool-race.pg.test.ts +182 -0
- package/tests/work-door.test.ts +3 -3
- package/translations/en.json +5 -0
- package/translations/es.json +5 -0
- package/translations/ja.json +5 -0
- package/translations/ko.json +5 -0
- package/translations/ms.json +5 -0
- package/translations/zh.json +5 -0
|
@@ -63,7 +63,7 @@ maybe('picking at once, on postgres', () => {
|
|
|
63
63
|
name: `p${round}`,
|
|
64
64
|
state: 'issued',
|
|
65
65
|
activity,
|
|
66
|
-
|
|
66
|
+
assigneeRoles: [role],
|
|
67
67
|
threadsMin: 1,
|
|
68
68
|
threadsMax: 1
|
|
69
69
|
})
|
|
@@ -111,7 +111,7 @@ maybe('picking at once, on postgres', () => {
|
|
|
111
111
|
name: `two${round}`,
|
|
112
112
|
state: 'issued',
|
|
113
113
|
activity,
|
|
114
|
-
|
|
114
|
+
assigneeRoles: [role],
|
|
115
115
|
threadsMin: 2,
|
|
116
116
|
threadsMax: 2
|
|
117
117
|
})
|
|
@@ -54,9 +54,9 @@ beforeEach(() => (seen.length = 0))
|
|
|
54
54
|
const handed = (name: string, on: string) => seen.find(one => one.name === name && one.on === on)?.entity
|
|
55
55
|
|
|
56
56
|
it('a new instance carries its domain, its maker and the role it waits for', async () => {
|
|
57
|
-
await db.getRepository(ActivityInstance).save({ domain, name: 'i', creator: user,
|
|
57
|
+
await db.getRepository(ActivityInstance).save({ domain, name: 'i', creator: user, assigneeRoles: [role], state: 'issued' })
|
|
58
58
|
|
|
59
|
-
expect(handed('ActivityInstance', 'insert')).toMatchObject({ domainId: domain.id, creatorId: user.id,
|
|
59
|
+
expect(handed('ActivityInstance', 'insert')).toMatchObject({ domainId: domain.id, creatorId: user.id, assigneeRoleIds: [role.id] })
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
it('a new thread carries its domain and its assignee', async () => {
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { join } from 'path'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Putting a case in a role's pool at the same moment as something else, on postgres (ADR-0091 decision 9).
|
|
5
|
+
*
|
|
6
|
+
* Every way into a waiting case takes the case's row first and its threads after - pick, a pool assign,
|
|
7
|
+
* a member claiming the pool's waiting thread. sqlite holds one connection and cannot run two transactions
|
|
8
|
+
* side by side, so what it says about this is no evidence either way. Runs only when WORKLIST_PG_URL names a
|
|
9
|
+
* postgres server (see discard-versus-issue.pg.test.ts):
|
|
10
|
+
*
|
|
11
|
+
* docker run -d --name wl-ux-pg -e POSTGRES_PASSWORD=wlux -e POSTGRES_USER=wlux -e POSTGRES_DB=wlux \
|
|
12
|
+
* -p 55433:5432 postgres:14-alpine
|
|
13
|
+
* WORKLIST_PG_URL=postgres://wlux:wlux@localhost:55433/wlux npx jest packages/worklist/tests/role-pool-race.pg.test.ts
|
|
14
|
+
*
|
|
15
|
+
* Each round must end one way or the other, and whoever lost is refused by name - a deadlock, two waiting
|
|
16
|
+
* threads, a pool wiped by a stale save, or someone outside the role holding the case is the defect.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const url = process.env.WORKLIST_PG_URL
|
|
20
|
+
const maybe = url ? describe : describe.skip
|
|
21
|
+
|
|
22
|
+
/* Nobody here manages activity instances - the role is the only way in. */
|
|
23
|
+
jest.mock('@things-factory/auth-base', () => {
|
|
24
|
+
const actual = jest.requireActual('@things-factory/auth-base')
|
|
25
|
+
return { ...actual, checkPermission: async () => false }
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
maybe('a role pool at the same moment as something else, on postgres', () => {
|
|
29
|
+
const { DataSource } = require('typeorm')
|
|
30
|
+
const { entityClosure } = require(join(__dirname, '..', '..', 'ops-master', 'test', 'support', 'database.cjs'))
|
|
31
|
+
const { NamingStrategy } = require('@things-factory/shell/dist-server/initializers/naming-strategy.js')
|
|
32
|
+
const DIST = join(__dirname, '..', 'dist-server')
|
|
33
|
+
const { Activity } = require(join(DIST, 'service', 'activity', 'activity.js'))
|
|
34
|
+
const { ActivityInstance } = require(join(DIST, 'service', 'activity-instance', 'activity-instance.js'))
|
|
35
|
+
const { ActivityThread } = require(join(DIST, 'service', 'activity-thread', 'activity-thread.js'))
|
|
36
|
+
const { ActivityApproval } = require(join(DIST, 'service', 'activity-approval', 'activity-approval.js'))
|
|
37
|
+
const { assign } = require(join(DIST, 'controllers', 'activity-instance', 'assign.js'))
|
|
38
|
+
const { pick } = require(join(DIST, 'controllers', 'activity-instance', 'pick.js'))
|
|
39
|
+
const { start } = require(join(DIST, 'controllers', 'activity-thread', 'start.js'))
|
|
40
|
+
const { Domain } = require('@things-factory/shell')
|
|
41
|
+
const { Role, User } = require('@things-factory/auth-base')
|
|
42
|
+
|
|
43
|
+
/* The refusals a loser may get - by name, never a deadlock or a constraint error. */
|
|
44
|
+
const NAMED = [
|
|
45
|
+
'error.activity-approval taken by someone else',
|
|
46
|
+
'error.activity-instance is addressed to another role',
|
|
47
|
+
'error.activity-instance should not be assigned',
|
|
48
|
+
'error.not authorized to handle this task'
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
let db: any
|
|
52
|
+
let domain: any
|
|
53
|
+
let manager: any
|
|
54
|
+
let finance: any
|
|
55
|
+
let support: any
|
|
56
|
+
let inFinance: any
|
|
57
|
+
let inSupport: any
|
|
58
|
+
let outsider: any
|
|
59
|
+
let activity: any
|
|
60
|
+
|
|
61
|
+
beforeAll(async () => {
|
|
62
|
+
db = new DataSource({
|
|
63
|
+
type: 'postgres',
|
|
64
|
+
url,
|
|
65
|
+
synchronize: true,
|
|
66
|
+
dropSchema: true,
|
|
67
|
+
entities: entityClosure([Activity, ActivityInstance, ActivityThread, ActivityApproval]),
|
|
68
|
+
namingStrategy: new NamingStrategy()
|
|
69
|
+
})
|
|
70
|
+
await db.initialize()
|
|
71
|
+
|
|
72
|
+
domain = await db.getRepository(Domain).save({ name: 'd', subdomain: 'd' })
|
|
73
|
+
const person = (name: string) =>
|
|
74
|
+
db.getRepository(User).save({ name, email: `${name}@example.com`, password: 'x', status: 'activated', userType: 'user', domains: [domain] })
|
|
75
|
+
manager = await person('manager')
|
|
76
|
+
inFinance = await person('in-finance')
|
|
77
|
+
inSupport = await person('in-support')
|
|
78
|
+
outsider = await person('outsider')
|
|
79
|
+
finance = await db.getRepository(Role).save({ domain, name: 'finance', users: [inFinance] })
|
|
80
|
+
support = await db.getRepository(Role).save({ domain, name: 'support', users: [inSupport] })
|
|
81
|
+
activity = await db.getRepository(Activity).save({ domain, name: 'tax-invoice', activityType: 'standard', startingType: 'issue' })
|
|
82
|
+
}, 60000)
|
|
83
|
+
|
|
84
|
+
afterAll(async () => db?.destroy())
|
|
85
|
+
|
|
86
|
+
const as = (user: any) => (tx: any) => ({ state: { domain, user, tx }, t: (key: string) => key }) as any
|
|
87
|
+
const aCase = (name: string) => db.getRepository(ActivityInstance).save({ domain, name, state: 'issued', activity })
|
|
88
|
+
const threadsOf = (instance: any) => db.getRepository(ActivityThread).find({ where: { activityInstance: { id: instance.id } } })
|
|
89
|
+
const reread = (instance: any) => db.getRepository(ActivityInstance).findOne({ where: { id: instance.id }, relations: ['assigneeRoles'] })
|
|
90
|
+
const poolOf = (row: any) => (row?.assigneeRoles || []).map((role: any) => role.id).sort()
|
|
91
|
+
const toPool = (instance: any, role: any) => (tx: any) => assign({ id: instance.id, assigneeRoles: [role.id] }, as(manager)(tx))
|
|
92
|
+
|
|
93
|
+
/** Every loser was refused by one of the named refusals. */
|
|
94
|
+
const refusedByName = (results: PromiseSettledResult<any>[]) =>
|
|
95
|
+
results
|
|
96
|
+
.filter(one => one.status === 'rejected')
|
|
97
|
+
.forEach((one: any) => expect(NAMED).toContain(one.reason?.message))
|
|
98
|
+
|
|
99
|
+
it('two pool assigns at once: one waiting thread, in one of the two pools', async () => {
|
|
100
|
+
const endings: string[] = []
|
|
101
|
+
|
|
102
|
+
for (let round = 0; round < 20; round++) {
|
|
103
|
+
const instance = await aCase(`two-${round}`)
|
|
104
|
+
|
|
105
|
+
const results = await Promise.allSettled([db.transaction(toPool(instance, finance)), db.transaction(toPool(instance, support))])
|
|
106
|
+
refusedByName(results)
|
|
107
|
+
|
|
108
|
+
const threads = await threadsOf(instance)
|
|
109
|
+
const after = await reread(instance)
|
|
110
|
+
endings.push(`${results.filter(one => one.status === 'fulfilled').length} won`)
|
|
111
|
+
|
|
112
|
+
expect(threads.map((thread: any) => thread.state)).toEqual(['unassigned'])
|
|
113
|
+
expect([[finance.id], [support.id]]).toContainEqual(poolOf(after))
|
|
114
|
+
expect(after.threadsMin).toBe(1)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.log('endings', [...new Set(endings)].join(' · '))
|
|
118
|
+
}, 120000)
|
|
119
|
+
|
|
120
|
+
it('a pool assign and a pick by someone outside the role at once: exactly one wins', async () => {
|
|
121
|
+
const endings: string[] = []
|
|
122
|
+
|
|
123
|
+
for (let round = 0; round < 20; round++) {
|
|
124
|
+
const instance = await aCase(`pick-${round}`)
|
|
125
|
+
|
|
126
|
+
const [assigned, picked] = await Promise.allSettled([
|
|
127
|
+
db.transaction(toPool(instance, finance)),
|
|
128
|
+
db.transaction((tx: any) => pick(instance.id, as(outsider)(tx)))
|
|
129
|
+
])
|
|
130
|
+
refusedByName([assigned, picked])
|
|
131
|
+
|
|
132
|
+
const threads = await threadsOf(instance)
|
|
133
|
+
const after = await reread(instance)
|
|
134
|
+
endings.push(`assign ${assigned.status} · pick ${picked.status}`)
|
|
135
|
+
|
|
136
|
+
expect([assigned.status, picked.status].filter(status => status === 'fulfilled').length).toBe(1)
|
|
137
|
+
|
|
138
|
+
if (picked.status === 'fulfilled') {
|
|
139
|
+
expect(threads.map((thread: any) => [thread.state, thread.assigneeId])).toEqual([['assigned', outsider.id]])
|
|
140
|
+
expect(poolOf(after)).toEqual([])
|
|
141
|
+
} else {
|
|
142
|
+
expect(threads.map((thread: any) => thread.state)).toEqual(['unassigned'])
|
|
143
|
+
expect(poolOf(after)).toEqual([finance.id])
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
console.log('endings', [...new Set(endings)].join(' · '))
|
|
148
|
+
}, 120000)
|
|
149
|
+
|
|
150
|
+
it('moving a pool while a member of it claims the waiting thread: exactly one wins', async () => {
|
|
151
|
+
const endings: string[] = []
|
|
152
|
+
|
|
153
|
+
for (let round = 0; round < 20; round++) {
|
|
154
|
+
const instance = await aCase(`claim-${round}`)
|
|
155
|
+
await db.transaction(toPool(instance, finance))
|
|
156
|
+
const [waiting] = await threadsOf(instance)
|
|
157
|
+
|
|
158
|
+
const [moved, claimed] = await Promise.allSettled([
|
|
159
|
+
db.transaction(toPool(instance, support)),
|
|
160
|
+
db.transaction((tx: any) => start(waiting.id, {}, '', as(inFinance)(tx)))
|
|
161
|
+
])
|
|
162
|
+
refusedByName([moved, claimed])
|
|
163
|
+
|
|
164
|
+
const threads = await threadsOf(instance)
|
|
165
|
+
const after = await reread(instance)
|
|
166
|
+
endings.push(`move ${moved.status} · claim ${claimed.status}`)
|
|
167
|
+
|
|
168
|
+
expect([moved.status, claimed.status].filter(status => status === 'fulfilled').length).toBe(1)
|
|
169
|
+
expect(threads.length).toBe(1)
|
|
170
|
+
|
|
171
|
+
if (claimed.status === 'fulfilled') {
|
|
172
|
+
expect([threads[0].state, threads[0].assigneeId]).toEqual(['started', inFinance.id])
|
|
173
|
+
expect(poolOf(after)).toEqual([finance.id])
|
|
174
|
+
} else {
|
|
175
|
+
expect([threads[0].state, threads[0].assigneeId || null]).toEqual(['unassigned', null])
|
|
176
|
+
expect(poolOf(after)).toEqual([support.id])
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
console.log('endings', [...new Set(endings)].join(' · '))
|
|
181
|
+
}, 120000)
|
|
182
|
+
})
|
package/tests/work-door.test.ts
CHANGED
|
@@ -154,18 +154,18 @@ describe('work door standing', () => {
|
|
|
154
154
|
* door reaches nobody. One shared sentence would leave the reader with the wrong action.
|
|
155
155
|
*/
|
|
156
156
|
it('says an unassigned door reaches nobody, not that it passes through', () => {
|
|
157
|
-
const door = judgeDoor(assignment('작업 지시 배정', { installed: {
|
|
157
|
+
const door = judgeDoor(assignment('작업 지시 배정', { installed: { assigneeRoles: [] } }))
|
|
158
158
|
|
|
159
159
|
assert.equal(door.standing, 'off')
|
|
160
160
|
assert.equal(door.reason, 'no-assignee')
|
|
161
161
|
})
|
|
162
162
|
|
|
163
163
|
it('reads a bound role as standing and names it', () => {
|
|
164
|
-
const door = judgeDoor(assignment('정비 배정', { installed: {
|
|
164
|
+
const door = judgeDoor(assignment('정비 배정', { installed: { assigneeRoles: ['MAINTENANCE-LEAD', 'SHIFT-LEAD'] } }))
|
|
165
165
|
|
|
166
166
|
assert.equal(door.standing, 'on')
|
|
167
167
|
assert.equal(door.reason, 'assignee-bound')
|
|
168
|
-
assert.
|
|
168
|
+
assert.deepEqual(door.assigneeRoles, ['MAINTENANCE-LEAD', 'SHIFT-LEAD'])
|
|
169
169
|
})
|
|
170
170
|
|
|
171
171
|
/** An approval line on an assignment door is not what fills it, and must not read as standing. */
|
package/translations/en.json
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"error.activity-instance is already terminated": "this task ({id}) has already been terminated with the {state} status.",
|
|
39
39
|
"error.activity-instance approval line is set": "this task already has its approval line; it is set on the task's detail screen.",
|
|
40
40
|
"error.activity-instance assignee not in this domain": "these are not people of this site: {emails}",
|
|
41
|
+
"error.activity-instance a role is not an assignee": "a role cannot be an assignee - it would go to one person of the role. to give it to anyone of the role, set the assignee role.",
|
|
42
|
+
"error.activity-instance assign people or a role, not both": "assign it to people or to a role, not both at once.",
|
|
43
|
+
"error.activity-instance role not in this domain": "this role is not of this site: {role}",
|
|
44
|
+
"error.activity-instance assignee role named twice": "the same role is named more than once: {role}. name each role once.",
|
|
45
|
+
"error.activity-instance role has no members": "nobody holds the role {role}, so nobody would see this task. add people to the role first.",
|
|
41
46
|
"error.activity-instance draft is gone": "this draft went out or was thrown away in the meantime. please read the list again.",
|
|
42
47
|
"error.activity-instance not found": "this task ({activityInstance}) cannot be found.",
|
|
43
48
|
"error.activity-instance not a draft any more": "this draft has already gone out, so it cannot be thrown away.",
|
package/translations/es.json
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"error.activity-instance is already terminated": "esta tarea ({id}) ya finalizó con el estado {state}.",
|
|
39
39
|
"error.activity-instance approval line is set": "esta tarea ya tiene su línea de aprobación; se configura en la pantalla de detalle de la tarea.",
|
|
40
40
|
"error.activity-instance assignee not in this domain": "estas personas no pertenecen a este sitio: {emails}",
|
|
41
|
+
"error.activity-instance a role is not an assignee": "un rol no puede ser asignado: llegaría a una sola persona del rol. para dárselo a cualquiera del rol, indique el rol asignado.",
|
|
42
|
+
"error.activity-instance assign people or a role, not both": "asígnelo a personas o a un rol, no a ambos a la vez.",
|
|
43
|
+
"error.activity-instance role not in this domain": "este rol no pertenece a este sitio: {role}",
|
|
44
|
+
"error.activity-instance assignee role named twice": "el mismo rol aparece más de una vez: {role}. indique cada rol una sola vez.",
|
|
45
|
+
"error.activity-instance role has no members": "nadie tiene el rol {role}, así que nadie vería esta tarea. añada personas al rol primero.",
|
|
41
46
|
"error.activity-instance draft is gone": "este borrador se envió o se descartó mientras tanto. vuelva a cargar la lista.",
|
|
42
47
|
"error.activity-instance not found": "no se encuentra esta tarea ({activityInstance}).",
|
|
43
48
|
"error.activity-instance not a draft any more": "este borrador ya se envió, así que no se puede descartar.",
|
package/translations/ja.json
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"error.activity-instance is already terminated": "このタスク({id})はすでに{state}状態で終了しています。",
|
|
39
39
|
"error.activity-instance approval line is set": "この業務は決裁ラインが決まっています。決裁ラインは業務詳細で変更します。",
|
|
40
40
|
"error.activity-instance assignee not in this domain": "このサイトの人ではありません: {emails}",
|
|
41
|
+
"error.activity-instance a role is not an assignee": "割当者に役割は指定できません。役割の一人にしか届きません。その役割の誰にでも任せるには割当役割を指定してください。",
|
|
42
|
+
"error.activity-instance assign people or a role, not both": "人か役割のどちらか一方に割り当ててください。",
|
|
43
|
+
"error.activity-instance role not in this domain": "このサイトの役割ではありません: {role}",
|
|
44
|
+
"error.activity-instance assignee role named twice": "同じ役割が複数回指定されています: {role}。役割はそれぞれ一度だけ指定してください。",
|
|
45
|
+
"error.activity-instance role has no members": "役割 {role} に人がいないため、誰もこの業務を見られません。先に役割に人を追加してください。",
|
|
41
46
|
"error.activity-instance draft is gone": "この下書きはその間に発行されたか破棄されました。一覧を読み直してください。",
|
|
42
47
|
"error.activity-instance not found": "このタスク({activityInstance})が見つかりません。",
|
|
43
48
|
"error.activity-instance not a draft any more": "この下書きはすでに発行されたため、破棄できません。",
|
package/translations/ko.json
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"error.activity-instance is already terminated": "이 작업({id})는 이미 {state} 상태로 종료되었습니다.",
|
|
39
39
|
"error.activity-instance approval line is set": "이 업무에는 결재선이 지정되어 있습니다. 업무 상세 화면에서 결재선을 변경해 주세요.",
|
|
40
40
|
"error.activity-instance assignee not in this domain": "이 사업장 사람이 아닙니다: {emails}",
|
|
41
|
+
"error.activity-instance a role is not an assignee": "피할당자에는 역할을 넣을 수 없습니다. 역할 중 한 사람에게만 갑니다. 그 역할의 누구에게나 맡기려면 피할당 역할을 지정해 주세요.",
|
|
42
|
+
"error.activity-instance assign people or a role, not both": "사람과 역할 중 하나에만 할당할 수 있습니다.",
|
|
43
|
+
"error.activity-instance role not in this domain": "이 사업장의 역할이 아닙니다: {role}",
|
|
44
|
+
"error.activity-instance assignee role named twice": "같은 역할을 두 번 이상 넣었습니다: {role}. 역할마다 한 번씩만 넣어 주세요.",
|
|
45
|
+
"error.activity-instance role has no members": "{role} 역할에 사람이 없어 아무도 이 업무를 볼 수 없습니다. 먼저 역할에 사람을 넣어 주세요.",
|
|
41
46
|
"error.activity-instance draft is gone": "이 초안은 그사이 발행되었거나 버려졌습니다. 목록을 새로 읽어 주십시오.",
|
|
42
47
|
"error.activity-instance not found": "이 작업({activityInstance})을 찾을 수 없습니다.",
|
|
43
48
|
"error.activity-instance not a draft any more": "이 초안은 이미 발행되어 버릴 수 없습니다.",
|
package/translations/ms.json
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"error.activity-instance is already terminated": "Tugas ini ({id}) telah tamat dengan status {state}.",
|
|
39
39
|
"error.activity-instance approval line is set": "tugas ini sudah mempunyai laluan kelulusan; ia ditetapkan pada skrin butiran tugas.",
|
|
40
40
|
"error.activity-instance assignee not in this domain": "ini bukan orang dalam domain ini: {emails}",
|
|
41
|
+
"error.activity-instance a role is not an assignee": "peranan tidak boleh menjadi penerima tugasan - ia akan pergi kepada seorang sahaja daripada peranan itu. untuk memberikannya kepada sesiapa dalam peranan itu, tetapkan peranan penerima.",
|
|
42
|
+
"error.activity-instance assign people or a role, not both": "tugaskan kepada orang atau kepada peranan, bukan kedua-duanya sekali.",
|
|
43
|
+
"error.activity-instance role not in this domain": "peranan ini bukan dari domain ini: {role}",
|
|
44
|
+
"error.activity-instance assignee role named twice": "peranan yang sama dinamakan lebih daripada sekali: {role}. namakan setiap peranan sekali sahaja.",
|
|
45
|
+
"error.activity-instance role has no members": "tiada sesiapa memegang peranan {role}, jadi tiada sesiapa akan melihat tugas ini. tambah orang ke peranan itu dahulu.",
|
|
41
46
|
"error.activity-instance draft is gone": "draf ini telah dikeluarkan atau dibuang sementara itu. sila baca senarai semula.",
|
|
42
47
|
"error.activity-instance not found": "Tugas ini ({activityInstance}) tidak dijumpai.",
|
|
43
48
|
"error.activity-instance not a draft any more": "draf ini sudah dikeluarkan, jadi ia tidak boleh dibuang.",
|
package/translations/zh.json
CHANGED
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"error.activity-instance is already terminated": "此任务({id})已以{state}状态终止。",
|
|
39
39
|
"error.activity-instance approval line is set": "此业务已设定审批线,请在业务详情中修改。",
|
|
40
40
|
"error.activity-instance assignee not in this domain": "以下不是本站点的人员:{emails}",
|
|
41
|
+
"error.activity-instance a role is not an assignee": "角色不能作为被分配人——只会分给该角色中的一个人。要交给该角色的任何人,请指定被分配角色。",
|
|
42
|
+
"error.activity-instance assign people or a role, not both": "只能分配给人员或角色之一,不能同时分配。",
|
|
43
|
+
"error.activity-instance role not in this domain": "此角色不属于本站点:{role}",
|
|
44
|
+
"error.activity-instance assignee role named twice": "同一角色被指定了多次:{role}。每个角色只能指定一次。",
|
|
45
|
+
"error.activity-instance role has no members": "角色 {role} 中没有人员,没有人能看到此任务。请先为该角色添加人员。",
|
|
41
46
|
"error.activity-instance draft is gone": "此草稿在此期间已发布或已丢弃,请重新读取列表。",
|
|
42
47
|
"error.activity-instance not found": "未找到此任务({activityInstance})。",
|
|
43
48
|
"error.activity-instance not a draft any more": "此草稿已发布,无法丢弃。",
|