@nixxie-cms/core 1.0.0 → 1.0.2

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 (187) hide show
  1. package/README.md +2 -2
  2. package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.cjs.js +4 -4
  3. package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.esm.js +4 -4
  4. package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.cjs.js +2 -2
  5. package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.esm.js +2 -2
  6. package/context/dist/nixxie-cms-core-context.cjs.js +2 -2
  7. package/context/dist/nixxie-cms-core-context.esm.js +2 -2
  8. package/dist/{CreateItemDialog-33335548.esm.js → CreateItemDialog-7008b050.esm.js} +1 -1
  9. package/dist/{CreateItemDialog-56cf59b7.cjs.js → CreateItemDialog-a0cab315.cjs.js} +1 -1
  10. package/dist/{PageContainer-7db73317.esm.js → PageContainer-5ae731cc.esm.js} +25 -18
  11. package/dist/{PageContainer-27c27f10.cjs.js → PageContainer-abd7159f.cjs.js} +25 -18
  12. package/dist/{admin-meta-graphql-6f7f5331.esm.js → admin-meta-graphql-0e6e606e.esm.js} +1 -1
  13. package/dist/{admin-meta-graphql-c8f926e9.cjs.js → admin-meta-graphql-306c224a.cjs.js} +1 -1
  14. package/dist/{context-3132c3ed.esm.js → context-af9957ed.esm.js} +2 -2
  15. package/dist/{context-e7a45152.cjs.js → context-b5204629.cjs.js} +2 -2
  16. package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
  17. package/dist/declarations/src/admin-ui/components/PageContainer.d.ts.map +1 -1
  18. package/dist/declarations/src/helpers.d.ts.map +1 -1
  19. package/dist/declarations/src/index.d.ts +1 -0
  20. package/dist/declarations/src/index.d.ts.map +1 -1
  21. package/dist/declarations/src/internal-unstable/admin-ui/id-field-view.d.ts.map +1 -0
  22. package/dist/declarations/src/internal-unstable/admin-ui/pages/App/index.d.ts.map +1 -0
  23. package/dist/declarations/src/internal-unstable/admin-ui/pages/CreateItemPage/index.d.ts.map +1 -0
  24. package/dist/declarations/src/internal-unstable/admin-ui/pages/HomePage/index.d.ts.map +1 -0
  25. package/dist/declarations/src/internal-unstable/admin-ui/pages/ItemPage/index.d.ts.map +1 -0
  26. package/dist/declarations/src/internal-unstable/admin-ui/pages/ListPage/index.d.ts.map +1 -0
  27. package/dist/declarations/src/internal-unstable/admin-ui/pages/NoAccessPage/index.d.ts.map +1 -0
  28. package/dist/declarations/src/internal-unstable/artifacts.d.ts.map +1 -0
  29. package/dist/declarations/src/lib/core/initialise-lists.d.ts +1 -1
  30. package/dist/declarations/src/schema.d.ts.map +1 -1
  31. package/dist/declarations/src/types/config/index.d.ts +60 -1
  32. package/dist/declarations/src/types/config/index.d.ts.map +1 -1
  33. package/dist/declarations/src/types/config/lists.d.ts +4 -4
  34. package/dist/declarations/src/types/context.d.ts +150 -0
  35. package/dist/declarations/src/types/context.d.ts.map +1 -1
  36. package/dist/declarations/src/types/next-fields.d.ts +1 -1
  37. package/dist/{express-e9ed9a7d.cjs.js → express-455ae20c.cjs.js} +1 -1
  38. package/dist/{express-6743b918.esm.js → express-7559ca2d.esm.js} +1 -1
  39. package/dist/{index-ac01583b.cjs.js → index-89635494.cjs.js} +4 -4
  40. package/dist/{index-24b78415.esm.js → index-baa799e0.esm.js} +4 -4
  41. package/dist/nixxie-cms-core.cjs.js +104 -77
  42. package/dist/nixxie-cms-core.esm.js +104 -77
  43. package/dist/{non-null-graphql-5315718c.esm.js → non-null-graphql-a84ed64d.esm.js} +1 -1
  44. package/dist/{non-null-graphql-17b83ddc.cjs.js → non-null-graphql-add6bb3d.cjs.js} +1 -1
  45. package/dist/{resolve-hooks-66fe8a8e.cjs.js → resolve-hooks-165a9ce2.cjs.js} +1 -1
  46. package/dist/{resolve-hooks-17aafd37.esm.js → resolve-hooks-6813a045.esm.js} +2 -2
  47. package/dist/{system-dfec2f0a.esm.js → system-03e49e4f.esm.js} +8 -4
  48. package/dist/{system-48c5f6df.cjs.js → system-a321642d.cjs.js} +8 -4
  49. package/dist/{useFilter-0b5a1ee6.esm.js → useFilter-9b6db1f9.esm.js} +1 -1
  50. package/dist/{useFilter-1a4e6900.cjs.js → useFilter-acc9d413.cjs.js} +1 -1
  51. package/fields/dist/nixxie-cms-core-fields.cjs.js +16 -16
  52. package/fields/dist/nixxie-cms-core-fields.esm.js +17 -17
  53. package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.cjs.js +3 -3
  54. package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.esm.js +3 -3
  55. package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.cjs.js +1 -1
  56. package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.esm.js +1 -1
  57. package/fields/types/password/dist/nixxie-cms-core-fields-types-password.cjs.js +3 -3
  58. package/fields/types/password/dist/nixxie-cms-core-fields-types-password.esm.js +3 -3
  59. package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.cjs.js +4 -4
  60. package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.esm.js +4 -4
  61. package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.cjs.js +1 -1
  62. package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.esm.js +1 -1
  63. package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.cjs.js +1 -1
  64. package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.esm.js +1 -1
  65. package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.d.ts +2 -0
  66. package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.js +244 -0
  67. package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.esm.js +235 -0
  68. package/internal-unstable/admin-ui/id-field-view/package.json +4 -0
  69. package/internal-unstable/admin-ui/next-config/package.json +4 -0
  70. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.d.ts +2 -0
  71. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.js +59 -0
  72. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.esm.js +55 -0
  73. package/internal-unstable/admin-ui/pages/App/package.json +4 -0
  74. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.d.ts +2 -0
  75. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.js +116 -0
  76. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.esm.js +112 -0
  77. package/internal-unstable/admin-ui/pages/CreateItemPage/package.json +4 -0
  78. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.d.ts +2 -0
  79. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.js +336 -0
  80. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.esm.js +332 -0
  81. package/internal-unstable/admin-ui/pages/HomePage/package.json +4 -0
  82. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.d.ts +2 -0
  83. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.js +463 -0
  84. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.esm.js +455 -0
  85. package/internal-unstable/admin-ui/pages/ItemPage/package.json +4 -0
  86. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.d.ts +2 -0
  87. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.js +1195 -0
  88. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.esm.js +1187 -0
  89. package/internal-unstable/admin-ui/pages/ListPage/package.json +4 -0
  90. package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.d.ts +2 -0
  91. package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.js +40 -0
  92. package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.esm.js +35 -0
  93. package/internal-unstable/admin-ui/pages/NoAccessPage/package.json +4 -0
  94. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.d.ts +2 -0
  95. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.js +51 -0
  96. package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.esm.js +38 -0
  97. package/internal-unstable/artifacts/package.json +4 -0
  98. package/package.json +44 -44
  99. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.cjs.js +44 -15
  100. package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +44 -15
  101. package/scripts/dist/nixxie-cms-core-scripts.cjs.js +3 -3
  102. package/scripts/dist/nixxie-cms-core-scripts.esm.js +3 -3
  103. package/src/admin-ui/admin-meta-graphql.ts +168 -168
  104. package/src/admin-ui/components/CommandPalette.tsx +433 -431
  105. package/src/admin-ui/components/Navigation.tsx +389 -385
  106. package/src/admin-ui/components/PageContainer.tsx +311 -310
  107. package/src/admin-ui/components/WelcomeDialog.tsx +1 -1
  108. package/src/admin-ui/context.tsx +338 -338
  109. package/src/admin-ui/templates/app.ts +60 -60
  110. package/src/admin-ui/templates/create-item.ts +5 -5
  111. package/src/admin-ui/templates/home.ts +2 -2
  112. package/src/admin-ui/templates/item.tsx +5 -5
  113. package/src/admin-ui/templates/list.tsx +5 -5
  114. package/src/admin-ui/templates/next-config.ts +29 -0
  115. package/src/admin-ui/templates/no-access.ts +7 -7
  116. package/src/fields/types/bigInt/index.ts +181 -181
  117. package/src/fields/types/bytes/index.ts +275 -275
  118. package/src/fields/types/calendarDay/index.ts +194 -194
  119. package/src/fields/types/checkbox/index.ts +76 -76
  120. package/src/fields/types/decimal/index.ts +182 -182
  121. package/src/fields/types/file/index.ts +168 -168
  122. package/src/fields/types/float/index.ts +133 -133
  123. package/src/fields/types/image/index.ts +244 -244
  124. package/src/fields/types/integer/index.ts +156 -156
  125. package/src/fields/types/json/index.ts +77 -77
  126. package/src/fields/types/multiselect/index.ts +212 -212
  127. package/src/fields/types/password/index.ts +241 -241
  128. package/src/fields/types/relationship/index.ts +381 -381
  129. package/src/fields/types/relationship/views/RelationshipTable.tsx +190 -190
  130. package/src/fields/types/select/index.ts +226 -226
  131. package/src/fields/types/text/index.ts +207 -207
  132. package/src/fields/types/timestamp/index.ts +116 -116
  133. package/src/fields/types/virtual/index.ts +108 -108
  134. package/src/helpers.ts +342 -316
  135. package/src/index.ts +4 -0
  136. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.tsx +167 -167
  137. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.tsx +22 -22
  138. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.tsx +71 -71
  139. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.tsx +333 -333
  140. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/common.tsx +358 -358
  141. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.tsx +483 -483
  142. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/FilterAdd.tsx +221 -221
  143. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/PaginationControls.tsx +170 -170
  144. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/Tag.tsx +72 -72
  145. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.tsx +1006 -1006
  146. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.tsx +24 -24
  147. package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.ts +5 -5
  148. package/src/lib/context/createContext.ts +165 -161
  149. package/src/lib/core/initialise-lists.ts +1097 -1097
  150. package/src/lib/id-field.ts +214 -214
  151. package/src/lib/telemetry.ts +342 -342
  152. package/src/schema.ts +237 -233
  153. package/src/scripts/telemetry.ts +1 -1
  154. package/src/types/config/index.ts +400 -333
  155. package/src/types/config/lists.ts +4 -4
  156. package/src/types/context.ts +700 -530
  157. package/src/types/next-fields.ts +499 -499
  158. package/src/types/telemetry.ts +51 -51
  159. package/tests/telemetry.test.ts +361 -361
  160. package/CHANGELOG.md +0 -3158
  161. package/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view/package.json +0 -4
  162. package/___internal-do-not-use-will-break-in-patch/admin-ui/next-config/package.json +0 -4
  163. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/package.json +0 -4
  164. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/package.json +0 -4
  165. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/package.json +0 -4
  166. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/package.json +0 -4
  167. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/package.json +0 -4
  168. package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/package.json +0 -4
  169. package/___internal-do-not-use-will-break-in-patch/artifacts/package.json +0 -4
  170. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.d.ts.map +0 -1
  171. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/index.d.ts.map +0 -1
  172. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/index.d.ts.map +0 -1
  173. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/index.d.ts.map +0 -1
  174. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.d.ts.map +0 -1
  175. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.d.ts.map +0 -1
  176. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/index.d.ts.map +0 -1
  177. package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/artifacts.d.ts.map +0 -1
  178. /package/dist/{common-1a350e11.cjs.js → common-5933f758.cjs.js} +0 -0
  179. /package/dist/{common-29fc82e6.esm.js → common-ea5c441a.esm.js} +0 -0
  180. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.d.ts +0 -0
  181. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.d.ts +0 -0
  182. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.d.ts +0 -0
  183. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.d.ts +0 -0
  184. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.d.ts +0 -0
  185. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.d.ts +0 -0
  186. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.d.ts +0 -0
  187. /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.d.ts +0 -0
