@things-factory/auth-ui 10.1.46 → 10.1.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/auth-ui",
3
- "version": "10.1.46",
3
+ "version": "10.1.47",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -31,18 +31,18 @@
31
31
  "@operato/attribute": "^10.0.0",
32
32
  "@operato/data-grist": "^10.19.0",
33
33
  "@operato/i18n": "^10.0.0",
34
- "@operato/layout": "^10.0.0",
34
+ "@operato/layout": "^10.26.0",
35
35
  "@operato/list-state": "^10.15.0",
36
36
  "@operato/lottie-player": "^10.0.0",
37
37
  "@operato/moment-timezone-es": "^10.0.0",
38
38
  "@operato/p13n": "^10.0.0",
39
39
  "@operato/popup": "^10.15.0",
40
40
  "@operato/styles": "^10.0.0",
41
- "@things-factory/auth-base": "^10.1.46",
42
- "@things-factory/component-ui": "^10.1.46",
43
- "@things-factory/more-base": "^10.1.46",
41
+ "@things-factory/auth-base": "^10.1.47",
42
+ "@things-factory/component-ui": "^10.1.47",
43
+ "@things-factory/more-base": "^10.1.47",
44
44
  "base64url": "^3.0.1",
45
45
  "clipboard": "^2.0.6"
46
46
  },
47
- "gitHead": "d3467cde550453f3348fed0ed6c79a12a6ba0db4"
47
+ "gitHead": "185f20d7d9a15715a0ee2757a6a8189ec36cfb9d"
48
48
  }
