@powerportalspro/react-fluent 5.1.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -9030,7 +9030,13 @@ function MainGridImpl({
9030
9030
  (row) => row.properties?.[columnName],
9031
9031
  {
9032
9032
  id: columnName,
9033
- header: () => resolvedColumn.displayName,
9033
+ // Headers normally show the server-resolved Dataverse display name, which bypasses the
9034
+ // client `t()` — so the ?ppp-show-keys aid couldn't reach them. Consult key-mode here too:
9035
+ // when it's on, show the column's localization key (the one a consumer would override),
9036
+ // keyed by the column's OWN owning table (`resolvedColumn.tableName` — the related table
9037
+ // for a linked-entity column, not the grid's primary table). For linked columns the name
9038
+ // is a dotted alias path, so take the segment after the last dot as the real column name.
9039
+ header: () => react$1.isKeyModeEnabled() ? `tables.${resolvedColumn.tableName}.columns.${columnName.split(".").pop() ?? columnName}.label` : resolvedColumn.displayName,
9034
9040
  cell: (cellCtx) => {
9035
9041
  const rowRecord = cellCtx.row.original;
9036
9042
  const rowId = rowRecord.id;
@@ -13573,27 +13579,57 @@ function NavMenu({ children, width, className, style }) {
13573
13579
  useNavSelectedStyles();
13574
13580
  const location = reactRouterDom.useLocation();
13575
13581
  const navigate = reactRouterDom.useNavigate();
13576
- const { allRoutes, defaultOpen } = react.useMemo(
13582
+ const { allRoutes, groups, defaultOpenIndexes } = react.useMemo(
13577
13583
  () => collectNavTree(children),
13578
13584
  [children]
13579
13585
  );
13580
- const selectedValue = react.useMemo(
13586
+ const selectedRoute = react.useMemo(
13581
13587
  () => bestRouteMatch(allRoutes, location.pathname),
13582
13588
  [allRoutes, location.pathname]
13583
13589
  );
13590
+ const [openIndexes, setOpenIndexes] = react.useState(
13591
+ () => /* @__PURE__ */ new Set([
13592
+ ...defaultOpenIndexes,
13593
+ // Seed the active route's group too, so it's open on first paint
13594
+ // (the effect below only fires after mount).
13595
+ ...selectedRoute && selectedRoute.groupIndex >= 0 ? [selectedRoute.groupIndex] : []
13596
+ ])
13597
+ );
13598
+ const selectedGroupIndex = selectedRoute?.groupIndex ?? -1;
13599
+ react.useEffect(() => {
13600
+ if (selectedGroupIndex < 0) return;
13601
+ setOpenIndexes(
13602
+ (prev) => prev.has(selectedGroupIndex) ? prev : new Set(prev).add(selectedGroupIndex)
13603
+ );
13604
+ }, [selectedGroupIndex]);
13605
+ const openCategories = react.useMemo(
13606
+ () => groups.filter((_, index) => openIndexes.has(index)),
13607
+ [groups, openIndexes]
13608
+ );
13584
13609
  const handleSelect = (_, data) => {
13585
13610
  const value = data.value;
13586
13611
  if (typeof value === "string" && value.startsWith("/")) {
13587
13612
  navigate(value);
13588
13613
  }
13589
13614
  };
13615
+ const handleCategoryToggle = (_, data) => {
13616
+ const index = groups.indexOf(data.value);
13617
+ if (index < 0) return;
13618
+ setOpenIndexes((prev) => {
13619
+ const next = new Set(prev);
13620
+ if (next.has(index)) next.delete(index);
13621
+ else next.add(index);
13622
+ return next;
13623
+ });
13624
+ };
13590
13625
  const navStyle = width ? { ...style, minWidth: width, maxWidth: width } : style;
13591
13626
  return /* @__PURE__ */ jsxRuntime.jsx(
13592
13627
  reactNav.Nav,
13593
13628
  {
13594
- selectedValue: selectedValue ?? "",
13629
+ selectedValue: selectedRoute?.to ?? "",
13595
13630
  onNavItemSelect: handleSelect,
13596
- defaultOpenCategories: defaultOpen,
13631
+ openCategories,
13632
+ onNavCategoryItemToggle: handleCategoryToggle,
13597
13633
  className: reactComponents.mergeClasses("ppp-nav-menu", styles.nav, className),
13598
13634
  style: navStyle,
13599
13635
  children
@@ -13623,42 +13659,46 @@ function NavItem({ to, icon, children }) {
13623
13659
  }
13624
13660
  function collectNavTree(children) {
13625
13661
  const allRoutes = [];
13626
- const defaultOpen = [];
13627
- const visit = (nodes) => {
13662
+ const groups = [];
13663
+ const defaultOpenIndexes = [];
13664
+ const visit = (nodes, groupIndex) => {
13628
13665
  react.Children.forEach(nodes, (child) => {
13629
13666
  if (!react.isValidElement(child)) return;
13630
13667
  if (child.type === NavGroup) {
13631
13668
  const props = child.props;
13632
13669
  const value = props.value ?? `group:${props.label}`;
13633
- if (props.defaultExpanded) defaultOpen.push(value);
13634
- visit(props.children);
13670
+ const index = groups.length;
13671
+ groups.push(value);
13672
+ if (props.defaultExpanded) defaultOpenIndexes.push(index);
13673
+ visit(props.children, index);
13635
13674
  return;
13636
13675
  }
13637
13676
  if (child.type === NavItem) {
13638
13677
  const props = child.props;
13639
13678
  allRoutes.push({
13640
13679
  to: props.to,
13641
- match: props.match ?? (props.to === "/" ? "exact" : "prefix")
13680
+ match: props.match ?? (props.to === "/" ? "exact" : "prefix"),
13681
+ groupIndex
13642
13682
  });
13643
13683
  return;
13644
13684
  }
13645
13685
  const wrapperChildren = child.props.children;
13646
- if (wrapperChildren !== void 0) visit(wrapperChildren);
13686
+ if (wrapperChildren !== void 0) visit(wrapperChildren, groupIndex);
13647
13687
  });
13648
13688
  };
13649
- visit(children);
13650
- return { allRoutes, defaultOpen };
13689
+ visit(children, -1);
13690
+ return { allRoutes, groups, defaultOpenIndexes };
13651
13691
  }
13652
13692
  function bestRouteMatch(routes, pathname) {
13653
13693
  const normalize = (p) => p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
13654
13694
  const target = normalize(pathname);
13655
13695
  let best;
13656
13696
  let bestLen = -1;
13657
- for (const { to, match } of routes) {
13658
- const route = normalize(to);
13659
- const matches = route === target || match === "prefix" && (route === "/" || target.startsWith(route + "/"));
13697
+ for (const candidate of routes) {
13698
+ const route = normalize(candidate.to);
13699
+ const matches = route === target || candidate.match === "prefix" && (route === "/" || target.startsWith(route + "/"));
13660
13700
  if (matches && route.length > bestLen) {
13661
- best = to;
13701
+ best = candidate;
13662
13702
  bestLen = route.length;
13663
13703
  }
13664
13704
  }
@@ -14401,8 +14441,28 @@ var useStyles12 = reactComponents.makeStyles({
14401
14441
  mergedButtons: {
14402
14442
  display: "flex",
14403
14443
  flexWrap: "wrap",
14404
- gap: reactComponents.tokens.spacingHorizontalS
14444
+ gap: reactComponents.tokens.spacingHorizontalL
14445
+ },
14446
+ // One culture group: language label + inspect button + download button, kept together.
14447
+ mergedCulture: {
14448
+ display: "flex",
14449
+ alignItems: "center",
14450
+ gap: reactComponents.tokens.spacingHorizontalXS
14405
14451
  },
14452
+ mergedCultureLabel: { fontSize: reactComponents.tokens.fontSizeBase200 },
14453
+ dialogSurface: { maxWidth: "1100px", width: "90vw" },
14454
+ dialogToolbar: {
14455
+ display: "flex",
14456
+ alignItems: "center",
14457
+ gap: reactComponents.tokens.spacingHorizontalM,
14458
+ flexWrap: "wrap",
14459
+ marginBottom: reactComponents.tokens.spacingVerticalS
14460
+ },
14461
+ // Scroll viewport for the merged grid so a tall result set scrolls inside the dialog.
14462
+ dialogGrid: { maxHeight: "60vh", overflowY: "auto", overflowX: "auto" },
14463
+ filterInput: { minWidth: "260px" },
14464
+ pager: { display: "flex", alignItems: "center", gap: reactComponents.tokens.spacingHorizontalS },
14465
+ grow: { flex: 1 },
14406
14466
  sectionBody: {
14407
14467
  display: "flex",
14408
14468
  flexDirection: "column",
@@ -14421,6 +14481,15 @@ function downloadBytes(fileName, data, contentType = "application/json") {
14421
14481
  anchor.click();
14422
14482
  URL.revokeObjectURL(url);
14423
14483
  }
14484
+ var kindKeyOf = (kind) => KIND_KEY[Number(kind)] ?? "tablemetadata";
14485
+ function cultureLabel(culture) {
14486
+ try {
14487
+ const name = new Intl.DisplayNames(void 0, { type: "language" }).of(culture);
14488
+ return name && name.toLowerCase() !== culture.toLowerCase() ? `${name} (${culture})` : culture;
14489
+ } catch {
14490
+ return culture;
14491
+ }
14492
+ }
14424
14493
  function LocalizationAdmin({ className }) {
14425
14494
  const styles = useStyles12();
14426
14495
  const t = react$1.useT();
@@ -14430,6 +14499,7 @@ function LocalizationAdmin({ className }) {
14430
14499
  const [isReloading, setIsReloading] = react.useState(false);
14431
14500
  const [isDownloading, setIsDownloading] = react.useState(false);
14432
14501
  const [message, setMessage] = react.useState();
14502
+ const [mergedDialogCulture, setMergedDialogCulture] = react.useState(null);
14433
14503
  const loadOverview = react.useCallback(async () => {
14434
14504
  try {
14435
14505
  const value = await ppp.getLocalizationOverviewAsync();
@@ -14587,17 +14657,44 @@ function LocalizationAdmin({ className }) {
14587
14657
  /* @__PURE__ */ jsxRuntime.jsx(LocalizationTranslator, {}),
14588
14658
  availableCultures.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Section, { headerText: t("app.localization-admin.download-merged-title"), borderVisible: true, children: /* @__PURE__ */ jsxRuntime.jsx(SectionColumn, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sectionBody, children: [
14589
14659
  /* @__PURE__ */ jsxRuntime.jsx(reactComponents.Text, { children: t("app.localization-admin.download-merged-description") }),
14590
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.mergedButtons, children: availableCultures.map((culture) => /* @__PURE__ */ jsxRuntime.jsx(
14591
- reactComponents.Button,
14592
- {
14593
- appearance: "outline",
14594
- disabled: isDownloading,
14595
- icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowDownloadRegular, {}),
14596
- onClick: () => onDownloadMerged(culture),
14597
- children: culture
14598
- },
14599
- culture
14600
- )) })
14660
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.mergedButtons, children: availableCultures.map((culture) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.mergedCulture, children: [
14661
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.mergedCultureLabel, children: cultureLabel(culture) }),
14662
+ /* @__PURE__ */ jsxRuntime.jsx(
14663
+ reactComponents.Tooltip,
14664
+ {
14665
+ content: t("app.localization-admin.view-merged-tooltip", [
14666
+ cultureLabel(culture)
14667
+ ]),
14668
+ relationship: "label",
14669
+ children: /* @__PURE__ */ jsxRuntime.jsx(
14670
+ reactComponents.Button,
14671
+ {
14672
+ appearance: "outline",
14673
+ icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.EyeRegular, {}),
14674
+ onClick: () => setMergedDialogCulture(culture)
14675
+ }
14676
+ )
14677
+ }
14678
+ ),
14679
+ /* @__PURE__ */ jsxRuntime.jsx(
14680
+ reactComponents.Tooltip,
14681
+ {
14682
+ content: t("app.localization-admin.download-merged-tooltip", [
14683
+ cultureLabel(culture)
14684
+ ]),
14685
+ relationship: "label",
14686
+ children: /* @__PURE__ */ jsxRuntime.jsx(
14687
+ reactComponents.Button,
14688
+ {
14689
+ appearance: "subtle",
14690
+ disabled: isDownloading,
14691
+ icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowDownloadRegular, {}),
14692
+ onClick: () => onDownloadMerged(culture)
14693
+ }
14694
+ )
14695
+ }
14696
+ )
14697
+ ] }, culture)) })
14601
14698
  ] }) }) }),
14602
14699
  /* @__PURE__ */ jsxRuntime.jsx(Section, { headerText: t("app.localization-admin.sources-title"), borderVisible: true, children: /* @__PURE__ */ jsxRuntime.jsx(SectionColumn, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sectionBody, children: [
14603
14700
  /* @__PURE__ */ jsxRuntime.jsx(reactComponents.Text, { children: t("app.localization-admin.sources-description") }),
@@ -14628,7 +14725,22 @@ function LocalizationAdmin({ className }) {
14628
14725
  ] }) }) })
14629
14726
  ] });
14630
14727
  }
