@byline/admin 6.6.0 → 6.7.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.
- package/dist/forms/available-locales-widget.d.ts +7 -1
- package/dist/forms/available-locales-widget.js +8 -3
- package/dist/forms/form-context.d.ts +3 -2
- package/dist/forms/form-modals.d.ts +5 -1
- package/dist/forms/form-modals.js +4 -0
- package/dist/forms/form-page-chrome.js +2 -1
- package/package.json +7 -7
- package/src/forms/available-locales-widget.tsx +15 -1
- package/src/forms/form-context.tsx +3 -2
- package/src/forms/form-modals.tsx +12 -1
- package/src/forms/form-page-chrome.tsx +1 -0
- package/src/forms/locale-visibility-copy.test.tsx +180 -0
|
@@ -14,6 +14,12 @@ export interface AvailableLocalesWidgetProps {
|
|
|
14
14
|
* surface supplies it (Slice 6) — in which case every row renders neutral.
|
|
15
15
|
*/
|
|
16
16
|
availableVersionLocales: readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* The document's source language. Its row explains that the source stays
|
|
19
|
+
* available while published whether or not it is checked; the checkbox only
|
|
20
|
+
* controls whether it is advertised.
|
|
21
|
+
*/
|
|
22
|
+
sourceLocale?: string;
|
|
17
23
|
}
|
|
18
24
|
/**
|
|
19
25
|
* System-managed `availableLocales` widget — the editorial "advertise these
|
|
@@ -27,4 +33,4 @@ export interface AvailableLocalesWidgetProps {
|
|
|
27
33
|
* Stable override handles: `.byline-form-available-locales`,
|
|
28
34
|
* `.byline-form-available-locales-list`.
|
|
29
35
|
*/
|
|
30
|
-
export declare const AvailableLocalesWidget: ({ disabled: mutationsBlocked, contentLocales, availableVersionLocales, }: AvailableLocalesWidgetProps) => import("react").JSX.Element | null;
|
|
36
|
+
export declare const AvailableLocalesWidget: ({ disabled: mutationsBlocked, contentLocales, availableVersionLocales, sourceLocale, }: AvailableLocalesWidgetProps) => import("react").JSX.Element | null;
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useMemo } from "react";
|
|
4
4
|
import { useTranslation } from "@byline/i18n/react";
|
|
5
|
-
import { Checkbox, Label } from "@byline/ui/react";
|
|
5
|
+
import { Checkbox, HelpText, Label } from "@byline/ui/react";
|
|
6
6
|
import clsx from "clsx";
|
|
7
7
|
import { reconcileLocaleState } from "./available-locales-reconcile.js";
|
|
8
8
|
import available_locales_widget_module from "./available-locales-widget.module.js";
|
|
9
9
|
import { useFormContext, useSystemAvailableLocales } from "./form-context.js";
|
|
10
|
-
const AvailableLocalesWidget = ({ disabled: mutationsBlocked = false, contentLocales, availableVersionLocales })=>{
|
|
10
|
+
const AvailableLocalesWidget = ({ disabled: mutationsBlocked = false, contentLocales, availableVersionLocales, sourceLocale })=>{
|
|
11
11
|
const { t } = useTranslation('byline-admin');
|
|
12
12
|
const { setSystemAvailableLocales } = useFormContext();
|
|
13
13
|
const advertised = useSystemAvailableLocales();
|
|
@@ -55,10 +55,15 @@ const AvailableLocalesWidget = ({ disabled: mutationsBlocked = false, contentLoc
|
|
|
55
55
|
intent: intent,
|
|
56
56
|
checked: checked,
|
|
57
57
|
disabled: mutationsBlocked || disabled,
|
|
58
|
-
onCheckedChange: (value)=>toggle(code, true === value)
|
|
58
|
+
onCheckedChange: (value)=>toggle(code, true === value),
|
|
59
|
+
helpText: code === sourceLocale ? t('availableLocalesWidget.sourceRowHint') : void 0
|
|
59
60
|
}, code);
|
|
60
61
|
})
|
|
61
62
|
}),
|
|
63
|
+
/*#__PURE__*/ jsx(HelpText, {
|
|
64
|
+
className: "byline-form-available-locales-hint",
|
|
65
|
+
text: t('availableLocalesWidget.hint')
|
|
66
|
+
}),
|
|
62
67
|
/*#__PURE__*/ jsx("span", {
|
|
63
68
|
id: "available-locales-description",
|
|
64
69
|
className: clsx('byline-form-available-locales-sr-only', available_locales_widget_module["sr-only"]),
|
|
@@ -34,8 +34,9 @@ type FieldUploadingListener = (uploading: boolean) => void;
|
|
|
34
34
|
* Why the form is dirty, partitioned by write semantics — drives the single
|
|
35
35
|
* Save button. `content` mints a new version (normal workflow). `direct-write`
|
|
36
36
|
* is an immediate, non-versioned write of the document-grain system fields
|
|
37
|
-
* (path / advertised locales) that does NOT reset workflow status. `both`
|
|
38
|
-
*
|
|
37
|
+
* (path / advertised locales) that does NOT reset workflow status. `both`
|
|
38
|
+
* saves the two together: one request, one guarded transaction, so both commit
|
|
39
|
+
* or neither does. See docs/08-internationalization/03-content-locales.md.
|
|
39
40
|
*/
|
|
40
41
|
export type DirtyReason = 'none' | 'content' | 'direct-write' | 'both';
|
|
41
42
|
export interface DirtyBreakdown {
|
|
@@ -10,7 +10,11 @@ export declare const UnsavedChangesModal: ({ onClose }: {
|
|
|
10
10
|
* Confirms an immediate, non-versioned write of the document-grain system
|
|
11
11
|
* fields (path / advertised locales) — which does NOT reset workflow status.
|
|
12
12
|
* When content is also dirty, the copy reassures that content edits still
|
|
13
|
-
* follow the normal revision + publish workflow
|
|
13
|
+
* follow the normal revision + publish workflow, and, for a locale change,
|
|
14
|
+
* explains that locale and content changes commit together (one guarded
|
|
15
|
+
* transaction, so a failed save applies neither), that an already-published
|
|
16
|
+
* checked translation becomes public once saved, and that a draft-only
|
|
17
|
+
* translation stays withheld until it is published. See docs/08-internationalization/index.md.
|
|
14
18
|
*/
|
|
15
19
|
export declare const SystemFieldsConfirmModal: ({ contentDirty, pathDirty, availableLocalesDirty, onCancel, onConfirm, }: {
|
|
16
20
|
contentDirty: boolean;
|
|
@@ -81,6 +81,10 @@ const SystemFieldsConfirmModal = ({ contentDirty, pathDirty, availableLocalesDir
|
|
|
81
81
|
className: clsx('byline-form-system-fields-content-note', 'm-0 mt-2'),
|
|
82
82
|
children: t('forms.systemFieldsConfirm.contentNote')
|
|
83
83
|
}),
|
|
84
|
+
contentDirty && availableLocalesDirty && /*#__PURE__*/ jsx("p", {
|
|
85
|
+
className: clsx('byline-form-system-fields-locales-note', 'm-0 mt-2'),
|
|
86
|
+
children: t('forms.systemFieldsConfirm.localesContentNote')
|
|
87
|
+
}),
|
|
84
88
|
/*#__PURE__*/ jsx("p", {
|
|
85
89
|
className: "m-0 mt-2",
|
|
86
90
|
style: contentDirty ? {
|
|
@@ -236,7 +236,8 @@ const FormSidebarWidgets = ({ disabled, mode, initialData, collectionPath, defau
|
|
|
236
236
|
advertiseLocales && /*#__PURE__*/ jsx(AvailableLocalesWidget, {
|
|
237
237
|
disabled: disabled,
|
|
238
238
|
contentLocales: contentLocales ?? [],
|
|
239
|
-
availableVersionLocales: initialData?._availableVersionLocales ?? []
|
|
239
|
+
availableVersionLocales: initialData?._availableVersionLocales ?? [],
|
|
240
|
+
sourceLocale: initialData?.sourceLocale ?? defaultLocale
|
|
240
241
|
})
|
|
241
242
|
]
|
|
242
243
|
});
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/admin",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "6.
|
|
5
|
+
"version": "6.7.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -183,12 +183,12 @@
|
|
|
183
183
|
"react-diff-viewer-continued": "^4.4.0",
|
|
184
184
|
"uuid": "^14.0.2",
|
|
185
185
|
"zod": "^4.6.5",
|
|
186
|
-
"@byline/analytics": "6.
|
|
187
|
-
"@byline/
|
|
188
|
-
"@byline/
|
|
189
|
-
"@byline/
|
|
190
|
-
"@byline/
|
|
191
|
-
"@byline/
|
|
186
|
+
"@byline/analytics-agent": "6.7.0",
|
|
187
|
+
"@byline/core": "6.7.0",
|
|
188
|
+
"@byline/i18n": "6.7.0",
|
|
189
|
+
"@byline/analytics": "6.7.0",
|
|
190
|
+
"@byline/ui": "6.7.0",
|
|
191
|
+
"@byline/auth": "6.7.0"
|
|
192
192
|
},
|
|
193
193
|
"peerDependencies": {
|
|
194
194
|
"react": "^19.0.0",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { useCallback, useMemo } from 'react'
|
|
12
12
|
|
|
13
13
|
import { useTranslation } from '@byline/i18n/react'
|
|
14
|
-
import { Checkbox, Label } from '@byline/ui/react'
|
|
14
|
+
import { Checkbox, HelpText, Label } from '@byline/ui/react'
|
|
15
15
|
import cx from 'clsx'
|
|
16
16
|
|
|
17
17
|
import { reconcileLocaleState } from './available-locales-reconcile'
|
|
@@ -36,6 +36,12 @@ export interface AvailableLocalesWidgetProps {
|
|
|
36
36
|
* surface supplies it (Slice 6) — in which case every row renders neutral.
|
|
37
37
|
*/
|
|
38
38
|
availableVersionLocales: readonly string[]
|
|
39
|
+
/**
|
|
40
|
+
* The document's source language. Its row explains that the source stays
|
|
41
|
+
* available while published whether or not it is checked; the checkbox only
|
|
42
|
+
* controls whether it is advertised.
|
|
43
|
+
*/
|
|
44
|
+
sourceLocale?: string
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
/**
|
|
@@ -54,6 +60,7 @@ export const AvailableLocalesWidget = ({
|
|
|
54
60
|
disabled: mutationsBlocked = false,
|
|
55
61
|
contentLocales,
|
|
56
62
|
availableVersionLocales,
|
|
63
|
+
sourceLocale,
|
|
57
64
|
}: AvailableLocalesWidgetProps) => {
|
|
58
65
|
const { t } = useTranslation('byline-admin')
|
|
59
66
|
const { setSystemAvailableLocales } = useFormContext()
|
|
@@ -107,10 +114,17 @@ export const AvailableLocalesWidget = ({
|
|
|
107
114
|
checked={checked}
|
|
108
115
|
disabled={mutationsBlocked || disabled}
|
|
109
116
|
onCheckedChange={(value) => toggle(code, value === true)}
|
|
117
|
+
helpText={
|
|
118
|
+
code === sourceLocale ? t('availableLocalesWidget.sourceRowHint') : undefined
|
|
119
|
+
}
|
|
110
120
|
/>
|
|
111
121
|
)
|
|
112
122
|
})}
|
|
113
123
|
</div>
|
|
124
|
+
<HelpText
|
|
125
|
+
className="byline-form-available-locales-hint"
|
|
126
|
+
text={t('availableLocalesWidget.hint')}
|
|
127
|
+
/>
|
|
114
128
|
<span
|
|
115
129
|
id="available-locales-description"
|
|
116
130
|
className={cx('byline-form-available-locales-sr-only', styles['sr-only'])}
|
|
@@ -73,8 +73,9 @@ const sameLocaleSet = (a: string[], b: string[]): boolean => {
|
|
|
73
73
|
* Why the form is dirty, partitioned by write semantics — drives the single
|
|
74
74
|
* Save button. `content` mints a new version (normal workflow). `direct-write`
|
|
75
75
|
* is an immediate, non-versioned write of the document-grain system fields
|
|
76
|
-
* (path / advertised locales) that does NOT reset workflow status. `both`
|
|
77
|
-
*
|
|
76
|
+
* (path / advertised locales) that does NOT reset workflow status. `both`
|
|
77
|
+
* saves the two together: one request, one guarded transaction, so both commit
|
|
78
|
+
* or neither does. See docs/08-internationalization/03-content-locales.md.
|
|
78
79
|
*/
|
|
79
80
|
export type DirtyReason = 'none' | 'content' | 'direct-write' | 'both'
|
|
80
81
|
|
|
@@ -54,7 +54,11 @@ export const UnsavedChangesModal = ({ onClose }: { onClose: () => void }) => {
|
|
|
54
54
|
* Confirms an immediate, non-versioned write of the document-grain system
|
|
55
55
|
* fields (path / advertised locales) — which does NOT reset workflow status.
|
|
56
56
|
* When content is also dirty, the copy reassures that content edits still
|
|
57
|
-
* follow the normal revision + publish workflow
|
|
57
|
+
* follow the normal revision + publish workflow, and, for a locale change,
|
|
58
|
+
* explains that locale and content changes commit together (one guarded
|
|
59
|
+
* transaction, so a failed save applies neither), that an already-published
|
|
60
|
+
* checked translation becomes public once saved, and that a draft-only
|
|
61
|
+
* translation stays withheld until it is published. See docs/08-internationalization/index.md.
|
|
58
62
|
*/
|
|
59
63
|
export const SystemFieldsConfirmModal = ({
|
|
60
64
|
contentDirty,
|
|
@@ -92,6 +96,13 @@ export const SystemFieldsConfirmModal = ({
|
|
|
92
96
|
{t('forms.systemFieldsConfirm.contentNote')}
|
|
93
97
|
</p>
|
|
94
98
|
)}
|
|
99
|
+
{/* Locale and content changes commit together. Say what the locale
|
|
100
|
+
change does to public delivery once the save succeeds. */}
|
|
101
|
+
{contentDirty && availableLocalesDirty && (
|
|
102
|
+
<p className={cx('byline-form-system-fields-locales-note', 'm-0 mt-2')}>
|
|
103
|
+
{t('forms.systemFieldsConfirm.localesContentNote')}
|
|
104
|
+
</p>
|
|
105
|
+
)}
|
|
95
106
|
<p
|
|
96
107
|
className="m-0 mt-2"
|
|
97
108
|
style={
|
|
@@ -437,6 +437,7 @@ export const FormSidebarWidgets = ({
|
|
|
437
437
|
availableVersionLocales={
|
|
438
438
|
(initialData?._availableVersionLocales as string[] | undefined) ?? []
|
|
439
439
|
}
|
|
440
|
+
sourceLocale={(initialData?.sourceLocale as string | undefined) ?? defaultLocale}
|
|
440
441
|
/>
|
|
441
442
|
)}
|
|
442
443
|
</>
|
|
@@ -0,0 +1,180 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* The advertised-locales widget and the immediate-save confirmation explain
|
|
11
|
+
* what a checkbox does to public delivery. Rendered with the real English
|
|
12
|
+
* admin bundle, so a renamed or deleted key fails here rather than showing a
|
|
13
|
+
* raw key to an editor.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { act, type ReactNode } from 'react'
|
|
17
|
+
|
|
18
|
+
import { adminTranslations } from '@byline/i18n/admin'
|
|
19
|
+
import { I18nProvider } from '@byline/i18n/react'
|
|
20
|
+
import { createRoot, type Root } from 'react-dom/client'
|
|
21
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
22
|
+
|
|
23
|
+
vi.mock('@byline/ui/react', () => {
|
|
24
|
+
const Modal = ({ children }: { children?: ReactNode }) => <div>{children}</div>
|
|
25
|
+
const Part = ({ children }: { children?: ReactNode }) => <div>{children}</div>
|
|
26
|
+
Modal.Container = Part
|
|
27
|
+
Modal.Header = Part
|
|
28
|
+
Modal.Content = Part
|
|
29
|
+
Modal.Actions = Part
|
|
30
|
+
return {
|
|
31
|
+
Label: ({ label }: { label?: string }) => <span>{label}</span>,
|
|
32
|
+
HelpText: ({ text }: { text: string }) => <p data-testid="group-hint">{text}</p>,
|
|
33
|
+
Checkbox: ({ id, label, helpText }: { id: string; label: string; helpText?: string }) => (
|
|
34
|
+
<div data-testid={id}>
|
|
35
|
+
<span>{label}</span>
|
|
36
|
+
{helpText ? <span data-testid={`${id}-hint`}>{helpText}</span> : null}
|
|
37
|
+
</div>
|
|
38
|
+
),
|
|
39
|
+
Modal,
|
|
40
|
+
Button: ({ children }: { children?: ReactNode }) => <button type="button">{children}</button>,
|
|
41
|
+
IconButton: ({ children }: { children?: ReactNode }) => (
|
|
42
|
+
<button type="button">{children}</button>
|
|
43
|
+
),
|
|
44
|
+
CloseIcon: () => null,
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
vi.mock('./form-context', () => ({
|
|
49
|
+
useFormContext: () => ({ setSystemAvailableLocales: vi.fn() }),
|
|
50
|
+
useSystemAvailableLocales: () => ['en'],
|
|
51
|
+
}))
|
|
52
|
+
|
|
53
|
+
import { AvailableLocalesWidget } from './available-locales-widget'
|
|
54
|
+
import { SystemFieldsConfirmModal } from './form-modals'
|
|
55
|
+
|
|
56
|
+
;(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true
|
|
57
|
+
|
|
58
|
+
const en: Record<string, string> = adminTranslations({ locales: ['en'] }).en?.['byline-admin'] ?? {}
|
|
59
|
+
|
|
60
|
+
describe('locale visibility copy', () => {
|
|
61
|
+
let container: HTMLDivElement
|
|
62
|
+
let root: Root
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
container = document.createElement('div')
|
|
66
|
+
document.body.appendChild(container)
|
|
67
|
+
root = createRoot(container)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
act(() => {
|
|
72
|
+
root.unmount()
|
|
73
|
+
})
|
|
74
|
+
container.remove()
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const render = (node: ReactNode) => {
|
|
78
|
+
act(() => {
|
|
79
|
+
root.render(
|
|
80
|
+
<I18nProvider
|
|
81
|
+
bundle={adminTranslations({ locales: ['en'] })}
|
|
82
|
+
activeLocale="en"
|
|
83
|
+
defaultLocale="en"
|
|
84
|
+
localeDefinitions={[{ code: 'en', nativeName: 'English' }]}
|
|
85
|
+
>
|
|
86
|
+
{node}
|
|
87
|
+
</I18nProvider>
|
|
88
|
+
)
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const text = (testId: string) =>
|
|
93
|
+
container.querySelector(`[data-testid="${testId}"]`)?.textContent ?? null
|
|
94
|
+
|
|
95
|
+
it('explains source availability on the source row only, and delivery for the group', () => {
|
|
96
|
+
render(
|
|
97
|
+
<AvailableLocalesWidget
|
|
98
|
+
contentLocales={[
|
|
99
|
+
{ code: 'en', label: 'English' },
|
|
100
|
+
{ code: 'es', label: 'Español' },
|
|
101
|
+
]}
|
|
102
|
+
availableVersionLocales={['en', 'es']}
|
|
103
|
+
sourceLocale="en"
|
|
104
|
+
/>
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
expect(text('available-locale-en-hint')).toBe(en['availableLocalesWidget.sourceRowHint'])
|
|
108
|
+
expect(text('available-locale-en-hint')).toContain('available while published')
|
|
109
|
+
expect(text('available-locale-es-hint')).toBeNull()
|
|
110
|
+
expect(text('group-hint')).toBe(en['availableLocalesWidget.hint'])
|
|
111
|
+
expect(text('group-hint')).toContain('unpublished draft')
|
|
112
|
+
expect(container.textContent).toContain('whether or not it is checked')
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('moves the source note with the document source language', () => {
|
|
116
|
+
render(
|
|
117
|
+
<AvailableLocalesWidget
|
|
118
|
+
contentLocales={[
|
|
119
|
+
{ code: 'en', label: 'English' },
|
|
120
|
+
{ code: 'es', label: 'Español' },
|
|
121
|
+
]}
|
|
122
|
+
availableVersionLocales={['en', 'es']}
|
|
123
|
+
sourceLocale="es"
|
|
124
|
+
/>
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
expect(text('available-locale-es-hint')).toBe(en['availableLocalesWidget.sourceRowHint'])
|
|
128
|
+
expect(text('available-locale-en-hint')).toBeNull()
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('explains immediate public delivery for a locale-only save', () => {
|
|
132
|
+
render(
|
|
133
|
+
<SystemFieldsConfirmModal
|
|
134
|
+
contentDirty={false}
|
|
135
|
+
pathDirty={false}
|
|
136
|
+
availableLocalesDirty={true}
|
|
137
|
+
onCancel={() => {}}
|
|
138
|
+
onConfirm={() => {}}
|
|
139
|
+
/>
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
expect(container.textContent).toContain(en['forms.systemFieldsConfirm.bulletLocales'])
|
|
143
|
+
expect(container.textContent).toContain('appears on the public site straight away')
|
|
144
|
+
expect(container.textContent).not.toContain(en['forms.systemFieldsConfirm.localesContentNote'])
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('explains the save order when locale and content changes are saved together', () => {
|
|
148
|
+
render(
|
|
149
|
+
<SystemFieldsConfirmModal
|
|
150
|
+
contentDirty={true}
|
|
151
|
+
pathDirty={false}
|
|
152
|
+
availableLocalesDirty={true}
|
|
153
|
+
onCancel={() => {}}
|
|
154
|
+
onConfirm={() => {}}
|
|
155
|
+
/>
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
const note = en['forms.systemFieldsConfirm.localesContentNote']
|
|
159
|
+
expect(container.textContent).toContain(note)
|
|
160
|
+
// The combined save is one guarded commit: a failed save applies neither.
|
|
161
|
+
expect(note).toContain('saved together')
|
|
162
|
+
expect(note).toContain('neither is applied')
|
|
163
|
+
expect(note).toContain('stays hidden until it is published')
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('adds no locale note to a combined path and content save', () => {
|
|
167
|
+
render(
|
|
168
|
+
<SystemFieldsConfirmModal
|
|
169
|
+
contentDirty={true}
|
|
170
|
+
pathDirty={true}
|
|
171
|
+
availableLocalesDirty={false}
|
|
172
|
+
onCancel={() => {}}
|
|
173
|
+
onConfirm={() => {}}
|
|
174
|
+
/>
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
expect(container.textContent).not.toContain(en['forms.systemFieldsConfirm.localesContentNote'])
|
|
178
|
+
expect(container.textContent).not.toContain(en['forms.systemFieldsConfirm.bulletLocales'])
|
|
179
|
+
})
|
|
180
|
+
})
|