@nixxie-cms/core 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.cjs.js +7 -7
  2. package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.esm.js +7 -7
  3. package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.cjs.js +2 -2
  4. package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.esm.js +2 -2
  5. package/admin-ui/utils/dist/nixxie-cms-core-admin-ui-utils.cjs.js +5 -5
  6. package/admin-ui/utils/dist/nixxie-cms-core-admin-ui-utils.esm.js +3 -3
  7. package/dist/{CreateItemDialog-7008b050.esm.js → CreateItemDialog-66621fe8.esm.js} +3 -3
  8. package/dist/{CreateItemDialog-a0cab315.cjs.js → CreateItemDialog-96b044ce.cjs.js} +4 -4
  9. package/dist/{Field-47f85161.esm.js → Field-1820c4e6.esm.js} +1 -0
  10. package/dist/{Field-ed8d7627.cjs.js → Field-38d3cdf9.cjs.js} +1 -0
  11. package/dist/GraphQLErrorNotice-7594a9f8.esm.js +64 -0
  12. package/dist/GraphQLErrorNotice-c8890f80.cjs.js +66 -0
  13. package/dist/{PageContainer-5ae731cc.esm.js → PageContainer-355cfbfa.esm.js} +362 -156
  14. package/dist/{PageContainer-abd7159f.cjs.js → PageContainer-4095555a.cjs.js} +361 -155
  15. package/dist/{context-af9957ed.esm.js → context-2924eaaa.esm.js} +53 -58
  16. package/dist/{context-b5204629.cjs.js → context-2ce61d0b.cjs.js} +53 -58
  17. package/dist/declarations/src/admin-ui/components/GraphQLErrorNotice.d.ts.map +1 -1
  18. package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
  19. package/dist/declarations/src/admin-ui/components/PageContainer.d.ts.map +1 -1
  20. package/dist/declarations/src/admin-ui/context.d.ts.map +1 -1
  21. package/dist/declarations/src/admin-ui/utils/useCreateItem.d.ts.map +1 -1
  22. package/dist/declarations/src/fields/types/bigInt/views/index.d.ts +2 -1
  23. package/dist/declarations/src/fields/types/bigInt/views/index.d.ts.map +1 -1
  24. package/dist/declarations/src/fields/types/bytes/views/index.d.ts +2 -1
  25. package/dist/declarations/src/fields/types/bytes/views/index.d.ts.map +1 -1
  26. package/dist/declarations/src/fields/types/calendarDay/views/index.d.ts.map +1 -1
  27. package/dist/declarations/src/fields/types/decimal/views/index.d.ts +2 -1
  28. package/dist/declarations/src/fields/types/decimal/views/index.d.ts.map +1 -1
  29. package/dist/declarations/src/fields/types/float/views/index.d.ts +2 -1
  30. package/dist/declarations/src/fields/types/float/views/index.d.ts.map +1 -1
  31. package/dist/declarations/src/fields/types/integer/views/index.d.ts +2 -1
  32. package/dist/declarations/src/fields/types/integer/views/index.d.ts.map +1 -1
  33. package/dist/declarations/src/fields/types/json/views/index.d.ts.map +1 -1
  34. package/dist/declarations/src/fields/types/multiselect/views/index.d.ts.map +1 -1
  35. package/dist/declarations/src/fields/types/relationship/views/index.d.ts.map +1 -1
  36. package/dist/declarations/src/fields/types/select/views/index.d.ts.map +1 -1
  37. package/dist/declarations/src/fields/types/text/views/index.d.ts +2 -1
  38. package/dist/declarations/src/fields/types/text/views/index.d.ts.map +1 -1
  39. package/dist/declarations/src/fields/types/timestamp/views/index.d.ts.map +1 -1
  40. package/dist/declarations/src/fields/types/virtual/views/index.d.ts.map +1 -1
  41. package/dist/declarations/src/internal-unstable/admin-ui/pages/HomePage/index.d.ts.map +1 -1
  42. package/dist/declarations/src/internal-unstable/admin-ui/pages/ItemPage/index.d.ts.map +1 -1
  43. package/dist/pick-4c785a54.esm.js +34 -0
  44. package/dist/pick-906341bb.cjs.js +37 -0
  45. package/dist/{useCreateItem-1f94d252.esm.js → useCreateItem-36a75f1c.esm.js} +26 -26
  46. package/dist/{useCreateItem-1be4987e.cjs.js → useCreateItem-acf06f77.cjs.js} +37 -37
  47. package/dist/{useFilter-acc9d413.cjs.js → useFilter-c29f17a8.cjs.js} +1 -1
  48. package/dist/{useFilter-9b6db1f9.esm.js → useFilter-f79b2abb.esm.js} +1 -1
  49. package/dist/{Fields-956d9a14.esm.js → usePreventNavigation-093389dd.esm.js} +28 -2
  50. package/dist/{Fields-e2c28056.cjs.js → usePreventNavigation-d4f9f4fa.cjs.js} +27 -0
  51. package/fields/types/bigInt/views/dist/nixxie-cms-core-fields-types-bigInt-views.cjs.js +8 -0
  52. package/fields/types/bigInt/views/dist/nixxie-cms-core-fields-types-bigInt-views.esm.js +8 -1
  53. package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.cjs.js +14 -3
  54. package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.esm.js +15 -5
  55. package/fields/types/calendarDay/views/dist/nixxie-cms-core-fields-types-calendarDay-views.cjs.js +2 -1
  56. package/fields/types/calendarDay/views/dist/nixxie-cms-core-fields-types-calendarDay-views.esm.js +2 -1
  57. package/fields/types/decimal/views/dist/nixxie-cms-core-fields-types-decimal-views.cjs.js +10 -1
  58. package/fields/types/decimal/views/dist/nixxie-cms-core-fields-types-decimal-views.esm.js +10 -2
  59. package/fields/types/file/views/dist/nixxie-cms-core-fields-types-file-views.cjs.js +1 -1
  60. package/fields/types/file/views/dist/nixxie-cms-core-fields-types-file-views.esm.js +2 -2
  61. package/fields/types/float/views/dist/nixxie-cms-core-fields-types-float-views.cjs.js +10 -1
  62. package/fields/types/float/views/dist/nixxie-cms-core-fields-types-float-views.esm.js +10 -2
  63. package/fields/types/image/views/dist/nixxie-cms-core-fields-types-image-views.cjs.js +2 -1
  64. package/fields/types/image/views/dist/nixxie-cms-core-fields-types-image-views.esm.js +2 -1
  65. package/fields/types/integer/views/dist/nixxie-cms-core-fields-types-integer-views.cjs.js +8 -0
  66. package/fields/types/integer/views/dist/nixxie-cms-core-fields-types-integer-views.esm.js +8 -1
  67. package/fields/types/json/views/dist/nixxie-cms-core-fields-types-json-views.cjs.js +19 -4
  68. package/fields/types/json/views/dist/nixxie-cms-core-fields-types-json-views.esm.js +19 -4
  69. package/fields/types/multiselect/views/dist/nixxie-cms-core-fields-types-multiselect-views.cjs.js +18 -3
  70. package/fields/types/multiselect/views/dist/nixxie-cms-core-fields-types-multiselect-views.esm.js +18 -3
  71. package/fields/types/password/views/dist/nixxie-cms-core-fields-types-password-views.cjs.js +1 -1
  72. package/fields/types/password/views/dist/nixxie-cms-core-fields-types-password-views.esm.js +1 -1
  73. package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.cjs.js +9 -7
  74. package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.esm.js +9 -7
  75. package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.cjs.js +3 -2
  76. package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.esm.js +3 -2
  77. package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.cjs.js +14 -3
  78. package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.esm.js +15 -5
  79. package/fields/types/timestamp/views/dist/nixxie-cms-core-fields-types-timestamp-views.cjs.js +2 -1
  80. package/fields/types/timestamp/views/dist/nixxie-cms-core-fields-types-timestamp-views.esm.js +2 -1
  81. package/fields/types/virtual/views/dist/nixxie-cms-core-fields-types-virtual-views.cjs.js +13 -1
  82. package/fields/types/virtual/views/dist/nixxie-cms-core-fields-types-virtual-views.esm.js +14 -2
  83. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.js +3 -3
  84. package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.esm.js +3 -3
  85. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.js +7 -7
  86. package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.esm.js +6 -6
  87. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.js +34 -33
  88. package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.esm.js +35 -34
  89. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.js +53 -13
  90. package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.esm.js +52 -12
  91. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.js +36 -25
  92. package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.esm.js +36 -25
  93. package/package.json +2 -2
  94. package/src/admin-ui/components/CommandPalette.tsx +134 -27
  95. package/src/admin-ui/components/CreateButtonLink.tsx +20 -46
  96. package/src/admin-ui/components/GraphQLErrorNotice.tsx +39 -33
  97. package/src/admin-ui/components/Logo.tsx +5 -5
  98. package/src/admin-ui/components/Navigation.tsx +41 -27
  99. package/src/admin-ui/components/PageContainer.tsx +171 -15
  100. package/src/admin-ui/components/WelcomeDialog.tsx +14 -14
  101. package/src/admin-ui/context.tsx +5 -2
  102. package/src/admin-ui/utils/useCreateItem.ts +21 -1
  103. package/src/fields/types/bigInt/views/index.tsx +10 -1
  104. package/src/fields/types/bytes/views/index.tsx +14 -1
  105. package/src/fields/types/calendarDay/views/index.tsx +2 -1
  106. package/src/fields/types/decimal/views/index.tsx +7 -1
  107. package/src/fields/types/file/views/Field.tsx +1 -1
  108. package/src/fields/types/float/views/index.tsx +7 -1
  109. package/src/fields/types/image/views/index.tsx +1 -1
  110. package/src/fields/types/integer/views/index.tsx +5 -0
  111. package/src/fields/types/json/views/index.tsx +20 -2
  112. package/src/fields/types/multiselect/views/index.tsx +7 -3
  113. package/src/fields/types/password/views/index.tsx +1 -1
  114. package/src/fields/types/relationship/views/index.tsx +1 -0
  115. package/src/fields/types/select/views/index.tsx +2 -1
  116. package/src/fields/types/text/views/index.tsx +14 -1
  117. package/src/fields/types/timestamp/views/__tests__/index.tsx +68 -68
  118. package/src/fields/types/timestamp/views/index.tsx +2 -1
  119. package/src/fields/types/virtual/views/index.tsx +17 -2
  120. package/src/internal-unstable/admin-ui/pages/HomePage/index.tsx +40 -31
  121. package/src/internal-unstable/admin-ui/pages/ItemPage/index.tsx +36 -3
  122. package/src/internal-unstable/admin-ui/pages/ListPage/PaginationControls.tsx +20 -33
  123. package/src/internal-unstable/admin-ui/pages/ListPage/index.tsx +24 -16
  124. package/tests/conditional-filters.test.ts +333 -326
  125. package/dist/GraphQLErrorNotice-cd74180d.cjs.js +0 -57
  126. package/dist/GraphQLErrorNotice-d9f0931b.esm.js +0 -55
  127. package/dist/pick-5fe45878.cjs.js +0 -71
  128. package/dist/pick-b7ef3115.esm.js +0 -68