@@ -0,0 +1,85 @@
1
+ import { readFileSync } from 'fs'
2
+ import path from 'path'
3
+
4
+ /**
5
+ * The person 360 (ADR-0067 person 360 ruling): auth-ui declares the kind, and three modules each hang
6
+ * a section read through its own door. How a door's answer becomes none / may-not-see / failed is
7
+ * tested where it lives (@operato/layout `entity360-section.test.ts`); this holds what the three
8
+ * sections do with it. The sections need a DOM, so the test reads their source with comments stripped.
9
+ */
10
+
11
+ const PACKAGES = path.resolve(__dirname, '../..')
12
+ const read = (file: string) =>
13
+ readFileSync(path.join(PACKAGES, file), 'utf-8')
14
+ .replace(/\/\*[\s\S]*?\*\//g, '')
15
+ .replace(/^\s*\/\/.*$/gm, '')
16
+
17
+ const SECTIONS = {
18
+ roles: { file: 'auth-ui/client/entity360/person-360.ts', register: 'registerPersonKind', bootstrap: 'auth-ui' },
19
+ membership: {
20
+ file: 'organization/client/entity360/person-membership-section.ts',
21
+ register: 'registerPersonMembershipSection',
22
+ bootstrap: 'organization'
23
+ },
24
+ 'open-work': {
25
+ file: 'worklist/client/entity360/person-open-work-section.ts',
26
+ register: 'registerPersonOpenWorkSection',
27
+ bootstrap: 'worklist'
28
+ }
29
+ }
30
+
31
+ describe('the person 360 sections', () => {
32
+ it('★ a User value opens the person kind', () => {
33
+ expect(read(SECTIONS.roles.file)).toMatch(/kind: 'person',\s*typenames: \['User'\]/)
34
+ })
35
+
36
+ it.each(Object.entries(SECTIONS))('★ %s is hung on person and its module bootstrap registers it', (name, one) => {
37
+ const code = read(one.file)
38
+ expect(code).toMatch(new RegExp(`registerEntity360Section\\('person', \\{\\s*name: '${name}'`))
39
+ const bootstrap = read(`${one.bootstrap}/client/bootstrap.ts`)
40
+ expect(bootstrap).toMatch(new RegExp(`\\n\\s*${one.register}\\(\\)`))
41
+ /* Without a semicolon, a next statement that opens with [ or ( is read as part of this call -
42
+ worklist's bootstrap broke the 10.1.47 build that way (registerPersonOpenWorkSection()[...]). */
43
+ const after = bootstrap.slice(bootstrap.indexOf(`${one.register}()`) + `${one.register}()`.length)
44
+ const next = after.replace(/^;/, '').trimStart()
45
+ if (/^[[(`]/.test(next)) expect(after.startsWith(';')).toBe(true)
46
+ })
47
+
48
+ it.each(Object.entries(SECTIONS))(
49
+ '★ %s shows its door answer through the shared section frame, never its own none',
50
+ (_, one) => {
51
+ const code = read(one.file)
52
+ expect(code).toMatch(/this\.answer = readEntity360Door\(response,/)
53
+ expect(code).toMatch(/<ox-entity360-section[\s\S]*\.state=\$\{answer\?\.state \?\? 'loading'\}/)
54
+ expect(code).toMatch(/\.message=\$\{answer\?\.message \?\? ''\}/)
55
+ }
56
+ )
57
+
58
+ it.each(Object.entries(SECTIONS))('%s drops an answer for a subject that is no longer shown', (_, one) => {
59
+ expect(read(one.file)).toMatch(/await client\.query[\s\S]*if \(this\.subject\?\.id !== id\) return\s*this\.answer =/)
60
+ })
61
+
62
+ it("★ roles are this site's - read through userRoles, never User.roles which answers every domain", () => {
63
+ const code = read(SECTIONS.roles.file)
64
+ expect(code).toMatch(/userRoles\(userId: \$userId\)/)
65
+ expect(code).toMatch(/\.filter\(\(role: any\) => role\.assigned\)/)
66
+ expect(code).not.toMatch(/\broles\s*\{/)
67
+ })
68
+
69
+ it('★ open work is counts only - the items stay with the person and the site owner', () => {
70
+ const query = read(SECTIONS['open-work'].file).match(/gql`([\s\S]*?)`/)![1]
71
+ expect(query.replace(/\s+/g, ' ').trim()).toBe(
72
+ 'query ($userId: String!) { personOpenWork(userId: $userId) { toDos approvalsPending } }'
73
+ )
74
+ })
75
+
76
+ it('membership reads this person only', () => {
77
+ expect(read(SECTIONS.membership.file)).toMatch(/filters: \[\{ name: 'userId', operator: 'eq', value: id \}\]/)
78
+ })
79
+
80
+ it('the dock reads who they are, then what they hold, then their roles', () => {
81
+ const order = (one: { file: string }) => Number(read(one.file).match(/order: (\d+)/)![1])
82
+ expect(order(SECTIONS.membership)).toBeLessThan(order(SECTIONS['open-work']))
83
+ expect(order(SECTIONS['open-work'])).toBeLessThan(order(SECTIONS.roles))
84
+ })
85
+ })
@@ -2,7 +2,6 @@
2
2
  "button.accept invitation": "accept invitation",
3
3
  "button.activate": "activate",
4
4
  "button.add what it can do": "Add what it can do",
5
- "button.cancel": "cancel",
6
5
  "button.close": "Close",
7
6
  "button.confirm": "confirm",
8
7
  "button.copy": "copy",
@@ -40,7 +39,6 @@
40
39
  "button.terminate contract": "terminate",
41
40
  "button.transfer owner": "transfer owner",
42
41
  "button.unlock": "unlock",
43
- "button.update": "update",
44
42
  "button.withdraw": "withdraw",
45
43
  "error.cannot_modify_system_subdomain": "the 'system' subdomain cannot be modified.",
46
44
  "error.domain not allowed": "the '{subdomain}' domain is not allowed for this user.",
@@ -69,28 +67,20 @@
69
67
  "field.confirm password": "confirm password",
70
68
  "field.contact email": "contact email",
71
69
  "field.created at": "created at",
72
- "field.description": "description",
73
- "field.email": "email address",
74
70
  "field.entity": "entity",
75
71
  "field.expires at": "expires at",
76
72
  "field.forgot-password": "forgot password",
77
73
  "field.granted at": "granted at",
78
74
  "field.granted by": "granted by",
79
75
  "field.granted privileges": "What it can do",
80
- "field.hidden": "hidden",
81
76
  "field.invited": "invited",
82
77
  "field.ip_address": "IP address",
83
- "field.model": "model",
84
78
  "field.module": "Module",
85
- "field.name": "name",
86
- "field.netmask": "netmask",
87
- "field.options": "options",
88
79
  "field.owner": "owner",
89
80
  "field.owner-user": "owner",
90
81
  "field.parent-domain": "parent domain",
91
82
  "field.password": "password",
92
83
  "field.private-key": "private key",
93
- "field.reason": "reason",
94
84
  "field.reason (optional)": "reason (optional)",
95
85
  "field.redirect url": "redirect url",
96
86
  "field.required privilege": "required privilege",
@@ -105,7 +95,6 @@
105
95
  "field.source-domain": "source domain",
106
96
  "field.state": "state",
107
97
  "field.status": "status",
108
- "field.tag": "tag",
109
98
  "field.target-domain": "target domain",
110
99
  "field.tenant-id": "tenant id",
111
100
  "field.token": "token",
@@ -139,7 +128,6 @@
139
128
  "label.customers": "customers",
140
129
  "label.delete account": "delete account",
141
130
  "label.deleted-user": "deleted",
142
- "label.description": "description",
143
131
  "label.domain": "domain",
144
132
  "label.domain-owner": "domain owner",
145
133
  "label.draft": "draft",
@@ -154,7 +142,6 @@
154
142
  "label.language": "language",
155
143
  "label.locked-user": "locked",
156
144
  "label.login_history": "login history",
157
- "label.name": "name",
158
145
  "label.ours": "Ours",
159
146
  "label.password": "password",
160
147
  "label.privilege": "privilege",
@@ -227,7 +214,6 @@
227
214
  "text.current password": "current password",
228
215
  "text.delete account warning message": "this action cannot be undone. this will permanently delete all about this account.\n\nplease type in the email and password of this account to confirm.",
229
216
  "text.deleted_successfully": "deleted successfully",
230
- "text.do_you_want_to_create_role": "do you want to create role?",
231
217
  "text.do_you_want_to_create_x": "do you want to create {x} ?",
232
218
  "text.do_you_want_to_invite_x": "do you want to invite {x}",
233
219
  "text.domain management": "domain management",
@@ -249,7 +235,6 @@
249
235
  "text.invalid-email": "that is not an email address",
250
236
  "text.invalid-username": "use an id or an email address",
251
237
  "text.invitation resent": "invitation sent again.",
252
- "text.loading": "loading…",
253
238
  "text.missing against template": "{count} missing",
254
239
  "text.new password": "new password",
255
240
  "text.no account and no default password": "No account uses this address, and this system has no default password. They have to sign up first.",
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "button.accept invitation": "招待を受ける",
3
3
  "button.activate": "アクティブ化",
4
- "button.cancel": "キャンセル",
5
4
  "button.close": "閉じる",
6
5
  "button.confirm": "確認",
7
6
  "button.copy": "コピー",
@@ -34,7 +33,6 @@
34
33
  "button.submit": "送信",
35
34
  "button.terminate contract": "契約解除",
36
35
  "button.transfer owner": "管理者付与",
37
- "button.update": "更新",
38
36
  "button.withdraw": "招待を取り消す",
39
37
  "error.cannot_modify_system_subdomain": "'system'サブドメインは変更できません。",
40
38
  "error.domain not allowed": "この$t(term.domain)は許可されていません.",
@@ -63,18 +61,11 @@
63
61
  "field.confirm password": "パスワード確認",
64
62
  "field.contact email": "連絡先メール",
65
63
  "field.created at": "送信日時",
66
- "field.description": "説明",
67
- "field.email": "メール",
68
64
  "field.entity": "エンティティ",
69
65
  "field.expires at": "有効期限",
70
66
  "field.forgot-password": "パスワードを忘れましたか?",
71
- "field.hidden": "隠し",
72
67
  "field.invited": "招待",
73
68
  "field.ip_address": "IPアドレス",
74
- "field.model": "モデル",
75
- "field.name": "名前",
76
- "field.netmask": "ネットマスク",
77
- "field.options": "オプション",
78
69
  "field.owner": "管理者",
79
70
  "field.owner-user": "管理者",
80
71
  "field.parent-domain": "親$t(term.domain)",
@@ -92,7 +83,6 @@
92
83
  "field.source-domain": "ソース$t(term.domain)",
93
84
  "field.state": "状態",
94
85
  "field.status": "状態",
95
- "field.tag": "タグ",
96
86
  "field.target-domain": "ターゲット$t(term.domain)",
97
87
  "field.tenant-id": "テナントID",
98
88
  "field.token": "認証トークン",
@@ -120,7 +110,6 @@
120
110
  "label.customers": "顧客",
121
111
  "label.delete account": "アカウント削除",
122
112
  "label.deleted-user": "削除済み",
123
- "label.description": "説明",
124
113
  "label.domain": "$t(term.domain)",
125
114
  "label.domain-owner": "$t(term.domain)オーナー",
126
115
  "label.draft": "下書き",
@@ -133,7 +122,6 @@
133
122
  "label.language": "言語",
134
123
  "label.locked-user": "ロック",
135
124
  "label.login_history": "ログイン履歴",
136
- "label.name": "名前",
137
125
  "label.password": "パスワード",
138
126
  "label.privilege": "特権",
139
127
  "label.protected-request-ip": "安全なリクエスト IP",
@@ -293,5 +281,73 @@
293
281
  "title.secure-ip-list": "セキュアな IP リスト",
294
282
  "title.sign in": "ログイン",
295
283
  "title.sign up": "ユーザー登録",
296
- "title.unlock account": "アカウントロック解除"
284
+ "title.unlock account": "アカウントロック解除",
285
+ "button.add what it can do": "できることを追加",
286
+ "button.drop": "外す",
287
+ "button.edit privileges": "権限を編集",
288
+ "button.remove from domain": "$t(term.domain)から外す",
289
+ "button.remove owner": "オーナーを解除",
290
+ "button.unlock": "ロック解除",
291
+ "field.granted at": "付与日時",
292
+ "field.granted by": "付与者",
293
+ "field.granted privileges": "できること",
294
+ "field.module": "モジュール",
295
+ "field.reason (optional)": "理由(任意)",
296
+ "field.source": "出所",
297
+ "field.username or email": "ユーザー名またはメール",
298
+ "label.add role": "ロールを追加",
299
+ "label.add to domain": "$t(term.domain)に追加",
300
+ "label.add user": "ユーザーを追加",
301
+ "label.all": "すべて",
302
+ "label.create account and add": "アカウントを作成して追加",
303
+ "label.execute": "実行",
304
+ "label.inherited": "継承",
305
+ "label.ours": "自分のロール",
306
+ "label.read": "読み取り",
307
+ "label.write": "書き込み",
308
+ "text.account exists so joins immediately": "このアカウントはすでにあります。追加するとすぐに入れます。",
309
+ "text.account will be created with the default password": "このメールで登録されたアカウントはありません。既定のパスワードでアカウントを作成して追加します。パスワードはご自身で伝えてください。",
310
+ "text.add_domain_owner_description": "$t(term.domain)のメンバーの一人にオーナー権限を付与します。",
311
+ "text.and x more": "ほか{x}件",
312
+ "text.are_you_sure_to_remove_domain_owner": "{x} を$t(term.domain)のオーナーから解除しますか?",
313
+ "text.cannot be undone": "元に戻せない操作",
314
+ "text.domain owner added successfully": "$t(term.domain)のオーナーを追加しました",
315
+ "text.domain owner removed successfully": "$t(term.domain)のオーナーを解除しました",
316
+ "text.domain owners": "$t(term.domain)のオーナー",
317
+ "text.failed": "失敗",
318
+ "text.failed to fetch": "一覧を読み込めませんでした",
319
+ "text.filter by module name": "モジュール名で絞り込み",
320
+ "text.inherited roles are edited in their own domain": "これらのロールは上位の$t(term.domain)で定義されており、そちらでのみ変更できます。",
321
+ "text.no account and no default password": "このメールで登録されたアカウントがなく、このシステムには既定のパスワードもありません。先にご本人が登録する必要があります。",
322
+ "text.no description for this privilege": "この権限の説明はまだありません。",
323
+ "text.no description for this role": "説明はまだありません — ロール一覧で書けます。",
324
+ "text.no one holds this role yet": "このロールを持つ人はまだいません。",
325
+ "text.no other user yet": "まだ他のユーザーはいません",
326
+ "text.no privilege declared in this deployment": "このデプロイで宣言された権限はまだありません。ロールに付けるものがありません。",
327
+ "text.no privilege granted": "何も開かない",
328
+ "text.no role assigned": "ロールなし",
329
+ "text.no role defined in this domain": "この$t(term.domain)にはロールがありません。付与する前にロールを作成してください。",
330
+ "text.no role yet": "まだ定義されたロールはありません",
331
+ "text.none on": "なし",
332
+ "text.not declared for this module": "このモジュールにはその権限が宣言されていません。",
333
+ "text.nothing is on for this role yet": "このロールはまだ何も開きません。下でできることを追加してください。",
334
+ "text.nothing matches x": "「{x}」を含むモジュール名はありません。",
335
+ "text.owner opens everything without a role": "オーナーはロールなしですべての画面を開けます。他のユーザーにはロールが必要です。",
336
+ "text.password becomes the default and must be told to them": "パスワードは既定値に戻ります。メールは送られないので、新しいパスワードはご自身で伝えてください。",
337
+ "text.pick a module on the left": "左でモジュールを選ぶと、このロールがそのモジュールで何をできるかが表示されます。",
338
+ "text.please enter username or email": "ユーザー名またはメールを入力してください",
339
+ "text.please try again": "しばらくしてからもう一度お試しください。",
340
+ "text.remove the role from x people first": "このロールを削除するには、まず持っている {x} 人から外してください。",
341
+ "text.role belongs to x domain and is edited there": "このロールは {x} で定義されており、そちらでのみ編集できます。ここで付与できるため一覧に表示されています。",
342
+ "text.roles in use are kept": "誰かが持っているロールは残します。使われていないものだけ削除されます。",
343
+ "text.they lose access to this domain but keep the account": "この$t(term.domain)では作業できなくなります。アカウントは残るので、後で再び追加できます。",
344
+ "text.unlocks in x minutes": "{x}分後にロック解除",
345
+ "text.view only": "継承ロール — 閲覧のみ",
346
+ "text.without a role they see nothing": "ロールを決めないと、入っても見られる画面がありません。",
347
+ "text.x is required": "{x}を入力してください。",
348
+ "text.x of y on": "{y}件中{x}件オン",
349
+ "text.x on": "{x}件オン",
350
+ "text.x people hold this role": "このロールを持つ人 {x}名",
351
+ "title.add domain owner": "$t(term.domain)のオーナーを追加",
352
+ "title.role privileges": "ロールの権限"
297
353
  }
@@ -2,7 +2,6 @@
2
2
  "button.accept invitation": "초대 수락",
3
3
  "button.activate": "활성화",
4
4
  "button.add what it can do": "할 수 있는 일 더하기",
5
- "button.cancel": "취소",
6
5
  "button.close": "닫기",
7
6
  "button.confirm": "확인",
8
7
  "button.copy": "복사",
@@ -40,7 +39,6 @@
40
39
  "button.terminate contract": "계약 해지",
41
40
  "button.transfer owner": "관리자 부여",
42
41
  "button.unlock": "잠금 해제",
43
- "button.update": "수정",
44
42
  "button.withdraw": "초대 취소",
45
43
  "error.cannot_modify_system_subdomain": "'system' 서브도메인은 수정할 수 없습니다.",
46
44
  "error.domain not allowed": "'{subdomain}' 영역은 이 사용자에게 허가되지 않았습니다.",
@@ -69,28 +67,20 @@
69
67
  "field.confirm password": "비밀번호 확인",
70
68
  "field.contact email": "연락 이메일",
71
69
  "field.created at": "보낸 시점",
72
- "field.description": "설명",
73
- "field.email": "이메일",
74
70
  "field.entity": "개체",
75
71
  "field.expires at": "만료 시점",
76
72
  "field.forgot-password": "암호가 기억나지 않나요?",
77
73
  "field.granted at": "부여 시각",
78
74
  "field.granted by": "권한 부여자",
79
75
  "field.granted privileges": "할 수 있는 일",
80
- "field.hidden": "감추기",
81
76
  "field.invited": "초대",
82
77
  "field.ip_address": "IP 주소",
83
- "field.model": "모델",
84
78
  "field.module": "모듈",
85
- "field.name": "이름",
86
- "field.netmask": "네트워크 마스크",
87
- "field.options": "옵션",
88
79
  "field.owner": "소유자",
89
80
  "field.owner-user": "소유자",
90
81
  "field.parent-domain": "부모$t(term.domain)",
91
82
  "field.password": "비밀번호",
92
83
  "field.private-key": "private key",
93
- "field.reason": "사유",
94
84
  "field.reason (optional)": "사유 (선택)",
95
85
  "field.redirect url": "리다이렉트 주소",
96
86
  "field.required privilege": "필수 권한",
@@ -105,7 +95,6 @@
105
95
  "field.source-domain": "소스 $t(term.domain)",
106
96
  "field.state": "상태",
107
97
  "field.status": "상태",
108
- "field.tag": "태그",
109
98
  "field.target-domain": "타겟 $t(term.domain)",
110
99
  "field.tenant-id": "tenant id",
111
100
  "field.token": "인증 토큰",
@@ -139,7 +128,6 @@
139
128
  "label.customers": "고객",
140
129
  "label.delete account": "계정 삭제",
141
130
  "label.deleted-user": "삭제됨",
142
- "label.description": "설명",
143
131
  "label.domain": "$t(term.domain)",
144
132
  "label.domain-owner": "$t(term.domain) 관리자",
145
133
  "label.draft": "초안",
@@ -154,7 +142,6 @@
154
142
  "label.language": "언어",
155
143
  "label.locked-user": "잠김",
156
144
  "label.login_history": "로그인 이력",
157
- "label.name": "이름",
158
145
  "label.ours": "우리 역할",
159
146
  "label.password": "비밀번호",
160
147
  "label.privilege": "권한",
@@ -248,7 +235,6 @@
248
235
  "text.invalid-email": "이메일 주소 형식이 맞지 않습니다",
249
236
  "text.invalid-username": "아이디나 이메일 주소를 적으십시오",
250
237
  "text.invitation resent": "초대 메일을 다시 보냈습니다.",
251
- "text.loading": "읽는 중…",
252
238
  "text.missing against template": "{count}개 빠짐",
253
239
  "text.new password": "새 비밀번호",
254
240
  "text.no account and no default password": "이 이메일로 가입한 계정이 없고, 이 시스템에는 기본 비밀번호가 설정되어 있지 않습니다. 그 사람이 먼저 가입해야 부를 수 있습니다.",
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "button.accept invitation": "terima jemputan",
3
3
  "button.activate": "aktifkan",
4
- "button.cancel": "batalkan",
5
4
  "button.close": "tutup",
6
5
  "button.confirm": "sahkan",
7
6
  "button.copy": "salin",
@@ -34,7 +33,6 @@
34
33
  "button.submit": "hantar",
35
34
  "button.terminate contract": "tamatkan",
36
35
  "button.transfer owner": "pindah pemilik",
37
- "button.update": "kemas kini",
38
36
  "button.withdraw": "tarik balik",
39
37
  "error.cannot_modify_system_subdomain": "subdomain 'system' tidak boleh diubah.",
40
38
  "error.domain not allowed": "domain ini tidak dibenarkan untuk anda",
@@ -63,18 +61,11 @@
63
61
  "field.confirm password": "sahkan kata laluan",
64
62
  "field.contact email": "emel untuk dihubungi",
65
63
  "field.created at": "dihantar pada",
66
- "field.description": "penerangan",
67
- "field.email": "e-mel",
68
64
  "field.entity": "entiti",
69
65
  "field.expires at": "tamat pada",
70
66
  "field.forgot-password": "terlupa kata laluan",
71
- "field.hidden": "tersembunyi",
72
67
  "field.invited": "dijemput",
73
68
  "field.ip_address": "alamat IP",
74
- "field.model": "model",
75
- "field.name": "nama",
76
- "field.netmask": "netmask",
77
- "field.options": "pilihan",
78
69
  "field.owner": "pemilik",
79
70
  "field.owner-user": "pemilik",
80
71
  "field.parent-domain": "domain induk",
@@ -92,7 +83,6 @@
92
83
  "field.source-domain": "domain sumber",
93
84
  "field.state": "keadaan",
94
85
  "field.status": "status",
95
- "field.tag": "tag",
96
86
  "field.target-domain": "domain sasaran",
97
87
  "field.tenant-id": "ID penyewa",
98
88
  "field.token": "token",
@@ -120,7 +110,6 @@
120
110
  "label.customers": "pelanggan",
121
111
  "label.delete account": "hapuskan akaun",
122
112
  "label.deleted-user": "pengguna dihapus",
123
- "label.description": "penerangan",
124
113
  "label.domain": "domain",
125
114
  "label.domain-owner": "pemilik domain",
126
115
  "label.draft": "draf",
@@ -133,7 +122,6 @@
133
122
  "label.language": "bahasa",
134
123
  "label.locked-user": "dikunci",
135
124
  "label.login_history": "sejarah log masuk",
136
- "label.name": "nama",
137
125
  "label.password": "kata laluan",
138
126
  "label.privilege": "keistimewaan",
139
127
  "label.protected-request-ip": "IP permintaan yang selamat",
@@ -197,11 +185,10 @@
197
185
  "text.current password": "kata laluan terkini",
198
186
  "text.delete account warning message": "langkah hapuskan akaun tidak boleh diundur.\n\nsila masukkan emel dan kata laluan akaun anda untuk mengesahkan penghapusan akaun.",
199
187
  "text.deleted_successfully": "berjaya dihapuskan",
200
- "text.do_you_want_to_create_role": "adakah anda hendak membina peranan?",
201
188
  "text.do_you_want_to_create_x": "adakah anda mahu mencipta {x}?",
202
189
  "text.do_you_want_to_invite_x": "adakah anda ingin mengundang {x}",
203
190
  "text.domain management": "pengurusan domain",
204
- "text.domain sumber dan sasaran tidak boleh sama": "domain sumber dan sasaran tidak boleh sama",
191
+ "text.source_and_target_domain_cannot_be_same": "domain sumber dan sasaran tidak boleh sama",
205
192
  "text.domain_name_change_warning": "adakah anda pasti mahu menukar nama domain? (subdomain akan kekal tidak berubah.)",
206
193
  "text.email is not matched": "alamat email tidak sepadan",
207
194
  "text.endpoints": "titik akhir",
@@ -236,7 +223,7 @@
236
223
  "text.should select at least one of x": "sila pilih antara satu {x}",
237
224
  "text.signed in": "telah log masuk",
238
225
  "text.signed out": "telah log keluar",
239
- "text.sila isi semua medan yang diperlukan": "sila isi semua medan yang diperlukan",
226
+ "text.please_fill_all_required_fields": "sila isi semua medan yang diperlukan",
240
227
  "text.stand this domain own role of the same name": "{name} ditakrifkan dalam {domain} dan sudah kelihatan di sini. Bina milik domain ini dengan nama yang sama hanya jika anda berniat menggantikan yang diwarisi — namanya kekal sama.",
241
228
  "text.start from a blank seat": "start from a blank seat",
242
229
  "text.struck through are not installed here": "Struck through are privileges this installation does not have.",
@@ -294,5 +281,73 @@
294
281
  "title.secure-ip-list": "senarai IP yang selamat",
295
282
  "title.sign in": "log masuk",
296
283
  "title.sign up": "daftar",
297
- "title.unlock account": "buka semula akaun"
284
+ "title.unlock account": "buka semula akaun",
285
+ "button.add what it can do": "tambah apa yang boleh dilakukan",
286
+ "button.drop": "tanggalkan",
287
+ "button.edit privileges": "sunting keistimewaan",
288
+ "button.remove from domain": "keluarkan dari $t(term.domain)",
289
+ "button.remove owner": "buang pemilik",
290
+ "button.unlock": "buka kunci",
291
+ "field.granted at": "diberi pada",
292
+ "field.granted by": "diberi oleh",
293
+ "field.granted privileges": "apa yang boleh dilakukan",
294
+ "field.module": "modul",
295
+ "field.reason (optional)": "sebab (pilihan)",
296
+ "field.source": "sumber",
297
+ "field.username or email": "nama pengguna atau e-mel",
298
+ "label.add role": "tambah peranan",
299
+ "label.add to domain": "tambah ke $t(term.domain)",
300
+ "label.add user": "tambah pengguna",
301
+ "label.all": "semua",
302
+ "label.create account and add": "cipta akaun dan tambah",
303
+ "label.execute": "laksana",
304
+ "label.inherited": "diwarisi",
305
+ "label.ours": "peranan kami",
306
+ "label.read": "baca",
307
+ "label.write": "tulis",
308
+ "text.account exists so joins immediately": "akaun ini sudah wujud. menambahnya membolehkan mereka masuk serta-merta.",
309
+ "text.account will be created with the default password": "belum ada akaun dengan e-mel ini. akaun akan dicipta dengan kata laluan lalai, yang perlu anda maklumkan sendiri.",
310
+ "text.add_domain_owner_description": "beri kebenaran pemilik kepada seorang ahli $t(term.domain).",
311
+ "text.and x more": "dan {x} lagi",
312
+ "text.are_you_sure_to_remove_domain_owner": "buang {x} sebagai pemilik $t(term.domain)?",
313
+ "text.cannot be undone": "tidak boleh dibatalkan",
314
+ "text.domain owner added successfully": "pemilik $t(term.domain) ditambah",
315
+ "text.domain owner removed successfully": "pemilik $t(term.domain) dibuang",
316
+ "text.domain owners": "pemilik $t(term.domain)",
317
+ "text.failed": "gagal",
318
+ "text.failed to fetch": "senarai tidak dapat dibaca",
319
+ "text.filter by module name": "tapis mengikut nama modul",
320
+ "text.inherited roles are edited in their own domain": "peranan ini ditakrifkan dalam $t(term.domain) induk dan hanya boleh diubah di sana.",
321
+ "text.no account and no default password": "tiada akaun dengan e-mel ini dan sistem ini tiada kata laluan lalai. mereka perlu mendaftar dahulu.",
322
+ "text.no description for this privilege": "belum ada keterangan untuk keistimewaan ini.",
323
+ "text.no description for this role": "belum ada keterangan — tulis dalam senarai peranan.",
324
+ "text.no one holds this role yet": "belum ada sesiapa memegang peranan ini.",
325
+ "text.no other user yet": "belum ada pengguna lain",
326
+ "text.no privilege declared in this deployment": "belum ada keistimewaan diisytiharkan dalam penggunaan ini, jadi tiada apa untuk diberi.",
327
+ "text.no privilege granted": "tiada apa dibuka",
328
+ "text.no role assigned": "tiada peranan",
329
+ "text.no role defined in this domain": "belum ada peranan dalam $t(term.domain) ini. cipta satu sebelum memberi.",
330
+ "text.no role yet": "belum ada peranan ditakrifkan",
331
+ "text.none on": "tiada",
332
+ "text.not declared for this module": "modul ini tidak mengisytiharkan keistimewaan itu.",
333
+ "text.nothing is on for this role yet": "peranan ini belum membuka apa-apa. tambah apa yang boleh dilakukan di bawah.",
334
+ "text.nothing matches x": "tiada nama modul mengandungi \"{x}\".",
335
+ "text.owner opens everything without a role": "sebagai pemilik anda boleh membuka setiap skrin tanpa peranan. orang lain memerlukannya.",
336
+ "text.password becomes the default and must be told to them": "kata laluan kembali kepada lalai. tiada e-mel dihantar, jadi anda perlu memaklumkan kata laluan baharu sendiri.",
337
+ "text.pick a module on the left": "pilih modul di sebelah kiri untuk melihat apa yang peranan ini boleh lakukan di situ.",
338
+ "text.please enter username or email": "sila masukkan nama pengguna atau e-mel",
339
+ "text.please try again": "cuba lagi sebentar lagi.",
340
+ "text.remove the role from x people first": "untuk memadam peranan ini, tanggalkannya dahulu daripada {x} orang yang memegangnya.",
341
+ "text.role belongs to x domain and is edited there": "peranan ini ditakrifkan dalam {x} dan hanya boleh disunting di sana. ia ditunjukkan di sini kerana boleh diberi di sini.",
342
+ "text.roles in use are kept": "peranan yang masih dipegang dikekalkan. hanya yang tidak digunakan dipadam.",
343
+ "text.they lose access to this domain but keep the account": "mereka hilang akses ke $t(term.domain) ini. akaun kekal, jadi anda boleh menambah mereka semula kemudian.",
344
+ "text.unlocks in x minutes": "dibuka dalam {x} minit",
345
+ "text.view only": "peranan diwarisi — lihat sahaja",
346
+ "text.without a role they see nothing": "tanpa peranan, tiada skrin untuk mereka.",
347
+ "text.x is required": "sila masukkan {x}.",
348
+ "text.x of y on": "{x} daripada {y} dihidupkan",
349
+ "text.x on": "{x} dihidupkan",
350
+ "text.x people hold this role": "dipegang oleh {x}",
351
+ "title.add domain owner": "tambah pemilik $t(term.domain)",
352
+ "title.role privileges": "keistimewaan peranan"
298
353
  }