@byline/cli 0.1.1

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 (251) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +23 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +72 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/doctor.d.ts +2 -0
  8. package/dist/commands/doctor.d.ts.map +1 -0
  9. package/dist/commands/doctor.js +36 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/init.d.ts +16 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +76 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/context.d.ts +38 -0
  16. package/dist/context.d.ts.map +1 -0
  17. package/dist/context.js +37 -0
  18. package/dist/context.js.map +1 -0
  19. package/dist/index.d.ts +5 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +4 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/lib/pg-url.d.ts +11 -0
  24. package/dist/lib/pg-url.d.ts.map +1 -0
  25. package/dist/lib/pg-url.js +22 -0
  26. package/dist/lib/pg-url.js.map +1 -0
  27. package/dist/manifest/deps.d.ts +29 -0
  28. package/dist/manifest/deps.d.ts.map +1 -0
  29. package/dist/manifest/deps.js +97 -0
  30. package/dist/manifest/deps.js.map +1 -0
  31. package/dist/manifest/env.d.ts +18 -0
  32. package/dist/manifest/env.d.ts.map +1 -0
  33. package/dist/manifest/env.js +38 -0
  34. package/dist/manifest/env.js.map +1 -0
  35. package/dist/phases/db-init.d.ts +3 -0
  36. package/dist/phases/db-init.d.ts.map +1 -0
  37. package/dist/phases/db-init.js +163 -0
  38. package/dist/phases/db-init.js.map +1 -0
  39. package/dist/phases/db.d.ts +11 -0
  40. package/dist/phases/db.d.ts.map +1 -0
  41. package/dist/phases/db.js +93 -0
  42. package/dist/phases/db.js.map +1 -0
  43. package/dist/phases/deps.d.ts +3 -0
  44. package/dist/phases/deps.d.ts.map +1 -0
  45. package/dist/phases/deps.js +115 -0
  46. package/dist/phases/deps.js.map +1 -0
  47. package/dist/phases/env.d.ts +3 -0
  48. package/dist/phases/env.d.ts.map +1 -0
  49. package/dist/phases/env.js +172 -0
  50. package/dist/phases/env.js.map +1 -0
  51. package/dist/phases/host.d.ts +3 -0
  52. package/dist/phases/host.d.ts.map +1 -0
  53. package/dist/phases/host.js +99 -0
  54. package/dist/phases/host.js.map +1 -0
  55. package/dist/phases/index.d.ts +7 -0
  56. package/dist/phases/index.d.ts.map +1 -0
  57. package/dist/phases/index.js +40 -0
  58. package/dist/phases/index.js.map +1 -0
  59. package/dist/phases/preflight.d.ts +4 -0
  60. package/dist/phases/preflight.d.ts.map +1 -0
  61. package/dist/phases/preflight.js +81 -0
  62. package/dist/phases/preflight.js.map +1 -0
  63. package/dist/phases/routes.d.ts +3 -0
  64. package/dist/phases/routes.d.ts.map +1 -0
  65. package/dist/phases/routes.js +145 -0
  66. package/dist/phases/routes.js.map +1 -0
  67. package/dist/phases/scaffold.d.ts +3 -0
  68. package/dist/phases/scaffold.d.ts.map +1 -0
  69. package/dist/phases/scaffold.js +113 -0
  70. package/dist/phases/scaffold.js.map +1 -0
  71. package/dist/phases/stub.d.ts +3 -0
  72. package/dist/phases/stub.d.ts.map +1 -0
  73. package/dist/phases/stub.js +25 -0
  74. package/dist/phases/stub.js.map +1 -0
  75. package/dist/phases/ui.d.ts +3 -0
  76. package/dist/phases/ui.d.ts.map +1 -0
  77. package/dist/phases/ui.js +93 -0
  78. package/dist/phases/ui.js.map +1 -0
  79. package/dist/phases/wire/index.d.ts +3 -0
  80. package/dist/phases/wire/index.d.ts.map +1 -0
  81. package/dist/phases/wire/index.js +67 -0
  82. package/dist/phases/wire/index.js.map +1 -0
  83. package/dist/phases/wire/root-tsx.d.ts +3 -0
  84. package/dist/phases/wire/root-tsx.d.ts.map +1 -0
  85. package/dist/phases/wire/root-tsx.js +57 -0
  86. package/dist/phases/wire/root-tsx.js.map +1 -0
  87. package/dist/phases/wire/server-ts.d.ts +3 -0
  88. package/dist/phases/wire/server-ts.d.ts.map +1 -0
  89. package/dist/phases/wire/server-ts.js +54 -0
  90. package/dist/phases/wire/server-ts.js.map +1 -0
  91. package/dist/phases/wire/shared.d.ts +34 -0
  92. package/dist/phases/wire/shared.d.ts.map +1 -0
  93. package/dist/phases/wire/shared.js +2 -0
  94. package/dist/phases/wire/shared.js.map +1 -0
  95. package/dist/phases/wire/start-ts.d.ts +3 -0
  96. package/dist/phases/wire/start-ts.d.ts.map +1 -0
  97. package/dist/phases/wire/start-ts.js +149 -0
  98. package/dist/phases/wire/start-ts.js.map +1 -0
  99. package/dist/phases/wire/tsconfig.d.ts +3 -0
  100. package/dist/phases/wire/tsconfig.d.ts.map +1 -0
  101. package/dist/phases/wire/tsconfig.js +105 -0
  102. package/dist/phases/wire/tsconfig.js.map +1 -0
  103. package/dist/phases/wire/vite-config.d.ts +3 -0
  104. package/dist/phases/wire/vite-config.d.ts.map +1 -0
  105. package/dist/phases/wire/vite-config.js +46 -0
  106. package/dist/phases/wire/vite-config.js.map +1 -0
  107. package/dist/prompts.d.ts +34 -0
  108. package/dist/prompts.d.ts.map +1 -0
  109. package/dist/prompts.js +49 -0
  110. package/dist/prompts.js.map +1 -0
  111. package/dist/runner.d.ts +5 -0
  112. package/dist/runner.d.ts.map +1 -0
  113. package/dist/runner.js +91 -0
  114. package/dist/runner.js.map +1 -0
  115. package/dist/state.d.ts +18 -0
  116. package/dist/state.d.ts.map +1 -0
  117. package/dist/state.js +68 -0
  118. package/dist/state.js.map +1 -0
  119. package/dist/templates/byline/admin.config.ts +41 -0
  120. package/dist/templates/byline/i18n.ts +47 -0
  121. package/dist/templates/byline/routes.ts +28 -0
  122. package/dist/templates/byline/seed.ts +19 -0
  123. package/dist/templates/byline/seeds/admin.ts +62 -0
  124. package/dist/templates/byline/server.config.ts +92 -0
  125. package/dist/templates/byline-examples/admin.config.ts +74 -0
  126. package/dist/templates/byline-examples/blocks/photo-block.ts +59 -0
  127. package/dist/templates/byline-examples/blocks/richtext-block.ts +35 -0
  128. package/dist/templates/byline-examples/collections/doc-example-flat-locale-all.ts +373 -0
  129. package/dist/templates/byline-examples/collections/doc-example-flat-locale-en.ts +283 -0
  130. package/dist/templates/byline-examples/collections/doc-example-tree-locale-all.ts +278 -0
  131. package/dist/templates/byline-examples/collections/doc-example-tree-locale-en.ts +205 -0
  132. package/dist/templates/byline-examples/collections/docs/admin.tsx +204 -0
  133. package/dist/templates/byline-examples/collections/docs/components/.gitkeep +0 -0
  134. package/dist/templates/byline-examples/collections/docs/components/feature-formatter.tsx +10 -0
  135. package/dist/templates/byline-examples/collections/docs/hooks/.gitkeep +0 -0
  136. package/dist/templates/byline-examples/collections/docs/index.ts +10 -0
  137. package/dist/templates/byline-examples/collections/docs/schema.ts +209 -0
  138. package/dist/templates/byline-examples/collections/docs-categories/admin.tsx +78 -0
  139. package/dist/templates/byline-examples/collections/docs-categories/components/.gitkeep +0 -0
  140. package/dist/templates/byline-examples/collections/docs-categories/hooks/.gitkeep +0 -0
  141. package/dist/templates/byline-examples/collections/docs-categories/index.ts +10 -0
  142. package/dist/templates/byline-examples/collections/docs-categories/schema.ts +33 -0
  143. package/dist/templates/byline-examples/collections/media/admin.tsx +188 -0
  144. package/dist/templates/byline-examples/collections/media/components/media-list-view.tsx +330 -0
  145. package/dist/templates/byline-examples/collections/media/components/media-thumbnail.tsx +63 -0
  146. package/dist/templates/byline-examples/collections/media/hooks/.gitkeep +0 -0
  147. package/dist/templates/byline-examples/collections/media/index.ts +10 -0
  148. package/dist/templates/byline-examples/collections/media/schema.ts +157 -0
  149. package/dist/templates/byline-examples/collections/news/admin.tsx +192 -0
  150. package/dist/templates/byline-examples/collections/news/components/.gitkeep +0 -0
  151. package/dist/templates/byline-examples/collections/news/hooks/.gitkeep +0 -0
  152. package/dist/templates/byline-examples/collections/news/index.ts +10 -0
  153. package/dist/templates/byline-examples/collections/news/schema.ts +91 -0
  154. package/dist/templates/byline-examples/collections/news-categories/admin.tsx +78 -0
  155. package/dist/templates/byline-examples/collections/news-categories/components/.gitkeep +0 -0
  156. package/dist/templates/byline-examples/collections/news-categories/hooks/.gitkeep +0 -0
  157. package/dist/templates/byline-examples/collections/news-categories/index.ts +10 -0
  158. package/dist/templates/byline-examples/collections/news-categories/schema.ts +33 -0
  159. package/dist/templates/byline-examples/collections/pages/admin.tsx +183 -0
  160. package/dist/templates/byline-examples/collections/pages/components/.gitkeep +0 -0
  161. package/dist/templates/byline-examples/collections/pages/hooks/.gitkeep +0 -0
  162. package/dist/templates/byline-examples/collections/pages/index.ts +10 -0
  163. package/dist/templates/byline-examples/collections/pages/schema.ts +96 -0
  164. package/dist/templates/byline-examples/components/length-indicator.tsx +138 -0
  165. package/dist/templates/byline-examples/components/pill.tsx +38 -0
  166. package/dist/templates/byline-examples/components/summary-length.tsx +39 -0
  167. package/dist/templates/byline-examples/fields/available-languages-field.ts +90 -0
  168. package/dist/templates/byline-examples/fields/lexical-richtext-compact.ts +88 -0
  169. package/dist/templates/byline-examples/i18n.ts +47 -0
  170. package/dist/templates/byline-examples/routes.ts +28 -0
  171. package/dist/templates/byline-examples/scripts/regenerate-media.ts +275 -0
  172. package/dist/templates/byline-examples/seed.ts +25 -0
  173. package/dist/templates/byline-examples/seeds/admin.ts +62 -0
  174. package/dist/templates/byline-examples/seeds/doc-categories.ts +71 -0
  175. package/dist/templates/byline-examples/seeds/docs.ts +293 -0
  176. package/dist/templates/byline-examples/seeds/news-categories.ts +71 -0
  177. package/dist/templates/byline-examples/server.config.ts +179 -0
  178. package/dist/templates/host/vite.config.ts +41 -0
  179. package/dist/templates/migrations/0000_condemned_kronos.sql +324 -0
  180. package/dist/templates/migrations/0001_sudden_phantom_reporter.sql +1 -0
  181. package/dist/templates/migrations/meta/0000_snapshot.json +2793 -0
  182. package/dist/templates/migrations/meta/0001_snapshot.json +2799 -0
  183. package/dist/templates/migrations/meta/_journal.json +20 -0
  184. package/dist/templates/routes/(byline)/admin/account/index.tsx +11 -0
  185. package/dist/templates/routes/(byline)/admin/collections/$collection/$id/api.tsx +16 -0
  186. package/dist/templates/routes/(byline)/admin/collections/$collection/$id/history.tsx +19 -0
  187. package/dist/templates/routes/(byline)/admin/collections/$collection/$id/index.tsx +16 -0
  188. package/dist/templates/routes/(byline)/admin/collections/$collection/create.tsx +11 -0
  189. package/dist/templates/routes/(byline)/admin/collections/$collection/index.tsx +11 -0
  190. package/dist/templates/routes/(byline)/admin/index.tsx +11 -0
  191. package/dist/templates/routes/(byline)/admin/permissions/index.tsx +11 -0
  192. package/dist/templates/routes/(byline)/admin/roles/$id/index.tsx +11 -0
  193. package/dist/templates/routes/(byline)/admin/roles/index.tsx +11 -0
  194. package/dist/templates/routes/(byline)/admin/route.tsx +11 -0
  195. package/dist/templates/routes/(byline)/admin/users/$id/index.tsx +11 -0
  196. package/dist/templates/routes/(byline)/admin/users/index.tsx +11 -0
  197. package/dist/templates/routes/(byline)/sign-in.tsx +11 -0
  198. package/dist/templates/ui-byline/blocks/photo-block/index.tsx +80 -0
  199. package/dist/templates/ui-byline/blocks/richtext-block/index.tsx +46 -0
  200. package/dist/templates/ui-byline/components/admonition/index.tsx +40 -0
  201. package/dist/templates/ui-byline/components/code/code-serializer.tsx +20 -0
  202. package/dist/templates/ui-byline/components/code/code.tsx +50 -0
  203. package/dist/templates/ui-byline/components/code/index.module.scss +137 -0
  204. package/dist/templates/ui-byline/components/code/index.ts +2 -0
  205. package/dist/templates/ui-byline/components/code/types.ts +5 -0
  206. package/dist/templates/ui-byline/components/code/utils.ts +20 -0
  207. package/dist/templates/ui-byline/components/heading-anchor/heading-anchor.tsx +69 -0
  208. package/dist/templates/ui-byline/components/heading-anchor/index.ts +1 -0
  209. package/dist/templates/ui-byline/components/heading-anchor/utils.ts +15 -0
  210. package/dist/templates/ui-byline/components/inline-image/index.tsx +109 -0
  211. package/dist/templates/ui-byline/components/layout/index.tsx +63 -0
  212. package/dist/templates/ui-byline/components/link/lang-link.tsx +70 -0
  213. package/dist/templates/ui-byline/components/link/link-field.tsx +298 -0
  214. package/dist/templates/ui-byline/components/link/link-lexical.tsx +191 -0
  215. package/dist/templates/ui-byline/components/list/index.ts +2 -0
  216. package/dist/templates/ui-byline/components/list/list-item.tsx +32 -0
  217. package/dist/templates/ui-byline/components/list/list.tsx +17 -0
  218. package/dist/templates/ui-byline/components/responsive-image/index.tsx +205 -0
  219. package/dist/templates/ui-byline/components/richtext-lexical/index.tsx +31 -0
  220. package/dist/templates/ui-byline/components/richtext-lexical/serialize/index.tsx +249 -0
  221. package/dist/templates/ui-byline/components/richtext-lexical/serialize/richtext-node-formats.ts +66 -0
  222. package/dist/templates/ui-byline/components/richtext-lexical/serialize/types.ts +48 -0
  223. package/dist/templates/ui-byline/components/richtext-lexical/serialize/utils.ts +15 -0
  224. package/dist/templates/ui-byline/components/table-cell/index.tsx +36 -0
  225. package/dist/templates/ui-byline/components/vimeo/index.tsx +21 -0
  226. package/dist/templates/ui-byline/components/youtube/index.tsx +22 -0
  227. package/dist/templates/ui-byline/render-blocks.tsx +71 -0
  228. package/dist/templates/ui-byline/types/i18n.ts +14 -0
  229. package/dist/templates/ui-byline/utils/image-sources.ts +102 -0
  230. package/dist/templates/ui-byline/utils/to-kebab-case.ts +5 -0
  231. package/dist/types.d.ts +54 -0
  232. package/dist/types.d.ts.map +1 -0
  233. package/dist/types.js +2 -0
  234. package/dist/types.js.map +1 -0
  235. package/dist/ui/diff.d.ts +4 -0
  236. package/dist/ui/diff.d.ts.map +1 -0
  237. package/dist/ui/diff.js +23 -0
  238. package/dist/ui/diff.js.map +1 -0
  239. package/dist/ui/grid.d.ts +7 -0
  240. package/dist/ui/grid.d.ts.map +1 -0
  241. package/dist/ui/grid.js +24 -0
  242. package/dist/ui/grid.js.map +1 -0
  243. package/dist/ui/logger.d.ts +14 -0
  244. package/dist/ui/logger.d.ts.map +1 -0
  245. package/dist/ui/logger.js +30 -0
  246. package/dist/ui/logger.js.map +1 -0
  247. package/dist/ui/snippet.d.ts +2 -0
  248. package/dist/ui/snippet.d.ts.map +1 -0
  249. package/dist/ui/snippet.js +7 -0
  250. package/dist/ui/snippet.js.map +1 -0
  251. package/package.json +69 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import { type CollectionAdminConfig, type ColumnDefinition, defineAdmin } from '@byline/core'
