@ketvietlab/ketsuite 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/modules/activity_backend/islands.d.ts +39 -2
  3. package/dist/modules/activity_backend/islands.d.ts.map +1 -1
  4. package/dist/modules/activity_backend/islands.js +5 -5
  5. package/dist/modules/activity_backend/islands.js.map +1 -1
  6. package/dist/modules/backend/design/client/backend-shell.d.mts +6 -0
  7. package/dist/modules/backend/design/client/backend-shell.d.mts.map +1 -0
  8. package/dist/modules/backend/design/client/backend-shell.mjs +2 -0
  9. package/dist/modules/backend/design/client/backend-shell.mjs.map +7 -0
  10. package/dist/modules/backend/design/client/chart.d.mts +3 -0
  11. package/dist/modules/backend/design/client/chart.d.mts.map +1 -1
  12. package/dist/modules/backend/design/client/chart.mjs +1 -1
  13. package/dist/modules/backend/design/client/chart.mjs.map +3 -3
  14. package/dist/modules/backend/design/design-system.css +1 -1
  15. package/dist/modules/backend/design/record.css +15 -2
  16. package/dist/modules/backend/index.d.ts.map +1 -1
  17. package/dist/modules/backend/index.js +8 -2
  18. package/dist/modules/backend/index.js.map +1 -1
  19. package/dist/modules/backend/islands.d.ts +38 -2
  20. package/dist/modules/backend/islands.d.ts.map +1 -1
  21. package/dist/modules/backend/islands.js +5 -11
  22. package/dist/modules/backend/islands.js.map +1 -1
  23. package/dist/modules/backend/joints.js +1 -1
  24. package/dist/modules/calendar_backend/islands.d.ts +20 -2
  25. package/dist/modules/calendar_backend/islands.d.ts.map +1 -1
  26. package/dist/modules/calendar_backend/islands.js +3 -3
  27. package/dist/modules/calendar_backend/islands.js.map +1 -1
  28. package/dist/modules/crm_backend/client/crm-kanban-view.d.mts.map +1 -1
  29. package/dist/modules/crm_backend/client/crm-kanban-view.mjs +0 -1
  30. package/dist/modules/crm_backend/client/crm-kanban-view.mjs.map +1 -1
  31. package/dist/modules/crm_backend/islands.d.ts +16 -2
  32. package/dist/modules/crm_backend/islands.d.ts.map +1 -1
  33. package/dist/modules/crm_backend/islands.js +3 -3
  34. package/dist/modules/crm_backend/islands.js.map +1 -1
  35. package/dist/modules/flow_backend/islands.d.ts +41 -2
  36. package/dist/modules/flow_backend/islands.d.ts.map +1 -1
  37. package/dist/modules/flow_backend/islands.js +8 -8
  38. package/dist/modules/flow_backend/islands.js.map +1 -1
  39. package/dist/modules/livedoc/islands.d.ts +24 -2
  40. package/dist/modules/livedoc/islands.d.ts.map +1 -1
  41. package/dist/modules/livedoc/islands.js +6 -5
  42. package/dist/modules/livedoc/islands.js.map +1 -1
  43. package/dist/modules/mail_backend/islands.d.ts +39 -2
  44. package/dist/modules/mail_backend/islands.d.ts.map +1 -1
  45. package/dist/modules/mail_backend/islands.js +5 -5
  46. package/dist/modules/mail_backend/islands.js.map +1 -1
  47. package/dist/modules/partner_backend/islands.d.ts +35 -2
  48. package/dist/modules/partner_backend/islands.d.ts.map +1 -1
  49. package/dist/modules/partner_backend/islands.js +3 -3
  50. package/dist/modules/partner_backend/islands.js.map +1 -1
  51. package/dist/modules/product_backend/client/editor-view.d.mts +5 -4
  52. package/dist/modules/product_backend/client/editor-view.d.mts.map +1 -1
  53. package/dist/modules/product_backend/client/editor-view.mjs +53 -79
  54. package/dist/modules/product_backend/client/editor-view.mjs.map +1 -1
  55. package/dist/modules/product_backend/client/product.d.mts +2 -5
  56. package/dist/modules/product_backend/client/product.d.mts.map +1 -1
  57. package/dist/modules/product_backend/client/product.mjs +2 -3
  58. package/dist/modules/product_backend/client/product.mjs.map +1 -1
  59. package/dist/modules/product_backend/index.d.ts.map +1 -1
  60. package/dist/modules/product_backend/index.js +7 -0
  61. package/dist/modules/product_backend/index.js.map +1 -1
  62. package/dist/modules/product_backend/islands.d.ts +35 -2
  63. package/dist/modules/product_backend/islands.d.ts.map +1 -1
  64. package/dist/modules/product_backend/islands.js +7 -9
  65. package/dist/modules/product_backend/islands.js.map +1 -1
  66. package/dist/modules/sale_backend/client/editor-view.d.mts +5 -4
  67. package/dist/modules/sale_backend/client/editor-view.d.mts.map +1 -1
  68. package/dist/modules/sale_backend/client/editor-view.mjs +49 -71
  69. package/dist/modules/sale_backend/client/editor-view.mjs.map +1 -1
  70. package/dist/modules/sale_backend/client/sale.d.mts +1 -5
  71. package/dist/modules/sale_backend/client/sale.d.mts.map +1 -1
  72. package/dist/modules/sale_backend/client/sale.mjs +1 -8
  73. package/dist/modules/sale_backend/client/sale.mjs.map +1 -1
  74. package/dist/modules/sale_backend/index.js +7 -0
  75. package/dist/modules/sale_backend/index.js.map +1 -1
  76. package/dist/modules/sale_backend/islands.d.ts +17 -2
  77. package/dist/modules/sale_backend/islands.d.ts.map +1 -1
  78. package/dist/modules/sale_backend/islands.js +5 -7
  79. package/dist/modules/sale_backend/islands.js.map +1 -1
  80. package/dist/modules/stock_backend/client/editor-view.d.mts +5 -4
  81. package/dist/modules/stock_backend/client/editor-view.d.mts.map +1 -1
  82. package/dist/modules/stock_backend/client/editor-view.mjs +77 -92
  83. package/dist/modules/stock_backend/client/editor-view.mjs.map +1 -1
  84. package/dist/modules/stock_backend/client/stock.d.mts +1 -5
  85. package/dist/modules/stock_backend/client/stock.d.mts.map +1 -1
  86. package/dist/modules/stock_backend/client/stock.mjs +1 -8
  87. package/dist/modules/stock_backend/client/stock.mjs.map +1 -1
  88. package/dist/modules/stock_backend/index.js +7 -0
  89. package/dist/modules/stock_backend/index.js.map +1 -1
  90. package/dist/modules/stock_backend/islands.d.ts +19 -2
  91. package/dist/modules/stock_backend/islands.d.ts.map +1 -1
  92. package/dist/modules/stock_backend/islands.js +5 -7
  93. package/dist/modules/stock_backend/islands.js.map +1 -1
  94. package/dist/modules/website/cms.d.ts.map +1 -1
  95. package/dist/modules/website/cms.js +34 -7
  96. package/dist/modules/website/cms.js.map +1 -1
  97. package/dist/modules/website_backend/index.js +144 -0
  98. package/dist/modules/website_backend/index.js.map +1 -1
  99. package/dist/modules/website_backend/screens/index.d.ts +11 -0
  100. package/dist/modules/website_backend/screens/index.d.ts.map +1 -1
  101. package/dist/modules/website_backend/screens/index.js +335 -112
  102. package/dist/modules/website_backend/screens/index.js.map +1 -1
  103. package/dist/modules/website_backend/screens/page-frame.d.ts +2 -1
  104. package/dist/modules/website_backend/screens/page-frame.d.ts.map +1 -1
  105. package/dist/modules/website_backend/screens/page-frame.js +1 -1
  106. package/dist/modules/website_backend/screens/page-frame.js.map +1 -1
  107. package/dist/modules/website_search/client/search.d.mts +8 -1
  108. package/dist/modules/website_search/client/search.d.mts.map +1 -1
  109. package/dist/modules/website_search/client/search.mjs +37 -16
  110. package/dist/modules/website_search/client/search.mjs.map +1 -1
  111. package/dist/modules/website_search/islands.d.ts +18 -2
  112. package/dist/modules/website_search/islands.d.ts.map +1 -1
  113. package/dist/modules/website_search/islands.js +4 -14
  114. package/dist/modules/website_search/islands.js.map +1 -1
  115. package/dist/scaffold/index.js +1 -1
  116. package/dist/ui/client/activity-view.d.mts +2 -0
  117. package/dist/ui/client/activity-view.d.mts.map +1 -1
  118. package/dist/ui/client/activity-view.mjs +6 -4
  119. package/dist/ui/client/activity-view.mjs.map +1 -1
  120. package/dist/ui/client/activity.d.mts +2 -0
  121. package/dist/ui/client/activity.d.mts.map +1 -1
  122. package/dist/ui/client/calendar-view.d.mts +1 -0
  123. package/dist/ui/client/calendar-view.d.mts.map +1 -1
  124. package/dist/ui/client/calendar-view.mjs +1 -2
  125. package/dist/ui/client/calendar-view.mjs.map +1 -1
  126. package/dist/ui/client/calendar.d.mts +1 -0
  127. package/dist/ui/client/calendar.d.mts.map +1 -1
  128. package/dist/ui/client/chart-view.d.ts +1 -7
  129. package/dist/ui/client/chart-view.d.ts.map +1 -1
  130. package/dist/ui/client/chart-view.js +10 -13
  131. package/dist/ui/client/chart-view.js.map +1 -1
  132. package/dist/ui/client/flow-board-view.d.mts.map +1 -1
  133. package/dist/ui/client/flow-board-view.mjs +3 -4
  134. package/dist/ui/client/flow-board-view.mjs.map +1 -1
  135. package/dist/ui/client/live-doc-view.d.ts +3 -3
  136. package/dist/ui/client/live-doc-view.d.ts.map +1 -1
  137. package/dist/ui/client/live-doc-view.js +13 -10
  138. package/dist/ui/client/live-doc-view.js.map +1 -1
  139. package/dist/ui/client/live-doc.d.mts +4 -1
  140. package/dist/ui/client/live-doc.d.mts.map +1 -1
  141. package/dist/ui/client/live-doc.mjs +1 -1
  142. package/dist/ui/client/live-doc.mjs.map +3 -3
  143. package/dist/ui/client/mail-bundle.d.mts +5 -3
  144. package/dist/ui/client/mail-bundle.d.mts.map +1 -1
  145. package/dist/ui/client/mail-bundle.mjs +5 -5
  146. package/dist/ui/client/mail-bundle.mjs.map +2 -2
  147. package/dist/ui/client/mail-entry.d.mts +2 -0
  148. package/dist/ui/client/mail-entry.d.mts.map +1 -1
  149. package/dist/ui/client/mail-view.d.mts +2 -0
  150. package/dist/ui/client/mail-view.d.mts.map +1 -1
  151. package/dist/ui/client/mail-view.mjs +6 -4
  152. package/dist/ui/client/mail-view.mjs.map +1 -1
  153. package/dist/ui/client/table-selection-view.d.ts +2 -3
  154. package/dist/ui/client/table-selection-view.d.ts.map +1 -1
  155. package/dist/ui/client/table-selection-view.js +49 -72
  156. package/dist/ui/client/table-selection-view.js.map +1 -1
  157. package/dist/ui/client/user-workflow.d.ts +1 -1
  158. package/dist/ui/client/user-workflow.d.ts.map +1 -1
  159. package/dist/ui/client/user-workflow.js +12 -10
  160. package/dist/ui/client/user-workflow.js.map +1 -1
  161. package/dist/ui/form-page.d.ts +14 -4
  162. package/dist/ui/form-page.d.ts.map +1 -1
  163. package/dist/ui/form-page.js +11 -3
  164. package/dist/ui/form-page.js.map +1 -1
  165. package/package.json +4 -4
  166. package/dist/modules/backend/design/client/table-selection.d.mts +0 -7
  167. package/dist/modules/backend/design/client/table-selection.d.mts.map +0 -1
  168. package/dist/modules/backend/design/client/table-selection.mjs +0 -2
  169. package/dist/modules/backend/design/client/table-selection.mjs.map +0 -7