14631
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: reactComponents.mergeClasses("ppp-localization-admin", styles.root, className), children: content });
14728
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: reactComponents.mergeClasses("ppp-localization-admin", styles.root, className), children: [
14729
+ content,
14730
+ mergedDialogCulture !== null && /* @__PURE__ */ jsxRuntime.jsx(
14731
+ MergedSourcesDialog,
14732
+ {
14733
+ culture: mergedDialogCulture,
14734
+ label: cultureLabel(mergedDialogCulture),
14735
+ onClose: () => setMergedDialogCulture(null),
14736
+ onDownload: () => onDownloadMerged(mergedDialogCulture),
14737
+ isDownloading,
14738
+ ppp,
14739
+ t,
14740
+ styles
14741
+ }
14742
+ )
14743
+ ] });
14632
14744
  }
14633
14745
  function ConfigRow({ styles, label, value }) {
14634
14746
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -14678,6 +14790,177 @@ function SourceRow({
14678
14790
  )) }) })
14679
14791
  ] });
14680
14792
  }
14793
+ var MERGED_PAGE_SIZE = 100;
14794
+ function MergedSourcesDialog({
14795
+ culture,
14796
+ label,
14797
+ onClose,
14798
+ onDownload,
14799
+ isDownloading,
14800
+ ppp,
14801
+ t,
14802
+ styles
14803
+ }) {
14804
+ const [entries, setEntries] = react.useState(null);
14805
+ const [loadError, setLoadError] = react.useState();
14806
+ const [filter, setFilter] = react.useState("");
14807
+ const [page, setPage] = react.useState(0);
14808
+ const [sortState, setSortState] = react.useState({
14809
+ sortColumn: "key",
14810
+ sortDirection: "ascending"
14811
+ });
14812
+ react.useEffect(() => {
14813
+ let cancelled = false;
14814
+ void (async () => {
14815
+ try {
14816
+ const value = await ppp.getMergedLocalizationEntriesAsync(culture);
14817
+ if (!cancelled) {
14818
+ setEntries(value);
14819
+ setLoadError(void 0);
14820
+ }
14821
+ } catch (reason) {
14822
+ if (!cancelled) {
14823
+ setEntries(null);
14824
+ setLoadError(reason instanceof Error ? reason.message : String(reason));
14825
+ }
14826
+ }
14827
+ })();
14828
+ return () => {
14829
+ cancelled = true;
14830
+ };
14831
+ }, [ppp, culture]);
14832
+ const columns = react.useMemo(
14833
+ () => [
14834
+ reactComponents.createTableColumn({
14835
+ columnId: "key",
14836
+ compare: (a, b) => a.key.localeCompare(b.key),
14837
+ renderHeaderCell: () => t("app.localization-admin.merged-column-key"),
14838
+ renderCell: (item) => item.key
14839
+ }),
14840
+ reactComponents.createTableColumn({
14841
+ columnId: "kind",
14842
+ compare: (a, b) => Number(a.sourceKind) - Number(b.sourceKind),
14843
+ renderHeaderCell: () => t("app.localization-admin.merged-column-kind"),
14844
+ renderCell: (item) => t(`app.localization-admin.kind-${kindKeyOf(item.sourceKind)}`)
14845
+ }),
14846
+ reactComponents.createTableColumn({
14847
+ columnId: "source",
14848
+ compare: (a, b) => a.sourceDisplayName.localeCompare(b.sourceDisplayName),
14849
+ renderHeaderCell: () => t("app.localization-admin.merged-column-source"),
14850
+ renderCell: (item) => item.sourceDisplayName
14851
+ }),
14852
+ reactComponents.createTableColumn({
14853
+ columnId: "value",
14854
+ compare: (a, b) => a.value.localeCompare(b.value),
14855
+ renderHeaderCell: () => t("app.localization-admin.merged-column-value"),
14856
+ renderCell: (item) => item.value
14857
+ })
14858
+ ],
14859
+ [t]
14860
+ );
14861
+ const filtered = react.useMemo(() => {
14862
+ if (!entries) return [];
14863
+ const q = filter.trim().toLowerCase();
14864
+ const base = q ? entries.filter(
14865
+ (e) => e.key.toLowerCase().includes(q) || e.value.toLowerCase().includes(q) || e.sourceDisplayName.toLowerCase().includes(q)
14866
+ ) : entries;
14867
+ return [...base];
14868
+ }, [entries, filter]);
14869
+ const sorted = react.useMemo(() => {
14870
+ const column = columns.find((c) => c.columnId === sortState.sortColumn);
14871
+ if (!column?.compare) return filtered;
14872
+ const sign = sortState.sortDirection === "ascending" ? 1 : -1;
14873
+ return [...filtered].sort((a, b) => sign * column.compare(a, b));
14874
+ }, [filtered, columns, sortState]);
14875
+ react.useEffect(() => {
14876
+ setPage(0);
14877
+ }, [filter, sortState]);
14878
+ const pageCount = Math.max(1, Math.ceil(sorted.length / MERGED_PAGE_SIZE));
14879
+ const currentPage = Math.min(page, pageCount - 1);
14880
+ const paged = sorted.slice(currentPage * MERGED_PAGE_SIZE, currentPage * MERGED_PAGE_SIZE + MERGED_PAGE_SIZE);
14881
+ const columnSizingOptions = react.useMemo(
14882
+ () => ({
14883
+ key: { minWidth: 200, defaultWidth: 320 },
14884
+ kind: { minWidth: 110, defaultWidth: 140 },
14885
+ source: { minWidth: 200, defaultWidth: 300 },
14886
+ value: { minWidth: 200, defaultWidth: 360 }
14887
+ }),
14888
+ []
14889
+ );
14890
+ return /* @__PURE__ */ jsxRuntime.jsx(reactComponents.Dialog, { open: true, onOpenChange: (_event, data) => !data.open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DialogSurface, { className: styles.dialogSurface, children: /* @__PURE__ */ jsxRuntime.jsxs(reactComponents.DialogBody, { children: [
14891
+ /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DialogTitle, { children: t("app.localization-admin.merged-dialog-title", [label]) }),
14892
+ /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DialogContent, { children: loadError !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactComponents.MessageBar, { intent: "error", children: /* @__PURE__ */ jsxRuntime.jsx(reactComponents.MessageBarBody, { children: t("app.localization-admin.merged-load-failed", [loadError]) }) }) : entries === null ? /* @__PURE__ */ jsxRuntime.jsx(reactComponents.Spinner, {}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14893
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.dialogToolbar, children: [
14894
+ /* @__PURE__ */ jsxRuntime.jsx(
14895
+ reactComponents.Input,
14896
+ {
14897
+ className: styles.filterInput,
14898
+ value: filter,
14899
+ onChange: (_event, data) => setFilter(data.value),
14900
+ contentBefore: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.SearchRegular, {}),
14901
+ placeholder: t("app.localization-admin.merged-filter-placeholder")
14902
+ }
14903
+ ),
14904
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.lastReloaded, children: t("app.localization-admin.merged-count", [sorted.length, entries.length]) }),
14905
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.grow }),
14906
+ pageCount > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles.pager, children: [
14907
+ /* @__PURE__ */ jsxRuntime.jsx(
14908
+ reactComponents.Button,
14909
+ {
14910
+ size: "small",
14911
+ appearance: "subtle",
14912
+ disabled: currentPage === 0,
14913
+ onClick: () => setPage(currentPage - 1),
14914
+ children: t("app.localization-admin.merged-prev")
14915
+ }
14916
+ ),
14917
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.lastReloaded, children: t("app.localization-admin.merged-page", [currentPage + 1, pageCount]) }),
14918
+ /* @__PURE__ */ jsxRuntime.jsx(
14919
+ reactComponents.Button,
14920
+ {
14921
+ size: "small",
14922
+ appearance: "subtle",
14923
+ disabled: currentPage >= pageCount - 1,
14924
+ onClick: () => setPage(currentPage + 1),
14925
+ children: t("app.localization-admin.merged-next")
14926
+ }
14927
+ )
14928
+ ] })
14929
+ ] }),
14930
+ sorted.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactComponents.MessageBar, { intent: "info", children: /* @__PURE__ */ jsxRuntime.jsx(reactComponents.MessageBarBody, { children: t("app.localization-admin.merged-empty") }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.dialogGrid, children: /* @__PURE__ */ jsxRuntime.jsxs(
14931
+ reactComponents.DataGrid,
14932
+ {
14933
+ items: paged,
14934
+ columns,
14935
+ sortable: true,
14936
+ resizableColumns: true,
14937
+ sortState,
14938
+ onSortChange: (_event, next) => setSortState(next),
14939
+ columnSizingOptions,
14940
+ getRowId: (item) => item.key,
14941
+ size: "small",
14942
+ children: [
14943
+ /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DataGridHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DataGridRow, { children: ({ renderHeaderCell }) => /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DataGridHeaderCell, { children: renderHeaderCell() }) }) }),
14944
+ /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DataGridBody, { children: ({ item, rowId }) => /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DataGridRow, { children: ({ renderCell }) => /* @__PURE__ */ jsxRuntime.jsx(reactComponents.DataGridCell, { children: renderCell(item) }) }, rowId) })
14945
+ ]
14946
+ }
14947
+ ) })
14948
+ ] }) }),
14949
+ /* @__PURE__ */ jsxRuntime.jsxs(reactComponents.DialogActions, { children: [
14950
+ /* @__PURE__ */ jsxRuntime.jsx(
14951
+ reactComponents.Button,
14952
+ {
14953
+ appearance: "primary",
14954
+ icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowDownloadRegular, {}),
14955
+ disabled: isDownloading,
14956
+ onClick: onDownload,
14957
+ children: t("app.localization-admin.merged-download-button")
14958
+ }
14959
+ ),
14960
+ /* @__PURE__ */ jsxRuntime.jsx(reactComponents.Button, { appearance: "secondary", icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DismissRegular, {}), onClick: onClose, children: t("app.buttons.close.label") })
14961
+ ] })
14962
+ ] }) }) });
14963
+ }
14681
14964
  var useStyles13 = reactComponents.makeStyles({
14682
14965
  root: {
14683
14966
  display: "flex",