10
+ import { DateTimeFormatter } from '@byline/ui/react/fields'
11
+
12
+ import { SummaryLength } from '~/components/summary-length.js'
13
+
14
+ import { News } from './schema.js'
15
+
16
+ /**
17
+ * Column definitions for the default table-based list view.
18
+ *
19
+ * These are passed to the built-in `ListView` component and control which
20
+ * fields appear as columns, their labels, sort behaviour, and formatters.
21
+ *
22
+ * Note: when a custom `listView` component is registered on the
23
+ * `CollectionAdminConfig`, it receives the raw paginated data directly and
24
+ * is responsible for its own layout. These column definitions can still
25
+ * be used in a custom list view, but they are not automatically applied
26
+ * as they are with the default table-based `ListView`. You can import
27
+ * them if needed - for example if you wanted to create a toggled grid/table
28
+ * custom view.
29
+ */
30
+ const listViewColumns: ColumnDefinition[] = [
31
+ {
32
+ fieldName: 'title',
33
+ label: 'Title',
34
+ sortable: true,
35
+ align: 'left',
36
+ className: 'w-[25%]',
37
+ },
38
+ {
39
+ fieldName: 'status',
40
+ label: 'Status',
41
+ align: 'center',
42
+ className: 'w-[15%]',
43
+ },
44
+ {
45
+ fieldName: 'updatedAt',
46
+ label: 'Last Updated',
47
+ sortable: true,
48
+ align: 'right',
49
+ className: 'w-[20%]',
50
+ formatter: { component: DateTimeFormatter },
51
+ },
52
+ ]
53
+
54
+ /**
55
+ * Columns rendered per row when a collection item appears as the
56
+ * target of a relation picker. Usually narrower than the list
57
+ * view — just enough to identify the right item at a glance.
58
+ */
59
+ // const pickerViewColumns: ColumnDefinition[] = []
60
+
61
+ export const NewsAdmin: CollectionAdminConfig = defineAdmin(News, {
62
+ /**
63
+ * Column definitions for the default table-based list view.
64
+ * Controls which fields appear as columns, their labels, sort behaviour, and formatters.
65
+ */
66
+ columns: listViewColumns,
67
+
68
+ /**
69
+ * Column definitions used when this collection appears as the target of a relation
70
+ * picker modal (opened from a `relation` field widget). Omit to fall back to a
71
+ * single-line render of `useAsTitle` + `path`.
72
+ *
73
+ * Shape matches `ColumnDefinition` so formatters can be reused across list and picker.
74
+ *
75
+ * @example
76
+ * picker: [{ fieldName: 'title', label: 'Title' }] // or defined above as `pickerViewColumns`
77
+ */
78
+ // picker: [],
79
+
80
+ /**
81
+ * Custom list-view component that completely replaces the default table-based `ListView`
82
+ * on the collection index route. Receives a `ListViewComponentProps` object and is
83
+ * responsible for rendering search, ordering, results, and pagination itself.
84
+ *
85
+ * When omitted, the default table-based `ListView` is used with the `columns` defined above.
86
+ *
87
+ * @example
88
+ * listView: MediaListView,
89
+ */
90
+ // listView: undefined,
91
+
92
+ /**
93
+ * Group name for organising this collection in the admin sidebar navigation.
94
+ *
95
+ * @example
96
+ * group: 'Editorial',
97
+ */
98
+ // group: undefined,
99
+
100
+ /**
101
+ * Per-field rendering overrides, keyed by field name. Use to supply custom
102
+ * UI component slots for a specific field without affecting placement.
103
+ * Placement is controlled exclusively through the layout primitives below.
104
+ */
105
+ fields: {
106
+ summary: {
107
+ components: {
108
+ HelpText: SummaryLength,
109
+ },
110
+ },
111
+ },
112
+
113
+ /**
114
+ * Preview URL builder for live preview links. Receives the document and an
115
+ * optional locale and should return a fully-qualified URL string.
116
+ *
117
+ * @example
118
+ * preview: (doc, { locale }) => `https://example.com/${locale}/news/${doc.fields.path}`
119
+ */
120
+ // preview: undefined,
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // UI Layout
124
+ //
125
+ // Tab, row, and group containers control how fields are grouped and positioned
126
+ // in the document edit view. Field names must match those defined in the
127
+ // collection schema. Names for tabSets, rows, and groups must be unique and
128
+ // must not collide with any schema field name (a startup error is thrown if
129
+ // they do).
130
+ // ---------------------------------------------------------------------------
131
+
132
+ /**
133
+ * Named tab sets. Each entry creates a separate tabbed interface in the edit
134
+ * view. You can define more than one tab set, though a single set is sufficient
135
+ * for most collections. Tab sets may only appear in `layout.main`.
136
+ *
137
+ * Each tab's `fields` array accepts schema field names, row names, and group names.
138
+ * An optional `condition` function can show/hide a tab based on live form data.
139
+ */
140
+ tabSets: [
141
+ {
142
+ name: 'main',
143
+ tabs: [
144
+ {
145
+ name: 'details',
146
+ label: 'Details',
147
+ fields: ['title', 'summary', 'category', 'featureImage'],
148
+ },
149
+ {
150
+ name: 'content',
151
+ label: 'Content',
152
+ fields: ['content'],
153
+ },
154
+ ],
155
+ },
156
+ ],
157
+
158
+ /**
159
+ * Named horizontal-row layouts. Fields listed inside a row are rendered
160
+ * side-by-side (flex row) on desktop and stack vertically below the `sm`
161
+ * breakpoint. Rows are leaf containers — they accept only schema field names.
162
+ *
163
+ * Reference a row by its `name` inside a tab's `fields`, a group's `fields`,
164
+ * or directly in `layout.main` / `layout.sidebar`.
165
+ */
166
+ // rows: [{ name: 'titles', fields: ['text1', 'text2'] }],
167
+ rows: [],
168
+
169
+ /**
170
+ * Named labelled-fieldset clusters. Groups accept schema field names and row
171
+ * names (not tabSets or nested groups). An optional `label` renders a heading
172
+ * above the cluster.
173
+ *
174
+ * Reference a group by its `name` inside a tab's `fields` or directly in
175
+ * `layout.main` / `layout.sidebar`.
176
+ */
177
+ groups: [],
178
+
179
+ /**
180
+ * Composition of all layout primitives into the form's two render regions.
181
+ *
182
+ * - `main` — accepts tabSet names, group names, row names, and schema field names.
183
+ * - `sidebar` — accepts group names, row names, and schema field names (no tabSets).
184
+ *
185
+ * When omitted entirely, the renderer synthesises a default that places every
186
+ * schema field in `main` in declaration order.
187
+ */
188
+ layout: {
189
+ main: ['main'],
190
+ sidebar: ['availableLanguages', 'publishedOn'],
191
+ },
192
+ })
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ export { NewsAdmin } from './admin.js'
10
+ export { News } from './schema.js'
@@ -0,0 +1,91 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import type { CollectionFieldData } from '@byline/core'
10
+ import { defineCollection, defineWorkflow } from '@byline/core'
11
+
12
+ import { availableLanguagesField } from '~/fields/available-languages-field.js'
13
+
14
+ // ---- Schema (server-safe, no UI concerns) ----
15
+
16
+ export const News = defineCollection({
17
+ path: 'news',
18
+ labels: {
19
+ singular: 'News',
20
+ plural: 'News',
21
+ },
22
+ // Workflow: defineWorkflow() guarantees draft, published, and archived are
23
+ // always present and correctly ordered. No custom statuses here — the
24
+ // standard three-step lifecycle is used.
25
+ //
26
+ // Resulting order: [draft, published, archived]
27
+ workflow: defineWorkflow({
28
+ draft: { label: 'Draft', verb: 'Revert to Draft' },
29
+ published: { label: 'Published', verb: 'Publish' },
30
+ archived: { label: 'Archived', verb: 'Archive' },
31
+ }),
32
+ showStats: true,
33
+ search: { fields: ['title'] },
34
+ useAsTitle: 'title',
35
+ useAsPath: 'title',
36
+ linksInEditor: true, // See type definition for details.
37
+ fields: [
38
+ { name: 'title', label: 'Title', type: 'text', localized: true },
39
+ {
40
+ name: 'summary',
41
+ label: 'Summary',
42
+ type: 'textArea',
43
+ localized: true,
44
+ helpText:
45
+ 'Enter a short summary. The first 150 characters are used for social media meta descriptions. Aim for 100–300 characters.',
46
+ },
47
+ {
48
+ name: 'category',
49
+ label: 'Category',
50
+ type: 'relation',
51
+ targetCollection: 'news-categories',
52
+ displayField: 'name',
53
+ },
54
+ // Relation field demo. Points at the Media upload collection
55
+ // so editors can choose a feature image via the relation picker widget.
56
+ // Set `displayField: 'title'` so the picker's row label reads from the
57
+ // uploaded item's `title` field rather than falling back to its path.
58
+ // Will display the picker defined columns if present in the admin.tsx
59
+ // configuration.
60
+ {
61
+ name: 'featureImage',
62
+ label: 'Feature Image',
63
+ type: 'relation',
64
+ targetCollection: 'media',
65
+ displayField: 'title',
66
+ optional: true,
67
+ },
68
+ {
69
+ name: 'content',
70
+ label: 'Content',
71
+ type: 'richText',
72
+ helpText: 'Enter the main content for this page.',
73
+ localized: true,
74
+ embedRelationsOnSave: true, // See type definition for details.
75
+ },
76
+ {
77
+ name: 'publishedOn',
78
+ label: 'Published On',
79
+ type: 'datetime',
80
+ mode: 'datetime',
81
+ },
82
+ availableLanguagesField(),
83
+ ],
84
+ })
85
+
86
+ /**
87
+ * Field data shape inferred directly from the schema. Use this as the
88
+ * generic to typed read calls — `client.collection('news').find<NewsFields>()`
89
+ * — so dot-notation on `doc.fields` is fully checked.
90
+ */
91
+ export type NewsFields = CollectionFieldData<typeof News>
@@ -0,0 +1,78 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import { type CollectionAdminConfig, type ColumnDefinition, defineAdmin } from '@byline/core'
10
+ import { DateTimeFormatter } from '@byline/ui/react/fields'
11
+
12
+ import { NewsCategories } from './schema.js'
13
+
14
+ // ---- Admin UI config (client-only, presentation concerns) ----
15
+
16
+ /**
17
+ * Column definitions for the default table-based list view.
18
+ *
19
+ * These are passed to the built-in `ListView` component and control which
20
+ * fields appear as columns, their labels, sort behaviour, and formatters.
21
+ *
22
+ * Note: when a custom `listView` component is registered on the
23
+ * `CollectionAdminConfig`, it receives the raw paginated data directly and
24
+ * is responsible for its own layout. These column definitions can still
25
+ * be used in a custom list view, but they are not automatically applied
26
+ * as they are with the default table-based `ListView`. You can import
27
+ * them if needed - for example if you wanted to create a toggled grid/table
28
+ * custom view.
29
+ */
30
+
31
+ const listViewColumns: ColumnDefinition[] = [
32
+ {
33
+ fieldName: 'name',
34
+ label: 'Name',
35
+ sortable: true,
36
+ align: 'left',
37
+ className: 'w-[25%]',
38
+ },
39
+ {
40
+ fieldName: 'status',
41
+ label: 'Status',
42
+ align: 'center',
43
+ className: 'w-[15%]',
44
+ },
45
+ {
46
+ fieldName: 'updatedAt',
47
+ label: 'Last Updated',
48
+ sortable: true,
49
+ align: 'right',
50
+ className: 'w-[20%]',
51
+ formatter: { component: DateTimeFormatter },
52
+ },
53
+ ]
54
+
55
+ /**
56
+ * Columns rendered per row when Media appears as the target of a relation
57
+ * picker (e.g. News → `heroImage` → Media). Narrower than the list view —
58
+ * just enough to identify the right media item at a glance.
59
+ */
60
+ const pickerViewColumns: ColumnDefinition[] = [
61
+ {
62
+ fieldName: 'name',
63
+ label: 'Name',
64
+ align: 'left',
65
+ className: 'flex-1',
66
+ },
67
+ {
68
+ fieldName: 'status',
69
+ label: 'Status',
70
+ align: 'right',
71
+ className: 'w-[80px] shrink-0 text-xs text-gray-500',
72
+ },
73
+ ]
74
+
75
+ export const NewsCategoriesAdmin: CollectionAdminConfig = defineAdmin(NewsCategories, {
76
+ columns: listViewColumns,
77
+ picker: pickerViewColumns,
78
+ })
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ export { NewsCategoriesAdmin } from './admin.js'
10
+ export { NewsCategories } from './schema.js'
@@ -0,0 +1,33 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import type { CollectionFieldData } from '@byline/core'
10
+ import { defineCollection, SINGLE_STATUS_WORKFLOW } from '@byline/core'
11
+
12
+ // ---- Schema (server-safe, no UI concerns) ----
13
+
14
+ export const NewsCategories = defineCollection({
15
+ path: 'news-categories',
16
+ labels: {
17
+ singular: 'News Category',
18
+ plural: 'News Categories',
19
+ },
20
+ // Lookup collection — no editorial lifecycle. Saves go straight to
21
+ // `published` and the form shows only Save / Close.
22
+ workflow: SINGLE_STATUS_WORKFLOW,
23
+ showStats: true,
24
+ search: { fields: ['name'] },
25
+ useAsTitle: 'name',
26
+ useAsPath: 'name',
27
+ fields: [
28
+ { name: 'name', label: 'Name', type: 'text', localized: true },
29
+ { name: 'description', label: 'Description', type: 'textArea', localized: true },
30
+ ],
31
+ })
32
+
33
+ export type NewsCategoryFields = CollectionFieldData<typeof NewsCategories>
@@ -0,0 +1,183 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import { type CollectionAdminConfig, type ColumnDefinition, defineAdmin } from '@byline/core'
10
+ import { DateTimeFormatter } from '@byline/ui/react/fields'
11
+
12
+ import { SummaryLength } from '~/components/summary-length.js'
13
+
14
+ import { Pages } from './schema.js'
15
+
16
+ /**
17
+ * Column definitions for the default table-based list view.
18
+ *
19
+ * These are passed to the built-in `ListView` component and control which
20
+ * fields appear as columns, their labels, sort behaviour, and formatters.
21
+ *
22
+ * Note: when a custom `listView` component is registered on the
23
+ * `CollectionAdminConfig`, it receives the raw paginated data directly and
24
+ * is responsible for its own layout. These column definitions can still
25
+ * be used in a custom list view, but they are not automatically applied
26
+ * as they are with the default table-based `ListView`. You can import
27
+ * them if needed - for example if you wanted to create a toggled grid/table
28
+ * custom view.
29
+ */
30
+
31
+ const listViewColumns: ColumnDefinition[] = [
32
+ {
33
+ fieldName: 'title',
34
+ label: 'Title',
35
+ sortable: true,
36
+ align: 'left',
37
+ className: 'w-[30%]',
38
+ },
39
+ {
40
+ fieldName: 'featured',
41
+ label: 'Featured',
42
+ align: 'center',
43
+ className: 'w-[10%]',
44
+ formatter: (value) => (value ? '★' : ''),
45
+ },
46
+ {
47
+ fieldName: 'status',
48
+ label: 'Status',
49
+ align: 'center',
50
+ className: 'w-[15%]',
51
+ },
52
+ {
53
+ fieldName: 'updatedAt',
54
+ label: 'Last Updated',
55
+ sortable: true,
56
+ align: 'right',
57
+ className: 'w-[20%]',
58
+ formatter: { component: DateTimeFormatter },
59
+ },
60
+ ]
61
+
62
+ /**
63
+ * Columns rendered per row when a collection item appears as the
64
+ * target of a relation picker. Usually narrower than the list
65
+ * view — just enough to identify the right item at a glance.
66
+ */
67
+ // const pickerViewColumns: ColumnDefinition[] = []
68
+
69
+ export const PagesAdmin: CollectionAdminConfig = defineAdmin(Pages, {
70
+ /**
71
+ * Column definitions for the default table-based list view.
72
+ * Controls which fields appear as columns, their labels, sort behaviour, and formatters.
73
+ */
74
+ columns: listViewColumns,
75
+
76
+ /**
77
+ * Column definitions used when this collection appears as the target of a relation
78
+ * picker modal (opened from a `relation` field widget). Omit to fall back to a
79
+ * single-line render of `useAsTitle` + `path`.
80
+ *
81
+ * Shape matches `ColumnDefinition` so formatters can be reused across list and picker.
82
+ *
83
+ * @example
84
+ * picker: [{ fieldName: 'title', label: 'Title' }] // or defined above as `pickerViewColumns`
85
+ */
86
+ // picker: [],
87
+
88
+ /**
89
+ * Custom list-view component that completely replaces the default table-based `ListView`
90
+ * on the collection index route. Receives a `ListViewComponentProps` object and is
91
+ * responsible for rendering search, ordering, results, and pagination itself.
92
+ *
93
+ * When omitted, the default table-based `ListView` is used with the `columns` defined above.
94
+ *
95
+ * @example
96
+ * listView: MediaListView,
97
+ */
98
+ // listView: undefined,
99
+
100
+ /**
101
+ * Group name for organising this collection in the admin sidebar navigation.
102
+ *
103
+ * @example
104
+ * group: 'Editorial',
105
+ */
106
+ // group: undefined,
107
+
108
+ /**
109
+ * Per-field rendering overrides, keyed by field name. Use to supply custom
110
+ * UI component slots for a specific field without affecting placement.
111
+ * Placement is controlled exclusively through the layout primitives below.
112
+ */
113
+ fields: {
114
+ summary: {
115
+ components: {
116
+ HelpText: SummaryLength,
117
+ },
118
+ },
119
+ },
120
+
121
+ /**
122
+ * Preview URL builder for live preview links. Receives the document and an
123
+ * optional locale and should return a fully-qualified URL string.
124
+ *
125
+ * @example
126
+ * preview: (doc, { locale }) => `https://example.com/${locale}/pages/${doc.fields.path}`
127
+ */
128
+ // preview: undefined,
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // UI Layout
132
+ //
133
+ // Tab, row, and group containers control how fields are grouped and positioned
134
+ // in the document edit view. Field names must match those defined in the
135
+ // collection schema. Names for tabSets, rows, and groups must be unique and
136
+ // must not collide with any schema field name (a startup error is thrown if
137
+ // they do).
138
+ // ---------------------------------------------------------------------------
139
+
140
+ /**
141
+ * Named tab sets. Each entry creates a separate tabbed interface in the edit
142
+ * view. You can define more than one tab set, though a single set is sufficient
143
+ * for most collections. Tab sets may only appear in `layout.main`.
144
+ *
145
+ * Each tab's `fields` array accepts schema field names, row names, and group names.
146
+ * An optional `condition` function can show/hide a tab based on live form data.
147
+ */
148
+ // tabSets: [],
149
+
150
+ /**
151
+ * Named horizontal-row layouts. Fields listed inside a row are rendered
152
+ * side-by-side (flex row) on desktop and stack vertically below the `sm`
153
+ * breakpoint. Rows are leaf containers — they accept only schema field names.
154
+ *
155
+ * Reference a row by its `name` inside a tab's `fields`, a group's `fields`,
156
+ * or directly in `layout.main` / `layout.sidebar`.
157
+ */
158
+ // rows: [],
159
+
160
+ /**
161
+ * Named labelled-fieldset clusters. Groups accept schema field names and row
162
+ * names (not tabSets or nested groups). An optional `label` renders a heading
163
+ * above the cluster.
164
+ *
165
+ * Reference a group by its `name` inside a tab's `fields` or directly in
166
+ * `layout.main` / `layout.sidebar`.
167
+ */
168
+ // groups: [],
169
+
170
+ /**
171
+ * Composition of all layout primitives into the form's two render regions.
172
+ *
173
+ * - `main` — accepts tabSet names, group names, row names, and schema field names.
174
+ * - `sidebar` — accepts group names, row names, and schema field names (no tabSets).
175
+ *
176
+ * When omitted entirely, the renderer synthesises a default that places every
177
+ * schema field in `main` in declaration order.
178
+ */
179
+ layout: {
180
+ main: ['title', 'summary', 'featureImage', 'category', 'content'],
181
+ sidebar: ['publishedOn', 'featured', 'availableLanguages'],
182
+ },
183
+ })
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ export { PagesAdmin } from './admin.js'
10
+ export { Pages } from './schema.js'