{"version":3,"file":"TranslationSheet.mjs","names":["React","useState","useMemo","useCallback","useTranslation","UdpDrawer","UdpFlexbox","UdpCard","UdpTextInput","UdpDropdown","UdpButton","UdpText","UdpMessageBar","TranslationScopeEnums","translateScopeName","languageDisplayName","language","t","label","code","defaultValue","id","languageId","languageNameList","langs","map","lang","join","TranslationSheetFields","languages","unityUserId","editTranslation","isEditMode","saving","setSaving","onClose","onCreate","onUpdate","onSaved","onSuggest","tierOptions","Brand","value","String","Tenant","User","setLabel","tier","setTier","entriesByLanguage","setEntriesByLanguage","editValue","setEditValue","suggesting","setSuggesting","feedback","setFeedback","valueOf","handleValueChange","prev","suggested","filledLanguages","filter","trim","canSave","length","translatableLanguages","suggestSourceLanguage","find","suggestTargetLanguages","showSuggest","canSuggest","suggestStatus","source","handleSuggest","suggestions","sourceLanguageCode","content","context","targetLanguageCodes","Array","isArray","intent","text","next","forEach","suggestion","target","toLowerCase","handleSave","ok","translationId","languageIds","results","Promise","all","scope","Number","then","outcome","created","r","duplicates","errors","parts","push","count","e","l","undefined","TranslationSheet","t0","$","_c","open","t1","handleClose","t2","t3","t4","t5"],"sources":["../../../../src/udp/pages/UdpTranslationsPage/TranslationSheet.jsx"],"sourcesContent":["import React, { useState, useMemo, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { UdpDrawer } from '../../../UI/fluent-web-components/UdpDrawer';\nimport { UdpFlexbox } from '../../../UI/fluent-web-components/UdpFlexbox';\nimport { UdpCard } from '../../../UI/fluent-web-components/UdpCard';\nimport { UdpTextInput } from '../../../UI/fluent-web-components/UdpTextInput';\nimport { UdpDropdown } from '../../../UI/fluent-web-components/UdpDropdown';\nimport { UdpButton } from '../../../UI/fluent-web-components/UdpButton';\nimport { UdpText } from '../../../UI/fluent-web-components/UdpText';\nimport { UdpMessageBar } from '../../../UI/fluent-web-components/UdpMessageBar';\nimport {\n  TranslationScopeEnums,\n  translateScopeName\n} from '../../../enums/translationEnums';\n\nconst languageDisplayName = (language, t) =>\n  language?.label ||\n  language?.code ||\n  t('translations.page.languageFallback', {\n    defaultValue: 'Language {{id}}',\n    id: language?.languageId\n  });\n\nconst languageNameList = (langs, t) =>\n  langs.map((lang) => languageDisplayName(lang, t)).join(', ');\n\n/**\n * Fields + footer for the create/edit sheet. Rendered as a child of UdpDrawer,\n * which unmounts its children once the sheet closes - so every state value here\n * is seeded at mount and needs no reset effect. Keyed on the edit target so\n * switching targets while open remounts too.\n */\nconst TranslationSheetFields = ({\n  languages,\n  unityUserId,\n  editTranslation,\n  isEditMode,\n  saving,\n  setSaving,\n  onClose,\n  onCreate,\n  onUpdate,\n  onSaved,\n  onSuggest,\n}) => {\n  const { t } = useTranslation();\n\n  // Creatable tiers (Product rows are seeded by migration scripts only).\n  // Values are strings and the dropdown uses valueAs='value': by default the\n  // stencil dropdown emits/matches the whole OPTION OBJECT, which breaks\n  // primitive controlled state (selection renders blank after the first change).\n  const tierOptions = useMemo(\n    () => [\n      {\n        label: translateScopeName(t, TranslationScopeEnums.Brand),\n        value: String(TranslationScopeEnums.Brand)\n      },\n      {\n        label: translateScopeName(t, TranslationScopeEnums.Tenant),\n        value: String(TranslationScopeEnums.Tenant)\n      },\n      {\n        label: t('translations.sheet.userTier', {\n          defaultValue: 'User (only you)'\n        }),\n        value: String(TranslationScopeEnums.User)\n      }\n    ],\n    [t]\n  );\n\n  const [label, setLabel] = useState(isEditMode ? editTranslation.label ?? '' : '');\n  const [tier, setTier] = useState(String(TranslationScopeEnums.Brand)); // Brand by default\n  // create mode: { [languageId]: { value, suggested } }. `suggested` records\n  // that the AI wrote the value and the user has not touched it since - the\n  // only signal that tells them which values still need review. Kept in the\n  // same state entry as the value so the flag can never drift from it.\n  const [entriesByLanguage, setEntriesByLanguage] = useState({});\n  // edit mode: single value\n  const [editValue, setEditValue] = useState(\n    isEditMode ? editTranslation.value ?? '' : ''\n  );\n  const [suggesting, setSuggesting] = useState(false);\n  const [feedback, setFeedback] = useState(null);\n\n  const valueOf = useCallback(\n    (languageId) => entriesByLanguage[languageId]?.value ?? '',\n    [entriesByLanguage]\n  );\n\n  const handleValueChange = useCallback((languageId, value) => {\n    // Typing over a suggestion makes it the user's own text, so the \"AI\n    // suggestion\" hint on that field clears with the same edit.\n    setEntriesByLanguage((prev) => ({\n      ...prev,\n      [languageId]: { value, suggested: false }\n    }));\n  }, []);\n\n  // Languages that will actually produce a row on Create.\n  const filledLanguages = useMemo(\n    () => languages.filter((lang) => valueOf(lang.languageId).trim()),\n    [languages, valueOf]\n  );\n\n  const canSave = useMemo(() => {\n    if (!label.trim()) return false;\n    return isEditMode ? editValue.trim().length > 0 : filledLanguages.length > 0;\n  }, [label, isEditMode, editValue, filledLanguages]);\n\n  // The suggest API is keyed by language CODE (stable across databases, unlike\n  // the languageId GUIDs), so only coded languages can take part. Gate the\n  // whole affordance on these - gating on `languages` renders a permanently\n  // dead button when the configured languages have no codes.\n  const translatableLanguages = useMemo(\n    () => languages.filter((lang) => lang.code),\n    [languages]\n  );\n\n  // Suggest source: the FIRST language with a value; targets: the empty ones.\n  const suggestSourceLanguage = useMemo(\n    () =>\n      translatableLanguages.find((lang) => valueOf(lang.languageId).trim()) ??\n      null,\n    [translatableLanguages, valueOf]\n  );\n\n  const suggestTargetLanguages = useMemo(\n    () =>\n      translatableLanguages.filter((lang) => !valueOf(lang.languageId).trim()),\n    [translatableLanguages, valueOf]\n  );\n\n  const showSuggest =\n    !!onSuggest && !isEditMode && translatableLanguages.length > 1;\n\n  const canSuggest =\n    showSuggest && !!suggestSourceLanguage && suggestTargetLanguages.length > 0;\n\n  // One line that states the action's contract in every state: what it needs,\n  // what it will do, or why it is disabled. A greyed-out button with no reason\n  // is a dead end - especially for an action whose source language is inferred\n  // rather than chosen.\n  const suggestStatus = useMemo(() => {\n    if (!suggestSourceLanguage) {\n      return t('translations.suggest.hint', {\n        defaultValue:\n          'Fill in one language, then suggest translations for the rest.'\n      });\n    }\n    if (suggestTargetLanguages.length === 0) {\n      return t('translations.suggest.hintAllFilled', {\n        defaultValue:\n          'Every language already has a value - clear one to suggest again.'\n      });\n    }\n    return t('translations.suggest.hintReady', {\n      defaultValue: 'Translates from {{source}} into: {{languages}}.',\n      source: languageDisplayName(suggestSourceLanguage, t),\n      languages: languageNameList(suggestTargetLanguages, t)\n    });\n  }, [suggestSourceLanguage, suggestTargetLanguages, t]);\n\n  const handleSuggest = useCallback(async () => {\n    if (!canSuggest || suggesting) return;\n    const source = suggestSourceLanguage;\n    setSuggesting(true);\n    setFeedback(null);\n    try {\n      const suggestions = await onSuggest({\n        sourceLanguageCode: source.code,\n        content: valueOf(source.languageId),\n        context: label.trim() || null,\n        targetLanguageCodes: suggestTargetLanguages.map((lang) => lang.code)\n      });\n      // null => request failed (the hook already toasted the error).\n      if (!Array.isArray(suggestions)) return;\n      if (suggestions.length === 0) {\n        setFeedback({\n          intent: 'warning',\n          text: t('translations.suggest.none', {\n            defaultValue: 'No suggestions were returned.'\n          })\n        });\n        return;\n      }\n      // Fill EMPTY fields only - never clobber something the user typed while\n      // the request was in flight. Suggestions are matched by CODE against the\n      // local language list (ids can differ across backends).\n      setEntriesByLanguage((prev) => {\n        const next = { ...prev };\n        suggestions.forEach((suggestion) => {\n          const target = languages.find(\n            (lang) =>\n              lang.code &&\n              lang.code.toLowerCase() === suggestion.code?.toLowerCase()\n          );\n          if (target && !(next[target.languageId]?.value ?? '').trim()) {\n            next[target.languageId] = {\n              value: suggestion.value,\n              suggested: true\n            };\n          }\n        });\n        return next;\n      });\n      // Suggestions land in fields further down a scrollable sheet, so confirm\n      // what happened - including that nothing has been saved yet.\n      setFeedback({\n        intent: 'success',\n        text: t('translations.suggest.filled', {\n          defaultValue:\n            'Suggestions added from {{source}}. Review each one before creating - nothing is saved yet.',\n          source: languageDisplayName(source, t)\n        })\n      });\n    } finally {\n      setSuggesting(false);\n    }\n  }, [\n    canSuggest,\n    suggesting,\n    onSuggest,\n    suggestSourceLanguage,\n    suggestTargetLanguages,\n    valueOf,\n    label,\n    languages,\n    t\n  ]);\n\n  const handleSave = useCallback(async () => {\n    if (!canSave) return;\n    setSaving(true);\n    setFeedback(null);\n    try {\n      if (isEditMode) {\n        const ok = await onUpdate({\n          translationId: editTranslation.translationId,\n          languageId: editTranslation.languageId,\n          label: label.trim(),\n          value: editValue,\n          unityUserId: editTranslation.unityUserId ?? null,\n        });\n        if (ok) {\n          onSaved?.({ languageIds: [editTranslation.languageId] });\n          onClose?.();\n        }\n        return;\n      }\n\n      // Create mode: one POST per language that has a value.\n      const results = await Promise.all(\n        filledLanguages.map((lang) =>\n          onCreate({\n            languageId: lang.languageId,\n            label: label.trim(),\n            value: valueOf(lang.languageId),\n            scope: Number(tier),\n            unityUserId: Number(tier) === TranslationScopeEnums.User ? unityUserId : null,\n          }).then((outcome) => ({ lang, outcome }))\n        )\n      );\n\n      const created = results.filter((r) => r.outcome === 'created');\n      const duplicates = results.filter((r) => r.outcome === 'duplicate');\n      const errors = results.filter((r) => r.outcome === 'error');\n\n      if (duplicates.length || errors.length) {\n        const parts = [];\n        if (created.length)\n          parts.push(t('translations.sheet.createdCount', {\n              defaultValue: '{{count}} created',\n              count: created.length\n            }));\n        if (duplicates.length)\n          parts.push(\n            t('translations.sheet.skippedCount', {\n              defaultValue:\n                '{{count}} skipped (this label already exists on the {{tier}} tier for: {{languages}})',\n              count: duplicates.length,\n              tier: translateScopeName(t, Number(tier)),\n              languages: languageNameList(\n                duplicates.map((r) => r.lang),\n                t\n              )\n            })\n          );\n        if (errors.length)\n          parts.push(\n            t('translations.sheet.failedCount', {\n              defaultValue: '{{count}} failed ({{languages}})',\n              count: errors.length,\n              languages: languageNameList(\n                errors.map((r) => r.lang),\n                t\n              )\n            })\n          );\n        setFeedback({ intent: errors.length ? 'error' : 'warning', text: parts.join('. ') });\n        if (created.length)\n          onSaved?.({ languageIds: created.map((r) => r.lang.languageId) });\n        return;\n      }\n\n      onSaved?.({ languageIds: created.map((r) => r.lang.languageId) });\n      onClose?.();\n    } finally {\n      setSaving(false);\n    }\n  }, [\n    canSave,\n    isEditMode,\n    setSaving,\n    onUpdate,\n    onCreate,\n    editTranslation,\n    label,\n    tier,\n    unityUserId,\n    editValue,\n    filledLanguages,\n    valueOf,\n    onSaved,\n    onClose,\n    t,\n  ]);\n\n  return (\n    <>\n      <UdpFlexbox direction='column' gap='md' width='100%'>\n        {/* Multiline: the aggregate create result enumerates languages and\n            outgrows a single line. Dismissible so a stale result can be\n            cleared without closing the sheet. */}\n        {feedback && (\n          <UdpMessageBar\n            intent={feedback.intent}\n            layout='multiline'\n            dismissible\n            onDismiss={() => setFeedback(null)}\n          >\n            {feedback.text}\n          </UdpMessageBar>\n        )}\n\n        {isEditMode ? (\n          <>\n            <UdpTextInput\n              label={t('translations.fields.label', { defaultValue: 'Label' })}\n              value={label}\n              required\n              disabled /* renaming the key is uncommon; keep label stable on edit */\n              hint={t('translations.sheet.labelFixedHint', {\n                defaultValue: 'The label cannot be changed here.'\n              })}\n              onChange={(e) => setLabel(e.target.value)}\n            />\n            <UdpText>\n              {t('translations.fields.language', { defaultValue: 'Language' })}:{' '}\n              {languageDisplayName(\n                languages.find((l) => l.languageId === editTranslation.languageId) ?? {\n                  languageId: editTranslation.languageId,\n                },\n                t\n              )}\n            </UdpText>\n            <UdpTextInput\n              label={t('translations.fields.value', { defaultValue: 'Value' })}\n              value={editValue}\n              required\n              onChange={(e) => setEditValue(e.target.value)}\n            />\n          </>\n        ) : (\n          <>\n            {/* Two named groups: what the entry IS, then its values. Without\n                them the tier dropdown, the key and one field per language read\n                as a single undifferentiated stack of inputs. */}\n            <UdpCard\n              appearance='muted'\n              label={t('translations.sheet.detailsSection', {\n                defaultValue: 'Translation details'\n              })}\n            >\n              <UdpFlexbox direction='column' gap='md' width='100%'>\n                <UdpDropdown\n                  label={t('translations.sheet.type', {\n                    defaultValue: 'Translation type'\n                  })}\n                  options={tierOptions}\n                  value={tier}\n                  optionLabel='label'\n                  optionValue='value'\n                  valueAs='value'\n                  hint={t('translations.sheet.typeHint', {\n                    defaultValue:\n                      'Brand applies to everyone on the brand; Tenant to this tenant; User only to you.'\n                  })}\n                  onChange={(e) => setTier(String(e.target.value))}\n                />\n                <UdpTextInput\n                  label={t('translations.fields.label', {\n                    defaultValue: 'Label'\n                  })}\n                  value={label}\n                  required\n                  hint={t('translations.sheet.labelHint', {\n                    defaultValue:\n                      'Use dot notation to group keys, e.g. \"customer.form.firstName\".'\n                  })}\n                  onChange={(e) => setLabel(e.target.value)}\n                />\n              </UdpFlexbox>\n            </UdpCard>\n\n            {languages.length === 0 ? (\n              <UdpMessageBar intent='warning' layout='multiline'>\n                {t('translations.sheet.noLanguages', {\n                  defaultValue:\n                    'No languages are configured yet. Add a language before creating translations.'\n                })}\n              </UdpMessageBar>\n            ) : (\n              <UdpCard\n                appearance='muted'\n                label={t('translations.sheet.valuesSection', {\n                  defaultValue: 'Values by language'\n                })}\n                subtitle={t('translations.sheet.valuesHint', {\n                  defaultValue: 'Languages you leave blank are not created.'\n                })}\n              >\n                {/* In the group header, not below the fields: Suggest fills the\n                    inputs beneath it, and past the second language a footer\n                    button sits below the fold of a medium drawer. */}\n                {showSuggest && (\n                  <UdpButton\n                    slot='header-action'\n                    appearance='outline'\n                    size='small'\n                    startIconName='wand'\n                    onClick={handleSuggest}\n                    disabled={!canSuggest || saving}\n                    loading={suggesting}\n                  >\n                    {t('translations.suggest.button', {\n                      defaultValue: 'Suggest translations'\n                    })}\n                  </UdpButton>\n                )}\n                <UdpFlexbox direction='column' gap='md' width='100%'>\n                  {showSuggest && (\n                    <UdpText variant='caption1'>{suggestStatus}</UdpText>\n                  )}\n                  {languages.map((lang) => (\n                    <UdpTextInput\n                      key={lang.languageId}\n                      label={languageDisplayName(lang, t)}\n                      value={valueOf(lang.languageId)}\n                      hint={\n                        entriesByLanguage[lang.languageId]?.suggested\n                          ? t('translations.suggest.fieldHint', {\n                              defaultValue:\n                                'AI suggestion - review before creating.'\n                            })\n                          : undefined\n                      }\n                      onChange={(e) =>\n                        handleValueChange(lang.languageId, e.target.value)\n                      }\n                    />\n                  ))}\n                </UdpFlexbox>\n              </UdpCard>\n            )}\n          </>\n        )}\n      </UdpFlexbox>\n\n      {/* No Cancel here - the drawer's own close handles dismissal. */}\n      <UdpFlexbox\n        slot='footer'\n        direction='column'\n        align='flex-end'\n        gap='xs'\n        width='100%'\n      >\n        {/* One Create writes a row per filled language at the chosen tier -\n            state the outcome instead of leaving it to be inferred. */}\n        {!isEditMode && canSave && (\n          <UdpText variant='caption1'>\n            {t('translations.sheet.createSummary', {\n              defaultValue: 'Creates {{tier}} entries for: {{languages}}',\n              tier: translateScopeName(t, Number(tier)),\n              languages: languageNameList(filledLanguages, t)\n            })}\n          </UdpText>\n        )}\n        <UdpButton appearance='primary' onClick={handleSave} disabled={!canSave} loading={saving}>\n          {isEditMode\n            ? t('common.save', { defaultValue: 'Save' })\n            : t('common.create', { defaultValue: 'Create' })}\n        </UdpButton>\n      </UdpFlexbox>\n    </>\n  );\n};\n\n/**\n * Create/edit sheet for translations.\n *\n * Create mode: one Label field plus one Value field per language. On save we\n * create a row only for languages with a non-empty value (so 3 languages can\n * yield up to 3 rows; blanks are skipped).\n *\n * Edit mode: a single existing translation row (fixed language) - edit its\n * label/value and PATCH it.\n *\n * Create mode can also SUGGEST: the first language with a value is the source,\n * and the AI gateway fills every empty language field with an editable\n * suggestion (nothing is saved until Create). Suggested fields stay marked as\n * such until the user edits them.\n */\nexport const TranslationSheet = ({\n  open,\n  onClose,\n  languages,\n  unityUserId, // required when creating User-tier entries\n  editTranslation,\n  onCreate,\n  onUpdate,\n  onSaved,\n  onSuggest,\n}) => {\n  const isEditMode = !!editTranslation;\n  const { t } = useTranslation();\n\n  // Owned here rather than in the fields: dismissal is a drawer-level concern\n  // and must stay blocked while a save is in flight.\n  const [saving, setSaving] = useState(false);\n\n  const handleClose = useCallback(() => {\n    if (saving) return;\n    onClose?.();\n  }, [saving, onClose]);\n\n  return (\n    <UdpDrawer\n      open={open}\n      drawerTitle={\n        isEditMode\n          ? t('translations.sheet.editTitle', { defaultValue: 'Edit Translation' })\n          : t('translations.sheet.createTitle', {\n              defaultValue: 'Create Translation'\n            })\n      }\n      size='medium'\n      onDrawerClose={handleClose}\n    >\n      <TranslationSheetFields\n        key={editTranslation?.translationId ?? 'create'}\n        languages={languages}\n        unityUserId={unityUserId}\n        editTranslation={editTranslation}\n        isEditMode={isEditMode}\n        saving={saving}\n        setSaving={setSaving}\n        onClose={onClose}\n        onCreate={onCreate}\n        onUpdate={onUpdate}\n        onSaved={onSaved}\n        onSuggest={onSuggest}\n      />\n    </UdpDrawer>\n  );\n};\n"],"mappings":"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"}