payload-intl 1.2.2 → 1.2.3

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 (163) hide show
  1. package/dist/components/MessageFormField.d.ts +15 -0
  2. package/dist/components/MessageFormField.d.ts.map +1 -0
  3. package/dist/components/{MessageController.js → MessageFormField.js} +5 -3
  4. package/dist/components/MessageFormField.js.map +1 -0
  5. package/dist/components/MessagesForm.d.ts +3 -1
  6. package/dist/components/MessagesForm.d.ts.map +1 -1
  7. package/dist/components/MessagesForm.js +25 -36
  8. package/dist/components/MessagesForm.js.map +1 -1
  9. package/dist/components/{MessageFormContext.d.ts → MessagesFormProvider.d.ts} +6 -2
  10. package/dist/components/MessagesFormProvider.d.ts.map +1 -0
  11. package/dist/components/{MessageFormContext.js → MessagesFormProvider.js} +8 -4
  12. package/dist/components/MessagesFormProvider.js.map +1 -0
  13. package/dist/components/MessagesLink.js +5 -2
  14. package/dist/components/MessagesLink.js.map +1 -1
  15. package/dist/components/MessagesView.d.ts +1 -1
  16. package/dist/components/MessagesView.d.ts.map +1 -1
  17. package/dist/components/MessagesView.js +13 -4
  18. package/dist/components/MessagesView.js.map +1 -1
  19. package/dist/components/actions/CopyMessages.d.ts +2 -0
  20. package/dist/components/actions/CopyMessages.d.ts.map +1 -0
  21. package/dist/components/actions/{Move.js → CopyMessages.js} +6 -6
  22. package/dist/components/actions/CopyMessages.js.map +1 -0
  23. package/dist/components/actions/JsonImport.d.ts +4 -1
  24. package/dist/components/actions/JsonImport.d.ts.map +1 -1
  25. package/dist/components/actions/JsonImport.js +7 -25
  26. package/dist/components/actions/JsonImport.js.map +1 -1
  27. package/dist/components/hooks/useHtmlLexicalAdapter.d.ts +12 -0
  28. package/dist/components/hooks/useHtmlLexicalAdapter.d.ts.map +1 -0
  29. package/dist/components/hooks/useHtmlLexicalAdapter.js +63 -0
  30. package/dist/components/hooks/useHtmlLexicalAdapter.js.map +1 -0
  31. package/dist/components/hooks/useMessagesFormSubmit.d.ts +11 -0
  32. package/dist/components/hooks/useMessagesFormSubmit.d.ts.map +1 -0
  33. package/dist/components/hooks/useMessagesFormSubmit.js +44 -0
  34. package/dist/components/hooks/useMessagesFormSubmit.js.map +1 -0
  35. package/dist/components/inputs/FieldWrapper.d.ts +9 -0
  36. package/dist/components/inputs/FieldWrapper.d.ts.map +1 -0
  37. package/dist/components/inputs/FieldWrapper.js +24 -0
  38. package/dist/components/inputs/FieldWrapper.js.map +1 -0
  39. package/dist/components/inputs/{InputWrapper.module.css → FieldWrapper.module.css} +2 -12
  40. package/dist/components/inputs/LexicalInput.d.ts +2 -13
  41. package/dist/components/inputs/LexicalInput.d.ts.map +1 -1
  42. package/dist/components/inputs/LexicalInput.js +4 -63
  43. package/dist/components/inputs/LexicalInput.js.map +1 -1
  44. package/dist/components/inputs/MessageInput.d.ts +6 -3
  45. package/dist/components/inputs/MessageInput.d.ts.map +1 -1
  46. package/dist/components/inputs/MessageInput.js +47 -43
  47. package/dist/components/inputs/MessageInput.js.map +1 -1
  48. package/dist/components/inputs/MessageInput.module.css +23 -4
  49. package/dist/components/inputs/ReferencePopover.d.ts +7 -0
  50. package/dist/components/inputs/ReferencePopover.d.ts.map +1 -0
  51. package/dist/components/inputs/ReferencePopover.js +42 -0
  52. package/dist/components/inputs/ReferencePopover.js.map +1 -0
  53. package/dist/components/inputs/ReferencePopover.module.css +70 -0
  54. package/dist/components/inputs/SingleLinePlugin.d.ts +2 -0
  55. package/dist/components/inputs/SingleLinePlugin.d.ts.map +1 -0
  56. package/dist/components/inputs/SingleLinePlugin.js +24 -0
  57. package/dist/components/inputs/SingleLinePlugin.js.map +1 -0
  58. package/dist/components/inputs/variables/VariableChip.d.ts.map +1 -1
  59. package/dist/components/inputs/variables/VariableChip.js +31 -32
  60. package/dist/components/inputs/variables/VariableChip.js.map +1 -1
  61. package/dist/components/inputs/variables/VariableChip.module.css +3 -3
  62. package/dist/components/inputs/variables/VariableSuggestion.d.ts +4 -0
  63. package/dist/components/inputs/variables/VariableSuggestion.d.ts.map +1 -0
  64. package/dist/components/inputs/variables/VariableSuggestion.js +24 -0
  65. package/dist/components/inputs/variables/VariableSuggestion.js.map +1 -0
  66. package/dist/components/inputs/variables/editors/PluralVariableEditor.d.ts.map +1 -1
  67. package/dist/components/inputs/variables/editors/PluralVariableEditor.js +62 -60
  68. package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +1 -1
  69. package/dist/components/inputs/variables/editors/PluralVariableEditor.module.css +4 -4
  70. package/dist/components/inputs/variables/editors/TemporalVariableEditor.d.ts +11 -0
  71. package/dist/components/inputs/variables/editors/TemporalVariableEditor.d.ts.map +1 -0
  72. package/dist/components/inputs/variables/editors/{DateVariableEditor.js → TemporalVariableEditor.js} +3 -3
  73. package/dist/components/inputs/variables/editors/TemporalVariableEditor.js.map +1 -0
  74. package/dist/components/inputs/variables/pickers/NumericVariableEditor.d.ts +7 -0
  75. package/dist/components/inputs/variables/pickers/{NumericVariablePicker.d.ts.map → NumericVariableEditor.d.ts.map} +1 -1
  76. package/dist/components/inputs/variables/pickers/{NumericVariablePicker.js → NumericVariableEditor.js} +15 -9
  77. package/dist/components/inputs/variables/pickers/NumericVariableEditor.js.map +1 -0
  78. package/dist/components/inputs/variables/pickers/{NumericVariablePicker.module.css → NumericVariableEditor.module.css} +3 -3
  79. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.d.ts +7 -0
  80. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.d.ts.map +1 -0
  81. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.js +57 -0
  82. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.js.map +1 -0
  83. package/dist/components/inputs/variables/pickers/{TemporalElementEditor.module.css → TemporalVariablePicker.module.css} +3 -3
  84. package/dist/components/layout/GroupStatusDot.d.ts +6 -0
  85. package/dist/components/layout/GroupStatusDot.d.ts.map +1 -0
  86. package/dist/components/layout/GroupStatusDot.js +24 -0
  87. package/dist/components/layout/GroupStatusDot.js.map +1 -0
  88. package/dist/components/layout/MessageField.d.ts +2 -1
  89. package/dist/components/layout/MessageField.d.ts.map +1 -1
  90. package/dist/components/layout/MessageField.js +52 -33
  91. package/dist/components/layout/MessageField.js.map +1 -1
  92. package/dist/components/layout/MessageField.module.css +21 -10
  93. package/dist/components/layout/MessagesTabs.d.ts.map +1 -1
  94. package/dist/components/layout/MessagesTabs.js +3 -5
  95. package/dist/components/layout/MessagesTabs.js.map +1 -1
  96. package/dist/components/layout/MessagesTree.d.ts +1 -1
  97. package/dist/components/layout/MessagesTree.d.ts.map +1 -1
  98. package/dist/components/layout/MessagesTree.js +33 -43
  99. package/dist/components/layout/MessagesTree.js.map +1 -1
  100. package/dist/components/layout/MessagesTree.module.css +10 -5
  101. package/dist/components/layout/StatusDot.d.ts +7 -0
  102. package/dist/components/layout/StatusDot.d.ts.map +1 -0
  103. package/dist/components/layout/StatusDot.js +12 -0
  104. package/dist/components/layout/StatusDot.js.map +1 -0
  105. package/dist/components/layout/StatusDot.module.css +16 -0
  106. package/dist/const.d.ts +2 -2
  107. package/dist/const.js +1 -1
  108. package/dist/entities.js +1 -1
  109. package/dist/internals/index.d.ts.map +1 -0
  110. package/dist/internals/index.js.map +1 -0
  111. package/dist/internals/procedure.d.ts.map +1 -0
  112. package/dist/internals/procedure.js.map +1 -0
  113. package/dist/internals/urls.d.ts.map +1 -0
  114. package/dist/internals/urls.js.map +1 -0
  115. package/dist/internals/utils.d.ts.map +1 -0
  116. package/dist/internals/utils.js.map +1 -0
  117. package/dist/utils/sanitize.d.ts +7 -6
  118. package/dist/utils/sanitize.d.ts.map +1 -1
  119. package/dist/utils/sanitize.js +11 -8
  120. package/dist/utils/sanitize.js.map +1 -1
  121. package/package.json +4 -3
  122. package/dist/_common/index.d.ts.map +0 -1
  123. package/dist/_common/index.js.map +0 -1
  124. package/dist/_common/procedure.d.ts.map +0 -1
  125. package/dist/_common/procedure.js.map +0 -1
  126. package/dist/_common/urls.d.ts.map +0 -1
  127. package/dist/_common/urls.js.map +0 -1
  128. package/dist/_common/utils.d.ts.map +0 -1
  129. package/dist/_common/utils.js.map +0 -1
  130. package/dist/components/MessageController.d.ts +0 -13
  131. package/dist/components/MessageController.d.ts.map +0 -1
  132. package/dist/components/MessageController.js.map +0 -1
  133. package/dist/components/MessageFormContext.d.ts.map +0 -1
  134. package/dist/components/MessageFormContext.js.map +0 -1
  135. package/dist/components/actions/Move.d.ts +0 -2
  136. package/dist/components/actions/Move.d.ts.map +0 -1
  137. package/dist/components/actions/Move.js.map +0 -1
  138. package/dist/components/inputs/InputWrapper.d.ts +0 -8
  139. package/dist/components/inputs/InputWrapper.d.ts.map +0 -1
  140. package/dist/components/inputs/InputWrapper.js +0 -34
  141. package/dist/components/inputs/InputWrapper.js.map +0 -1
  142. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts +0 -10
  143. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts.map +0 -1
  144. package/dist/components/inputs/variables/editors/DateVariableEditor.js.map +0 -1
  145. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts +0 -10
  146. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts.map +0 -1
  147. package/dist/components/inputs/variables/editors/TimeVariableEditor.js +0 -15
  148. package/dist/components/inputs/variables/editors/TimeVariableEditor.js.map +0 -1
  149. package/dist/components/inputs/variables/pickers/NumericVariablePicker.d.ts +0 -7
  150. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js.map +0 -1
  151. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts +0 -7
  152. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts.map +0 -1
  153. package/dist/components/inputs/variables/pickers/TemporalElementEditor.js +0 -58
  154. package/dist/components/inputs/variables/pickers/TemporalElementEditor.js.map +0 -1
  155. /package/dist/components/actions/{Move.module.css → CopyMessages.module.css} +0 -0
  156. /package/dist/{_common → internals}/index.d.ts +0 -0
  157. /package/dist/{_common → internals}/index.js +0 -0
  158. /package/dist/{_common → internals}/procedure.d.ts +0 -0
  159. /package/dist/{_common → internals}/procedure.js +0 -0
  160. /package/dist/{_common → internals}/urls.d.ts +0 -0
  161. /package/dist/{_common → internals}/urls.js +0 -0
  162. /package/dist/{_common → internals}/utils.d.ts +0 -0
  163. /package/dist/{_common → internals}/utils.js +0 -0
