betterstart-cli 0.0.117 → 0.0.119
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.
- package/dist/assets/adapters/next/templates/init/admin-globals.css +154 -38
- package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-grid-row.tsx +33 -1
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-gallery-dialog.tsx +3 -3
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-preview.tsx +3 -1
- package/dist/assets/adapters/next/templates/init/hooks/use-field-error-visible.ts +25 -0
- package/dist/assets/adapters/next/templates/init/hooks/use-media.ts +1 -1
- package/dist/assets/adapters/next/templates/init/hooks/use-upload.ts +11 -5
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/cleanup-audit-logs.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/query-audit-logs.ts +2 -2
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/record-audit-event.ts +1 -2
- package/dist/assets/adapters/next/templates/init/lib/actions/auth/client.ts +4 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/entity-versions/get-entity-versions.ts +5 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/forms/get-all-form-settings.ts +1 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/media/create-media.ts +2 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media-bulk.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/media/update-media.ts +2 -4
- package/dist/assets/adapters/next/templates/init/lib/actions/profile/change-own-password.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/profile/update-email.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-files.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-media-from-url.ts +16 -6
- package/dist/assets/adapters/next/templates/init/lib/actions/users/change-user-password.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/users/create-user.ts +2 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/users/delete-user.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/users/types.ts +1 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/users/update-user-role.ts +1 -0
- package/dist/assets/adapters/next/templates/init/lib/db/core/schema.ts +12 -4
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/registry.ts +4 -4
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/runner.ts +3 -7
- package/dist/assets/adapters/next/templates/init/pages/forgot-password-form.tsx +5 -8
- package/dist/assets/adapters/next/templates/init/pages/forgot-password-page-skeleton.tsx +2 -2
- package/dist/assets/adapters/next/templates/init/pages/login-form.tsx +7 -9
- package/dist/assets/adapters/next/templates/init/pages/login-page-skeleton.tsx +2 -2
- package/dist/assets/adapters/next/templates/init/pages/reset-password-form.tsx +8 -16
- package/dist/assets/adapters/next/templates/init/pages/reset-password-page-skeleton.tsx +2 -2
- package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-detail-row.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/settings/audit-log/audit-log-table.tsx +1 -6
- package/dist/assets/adapters/next/templates/init/pages/settings/forms/forms-settings-table.tsx +2 -7
- package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhooks-table.tsx +1 -6
- package/dist/assets/adapters/next/templates/init/pages/users/users-table.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/public/placeholder.png +0 -0
- package/dist/assets/adapters/next/templates/init/types/index.ts +2 -0
- package/dist/assets/adapters/next/templates/init/utils/audit/normalize-comparable-value.ts +4 -2
- package/dist/assets/adapters/next/templates/init/utils/date/format-action-date.ts +12 -0
- package/dist/assets/adapters/next/templates/init/utils/dev-mode/dev-mode-json-schemas.ts +66 -0
- package/dist/assets/adapters/next/templates/init/utils/dev-mode/parse-dev-mode-lifecycle-hooks.ts +11 -0
- package/dist/assets/adapters/next/templates/init/utils/dev-mode/parse-dev-mode-snippets.ts +9 -0
- package/dist/assets/adapters/next/templates/init/utils/editor/set-task-item-checked.ts +13 -0
- package/dist/assets/adapters/next/templates/init/utils/editor/update-nodes-attr.ts +2 -1
- package/dist/assets/adapters/next/templates/init/utils/email/email-theme.ts +13 -0
- package/dist/assets/adapters/next/templates/init/utils/email/render-form-submission-rows.ts +3 -2
- package/dist/assets/adapters/next/templates/init/utils/email/render-notification-email.ts +7 -6
- package/dist/assets/adapters/next/templates/init/utils/email/render-thank-you-email.ts +5 -4
- package/dist/assets/adapters/next/templates/init/utils/error/read-string-property.ts +4 -2
- package/dist/assets/adapters/next/templates/init/utils/error/recognize.ts +2 -4
- package/dist/assets/adapters/next/templates/init/utils/error/to-action-error.ts +0 -1
- package/dist/assets/adapters/next/templates/init/utils/form/clone-default-value.ts +4 -2
- package/dist/assets/adapters/next/templates/init/utils/shared/is-record.ts +3 -0
- package/dist/assets/adapters/next/templates/init/utils/table/default-get-id.ts +3 -2
- package/dist/assets/shared-assets/react-admin/custom/content-editor/editor-toolbar.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/slash-command-menu.tsx +5 -3
- package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/removable-image-node/removable-image-node.tsx +3 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/task-item-node/task-item-node-extension.tsx +6 -15
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx +1 -6
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx +1 -6
- package/dist/assets/shared-assets/react-admin/custom/date-range-picker.tsx +9 -2
- package/dist/assets/shared-assets/react-admin/custom/gallery-field.tsx +3 -3
- package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/custom/nested-object-list-field.tsx +3 -1
- package/dist/assets/shared-assets/react-admin/custom/progressive-blur.tsx +3 -1
- package/dist/assets/shared-assets/react-admin/ui/badge.tsx +1 -2
- package/dist/assets/shared-assets/react-admin/ui/dropdown-menu.tsx +20 -23
- package/dist/assets/shared-assets/react-admin/ui/form.tsx +6 -3
- package/dist/assets/shared-assets/react-admin/ui/input.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/native-select.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/navigation-menu.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/select.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/textarea.tsx +1 -1
- package/dist/{chunk-FGEVDA53.js → chunk-BNHFSHPE.js} +12 -1
- package/dist/chunk-BNHFSHPE.js.map +1 -0
- package/dist/cli.js +909 -598
- package/dist/cli.js.map +1 -1
- package/dist/{read-namespaced-template-KUENIIDC.js → read-namespaced-template-WYIGUH7S.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-FGEVDA53.js.map +0 -1
- /package/dist/{read-namespaced-template-KUENIIDC.js.map → read-namespaced-template-WYIGUH7S.js.map} +0 -0
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
--color-input: var(--input);
|
|
28
28
|
--color-border: var(--border);
|
|
29
29
|
--color-highlight: var(--highlight);
|
|
30
|
+
--color-placeholder: var(--placeholder);
|
|
30
31
|
--color-destructive: var(--destructive);
|
|
32
|
+
--color-success: var(--success);
|
|
31
33
|
--color-warning: var(--warning);
|
|
32
34
|
--color-warning-foreground: var(--warning-foreground);
|
|
33
35
|
--color-accent-foreground: var(--accent-foreground);
|
|
@@ -80,36 +82,152 @@
|
|
|
80
82
|
);
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
@theme {
|
|
86
|
+
--breakpoint-xs: 480px;
|
|
87
|
+
--spacing-entity-editor: 300px;
|
|
88
|
+
--spacing-table-cell: 300px;
|
|
89
|
+
--spacing-form-settings-name: 200px;
|
|
90
|
+
--spacing-form-settings-recipients: 240px;
|
|
91
|
+
--spacing-auth-login-panel: 540px;
|
|
92
|
+
--spacing-auth-reset-panel: 520px;
|
|
93
|
+
--spacing-auth-forgot-panel: 460px;
|
|
94
|
+
--spacing-media-dialog: 700px;
|
|
95
|
+
--spacing-media-tile: 180px;
|
|
96
|
+
--spacing-media-thumb: 100px;
|
|
97
|
+
--spacing-gallery-item: 184px;
|
|
98
|
+
--spacing-date-range-trigger: 206px;
|
|
99
|
+
--spacing-date-range-popover: 282px;
|
|
100
|
+
--spacing-source-editor: 240px;
|
|
101
|
+
--grid-template-columns-entity-form: 1fr 360px;
|
|
102
|
+
--grid-template-columns-audit-detail: 120px 1fr;
|
|
103
|
+
}
|
|
104
|
+
|
|
83
105
|
:root {
|
|
84
|
-
--
|
|
85
|
-
--
|
|
86
|
-
--
|
|
87
|
-
--
|
|
88
|
-
--
|
|
89
|
-
--
|
|
90
|
-
--
|
|
91
|
-
--
|
|
92
|
-
--
|
|
93
|
-
--
|
|
94
|
-
--
|
|
95
|
-
--
|
|
96
|
-
--
|
|
97
|
-
--
|
|
98
|
-
--
|
|
99
|
-
--
|
|
100
|
-
--
|
|
101
|
-
--
|
|
102
|
-
--
|
|
103
|
-
--
|
|
104
|
-
--
|
|
105
|
-
--
|
|
106
|
-
--
|
|
107
|
-
--
|
|
106
|
+
--ds-background-100: lab(100% 0 0);
|
|
107
|
+
--ds-background-200: lab(98.144% 0 -0.0000119209);
|
|
108
|
+
--ds-gray-100: lab(95.476% -0.0000298023 0);
|
|
109
|
+
--ds-gray-200: lab(93.04% 0.0000298023 -0.0000119209);
|
|
110
|
+
--ds-gray-300: lab(91.3% 0 -0.0000119209);
|
|
111
|
+
--ds-gray-400: lab(92.692% 0 0);
|
|
112
|
+
--ds-gray-500: lab(80.976% 0 -0.0000119209);
|
|
113
|
+
--ds-gray-600: lab(68.912% 0 -0.0000119209);
|
|
114
|
+
--ds-gray-700: lab(59.4% 0 0);
|
|
115
|
+
--ds-gray-800: lab(52.44% 0 0);
|
|
116
|
+
--ds-gray-900: lab(32.72% -0.0000149012 0);
|
|
117
|
+
--ds-gray-1000: lab(7.78201% -0.0000149012 0);
|
|
118
|
+
--ds-gray-alpha-100: lab(0% 0 0 / 0.05);
|
|
119
|
+
--ds-gray-alpha-200: lab(0% 0 0 / 0.081);
|
|
120
|
+
--ds-gray-alpha-300: lab(0% 0 0 / 0.1);
|
|
121
|
+
--ds-gray-alpha-400: lab(0% 0 0 / 0.08);
|
|
122
|
+
--ds-gray-alpha-500: lab(0% 0 0 / 0.21);
|
|
123
|
+
--ds-gray-alpha-600: lab(0% 0 0 / 0.24);
|
|
124
|
+
--ds-gray-alpha-700: lab(0% 0 0 / 0.44);
|
|
125
|
+
--ds-gray-alpha-800: lab(0% 0 0 / 0.51);
|
|
126
|
+
--ds-gray-alpha-900: lab(0% 0 0 / 0.7);
|
|
127
|
+
--ds-gray-alpha-1000: lab(0% 0 0 / 0.91);
|
|
128
|
+
--ds-blue-100: lab(96.8732% -1.39889 -5.07131);
|
|
129
|
+
--ds-blue-200: lab(95.6744% -2.00856 -6.9569);
|
|
130
|
+
--ds-blue-300: lab(93.6801% -3.04809 -10.3604);
|
|
131
|
+
--ds-blue-400: lab(90.2207% -5.88808 -16.0541);
|
|
132
|
+
--ds-blue-500: lab(79.7793% -8.30209 -33.3699);
|
|
133
|
+
--ds-blue-600: lab(68.1823% -8.44929 -52.7934);
|
|
134
|
+
--ds-blue-700: lab(47.9229% 22.3147 -86.8328);
|
|
135
|
+
--ds-blue-800: lab(40.8106% 23.698 -82.9445);
|
|
136
|
+
--ds-blue-900: lab(42.9093% 21.1896 -82.6493);
|
|
137
|
+
--ds-blue-1000: lab(13.8687% 6.36795 -37.4197);
|
|
138
|
+
--ds-red-100: lab(95.6935% 7.32443 2.00332);
|
|
139
|
+
--ds-red-200: lab(94.3497% 9.77078 2.91723);
|
|
140
|
+
--ds-red-300: lab(93.0242% 12.0165 3.78883);
|
|
141
|
+
--ds-red-400: lab(89.6749% 14.9771 6.30434);
|
|
142
|
+
--ds-red-500: lab(80.9124% 32.7639 12.5167);
|
|
143
|
+
--ds-red-600: lab(64.5512% 60.0041 29.3131);
|
|
144
|
+
--ds-red-700: lab(53.9255% 80.6033 48.0845);
|
|
145
|
+
--ds-red-800: lab(48.9343% 78.946 55.0086);
|
|
146
|
+
--ds-red-900: lab(45.3957% 73.7444 51.3924);
|
|
147
|
+
--ds-red-1000: lab(11.6345% 33.5137 13.8317);
|
|
148
|
+
--ds-amber-100: lab(97.2024% 1.01992 12.7992);
|
|
149
|
+
--ds-amber-200: lab(96.5222% 0.44781 19.38);
|
|
150
|
+
--ds-amber-300: lab(95.5532% 0.730604 25.1573);
|
|
151
|
+
--ds-amber-400: lab(89.9281% 6.02812 56.553);
|
|
152
|
+
--ds-amber-500: lab(84.4286% 16.6827 71.0758);
|
|
153
|
+
--ds-amber-600: lab(76.726% 29.5673 105.476);
|
|
154
|
+
--ds-amber-700: lab(78.7256% 26.6905 107.161);
|
|
155
|
+
--ds-amber-800: lab(72.7954% 39.7122 103.301);
|
|
156
|
+
--ds-amber-900: lab(44.3662% 36.3127 70.4646);
|
|
157
|
+
--ds-amber-1000: lab(19.0178% 27.3692 31.8945);
|
|
158
|
+
--ds-green-100: lab(97.5853% -8.11777 6.20661);
|
|
159
|
+
--ds-green-200: lab(96.9166% -10.612 7.60013);
|
|
160
|
+
--ds-green-300: lab(94.6031% -18.6422 15.0889);
|
|
161
|
+
--ds-green-400: lab(91.3796% -27.7496 20.9385);
|
|
162
|
+
--ds-green-500: lab(85.1416% -46.4903 35.8939);
|
|
163
|
+
--ds-green-600: lab(79.6441% -60.3529 50.7117);
|
|
164
|
+
--ds-green-700: lab(61.0339% -50.9714 38.8312);
|
|
165
|
+
--ds-green-800: lab(52.9002% -44.1062 33.0987);
|
|
166
|
+
--ds-green-900: lab(45.7946% -42.7208 32.0975);
|
|
167
|
+
--ds-green-1000: lab(19.2017% -35.6785 27.2939);
|
|
168
|
+
--ds-teal-100: lab(97.7805% -12.1079 -1.6973);
|
|
169
|
+
--ds-teal-200: lab(97.0232% -11.8163 -0.259781);
|
|
170
|
+
--ds-teal-300: lab(94.6978% -16.2983 -0.800061);
|
|
171
|
+
--ds-teal-400: lab(92.4757% -24.5274 -1.99826);
|
|
172
|
+
--ds-teal-500: lab(86.4355% -46.7053 -2.48644);
|
|
173
|
+
--ds-teal-600: lab(80.5746% -56.8254 0.696123);
|
|
174
|
+
--ds-teal-700: lab(61.2492% -55.7738 -2.36303);
|
|
175
|
+
--ds-teal-800: lab(52.4585% -49.4257 -1.83064);
|
|
176
|
+
--ds-teal-900: lab(45.9452% -44.2291 -2.67519);
|
|
177
|
+
--ds-teal-1000: lab(22.2372% -28.1244 -0.0907302);
|
|
178
|
+
--ds-purple-100: lab(95.8064% 5.66289 -6.77673);
|
|
179
|
+
--ds-purple-200: lab(95.9251% 5.05617 -6.57121);
|
|
180
|
+
--ds-purple-300: lab(93.5693% 8.17552 -10.3939);
|
|
181
|
+
--ds-purple-400: lab(89.6505% 14.5975 -16.7056);
|
|
182
|
+
--ds-purple-500: lab(76.2735% 33.6932 -38.7706);
|
|
183
|
+
--ds-purple-600: lab(64.3635% 50.5605 -58.6804);
|
|
184
|
+
--ds-purple-700: lab(42.3587% 81.2683 -86.4789);
|
|
185
|
+
--ds-purple-800: lab(35.0556% 71.1896 -76.2188);
|
|
186
|
+
--ds-purple-900: lab(33.4854% 69.2003 -76.1092);
|
|
187
|
+
--ds-purple-1000: lab(9.18347% 35.0629 -37.5931);
|
|
188
|
+
--ds-pink-100: lab(94.5133% 11.6709 -3.49871);
|
|
189
|
+
--ds-pink-200: lab(94.6026% 10.7321 -1.35195);
|
|
190
|
+
--ds-pink-300: lab(92.2617% 15.1106 -0.957537);
|
|
191
|
+
--ds-pink-400: lab(88.9731% 19.1876 -0.249231);
|
|
192
|
+
--ds-pink-500: lab(80.5902% 30.3695 -1.5003);
|
|
193
|
+
--ds-pink-600: lab(68.2806% 50.7706 0.897086);
|
|
194
|
+
--ds-pink-700: lab(54.7091% 76.7064 2.85504);
|
|
195
|
+
--ds-pink-800: lab(50.1788% 75.5319 8.12644);
|
|
196
|
+
--ds-pink-900: lab(43.5237% 66.4129 5.12512);
|
|
197
|
+
--ds-pink-1000: lab(12.9204% 31.3916 -0.183001);
|
|
198
|
+
|
|
199
|
+
--background: var(--ds-background-200);
|
|
200
|
+
--foreground: var(--ds-gray-1000);
|
|
201
|
+
--card: var(--ds-background-100);
|
|
202
|
+
--card-foreground: var(--ds-gray-1000);
|
|
203
|
+
--popover: var(--ds-background-100);
|
|
204
|
+
--popover-foreground: var(--ds-gray-1000);
|
|
205
|
+
--primary: var(--ds-gray-1000);
|
|
206
|
+
--primary-foreground: var(--ds-background-100);
|
|
207
|
+
--secondary: var(--ds-gray-200);
|
|
208
|
+
--secondary-foreground: var(--ds-gray-1000);
|
|
209
|
+
--muted: var(--ds-gray-100);
|
|
210
|
+
--muted-foreground: var(--ds-gray-900);
|
|
211
|
+
--placeholder: var(--ds-gray-700);
|
|
212
|
+
--accent: var(--ds-gray-100);
|
|
213
|
+
--accent-foreground: var(--ds-gray-1000);
|
|
214
|
+
--destructive: var(--ds-red-900);
|
|
215
|
+
--success: var(--ds-green-900);
|
|
216
|
+
--warning: var(--ds-amber-900);
|
|
217
|
+
--warning-foreground: var(--ds-amber-900);
|
|
218
|
+
--border: var(--ds-gray-400);
|
|
219
|
+
--highlight: var(--ds-gray-600);
|
|
220
|
+
--input: var(--ds-gray-400);
|
|
221
|
+
--ring: var(--ds-gray-600);
|
|
222
|
+
--chart-1: var(--ds-blue-700);
|
|
223
|
+
--chart-2: var(--ds-purple-700);
|
|
224
|
+
--chart-3: var(--ds-teal-700);
|
|
225
|
+
--chart-4: var(--ds-amber-700);
|
|
226
|
+
--chart-5: var(--ds-pink-700);
|
|
108
227
|
--radius: 0.625rem;
|
|
109
228
|
--shadow-background-border: 0 0 0 1px var(--background);
|
|
110
|
-
--shadow-border-base: 0 0 0 1px
|
|
111
|
-
|
|
112
|
-
--shadow-border-inset: inset 0 0 0 1px var(--border);
|
|
229
|
+
--shadow-border-base: 0 0 0 1px var(--ds-gray-alpha-400);
|
|
230
|
+
--shadow-border-inset: inset 0 0 0 1px var(--ds-gray-alpha-400);
|
|
113
231
|
--shadow-border: var(--shadow-border-base), var(--shadow-background-border);
|
|
114
232
|
--shadow-small: 0px 2px 2px #0000000a;
|
|
115
233
|
--shadow-border-small:
|
|
@@ -141,16 +259,14 @@
|
|
|
141
259
|
var(--shadow-border-base), 0px 1px 1px #00000005, 0px 8px 16px -4px #0000000a, 0px 24px 32px -8px #0000000f, var(
|
|
142
260
|
--shadow-background-border
|
|
143
261
|
);
|
|
144
|
-
--sidebar:
|
|
145
|
-
--sidebar-foreground:
|
|
146
|
-
--sidebar-primary:
|
|
147
|
-
--sidebar-primary-foreground:
|
|
148
|
-
--sidebar-accent:
|
|
149
|
-
--sidebar-accent-foreground:
|
|
150
|
-
--sidebar-border:
|
|
151
|
-
--sidebar-ring:
|
|
152
|
-
--background: oklch(0.983 0 0);
|
|
153
|
-
--foreground: oklch(0.145 0 0);
|
|
262
|
+
--sidebar: var(--ds-background-200);
|
|
263
|
+
--sidebar-foreground: var(--ds-gray-900);
|
|
264
|
+
--sidebar-primary: var(--ds-gray-1000);
|
|
265
|
+
--sidebar-primary-foreground: var(--ds-background-100);
|
|
266
|
+
--sidebar-accent: var(--ds-gray-200);
|
|
267
|
+
--sidebar-accent-foreground: var(--ds-gray-1000);
|
|
268
|
+
--sidebar-border: var(--ds-gray-400);
|
|
269
|
+
--sidebar-ring: var(--ds-gray-600);
|
|
154
270
|
--tt-bg-color: var(--background);
|
|
155
271
|
--tt-bg-color-contrast: var(--border);
|
|
156
272
|
--tt-color-highlight-yellow: #fef9c3;
|
|
@@ -441,7 +557,7 @@
|
|
|
441
557
|
.admin-root
|
|
442
558
|
.content-editor-prose
|
|
443
559
|
.is-empty[data-placeholder]:has(> .ProseMirror-trailingBreak)::before {
|
|
444
|
-
@apply pointer-events-none absolute inset-x-0 h-0 w-full text-
|
|
560
|
+
@apply pointer-events-none absolute inset-x-0 h-0 w-full text-placeholder;
|
|
445
561
|
text-align: inherit;
|
|
446
562
|
}
|
|
447
563
|
|
package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-grid-row.tsx
CHANGED
|
@@ -3,7 +3,37 @@
|
|
|
3
3
|
import type * as React from 'react'
|
|
4
4
|
import { cn } from '@admin/utils/shared/cn'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const INTERACTIVE_ROW_SELECTOR = 'button, a, input, [role="checkbox"], [role="switch"]'
|
|
7
|
+
|
|
8
|
+
type DataGridRowProps = React.ComponentProps<'div'> & {
|
|
9
|
+
onActivate?: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function DataGridRow({
|
|
13
|
+
className,
|
|
14
|
+
style,
|
|
15
|
+
onActivate,
|
|
16
|
+
onClick,
|
|
17
|
+
onKeyDown,
|
|
18
|
+
...props
|
|
19
|
+
}: DataGridRowProps) {
|
|
20
|
+
function handleClick(event: React.MouseEvent<HTMLDivElement>) {
|
|
21
|
+
onClick?.(event)
|
|
22
|
+
const target = event.target
|
|
23
|
+
if (!onActivate || !(target instanceof HTMLElement)) return
|
|
24
|
+
if (!event.currentTarget.contains(target)) return
|
|
25
|
+
if (target.closest(INTERACTIVE_ROW_SELECTOR)) return
|
|
26
|
+
onActivate()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
|
|
30
|
+
onKeyDown?.(event)
|
|
31
|
+
if (!onActivate || event.target !== event.currentTarget) return
|
|
32
|
+
if (event.key !== 'Enter' && event.key !== ' ') return
|
|
33
|
+
event.preventDefault()
|
|
34
|
+
onActivate()
|
|
35
|
+
}
|
|
36
|
+
|
|
7
37
|
return (
|
|
8
38
|
<div
|
|
9
39
|
role="row"
|
|
@@ -14,6 +44,8 @@ function DataGridRow({ className, style, ...props }: React.ComponentProps<'div'>
|
|
|
14
44
|
)}
|
|
15
45
|
style={{ ...style, gridColumn: '1 / -1', gridTemplateColumns: 'subgrid' }}
|
|
16
46
|
tabIndex={-1}
|
|
47
|
+
onClick={handleClick}
|
|
48
|
+
onKeyDown={handleKeyDown}
|
|
17
49
|
{...props}
|
|
18
50
|
/>
|
|
19
51
|
)
|
package/dist/assets/adapters/next/templates/init/components/shared/media/media-gallery-dialog.tsx
CHANGED
|
@@ -99,7 +99,7 @@ export function MediaGalleryDialog({
|
|
|
99
99
|
onOpenChange(next)
|
|
100
100
|
}}
|
|
101
101
|
>
|
|
102
|
-
<DialogContent className="flex h-[80svh] max-h-
|
|
102
|
+
<DialogContent className="flex h-[80svh] max-h-media-dialog min-h-0 max-w-3xl flex-col gap-0 overflow-hidden">
|
|
103
103
|
<DialogHeader>
|
|
104
104
|
<DialogTitle>Select file</DialogTitle>
|
|
105
105
|
<DialogDescription>
|
|
@@ -128,7 +128,7 @@ export function MediaGalleryDialog({
|
|
|
128
128
|
progress={progress}
|
|
129
129
|
isUploading={isUploading}
|
|
130
130
|
accept={accept}
|
|
131
|
-
className="h-
|
|
131
|
+
className="h-media-tile"
|
|
132
132
|
/>
|
|
133
133
|
</TabsUi.TabsContent>
|
|
134
134
|
|
|
@@ -136,7 +136,7 @@ export function MediaGalleryDialog({
|
|
|
136
136
|
<MediaUrlImporter
|
|
137
137
|
onImportFromUrl={uploadFromUrl}
|
|
138
138
|
accept={accept}
|
|
139
|
-
className="h-
|
|
139
|
+
className="h-media-tile"
|
|
140
140
|
/>
|
|
141
141
|
</TabsUi.TabsContent>
|
|
142
142
|
</TabsUi.Tabs>
|
|
@@ -12,6 +12,8 @@ interface MediaPreviewProps {
|
|
|
12
12
|
showMetadata?: boolean
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
const MEDIA_PREVIEW_IMAGE_SIZES = '200px'
|
|
16
|
+
|
|
15
17
|
export function MediaPreview({ media, isFilled = false, showMetadata = false }: MediaPreviewProps) {
|
|
16
18
|
const { hasImageFailed, markImageFailed } = useFailedImageUrl(media.url)
|
|
17
19
|
|
|
@@ -26,7 +28,7 @@ export function MediaPreview({ media, isFilled = false, showMetadata = false }:
|
|
|
26
28
|
'object-contain': !isFilled
|
|
27
29
|
})}
|
|
28
30
|
fill
|
|
29
|
-
sizes=
|
|
31
|
+
sizes={MEDIA_PREVIEW_IMAGE_SIZES}
|
|
30
32
|
unoptimized
|
|
31
33
|
loading="lazy"
|
|
32
34
|
decoding="async"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import type { FieldPath, FieldValues, UseFormReturn } from 'react-hook-form'
|
|
4
|
+
import { useWatch } from 'react-hook-form'
|
|
5
|
+
|
|
6
|
+
function hasValue(value: unknown): boolean {
|
|
7
|
+
if (value === null || value === undefined) return false
|
|
8
|
+
if (typeof value === 'string') return value.trim().length > 0
|
|
9
|
+
if (Array.isArray(value)) return value.length > 0
|
|
10
|
+
|
|
11
|
+
return true
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useFieldErrorVisible<TValues extends FieldValues>(
|
|
15
|
+
form: UseFormReturn<TValues>,
|
|
16
|
+
name: FieldPath<TValues>
|
|
17
|
+
): boolean {
|
|
18
|
+
const value = useWatch({ control: form.control, name })
|
|
19
|
+
const { error, isTouched } = form.getFieldState(name, form.formState)
|
|
20
|
+
|
|
21
|
+
if (!error) return false
|
|
22
|
+
if (form.formState.isSubmitted) return true
|
|
23
|
+
|
|
24
|
+
return isTouched && hasValue(value)
|
|
25
|
+
}
|
|
@@ -69,7 +69,7 @@ export function useMediaSelection(mode: 'single' | 'multi') {
|
|
|
69
69
|
[mode]
|
|
70
70
|
)
|
|
71
71
|
|
|
72
|
-
const reset =
|
|
72
|
+
const reset = () => setSelectedMap(emptySelection())
|
|
73
73
|
|
|
74
74
|
const getSelection = React.useCallback(() => {
|
|
75
75
|
const values = [...selectedMap.values()]
|
|
@@ -190,11 +190,17 @@ export function useUpload(options: UseUploadOptions = {}): UseUploadReturn {
|
|
|
190
190
|
formData.append('allowedTypes', validationConfig.allowedTypes.join(','))
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
193
|
+
let response: Response
|
|
194
|
+
try {
|
|
195
|
+
response = await fetch('/api/admin/upload', {
|
|
196
|
+
method: 'POST',
|
|
197
|
+
body: formData,
|
|
198
|
+
signal: abortController.signal
|
|
199
|
+
})
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (error instanceof Error && error.name === 'AbortError') throw error
|
|
202
|
+
throw new Error('Upload failed. Check your connection and try again.')
|
|
203
|
+
}
|
|
198
204
|
|
|
199
205
|
const result = (await response.json()) as UploadFileResult
|
|
200
206
|
|
|
@@ -51,6 +51,7 @@ export async function cleanupAuditLogs(): Promise<CleanupAuditLogsResult> {
|
|
|
51
51
|
|
|
52
52
|
return { success: true, deletedCount: deletedRows.length, cutoff }
|
|
53
53
|
} catch (error) {
|
|
54
|
+
console.error('Failed to clean up audit logs:', error)
|
|
54
55
|
return {
|
|
55
56
|
success: false,
|
|
56
57
|
error: toActionError(error, 'Failed to clean up audit logs')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AuditLogPage, AuditLogQuery } from '@admin/actions/audit/types'
|
|
2
2
|
import { clampPage } from '@admin/actions/audit/clamp-page'
|
|
3
3
|
import { getAuditLogOrderBy } from '@admin/actions/audit/get-audit-log-order-by'
|
|
4
4
|
import { normalizePageSize } from '@admin/actions/audit/normalize-page-size'
|
|
@@ -62,7 +62,7 @@ export async function queryAuditLogs(query: AuditLogQuery = {}): Promise<AuditLo
|
|
|
62
62
|
const resolvedPageSize = pageSize ?? total
|
|
63
63
|
|
|
64
64
|
return {
|
|
65
|
-
auditLogs: rows
|
|
65
|
+
auditLogs: rows,
|
|
66
66
|
total,
|
|
67
67
|
page,
|
|
68
68
|
pageSize: resolvedPageSize,
|
|
@@ -6,7 +6,6 @@ import db from '@admin/db'
|
|
|
6
6
|
import { auditLog } from '@admin/db/schema'
|
|
7
7
|
|
|
8
8
|
const MAX_TARGET_TYPE_LENGTH = 100
|
|
9
|
-
const MAX_SOURCE_TYPE_LENGTH = 50
|
|
10
9
|
|
|
11
10
|
function truncate(value: string | null | undefined, maxLength: number): string | null {
|
|
12
11
|
if (!value) return null
|
|
@@ -24,7 +23,7 @@ export async function recordAuditEvent(event: AdminEventContext): Promise<void>
|
|
|
24
23
|
actorEmail: event.user?.email ?? null,
|
|
25
24
|
actorName: event.user?.name ?? null,
|
|
26
25
|
actorRole: typeof event.user?.role === 'string' ? event.user.role : null,
|
|
27
|
-
sourceType:
|
|
26
|
+
sourceType: event.sourceType ?? 'server_action',
|
|
28
27
|
ipAddress: truncate(event.ipAddress, MAX_IP_LENGTH),
|
|
29
28
|
userAgent: truncate(event.userAgent, MAX_USER_AGENT_LENGTH),
|
|
30
29
|
changedFields: normalizeChangedFields(event.changedFields),
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
+
import type { auth } from '@admin/auth/server'
|
|
4
|
+
import { inferAdditionalFields } from 'better-auth/client/plugins'
|
|
3
5
|
import { createAuthClient } from 'better-auth/react'
|
|
4
6
|
|
|
5
7
|
export const authClient = createAuthClient({
|
|
6
8
|
baseURL:
|
|
7
9
|
process.env.NEXT_PUBLIC_BETTERSTART_AUTH_URL ||
|
|
8
10
|
(typeof window !== 'undefined' ? window.location.origin : ''),
|
|
9
|
-
basePath: '/api/admin/auth'
|
|
11
|
+
basePath: '/api/admin/auth',
|
|
12
|
+
plugins: [inferAdditionalFields<typeof auth>()]
|
|
10
13
|
})
|
|
11
14
|
|
|
12
15
|
export const { signIn, signUp, signOut, useSession } = authClient
|
package/dist/assets/adapters/next/templates/init/lib/actions/entity-versions/get-entity-versions.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import type { EntityVersionWithAuthor } from './types'
|
|
4
4
|
import db from '@admin/db'
|
|
5
5
|
import { entityVersions, user } from '@admin/db/schema'
|
|
6
|
+
import { isRecord } from '@admin/utils/shared/is-record'
|
|
6
7
|
import { and, desc, eq } from 'drizzle-orm'
|
|
7
8
|
import { alias } from 'drizzle-orm/pg-core'
|
|
8
9
|
import { cacheLife, cacheTag } from 'next/cache'
|
|
@@ -40,7 +41,10 @@ export async function getEntityVersions(
|
|
|
40
41
|
.where(and(eq(entityVersions.entityType, entityType), eq(entityVersions.entityId, entityId)))
|
|
41
42
|
.orderBy(desc(entityVersions.version), desc(entityVersions.createdAt))
|
|
42
43
|
|
|
43
|
-
return rows
|
|
44
|
+
return rows.map((row) => ({
|
|
45
|
+
...row,
|
|
46
|
+
data: isRecord(row.data) ? row.data : {}
|
|
47
|
+
}))
|
|
44
48
|
} catch (error) {
|
|
45
49
|
console.error('Error fetching entity versions:', error)
|
|
46
50
|
return []
|
|
@@ -13,7 +13,7 @@ export async function getAllFormSettings(): Promise<FormSettingsData[]> {
|
|
|
13
13
|
|
|
14
14
|
try {
|
|
15
15
|
const settings = await db.select().from(formSettings)
|
|
16
|
-
return settings
|
|
16
|
+
return settings
|
|
17
17
|
} catch (error) {
|
|
18
18
|
console.error('Error fetching all form settings:', error)
|
|
19
19
|
return []
|
|
@@ -43,7 +43,7 @@ export async function createMedia(data: CreateMediaInput): Promise<CreateMediaRe
|
|
|
43
43
|
user: actor,
|
|
44
44
|
timestamp: now,
|
|
45
45
|
sourceType: 'admin_ui' as const,
|
|
46
|
-
changedFields: getTouchedFieldNames(data
|
|
46
|
+
changedFields: getTouchedFieldNames(data),
|
|
47
47
|
metadata: { contentType: media.contentType, size: media.size },
|
|
48
48
|
...auditRequestMetadata
|
|
49
49
|
})
|
|
@@ -52,6 +52,7 @@ export async function createMedia(data: CreateMediaInput): Promise<CreateMediaRe
|
|
|
52
52
|
? { success: true, media }
|
|
53
53
|
: { success: false, error: 'Failed to create media record' }
|
|
54
54
|
} catch (error) {
|
|
55
|
+
console.error('Failed to create media record:', error)
|
|
55
56
|
return {
|
|
56
57
|
success: false,
|
|
57
58
|
error: toActionError(error, 'Failed to create media record')
|
|
@@ -45,6 +45,7 @@ export async function deleteMediaBulk(ids: string[]): Promise<DeleteMediaBulkRes
|
|
|
45
45
|
}
|
|
46
46
|
return { success: true, deletedCount: deletedRows.length }
|
|
47
47
|
} catch (error) {
|
|
48
|
+
console.error('Failed to delete media:', error)
|
|
48
49
|
return {
|
|
49
50
|
success: false,
|
|
50
51
|
error: toActionError(error, 'Failed to delete media')
|
|
@@ -36,6 +36,7 @@ export async function deleteMedia(id: string): Promise<DeleteMediaResult> {
|
|
|
36
36
|
})
|
|
37
37
|
return { success: true }
|
|
38
38
|
} catch (error) {
|
|
39
|
+
console.error('Failed to delete media:', error)
|
|
39
40
|
return {
|
|
40
41
|
success: false,
|
|
41
42
|
error: toActionError(error, 'Failed to delete media')
|
|
@@ -41,15 +41,13 @@ export async function updateMedia(
|
|
|
41
41
|
user: actor,
|
|
42
42
|
timestamp: now,
|
|
43
43
|
sourceType: 'admin_ui' as const,
|
|
44
|
-
changedFields: getChangedFieldNames(
|
|
45
|
-
previousMedia as unknown as Record<string, unknown>,
|
|
46
|
-
data as Record<string, unknown>
|
|
47
|
-
),
|
|
44
|
+
changedFields: getChangedFieldNames(previousMedia, data),
|
|
48
45
|
metadata: { contentType: previousMedia?.contentType ?? null },
|
|
49
46
|
...auditRequestMetadata
|
|
50
47
|
})
|
|
51
48
|
return { success: true }
|
|
52
49
|
} catch (error) {
|
|
50
|
+
console.error('Failed to update media:', error)
|
|
53
51
|
return {
|
|
54
52
|
success: false,
|
|
55
53
|
error: toActionError(error, 'Failed to update media')
|
package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-media-from-url.ts
CHANGED
|
@@ -22,12 +22,21 @@ export async function uploadMediaFromUrl(
|
|
|
22
22
|
return { success: false, error: 'Only HTTP and HTTPS URLs are allowed' }
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
let response: Response
|
|
26
|
+
try {
|
|
27
|
+
response = await fetch(mediaUrl, {
|
|
28
|
+
headers: {
|
|
29
|
+
'User-Agent': 'Mozilla/5.0 (compatible; BetterStartMediaFetcher/1.0)'
|
|
30
|
+
},
|
|
31
|
+
signal: AbortSignal.timeout(REMOTE_FETCH_TIMEOUT_MS)
|
|
32
|
+
})
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('Failed to fetch remote media:', error)
|
|
35
|
+
return {
|
|
36
|
+
success: false,
|
|
37
|
+
error: "Couldn't reach that URL. Check the link and try again."
|
|
38
|
+
}
|
|
39
|
+
}
|
|
31
40
|
|
|
32
41
|
if (!response.ok) {
|
|
33
42
|
return {
|
|
@@ -129,6 +138,7 @@ export async function uploadMediaFromUrl(
|
|
|
129
138
|
]
|
|
130
139
|
}
|
|
131
140
|
} catch (error) {
|
|
141
|
+
console.error('Failed to upload media from URL:', error)
|
|
132
142
|
return { success: false, error: toActionError(error, 'Failed to upload media from URL') }
|
|
133
143
|
}
|
|
134
144
|
}
|
|
@@ -48,7 +48,7 @@ export async function createUser(input: CreateUserInput): Promise<CreateUserResu
|
|
|
48
48
|
user: actor,
|
|
49
49
|
timestamp: now,
|
|
50
50
|
sourceType: 'admin_ui' as const,
|
|
51
|
-
changedFields: getTouchedFieldNames(input
|
|
51
|
+
changedFields: getTouchedFieldNames(input),
|
|
52
52
|
metadata: { role: input.role },
|
|
53
53
|
...auditRequestMetadata
|
|
54
54
|
})
|
|
@@ -66,6 +66,7 @@ export async function createUser(input: CreateUserInput): Promise<CreateUserResu
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
} catch (error) {
|
|
69
|
+
console.error('Failed to create user:', error)
|
|
69
70
|
return {
|
|
70
71
|
success: false,
|
|
71
72
|
error: toActionError(error, 'Failed to create user')
|
|
@@ -39,6 +39,7 @@ export async function deleteUser(userId: string): Promise<DeleteUserResult> {
|
|
|
39
39
|
})
|
|
40
40
|
return { success: true }
|
|
41
41
|
} catch (error) {
|
|
42
|
+
console.error('Failed to delete user:', error)
|
|
42
43
|
return {
|
|
43
44
|
success: false,
|
|
44
45
|
error: toActionError(error, 'Failed to delete user')
|