@byline/host-tanstack-start 3.0.1 → 3.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.
@@ -4,7 +4,7 @@ import { FormRenderer } from "@byline/admin/react";
4
4
  import { getDefaultStatus, getWorkflowStatuses } from "@byline/core";
5
5
  import { useTranslation } from "@byline/i18n/react";
6
6
  import { Container, Section, useToastManager } from "@byline/ui/react";
7
- import { copyDocumentToLocale, deleteDocument, duplicateCollectionDocument, unpublishDocument, updateCollectionDocumentWithPatches, updateDocumentStatus } from "../../server-fns/collections/index.js";
7
+ import { copyDocumentToLocale, deleteDocument, deleteDocumentLocale, duplicateCollectionDocument, unpublishDocument, updateCollectionDocumentWithPatches, updateDocumentStatus } from "../../server-fns/collections/index.js";
8
8
  import { useNavigate } from "../chrome/loose-router.js";
9
9
  import { useTanStackNavigationGuard } from "./tanstack-navigation-guard.js";
10
10
  import { ViewMenu } from "./view-menu.js";
@@ -290,6 +290,69 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
290
290
  });
291
291
  }
292
292
  };
293
+ const handleDeleteLocale = async ({ targetLocale })=>{
294
+ try {
295
+ const result = await deleteDocumentLocale({
296
+ data: {
297
+ collection: path,
298
+ id: String(initialData.id),
299
+ locale: targetLocale
300
+ }
301
+ });
302
+ const targetLabel = contentLocales.find((l)=>l.code === result.locale)?.label ?? result.locale;
303
+ const description = t("collections.edit.deletedLocaleDescription", {
304
+ label: singular,
305
+ locale: targetLabel
306
+ });
307
+ toastManager.add({
308
+ title: t('collections.edit.deleteLocaleTitle', {
309
+ label: singular
310
+ }),
311
+ description,
312
+ data: {
313
+ intent: 'success',
314
+ iconType: 'success',
315
+ icon: true,
316
+ close: true
317
+ }
318
+ });
319
+ setEditState({
320
+ status: 'success',
321
+ message: description
322
+ });
323
+ navigate({
324
+ to: '/admin/collections/$collection/$id',
325
+ params: {
326
+ collection: path,
327
+ id: String(initialData.id)
328
+ },
329
+ search: {
330
+ locale: defaultContentLocale
331
+ }
332
+ });
333
+ } catch (err) {
334
+ console.error('Delete locale error:', err);
335
+ const description = t("collections.edit.deleteLocaleFailedDescription", {
336
+ message: err.message
337
+ });
338
+ toastManager.add({
339
+ title: t('collections.edit.deleteLocaleTitle', {
340
+ label: singular
341
+ }),
342
+ description,
343
+ data: {
344
+ intent: 'danger',
345
+ iconType: 'danger',
346
+ icon: true,
347
+ close: true
348
+ }
349
+ });
350
+ setEditState({
351
+ status: 'failed',
352
+ message: description
353
+ });
354
+ }
355
+ };
293
356
  const handleDelete = async ()=>{
294
357
  try {
295
358
  await deleteDocument({
@@ -445,6 +508,7 @@ const EditView = ({ collectionDefinition, adminConfig, initialData, locale, cont
445
508
  onDelete: handleDelete,
446
509
  onDuplicate: handleDuplicate,
447
510
  onCopyToLocale: handleCopyToLocale,
511
+ onDeleteLocale: handleDeleteLocale,
448
512
  contentLocales: contentLocales,
449
513
  publishedVersion: publishedVersion,
450
514
  restoreWarnings: restoreWarnings,
@@ -0,0 +1,27 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { DeleteLocaleResult } from '@byline/core/services';
9
+ /**
10
+ * Remove a single (non-default) content locale from a document, leaving every
11
+ * other locale untouched. Mirrors the thin-wrapper pattern of the other
12
+ * collection server fns: resolve the request context, build the lifecycle
13
+ * context, delegate to the `deleteLocale` service.
14
+ *
15
+ * `assertActorCanPerform('update')` and the default-locale guard run inside
16
+ * the service; auth and validation failures propagate to TanStack Start's
17
+ * transport layer.
18
+ */
19
+ export declare const deleteDocumentLocale: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
20
+ collection: string;
21
+ id: string;
22
+ locale: string;
23
+ }) => {
24
+ collection: string;
25
+ id: string;
26
+ locale: string;
27
+ }, Promise<DeleteLocaleResult>>;
@@ -0,0 +1,35 @@
1
+ import { createServerFn } from "@tanstack/react-start";
2
+ import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
+ import { deleteLocale } from "@byline/core/services";
4
+ import { getAdminRequestContext } from "../../auth/auth-context.js";
5
+ import { ensureCollection } from "../../integrations/api-utils.js";
6
+ const deleteDocumentLocale = createServerFn({
7
+ method: 'POST'
8
+ }).inputValidator((input)=>input).handler(async ({ data: input })=>{
9
+ const { collection: path, id, locale } = input;
10
+ const logger = getLogger();
11
+ const config = await ensureCollection(path);
12
+ if (!config) throw ERR_NOT_FOUND({
13
+ message: 'Collection not found',
14
+ details: {
15
+ collectionPath: path
16
+ }
17
+ }).log(logger);
18
+ const serverConfig = getServerConfig();
19
+ const ctx = {
20
+ db: serverConfig.db,
21
+ definition: config.definition,
22
+ collectionId: config.collection.id,
23
+ collectionVersion: config.collection.version,
24
+ collectionPath: path,
25
+ logger,
26
+ defaultLocale: serverConfig.i18n.content.defaultLocale,
27
+ slugifier: serverConfig.slugifier,
28
+ requestContext: await getAdminRequestContext()
29
+ };
30
+ return deleteLocale(ctx, {
31
+ documentId: id,
32
+ locale
33
+ });
34
+ });
35
+ export { deleteDocumentLocale };
@@ -7,6 +7,7 @@
7
7
  export * from './copy-to-locale';
8
8
  export * from './create';
9
9
  export * from './delete';
10
+ export * from './delete-locale';
10
11
  export * from './duplicate';
11
12
  export * from './get';
12
13
  export * from './history';
@@ -1,6 +1,7 @@
1
1
  export * from "./copy-to-locale.js";
2
2
  export * from "./create.js";
3
3
  export * from "./delete.js";
4
+ export * from "./delete-locale.js";
4
5
  export * from "./duplicate.js";
5
6
  export * from "./get.js";
6
7
  export * from "./history.js";
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "private": false,
4
4
  "type": "module",
5
5
  "license": "MPL-2.0",
6
- "version": "3.0.1",
6
+ "version": "3.0.2",
7
7
  "engines": {
8
8
  "node": ">=20.9.0"
9
9
  },
@@ -115,13 +115,13 @@
115
115
  "react-swipeable": "^7.0.2",
116
116
  "uuid": "^14.0.0",
117
117
  "zod": "^4.4.3",
118
- "@byline/admin": "3.0.1",
119
- "@byline/auth": "3.0.1",
120
- "@byline/core": "3.0.1",
121
- "@byline/ui": "3.0.1",
122
- "@byline/i18n": "3.0.1",
123
- "@byline/client": "3.0.1",
124
- "@byline/ai": "3.0.1"
118
+ "@byline/core": "3.0.2",
119
+ "@byline/auth": "3.0.2",
120
+ "@byline/admin": "3.0.2",
121
+ "@byline/ui": "3.0.2",
122
+ "@byline/ai": "3.0.2",
123
+ "@byline/client": "3.0.2",
124
+ "@byline/i18n": "3.0.2"
125
125
  },
126
126
  "peerDependencies": {
127
127
  "@tanstack/react-router": "^1.167.0",
@@ -18,6 +18,7 @@ import { Container, Section, useToastManager } from '@byline/ui/react'
18
18
  import {
19
19
  copyDocumentToLocale,
20
20
  deleteDocument,
21
+ deleteDocumentLocale,
21
22
  duplicateCollectionDocument,
22
23
  unpublishDocument,
23
24
  updateCollectionDocumentWithPatches,
@@ -291,6 +292,58 @@ export const EditView = ({
291
292
  }
292
293
  }
293
294
 
295
+ const handleDeleteLocale = async ({ targetLocale }: { targetLocale: string }) => {
296
+ try {
297
+ const result = await deleteDocumentLocale({
298
+ data: {
299
+ collection: path,
300
+ id: String(initialData.id),
301
+ locale: targetLocale,
302
+ },
303
+ })
304
+ const targetLabel =
305
+ contentLocales.find((l) => l.code === result.locale)?.label ?? result.locale
306
+ const description = t('collections.edit.deletedLocaleDescription', {
307
+ label: singular,
308
+ locale: targetLabel,
309
+ })
310
+ toastManager.add({
311
+ title: t('collections.edit.deleteLocaleTitle', { label: singular }),
312
+ description,
313
+ data: {
314
+ intent: 'success',
315
+ iconType: 'success',
316
+ icon: true,
317
+ close: true,
318
+ },
319
+ })
320
+ setEditState({ status: 'success', message: description })
321
+ // The deleted locale may be the one being viewed — land on the default
322
+ // locale (which always survives) so the loader re-fetches a valid view.
323
+ navigate({
324
+ to: '/admin/collections/$collection/$id' as never,
325
+ params: { collection: path, id: String(initialData.id) },
326
+ search: { locale: defaultContentLocale },
327
+ })
328
+ } catch (err) {
329
+ console.error('Delete locale error:', err)
330
+ const description = t('collections.edit.deleteLocaleFailedDescription', {
331
+ message: (err as Error).message,
332
+ })
333
+ toastManager.add({
334
+ title: t('collections.edit.deleteLocaleTitle', { label: singular }),
335
+ description,
336
+ data: {
337
+ intent: 'danger',
338
+ iconType: 'danger',
339
+ icon: true,
340
+ close: true,
341
+ },
342
+ })
343
+ setEditState({ status: 'failed', message: description })
344
+ }
345
+ }
346
+
294
347
  const handleDelete = async () => {
295
348
  try {
296
349
  await deleteDocument({ data: { collection: path, id: String(initialData.id) } })
@@ -432,6 +485,7 @@ export const EditView = ({
432
485
  onDelete={handleDelete}
433
486
  onDuplicate={handleDuplicate}
434
487
  onCopyToLocale={handleCopyToLocale}
488
+ onDeleteLocale={handleDeleteLocale}
435
489
  contentLocales={contentLocales}
436
490
  publishedVersion={publishedVersion}
437
491
  restoreWarnings={restoreWarnings}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import { createServerFn } from '@tanstack/react-start'
10
+
11
+ import { ERR_NOT_FOUND, getLogger, getServerConfig } from '@byline/core'
12
+ import type { DeleteLocaleResult, DocumentLifecycleContext } from '@byline/core/services'
13
+ import { deleteLocale } from '@byline/core/services'
14
+
15
+ import { getAdminRequestContext } from '../../auth/auth-context.js'
16
+ import { ensureCollection } from '../../integrations/api-utils.js'
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Delete one content locale's data from a document
20
+ // ---------------------------------------------------------------------------
21
+
22
+ /**
23
+ * Remove a single (non-default) content locale from a document, leaving every
24
+ * other locale untouched. Mirrors the thin-wrapper pattern of the other
25
+ * collection server fns: resolve the request context, build the lifecycle
26
+ * context, delegate to the `deleteLocale` service.
27
+ *
28
+ * `assertActorCanPerform('update')` and the default-locale guard run inside
29
+ * the service; auth and validation failures propagate to TanStack Start's
30
+ * transport layer.
31
+ */
32
+ export const deleteDocumentLocale = createServerFn({ method: 'POST' })
33
+ .inputValidator((input: { collection: string; id: string; locale: string }) => input)
34
+ .handler(async ({ data: input }): Promise<DeleteLocaleResult> => {
35
+ const { collection: path, id, locale } = input
36
+ const logger = getLogger()
37
+ const config = await ensureCollection(path)
38
+ if (!config) {
39
+ throw ERR_NOT_FOUND({
40
+ message: 'Collection not found',
41
+ details: { collectionPath: path },
42
+ }).log(logger)
43
+ }
44
+
45
+ const serverConfig = getServerConfig()
46
+ const ctx: DocumentLifecycleContext = {
47
+ db: serverConfig.db,
48
+ definition: config.definition,
49
+ collectionId: config.collection.id,
50
+ collectionVersion: config.collection.version,
51
+ collectionPath: path,
52
+ logger,
53
+ defaultLocale: serverConfig.i18n.content.defaultLocale,
54
+ slugifier: serverConfig.slugifier,
55
+ requestContext: await getAdminRequestContext(),
56
+ }
57
+
58
+ return deleteLocale(ctx, { documentId: id, locale })
59
+ })
@@ -8,6 +8,7 @@
8
8
  export * from './copy-to-locale'
9
9
  export * from './create'
10
10
  export * from './delete'
11
+ export * from './delete-locale'
11
12
  export * from './duplicate'
12
13
  export * from './get'
13
14
  export * from './history'