@@ -0,0 +1,15 @@
1
+ import type { Locale, TemplateVariable } from '../types';
2
+ import type { MessageValidator } from '../utils/validate';
3
+ interface MessageFormFieldProps {
4
+ label?: string;
5
+ locale: Locale;
6
+ name: string;
7
+ className?: string;
8
+ variables: TemplateVariable[];
9
+ validate: MessageValidator;
10
+ multiline?: boolean;
11
+ reference?: string;
12
+ }
13
+ export declare function MessageFormField({ name, variables, label, locale, validate, className, multiline, reference, }: MessageFormFieldProps): React.ReactNode;
14
+ export {};
15
+ //# sourceMappingURL=MessageFormField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageFormField.d.ts","sourceRoot":"","sources":["../../src/components/MessageFormField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzD,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,GACV,EAAE,qBAAqB,GAAG,KAAK,CAAC,SAAS,CA2BzC"}
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Controller } from 'react-hook-form';
3
- import { useMessagesForm } from '../components/MessageFormContext';
3
+ import { useMessagesForm } from '../components/MessagesFormProvider';
4
4
  import { MessageInput } from './inputs/MessageInput';
5
- export function MessageController({ name, variables, label, locale, validate, className }) {
5
+ export function MessageFormField({ name, variables, label, locale, validate, className, multiline, reference }) {
6
6
  const { control } = useMessagesForm();
7
7
  return /*#__PURE__*/ _jsx(Controller, {
8
8
  control: control,
@@ -12,8 +12,10 @@ export function MessageController({ name, variables, label, locale, validate, cl
12
12
  error: fieldState.error,
13
13
  label: label,
14
14
  lang: locale,
15
+ multiline: multiline,
15
16
  onBlur: field.onBlur,
16
17
  onChange: field.onChange,
18
+ reference: reference,
17
19
  value: field.value || '',
18
20
  variables: variables
19
21
  }),
@@ -24,4 +26,4 @@ export function MessageController({ name, variables, label, locale, validate, cl
24
26
  });
25
27
  }
26
28
 
27
- //# sourceMappingURL=MessageController.js.map
29
+ //# sourceMappingURL=MessageFormField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/MessageFormField.tsx"],"sourcesContent":["import { Controller } from 'react-hook-form';\nimport { useMessagesForm } from '@/components/MessagesFormProvider';\nimport type { Locale, TemplateVariable } from '@/types';\nimport type { MessageValidator } from '@/utils/validate';\n\nimport { MessageInput } from './inputs/MessageInput';\n\ninterface MessageFormFieldProps {\n label?: string;\n locale: Locale;\n name: string;\n className?: string;\n variables: TemplateVariable[];\n validate: MessageValidator;\n multiline?: boolean;\n reference?: string;\n}\n\nexport function MessageFormField({\n name,\n variables,\n label,\n locale,\n validate,\n className,\n multiline,\n reference,\n}: MessageFormFieldProps): React.ReactNode {\n const { control } = useMessagesForm();\n\n return (\n <Controller\n control={control}\n name={name}\n render={({ field, fieldState }) => (\n <MessageInput\n className={className}\n error={fieldState.error}\n label={label}\n lang={locale}\n multiline={multiline}\n onBlur={field.onBlur}\n onChange={field.onChange}\n reference={reference}\n value={(field.value as unknown as string) || ''}\n variables={variables}\n />\n )}\n rules={{\n required: true,\n validate,\n }}\n />\n );\n}\n"],"names":["Controller","useMessagesForm","MessageInput","MessageFormField","name","variables","label","locale","validate","className","multiline","reference","control","render","field","fieldState","error","lang","onBlur","onChange","value","rules","required"],"mappings":";AAAA,SAASA,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,eAAe,QAAQ,oCAAoC;AAIpE,SAASC,YAAY,QAAQ,wBAAwB;AAarD,OAAO,SAASC,iBAAiB,EAC/BC,IAAI,EACJC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,QAAQ,EACRC,SAAS,EACTC,SAAS,EACTC,SAAS,EACa;IACtB,MAAM,EAAEC,OAAO,EAAE,GAAGX;IAEpB,qBACE,KAACD;QACCY,SAASA;QACTR,MAAMA;QACNS,QAAQ,CAAC,EAAEC,KAAK,EAAEC,UAAU,EAAE,iBAC5B,KAACb;gBACCO,WAAWA;gBACXO,OAAOD,WAAWC,KAAK;gBACvBV,OAAOA;gBACPW,MAAMV;gBACNG,WAAWA;gBACXQ,QAAQJ,MAAMI,MAAM;gBACpBC,UAAUL,MAAMK,QAAQ;gBACxBR,WAAWA;gBACXS,OAAO,AAACN,MAAMM,KAAK,IAA0B;gBAC7Cf,WAAWA;;QAGfgB,OAAO;YACLC,UAAU;YACVd;QACF;;AAGN"}
@@ -1,11 +1,13 @@
1
1
  import type { DeepPartial, Locale, Messages, MessagesSchema, Translations } from '../types';
2
2
  interface MessagesFormProps {
3
3
  locales: Locale[];
4
+ defaultLocale: Locale;
5
+ activeLocale: Locale;
4
6
  schema: MessagesSchema;
5
7
  tabs?: boolean;
6
8
  values: Translations<DeepPartial<Messages>>;
7
9
  endpointUrl: string;
8
10
  }
9
- export declare function MessagesForm({ locales, schema, tabs, values, endpointUrl, }: MessagesFormProps): React.ReactNode;
11
+ export declare function MessagesForm({ locales, defaultLocale, activeLocale, schema, tabs, values, endpointUrl, }: MessagesFormProps): React.ReactNode;
10
12
  export {};
11
13
  //# sourceMappingURL=MessagesForm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessagesForm.d.ts","sourceRoot":"","sources":["../../src/components/MessagesForm.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,QAAQ,EACR,cAAc,EACd,YAAY,EACb,MAAM,SAAS,CAAC;AAQjB,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,MAAM,EACN,IAAY,EACZ,MAAM,EACN,WAAW,GACZ,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAuGrC"}
1
+ {"version":3,"file":"MessagesForm.d.ts","sourceRoot":"","sources":["../../src/components/MessagesForm.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,QAAQ,EACR,cAAc,EACd,YAAY,EACb,MAAM,SAAS,CAAC;AAQjB,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,aAAa,EACb,YAAY,EACZ,MAAM,EACN,IAAY,EACZ,MAAM,EACN,WAAW,GACZ,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAyFrC"}
@@ -1,17 +1,16 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Button, toast, useStepNav } from '@payloadcms/ui';
4
- import { isEqual } from 'lodash-es';
3
+ import { Button, useStepNav } from '@payloadcms/ui';
5
4
  import { useEffect, useState } from 'react';
6
5
  import { useForm } from 'react-hook-form';
7
- import { MessagesFormProvider } from '../components/MessageFormContext';
8
- import { getErrorMessage } from '../utils/error-handling';
6
+ import { MessagesFormProvider } from '../components/MessagesFormProvider';
9
7
  import { JsonImport } from './actions/JsonImport';
8
+ import { useMessagesFormSubmit } from './hooks/useMessagesFormSubmit';
10
9
  import { MessageField } from './layout/MessageField';
11
10
  import { MessagesTabs } from './layout/MessagesTabs';
12
11
  import { MessagesTree } from './layout/MessagesTree';
13
12
  import styles from './MessagesForm.module.css';
14
- export function MessagesForm({ locales, schema, tabs = false, values, endpointUrl }) {
13
+ export function MessagesForm({ locales, defaultLocale, activeLocale, schema, tabs = false, values, endpointUrl }) {
15
14
  const { setStepNav } = useStepNav();
16
15
  useEffect(()=>{
17
16
  setStepNav([
@@ -25,40 +24,28 @@ export function MessagesForm({ locales, schema, tabs = false, values, endpointUr
25
24
  ]);
26
25
  const form = useForm({
27
26
  defaultValues: values,
28
- reValidateMode: 'onChange'
27
+ reValidateMode: 'onBlur'
29
28
  });
30
29
  const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);
31
- const handleSubmit = async (currentValues)=>{
32
- const toastId = toast.loading('Saving...');
33
- const changes = Object.entries(currentValues).reduce((acc, [locale, value])=>{
34
- const hasChanged = !isEqual(value, values[locale]);
35
- if (!hasChanged) return acc;
36
- acc[locale] = value;
37
- return acc;
38
- }, {});
39
- try {
40
- const response = await fetch(endpointUrl, {
41
- method: 'PUT',
42
- headers: {
43
- 'Content-Type': 'application/json'
44
- },
45
- body: JSON.stringify(changes)
46
- });
47
- if (!response.ok) {
48
- const error = await getErrorMessage(response);
49
- throw new Error(error);
30
+ useEffect(()=>{
31
+ const handler = (e)=>{
32
+ if (form.formState.isDirty) {
33
+ e.preventDefault();
50
34
  }
51
- form.reset(currentValues);
52
- toast.success('Saved', {
53
- id: toastId
54
- });
55
- } catch (error) {
56
- toast.error(`Failed to save: ${error instanceof Error ? error.message : 'Unknown error'}`, {
57
- id: toastId
58
- });
59
- }
60
- };
35
+ };
36
+ window.addEventListener('beforeunload', handler);
37
+ return ()=>window.removeEventListener('beforeunload', handler);
38
+ }, [
39
+ form
40
+ ]);
41
+ const handleSubmit = useMessagesFormSubmit({
42
+ endpointUrl,
43
+ defaultValues: values,
44
+ form
45
+ });
61
46
  return /*#__PURE__*/ _jsx(MessagesFormProvider, {
47
+ activeLocale: activeLocale,
48
+ defaultLocale: defaultLocale,
62
49
  form: form,
63
50
  locales: locales,
64
51
  children: /*#__PURE__*/ _jsxs("form", {
@@ -78,7 +65,9 @@ export function MessagesForm({ locales, schema, tabs = false, values, endpointUr
78
65
  /*#__PURE__*/ _jsxs("div", {
79
66
  className: styles.actions,
80
67
  children: [
81
- /*#__PURE__*/ _jsx(JsonImport, {}),
68
+ /*#__PURE__*/ _jsx(JsonImport, {
69
+ activeLocale: activeLocale
70
+ }),
82
71
  /*#__PURE__*/ _jsx(Button, {
83
72
  className: styles.saveButton,
84
73
  disabled: !form.formState.isDirty,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/MessagesForm.tsx"],"sourcesContent":["'use client';\n\nimport { Button, toast, useStepNav } from '@payloadcms/ui';\nimport { isEqual } from 'lodash-es';\nimport { useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport type { FormValues } from '@/components/MessageFormContext';\nimport { MessagesFormProvider } from '@/components/MessageFormContext';\nimport type {\n DeepPartial,\n Locale,\n Messages,\n MessagesSchema,\n Translations,\n} from '@/types';\nimport { getErrorMessage } from '@/utils/error-handling';\nimport { JsonImport } from './actions/JsonImport';\nimport { MessageField } from './layout/MessageField';\nimport { MessagesTabs } from './layout/MessagesTabs';\nimport { MessagesTree } from './layout/MessagesTree';\nimport styles from './MessagesForm.module.css';\n\ninterface MessagesFormProps {\n locales: Locale[];\n schema: MessagesSchema;\n tabs?: boolean;\n values: Translations<DeepPartial<Messages>>;\n endpointUrl: string;\n}\n\nexport function MessagesForm({\n locales,\n schema,\n tabs = false,\n values,\n endpointUrl,\n}: MessagesFormProps): React.ReactNode {\n const { setStepNav } = useStepNav();\n useEffect(() => {\n setStepNav([{ label: 'Intl Messages', url: '/intl' }]);\n }, [setStepNav]);\n\n const form = useForm<FormValues>({\n defaultValues: values,\n reValidateMode: 'onChange',\n });\n const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);\n\n const handleSubmit = async (currentValues: FormValues) => {\n const toastId = toast.loading('Saving...');\n const changes = Object.entries(currentValues).reduce<\n Translations<Messages>\n >((acc, [locale, value]) => {\n const hasChanged = !isEqual(value, values[locale]);\n if (!hasChanged) return acc;\n acc[locale] = value;\n return acc;\n }, {});\n\n try {\n const response = await fetch(endpointUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(changes),\n });\n\n if (!response.ok) {\n const error = await getErrorMessage(response);\n throw new Error(error);\n }\n\n form.reset(currentValues);\n toast.success('Saved', { id: toastId });\n } catch (error) {\n toast.error(\n `Failed to save: ${error instanceof Error ? error.message : 'Unknown error'}`,\n { id: toastId },\n );\n }\n };\n\n return (\n <MessagesFormProvider form={form} locales={locales}>\n <form className={styles.form} onSubmit={form.handleSubmit(handleSubmit)}>\n <div className={styles.stickyHeader}>\n <header className={styles.header}>\n <h1 className={styles.title}>Messages</h1>\n <div className={styles.actions}>\n <JsonImport />\n <Button\n className={styles.saveButton}\n disabled={!form.formState.isDirty}\n type=\"submit\"\n >\n Save\n </Button>\n </div>\n </header>\n\n {tabs && (\n <MessagesTabs\n activeTab={activeTab}\n schema={schema}\n setActiveTab={setActiveTab}\n />\n )}\n </div>\n\n <div className={styles.content} id=\"messages-form-content\">\n {!tabs && <MessagesTree nestingLevel={0} path=\"\" schema={schema} />}\n {tabs &&\n Object.entries(schema).map(([key, value]) => {\n if (typeof value === 'string') {\n return (\n <MessageField\n hidden={activeTab !== key}\n key={key}\n messageKey={key}\n path={key}\n schema={value}\n />\n );\n }\n return (\n <MessagesTree\n hidden={activeTab !== key}\n key={key}\n nestingLevel={0}\n path={key}\n schema={value}\n />\n );\n })}\n </div>\n </form>\n </MessagesFormProvider>\n );\n}\n"],"names":["Button","toast","useStepNav","isEqual","useEffect","useState","useForm","MessagesFormProvider","getErrorMessage","JsonImport","MessageField","MessagesTabs","MessagesTree","styles","MessagesForm","locales","schema","tabs","values","endpointUrl","setStepNav","label","url","form","defaultValues","reValidateMode","activeTab","setActiveTab","Object","keys","handleSubmit","currentValues","toastId","loading","changes","entries","reduce","acc","locale","value","hasChanged","response","fetch","method","headers","body","JSON","stringify","ok","error","Error","reset","success","id","message","className","onSubmit","div","stickyHeader","header","h1","title","actions","saveButton","disabled","formState","isDirty","type","content","nestingLevel","path","map","key","hidden","messageKey"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,KAAK,EAAEC,UAAU,QAAQ,iBAAiB;AAC3D,SAASC,OAAO,QAAQ,YAAY;AACpC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAC5C,SAASC,OAAO,QAAQ,kBAAkB;AAE1C,SAASC,oBAAoB,QAAQ,kCAAkC;AAQvE,SAASC,eAAe,QAAQ,yBAAyB;AACzD,SAASC,UAAU,QAAQ,uBAAuB;AAClD,SAASC,YAAY,QAAQ,wBAAwB;AACrD,SAASC,YAAY,QAAQ,wBAAwB;AACrD,SAASC,YAAY,QAAQ,wBAAwB;AACrD,OAAOC,YAAY,4BAA4B;AAU/C,OAAO,SAASC,aAAa,EAC3BC,OAAO,EACPC,MAAM,EACNC,OAAO,KAAK,EACZC,MAAM,EACNC,WAAW,EACO;IAClB,MAAM,EAAEC,UAAU,EAAE,GAAGlB;IACvBE,UAAU;QACRgB,WAAW;YAAC;gBAAEC,OAAO;gBAAiBC,KAAK;YAAQ;SAAE;IACvD,GAAG;QAACF;KAAW;IAEf,MAAMG,OAAOjB,QAAoB;QAC/BkB,eAAeN;QACfO,gBAAgB;IAClB;IACA,MAAM,CAACC,WAAWC,aAAa,GAAGtB,SAASuB,OAAOC,IAAI,CAACb,OAAO,CAAC,EAAE;IAEjE,MAAMc,eAAe,OAAOC;QAC1B,MAAMC,UAAU/B,MAAMgC,OAAO,CAAC;QAC9B,MAAMC,UAAUN,OAAOO,OAAO,CAACJ,eAAeK,MAAM,CAElD,CAACC,KAAK,CAACC,QAAQC,MAAM;YACrB,MAAMC,aAAa,CAACrC,QAAQoC,OAAOrB,MAAM,CAACoB,OAAO;YACjD,IAAI,CAACE,YAAY,OAAOH;YACxBA,GAAG,CAACC,OAAO,GAAGC;YACd,OAAOF;QACT,GAAG,CAAC;QAEJ,IAAI;YACF,MAAMI,WAAW,MAAMC,MAAMvB,aAAa;gBACxCwB,QAAQ;gBACRC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,MAAMC,KAAKC,SAAS,CAACb;YACvB;YAEA,IAAI,CAACO,SAASO,EAAE,EAAE;gBAChB,MAAMC,QAAQ,MAAMzC,gBAAgBiC;gBACpC,MAAM,IAAIS,MAAMD;YAClB;YAEA1B,KAAK4B,KAAK,CAACpB;YACX9B,MAAMmD,OAAO,CAAC,SAAS;gBAAEC,IAAIrB;YAAQ;QACvC,EAAE,OAAOiB,OAAO;YACdhD,MAAMgD,KAAK,CACT,CAAC,gBAAgB,EAAEA,iBAAiBC,QAAQD,MAAMK,OAAO,GAAG,iBAAiB,EAC7E;gBAAED,IAAIrB;YAAQ;QAElB;IACF;IAEA,qBACE,KAACzB;QAAqBgB,MAAMA;QAAMR,SAASA;kBACzC,cAAA,MAACQ;YAAKgC,WAAW1C,OAAOU,IAAI;YAAEiC,UAAUjC,KAAKO,YAAY,CAACA;;8BACxD,MAAC2B;oBAAIF,WAAW1C,OAAO6C,YAAY;;sCACjC,MAACC;4BAAOJ,WAAW1C,OAAO8C,MAAM;;8CAC9B,KAACC;oCAAGL,WAAW1C,OAAOgD,KAAK;8CAAE;;8CAC7B,MAACJ;oCAAIF,WAAW1C,OAAOiD,OAAO;;sDAC5B,KAACrD;sDACD,KAACT;4CACCuD,WAAW1C,OAAOkD,UAAU;4CAC5BC,UAAU,CAACzC,KAAK0C,SAAS,CAACC,OAAO;4CACjCC,MAAK;sDACN;;;;;;wBAMJlD,sBACC,KAACN;4BACCe,WAAWA;4BACXV,QAAQA;4BACRW,cAAcA;;;;8BAKpB,MAAC8B;oBAAIF,WAAW1C,OAAOuD,OAAO;oBAAEf,IAAG;;wBAChC,CAACpC,sBAAQ,KAACL;4BAAayD,cAAc;4BAAGC,MAAK;4BAAGtD,QAAQA;;wBACxDC,QACCW,OAAOO,OAAO,CAACnB,QAAQuD,GAAG,CAAC,CAAC,CAACC,KAAKjC,MAAM;4BACtC,IAAI,OAAOA,UAAU,UAAU;gCAC7B,qBACE,KAAC7B;oCACC+D,QAAQ/C,cAAc8C;oCAEtBE,YAAYF;oCACZF,MAAME;oCACNxD,QAAQuB;mCAHHiC;4BAMX;4BACA,qBACE,KAAC5D;gCACC6D,QAAQ/C,cAAc8C;gCAEtBH,cAAc;gCACdC,MAAME;gCACNxD,QAAQuB;+BAHHiC;wBAMX;;;;;;AAKZ"}
1
+ {"version":3,"sources":["../../src/components/MessagesForm.tsx"],"sourcesContent":["'use client';\n\nimport { Button, useStepNav } from '@payloadcms/ui';\nimport { useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport type { FormValues } from '@/components/MessagesFormProvider';\nimport { MessagesFormProvider } from '@/components/MessagesFormProvider';\nimport type {\n DeepPartial,\n Locale,\n Messages,\n MessagesSchema,\n Translations,\n} from '@/types';\nimport { JsonImport } from './actions/JsonImport';\nimport { useMessagesFormSubmit } from './hooks/useMessagesFormSubmit';\nimport { MessageField } from './layout/MessageField';\nimport { MessagesTabs } from './layout/MessagesTabs';\nimport { MessagesTree } from './layout/MessagesTree';\nimport styles from './MessagesForm.module.css';\n\ninterface MessagesFormProps {\n locales: Locale[];\n defaultLocale: Locale;\n activeLocale: Locale;\n schema: MessagesSchema;\n tabs?: boolean;\n values: Translations<DeepPartial<Messages>>;\n endpointUrl: string;\n}\n\nexport function MessagesForm({\n locales,\n defaultLocale,\n activeLocale,\n schema,\n tabs = false,\n values,\n endpointUrl,\n}: MessagesFormProps): React.ReactNode {\n const { setStepNav } = useStepNav();\n useEffect(() => {\n setStepNav([{ label: 'Intl Messages', url: '/intl' }]);\n }, [setStepNav]);\n\n const form = useForm<FormValues>({\n defaultValues: values,\n reValidateMode: 'onBlur',\n });\n const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);\n\n useEffect(() => {\n const handler = (e: BeforeUnloadEvent) => {\n if (form.formState.isDirty) {\n e.preventDefault();\n }\n };\n window.addEventListener('beforeunload', handler);\n return () => window.removeEventListener('beforeunload', handler);\n }, [form]);\n\n const handleSubmit = useMessagesFormSubmit({\n endpointUrl,\n defaultValues: values,\n form,\n });\n\n return (\n <MessagesFormProvider\n activeLocale={activeLocale}\n defaultLocale={defaultLocale}\n form={form}\n locales={locales}\n >\n <form className={styles.form} onSubmit={form.handleSubmit(handleSubmit)}>\n <div className={styles.stickyHeader}>\n <header className={styles.header}>\n <h1 className={styles.title}>Messages</h1>\n <div className={styles.actions}>\n <JsonImport activeLocale={activeLocale} />\n <Button\n className={styles.saveButton}\n disabled={!form.formState.isDirty}\n type=\"submit\"\n >\n Save\n </Button>\n </div>\n </header>\n\n {tabs && (\n <MessagesTabs\n activeTab={activeTab}\n schema={schema}\n setActiveTab={setActiveTab}\n />\n )}\n </div>\n\n <div className={styles.content} id=\"messages-form-content\">\n {!tabs && <MessagesTree nestingLevel={0} path=\"\" schema={schema} />}\n {tabs &&\n Object.entries(schema).map(([key, value]) => {\n if (typeof value === 'string') {\n return (\n <MessageField\n hidden={activeTab !== key}\n key={key}\n messageKey={key}\n path={key}\n schema={value}\n />\n );\n }\n return (\n <MessagesTree\n hidden={activeTab !== key}\n key={key}\n nestingLevel={0}\n path={key}\n schema={value}\n />\n );\n })}\n </div>\n </form>\n </MessagesFormProvider>\n );\n}\n"],"names":["Button","useStepNav","useEffect","useState","useForm","MessagesFormProvider","JsonImport","useMessagesFormSubmit","MessageField","MessagesTabs","MessagesTree","styles","MessagesForm","locales","defaultLocale","activeLocale","schema","tabs","values","endpointUrl","setStepNav","label","url","form","defaultValues","reValidateMode","activeTab","setActiveTab","Object","keys","handler","e","formState","isDirty","preventDefault","window","addEventListener","removeEventListener","handleSubmit","className","onSubmit","div","stickyHeader","header","h1","title","actions","saveButton","disabled","type","content","id","nestingLevel","path","entries","map","key","value","hidden","messageKey"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,UAAU,QAAQ,iBAAiB;AACpD,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAC5C,SAASC,OAAO,QAAQ,kBAAkB;AAE1C,SAASC,oBAAoB,QAAQ,oCAAoC;AAQzE,SAASC,UAAU,QAAQ,uBAAuB;AAClD,SAASC,qBAAqB,QAAQ,gCAAgC;AACtE,SAASC,YAAY,QAAQ,wBAAwB;AACrD,SAASC,YAAY,QAAQ,wBAAwB;AACrD,SAASC,YAAY,QAAQ,wBAAwB;AACrD,OAAOC,YAAY,4BAA4B;AAY/C,OAAO,SAASC,aAAa,EAC3BC,OAAO,EACPC,aAAa,EACbC,YAAY,EACZC,MAAM,EACNC,OAAO,KAAK,EACZC,MAAM,EACNC,WAAW,EACO;IAClB,MAAM,EAAEC,UAAU,EAAE,GAAGnB;IACvBC,UAAU;QACRkB,WAAW;YAAC;gBAAEC,OAAO;gBAAiBC,KAAK;YAAQ;SAAE;IACvD,GAAG;QAACF;KAAW;IAEf,MAAMG,OAAOnB,QAAoB;QAC/BoB,eAAeN;QACfO,gBAAgB;IAClB;IACA,MAAM,CAACC,WAAWC,aAAa,GAAGxB,SAASyB,OAAOC,IAAI,CAACb,OAAO,CAAC,EAAE;IAEjEd,UAAU;QACR,MAAM4B,UAAU,CAACC;YACf,IAAIR,KAAKS,SAAS,CAACC,OAAO,EAAE;gBAC1BF,EAAEG,cAAc;YAClB;QACF;QACAC,OAAOC,gBAAgB,CAAC,gBAAgBN;QACxC,OAAO,IAAMK,OAAOE,mBAAmB,CAAC,gBAAgBP;IAC1D,GAAG;QAACP;KAAK;IAET,MAAMe,eAAe/B,sBAAsB;QACzCY;QACAK,eAAeN;QACfK;IACF;IAEA,qBACE,KAAClB;QACCU,cAAcA;QACdD,eAAeA;QACfS,MAAMA;QACNV,SAASA;kBAET,cAAA,MAACU;YAAKgB,WAAW5B,OAAOY,IAAI;YAAEiB,UAAUjB,KAAKe,YAAY,CAACA;;8BACxD,MAACG;oBAAIF,WAAW5B,OAAO+B,YAAY;;sCACjC,MAACC;4BAAOJ,WAAW5B,OAAOgC,MAAM;;8CAC9B,KAACC;oCAAGL,WAAW5B,OAAOkC,KAAK;8CAAE;;8CAC7B,MAACJ;oCAAIF,WAAW5B,OAAOmC,OAAO;;sDAC5B,KAACxC;4CAAWS,cAAcA;;sDAC1B,KAACf;4CACCuC,WAAW5B,OAAOoC,UAAU;4CAC5BC,UAAU,CAACzB,KAAKS,SAAS,CAACC,OAAO;4CACjCgB,MAAK;sDACN;;;;;;wBAMJhC,sBACC,KAACR;4BACCiB,WAAWA;4BACXV,QAAQA;4BACRW,cAAcA;;;;8BAKpB,MAACc;oBAAIF,WAAW5B,OAAOuC,OAAO;oBAAEC,IAAG;;wBAChC,CAAClC,sBAAQ,KAACP;4BAAa0C,cAAc;4BAAGC,MAAK;4BAAGrC,QAAQA;;wBACxDC,QACCW,OAAO0B,OAAO,CAACtC,QAAQuC,GAAG,CAAC,CAAC,CAACC,KAAKC,MAAM;4BACtC,IAAI,OAAOA,UAAU,UAAU;gCAC7B,qBACE,KAACjD;oCACCkD,QAAQhC,cAAc8B;oCAEtBG,YAAYH;oCACZH,MAAMG;oCACNxC,QAAQyC;mCAHHD;4BAMX;4BACA,qBACE,KAAC9C;gCACCgD,QAAQhC,cAAc8B;gCAEtBJ,cAAc;gCACdC,MAAMG;gCACNxC,QAAQyC;+BAHHD;wBAMX;;;;;;AAKZ"}
@@ -3,9 +3,11 @@ import type { Locale, Messages, Translations } from '../types';
3
3
  export type FormValues = Translations<Messages>;
4
4
  interface MessagesFormProviderProps {
5
5
  locales: Locale[];
6
+ defaultLocale: Locale;
7
+ activeLocale: Locale;
6
8
  form: UseFormReturn<FormValues>;
7
9
  }
8
- export declare function MessagesFormProvider({ locales, form, children, }: React.PropsWithChildren<MessagesFormProviderProps>): import("react/jsx-runtime").JSX.Element;
10
+ export declare function MessagesFormProvider({ locales, defaultLocale, activeLocale, form, children, }: React.PropsWithChildren<MessagesFormProviderProps>): import("react/jsx-runtime").JSX.Element;
9
11
  export declare const useMessagesForm: () => {
10
12
  watch: import("react-hook-form").UseFormWatch<FormValues>;
11
13
  getValues: import("react-hook-form").UseFormGetValues<FormValues>;
@@ -24,6 +26,8 @@ export declare const useMessagesForm: () => {
24
26
  setFocus: import("react-hook-form").UseFormSetFocus<FormValues>;
25
27
  subscribe: import("react-hook-form").UseFormSubscribe<FormValues>;
26
28
  locales: Locale[];
29
+ defaultLocale: Locale;
30
+ activeLocale: Locale;
27
31
  };
28
32
  export {};
29
- //# sourceMappingURL=MessageFormContext.d.ts.map
33
+ //# sourceMappingURL=MessagesFormProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagesFormProvider.d.ts","sourceRoot":"","sources":["../../src/components/MessagesFormProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE9D,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AAYhD,UAAU,yBAAyB;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACjC;AAED,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,aAAa,EACb,YAAY,EACZ,IAAI,EACJ,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC,yBAAyB,CAAC,2CAMpD;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;aA9BjB,MAAM,EAAE;mBACF,MAAM;kBACP,MAAM;CAmCrB,CAAC"}
@@ -5,12 +5,16 @@ import { FormProvider, useFormContext } from 'react-hook-form';
5
5
  const MessagesFormContext = /*#__PURE__*/ createContext({
6
6
  locales: [
7
7
  'en'
8
- ]
8
+ ],
9
+ defaultLocale: 'en',
10
+ activeLocale: 'en'
9
11
  });
10
- export function MessagesFormProvider({ locales, form, children }) {
12
+ export function MessagesFormProvider({ locales, defaultLocale, activeLocale, form, children }) {
11
13
  return /*#__PURE__*/ _jsx(MessagesFormContext, {
12
14
  value: {
13
- locales
15
+ locales,
16
+ defaultLocale,
17
+ activeLocale
14
18
  },
15
19
  children: /*#__PURE__*/ _jsx(FormProvider, {
16
20
  ...form,
@@ -27,4 +31,4 @@ export const useMessagesForm = ()=>{
27
31
  };
28
32
  };
29
33
 
30
- //# sourceMappingURL=MessageFormContext.js.map
34
+ //# sourceMappingURL=MessagesFormProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/MessagesFormProvider.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, use } from 'react';\nimport type { UseFormReturn } from 'react-hook-form';\nimport { FormProvider, useFormContext } from 'react-hook-form';\nimport type { Locale, Messages, Translations } from '@/types';\n\nexport type FormValues = Translations<Messages>;\n\nconst MessagesFormContext = createContext<{\n locales: Locale[];\n defaultLocale: Locale;\n activeLocale: Locale;\n}>({\n locales: ['en'],\n defaultLocale: 'en',\n activeLocale: 'en',\n});\n\ninterface MessagesFormProviderProps {\n locales: Locale[];\n defaultLocale: Locale;\n activeLocale: Locale;\n form: UseFormReturn<FormValues>;\n}\n\nexport function MessagesFormProvider({\n locales,\n defaultLocale,\n activeLocale,\n form,\n children,\n}: React.PropsWithChildren<MessagesFormProviderProps>) {\n return (\n <MessagesFormContext value={{ locales, defaultLocale, activeLocale }}>\n <FormProvider {...form}>{children}</FormProvider>\n </MessagesFormContext>\n );\n}\n\nexport const useMessagesForm = () => {\n const context = use(MessagesFormContext);\n const form = useFormContext<FormValues>();\n return {\n ...context,\n ...form,\n };\n};\n"],"names":["createContext","use","FormProvider","useFormContext","MessagesFormContext","locales","defaultLocale","activeLocale","MessagesFormProvider","form","children","value","useMessagesForm","context"],"mappings":"AAAA;;AAEA,SAASA,aAAa,EAAEC,GAAG,QAAQ,QAAQ;AAE3C,SAASC,YAAY,EAAEC,cAAc,QAAQ,kBAAkB;AAK/D,MAAMC,oCAAsBJ,cAIzB;IACDK,SAAS;QAAC;KAAK;IACfC,eAAe;IACfC,cAAc;AAChB;AASA,OAAO,SAASC,qBAAqB,EACnCH,OAAO,EACPC,aAAa,EACbC,YAAY,EACZE,IAAI,EACJC,QAAQ,EAC2C;IACnD,qBACE,KAACN;QAAoBO,OAAO;YAAEN;YAASC;YAAeC;QAAa;kBACjE,cAAA,KAACL;YAAc,GAAGO,IAAI;sBAAGC;;;AAG/B;AAEA,OAAO,MAAME,kBAAkB;IAC7B,MAAMC,UAAUZ,IAAIG;IACpB,MAAMK,OAAON;IACb,OAAO;QACL,GAAGU,OAAO;QACV,GAAGJ,IAAI;IACT;AACF,EAAE"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Button } from '@payloadcms/ui';
3
- import { getAdminURL } from '../_common/index.js';
3
+ import { getAdminURL } from '../internals/index.js';
4
4
  import { IconWorld } from '@tabler/icons-react';
5
5
  export async function MessagesLink({ access = ()=>true, req }) {
6
6
  const hasAccess = await access(req);
@@ -12,7 +12,10 @@ export async function MessagesLink({ access = ()=>true, req }) {
12
12
  req,
13
13
  path: '/intl'
14
14
  }),
15
- children: /*#__PURE__*/ _jsx(IconWorld, {})
15
+ children: /*#__PURE__*/ _jsx(IconWorld, {
16
+ size: 20,
17
+ strokeWidth: 1.5
18
+ })
16
19
  });
17
20
  }
18
21
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/MessagesLink.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui';\nimport { getAdminURL } from '@repo/common';\nimport { IconWorld } from '@tabler/icons-react';\nimport type { PayloadRequest } from 'payload';\nimport type { MessagesGuard } from '@/types';\n\nexport interface MessagesLinkProps {\n access?: MessagesGuard;\n req: PayloadRequest;\n}\n\nexport async function MessagesLink({\n access = () => true,\n req,\n}: MessagesLinkProps) {\n const hasAccess = await access(req);\n if (!hasAccess) return null;\n\n return (\n <Button\n buttonStyle=\"tab\"\n el=\"link\"\n to={getAdminURL({ req, path: '/intl' })}\n >\n <IconWorld />\n </Button>\n );\n}\n"],"names":["Button","getAdminURL","IconWorld","MessagesLink","access","req","hasAccess","buttonStyle","el","to","path"],"mappings":";AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,WAAW,QAAQ,eAAe;AAC3C,SAASC,SAAS,QAAQ,sBAAsB;AAShD,OAAO,eAAeC,aAAa,EACjCC,SAAS,IAAM,IAAI,EACnBC,GAAG,EACe;IAClB,MAAMC,YAAY,MAAMF,OAAOC;IAC/B,IAAI,CAACC,WAAW,OAAO;IAEvB,qBACE,KAACN;QACCO,aAAY;QACZC,IAAG;QACHC,IAAIR,YAAY;YAAEI;YAAKK,MAAM;QAAQ;kBAErC,cAAA,KAACR;;AAGP"}
1
+ {"version":3,"sources":["../../src/components/MessagesLink.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui';\nimport { getAdminURL } from '@repo/common';\nimport { IconWorld } from '@tabler/icons-react';\nimport type { PayloadRequest } from 'payload';\nimport type { MessagesGuard } from '@/types';\n\nexport interface MessagesLinkProps {\n access?: MessagesGuard;\n req: PayloadRequest;\n}\n\nexport async function MessagesLink({\n access = () => true,\n req,\n}: MessagesLinkProps) {\n const hasAccess = await access(req);\n if (!hasAccess) return null;\n\n return (\n <Button\n buttonStyle=\"tab\"\n el=\"link\"\n to={getAdminURL({ req, path: '/intl' })}\n >\n <IconWorld size={20} strokeWidth={1.5} />\n </Button>\n );\n}\n"],"names":["Button","getAdminURL","IconWorld","MessagesLink","access","req","hasAccess","buttonStyle","el","to","path","size","strokeWidth"],"mappings":";AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,WAAW,QAAQ,eAAe;AAC3C,SAASC,SAAS,QAAQ,sBAAsB;AAShD,OAAO,eAAeC,aAAa,EACjCC,SAAS,IAAM,IAAI,EACnBC,GAAG,EACe;IAClB,MAAMC,YAAY,MAAMF,OAAOC;IAC/B,IAAI,CAACC,WAAW,OAAO;IAEvB,qBACE,KAACN;QACCO,aAAY;QACZC,IAAG;QACHC,IAAIR,YAAY;YAAEI;YAAKK,MAAM;QAAQ;kBAErC,cAAA,KAACR;YAAUS,MAAM;YAAIC,aAAa;;;AAGxC"}
@@ -6,5 +6,5 @@ export interface MessagesViewProps {
6
6
  tabs: boolean | undefined;
7
7
  access: MessagesGuard;
8
8
  }
9
- export declare function MessagesView({ access, initPageResult: { req, locale, permissions, visibleEntities }, locales, params, payload, schema, searchParams, tabs, }: AdminViewServerProps & MessagesViewProps): Promise<import("react/jsx-runtime").JSX.Element>;
9
+ export declare function MessagesView({ access, initPageResult: { req, locale, permissions, visibleEntities }, locales, params, payload, schema, searchParams, tabs, }: AdminViewServerProps & MessagesViewProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
10
10
  //# sourceMappingURL=MessagesView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessagesView.d.ts","sourceRoot":"","sources":["../../src/components/MessagesView.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,KAAK,EAEV,MAAM,EACN,QAAQ,EACR,aAAa,EAEd,MAAM,SAAS,CAAC;AAKjB,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,cAAc,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,EAC7D,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,YAAY,EACZ,IAAY,GACb,EAAE,oBAAoB,GAAG,iBAAiB,oDA6C1C"}
1
+ {"version":3,"file":"MessagesView.d.ts","sourceRoot":"","sources":["../../src/components/MessagesView.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,KAAK,EAEV,MAAM,EACN,QAAQ,EACR,aAAa,EAEd,MAAM,SAAS,CAAC;AAKjB,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,cAAc,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,EAC7D,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,YAAY,EACZ,IAAY,GACb,EAAE,oBAAoB,GAAG,iBAAiB,2DAwD1C"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { DefaultTemplate } from '@payloadcms/next/templates';
3
3
  import { Gutter } from '@payloadcms/ui';
4
- import { getAdminURL } from '../_common/index.js';
4
+ import { getAdminURL } from '../internals/index.js';
5
5
  import { RedirectType, redirect } from 'next/navigation';
6
6
  import { sanitizeMessages } from '../utils/sanitize';
7
7
  import { fetchMessages } from '../requests/fetchMessages';
@@ -13,10 +13,17 @@ export async function MessagesView({ access, initPageResult: { req, locale, perm
13
13
  if (!hasAccess) redirect(getAdminURL({
14
14
  req
15
15
  }), RedirectType.replace);
16
+ if (!payload.config.localization) {
17
+ return null;
18
+ }
19
+ const defaultLocale = payload.config.localization.defaultLocale;
20
+ const activeLocale = typeof locale === 'string' ? locale : locale?.code ?? defaultLocale;
16
21
  const translations = {};
17
- for (const locale of locales){
18
- const messages = await fetchMessages(payload, locale);
19
- translations[locale] = sanitizeMessages(schema, messages);
22
+ for (const loc of locales){
23
+ const messages = await fetchMessages(payload, loc);
24
+ translations[loc] = sanitizeMessages(schema, messages, {
25
+ useSchemaDefaults: loc === defaultLocale
26
+ });
20
27
  }
21
28
  return /*#__PURE__*/ _jsx(DefaultTemplate, {
22
29
  i18n: req.i18n,
@@ -35,6 +42,8 @@ export async function MessagesView({ access, initPageResult: { req, locale, perm
35
42
  visibleEntities: visibleEntities,
36
43
  children: /*#__PURE__*/ _jsx(Gutter, {
37
44
  children: /*#__PURE__*/ _jsx(MessagesForm, {
45
+ activeLocale: activeLocale,
46
+ defaultLocale: defaultLocale,
38
47
  endpointUrl: endpointUrl,
39
48
  locales: locales,
40
49
  schema: schema,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/MessagesView.tsx"],"sourcesContent":["import { DefaultTemplate } from '@payloadcms/next/templates';\nimport { Gutter } from '@payloadcms/ui';\nimport { getAdminURL } from '@repo/common';\nimport { RedirectType, redirect } from 'next/navigation';\nimport type { AdminViewServerProps } from 'payload';\nimport type {\n DeepPartial,\n Locale,\n Messages,\n MessagesGuard,\n Translations,\n} from '@/types';\nimport { sanitizeMessages } from '@/utils/sanitize';\nimport { fetchMessages } from '../requests/fetchMessages';\nimport { MessagesForm } from './MessagesForm';\n\nexport interface MessagesViewProps {\n locales: Locale[];\n schema: Messages;\n tabs: boolean | undefined;\n access: MessagesGuard;\n}\n\nexport async function MessagesView({\n access,\n initPageResult: { req, locale, permissions, visibleEntities },\n locales,\n params,\n payload,\n schema,\n searchParams,\n tabs = false,\n}: AdminViewServerProps & MessagesViewProps) {\n const apiUrl = payload.getAPIURL();\n const endpointUrl = apiUrl.endsWith('/')\n ? `${apiUrl}intl-plugin`\n : `${apiUrl}/intl-plugin`;\n\n const hasAccess = await access(req);\n if (!hasAccess) redirect(getAdminURL({ req }), RedirectType.replace);\n\n const translations: Translations<DeepPartial<Messages>> = {};\n\n for (const locale of locales) {\n const messages = await fetchMessages(payload, locale);\n\n translations[locale] = sanitizeMessages(schema, messages);\n }\n\n return (\n <DefaultTemplate\n i18n={req.i18n}\n locale={locale}\n params={params}\n payload={req.payload}\n permissions={permissions}\n searchParams={searchParams}\n user={req.user || undefined}\n viewActions={payload.config.admin.components.actions.filter((action) => {\n if (typeof action !== 'object') {\n return true;\n }\n return action.exportName !== 'MessagesLink';\n })}\n visibleEntities={visibleEntities}\n >\n <Gutter>\n <MessagesForm\n endpointUrl={endpointUrl}\n locales={locales}\n schema={schema}\n tabs={tabs}\n values={translations}\n />\n </Gutter>\n </DefaultTemplate>\n );\n}\n"],"names":["DefaultTemplate","Gutter","getAdminURL","RedirectType","redirect","sanitizeMessages","fetchMessages","MessagesForm","MessagesView","access","initPageResult","req","locale","permissions","visibleEntities","locales","params","payload","schema","searchParams","tabs","apiUrl","getAPIURL","endpointUrl","endsWith","hasAccess","replace","translations","messages","i18n","user","undefined","viewActions","config","admin","components","actions","filter","action","exportName","values"],"mappings":";AAAA,SAASA,eAAe,QAAQ,6BAA6B;AAC7D,SAASC,MAAM,QAAQ,iBAAiB;AACxC,SAASC,WAAW,QAAQ,eAAe;AAC3C,SAASC,YAAY,EAAEC,QAAQ,QAAQ,kBAAkB;AASzD,SAASC,gBAAgB,QAAQ,mBAAmB;AACpD,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,YAAY,QAAQ,iBAAiB;AAS9C,OAAO,eAAeC,aAAa,EACjCC,MAAM,EACNC,gBAAgB,EAAEC,GAAG,EAAEC,MAAM,EAAEC,WAAW,EAAEC,eAAe,EAAE,EAC7DC,OAAO,EACPC,MAAM,EACNC,OAAO,EACPC,MAAM,EACNC,YAAY,EACZC,OAAO,KAAK,EAC6B;IACzC,MAAMC,SAASJ,QAAQK,SAAS;IAChC,MAAMC,cAAcF,OAAOG,QAAQ,CAAC,OAChC,GAAGH,OAAO,WAAW,CAAC,GACtB,GAAGA,OAAO,YAAY,CAAC;IAE3B,MAAMI,YAAY,MAAMhB,OAAOE;IAC/B,IAAI,CAACc,WAAWrB,SAASF,YAAY;QAAES;IAAI,IAAIR,aAAauB,OAAO;IAEnE,MAAMC,eAAoD,CAAC;IAE3D,KAAK,MAAMf,UAAUG,QAAS;QAC5B,MAAMa,WAAW,MAAMtB,cAAcW,SAASL;QAE9Ce,YAAY,CAACf,OAAO,GAAGP,iBAAiBa,QAAQU;IAClD;IAEA,qBACE,KAAC5B;QACC6B,MAAMlB,IAAIkB,IAAI;QACdjB,QAAQA;QACRI,QAAQA;QACRC,SAASN,IAAIM,OAAO;QACpBJ,aAAaA;QACbM,cAAcA;QACdW,MAAMnB,IAAImB,IAAI,IAAIC;QAClBC,aAAaf,QAAQgB,MAAM,CAACC,KAAK,CAACC,UAAU,CAACC,OAAO,CAACC,MAAM,CAAC,CAACC;YAC3D,IAAI,OAAOA,WAAW,UAAU;gBAC9B,OAAO;YACT;YACA,OAAOA,OAAOC,UAAU,KAAK;QAC/B;QACAzB,iBAAiBA;kBAEjB,cAAA,KAACb;sBACC,cAAA,KAACM;gBACCgB,aAAaA;gBACbR,SAASA;gBACTG,QAAQA;gBACRE,MAAMA;gBACNoB,QAAQb;;;;AAKlB"}
1
+ {"version":3,"sources":["../../src/components/MessagesView.tsx"],"sourcesContent":["import { DefaultTemplate } from '@payloadcms/next/templates';\nimport { Gutter } from '@payloadcms/ui';\nimport { getAdminURL } from '@repo/common';\nimport { RedirectType, redirect } from 'next/navigation';\nimport type { AdminViewServerProps } from 'payload';\nimport type {\n DeepPartial,\n Locale,\n Messages,\n MessagesGuard,\n Translations,\n} from '@/types';\nimport { sanitizeMessages } from '@/utils/sanitize';\nimport { fetchMessages } from '../requests/fetchMessages';\nimport { MessagesForm } from './MessagesForm';\n\nexport interface MessagesViewProps {\n locales: Locale[];\n schema: Messages;\n tabs: boolean | undefined;\n access: MessagesGuard;\n}\n\nexport async function MessagesView({\n access,\n initPageResult: { req, locale, permissions, visibleEntities },\n locales,\n params,\n payload,\n schema,\n searchParams,\n tabs = false,\n}: AdminViewServerProps & MessagesViewProps) {\n const apiUrl = payload.getAPIURL();\n const endpointUrl = apiUrl.endsWith('/')\n ? `${apiUrl}intl-plugin`\n : `${apiUrl}/intl-plugin`;\n\n const hasAccess = await access(req);\n if (!hasAccess) redirect(getAdminURL({ req }), RedirectType.replace);\n\n if (!payload.config.localization) {\n return null;\n }\n const defaultLocale = payload.config.localization.defaultLocale;\n const activeLocale =\n typeof locale === 'string' ? locale : (locale?.code ?? defaultLocale);\n\n const translations: Translations<DeepPartial<Messages>> = {};\n\n for (const loc of locales) {\n const messages = await fetchMessages(payload, loc);\n\n translations[loc] = sanitizeMessages(schema, messages, {\n useSchemaDefaults: loc === defaultLocale,\n });\n }\n\n return (\n <DefaultTemplate\n i18n={req.i18n}\n locale={locale}\n params={params}\n payload={req.payload}\n permissions={permissions}\n searchParams={searchParams}\n user={req.user || undefined}\n viewActions={payload.config.admin.components.actions.filter((action) => {\n if (typeof action !== 'object') {\n return true;\n }\n return action.exportName !== 'MessagesLink';\n })}\n visibleEntities={visibleEntities}\n >\n <Gutter>\n <MessagesForm\n activeLocale={activeLocale}\n defaultLocale={defaultLocale}\n endpointUrl={endpointUrl}\n locales={locales}\n schema={schema}\n tabs={tabs}\n values={translations}\n />\n </Gutter>\n </DefaultTemplate>\n );\n}\n"],"names":["DefaultTemplate","Gutter","getAdminURL","RedirectType","redirect","sanitizeMessages","fetchMessages","MessagesForm","MessagesView","access","initPageResult","req","locale","permissions","visibleEntities","locales","params","payload","schema","searchParams","tabs","apiUrl","getAPIURL","endpointUrl","endsWith","hasAccess","replace","config","localization","defaultLocale","activeLocale","code","translations","loc","messages","useSchemaDefaults","i18n","user","undefined","viewActions","admin","components","actions","filter","action","exportName","values"],"mappings":";AAAA,SAASA,eAAe,QAAQ,6BAA6B;AAC7D,SAASC,MAAM,QAAQ,iBAAiB;AACxC,SAASC,WAAW,QAAQ,eAAe;AAC3C,SAASC,YAAY,EAAEC,QAAQ,QAAQ,kBAAkB;AASzD,SAASC,gBAAgB,QAAQ,mBAAmB;AACpD,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,YAAY,QAAQ,iBAAiB;AAS9C,OAAO,eAAeC,aAAa,EACjCC,MAAM,EACNC,gBAAgB,EAAEC,GAAG,EAAEC,MAAM,EAAEC,WAAW,EAAEC,eAAe,EAAE,EAC7DC,OAAO,EACPC,MAAM,EACNC,OAAO,EACPC,MAAM,EACNC,YAAY,EACZC,OAAO,KAAK,EAC6B;IACzC,MAAMC,SAASJ,QAAQK,SAAS;IAChC,MAAMC,cAAcF,OAAOG,QAAQ,CAAC,OAChC,GAAGH,OAAO,WAAW,CAAC,GACtB,GAAGA,OAAO,YAAY,CAAC;IAE3B,MAAMI,YAAY,MAAMhB,OAAOE;IAC/B,IAAI,CAACc,WAAWrB,SAASF,YAAY;QAAES;IAAI,IAAIR,aAAauB,OAAO;IAEnE,IAAI,CAACT,QAAQU,MAAM,CAACC,YAAY,EAAE;QAChC,OAAO;IACT;IACA,MAAMC,gBAAgBZ,QAAQU,MAAM,CAACC,YAAY,CAACC,aAAa;IAC/D,MAAMC,eACJ,OAAOlB,WAAW,WAAWA,SAAUA,QAAQmB,QAAQF;IAEzD,MAAMG,eAAoD,CAAC;IAE3D,KAAK,MAAMC,OAAOlB,QAAS;QACzB,MAAMmB,WAAW,MAAM5B,cAAcW,SAASgB;QAE9CD,YAAY,CAACC,IAAI,GAAG5B,iBAAiBa,QAAQgB,UAAU;YACrDC,mBAAmBF,QAAQJ;QAC7B;IACF;IAEA,qBACE,KAAC7B;QACCoC,MAAMzB,IAAIyB,IAAI;QACdxB,QAAQA;QACRI,QAAQA;QACRC,SAASN,IAAIM,OAAO;QACpBJ,aAAaA;QACbM,cAAcA;QACdkB,MAAM1B,IAAI0B,IAAI,IAAIC;QAClBC,aAAatB,QAAQU,MAAM,CAACa,KAAK,CAACC,UAAU,CAACC,OAAO,CAACC,MAAM,CAAC,CAACC;YAC3D,IAAI,OAAOA,WAAW,UAAU;gBAC9B,OAAO;YACT;YACA,OAAOA,OAAOC,UAAU,KAAK;QAC/B;QACA/B,iBAAiBA;kBAEjB,cAAA,KAACb;sBACC,cAAA,KAACM;gBACCuB,cAAcA;gBACdD,eAAeA;gBACfN,aAAaA;gBACbR,SAASA;gBACTG,QAAQA;gBACRE,MAAMA;gBACN0B,QAAQd;;;;AAKlB"}
@@ -0,0 +1,2 @@
1
+ export declare function CopyMessages(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=CopyMessages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyMessages.d.ts","sourceRoot":"","sources":["../../../src/components/actions/CopyMessages.tsx"],"names":[],"mappings":"AAQA,wBAAgB,YAAY,4CA4B3B"}
@@ -2,11 +2,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Button } from '@payloadcms/ui';
3
3
  import { IconBraces } from '@tabler/icons-react';
4
4
  import { get } from 'lodash-es';
5
- import { useMessagesForm } from '../../components/MessageFormContext';
6
- import styles from './Move.module.css';
7
- export function Move() {
5
+ import { useMessagesForm } from '../../components/MessagesFormProvider';
6
+ import styles from './CopyMessages.module.css';
7
+ export function CopyMessages() {
8
8
  const { getValues, setValue, locales } = useMessagesForm();
9
- const handleMove = ()=>{
9
+ const handleCopy = ()=>{
10
10
  const sourcePath = prompt('Source path');
11
11
  if (!sourcePath) {
12
12
  return;
@@ -33,9 +33,9 @@ export function Move() {
33
33
  className: styles.icon
34
34
  }),
35
35
  iconPosition: "left",
36
- onClick: handleMove,
36
+ onClick: handleCopy,
37
37
  children: "Copy"
38
38
  });
39
39
  }
40
40
 
41
- //# sourceMappingURL=Move.js.map
41
+ //# sourceMappingURL=CopyMessages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/actions/CopyMessages.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui';\nimport { IconBraces } from '@tabler/icons-react';\nimport { get } from 'lodash-es';\n\nimport { useMessagesForm } from '@/components/MessagesFormProvider';\n\nimport styles from './CopyMessages.module.css';\n\nexport function CopyMessages() {\n const { getValues, setValue, locales } = useMessagesForm();\n const handleCopy = () => {\n const sourcePath = prompt('Source path');\n if (!sourcePath) {\n return;\n }\n const targetPath = prompt('Target path');\n if (!targetPath) {\n return;\n }\n\n locales.forEach((locale) => {\n const sourceValue = get(getValues(), [locale, sourcePath].join('.'));\n setValue([locale, targetPath].join('.'), sourceValue);\n });\n };\n return (\n <Button\n buttonStyle=\"subtle\"\n className={styles.button}\n icon={<IconBraces className={styles.icon} />}\n iconPosition=\"left\"\n onClick={handleCopy}\n >\n Copy\n </Button>\n );\n}\n"],"names":["Button","IconBraces","get","useMessagesForm","styles","CopyMessages","getValues","setValue","locales","handleCopy","sourcePath","prompt","targetPath","forEach","locale","sourceValue","join","buttonStyle","className","button","icon","iconPosition","onClick"],"mappings":";AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,GAAG,QAAQ,YAAY;AAEhC,SAASC,eAAe,QAAQ,oCAAoC;AAEpE,OAAOC,YAAY,4BAA4B;AAE/C,OAAO,SAASC;IACd,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,OAAO,EAAE,GAAGL;IACzC,MAAMM,aAAa;QACjB,MAAMC,aAAaC,OAAO;QAC1B,IAAI,CAACD,YAAY;YACf;QACF;QACA,MAAME,aAAaD,OAAO;QAC1B,IAAI,CAACC,YAAY;YACf;QACF;QAEAJ,QAAQK,OAAO,CAAC,CAACC;YACf,MAAMC,cAAcb,IAAII,aAAa;gBAACQ;gBAAQJ;aAAW,CAACM,IAAI,CAAC;YAC/DT,SAAS;gBAACO;gBAAQF;aAAW,CAACI,IAAI,CAAC,MAAMD;QAC3C;IACF;IACA,qBACE,KAACf;QACCiB,aAAY;QACZC,WAAWd,OAAOe,MAAM;QACxBC,oBAAM,KAACnB;YAAWiB,WAAWd,OAAOgB,IAAI;;QACxCC,cAAa;QACbC,SAASb;kBACV;;AAIL"}
@@ -1,2 +1,5 @@
1
- export declare function JsonImport(): import("react/jsx-runtime").JSX.Element;
1
+ export interface JsonImportProps {
2
+ activeLocale: string;
3
+ }
4
+ export declare function JsonImport({ activeLocale }: JsonImportProps): import("react/jsx-runtime").JSX.Element;
2
5
  //# sourceMappingURL=JsonImport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"JsonImport.d.ts","sourceRoot":"","sources":["../../../src/components/actions/JsonImport.tsx"],"names":[],"mappings":"AAQA,wBAAgB,UAAU,4CAiEzB"}
1
+ {"version":3,"file":"JsonImport.d.ts","sourceRoot":"","sources":["../../../src/components/actions/JsonImport.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB;AACD,wBAAgB,UAAU,CAAC,EAAE,YAAY,EAAE,EAAE,eAAe,2CA6C3D"}
@@ -1,16 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Button } from '@payloadcms/ui';
3
3
  import { IconBraces } from '@tabler/icons-react';
4
- import { useRef, useState } from 'react';
5
- import { useMessagesForm } from '../../components/MessageFormContext';
4
+ import { useRef } from 'react';
5
+ import { useMessagesForm } from '../../components/MessagesFormProvider';
6
6
  import styles from './JsonImport.module.css';
7
- export function JsonImport() {
8
- const { locales, setValue } = useMessagesForm();
7
+ export function JsonImport({ activeLocale }) {
8
+ const { setValue } = useMessagesForm();
9
9
  const inputRef = useRef(null);
10
- const [selectedLocale, setSelectedLocale] = useState();
11
10
  const handleImportJSON = (event)=>{
12
11
  const file = event.target.files?.[0];
13
- if (!selectedLocale || !file) {
12
+ if (!file) {
14
13
  event.target.value = '';
15
14
  return;
16
15
  }
@@ -18,12 +17,10 @@ export function JsonImport() {
18
17
  reader.onload = (readerEvent)=>{
19
18
  const text = readerEvent.target?.result;
20
19
  const data = JSON.parse(text);
21
- // FIMXE this does not cause the form to re-render
22
- setValue(selectedLocale, data, {
20
+ setValue(activeLocale, data, {
23
21
  shouldDirty: true,
24
22
  shouldValidate: true
25
23
  });
26
- setSelectedLocale(undefined);
27
24
  // Clear the input value to allow re-selection of the same or different file
28
25
  event.target.value = '';
29
26
  };
@@ -45,22 +42,7 @@ export function JsonImport() {
45
42
  className: styles.icon
46
43
  }),
47
44
  iconPosition: "left",
48
- SubMenuPopupContent: ({ close })=>/*#__PURE__*/ _jsx("div", {
49
- className: styles.submenu,
50
- children: locales.map((locale)=>/*#__PURE__*/ _jsxs(Button, {
51
- buttonStyle: "subtle",
52
- onClick: ()=>{
53
- setSelectedLocale(locale);
54
- inputRef.current?.click();
55
- close();
56
- },
57
- size: "small",
58
- children: [
59
- locale,
60
- ".json"
61
- ]
62
- }, locale))
63
- }),
45
+ onClick: ()=>inputRef.current?.click(),
64
46
  children: "Import"
65
47
  })
66
48
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/actions/JsonImport.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui';\nimport { IconBraces } from '@tabler/icons-react';\nimport { useRef, useState } from 'react';\n\nimport { useMessagesForm } from '@/components/MessageFormContext';\n\nimport styles from './JsonImport.module.css';\n\nexport function JsonImport() {\n const { locales, setValue } = useMessagesForm();\n const inputRef = useRef<HTMLInputElement>(null);\n const [selectedLocale, setSelectedLocale] = useState<string>();\n\n const handleImportJSON = (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (!selectedLocale || !file) {\n event.target.value = '';\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (readerEvent) => {\n const text = readerEvent.target?.result as string;\n const data = JSON.parse(text);\n // FIMXE this does not cause the form to re-render\n setValue(selectedLocale, data, {\n shouldDirty: true,\n shouldValidate: true,\n });\n setSelectedLocale(undefined);\n // Clear the input value to allow re-selection of the same or different file\n event.target.value = '';\n };\n reader.readAsText(file);\n };\n\n return (\n <>\n <input\n accept=\".json\"\n hidden\n onChange={handleImportJSON}\n ref={inputRef}\n type=\"file\"\n />\n <Button\n buttonStyle=\"subtle\"\n className={styles.button}\n icon={<IconBraces className={styles.icon} />}\n iconPosition=\"left\"\n SubMenuPopupContent={({ close }) => (\n <div className={styles.submenu}>\n {locales.map((locale) => (\n <Button\n buttonStyle=\"subtle\"\n key={locale}\n onClick={() => {\n setSelectedLocale(locale);\n inputRef.current?.click();\n close();\n }}\n size=\"small\"\n >\n {locale}.json\n </Button>\n ))}\n </div>\n )}\n >\n Import\n </Button>\n </>\n );\n}\n"],"names":["Button","IconBraces","useRef","useState","useMessagesForm","styles","JsonImport","locales","setValue","inputRef","selectedLocale","setSelectedLocale","handleImportJSON","event","file","target","files","value","reader","FileReader","onload","readerEvent","text","result","data","JSON","parse","shouldDirty","shouldValidate","undefined","readAsText","input","accept","hidden","onChange","ref","type","buttonStyle","className","button","icon","iconPosition","SubMenuPopupContent","close","div","submenu","map","locale","onClick","current","click","size"],"mappings":";AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAEzC,SAASC,eAAe,QAAQ,kCAAkC;AAElE,OAAOC,YAAY,0BAA0B;AAE7C,OAAO,SAASC;IACd,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGJ;IAC9B,MAAMK,WAAWP,OAAyB;IAC1C,MAAM,CAACQ,gBAAgBC,kBAAkB,GAAGR;IAE5C,MAAMS,mBAAmB,CAACC;QACxB,MAAMC,OAAOD,MAAME,MAAM,CAACC,KAAK,EAAE,CAAC,EAAE;QACpC,IAAI,CAACN,kBAAkB,CAACI,MAAM;YAC5BD,MAAME,MAAM,CAACE,KAAK,GAAG;YACrB;QACF;QAEA,MAAMC,SAAS,IAAIC;QACnBD,OAAOE,MAAM,GAAG,CAACC;YACf,MAAMC,OAAOD,YAAYN,MAAM,EAAEQ;YACjC,MAAMC,OAAOC,KAAKC,KAAK,CAACJ;YACxB,kDAAkD;YAClDd,SAASE,gBAAgBc,MAAM;gBAC7BG,aAAa;gBACbC,gBAAgB;YAClB;YACAjB,kBAAkBkB;YAClB,4EAA4E;YAC5EhB,MAAME,MAAM,CAACE,KAAK,GAAG;QACvB;QACAC,OAAOY,UAAU,CAAChB;IACpB;IAEA,qBACE;;0BACE,KAACiB;gBACCC,QAAO;gBACPC,MAAM;gBACNC,UAAUtB;gBACVuB,KAAK1B;gBACL2B,MAAK;;0BAEP,KAACpC;gBACCqC,aAAY;gBACZC,WAAWjC,OAAOkC,MAAM;gBACxBC,oBAAM,KAACvC;oBAAWqC,WAAWjC,OAAOmC,IAAI;;gBACxCC,cAAa;gBACbC,qBAAqB,CAAC,EAAEC,KAAK,EAAE,iBAC7B,KAACC;wBAAIN,WAAWjC,OAAOwC,OAAO;kCAC3BtC,QAAQuC,GAAG,CAAC,CAACC,uBACZ,MAAC/C;gCACCqC,aAAY;gCAEZW,SAAS;oCACPrC,kBAAkBoC;oCAClBtC,SAASwC,OAAO,EAAEC;oCAClBP;gCACF;gCACAQ,MAAK;;oCAEJJ;oCAAO;;+BARHA;;0BAad;;;;AAKP"}
1
+ {"version":3,"sources":["../../../src/components/actions/JsonImport.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui';\nimport { IconBraces } from '@tabler/icons-react';\nimport { useRef } from 'react';\n\nimport { useMessagesForm } from '@/components/MessagesFormProvider';\n\nimport styles from './JsonImport.module.css';\n\nexport interface JsonImportProps {\n activeLocale: string;\n}\nexport function JsonImport({ activeLocale }: JsonImportProps) {\n const { setValue } = useMessagesForm();\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleImportJSON = (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (!file) {\n event.target.value = '';\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (readerEvent) => {\n const text = readerEvent.target?.result as string;\n const data = JSON.parse(text);\n setValue(activeLocale, data, {\n shouldDirty: true,\n shouldValidate: true,\n });\n // Clear the input value to allow re-selection of the same or different file\n event.target.value = '';\n };\n reader.readAsText(file);\n };\n\n return (\n <>\n <input\n accept=\".json\"\n hidden\n onChange={handleImportJSON}\n ref={inputRef}\n type=\"file\"\n />\n <Button\n buttonStyle=\"subtle\"\n className={styles.button}\n icon={<IconBraces className={styles.icon} />}\n iconPosition=\"left\"\n onClick={() => inputRef.current?.click()}\n >\n Import\n </Button>\n </>\n );\n}\n"],"names":["Button","IconBraces","useRef","useMessagesForm","styles","JsonImport","activeLocale","setValue","inputRef","handleImportJSON","event","file","target","files","value","reader","FileReader","onload","readerEvent","text","result","data","JSON","parse","shouldDirty","shouldValidate","readAsText","input","accept","hidden","onChange","ref","type","buttonStyle","className","button","icon","iconPosition","onClick","current","click"],"mappings":";AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,MAAM,QAAQ,QAAQ;AAE/B,SAASC,eAAe,QAAQ,oCAAoC;AAEpE,OAAOC,YAAY,0BAA0B;AAK7C,OAAO,SAASC,WAAW,EAAEC,YAAY,EAAmB;IAC1D,MAAM,EAAEC,QAAQ,EAAE,GAAGJ;IACrB,MAAMK,WAAWN,OAAyB;IAE1C,MAAMO,mBAAmB,CAACC;QACxB,MAAMC,OAAOD,MAAME,MAAM,CAACC,KAAK,EAAE,CAAC,EAAE;QACpC,IAAI,CAACF,MAAM;YACTD,MAAME,MAAM,CAACE,KAAK,GAAG;YACrB;QACF;QAEA,MAAMC,SAAS,IAAIC;QACnBD,OAAOE,MAAM,GAAG,CAACC;YACf,MAAMC,OAAOD,YAAYN,MAAM,EAAEQ;YACjC,MAAMC,OAAOC,KAAKC,KAAK,CAACJ;YACxBZ,SAASD,cAAce,MAAM;gBAC3BG,aAAa;gBACbC,gBAAgB;YAClB;YACA,4EAA4E;YAC5Ef,MAAME,MAAM,CAACE,KAAK,GAAG;QACvB;QACAC,OAAOW,UAAU,CAACf;IACpB;IAEA,qBACE;;0BACE,KAACgB;gBACCC,QAAO;gBACPC,MAAM;gBACNC,UAAUrB;gBACVsB,KAAKvB;gBACLwB,MAAK;;0BAEP,KAAChC;gBACCiC,aAAY;gBACZC,WAAW9B,OAAO+B,MAAM;gBACxBC,oBAAM,KAACnC;oBAAWiC,WAAW9B,OAAOgC,IAAI;;gBACxCC,cAAa;gBACbC,SAAS,IAAM9B,SAAS+B,OAAO,EAAEC;0BAClC;;;;AAKP"}
@@ -0,0 +1,12 @@
1
+ import type { DefaultNodeTypes, TypedEditorState } from '@payloadcms/richtext-lexical';
2
+ import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';
3
+ interface UseHtmlLexicalAdapterProps {
4
+ html: string;
5
+ onChange: (html: string) => void;
6
+ }
7
+ export declare function useHtmlLexicalAdapter({ html, onChange, }: UseHtmlLexicalAdapterProps): {
8
+ value: TypedEditorState<DefaultNodeTypes>;
9
+ setValue: (serializedState: SerializedEditorState) => void;
10
+ };
11
+ export {};
12
+ //# sourceMappingURL=useHtmlLexicalAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHtmlLexicalAdapter.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useHtmlLexicalAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAUtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAWlF,UAAU,0BAA0B;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,QAAQ,GACT,EAAE,0BAA0B;WAiEF,gBAAgB,CAAC,gBAAgB,CAAC;gCAjBvC,qBAAqB;EAkB1C"}
@@ -0,0 +1,63 @@
1
+ import { defaultEditorConfig, defaultEditorFeatures } from '@payloadcms/richtext-lexical';
2
+ import { buildDefaultEditorState, getEnabledNodes, sanitizeClientEditorConfig } from '@payloadcms/richtext-lexical/client';
3
+ import { $getRoot } from '@payloadcms/richtext-lexical/lexical';
4
+ import { createHeadlessEditor } from '@payloadcms/richtext-lexical/lexical/headless';
5
+ import { $generateHtmlFromNodes, $generateNodesFromDOM } from '@payloadcms/richtext-lexical/lexical/html';
6
+ import { useCallback, useMemo, useRef } from 'react';
7
+ const EMPTY_STATE = buildDefaultEditorState({});
8
+ export function useHtmlLexicalAdapter({ html, onChange }) {
9
+ // 1. Maintain a persistent headless editor for conversion
10
+ const headlessEditor = useRef(createHeadlessEditor({
11
+ nodes: getEnabledNodes({
12
+ editorConfig: sanitizeClientEditorConfig(// @ts-expect-error - FIXME
13
+ defaultEditorFeatures, defaultEditorConfig)
14
+ })
15
+ }));
16
+ // 2. HTML -> SerializedState
17
+ const getSerializedState = useCallback((htmlString)=>{
18
+ const editor = headlessEditor.current;
19
+ editor.update(()=>{
20
+ const parser = new DOMParser();
21
+ const dom = parser.parseFromString(htmlString, 'text/html');
22
+ const nodes = $generateNodesFromDOM(editor, dom);
23
+ const root = $getRoot();
24
+ root.clear().append(...nodes);
25
+ }, {
26
+ discrete: true
27
+ });
28
+ return editor.getEditorState().toJSON();
29
+ }, []);
30
+ // 3. Memoize the initial value to prevent unnecessary re-renders
31
+ const value = useMemo(()=>{
32
+ const serializedState = getSerializedState(html);
33
+ if (serializedState.root.children.length === 0) {
34
+ return EMPTY_STATE;
35
+ }
36
+ return serializedState;
37
+ }, [
38
+ html,
39
+ getSerializedState
40
+ ]);
41
+ // 4. SerializedState -> HTML
42
+ const setValue = useCallback((serializedState)=>{
43
+ const editor = headlessEditor.current;
44
+ // Update headless editor to match the incoming state
45
+ editor.setEditorState(editor.parseEditorState(serializedState));
46
+ // Generate HTML and broadcast if it has changed
47
+ editor.read(()=>{
48
+ const newHtml = $generateHtmlFromNodes(editor);
49
+ if (newHtml !== html) {
50
+ onChange(newHtml);
51
+ }
52
+ });
53
+ }, [
54
+ html,
55
+ onChange
56
+ ]);
57
+ return {
58
+ value: value,
59
+ setValue
60
+ };
61
+ }
62
+
63
+ //# sourceMappingURL=useHtmlLexicalAdapter.js.map