@objectstack/platform-objects 7.0.0 → 7.1.0

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.
@@ -32,7 +32,7 @@ declare const SysWebhook: Omit<{
32
32
  abstract: boolean;
33
33
  datasource: string;
34
34
  fields: Record<string, {
35
- type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
35
+ type: "number" | "boolean" | "tags" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
36
36
  required: boolean;
37
37
  searchable: boolean;
38
38
  multiple: boolean;
@@ -171,7 +171,7 @@ declare const SysWebhook: Omit<{
171
171
  autoRotate: boolean;
172
172
  } | undefined;
173
173
  };
174
- scope: "field" | "record" | "table" | "database";
174
+ scope: "record" | "field" | "table" | "database";
175
175
  deterministicEncryption: boolean;
176
176
  searchableEncryption: boolean;
177
177
  } | undefined;
@@ -654,7 +654,7 @@ declare const SysWebhook: Omit<{
654
654
  field?: string | undefined;
655
655
  objectOverride?: string | undefined;
656
656
  label?: string | undefined;
657
- type?: "number" | "boolean" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
657
+ type?: "number" | "boolean" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
658
658
  options?: {
659
659
  label: string;
660
660
  value: string;
@@ -32,7 +32,7 @@ declare const SysWebhook: Omit<{
32
32
  abstract: boolean;
33
33
  datasource: string;
34
34
  fields: Record<string, {
35
- type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
35
+ type: "number" | "boolean" | "tags" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
36
36
  required: boolean;
37
37
  searchable: boolean;
38
38
  multiple: boolean;
@@ -171,7 +171,7 @@ declare const SysWebhook: Omit<{
171
171
  autoRotate: boolean;
172
172
  } | undefined;
173
173
  };
174
- scope: "field" | "record" | "table" | "database";
174
+ scope: "record" | "field" | "table" | "database";
175
175
  deterministicEncryption: boolean;
176
176
  searchableEncryption: boolean;
177
177
  } | undefined;
@@ -654,7 +654,7 @@ declare const SysWebhook: Omit<{
654
654
  field?: string | undefined;
655
655
  objectOverride?: string | undefined;
656
656
  label?: string | undefined;
657
- type?: "number" | "boolean" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
657
+ type?: "number" | "boolean" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
658
658
  options?: {
659
659
  label: string;
660
660
  value: string;
@@ -21,7 +21,7 @@ declare const SysMetadataObject: Omit<{
21
21
  abstract: boolean;
22
22
  datasource: string;
23
23
  fields: Record<string, {
24
- type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
24
+ type: "number" | "boolean" | "tags" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
25
25
  required: boolean;
26
26
  searchable: boolean;
27
27
  multiple: boolean;
@@ -160,7 +160,7 @@ declare const SysMetadataObject: Omit<{
160
160
  autoRotate: boolean;
161
161
  } | undefined;
162
162
  };
163
- scope: "field" | "record" | "table" | "database";
163
+ scope: "record" | "field" | "table" | "database";
164
164
  deterministicEncryption: boolean;
165
165
  searchableEncryption: boolean;
166
166
  } | undefined;
@@ -643,7 +643,7 @@ declare const SysMetadataObject: Omit<{
643
643
  field?: string | undefined;
644
644
  objectOverride?: string | undefined;
645
645
  label?: string | undefined;
646
- type?: "number" | "boolean" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
646
+ type?: "number" | "boolean" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
647
647
  options?: {
648
648
  label: string;
649
649
  value: string;
@@ -4900,7 +4900,7 @@ declare const SysMetadataHistoryObject: Omit<{
4900
4900
  abstract: boolean;
4901
4901
  datasource: string;
4902
4902
  fields: Record<string, {
4903
- type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
4903
+ type: "number" | "boolean" | "tags" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
4904
4904
  required: boolean;
4905
4905
  searchable: boolean;
4906
4906
  multiple: boolean;
@@ -5039,7 +5039,7 @@ declare const SysMetadataHistoryObject: Omit<{
5039
5039
  autoRotate: boolean;
5040
5040
  } | undefined;
5041
5041
  };
5042
- scope: "field" | "record" | "table" | "database";
5042
+ scope: "record" | "field" | "table" | "database";
5043
5043
  deterministicEncryption: boolean;
5044
5044
  searchableEncryption: boolean;
5045
5045
  } | undefined;
@@ -5522,7 +5522,7 @@ declare const SysMetadataHistoryObject: Omit<{
5522
5522
  field?: string | undefined;
5523
5523
  objectOverride?: string | undefined;
5524
5524
  label?: string | undefined;
5525
- type?: "number" | "boolean" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
5525
+ type?: "number" | "boolean" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
5526
5526
  options?: {
5527
5527
  label: string;
5528
5528
  value: string;
@@ -21,7 +21,7 @@ declare const SysMetadataObject: Omit<{
21
21
  abstract: boolean;
22
22
  datasource: string;
23
23
  fields: Record<string, {
24
- type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
24
+ type: "number" | "boolean" | "tags" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
25
25
  required: boolean;
26
26
  searchable: boolean;
27
27
  multiple: boolean;
@@ -160,7 +160,7 @@ declare const SysMetadataObject: Omit<{
160
160
  autoRotate: boolean;
161
161
  } | undefined;
162
162
  };
163
- scope: "field" | "record" | "table" | "database";
163
+ scope: "record" | "field" | "table" | "database";
164
164
  deterministicEncryption: boolean;
165
165
  searchableEncryption: boolean;
166
166
  } | undefined;
@@ -643,7 +643,7 @@ declare const SysMetadataObject: Omit<{
643
643
  field?: string | undefined;
644
644
  objectOverride?: string | undefined;
645
645
  label?: string | undefined;
646
- type?: "number" | "boolean" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
646
+ type?: "number" | "boolean" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
647
647
  options?: {
648
648
  label: string;
649
649
  value: string;
@@ -4900,7 +4900,7 @@ declare const SysMetadataHistoryObject: Omit<{
4900
4900
  abstract: boolean;
4901
4901
  datasource: string;
4902
4902
  fields: Record<string, {
4903
- type: "number" | "boolean" | "tags" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
4903
+ type: "number" | "boolean" | "tags" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "vector";
4904
4904
  required: boolean;
4905
4905
  searchable: boolean;
4906
4906
  multiple: boolean;
@@ -5039,7 +5039,7 @@ declare const SysMetadataHistoryObject: Omit<{
5039
5039
  autoRotate: boolean;
5040
5040
  } | undefined;
5041
5041
  };
5042
- scope: "field" | "record" | "table" | "database";
5042
+ scope: "record" | "field" | "table" | "database";
5043
5043
  deterministicEncryption: boolean;
5044
5044
  searchableEncryption: boolean;
5045
5045
  } | undefined;
@@ -5522,7 +5522,7 @@ declare const SysMetadataHistoryObject: Omit<{
5522
5522
  field?: string | undefined;
5523
5523
  objectOverride?: string | undefined;
5524
5524
  label?: string | undefined;
5525
- type?: "number" | "boolean" | "date" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
5525
+ type?: "number" | "boolean" | "date" | "record" | "file" | "code" | "datetime" | "signature" | "progress" | "url" | "text" | "textarea" | "email" | "phone" | "password" | "markdown" | "html" | "richtext" | "currency" | "percent" | "time" | "toggle" | "select" | "multiselect" | "radio" | "checkboxes" | "lookup" | "master_detail" | "tree" | "image" | "avatar" | "video" | "audio" | "formula" | "summary" | "autonumber" | "composite" | "repeater" | "location" | "address" | "json" | "color" | "rating" | "slider" | "qrcode" | "tags" | "vector" | undefined;
5526
5526
  options?: {
5527
5527
  label: string;
5528
5528
  value: string;
@@ -34,9 +34,14 @@ declare const SysOrganizationDetailPage: Page;
34
34
  /**
35
35
  * sys_user — Record Detail Page (slotted, default for ALL sys_user records)
36
36
  *
37
- * Tailors the synthesized admin form into a layout that works for both:
38
- * • the end user landing on their own profile from the Account App, and
39
- * an admin opening someone else's user record from Setup.
37
+ * **Audience**: admins browsing user records from Setup.
38
+ *
39
+ * The Account App's "Profile" entry no longer routes here — it points at
40
+ * the `account:profile_card` Console component for a settings-form-style
41
+ * personal profile. This page therefore optimizes for the admin
42
+ * use case: scanning a user's signals (email/verification/2FA/role),
43
+ * reviewing related sessions/orgs/oauth/api-keys, and triggering
44
+ * admin actions (ban / impersonate / set_role).
40
45
  *
41
46
  * Strategy
42
47
  * --------
@@ -34,9 +34,14 @@ declare const SysOrganizationDetailPage: Page;
34
34
  /**
35
35
  * sys_user — Record Detail Page (slotted, default for ALL sys_user records)
36
36
  *
37
- * Tailors the synthesized admin form into a layout that works for both:
38
- * • the end user landing on their own profile from the Account App, and
39
- * an admin opening someone else's user record from Setup.
37
+ * **Audience**: admins browsing user records from Setup.
38
+ *
39
+ * The Account App's "Profile" entry no longer routes here — it points at
40
+ * the `account:profile_card` Console component for a settings-form-style
41
+ * personal profile. This page therefore optimizes for the admin
42
+ * use case: scanning a user's signals (email/verification/2FA/role),
43
+ * reviewing related sessions/orgs/oauth/api-keys, and triggering
44
+ * admin actions (ban / impersonate / set_role).
40
45
  *
41
46
  * Strategy
42
47
  * --------
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/pages/sys-organization.page.ts","../../src/pages/sys-user.page.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_organization — Record Detail Page (slotted)\n *\n * Adds Members / Invitations / Teams tabs to the organization detail\n * page so an admin can manage the membership graph from a single place\n * instead of switching between three separate Setup list views.\n *\n * The page is `kind: 'slotted'` and overrides only the `tabs` slot —\n * header, actions, highlights, details and discussion fall through to\n * the synthesized default, so the organization's own fields and the\n * existing record-header actions (Set Active, Edit, Delete, Leave) are\n * preserved.\n *\n * Each tab is a `record:related_list` over a child object that already\n * has `organization_id` as a `Field.lookup('sys_organization')` — the\n * renderer scopes the list to the current organization automatically\n * (the related-list runtime uses the parent record id from the page\n * context as the filter value for `relationshipField`). The per-row\n * actions defined on each child object (invite_user, cancel_invitation,\n * remove_member, transfer_ownership, create_team, …) are inherited\n * unchanged — no admin endpoint has to be re-declared here.\n *\n * Notable omissions:\n * - **OAuth Apps**: `sys_oauth_application` is owned by `user_id`, not\n * `organization_id`. They surface on the user's Account → Developer\n * section instead of the org detail.\n * - **SSO**: no `sys_sso*` object exists yet. When the SSO plugin lands,\n * add a fourth tab here.\n */\nexport const SysOrganizationDetailPage: Page = {\n name: 'sys_organization_detail',\n label: 'Organization',\n type: 'record',\n object: 'sys_organization',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n // `regions` is required by the Page schema even for slotted pages —\n // empty array lets the synthesizer fill in header/details/discussion\n // while the `slots.tabs` override below replaces the synthesized\n // tabs strip.\n regions: [],\n slots: {\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Members',\n icon: 'users',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'organization_id',\n columns: ['user_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Members',\n },\n },\n ],\n },\n {\n label: 'Invitations',\n icon: 'mail',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_invitation',\n relationshipField: 'organization_id',\n columns: ['email', 'role', 'status', 'expires_at', 'inviter_id'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Invitations',\n },\n },\n ],\n },\n {\n label: 'Teams',\n icon: 'users-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_team',\n relationshipField: 'organization_id',\n columns: ['name', 'created_at', 'updated_at'],\n sort: [{ field: 'name', order: 'asc' }],\n limit: 25,\n showViewAll: true,\n title: 'Teams',\n },\n },\n ],\n },\n ],\n },\n },\n },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_user — Record Detail Page (slotted, default for ALL sys_user records)\n *\n * Tailors the synthesized admin form into a layout that works for both:\n * • the end user landing on their own profile from the Account App, and\n * • an admin opening someone else's user record from Setup.\n *\n * Strategy\n * --------\n * - `kind: 'slotted'` + `isDefault: true`: overrides `highlights`,\n * `details`, `tabs` and `discussion`. Header / actions fall through\n * to the synthesizer so the object's declared actions\n * (`update_my_profile / change_my_password / resend_verification_email\n * / ban_user / set_user_role / impersonate_user / …`) still appear\n * in the header overflow menu automatically.\n * - `highlights` promotes the four signals worth scanning at the top:\n * email, verification state, 2FA, platform role. Highlight fields\n * are auto-dropped from the details grid below.\n * - `details` re-groups remaining fields into sections and hides\n * admin-internal audit columns. Banned / ban metadata is still\n * editable from the header actions — we just don't show it in\n * every user's body.\n * - `tabs` is **explicitly curated** to the 4 related lists that matter\n * on a user profile (Sessions / Linked Accounts / Organizations /\n * Personal OAuth Apps). Without this override, the synthesizer\n * auto-generates a tab per object that has a FK to sys_user\n * (sys_role.created_by, sys_email.updated_by, sys_user_preference,\n * sys_email_template.created_by, …) producing dozens of noisy\n * \"查看全部\" cards on every profile.\n * - `discussion: []` removes the Chatter feed — it has no business\n * on a personal profile.\n */\nexport const SysUserDetailPage: Page = {\n name: 'sys_user_detail',\n label: 'User',\n type: 'record',\n object: 'sys_user',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n\n regions: [],\n\n slots: {\n // ── Alert banners ─────────────────────────────────────────────\n // Conditional notices rendered between the page header and the\n // highlight strip. The unverified-email banner only shows for the\n // current user viewing their own profile (admins looking at other\n // users see nothing — they can use Setup actions instead).\n alerts: [\n {\n type: 'record:alert',\n properties: {\n severity: 'warning',\n icon: 'mail',\n title: '邮箱未验证',\n body: '验证你的邮箱以接收密码重置和重要的系统通知。',\n visible: 'record.id == ctx.user.id && record.email_verified == false',\n dismissible: false,\n action: {\n actionName: 'resend_verification_email',\n label: '重新发送验证邮件',\n },\n },\n },\n ],\n\n // ── Highlight chips above the fold ────────────────────────────\n highlights: {\n type: 'record:highlights',\n properties: {\n fields: ['email', 'email_verified', 'two_factor_enabled', 'role'],\n },\n },\n\n // ── Body / details grid ───────────────────────────────────────\n details: {\n type: 'record:details',\n properties: {\n hideFields: [\n 'id',\n 'banned',\n 'ban_reason',\n 'ban_expires',\n // already promoted to highlights:\n 'email',\n 'email_verified',\n 'two_factor_enabled',\n 'role',\n ],\n sections: [\n {\n label: 'Identity',\n fields: ['name', 'image'],\n },\n {\n label: 'Audit',\n fields: ['created_at', 'updated_at'],\n },\n ],\n },\n },\n\n // ── Tabs: curated related lists ───────────────────────────────\n // Only the 4 lists that are semantically about THIS user account.\n // Everything else (sys_role created_by, sys_email_template\n // updated_by, …) is incidental authorship metadata and would only\n // create noise.\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Sessions',\n icon: 'monitor',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_session',\n relationshipField: 'user_id',\n columns: ['user_agent', 'ip_address', 'created_at', 'expires_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Sessions',\n },\n },\n ],\n },\n {\n label: 'Linked Accounts',\n icon: 'link',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_account',\n relationshipField: 'user_id',\n columns: ['provider_id', 'account_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Linked Accounts',\n },\n },\n ],\n },\n {\n label: 'Organizations',\n icon: 'building-2',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'user_id',\n columns: ['organization_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Organizations',\n },\n },\n ],\n },\n {\n label: 'OAuth Apps',\n icon: 'key-square',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_oauth_application',\n relationshipField: 'user_id',\n columns: ['name', 'client_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'OAuth Apps',\n },\n },\n ],\n },\n // ── Security ──────────────────────────────────────────────\n // Grouped self-service security controls. Each `record:quick_actions`\n // pulls its actions by name from the sys_user object metadata\n // (DRY — definitions stay on the object) and filters by\n // `location: 'record_section'` so they only render here, not\n // in the global header row.\n {\n label: 'Security',\n icon: 'shield',\n children: [\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Password & Sign-in',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Change your password or the email address associated with this account.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['change_my_password', 'change_my_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Two-Factor Authentication',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Add a second layer of security using a TOTP authenticator app. Backup codes let you sign in if you lose your device.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['enable_two_factor', 'disable_two_factor', 'generate_backup_codes'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Email Verification',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Verify your email so password resets and notifications reach you. The button appears only while verification is pending.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['resend_verification_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Danger Zone',\n },\n className: 'text-destructive',\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Permanent. Once deleted, your account cannot be recovered.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['delete_my_account'],\n },\n },\n ],\n },\n // ── API Keys ──────────────────────────────────────────────\n // Programmatic credentials issued for this user. Filtered by\n // user_id FK; the sys_api_key object's own list-item actions\n // (revoke / restore) handle row operations.\n {\n label: 'API Keys',\n icon: 'key-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_api_key',\n relationshipField: 'user_id',\n columns: ['name', 'prefix', 'expires_at', 'revoked', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'API Keys',\n },\n },\n ],\n },\n ],\n },\n },\n\n // ── Suppress the Discussion / Chatter thread ──────────────────\n discussion: [],\n },\n};\n"]}
1
+ {"version":3,"sources":["../../src/pages/sys-organization.page.ts","../../src/pages/sys-user.page.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_organization — Record Detail Page (slotted)\n *\n * Adds Members / Invitations / Teams tabs to the organization detail\n * page so an admin can manage the membership graph from a single place\n * instead of switching between three separate Setup list views.\n *\n * The page is `kind: 'slotted'` and overrides only the `tabs` slot —\n * header, actions, highlights, details and discussion fall through to\n * the synthesized default, so the organization's own fields and the\n * existing record-header actions (Set Active, Edit, Delete, Leave) are\n * preserved.\n *\n * Each tab is a `record:related_list` over a child object that already\n * has `organization_id` as a `Field.lookup('sys_organization')` — the\n * renderer scopes the list to the current organization automatically\n * (the related-list runtime uses the parent record id from the page\n * context as the filter value for `relationshipField`). The per-row\n * actions defined on each child object (invite_user, cancel_invitation,\n * remove_member, transfer_ownership, create_team, …) are inherited\n * unchanged — no admin endpoint has to be re-declared here.\n *\n * Notable omissions:\n * - **OAuth Apps**: `sys_oauth_application` is owned by `user_id`, not\n * `organization_id`. They surface on the user's Account → Developer\n * section instead of the org detail.\n * - **SSO**: no `sys_sso*` object exists yet. When the SSO plugin lands,\n * add a fourth tab here.\n */\nexport const SysOrganizationDetailPage: Page = {\n name: 'sys_organization_detail',\n label: 'Organization',\n type: 'record',\n object: 'sys_organization',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n // `regions` is required by the Page schema even for slotted pages —\n // empty array lets the synthesizer fill in header/details/discussion\n // while the `slots.tabs` override below replaces the synthesized\n // tabs strip.\n regions: [],\n slots: {\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Members',\n icon: 'users',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'organization_id',\n columns: ['user_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Members',\n },\n },\n ],\n },\n {\n label: 'Invitations',\n icon: 'mail',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_invitation',\n relationshipField: 'organization_id',\n columns: ['email', 'role', 'status', 'expires_at', 'inviter_id'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Invitations',\n },\n },\n ],\n },\n {\n label: 'Teams',\n icon: 'users-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_team',\n relationshipField: 'organization_id',\n columns: ['name', 'created_at', 'updated_at'],\n sort: [{ field: 'name', order: 'asc' }],\n limit: 25,\n showViewAll: true,\n title: 'Teams',\n },\n },\n ],\n },\n ],\n },\n },\n },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_user — Record Detail Page (slotted, default for ALL sys_user records)\n *\n * **Audience**: admins browsing user records from Setup.\n *\n * The Account App's \"Profile\" entry no longer routes here — it points at\n * the `account:profile_card` Console component for a settings-form-style\n * personal profile. This page therefore optimizes for the admin\n * use case: scanning a user's signals (email/verification/2FA/role),\n * reviewing related sessions/orgs/oauth/api-keys, and triggering\n * admin actions (ban / impersonate / set_role).\n *\n * Strategy\n * --------\n * - `kind: 'slotted'` + `isDefault: true`: overrides `highlights`,\n * `details`, `tabs` and `discussion`. Header / actions fall through\n * to the synthesizer so the object's declared actions\n * (`update_my_profile / change_my_password / resend_verification_email\n * / ban_user / set_user_role / impersonate_user / …`) still appear\n * in the header overflow menu automatically.\n * - `highlights` promotes the four signals worth scanning at the top:\n * email, verification state, 2FA, platform role. Highlight fields\n * are auto-dropped from the details grid below.\n * - `details` re-groups remaining fields into sections and hides\n * admin-internal audit columns. Banned / ban metadata is still\n * editable from the header actions — we just don't show it in\n * every user's body.\n * - `tabs` is **explicitly curated** to the 4 related lists that matter\n * on a user profile (Sessions / Linked Accounts / Organizations /\n * Personal OAuth Apps). Without this override, the synthesizer\n * auto-generates a tab per object that has a FK to sys_user\n * (sys_role.created_by, sys_email.updated_by, sys_user_preference,\n * sys_email_template.created_by, …) producing dozens of noisy\n * \"查看全部\" cards on every profile.\n * - `discussion: []` removes the Chatter feed — it has no business\n * on a personal profile.\n */\nexport const SysUserDetailPage: Page = {\n name: 'sys_user_detail',\n label: 'User',\n type: 'record',\n object: 'sys_user',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n\n regions: [],\n\n slots: {\n // ── Alert banners ─────────────────────────────────────────────\n // Conditional notices rendered between the page header and the\n // highlight strip. The unverified-email banner only shows for the\n // current user viewing their own profile (admins looking at other\n // users see nothing — they can use Setup actions instead).\n alerts: [\n {\n type: 'record:alert',\n properties: {\n severity: 'warning',\n icon: 'mail',\n title: '邮箱未验证',\n body: '验证你的邮箱以接收密码重置和重要的系统通知。',\n visible: 'record.id == ctx.user.id && record.email_verified == false',\n dismissible: false,\n action: {\n actionName: 'resend_verification_email',\n label: '重新发送验证邮件',\n },\n },\n },\n ],\n\n // ── Highlight chips above the fold ────────────────────────────\n highlights: {\n type: 'record:highlights',\n properties: {\n fields: ['email', 'email_verified', 'two_factor_enabled', 'role'],\n },\n },\n\n // ── Body / details grid ───────────────────────────────────────\n details: {\n type: 'record:details',\n properties: {\n hideFields: [\n 'id',\n 'banned',\n 'ban_reason',\n 'ban_expires',\n // already promoted to highlights:\n 'email',\n 'email_verified',\n 'two_factor_enabled',\n 'role',\n ],\n sections: [\n {\n label: 'Identity',\n fields: ['name', 'image'],\n },\n {\n label: 'Audit',\n fields: ['created_at', 'updated_at'],\n },\n ],\n },\n },\n\n // ── Tabs: curated related lists ───────────────────────────────\n // Only the 4 lists that are semantically about THIS user account.\n // Everything else (sys_role created_by, sys_email_template\n // updated_by, …) is incidental authorship metadata and would only\n // create noise.\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Sessions',\n icon: 'monitor',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_session',\n relationshipField: 'user_id',\n columns: ['user_agent', 'ip_address', 'created_at', 'expires_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Sessions',\n },\n },\n ],\n },\n {\n label: 'Linked Accounts',\n icon: 'link',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_account',\n relationshipField: 'user_id',\n columns: ['provider_id', 'account_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Linked Accounts',\n },\n },\n ],\n },\n {\n label: 'Organizations',\n icon: 'building-2',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'user_id',\n columns: ['organization_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Organizations',\n },\n },\n ],\n },\n {\n label: 'OAuth Apps',\n icon: 'key-square',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_oauth_application',\n relationshipField: 'user_id',\n columns: ['name', 'client_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'OAuth Apps',\n },\n },\n ],\n },\n // ── Security ──────────────────────────────────────────────\n // Grouped self-service security controls. Each `record:quick_actions`\n // pulls its actions by name from the sys_user object metadata\n // (DRY — definitions stay on the object) and filters by\n // `location: 'record_section'` so they only render here, not\n // in the global header row.\n {\n label: 'Security',\n icon: 'shield',\n children: [\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Password & Sign-in',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Change your password or the email address associated with this account.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['change_my_password', 'change_my_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Two-Factor Authentication',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Add a second layer of security using a TOTP authenticator app. Backup codes let you sign in if you lose your device.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['enable_two_factor', 'disable_two_factor', 'generate_backup_codes'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Email Verification',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Verify your email so password resets and notifications reach you. The button appears only while verification is pending.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['resend_verification_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Danger Zone',\n },\n className: 'text-destructive',\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Permanent. Once deleted, your account cannot be recovered.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['delete_my_account'],\n },\n },\n ],\n },\n // ── API Keys ──────────────────────────────────────────────\n // Programmatic credentials issued for this user. Filtered by\n // user_id FK; the sys_api_key object's own list-item actions\n // (revoke / restore) handle row operations.\n {\n label: 'API Keys',\n icon: 'key-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_api_key',\n relationshipField: 'user_id',\n columns: ['name', 'prefix', 'expires_at', 'revoked', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'API Keys',\n },\n },\n ],\n },\n ],\n },\n },\n\n // ── Suppress the Discussion / Chatter thread ──────────────────\n discussion: [],\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/pages/sys-organization.page.ts","../../src/pages/sys-user.page.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_organization — Record Detail Page (slotted)\n *\n * Adds Members / Invitations / Teams tabs to the organization detail\n * page so an admin can manage the membership graph from a single place\n * instead of switching between three separate Setup list views.\n *\n * The page is `kind: 'slotted'` and overrides only the `tabs` slot —\n * header, actions, highlights, details and discussion fall through to\n * the synthesized default, so the organization's own fields and the\n * existing record-header actions (Set Active, Edit, Delete, Leave) are\n * preserved.\n *\n * Each tab is a `record:related_list` over a child object that already\n * has `organization_id` as a `Field.lookup('sys_organization')` — the\n * renderer scopes the list to the current organization automatically\n * (the related-list runtime uses the parent record id from the page\n * context as the filter value for `relationshipField`). The per-row\n * actions defined on each child object (invite_user, cancel_invitation,\n * remove_member, transfer_ownership, create_team, …) are inherited\n * unchanged — no admin endpoint has to be re-declared here.\n *\n * Notable omissions:\n * - **OAuth Apps**: `sys_oauth_application` is owned by `user_id`, not\n * `organization_id`. They surface on the user's Account → Developer\n * section instead of the org detail.\n * - **SSO**: no `sys_sso*` object exists yet. When the SSO plugin lands,\n * add a fourth tab here.\n */\nexport const SysOrganizationDetailPage: Page = {\n name: 'sys_organization_detail',\n label: 'Organization',\n type: 'record',\n object: 'sys_organization',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n // `regions` is required by the Page schema even for slotted pages —\n // empty array lets the synthesizer fill in header/details/discussion\n // while the `slots.tabs` override below replaces the synthesized\n // tabs strip.\n regions: [],\n slots: {\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Members',\n icon: 'users',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'organization_id',\n columns: ['user_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Members',\n },\n },\n ],\n },\n {\n label: 'Invitations',\n icon: 'mail',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_invitation',\n relationshipField: 'organization_id',\n columns: ['email', 'role', 'status', 'expires_at', 'inviter_id'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Invitations',\n },\n },\n ],\n },\n {\n label: 'Teams',\n icon: 'users-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_team',\n relationshipField: 'organization_id',\n columns: ['name', 'created_at', 'updated_at'],\n sort: [{ field: 'name', order: 'asc' }],\n limit: 25,\n showViewAll: true,\n title: 'Teams',\n },\n },\n ],\n },\n ],\n },\n },\n },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_user — Record Detail Page (slotted, default for ALL sys_user records)\n *\n * Tailors the synthesized admin form into a layout that works for both:\n * • the end user landing on their own profile from the Account App, and\n * • an admin opening someone else's user record from Setup.\n *\n * Strategy\n * --------\n * - `kind: 'slotted'` + `isDefault: true`: overrides `highlights`,\n * `details`, `tabs` and `discussion`. Header / actions fall through\n * to the synthesizer so the object's declared actions\n * (`update_my_profile / change_my_password / resend_verification_email\n * / ban_user / set_user_role / impersonate_user / …`) still appear\n * in the header overflow menu automatically.\n * - `highlights` promotes the four signals worth scanning at the top:\n * email, verification state, 2FA, platform role. Highlight fields\n * are auto-dropped from the details grid below.\n * - `details` re-groups remaining fields into sections and hides\n * admin-internal audit columns. Banned / ban metadata is still\n * editable from the header actions — we just don't show it in\n * every user's body.\n * - `tabs` is **explicitly curated** to the 4 related lists that matter\n * on a user profile (Sessions / Linked Accounts / Organizations /\n * Personal OAuth Apps). Without this override, the synthesizer\n * auto-generates a tab per object that has a FK to sys_user\n * (sys_role.created_by, sys_email.updated_by, sys_user_preference,\n * sys_email_template.created_by, …) producing dozens of noisy\n * \"查看全部\" cards on every profile.\n * - `discussion: []` removes the Chatter feed — it has no business\n * on a personal profile.\n */\nexport const SysUserDetailPage: Page = {\n name: 'sys_user_detail',\n label: 'User',\n type: 'record',\n object: 'sys_user',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n\n regions: [],\n\n slots: {\n // ── Alert banners ─────────────────────────────────────────────\n // Conditional notices rendered between the page header and the\n // highlight strip. The unverified-email banner only shows for the\n // current user viewing their own profile (admins looking at other\n // users see nothing — they can use Setup actions instead).\n alerts: [\n {\n type: 'record:alert',\n properties: {\n severity: 'warning',\n icon: 'mail',\n title: '邮箱未验证',\n body: '验证你的邮箱以接收密码重置和重要的系统通知。',\n visible: 'record.id == ctx.user.id && record.email_verified == false',\n dismissible: false,\n action: {\n actionName: 'resend_verification_email',\n label: '重新发送验证邮件',\n },\n },\n },\n ],\n\n // ── Highlight chips above the fold ────────────────────────────\n highlights: {\n type: 'record:highlights',\n properties: {\n fields: ['email', 'email_verified', 'two_factor_enabled', 'role'],\n },\n },\n\n // ── Body / details grid ───────────────────────────────────────\n details: {\n type: 'record:details',\n properties: {\n hideFields: [\n 'id',\n 'banned',\n 'ban_reason',\n 'ban_expires',\n // already promoted to highlights:\n 'email',\n 'email_verified',\n 'two_factor_enabled',\n 'role',\n ],\n sections: [\n {\n label: 'Identity',\n fields: ['name', 'image'],\n },\n {\n label: 'Audit',\n fields: ['created_at', 'updated_at'],\n },\n ],\n },\n },\n\n // ── Tabs: curated related lists ───────────────────────────────\n // Only the 4 lists that are semantically about THIS user account.\n // Everything else (sys_role created_by, sys_email_template\n // updated_by, …) is incidental authorship metadata and would only\n // create noise.\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Sessions',\n icon: 'monitor',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_session',\n relationshipField: 'user_id',\n columns: ['user_agent', 'ip_address', 'created_at', 'expires_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Sessions',\n },\n },\n ],\n },\n {\n label: 'Linked Accounts',\n icon: 'link',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_account',\n relationshipField: 'user_id',\n columns: ['provider_id', 'account_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Linked Accounts',\n },\n },\n ],\n },\n {\n label: 'Organizations',\n icon: 'building-2',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'user_id',\n columns: ['organization_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Organizations',\n },\n },\n ],\n },\n {\n label: 'OAuth Apps',\n icon: 'key-square',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_oauth_application',\n relationshipField: 'user_id',\n columns: ['name', 'client_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'OAuth Apps',\n },\n },\n ],\n },\n // ── Security ──────────────────────────────────────────────\n // Grouped self-service security controls. Each `record:quick_actions`\n // pulls its actions by name from the sys_user object metadata\n // (DRY — definitions stay on the object) and filters by\n // `location: 'record_section'` so they only render here, not\n // in the global header row.\n {\n label: 'Security',\n icon: 'shield',\n children: [\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Password & Sign-in',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Change your password or the email address associated with this account.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['change_my_password', 'change_my_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Two-Factor Authentication',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Add a second layer of security using a TOTP authenticator app. Backup codes let you sign in if you lose your device.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['enable_two_factor', 'disable_two_factor', 'generate_backup_codes'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Email Verification',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Verify your email so password resets and notifications reach you. The button appears only while verification is pending.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['resend_verification_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Danger Zone',\n },\n className: 'text-destructive',\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Permanent. Once deleted, your account cannot be recovered.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['delete_my_account'],\n },\n },\n ],\n },\n // ── API Keys ──────────────────────────────────────────────\n // Programmatic credentials issued for this user. Filtered by\n // user_id FK; the sys_api_key object's own list-item actions\n // (revoke / restore) handle row operations.\n {\n label: 'API Keys',\n icon: 'key-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_api_key',\n relationshipField: 'user_id',\n columns: ['name', 'prefix', 'expires_at', 'revoked', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'API Keys',\n },\n },\n ],\n },\n ],\n },\n },\n\n // ── Suppress the Discussion / Chatter thread ──────────────────\n discussion: [],\n },\n};\n"]}
1
+ {"version":3,"sources":["../../src/pages/sys-organization.page.ts","../../src/pages/sys-user.page.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_organization — Record Detail Page (slotted)\n *\n * Adds Members / Invitations / Teams tabs to the organization detail\n * page so an admin can manage the membership graph from a single place\n * instead of switching between three separate Setup list views.\n *\n * The page is `kind: 'slotted'` and overrides only the `tabs` slot —\n * header, actions, highlights, details and discussion fall through to\n * the synthesized default, so the organization's own fields and the\n * existing record-header actions (Set Active, Edit, Delete, Leave) are\n * preserved.\n *\n * Each tab is a `record:related_list` over a child object that already\n * has `organization_id` as a `Field.lookup('sys_organization')` — the\n * renderer scopes the list to the current organization automatically\n * (the related-list runtime uses the parent record id from the page\n * context as the filter value for `relationshipField`). The per-row\n * actions defined on each child object (invite_user, cancel_invitation,\n * remove_member, transfer_ownership, create_team, …) are inherited\n * unchanged — no admin endpoint has to be re-declared here.\n *\n * Notable omissions:\n * - **OAuth Apps**: `sys_oauth_application` is owned by `user_id`, not\n * `organization_id`. They surface on the user's Account → Developer\n * section instead of the org detail.\n * - **SSO**: no `sys_sso*` object exists yet. When the SSO plugin lands,\n * add a fourth tab here.\n */\nexport const SysOrganizationDetailPage: Page = {\n name: 'sys_organization_detail',\n label: 'Organization',\n type: 'record',\n object: 'sys_organization',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n // `regions` is required by the Page schema even for slotted pages —\n // empty array lets the synthesizer fill in header/details/discussion\n // while the `slots.tabs` override below replaces the synthesized\n // tabs strip.\n regions: [],\n slots: {\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Members',\n icon: 'users',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'organization_id',\n columns: ['user_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Members',\n },\n },\n ],\n },\n {\n label: 'Invitations',\n icon: 'mail',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_invitation',\n relationshipField: 'organization_id',\n columns: ['email', 'role', 'status', 'expires_at', 'inviter_id'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Invitations',\n },\n },\n ],\n },\n {\n label: 'Teams',\n icon: 'users-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_team',\n relationshipField: 'organization_id',\n columns: ['name', 'created_at', 'updated_at'],\n sort: [{ field: 'name', order: 'asc' }],\n limit: 25,\n showViewAll: true,\n title: 'Teams',\n },\n },\n ],\n },\n ],\n },\n },\n },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Page } from '@objectstack/spec/ui';\n\n/**\n * sys_user — Record Detail Page (slotted, default for ALL sys_user records)\n *\n * **Audience**: admins browsing user records from Setup.\n *\n * The Account App's \"Profile\" entry no longer routes here — it points at\n * the `account:profile_card` Console component for a settings-form-style\n * personal profile. This page therefore optimizes for the admin\n * use case: scanning a user's signals (email/verification/2FA/role),\n * reviewing related sessions/orgs/oauth/api-keys, and triggering\n * admin actions (ban / impersonate / set_role).\n *\n * Strategy\n * --------\n * - `kind: 'slotted'` + `isDefault: true`: overrides `highlights`,\n * `details`, `tabs` and `discussion`. Header / actions fall through\n * to the synthesizer so the object's declared actions\n * (`update_my_profile / change_my_password / resend_verification_email\n * / ban_user / set_user_role / impersonate_user / …`) still appear\n * in the header overflow menu automatically.\n * - `highlights` promotes the four signals worth scanning at the top:\n * email, verification state, 2FA, platform role. Highlight fields\n * are auto-dropped from the details grid below.\n * - `details` re-groups remaining fields into sections and hides\n * admin-internal audit columns. Banned / ban metadata is still\n * editable from the header actions — we just don't show it in\n * every user's body.\n * - `tabs` is **explicitly curated** to the 4 related lists that matter\n * on a user profile (Sessions / Linked Accounts / Organizations /\n * Personal OAuth Apps). Without this override, the synthesizer\n * auto-generates a tab per object that has a FK to sys_user\n * (sys_role.created_by, sys_email.updated_by, sys_user_preference,\n * sys_email_template.created_by, …) producing dozens of noisy\n * \"查看全部\" cards on every profile.\n * - `discussion: []` removes the Chatter feed — it has no business\n * on a personal profile.\n */\nexport const SysUserDetailPage: Page = {\n name: 'sys_user_detail',\n label: 'User',\n type: 'record',\n object: 'sys_user',\n template: 'default',\n kind: 'slotted',\n isDefault: true,\n\n regions: [],\n\n slots: {\n // ── Alert banners ─────────────────────────────────────────────\n // Conditional notices rendered between the page header and the\n // highlight strip. The unverified-email banner only shows for the\n // current user viewing their own profile (admins looking at other\n // users see nothing — they can use Setup actions instead).\n alerts: [\n {\n type: 'record:alert',\n properties: {\n severity: 'warning',\n icon: 'mail',\n title: '邮箱未验证',\n body: '验证你的邮箱以接收密码重置和重要的系统通知。',\n visible: 'record.id == ctx.user.id && record.email_verified == false',\n dismissible: false,\n action: {\n actionName: 'resend_verification_email',\n label: '重新发送验证邮件',\n },\n },\n },\n ],\n\n // ── Highlight chips above the fold ────────────────────────────\n highlights: {\n type: 'record:highlights',\n properties: {\n fields: ['email', 'email_verified', 'two_factor_enabled', 'role'],\n },\n },\n\n // ── Body / details grid ───────────────────────────────────────\n details: {\n type: 'record:details',\n properties: {\n hideFields: [\n 'id',\n 'banned',\n 'ban_reason',\n 'ban_expires',\n // already promoted to highlights:\n 'email',\n 'email_verified',\n 'two_factor_enabled',\n 'role',\n ],\n sections: [\n {\n label: 'Identity',\n fields: ['name', 'image'],\n },\n {\n label: 'Audit',\n fields: ['created_at', 'updated_at'],\n },\n ],\n },\n },\n\n // ── Tabs: curated related lists ───────────────────────────────\n // Only the 4 lists that are semantically about THIS user account.\n // Everything else (sys_role created_by, sys_email_template\n // updated_by, …) is incidental authorship metadata and would only\n // create noise.\n tabs: {\n type: 'page:tabs',\n properties: {\n type: 'line',\n position: 'top',\n items: [\n {\n label: 'Sessions',\n icon: 'monitor',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_session',\n relationshipField: 'user_id',\n columns: ['user_agent', 'ip_address', 'created_at', 'expires_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Sessions',\n },\n },\n ],\n },\n {\n label: 'Linked Accounts',\n icon: 'link',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_account',\n relationshipField: 'user_id',\n columns: ['provider_id', 'account_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Linked Accounts',\n },\n },\n ],\n },\n {\n label: 'Organizations',\n icon: 'building-2',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_member',\n relationshipField: 'user_id',\n columns: ['organization_id', 'role', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'Organizations',\n },\n },\n ],\n },\n {\n label: 'OAuth Apps',\n icon: 'key-square',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_oauth_application',\n relationshipField: 'user_id',\n columns: ['name', 'client_id', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'OAuth Apps',\n },\n },\n ],\n },\n // ── Security ──────────────────────────────────────────────\n // Grouped self-service security controls. Each `record:quick_actions`\n // pulls its actions by name from the sys_user object metadata\n // (DRY — definitions stay on the object) and filters by\n // `location: 'record_section'` so they only render here, not\n // in the global header row.\n {\n label: 'Security',\n icon: 'shield',\n children: [\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Password & Sign-in',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Change your password or the email address associated with this account.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['change_my_password', 'change_my_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Two-Factor Authentication',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Add a second layer of security using a TOTP authenticator app. Backup codes let you sign in if you lose your device.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['enable_two_factor', 'disable_two_factor', 'generate_backup_codes'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Email Verification',\n },\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Verify your email so password resets and notifications reach you. The button appears only while verification is pending.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['resend_verification_email'],\n },\n },\n { type: 'element:divider' },\n {\n type: 'element:text',\n properties: {\n variant: 'subheading',\n content: 'Danger Zone',\n },\n className: 'text-destructive',\n },\n {\n type: 'element:text',\n properties: {\n variant: 'caption',\n content: 'Permanent. Once deleted, your account cannot be recovered.',\n },\n },\n {\n type: 'record:quick_actions',\n properties: {\n location: 'record_section',\n align: 'start',\n actionNames: ['delete_my_account'],\n },\n },\n ],\n },\n // ── API Keys ──────────────────────────────────────────────\n // Programmatic credentials issued for this user. Filtered by\n // user_id FK; the sys_api_key object's own list-item actions\n // (revoke / restore) handle row operations.\n {\n label: 'API Keys',\n icon: 'key-round',\n children: [\n {\n type: 'record:related_list',\n properties: {\n objectName: 'sys_api_key',\n relationshipField: 'user_id',\n columns: ['name', 'prefix', 'expires_at', 'revoked', 'created_at'],\n sort: [{ field: 'created_at', order: 'desc' }],\n limit: 25,\n showViewAll: true,\n title: 'API Keys',\n },\n },\n ],\n },\n ],\n },\n },\n\n // ── Suppress the Discussion / Chatter thread ──────────────────\n discussion: [],\n },\n};\n"]}
package/dist/plugin.js CHANGED
@@ -3069,8 +3069,7 @@ var en = {
3069
3069
  nav_account_linked: { label: "Linked Accounts" },
3070
3070
  nav_account_sessions: { label: "Active Sessions" },
3071
3071
  nav_account_api_keys: { label: "API Keys" },
3072
- nav_account_oauth_apps: { label: "OAuth Applications" },
3073
- nav_account_preferences: { label: "Preferences" }
3072
+ nav_account_oauth_apps: { label: "OAuth Applications" }
3074
3073
  }
3075
3074
  },
3076
3075
  setup: {
@@ -6281,8 +6280,7 @@ var zhCN = {
6281
6280
  nav_account_linked: { label: "\u5DF2\u5173\u8054\u8D26\u6237" },
6282
6281
  nav_account_sessions: { label: "\u6D3B\u52A8\u4F1A\u8BDD" },
6283
6282
  nav_account_api_keys: { label: "API \u5BC6\u94A5" },
6284
- nav_account_oauth_apps: { label: "OAuth \u5E94\u7528" },
6285
- nav_account_preferences: { label: "\u504F\u597D\u8BBE\u7F6E" }
6283
+ nav_account_oauth_apps: { label: "OAuth \u5E94\u7528" }
6286
6284
  }
6287
6285
  },
6288
6286
  setup: {
@@ -9454,8 +9452,7 @@ var jaJP = {
9454
9452
  nav_account_linked: { label: "\u9023\u643A\u30A2\u30AB\u30A6\u30F3\u30C8" },
9455
9453
  nav_account_sessions: { label: "\u30A2\u30AF\u30C6\u30A3\u30D6\u30BB\u30C3\u30B7\u30E7\u30F3" },
9456
9454
  nav_account_api_keys: { label: "API \u30AD\u30FC" },
9457
- nav_account_oauth_apps: { label: "OAuth \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3" },
9458
- nav_account_preferences: { label: "\u74B0\u5883\u8A2D\u5B9A" }
9455
+ nav_account_oauth_apps: { label: "OAuth \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3" }
9459
9456
  }
9460
9457
  },
9461
9458
  setup: {
@@ -12627,8 +12624,7 @@ var esES = {
12627
12624
  nav_account_linked: { label: "Cuentas vinculadas" },
12628
12625
  nav_account_sessions: { label: "Sesiones activas" },
12629
12626
  nav_account_api_keys: { label: "Claves API" },
12630
- nav_account_oauth_apps: { label: "Aplicaciones OAuth" },
12631
- nav_account_preferences: { label: "Preferencias" }
12627
+ nav_account_oauth_apps: { label: "Aplicaciones OAuth" }
12632
12628
  }
12633
12629
  },
12634
12630
  setup: {