@@ -1,338 +1,338 @@
1
- import UploadLink from 'apollo-upload-client/UploadHttpLink.mjs'
2
- import NextHead from 'next/head'
3
- import { type ReactNode, createContext, useContext, useEffect, useMemo } from 'react'
4
-
5
- import { ClientSideOnlyDocumentElement, KeystarProvider } from '@keystar/ui/core'
6
- import { injectGlobal, tokenSchema } from '@keystar/ui/style'
7
- import { Toaster } from '@keystar/ui/toast'
8
- import { useRouter } from '@nixxie-cms/core/admin-ui/router'
9
-
10
- import { snapValueToClosest } from '../___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/PaginationControls'
11
- import type {
12
- AdminConfig,
13
- BaseListTypeInfo,
14
- ConditionalFilter,
15
- ConditionalFilterCase,
16
- FieldViews,
17
- ListMeta,
18
- } from '../types'
19
- import { type AdminMetaQuery, adminMetaQuery } from './admin-meta-graphql'
20
- import {
21
- ApolloClient,
22
- ApolloProvider,
23
- type ErrorLike,
24
- InMemoryCache,
25
- gql,
26
- useQuery,
27
- } from './apollo'
28
- import { getConditionalFilterFieldKeys, isActionAvailable } from './utils/filters'
29
-
30
- type NixxieContextType = {
31
- adminConfig: AdminConfig | null
32
- apiPath: string | null
33
- error?: ErrorLike | null
34
- fieldViews: FieldViews
35
- lists: { [list: string]: ListMeta }
36
- }
37
-
38
- const NixxieContext = createContext<NixxieContextType>({
39
- adminConfig: null,
40
- apiPath: null,
41
- lists: {},
42
- fieldViews: {},
43
- })
44
-
45
- type NixxieProviderProps = {
46
- adminConfig: AdminConfig
47
- apiPath: string
48
- fieldViews: FieldViews
49
- children: ReactNode
50
- }
51
-
52
- const expectedExports = new Set(['Field', 'controller'])
53
-
54
- function InternalNixxieProvider({
55
- adminConfig,
56
- apiPath,
57
- fieldViews,
58
- children,
59
- }: NixxieProviderProps) {
60
- const { push: navigate } = useRouter()
61
- const keystarRouter = useMemo(() => ({ navigate }), [navigate])
62
- const { data, loading, error } = useQuery<AdminMetaQuery>(adminMetaQuery, {
63
- errorPolicy: 'all',
64
- })
65
- const listsData = data?.nixxie?.adminMeta?.lists
66
- const lists = useMemo(() => {
67
- if (!listsData) return
68
- if (error) return
69
-
70
- const lists: NixxieContextType['lists'] = {}
71
-
72
- for (const listData of listsData) {
73
- lists[listData.key] = {
74
- ...listData,
75
- pageSize: snapValueToClosest(listData.pageSize ?? 50),
76
- fields: {},
77
- groups: [],
78
- }
79
-
80
- for (const field of listData.fields) {
81
- for (const exportName of expectedExports) {
82
- if ((fieldViews[field.viewsIndex] as any)[exportName] === undefined) {
83
- throw new Error(
84
- `The view for the field at ${listData.key}.${field.key} is missing the ${exportName} export`
85
- )
86
- }
87
- }
88
-
89
- const views = { ...fieldViews[field.viewsIndex] }
90
- const customViews: Record<string, any> = {}
91
- if (field.customViewsIndex !== null) {
92
- const customViewsSource: FieldViews[number] & Record<string, any> =
93
- fieldViews[field.customViewsIndex]
94
- const allowedExportsOnCustomViews = new Set(views.allowedExportsOnCustomViews)
95
- for (const exportName in customViewsSource) {
96
- if (allowedExportsOnCustomViews.has(exportName)) {
97
- customViews[exportName] = customViewsSource[exportName]
98
- } else if (expectedExports.has(exportName)) {
99
- ;(views as any)[exportName] = customViewsSource[exportName]
100
- }
101
- }
102
- }
103
-
104
- lists[listData.key].fields[field.key] = {
105
- ...field,
106
- createView: {
107
- fieldMode: field.createView?.fieldMode ?? null,
108
- isRequired: field.createView?.isRequired ?? false,
109
- },
110
- itemView: {
111
- fieldMode: field.itemView?.fieldMode ?? null,
112
- fieldPosition: field.itemView?.fieldPosition ?? null,
113
- isRequired: field.itemView?.isRequired ?? false,
114
- },
115
- listView: {
116
- fieldMode: field.listView?.fieldMode ?? null,
117
- },
118
- views,
119
- controller: views.controller({
120
- listKey: listData.key,
121
- fieldKey: field.key,
122
- label: field.label,
123
- description: field.description,
124
- fieldMeta: field.fieldMeta,
125
- customViews,
126
- }),
127
- }
128
- }
129
-
130
- for (const group of listData.groups) {
131
- lists[listData.key].groups.push({
132
- label: group.label,
133
- description: group.description,
134
- fields: group.fields.map(field => lists[listData.key].fields[field.key]),
135
- })
136
- }
137
- }
138
-
139
- return lists
140
- }, [listsData, error, fieldViews])
141
-
142
- useEffect(() => {
143
- injectGlobal({
144
- body: {
145
- fontFamily:
146
- "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
147
- WebkitFontSmoothing: 'antialiased',
148
- MozOsxFontSmoothing: 'grayscale',
149
- },
150
- '*, ::before, ::after': {
151
- borderWidth: 0,
152
- borderStyle: 'solid',
153
- borderColor: tokenSchema.color.border.neutral,
154
- boxSizing: 'border-box',
155
- },
156
- // Force light background on all Keystar surface/canvas elements
157
- // when they appear inside the main content (not inside our dark sidebar)
158
- '[data-nixxie-content]': {
159
- colorScheme: 'light',
160
- },
161
- })
162
- }, [])
163
-
164
- // TODO
165
- if (loading) return null
166
- // if (!meta) return null
167
- return (
168
- <KeystarProvider router={keystarRouter} colorScheme="light">
169
- <ClientSideOnlyDocumentElement bodyBackground="canvas" />
170
- <NextHead>
171
- <meta key="viewport" name="viewport" content="width=device-width, initial-scale=1.0" />
172
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
173
- <link
174
- href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
175
- rel="stylesheet"
176
- />
177
- </NextHead>
178
-
179
- <NixxieContext.Provider
180
- value={{
181
- adminConfig,
182
- apiPath,
183
- fieldViews,
184
- lists: lists ?? {},
185
- error: error ?? null,
186
- }}
187
- >
188
- {children}
189
- </NixxieContext.Provider>
190
- <Toaster />
191
- </KeystarProvider>
192
- )
193
- }
194
-
195
- export function NixxieProvider(props: NixxieProviderProps) {
196
- const apolloClient = useMemo(
197
- () =>
198
- new ApolloClient({
199
- cache: new InMemoryCache(),
200
- link: new UploadLink({
201
- uri: props.apiPath,
202
- headers: { 'Apollo-Require-Preflight': 'true' },
203
- }),
204
- }),
205
- [props.apiPath]
206
- )
207
-
208
- return (
209
- <ApolloProvider client={apolloClient}>
210
- <InternalNixxieProvider {...props} />
211
- </ApolloProvider>
212
- )
213
- }
214
-
215
- export function useNixxie() {
216
- return useContext(NixxieContext)
217
- }
218
-
219
- export function useList(listKey: string) {
220
- const { lists } = useNixxie()
221
- const list = lists?.[listKey]
222
- if (!list) throw new Error(`Unknown list ${listKey}`)
223
- return list
224
- }
225
-
226
- export function useField(listKey: string, fieldKey: string) {
227
- const list = useList(listKey)
228
- const field = list.fields[fieldKey]
229
- if (!field) throw new Error(`Unknown field ${listKey}.${fieldKey}`)
230
- return field
231
- }
232
-
233
- // TODO useContext?
234
- export function useListItem(
235
- listKey: string,
236
- itemId: string | null
237
- ): useQuery.Result<
238
- {
239
- item: Record<string, unknown> | null
240
- nixxie: {
241
- adminMeta: {
242
- list: {
243
- fields: {
244
- key: string
245
- itemView: {
246
- fieldMode: ConditionalFilter<
247
- 'edit' | 'read' | 'hidden',
248
- 'read' | 'hidden',
249
- BaseListTypeInfo
250
- >
251
- fieldPosition: 'form' | 'sidebar'
252
- isRequired: ConditionalFilterCase<BaseListTypeInfo>
253
- } | null
254
- }[]
255
- actions: {
256
- key: string
257
- itemView: {
258
- actionMode: ConditionalFilter<
259
- 'enabled' | 'disabled' | 'hidden',
260
- 'disabled' | 'hidden',
261
- BaseListTypeInfo
262
- >
263
- } | null
264
- }[]
265
- } | null
266
- }
267
- }
268
- },
269
- { id: string | null; listKey: string }
270
- > {
271
- const list = useList(listKey)
272
- const query = useMemo(() => {
273
- const selectedFieldKeys = new Set<string>()
274
-
275
- for (const field of Object.values(list.fields)) {
276
- if (field.key === 'id') continue // always in the query
277
- if (field.itemView.fieldMode === 'hidden') continue
278
- selectedFieldKeys.add(field.key)
279
- }
280
-
281
- for (const action of list.actions) {
282
- if (!isActionAvailable(action, action.itemView)) continue
283
-
284
- for (const fieldKey of getConditionalFilterFieldKeys(action.itemView.actionMode)) {
285
- selectedFieldKeys.add(fieldKey)
286
- }
287
-
288
- for (const arg of action.graphql.arguments) {
289
- if (!arg.source) continue
290
- selectedFieldKeys.add(arg.source.itemField)
291
- }
292
- }
293
-
294
- const selectedFields = [...selectedFieldKeys]
295
- .map(fieldKey => list.fields[fieldKey])
296
- .filter(Boolean)
297
- .map(field => field.controller.graphqlSelection)
298
- .join('\n')
299
-
300
- return gql`
301
- query KsFetchItem ($listKey: String!, $id: ID!) {
302
- nixxie {
303
- adminMeta {
304
- list(key: $listKey, itemId: $id) {
305
- fields {
306
- key
307
- itemView {
308
- fieldMode
309
- fieldPosition
310
- isRequired
311
- }
312
- }
313
- actions {
314
- key
315
- itemView {
316
- actionMode
317
- }
318
- }
319
- }
320
- }
321
- }
322
- item: ${list.graphql.names.itemQueryName}(where: { id: $id }) {
323
- id
324
- ${selectedFields}
325
- }
326
- }
327
- `
328
- }, [list])
329
-
330
- return useQuery(query, {
331
- errorPolicy: 'all',
332
- skip: itemId === null,
333
- variables: {
334
- listKey,
335
- id: itemId,
336
- },
337
- })
338
- }
1
+ import UploadLink from 'apollo-upload-client/UploadHttpLink.mjs'
2
+ import NextHead from 'next/head'
3
+ import { type ReactNode, createContext, useContext, useEffect, useMemo } from 'react'
4
+
5
+ import { ClientSideOnlyDocumentElement, KeystarProvider } from '@keystar/ui/core'
6
+ import { injectGlobal, tokenSchema } from '@keystar/ui/style'
7
+ import { Toaster } from '@keystar/ui/toast'
8
+ import { useRouter } from '@nixxie-cms/core/admin-ui/router'
9
+
10
+ import { snapValueToClosest } from '../internal-unstable/admin-ui/pages/ListPage/PaginationControls'
11
+ import type {
12
+ AdminConfig,
13
+ BaseListTypeInfo,
14
+ ConditionalFilter,
15
+ ConditionalFilterCase,
16
+ FieldViews,
17
+ ListMeta,
18
+ } from '../types'
19
+ import { type AdminMetaQuery, adminMetaQuery } from './admin-meta-graphql'
20
+ import {
21
+ ApolloClient,
22
+ ApolloProvider,
23
+ type ErrorLike,
24
+ InMemoryCache,
25
+ gql,
26
+ useQuery,
27
+ } from './apollo'
28
+ import { getConditionalFilterFieldKeys, isActionAvailable } from './utils/filters'
29
+
30
+ type NixxieContextType = {
31
+ adminConfig: AdminConfig | null
32
+ apiPath: string | null
33
+ error?: ErrorLike | null
34
+ fieldViews: FieldViews
35
+ lists: { [list: string]: ListMeta }
36
+ }
37
+
38
+ const NixxieContext = createContext<NixxieContextType>({
39
+ adminConfig: null,
40
+ apiPath: null,
41
+ lists: {},
42
+ fieldViews: {},
43
+ })
44
+
45
+ type NixxieProviderProps = {
46
+ adminConfig: AdminConfig
47
+ apiPath: string
48
+ fieldViews: FieldViews
49
+ children: ReactNode
50
+ }
51
+
52
+ const expectedExports = new Set(['Field', 'controller'])
53
+
54
+ function InternalNixxieProvider({
55
+ adminConfig,
56
+ apiPath,
57
+ fieldViews,
58
+ children,
59
+ }: NixxieProviderProps) {
60
+ const { push: navigate } = useRouter()
61
+ const keystarRouter = useMemo(() => ({ navigate }), [navigate])
62
+ const { data, loading, error } = useQuery<AdminMetaQuery>(adminMetaQuery, {
63
+ errorPolicy: 'all',
64
+ })
65
+ const listsData = data?.nixxie?.adminMeta?.lists
66
+ const lists = useMemo(() => {
67
+ if (!listsData) return
68
+ if (error) return
69
+
70
+ const lists: NixxieContextType['lists'] = {}
71
+
72
+ for (const listData of listsData) {
73
+ lists[listData.key] = {
74
+ ...listData,
75
+ pageSize: snapValueToClosest(listData.pageSize ?? 50),
76
+ fields: {},
77
+ groups: [],
78
+ }
79
+
80
+ for (const field of listData.fields) {
81
+ for (const exportName of expectedExports) {
82
+ if ((fieldViews[field.viewsIndex] as any)[exportName] === undefined) {
83
+ throw new Error(
84
+ `The view for the field at ${listData.key}.${field.key} is missing the ${exportName} export`
85
+ )
86
+ }
87
+ }
88
+
89
+ const views = { ...fieldViews[field.viewsIndex] }
90
+ const customViews: Record<string, any> = {}
91
+ if (field.customViewsIndex !== null) {
92
+ const customViewsSource: FieldViews[number] & Record<string, any> =
93
+ fieldViews[field.customViewsIndex]
94
+ const allowedExportsOnCustomViews = new Set(views.allowedExportsOnCustomViews)
95
+ for (const exportName in customViewsSource) {
96
+ if (allowedExportsOnCustomViews.has(exportName)) {
97
+ customViews[exportName] = customViewsSource[exportName]
98
+ } else if (expectedExports.has(exportName)) {
99
+ ;(views as any)[exportName] = customViewsSource[exportName]
100
+ }
101
+ }
102
+ }
103
+
104
+ lists[listData.key].fields[field.key] = {
105
+ ...field,
106
+ createView: {
107
+ fieldMode: field.createView?.fieldMode ?? null,
108
+ isRequired: field.createView?.isRequired ?? false,
109
+ },
110
+ itemView: {
111
+ fieldMode: field.itemView?.fieldMode ?? null,
112
+ fieldPosition: field.itemView?.fieldPosition ?? null,
113
+ isRequired: field.itemView?.isRequired ?? false,
114
+ },
115
+ listView: {
116
+ fieldMode: field.listView?.fieldMode ?? null,
117
+ },
118
+ views,
119
+ controller: views.controller({
120
+ listKey: listData.key,
121
+ fieldKey: field.key,
122
+ label: field.label,
123
+ description: field.description,
124
+ fieldMeta: field.fieldMeta,
125
+ customViews,
126
+ }),
127
+ }
128
+ }
129
+
130
+ for (const group of listData.groups) {
131
+ lists[listData.key].groups.push({
132
+ label: group.label,
133
+ description: group.description,
134
+ fields: group.fields.map(field => lists[listData.key].fields[field.key]),
135
+ })
136
+ }
137
+ }
138
+
139
+ return lists
140
+ }, [listsData, error, fieldViews])
141
+
142
+ useEffect(() => {
143
+ injectGlobal({
144
+ body: {
145
+ fontFamily:
146
+ "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
147
+ WebkitFontSmoothing: 'antialiased',
148
+ MozOsxFontSmoothing: 'grayscale',
149
+ },
150
+ '*, ::before, ::after': {
151
+ borderWidth: 0,
152
+ borderStyle: 'solid',
153
+ borderColor: tokenSchema.color.border.neutral,
154
+ boxSizing: 'border-box',
155
+ },
156
+ // Force light background on all Keystar surface/canvas elements
157
+ // when they appear inside the main content (not inside our dark sidebar)
158
+ '[data-nixxie-content]': {
159
+ colorScheme: 'light',
160
+ },
161
+ })
162
+ }, [])
163
+
164
+ // TODO
165
+ if (loading) return null
166
+ // if (!meta) return null
167
+ return (
168
+ <KeystarProvider router={keystarRouter} colorScheme="light">
169
+ <ClientSideOnlyDocumentElement bodyBackground="canvas" />
170
+ <NextHead>
171
+ <meta key="viewport" name="viewport" content="width=device-width, initial-scale=1.0" />
172
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
173
+ <link
174
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
175
+ rel="stylesheet"
176
+ />
177
+ </NextHead>
178
+
179
+ <NixxieContext.Provider
180
+ value={{
181
+ adminConfig,
182
+ apiPath,
183
+ fieldViews,
184
+ lists: lists ?? {},
185
+ error: error ?? null,
186
+ }}
187
+ >
188
+ {children}
189
+ </NixxieContext.Provider>
190
+ <Toaster />
191
+ </KeystarProvider>
192
+ )
193
+ }
194
+
195
+ export function NixxieProvider(props: NixxieProviderProps) {
196
+ const apolloClient = useMemo(
197
+ () =>
198
+ new ApolloClient({
199
+ cache: new InMemoryCache(),
200
+ link: new UploadLink({
201
+ uri: props.apiPath,
202
+ headers: { 'Apollo-Require-Preflight': 'true' },
203
+ }),
204
+ }),
205
+ [props.apiPath]
206
+ )
207
+
208
+ return (
209
+ <ApolloProvider client={apolloClient}>
210
+ <InternalNixxieProvider {...props} />
211
+ </ApolloProvider>
212
+ )
213
+ }
214
+
215
+ export function useNixxie() {
216
+ return useContext(NixxieContext)
217
+ }
218
+
219
+ export function useList(listKey: string) {
220
+ const { lists } = useNixxie()
221
+ const list = lists?.[listKey]
222
+ if (!list) throw new Error(`Unknown list ${listKey}`)
223
+ return list
224
+ }
225
+
226
+ export function useField(listKey: string, fieldKey: string) {
227
+ const list = useList(listKey)
228
+ const field = list.fields[fieldKey]
229
+ if (!field) throw new Error(`Unknown field ${listKey}.${fieldKey}`)
230
+ return field
231
+ }
232
+
233
+ // TODO useContext?
234
+ export function useListItem(
235
+ listKey: string,
236
+ itemId: string | null
237
+ ): useQuery.Result<
238
+ {
239
+ item: Record<string, unknown> | null
240
+ nixxie: {
241
+ adminMeta: {
242
+ list: {
243
+ fields: {
244
+ key: string
245
+ itemView: {
246
+ fieldMode: ConditionalFilter<
247
+ 'edit' | 'read' | 'hidden',
248
+ 'read' | 'hidden',
249
+ BaseListTypeInfo
250
+ >
251
+ fieldPosition: 'form' | 'sidebar'
252
+ isRequired: ConditionalFilterCase<BaseListTypeInfo>
253
+ } | null
254
+ }[]
255
+ actions: {
256
+ key: string
257
+ itemView: {
258
+ actionMode: ConditionalFilter<
259
+ 'enabled' | 'disabled' | 'hidden',
260
+ 'disabled' | 'hidden',
261
+ BaseListTypeInfo
262
+ >
263
+ } | null
264
+ }[]
265
+ } | null
266
+ }
267
+ }
268
+ },
269
+ { id: string | null; listKey: string }
270
+ > {
271
+ const list = useList(listKey)
272
+ const query = useMemo(() => {
273
+ const selectedFieldKeys = new Set<string>()
274
+
275
+ for (const field of Object.values(list.fields)) {
276
+ if (field.key === 'id') continue // always in the query
277
+ if (field.itemView.fieldMode === 'hidden') continue
278
+ selectedFieldKeys.add(field.key)
279
+ }
280
+
281
+ for (const action of list.actions) {
282
+ if (!isActionAvailable(action, action.itemView)) continue
283
+
284
+ for (const fieldKey of getConditionalFilterFieldKeys(action.itemView.actionMode)) {
285
+ selectedFieldKeys.add(fieldKey)
286
+ }
287
+
288
+ for (const arg of action.graphql.arguments) {
289
+ if (!arg.source) continue
290
+ selectedFieldKeys.add(arg.source.itemField)
291
+ }
292
+ }
293
+
294
+ const selectedFields = [...selectedFieldKeys]
295
+ .map(fieldKey => list.fields[fieldKey])
296
+ .filter(Boolean)
297
+ .map(field => field.controller.graphqlSelection)
298
+ .join('\n')
299
+
300
+ return gql`
301
+ query NxFetchItem ($listKey: String!, $id: ID!) {
302
+ nixxie {
303
+ adminMeta {
304
+ list(key: $listKey, itemId: $id) {
305
+ fields {
306
+ key
307
+ itemView {
308
+ fieldMode
309
+ fieldPosition
310
+ isRequired
311
+ }
312
+ }
313
+ actions {
314
+ key
315
+ itemView {
316
+ actionMode
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+ item: ${list.graphql.names.itemQueryName}(where: { id: $id }) {
323
+ id
324
+ ${selectedFields}
325
+ }
326
+ }
327
+ `
328
+ }, [list])
329
+
330
+ return useQuery(query, {
331
+ errorPolicy: 'all',
332
+ skip: itemId === null,
333
+ variables: {
334
+ listKey,
335
+ id: itemId,
336
+ },
337
+ })
338
+ }