@@ -1,5 +1,5 @@
1
1
  import router, { useRouter } from 'next/router';
2
- import { useMemo, useState, useEffect, Fragment, useRef, useCallback } from 'react';
2
+ import { useMemo, useState, useEffect, useRef, Fragment, useCallback } from 'react';
3
3
  import { Button } from '@keystar/ui/button';
4
4
  import { DialogContainer, DialogTrigger, AlertDialog } from '@keystar/ui/dialog';
5
5
  import { Icon } from '@keystar/ui/icon';
@@ -11,33 +11,34 @@ import { toastQueue } from '@keystar/ui/toast';
11
11
  import { Text, Heading } from '@keystar/ui/typography';
12
12
  import { gql, CombinedGraphQLErrors } from '@apollo/client';
13
13
  import { useMutation } from '@apollo/client/react';
14
- import { p as pick, C as CreateButtonLink } from '../../../../../dist/pick-b7ef3115.esm.js';
14
+ import { p as pick, C as CreateButtonLink } from '../../../../../dist/pick-4c785a54.esm.js';
15
15
  import { b as ErrorDetailsDialog } from '../../../../../dist/Errors-bf24759e.esm.js';
16
- import { G as GraphQLErrorNotice } from '../../../../../dist/GraphQLErrorNotice-d9f0931b.esm.js';
17
- import { P as PageContainer } from '../../../../../dist/PageContainer-5ae731cc.esm.js';
18
- import { a as useList, b as useListItem } from '../../../../../dist/context-af9957ed.esm.js';
19
- import { F as Fields } from '../../../../../dist/Fields-956d9a14.esm.js';
16
+ import { G as GraphQLErrorNotice } from '../../../../../dist/GraphQLErrorNotice-7594a9f8.esm.js';
17
+ import { P as PageContainer } from '../../../../../dist/PageContainer-355cfbfa.esm.js';
18
+ import { a as useList, b as useListItem } from '../../../../../dist/context-2924eaaa.esm.js';
19
+ import { u as usePreventNavigation, F as Fields } from '../../../../../dist/usePreventNavigation-093389dd.esm.js';
20
20
  import { g as getConditionalFilterFieldKeys, s as serializeItemForConditionalFilters, r as resolveActionMode, i as isActionAvailable } from '../../../../../dist/filters-8c8616f9.esm.js';