@@ -1,5 +1,5 @@
1
- import { jsx as _jsx } from "@ketvietlab/ketjs-view/jsx-runtime";
2
- import { badge, code, dataTable, emptyState, RecordScreen, inline, linkButton, Notice, pagerBar, RecordActions, RecordForm, Section, stack, Surface, } from '../../../ui/index.js';
1
+ import { Fragment as _Fragment, jsx as _jsx } from "@ketvietlab/ketjs-view/jsx-runtime";
2
+ import { badge, code, columns, ContentCard, dataTable, emptyState, RecordScreen, inline, linkButton, Notice, pagerBar, RecordActions, RecordForm, Section, stack, Surface, } from '../../../ui/index.js';
3
3
  import { FormScreenFrame, ListScreenFrame } from './page-frame.js';
4
4
  const statusTone = (status) => status === 'published'
5
5
  ? 'positive'
@@ -30,6 +30,113 @@ const activeFilter = (_, href, chosen) => inline([
30
30
  variant: chosen === 'inactive' ? 'secondary' : 'tertiary',
31
31
  }),
32
32
  ]);
33
+ const roleLabel = (_, role) => {
34
+ if (!role)
35
+ return _('website_backend.sites.roleUnknown');
36
+ const key = `website_backend.role.${role}`;
37
+ return _.has?.(key) ? _(key) : role;
38
+ };
39
+ const companyLabel = (_, frame, row) => {
40
+ const viewer = frame.viewer;
41
+ return (row?.siteGroup || viewer?.companyName || viewer?.branchName || _('website_backend.sites.companyCurrent'));
42
+ };
43
+ const primaryHost = (_, row) => row.primaryHost ||
44
+ (row.domainCount ? _('website_backend.sites.noPrimary') : _('website_backend.sites.noDomain'));
45
+ const domainEvidenceBadge = (_, row) => row.primaryHost
46
+ ? badge(_('website_backend.domains.pendingEvidence'), 'warning')
47
+ : row.domainCount
48
+ ? badge(_('website_backend.sites.noPrimary'), 'warning')
49
+ : badge(_('website_backend.sites.noDomain'), 'neutral');
50
+ const siteFacts = (_, items) => dataTable(_, {
51
+ rows: items.map(([term, value], index) => ({ id: String(index), term, value })),
52
+ id: (item) => item.id,
53
+ columns: [
54
+ {
55
+ key: 'term',
56
+ label: _('website_backend.sites.setting'),
57
+ cell: (item) => item.term,
58
+ priority: 'primary',
59
+ },
60
+ { key: 'value', label: _('website_backend.sites.value'), cell: (item) => item.value },
61
+ ],
62
+ responsive: 'stack',
63
+ });
64
+ const setupChecklist = (_) => (_jsx(Surface, { tone: "subtle", body: siteFacts(_, [
65
+ [_('website_backend.sites.step1'), _('website_backend.sites.step1Hint')],
66
+ [_('website_backend.sites.step2'), _('website_backend.sites.step2Hint')],
67
+ [_('website_backend.sites.step3'), _('website_backend.sites.step3Hint')],
68
+ [_('website_backend.sites.step4'), _('website_backend.sites.step4Hint')],
69
+ ]) }));
70
+ const siteReadiness = (_, row, frame) => {
71
+ const host = row.primaryHost || _('website_backend.sites.noDomain');
72
+ return (_jsx(Section, { title: _('website_backend.sites.readinessTitle'), description: _('website_backend.sites.readinessHint'), body: stack([
73
+ _jsx(Surface, { body: siteFacts(_, [
74
+ [_('website_backend.sites.company'), companyLabel(_, frame, row)],
75
+ [_('website_backend.sites.publicUrl'), host],
76
+ [_('website_backend.domains.title'), domainEvidenceBadge(_, row)],
77
+ [_('website_backend.field.theme'), code(String(row.theme ?? ''))],
78
+ [_('website_backend.sites.homepage'), `/${row.defaultLocale ?? 'vi'}`],
79
+ [
80
+ _('website_backend.sites.missingSettings'),
81
+ row.primaryHost
82
+ ? badge(_('website_backend.sites.needsPlatform'), 'warning')
83
+ : badge(_('website_backend.sites.needsDomain'), 'warning'),
84
+ ],
85
+ ]) }),
86
+ ]) }));
87
+ };
88
+ const siteCapabilityPanel = (_, row) => (_jsx(Section, { title: _('website_backend.sites.capabilityTitle'), description: _('website_backend.sites.capabilityHint'), body: dataTable(_, {
89
+ rows: [
90
+ {
91
+ key: 'public',
92
+ setting: row.primaryHost || _('website_backend.sites.noDomain'),
93
+ state: row.primaryHost ? 'pending' : 'missing',
94
+ },
95
+ { key: 'realm', setting: _('website_backend.sites.realmAuto'), state: 'ready' },
96
+ { key: 'theme', setting: String(row.theme ?? ''), state: row.theme ? 'ready' : 'missing' },
97
+ { key: 'binding', setting: _('website_backend.sites.bindingDeployment'), state: 'pending' },
98
+ ],
99
+ id: (item) => item.key,
100
+ columns: [
101
+ {
102
+ key: 'capability',
103
+ label: _('website_backend.sites.capability'),
104
+ cell: (item) => _(`website_backend.sites.capability.${item.key}`),
105
+ priority: 'primary',
106
+ },
107
+ { key: 'setting', label: _('website_backend.sites.setting'), cell: (item) => item.setting },
108
+ {
109
+ key: 'state',
110
+ label: _('website_backend.field.status'),
111
+ kind: 'status',
112
+ cell: (item) => item.state === 'ready'
113
+ ? badge(_('website_backend.sites.ready'), 'positive')
114
+ : item.state === 'pending'
115
+ ? badge(_('website_backend.sites.pending'), 'warning')
116
+ : badge(_('website_backend.sites.missing'), 'danger'),
117
+ },
118
+ ],
119
+ }) }));
120
+ const domainStateSummary = (_, row) => (_jsx(Surface, { tone: "subtle", body: siteFacts(_, [
121
+ [
122
+ _('website_backend.domains.ownership'),
123
+ badge(_('website_backend.domains.pendingEvidence'), 'warning'),
124
+ ],
125
+ [_('website_backend.domains.tls'), badge(_('website_backend.domains.pendingEvidence'), 'warning')],
126
+ [
127
+ _('website_backend.domains.primary'),
128
+ row.primary
129
+ ? badge(_('website_backend.state.yes'), 'positive')
130
+ : badge(_('website_backend.state.no'), 'neutral'),
131
+ ],
132
+ [_('website_backend.domains.operation'), row.operationId || _('website_backend.domains.noOperation')],
133
+ ]) }));
134
+ const domainInstructions = (_, site, row) => (_jsx(Surface, { body: siteFacts(_, [
135
+ [_('website_backend.domains.siteTarget'), site.title],
136
+ [_('website_backend.domains.normalizedHost'), code(row.host)],
137
+ [_('website_backend.domains.challenge'), _('website_backend.domains.challengeHint')],
138
+ [_('website_backend.domains.nextStep'), _('website_backend.domains.nextStepHint')],
139
+ ]) }));
33
140
  export const sitesScreen = (_, rows, frame, locale = '', active = 'all') => (_jsx(ListScreenFrame, { translator: _, title: _('website_backend.sites.title'), frame: frame, body: stack([
34
141
  inline([
35
142
  linkButton({
@@ -52,104 +159,155 @@ export const sitesScreen = (_, rows, frame, locale = '', active = 'all') => (_js
52
159
  rowHref: (row) => `/admin/website/sites/${row.id}${locale}`,
53
160
  columns: [
54
161
  {
55
- key: 'name',
56
- label: _('website_backend.field.name'),
162
+ key: 'site',
163
+ label: _('website_backend.sites.site'),
57
164
  priority: 'primary',
58
- cell: (row) => row.name,
165
+ cell: (row) => `${row.title} · ${companyLabel(_, frame, row)}`,
59
166
  },
60
167
  {
61
- key: 'title',
62
- label: _('website_backend.field.siteTitle'),
168
+ key: 'primaryHost',
169
+ label: _('website_backend.sites.primaryHost'),
63
170
  priority: 'primary',
64
- cell: (row) => row.title,
171
+ cell: (row) => primaryHost(_, row),
65
172
  },
66
173
  {
67
174
  key: 'locale',
68
175
  label: _('website_backend.field.locale'),
69
176
  cell: (row) => code(row.defaultLocale),
70
177
  },
71
- { key: 'theme', label: _('website_backend.field.theme'), cell: (row) => code(row.theme) },
72
178
  {
73
179
  key: 'state',
74
180
  label: _('website_backend.field.status'),
75
181
  kind: 'status',
76
- cell: (row) => badge(row.active ? _('website_backend.state.active') : _('website_backend.state.inactive'), row.active ? 'positive' : 'neutral'),
182
+ cell: (row) => row.active
183
+ ? domainEvidenceBadge(_, row)
184
+ : badge(_('website_backend.state.inactive'), 'neutral'),
185
+ },
186
+ {
187
+ key: 'role',
188
+ label: _('website_backend.sites.yourRole'),
189
+ cell: (row) => roleLabel(_, row.role),
77
190
  },
78
191
  ],
192
+ responsive: 'stack',
79
193
  }),
80
194
  ]) }));
81
195
  export const siteFormScreen = (_, row, themes, frame, options = {}) => {
82
196
  const existing = !!row.id;
83
- return (_jsx(FormScreenFrame, { translator: _, title: existing ? String(row.title ?? row.name) : _('website_backend.sites.newTitle'), frame: frame, body: stack([
84
- // Only on a site that exists: membership, domains and the index all
85
- // need something to hang off, and offering them while creating would
86
- // be offering to configure a thing that is not there yet.
197
+ const locale = options.locale ?? '';
198
+ const form = (_jsx(Section, { eyebrow: _('website_backend.sites.eyebrow'), title: existing ? String(row.title ?? row.name) : _('website_backend.sites.newTitle'), description: _('website_backend.sites.formHint'), body: _jsx(Surface, { body: _jsx(RecordForm, { action: existing ? `/admin/website/sites/${row.id}${locale}` : `/admin/website/sites/new${locale}`, fields: [
199
+ {
200
+ name: 'title',
201
+ label: _('website_backend.field.siteTitle'),
202
+ value: row.title,
203
+ required: true,
204
+ },
205
+ { name: 'name', label: _('website_backend.field.name'), value: row.name, required: true },
206
+ {
207
+ name: 'companyContext',
208
+ label: _('website_backend.sites.company'),
209
+ value: companyLabel(_, frame, row),
210
+ disabled: true,
211
+ help: _('website_backend.sites.companyHint'),
212
+ },
213
+ {
214
+ name: 'defaultLocale',
215
+ label: _('website_backend.field.locale'),
216
+ type: 'select',
217
+ value: row.defaultLocale ?? 'vi',
218
+ options: [
219
+ { value: 'vi', label: 'Tiếng Việt' },
220
+ { value: 'en', label: 'English' },
221
+ ],
222
+ required: true,
223
+ },
224
+ {
225
+ name: 'timezone',
226
+ label: _('website_backend.sites.timezone'),
227
+ value: 'Asia/Ho_Chi_Minh',
228
+ disabled: true,
229
+ help: _('website_backend.sites.timezoneHint'),
230
+ },
231
+ {
232
+ name: 'theme',
233
+ label: _('website_backend.field.theme'),
234
+ type: 'select',
235
+ value: row.theme,
236
+ options: themes,
237
+ required: true,
238
+ },
239
+ {
240
+ name: 'description',
241
+ label: _('website_backend.field.description'),
242
+ type: 'textarea',
243
+ value: '',
244
+ placeholder: _('website_backend.sites.descriptionPlaceholder'),
245
+ disabled: true,
246
+ help: _('website_backend.sites.descriptionHint'),
247
+ span: 'full',
248
+ },
249
+ {
250
+ // The layer order already puts a site above its theme, so these
251
+ // override rather than replace: a site that sets nothing looks
252
+ // exactly as it did.
253
+ name: 'tokens',
254
+ label: _('website_backend.field.tokens'),
255
+ type: 'textarea',
256
+ value: JSON.stringify(row.tokens ?? {}, null, 2),
257
+ help: _('website_backend.field.tokensHint'),
258
+ span: 'full',
259
+ },
260
+ {
261
+ name: 'active',
262
+ label: _('website_backend.field.active'),
263
+ type: 'checkbox',
264
+ value: row.active ?? true,
265
+ span: 'full',
266
+ },
267
+ ], submit: _('website_backend.action.save'), submitVariant: "primary", errors: options.errors, cancelHref: `/admin/website/sites${locale}`, cancelLabel: _('website_backend.action.cancel') }) }) }));
268
+ return (_jsx(FormScreenFrame, { translator: _, title: existing ? String(row.title ?? row.name) : _('website_backend.sites.newTitle'), frame: frame, width: "wide", body: stack([
87
269
  ...(existing
88
270
  ? [
89
271
  inline([
90
272
  linkButton({
91
- label: _('website_backend.members.title'),
92
- href: `/admin/website/sites/${row.id}/members${options.locale ?? ''}`,
273
+ label: _('website_backend.sites.generalTab'),
274
+ href: `/admin/website/sites/${row.id}${locale}`,
275
+ variant: 'secondary',
93
276
  }),
94
277
  linkButton({
95
278
  label: _('website_backend.domains.title'),
96
- href: `/admin/website/sites/${row.id}/domains${options.locale ?? ''}`,
279
+ href: `/admin/website/sites/${row.id}/domains${locale}`,
280
+ }),
281
+ linkButton({
282
+ label: _('website_backend.members.title'),
283
+ href: `/admin/website/sites/${row.id}/members${locale}`,
284
+ }),
285
+ linkButton({
286
+ label: _('website_backend.sites.themeTab'),
287
+ href: `/admin/website/sites/${row.id}${locale}`,
288
+ disabled: true,
289
+ }),
290
+ linkButton({
291
+ label: _('website_backend.sites.customerTab'),
292
+ href: `/admin/website/sites/${row.id}${locale}`,
293
+ disabled: true,
97
294
  }),
98
295
  linkButton({
99
296
  label: _('website_backend.index.title'),
100
- href: `/admin/website/sites/${row.id}/index${options.locale ?? ''}`,
297
+ href: `/admin/website/sites/${row.id}/index${locale}`,
101
298
  }),
102
299
  ]),
103
300
  ]
104
301
  : []),
105
- _jsx(Section, { eyebrow: _('website_backend.sites.eyebrow'), title: existing ? String(row.title ?? row.name) : _('website_backend.sites.newTitle'), description: _('website_backend.sites.formHint'), body: _jsx(Surface, { body: _jsx(RecordForm, { action: existing
106
- ? `/admin/website/sites/${row.id}${options.locale ?? ''}`
107
- : `/admin/website/sites/new${options.locale ?? ''}`, fields: [
108
- { name: 'name', label: _('website_backend.field.name'), value: row.name, required: true },
109
- {
110
- name: 'title',
111
- label: _('website_backend.field.siteTitle'),
112
- value: row.title,
113
- required: true,
114
- },
115
- {
116
- name: 'defaultLocale',
117
- label: _('website_backend.field.locale'),
118
- type: 'select',
119
- value: row.defaultLocale ?? 'vi',
120
- options: [
121
- { value: 'vi', label: 'Tiếng Việt' },
122
- { value: 'en', label: 'English' },
123
- ],
124
- required: true,
125
- },
126
- {
127
- name: 'theme',
128
- label: _('website_backend.field.theme'),
129
- type: 'select',
130
- value: row.theme,
131
- options: themes,
132
- required: true,
133
- },
134
- {
135
- // The layer order already puts a site above its theme, so
136
- // these override rather than replace: a site that sets
137
- // nothing looks exactly as it did.
138
- name: 'tokens',
139
- label: _('website_backend.field.tokens'),
140
- type: 'textarea',
141
- value: JSON.stringify(row.tokens ?? {}, null, 2),
142
- help: _('website_backend.field.tokensHint'),
143
- span: 'full',
144
- },
145
- {
146
- name: 'active',
147
- label: _('website_backend.field.active'),
148
- type: 'checkbox',
149
- value: row.active ?? true,
150
- span: 'full',
151
- },
152
- ], submit: _('website_backend.action.save'), submitVariant: "primary", errors: options.errors, cancelHref: `/admin/website/sites${options.locale ?? ''}`, cancelLabel: _('website_backend.action.cancel') }) }) }),
302
+ existing
303
+ ? stack([form, columns([siteCapabilityPanel(_, row), siteReadiness(_, row, frame)], 'loose')])
304
+ : stack([
305
+ form,
306
+ columns([
307
+ _jsx(Section, { title: _('website_backend.sites.initialSetup'), body: setupChecklist(_) }),
308
+ siteReadiness(_, row, frame),
309
+ ], 'loose'),
310
+ ]),
153
311
  ]) }));
154
312
  };
155
313
  export const contentScreen = (_, rows, sites, siteId, frame, locale = '', kind = { basePath: '/admin/website/pages', titleKey: 'pages' }, pager = null,
@@ -1350,27 +1508,58 @@ export const siteMembersScreen = (_, site, rows, frame, options = {}) => (_jsx(L
1350
1508
  export const siteDomainsScreen = (_, site, rows, frame, options = {}) => {
1351
1509
  const editing = options.editing ?? null;
1352
1510
  const values = options.values ?? {};
1511
+ const locale = options.locale ?? '';
1512
+ const primary = rows.find((row) => row.primary) ?? null;
1513
+ const domainCards = rows.map((row) => (_jsx(ContentCard, { title: row.host, summary: row.primary ? _('website_backend.domains.primarySummary') : _('website_backend.domains.aliasSummary'), body: stack([domainStateSummary(_, row), domainInstructions(_, site, row)], 'compact'), actions: inline([
1514
+ linkButton({
1515
+ label: _('website_backend.domains.requestVerification'),
1516
+ href: `/admin/website/health${locale}`,
1517
+ size: 'compact',
1518
+ variant: 'primary',
1519
+ }),
1520
+ linkButton({
1521
+ label: _('website_backend.action.edit'),
1522
+ href: `/admin/website/sites/${site.id}/domains?edit=${encodeURIComponent(row.id)}${locale ? `&${locale.slice(1)}` : ''}`,
1523
+ size: 'compact',
1524
+ }),
1525
+ ]) })));
1353
1526
  return (_jsx(ListScreenFrame, { translator: _, title: _('website_backend.domains.title'), frame: frame, body: stack([
1354
1527
  inline([
1355
1528
  linkButton({
1356
1529
  label: _('website_backend.action.backToSite'),
1357
- href: `/admin/website/sites/${site.id}${options.locale ?? ''}`,
1530
+ href: `/admin/website/sites/${site.id}${locale}`,
1358
1531
  }),
1359
1532
  ...(editing
1360
1533
  ? [
1361
1534
  linkButton({
1362
1535
  label: _('website_backend.action.cancel'),
1363
- href: `/admin/website/sites/${site.id}/domains${options.locale ?? ''}`,
1536
+ href: `/admin/website/sites/${site.id}/domains${locale}`,
1364
1537
  }),
1365
1538
  ]
1366
1539
  : []),
1367
1540
  ]),
1368
- _jsx(Section, { title: editing ? _('website_backend.domains.edit') : _('website_backend.domains.add'), description: _('website_backend.domains.addHint'), body: _jsx(Surface, { padding: "compact", body: _jsx(RecordForm, { action: `/admin/website/sites/${site.id}/domains${editing ? `/${editing.id}` : ''}${options.locale ?? ''}`, layout: "inline", fields: [
1541
+ rows.length === 0
1542
+ ? Notice({
1543
+ tone: 'warning',
1544
+ title: _('website_backend.domains.noPrimaryTitle'),
1545
+ message: _('website_backend.domains.noPrimaryMessage'),
1546
+ })
1547
+ : Notice({
1548
+ tone: primary ? 'warning' : 'danger',
1549
+ title: primary
1550
+ ? _('website_backend.domains.pendingTitle')
1551
+ : _('website_backend.domains.noPrimaryTitle'),
1552
+ message: primary
1553
+ ? _('website_backend.domains.pendingMessage')
1554
+ : _('website_backend.domains.noPrimaryMessage'),
1555
+ }),
1556
+ _jsx(Section, { title: editing ? _('website_backend.domains.edit') : _('website_backend.domains.add'), description: _('website_backend.domains.addHint'), body: _jsx(Surface, { padding: "compact", body: _jsx(RecordForm, { action: `/admin/website/sites/${site.id}/domains${editing ? `/${editing.id}` : ''}${locale}`, layout: "inline", fields: [
1369
1557
  {
1370
1558
  name: 'host',
1371
1559
  label: _('website_backend.domains.host'),
1372
1560
  value: values.host ?? editing?.host,
1373
1561
  required: true,
1562
+ help: _('website_backend.domains.hostHint'),
1374
1563
  },
1375
1564
  {
1376
1565
  name: 'primary',
@@ -1390,50 +1579,84 @@ export const siteDomainsScreen = (_, site, rows, frame, options = {}) => {
1390
1579
  ], submit: _('website_backend.action.save'), submitVariant: "primary", errors: options.errors }) }) }),
1391
1580
  rows.length === 0
1392
1581
  ? emptyState(_('website_backend.domains.empty'), _('website_backend.domains.emptyHint'))
1393
- : dataTable(_, {
1394
- rows,
1395
- id: (row) => row.id,
1396
- columns: [
1397
- {
1398
- key: 'host',
1399
- label: _('website_backend.domains.host'),
1400
- priority: 'primary',
1401
- cell: (row) => row.host,
1402
- },
1403
- {
1404
- key: 'primary',
1405
- label: _('website_backend.domains.primary'),
1406
- cell: (row) => row.primary
1407
- ? badge(_('website_backend.state.yes'), 'positive')
1408
- : badge(_('website_backend.state.no'), 'neutral'),
1409
- },
1410
- {
1411
- key: 'redirect',
1412
- label: _('website_backend.domains.redirect'),
1413
- cell: (row) => badge(row.redirectToPrimary ? _('website_backend.state.yes') : _('website_backend.state.no'), 'neutral'),
1414
- },
1415
- {
1416
- key: 'edit',
1417
- label: _('website_backend.action.edit'),
1418
- cell: (row) => linkButton({
1419
- label: _('website_backend.action.edit'),
1420
- href: `/admin/website/sites/${site.id}/domains?edit=${encodeURIComponent(row.id)}${options.locale ? `&${options.locale.slice(1)}` : ''}`,
1421
- size: 'compact',
1582
+ : columns([
1583
+ stack(domainCards),
1584
+ _jsx(Section, { title: _('website_backend.domains.readinessTitle'), description: _('website_backend.domains.readinessHint'), body: stack([
1585
+ _jsx(Surface, { body: siteFacts(_, [
1586
+ [_('website_backend.domains.siteTarget'), site.title],
1587
+ [
1588
+ _('website_backend.sites.primaryHost'),
1589
+ primary?.host ?? _('website_backend.sites.noPrimary'),
1590
+ ],
1591
+ [_('website_backend.domains.lastCheck'), _('website_backend.domains.noOperation')],
1592
+ [
1593
+ _('website_backend.domains.tls'),
1594
+ badge(_('website_backend.domains.pendingEvidence'), 'warning'),
1595
+ ],
1596
+ [
1597
+ _('website_backend.domains.aliases'),
1598
+ String(Math.max(0, rows.length - (primary ? 1 : 0))),
1599
+ ],
1600
+ ]) }),
1601
+ Notice({
1602
+ tone: 'info',
1603
+ title: _('website_backend.domains.keepOldTitle'),
1604
+ message: _('website_backend.domains.keepOldMessage'),
1422
1605
  }),
1423
- },
1424
- {
1425
- key: 'remove',
1426
- label: _('website_backend.action.remove'),
1427
- cell: (row) => (_jsx(RecordActions, { action: `/admin/website/sites/${site.id}/domains/${row.id}/remove${options.locale ?? ''}`, size: "compact", actions: [
1428
- {
1429
- value: 'remove',
1430
- label: _('website_backend.action.remove'),
1431
- variant: 'destructive',
1432
- },
1433
- ] })),
1434
- },
1435
- ],
1436
- }),
1606
+ ]) }),
1607
+ ], 'loose'),
1608
+ rows.length === 0 ? (_jsx(_Fragment, {})) : (dataTable(_, {
1609
+ rows,
1610
+ id: (row) => row.id,
1611
+ columns: [
1612
+ {
1613
+ key: 'host',
1614
+ label: _('website_backend.domains.host'),
1615
+ priority: 'primary',
1616
+ cell: (row) => row.host,
1617
+ },
1618
+ {
1619
+ key: 'evidence',
1620
+ label: _('website_backend.domains.evidence'),
1621
+ kind: 'status',
1622
+ cell: () => badge(_('website_backend.domains.pendingEvidence'), 'warning'),
1623
+ },
1624
+ {
1625
+ key: 'tls',
1626
+ label: _('website_backend.domains.tls'),
1627
+ kind: 'status',
1628
+ cell: () => badge(_('website_backend.domains.pendingEvidence'), 'warning'),
1629
+ },
1630
+ {
1631
+ key: 'primary',
1632
+ label: _('website_backend.domains.primary'),
1633
+ cell: (row) => row.primary
1634
+ ? badge(_('website_backend.state.yes'), 'positive')
1635
+ : badge(_('website_backend.state.no'), 'neutral'),
1636
+ },
1637
+ {
1638
+ key: 'edit',
1639
+ label: _('website_backend.action.edit'),
1640
+ cell: (row) => linkButton({
1641
+ label: _('website_backend.action.edit'),
1642
+ href: `/admin/website/sites/${site.id}/domains?edit=${encodeURIComponent(row.id)}${locale ? `&${locale.slice(1)}` : ''}`,
1643
+ size: 'compact',
1644
+ }),
1645
+ },
1646
+ {
1647
+ key: 'remove',
1648
+ label: _('website_backend.action.remove'),
1649
+ cell: (row) => (_jsx(RecordActions, { action: `/admin/website/sites/${site.id}/domains/${row.id}/remove${locale}`, size: "compact", actions: [
1650
+ {
1651
+ value: 'remove',
1652
+ label: _('website_backend.action.remove'),
1653
+ variant: 'destructive',
1654
+ },
1655
+ ] })),
1656
+ },
1657
+ ],
1658
+ responsive: 'stack',
1659
+ })),
1437
1660
  ]) }));
1438
1661
  };
1439
1662
  /**