21
21
  import { d as deserializeItemToValue, u as useInvalidFields, a as useHasChanges, s as serializeValueToOperationItem } from '../../../../../dist/utils-5e1d4d28.esm.js';
22
22
  import { I as ItemPageHeader, C as ColumnLayout, S as StickySidebar, B as BaseToolbar } from '../../../../../dist/common-ea5c441a.esm.js';
23
23
  import { jsx, jsxs } from 'react/jsx-runtime';
24
- import '@keystar/ui/style';
24
+ import '@keystar/ui/icon/icons/plusIcon';
25
25
  import '@babel/runtime/helpers/defineProperty';
26
26
  import '@keystar/ui/icon/icons/alertTriangleIcon';
27
27
  import '@keystar/ui/notice';
28
+ import '@keystar/ui/style';
28
29
  import 'next/head';
29
30
  import 'next/link';
31
+ import '@react-aria/utils';
30
32
  import 'apollo-upload-client/UploadHttpLink.mjs';
31
33
  import '@keystar/ui/core';
32
34
  import '@nixxie-cms/core/admin-ui/router';
33
35
  import '@keystar/ui/icon/icons/chevronLeftIcon';
34
36
  import '@keystar/ui/icon/icons/chevronRightIcon';
35
37
  import '@keystar/ui/icon/icons/undo2Icon';
38
+ import '@keystar/ui/number-field';
36
39
  import '@keystar/ui/picker';
37
- import '@keystar/ui/tag';
38
40
  import '@keystar/ui/tooltip';
39
41
  import '../../../../../dist/admin-meta-graphql-0e6e606e.esm.js';
40
- import '@react-aria/utils';
41
42
  import '@keystar/ui/icon/icons/textCursorInputIcon';
42
43
  import '@keystar/ui/utils';
43
44
  import 'fast-deep-equal';
@@ -57,6 +58,27 @@ function useEventCallback(callback) {
57
58
  });
58
59
  return cb;
59
60
  }
61
+
62
+ // after forcing validation, move focus to the first invalid field so the user
63
+ // can see and fix it. runs on the next frame so the DOM reflects the new
64
+ // aria-invalid state, and is fully defensive so it can never throw.
65
+ function focusFirstInvalidField() {
66
+ requestAnimationFrame(() => {
67
+ try {
68
+ const el = document.querySelector('[aria-invalid="true"]');
69
+ if (!el) return;
70
+ el.focus({
71
+ preventScroll: false
72
+ });
73
+ el.scrollIntoView({
74
+ block: 'center',
75
+ behavior: 'smooth'
76
+ });
77
+ } catch {
78
+ // ignore — focusing is a best-effort enhancement
79
+ }
80
+ });
81
+ }
60
82
  function DeleteButton({
61
83
  list,
62
84
  itemId,
@@ -155,7 +177,6 @@ function ResetButton(props) {
155
177
  title: "Reset changes",
156
178
  cancelLabel: "Cancel",
157
179
  primaryActionLabel: "Yes, reset",
158
- autoFocusButton: "primary",
159
180
  onPrimaryAction: props.onReset,
160
181
  children: "Are you sure? Any unsaved changes will be lost and cannot be recovered."
161
182
  })]
@@ -195,7 +216,11 @@ function ItemForm({
195
216
  e.preventDefault();
196
217
  const newForceValidation = invalidFields.size !== 0;
197
218
  setForceValidation(newForceValidation);
198
- if (newForceValidation) return;
219
+ if (newForceValidation) {
220
+ toastQueue.critical('Please fix the highlighted field(s) before saving.');
221
+ focusFirstInvalidField();
222
+ return;
223
+ }
199
224
  const {
200
225
  error: _error
201
226
  } = await update({
@@ -219,9 +244,18 @@ function ItemForm({
219
244
  toastQueue.positive(`Saved changes to ${list.singular.toLocaleLowerCase()}.`, {
220
245
  timeout: 5000
221
246
  });
247
+
248
+ // reset the navigation guard before refetch so saving and then navigating
249
+ // away doesn't prompt for unsaved changes
250
+ shouldPreventNavigationRef.current = false;
222
251
  onSaveSuccess();
223
252
  });
224
253
  const hasChangedFields = useHasChanges('update', list.fields, value, initialValue);
254
+ const shouldPreventNavigationRef = useRef(hasChangedFields);
255
+ useEffect(() => {
256
+ shouldPreventNavigationRef.current = hasChangedFields;
257
+ }, [hasChangedFields]);
258
+ usePreventNavigation(shouldPreventNavigationRef);
225
259
  return /*#__PURE__*/jsxs(Fragment, {
226
260
  children: [/*#__PURE__*/jsxs("form", {
227
261
  onSubmit: onSave,
@@ -317,7 +351,13 @@ function ItemPage({
317
351
  const item = data === null || data === void 0 ? void 0 : data.item;
318
352
  const itemLabel_ = (_item$list$labelField = item === null || item === void 0 ? void 0 : item[list.labelField]) !== null && _item$list$labelField !== void 0 ? _item$list$labelField : item === null || item === void 0 ? void 0 : item.id;
319
353
  const itemLabel = typeof itemLabel_ === 'string' ? itemLabel_ : itemId !== null && itemId !== void 0 ? itemId : '';
320
- const pageLoading = loading || itemId === undefined;
354
+
355
+ // Only show the full-page spinner on the INITIAL load (no data yet). On a
356
+ // post-save refetch Apollo keeps `data` populated while `loading` flips back
357
+ // to true; gating on `!data` keeps the form mounted (no scroll reset / flash)
358
+ // during background refetches while still showing the spinner before the
359
+ // first result arrives.
360
+ const pageLoading = loading && !data || itemId === undefined;
321
361
  const pageLabel = itemLabel || itemId;
322
362
  const pageTitle = list.isSingleton || typeof pageLabel !== 'string' ? list.label : pageLabel;
323
363
  const initialValue = useMemo(() => {
@@ -28,21 +28,22 @@ var link = require('@keystar/ui/link');
28
28
  var notice = require('@keystar/ui/notice');
29
29
  var client = require('@apollo/client');
30
30
  var react$1 = require('@apollo/client/react');
31
- var pick = require('../../../../../dist/pick-5fe45878.cjs.js');
31
+ var pick = require('../../../../../dist/pick-906341bb.cjs.js');
32
32
  var utils$1 = require('../../../../../dist/utils-230cddb1.cjs.js');
33
- var GraphQLErrorNotice = require('../../../../../dist/GraphQLErrorNotice-cd74180d.cjs.js');
34
- var PageContainer = require('../../../../../dist/PageContainer-abd7159f.cjs.js');
35
- var adminUi_context_dist_nixxieCmsCoreAdminUiContext = require('../../../../../dist/context-b5204629.cjs.js');
33
+ var GraphQLErrorNotice = require('../../../../../dist/GraphQLErrorNotice-c8890f80.cjs.js');
34
+ var PageContainer = require('../../../../../dist/PageContainer-4095555a.cjs.js');
35
+ var adminUi_context_dist_nixxieCmsCoreAdminUiContext = require('../../../../../dist/context-2ce61d0b.cjs.js');
36
36
  require('@react-aria/utils');
37
37
  require('@keystar/ui/icon/icons/chevronRightIcon');
38
38
  require('@keystar/ui/icon/icons/textCursorInputIcon');
39
39
  var filters = require('../../../../../dist/filters-b3e5eb50.cjs.js');
40
40
  var jsxRuntime = require('react/jsx-runtime');
41
41
  var actionData = require('../../../../../dist/actionData-7858738d.cjs.js');
42
- var useFilter = require('../../../../../dist/useFilter-acc9d413.cjs.js');
42
+ var useFilter = require('../../../../../dist/useFilter-c29f17a8.cjs.js');
43
43
  var picker = require('@keystar/ui/picker');
44
44
  var xIcon = require('@keystar/ui/icon/icons/xIcon');
45
45
  var utils = require('@keystar/ui/utils');
46
+ require('@keystar/ui/icon/icons/plusIcon');
46
47
  require('graphql');
47
48
  require('next/head');
48
49
  require('next/link');
@@ -50,7 +51,7 @@ require('apollo-upload-client/UploadHttpLink.mjs');
50
51
  require('@keystar/ui/core');
51
52
  require('@nixxie-cms/core/admin-ui/router');
52
53
  require('@keystar/ui/icon/icons/chevronLeftIcon');
53
- require('@keystar/ui/tag');
54
+ require('@keystar/ui/number-field');
54
55
  require('../../../../../dist/admin-meta-graphql-306c224a.cjs.js');
55
56
 
56
57
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
@@ -1094,26 +1095,36 @@ function ActionItemsDialog({
1094
1095
  id
1095
1096
  }
1096
1097
  }`;
1098
+ // The ids actually included in the mutation payload, in the exact order
1099
+ // they are sent to the server. Server error paths reference indices into
1100
+ // this array, so error/affected-record attribution must be done against it
1101
+ // rather than the original (possibly larger) itemIds list.
1102
+ const sentIds = [];
1103
+ const mutationData = action.key === 'delete' ? itemIds.map(id => {
1104
+ sentIds.push(id);
1105
+ return {
1106
+ id
1107
+ };
1108
+ }) : itemIds.flatMap(id => {
1109
+ const row = items.find(item => String(item.id) === id);
1110
+ if (!row) {
1111
+ return [];
1112
+ }
1113
+ const deserialized = utils$1.deserializeItemToValue(list.fields, row);
1114
+ const args = actionData.getActionArguments(list, action, deserialized);
1115
+ sentIds.push(id);
1116
+ return {
1117
+ where: {
1118
+ id
1119
+ },
1120
+ ...args
1121
+ };
1122
+ });
1097
1123
  const [actionOnItems] = react$1.useMutation(actionMutation, {
1098
1124
  variables: action.key === 'delete' ? {
1099
- where: itemIds.map(id => ({
1100
- id
1101
- }))
1125
+ where: mutationData
1102
1126
  } : {
1103
- data: itemIds.flatMap(id => {
1104
- const row = items.find(item => String(item.id) === id);
1105
- if (!row) {
1106
- return [];
1107
- }
1108
- const deserialized = utils$1.deserializeItemToValue(list.fields, row);
1109
- const args = actionData.getActionArguments(list, action, deserialized);
1110
- return {
1111
- where: {
1112
- id
1113
- },
1114
- ...args
1115
- };
1116
- })
1127
+ data: mutationData
1117
1128
  },
1118
1129
  errorPolicy: 'all'
1119
1130
  });
@@ -1134,13 +1145,13 @@ function ActionItemsDialog({
1134
1145
  var _error$errors, _err$path, _actionErrors$itemId;
1135
1146
  const i = (_err$path = err.path) === null || _err$path === void 0 ? void 0 : _err$path[1];
1136
1147
  if (typeof i !== 'number') continue;
1137
- const itemId = itemIds[i];
1148
+ const itemId = sentIds[i];
1138
1149
  failed.add(itemId);
1139
1150
  (_actionErrors$itemId = actionErrors[itemId]) !== null && _actionErrors$itemId !== void 0 ? _actionErrors$itemId : actionErrors[itemId] = [];
1140
1151
  actionErrors[itemId].push(err);
1141
1152
  }
1142
1153
  }
1143
- const countSuccess = itemIds.length - countFail;
1154
+ const countSuccess = sentIds.length - countFail;
1144
1155
  if (countSuccess) {
1145
1156
  toast.toastQueue.neutral(replace(m.successMany, list, {
1146
1157
  ...action,
@@ -24,21 +24,22 @@ import { TextLink } from '@keystar/ui/link';
24
24
  import { Notice } from '@keystar/ui/notice';
25
25
  import { gql, CombinedGraphQLErrors } from '@apollo/client';
26
26
  import { useQuery, useMutation } from '@apollo/client/react';
27
- import { p as pick, C as CreateButtonLink } from '../../../../../dist/pick-b7ef3115.esm.js';
27
+ import { p as pick, C as CreateButtonLink } from '../../../../../dist/pick-4c785a54.esm.js';
28
28
  import { d as deserializeItemToValue, E as EmptyState } from '../../../../../dist/utils-5e1d4d28.esm.js';
29
- import { G as GraphQLErrorNotice } from '../../../../../dist/GraphQLErrorNotice-d9f0931b.esm.js';
30
- import { P as PageContainer } from '../../../../../dist/PageContainer-5ae731cc.esm.js';
31
- import { a as useList, P as PaginationControls, s as snapValueToClosest } from '../../../../../dist/context-af9957ed.esm.js';
29
+ import { G as GraphQLErrorNotice } from '../../../../../dist/GraphQLErrorNotice-7594a9f8.esm.js';
30
+ import { P as PageContainer } from '../../../../../dist/PageContainer-355cfbfa.esm.js';
31
+ import { a as useList, P as PaginationControls, s as snapValueToClosest } from '../../../../../dist/context-2924eaaa.esm.js';
32
32
  import '@react-aria/utils';
33
33
  import '@keystar/ui/icon/icons/chevronRightIcon';
34
34
  import '@keystar/ui/icon/icons/textCursorInputIcon';
35
35
  import { i as isActionAvailable, g as getConditionalFilterFieldKeys, s as serializeItemForConditionalFilters, r as resolveActionMode } from '../../../../../dist/filters-8c8616f9.esm.js';
36
36
  import { jsxs, jsx } from 'react/jsx-runtime';
37
37
  import { g as getActionArguments } from '../../../../../dist/actionData-64d4c37a.esm.js';
38
- import { u as useSearchFilter } from '../../../../../dist/useFilter-9b6db1f9.esm.js';
38
+ import { u as useSearchFilter } from '../../../../../dist/useFilter-f79b2abb.esm.js';
39
39
  import { Picker } from '@keystar/ui/picker';
40
40
  import { xIcon } from '@keystar/ui/icon/icons/xIcon';
41
41
  import { composeId } from '@keystar/ui/utils';
42
+ import '@keystar/ui/icon/icons/plusIcon';
42
43
  import 'graphql';
43
44
  import 'next/head';
44
45
  import 'next/link';
@@ -46,7 +47,7 @@ import 'apollo-upload-client/UploadHttpLink.mjs';
46
47
  import '@keystar/ui/core';
47
48
  import '@nixxie-cms/core/admin-ui/router';
48
49
  import '@keystar/ui/icon/icons/chevronLeftIcon';
49
- import '@keystar/ui/tag';
50
+ import '@keystar/ui/number-field';
50
51
  import '../../../../../dist/admin-meta-graphql-0e6e606e.esm.js';
51
52
 
52
53
  function FilterAdd({
@@ -1086,26 +1087,36 @@ function ActionItemsDialog({
1086
1087
  id
1087
1088
  }
1088
1089
  }`;
1090
+ // The ids actually included in the mutation payload, in the exact order
1091
+ // they are sent to the server. Server error paths reference indices into
1092
+ // this array, so error/affected-record attribution must be done against it
1093
+ // rather than the original (possibly larger) itemIds list.
1094
+ const sentIds = [];
1095
+ const mutationData = action.key === 'delete' ? itemIds.map(id => {
1096
+ sentIds.push(id);
1097
+ return {
1098
+ id
1099
+ };
1100
+ }) : itemIds.flatMap(id => {
1101
+ const row = items.find(item => String(item.id) === id);
1102
+ if (!row) {
1103
+ return [];
1104
+ }
1105
+ const deserialized = deserializeItemToValue(list.fields, row);
1106
+ const args = getActionArguments(list, action, deserialized);
1107
+ sentIds.push(id);
1108
+ return {
1109
+ where: {
1110
+ id
1111
+ },
1112
+ ...args
1113
+ };
1114
+ });
1089
1115
  const [actionOnItems] = useMutation(actionMutation, {
1090
1116
  variables: action.key === 'delete' ? {
1091
- where: itemIds.map(id => ({
1092
- id
1093
- }))
1117
+ where: mutationData
1094
1118
  } : {
1095
- data: itemIds.flatMap(id => {
1096
- const row = items.find(item => String(item.id) === id);
1097
- if (!row) {
1098
- return [];
1099
- }
1100
- const deserialized = deserializeItemToValue(list.fields, row);
1101
- const args = getActionArguments(list, action, deserialized);
1102
- return {
1103
- where: {
1104
- id
1105
- },
1106
- ...args
1107
- };
1108
- })
1119
+ data: mutationData
1109
1120
  },
1110
1121
  errorPolicy: 'all'
1111
1122
  });
@@ -1126,13 +1137,13 @@ function ActionItemsDialog({
1126
1137
  var _error$errors, _err$path, _actionErrors$itemId;
1127
1138
  const i = (_err$path = err.path) === null || _err$path === void 0 ? void 0 : _err$path[1];
1128
1139
  if (typeof i !== 'number') continue;
1129
- const itemId = itemIds[i];
1140
+ const itemId = sentIds[i];
1130
1141
  failed.add(itemId);
1131
1142
  (_actionErrors$itemId = actionErrors[itemId]) !== null && _actionErrors$itemId !== void 0 ? _actionErrors$itemId : actionErrors[itemId] = [];
1132
1143
  actionErrors[itemId].push(err);
1133
1144
  }
1134
1145
  }
1135
- const countSuccess = itemIds.length - countFail;
1146
+ const countSuccess = sentIds.length - countFail;
1136
1147
  if (countSuccess) {
1137
1148
  toastQueue.neutral(replace(m.successMany, list, {
1138
1149
  ...action,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nixxie-cms/core",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/nixxiecms/nixxie/tree/main/packages/core"
@@ -302,7 +302,7 @@
302
302
  "@types/react-dom": "^19.2.3",
303
303
  "@types/resolve": "^1.20.2",
304
304
  "@types/uuid": "^11.0.0",
305
- "@nixxie-cms/core": "^2.0.0"
305
+ "@nixxie-cms/core": "^2.2.0"
306
306
  },
307
307
  "preconstruct": {
308
308
  "entrypoints": [