@crowdin/app-project-module 3.3.0 → 3.4.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.
@@ -18718,6 +18718,11 @@
18718
18718
  toast(message);
18719
18719
  }
18720
18720
  }
18721
+ function contactUser(userId) {
18722
+ AP.getContext(function (context) {
18723
+ AP.redirect(`${context.organization_id ? '/u' : ''}/messages/create/${userId}`);
18724
+ });
18725
+ }
18721
18726
  function reloadLocation() {
18722
18727
  ensureInitialized();
18723
18728
  window.location.href =
@@ -36165,17 +36170,12 @@ Defaulting to \`null\`.`;
36165
36170
  function isFolder$1(e) {
36166
36171
  return !e.type && (e.nodeType === undefined || e.nodeType === FOLDER_TYPE || e.nodeType === BRANCH_TYPE);
36167
36172
  }
36168
- function openModal(modal) {
36169
- if (!modal) {
36170
- return;
36173
+ // Throws like the old `ref.current.x` access did, instead of silently skipping.
36174
+ function requireRef(ref) {
36175
+ if (!ref.current) {
36176
+ throw new Error('Component is not mounted');
36171
36177
  }
36172
- modal.open();
36173
- }
36174
- function closeModal(modal) {
36175
- if (!modal) {
36176
- return;
36177
- }
36178
- modal.close();
36178
+ return ref.current;
36179
36179
  }
36180
36180
  function normalizeMenuItems(value) {
36181
36181
  let parsed = value;
@@ -36370,9 +36370,6 @@ Defaulting to \`null\`.`;
36370
36370
  }
36371
36371
  return items.filter((item) => item.schedule && (all || isFile(item)) && !item.disabled);
36372
36372
  }
36373
- function parseBoolean(value) {
36374
- return value === true || value === 'true' || value === '';
36375
- }
36376
36373
  const SimpleIntegration = reactExports.forwardRef(function SimpleIntegration({ name, logo = 'logo.png', syncNewElements, withCronSync, webhooks, integrationOneLevelFetching, integrationSearchListener, filtering, integrationButtonMenuItems = [], crowdinButtonMenuItems = [], onRefreshFilesList, onFolderToggle, onUploadFilesToCrowdin, onUploadFilesToIntegration, onLoadMore, onIntegrationFilterChange, onIntegrationScheduleSync, onCrowdinScheduleSync, onIntegrationDisableSync, onCrowdinDisableSync, }, ref) {
36377
36374
  const [providers, setProviders] = reactExports.useState({
36378
36375
  crowdin: { ...INITIAL_PROVIDER_STATE },
@@ -36384,7 +36381,7 @@ Defaulting to \`null\`.`;
36384
36381
  // getCrowdinSelected has no deps, so it reads the current filter through a ref.
36385
36382
  const displayedLanguagesRef = reactExports.useRef([]);
36386
36383
  const [progresses, setProgresses] = reactExports.useState({});
36387
- const [process, setProcess] = reactExports.useState({ toCrowdin: false, toIntegration: false });
36384
+ const [syncProcess, setSyncProcess] = reactExports.useState({ toCrowdin: false, toIntegration: false });
36388
36385
  const [activeProvider, setActiveProvider] = reactExports.useState('crowdin');
36389
36386
  const isMobile = useIsMobile();
36390
36387
  const [loadMoreLoadingIds, setLoadMoreLoadingIds] = reactExports.useState([]);
@@ -36482,24 +36479,10 @@ Defaulting to \`null\`.`;
36482
36479
  })),
36483
36480
  updateCrowdinFileData: async (items) => setProvider('crowdin', (state) => ({ ...state, items: updateItems(state.items, items) })),
36484
36481
  updateIntegrationFileData: async (items) => setProvider('integration', (state) => ({ ...state, items: updateItems(state.items, items) })),
36485
- querySelector: (selector) => selector === '#crowdin-files'
36486
- ? fileHandle('crowdin')
36487
- : selector === '#integration-files'
36488
- ? fileHandle('integration')
36489
- : null,
36490
- setAttribute: (attribute, value) => {
36491
- var _a;
36492
- const booleanValue = parseBoolean(value);
36493
- const mapping = {
36494
- 'is-crowdin-loading': () => setProvider('crowdin', { loading: booleanValue }),
36495
- 'is-integration-loading': () => setProvider('integration', { loading: booleanValue }),
36496
- 'is-crowdin-sync-settings-in-progress': () => setProvider('crowdin', { syncSettingsLoading: booleanValue }),
36497
- 'is-integration-sync-settings-in-progress': () => setProvider('integration', { syncSettingsLoading: booleanValue }),
36498
- 'is-to-crowdin-process': () => setProcess((current) => ({ ...current, toCrowdin: booleanValue })),
36499
- 'is-to-integration-process': () => setProcess((current) => ({ ...current, toIntegration: booleanValue })),
36500
- };
36501
- (_a = mapping[attribute]) === null || _a === void 0 ? void 0 : _a.call(mapping);
36502
- },
36482
+ getFilesHandle: fileHandle,
36483
+ setLoading: (provider, loading) => setProvider(provider, { loading }),
36484
+ setSyncSettingsInProgress: (provider, inProgress) => setProvider(provider, { syncSettingsLoading: inProgress }),
36485
+ setProcess: (next) => setSyncProcess((current) => ({ ...current, ...next })),
36503
36486
  }), [fileHandle, setProvider]);
36504
36487
  const displayedLanguages = reactExports.useMemo(() => filteredLanguageIds.length
36505
36488
  ? languages.filter((language) => filteredLanguageIds.includes(String(language.id)))
@@ -36590,7 +36573,7 @@ Defaulting to \`null\`.`;
36590
36573
  ? Object.keys(getCrowdinSelected()).length
36591
36574
  : selectedItems(provider).length;
36592
36575
  const syncDisabled = (provider) => selectedCount(provider) === 0;
36593
- const anyProcess = process.toCrowdin || process.toIntegration;
36576
+ const anyProcess = syncProcess.toCrowdin || syncProcess.toIntegration;
36594
36577
  const scheduleEnabled = (provider) => Boolean((withCronSync === null || withCronSync === void 0 ? void 0 : withCronSync[provider]) || (webhooks === null || webhooks === void 0 ? void 0 : webhooks[provider]));
36595
36578
  const upload = (provider, action, item) => {
36596
36579
  var _a, _b;
@@ -36789,7 +36772,7 @@ Defaulting to \`null\`.`;
36789
36772
  const isCrowdin = provider === 'crowdin';
36790
36773
  const displayItems = isCrowdin ? displayCrowdinItems : displayIntegrationItems;
36791
36774
  const providerName = isCrowdin ? 'Crowdin' : name;
36792
- const syncing = isCrowdin ? process.toIntegration : process.toCrowdin;
36775
+ const syncing = isCrowdin ? syncProcess.toIntegration : syncProcess.toCrowdin;
36793
36776
  const menuItems = isCrowdin ? normalizedCrowdinButtonMenuItems : normalizedIntegrationButtonMenuItems;
36794
36777
  // Derived, never stored: as state it went stale whenever items changed without a
36795
36778
  // selection change - disableSync cleared the markers but left the button live.
@@ -37014,6 +36997,8 @@ Defaulting to \`null\`.`;
37014
36997
  const checkUsersSeqRef = reactExports.useRef(0);
37015
36998
  const permissionsOpenSeqRef = reactExports.useRef(0);
37016
36999
  const [isLoading, setIsLoading] = reactExports.useState(false);
37000
+ // Kept apart from isLoading: disabling the focused users input would hide it from assistive tech.
37001
+ const [isCheckingUsers, setIsCheckingUsers] = reactExports.useState(false);
37017
37002
  // Gates Save until the user list loads, so a failed load can't save an empty list.
37018
37003
  const [isPermissionsLoaded, setIsPermissionsLoaded] = reactExports.useState(false);
37019
37004
  const [permissionUserOptions, setPermissionUserOptions] = reactExports.useState([]);
@@ -37034,10 +37019,12 @@ Defaulting to \`null\`.`;
37034
37019
  setIsPermissionsConfirmVisible(true);
37035
37020
  }
37036
37021
  async function showPermissionsDialog() {
37037
- var _a;
37022
+ var _a, _b;
37038
37023
  hideConfirmUsersBlock();
37039
- openModal(permissionsModalRef.current);
37024
+ (_a = permissionsModalRef.current) === null || _a === void 0 ? void 0 : _a.open();
37040
37025
  setIsLoading(true);
37026
+ // The bumped sequence below stops a pending check from clearing this itself.
37027
+ setIsCheckingUsers(false);
37041
37028
  setPermissionsSelectedUsers([]);
37042
37029
  // Reset before the async load, so a change event mid-load can't act on the
37043
37030
  // previous session's state.
@@ -37069,7 +37056,7 @@ Defaulting to \`null\`.`;
37069
37056
  const validUserIds = new Set(users.map((user) => `${user.id}`));
37070
37057
  const storedManagers = parsedManagers.filter((id) => validUserIds.has(id));
37071
37058
  // Ids are compared as strings; a missing owner id must stay null, not become "undefined".
37072
- connectionOwnerIdRef.current = (_a = ownerId === null || ownerId === void 0 ? void 0 : ownerId.toString()) !== null && _a !== void 0 ? _a : null;
37059
+ connectionOwnerIdRef.current = (_b = ownerId === null || ownerId === void 0 ? void 0 : ownerId.toString()) !== null && _b !== void 0 ? _b : null;
37073
37060
  // Baseline for telling additions from removals: stored managers plus the owner
37074
37061
  // (who always has access). The acting user is deliberately NOT seeded.
37075
37062
  initialManagerIdsRef.current = new Set(storedManagers);
@@ -37114,13 +37101,14 @@ Defaulting to \`null\`.`;
37114
37101
  showToast("The integration owner can't be removed from the access list.");
37115
37102
  }
37116
37103
  setPermissionsSelectedUsers(selectedUsers);
37117
- setIsLoading(true);
37104
+ setIsCheckingUsers(true);
37118
37105
  // Stamped on every invocation, the empty-selection early-return included, so a
37119
37106
  // cleared selection also invalidates a validation still in flight.
37120
37107
  const seq = ++checkUsersSeqRef.current;
37108
+ const finishChecking = () => setTimeout(() => seq === checkUsersSeqRef.current && setIsCheckingUsers(false), 500);
37121
37109
  if (selectedUsers.length === 0) {
37122
37110
  hideConfirmUsersBlock();
37123
- setTimeout(() => setIsLoading(false), 500);
37111
+ finishChecking();
37124
37112
  return;
37125
37113
  }
37126
37114
  const user_ids = selectedUsers.filter((id) => parseInt(id));
@@ -37190,9 +37178,7 @@ Defaulting to \`null\`.`;
37190
37178
  }
37191
37179
  }
37192
37180
  finally {
37193
- if (seq === checkUsersSeqRef.current) {
37194
- setTimeout(() => setIsLoading(false), 500);
37195
- }
37181
+ finishChecking();
37196
37182
  }
37197
37183
  }
37198
37184
  function inviteUsers() {
@@ -37207,7 +37193,7 @@ Defaulting to \`null\`.`;
37207
37193
  !!actingUserId &&
37208
37194
  !permissionsSelectedUsers.some((id) => `${id}` === actingUserId);
37209
37195
  AP.inviteUsers({ user_ids, emails }, async (res) => {
37210
- var _a;
37196
+ var _a, _b;
37211
37197
  if (!res.success) {
37212
37198
  catchRejection(res, ((_a = res === null || res === void 0 ? void 0 : res.error) === null || _a === void 0 ? void 0 : _a.message) || "Can't invite users");
37213
37199
  setTimeout(() => setIsLoading(false), 500);
@@ -37226,7 +37212,7 @@ Defaulting to \`null\`.`;
37226
37212
  }
37227
37213
  showToast('Users successfully updated');
37228
37214
  hideConfirmUsersBlock();
37229
- closeModal(permissionsModalRef.current);
37215
+ (_b = permissionsModalRef.current) === null || _b === void 0 ? void 0 : _b.close();
37230
37216
  }
37231
37217
  catch (e) {
37232
37218
  catchRejection(e, (e === null || e === void 0 ? void 0 : e.error) || "Can't invite users");
@@ -37282,6 +37268,7 @@ Defaulting to \`null\`.`;
37282
37268
  }
37283
37269
  return {
37284
37270
  isLoading,
37271
+ isCheckingUsers,
37285
37272
  isPermissionsLoaded,
37286
37273
  permissionUserOptions,
37287
37274
  permissionsSelectedUsers,
@@ -37340,7 +37327,7 @@ Defaulting to \`null\`.`;
37340
37327
  found = selectedFiles.find((file) => file.node_type === FOLDER_TYPE || file.node_type === BRANCH_TYPE);
37341
37328
  }
37342
37329
  else {
37343
- const files = await appComponent.current.getCrowdinFilesData();
37330
+ const files = await requireRef(appComponent).getCrowdinFilesData();
37344
37331
  const folders = files.filter((file) => file.node_type === FOLDER_TYPE || file.node_type === BRANCH_TYPE);
37345
37332
  found = folders.find((folder) => selectedFiles.hasOwnProperty(folder.id));
37346
37333
  }
@@ -37355,11 +37342,11 @@ Defaulting to \`null\`.`;
37355
37342
  : [];
37356
37343
  }
37357
37344
  async function openScheduleModal(type, options = {}) {
37358
- var _a, _b, _c, _d;
37345
+ var _a, _b, _c, _d, _e;
37359
37346
  const { showAllFolderFiles = false, showNewFiles = true } = options;
37360
37347
  let newFileStatus = 'unChecked';
37361
37348
  const integrationSyncFolders = ((await ((_b = (_a = appComponent.current) === null || _a === void 0 ? void 0 : _a.getIntegrationScheduleSync) === null || _b === void 0 ? void 0 : _b.call(_a, true))) || []).filter((elements) => elements.node_type === FOLDER_TYPE);
37362
- const integrationFiles = (_c = appComponent.current) === null || _c === void 0 ? void 0 : _c.querySelector('#integration-files');
37349
+ const integrationFiles = (_c = appComponent.current) === null || _c === void 0 ? void 0 : _c.getFilesHandle('integration');
37363
37350
  const selectedIntegrationFolders = ((await ((_d = integrationFiles === null || integrationFiles === void 0 ? void 0 : integrationFiles.getSelected) === null || _d === void 0 ? void 0 : _d.call(integrationFiles, true))) || []).filter((elements) => elements.node_type === FOLDER_TYPE);
37364
37351
  for (let i = 0; i < selectedIntegrationFolders.length; i++) {
37365
37352
  const selectedElement = selectedIntegrationFolders[i];
@@ -37385,7 +37372,7 @@ Defaulting to \`null\`.`;
37385
37372
  allFolderFiles: false,
37386
37373
  });
37387
37374
  setIsScheduleSaveDisabled(false);
37388
- openModal(scheduleModalRef.current);
37375
+ (_e = scheduleModalRef.current) === null || _e === void 0 ? void 0 : _e.open();
37389
37376
  }
37390
37377
  function onChangeAutoSynchronizationOptions() {
37391
37378
  var _a, _b, _c;
@@ -37404,28 +37391,29 @@ Defaulting to \`null\`.`;
37404
37391
  setIsScheduleSaveDisabled(!nextState.newFiles && !nextState.selectedFiles && !nextState.allFolderFiles);
37405
37392
  }
37406
37393
  async function saveScheduleSync() {
37394
+ var _a;
37407
37395
  const { type, newFiles: newFile, selectedFiles, allFolderFiles } = scheduleModalState;
37408
37396
  if (type === 'crowdin') {
37409
- const crowdinFiles = await appComponent.current.getCrowdinFilesData();
37397
+ const crowdinFiles = await requireRef(appComponent).getCrowdinFilesData();
37410
37398
  const syncedFileIds = Object.keys(syncData.current);
37411
37399
  const crowdinFolderIds = crowdinFiles
37412
37400
  .filter((file) => file.node_type === FOLDER_TYPE || file.node_type === BRANCH_TYPE)
37413
37401
  .filter((file) => syncedFileIds.includes(String(file.id)))
37414
37402
  .map((file) => String(file.id));
37415
- appComponent.current.setCrowdinScheduleSync(syncData.current, newFile, selectedFiles);
37416
- const syncedFiles = await appComponent.current.getCrowdinScheduleSync(true);
37417
- appComponent.current.setAttribute('is-crowdin-sync-settings-in-progress', true);
37403
+ requireRef(appComponent).setCrowdinScheduleSync(syncData.current, newFile, selectedFiles);
37404
+ const syncedFiles = await requireRef(appComponent).getCrowdinScheduleSync(true);
37405
+ requireRef(appComponent).setSyncSettingsInProgress('crowdin', true);
37418
37406
  updateSyncSettings(syncedFiles, 'schedule', 'crowdin', [], crowdinFolderIds);
37419
37407
  }
37420
37408
  else if (type === 'integration') {
37421
37409
  if (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration) {
37422
- appComponent.current.setIntegrationScheduleSync(syncData.current, newFile, selectedFiles);
37410
+ requireRef(appComponent).setIntegrationScheduleSync(syncData.current, newFile, selectedFiles);
37423
37411
  }
37424
37412
  else {
37425
- appComponent.current.setIntegrationScheduleSync(syncData.current);
37413
+ requireRef(appComponent).setIntegrationScheduleSync(syncData.current);
37426
37414
  }
37427
- const syncedFiles = await appComponent.current.getIntegrationScheduleSync(true);
37428
- appComponent.current.setAttribute('is-integration-sync-settings-in-progress', true);
37415
+ const syncedFiles = await requireRef(appComponent).getIntegrationScheduleSync(true);
37416
+ requireRef(appComponent).setSyncSettingsInProgress('integration', true);
37429
37417
  if (integrationOneLevelFetching) {
37430
37418
  updateSyncSettings(syncedFiles, 'schedule', 'integration', selectedFiles ? getIntegrationFoldersToExpand(syncData.current, syncedFiles) : []);
37431
37419
  }
@@ -37441,7 +37429,7 @@ Defaulting to \`null\`.`;
37441
37429
  }
37442
37430
  }
37443
37431
  }
37444
- closeModal(scheduleModalRef.current);
37432
+ (_a = scheduleModalRef.current) === null || _a === void 0 ? void 0 : _a.close();
37445
37433
  }
37446
37434
  async function setIntegrationScheduleSync(e) {
37447
37435
  var _a;
@@ -37461,8 +37449,8 @@ Defaulting to \`null\`.`;
37461
37449
  await openScheduleModal('integration', { showNewFiles, showAllFolderFiles });
37462
37450
  return;
37463
37451
  }
37464
- appComponent.current.setIntegrationScheduleSync(e.detail);
37465
- syncedFiles = await appComponent.current.getIntegrationScheduleSync(true);
37452
+ requireRef(appComponent).setIntegrationScheduleSync(e.detail);
37453
+ syncedFiles = await requireRef(appComponent).getIntegrationScheduleSync(true);
37466
37454
  }
37467
37455
  else {
37468
37456
  syncData.current = e.detail;
@@ -37471,9 +37459,9 @@ Defaulting to \`null\`.`;
37471
37459
  await openScheduleModal('integration', { showNewFiles: false, showAllFolderFiles: true });
37472
37460
  return;
37473
37461
  }
37474
- syncedFiles = await appComponent.current.getIntegrationScheduleSync();
37462
+ syncedFiles = await requireRef(appComponent).getIntegrationScheduleSync();
37475
37463
  }
37476
- appComponent.current.setAttribute('is-integration-sync-settings-in-progress', true);
37464
+ requireRef(appComponent).setSyncSettingsInProgress('integration', true);
37477
37465
  if (integrationOneLevelFetching) {
37478
37466
  updateSyncSettings(syncedFiles, 'schedule', 'integration', getIntegrationFoldersToExpand(e.detail, syncedFiles));
37479
37467
  }
@@ -37504,13 +37492,13 @@ Defaulting to \`null\`.`;
37504
37492
  await openScheduleModal('crowdin');
37505
37493
  return;
37506
37494
  }
37507
- appComponent.current.setCrowdinScheduleSync(e.detail);
37508
- syncedFiles = await appComponent.current.getCrowdinScheduleSync(true);
37495
+ requireRef(appComponent).setCrowdinScheduleSync(e.detail);
37496
+ syncedFiles = await requireRef(appComponent).getCrowdinScheduleSync(true);
37509
37497
  }
37510
37498
  else {
37511
- syncedFiles = await appComponent.current.getCrowdinScheduleSync();
37499
+ syncedFiles = await requireRef(appComponent).getCrowdinScheduleSync();
37512
37500
  }
37513
- appComponent.current.setAttribute('is-crowdin-sync-settings-in-progress', true);
37501
+ requireRef(appComponent).setSyncSettingsInProgress('crowdin', true);
37514
37502
  updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
37515
37503
  }
37516
37504
  async function disableIntegrationSync(e) {
@@ -37518,10 +37506,10 @@ Defaulting to \`null\`.`;
37518
37506
  showToast('Select templates which will be pushed to Crowdin');
37519
37507
  return;
37520
37508
  }
37521
- appComponent.current.setAttribute('is-integration-sync-settings-in-progress', true);
37509
+ requireRef(appComponent).setSyncSettingsInProgress('integration', true);
37522
37510
  const syncedFiles = (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)
37523
- ? await appComponent.current.getIntegrationScheduleSync(true)
37524
- : await appComponent.current.getIntegrationScheduleSync();
37511
+ ? await requireRef(appComponent).getIntegrationScheduleSync(true)
37512
+ : await requireRef(appComponent).getIntegrationScheduleSync();
37525
37513
  updateSyncSettings(syncedFiles, 'schedule', 'integration');
37526
37514
  }
37527
37515
  async function disableCrowdinSync(e) {
@@ -37529,10 +37517,10 @@ Defaulting to \`null\`.`;
37529
37517
  showToast('Select templates which will be pushed to Crowdin');
37530
37518
  return;
37531
37519
  }
37532
- appComponent.current.setAttribute('is-crowdin-sync-settings-in-progress', true);
37520
+ requireRef(appComponent).setSyncSettingsInProgress('crowdin', true);
37533
37521
  const syncedFiles = (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin)
37534
- ? await appComponent.current.getCrowdinScheduleSync(true)
37535
- : await appComponent.current.getCrowdinScheduleSync();
37522
+ ? await requireRef(appComponent).getCrowdinScheduleSync(true)
37523
+ : await requireRef(appComponent).getCrowdinScheduleSync();
37536
37524
  updateSyncSettings(syncedFiles, 'schedule', 'crowdin');
37537
37525
  }
37538
37526
  return {
@@ -37608,7 +37596,7 @@ Defaulting to \`null\`.`;
37608
37596
  setTimeout(refreshDependencies, 100);
37609
37597
  }
37610
37598
  async function saveSettings() {
37611
- var _a, _b;
37599
+ var _a, _b, _c;
37612
37600
  setIsLoading(true);
37613
37601
  const configReq = {};
37614
37602
  for (const tab of configurationFields || []) {
@@ -37663,10 +37651,11 @@ Defaulting to \`null\`.`;
37663
37651
  showToast("Can't save settings");
37664
37652
  },
37665
37653
  onFinally: () => {
37654
+ var _a;
37666
37655
  setTimeout(() => setIsLoading(false), 500);
37667
37656
  setIsSettingsSaveDisabled(false);
37668
37657
  if (!isValidationError && !isSettingsSaveFailed) {
37669
- closeModal(settingsModalRef.current);
37658
+ (_a = settingsModalRef.current) === null || _a === void 0 ? void 0 : _a.close();
37670
37659
  if (reloadOnConfigSave) {
37671
37660
  getIntegrationData({ hardReload: true });
37672
37661
  getCrowdinData();
@@ -37706,7 +37695,7 @@ Defaulting to \`null\`.`;
37706
37695
  setTimeout(() => setIsLoading(false), 500);
37707
37696
  setIsSettingsSaveDisabled(false);
37708
37697
  if (!isValidationError) {
37709
- closeModal(settingsModalRef.current);
37698
+ (_c = settingsModalRef.current) === null || _c === void 0 ? void 0 : _c.close();
37710
37699
  if (reloadOnConfigSave) {
37711
37700
  getIntegrationData({ hardReload: true });
37712
37701
  getCrowdinData();
@@ -37771,7 +37760,7 @@ Defaulting to \`null\`.`;
37771
37760
  }
37772
37761
  async function handleLoadMore(detail) {
37773
37762
  var _a;
37774
- const fileComponent = (_a = appComponent.current) === null || _a === void 0 ? void 0 : _a.querySelector('#integration-files');
37763
+ const fileComponent = (_a = appComponent.current) === null || _a === void 0 ? void 0 : _a.getFilesHandle('integration');
37775
37764
  if (!fileComponent) {
37776
37765
  return;
37777
37766
  }
@@ -37789,15 +37778,15 @@ Defaulting to \`null\`.`;
37789
37778
  }
37790
37779
  const isEmptySearch = !search || search.trim() === '';
37791
37780
  if (isEmptySearch && savedIntegrationData.current && hasLoadMoreElements.current) {
37792
- appComponent.current.setIntegrationFilesData(savedIntegrationData.current);
37793
- appComponent.current.setIntegrationOpenedFolders(currentOpenedFolders.current);
37781
+ requireRef(appComponent).setIntegrationFilesData(savedIntegrationData.current);
37782
+ requireRef(appComponent).setIntegrationOpenedFolders(currentOpenedFolders.current);
37794
37783
  savedIntegrationData.current = null;
37795
37784
  currentOpenedFolders.current = null;
37796
37785
  return;
37797
37786
  }
37798
37787
  if (!isEmptySearch && hasLoadMoreElements.current && !savedIntegrationData.current) {
37799
- savedIntegrationData.current = await appComponent.current.getIntegrationFilesData();
37800
- currentOpenedFolders.current = await appComponent.current.getIntegrationOpenedFolders();
37788
+ savedIntegrationData.current = await requireRef(appComponent).getIntegrationFilesData();
37789
+ currentOpenedFolders.current = await requireRef(appComponent).getIntegrationOpenedFolders();
37801
37790
  }
37802
37791
  getIntegrationData({ search });
37803
37792
  }
@@ -37824,7 +37813,7 @@ Defaulting to \`null\`.`;
37824
37813
  }
37825
37814
  async function getCrowdinData() {
37826
37815
  var _a, _b, _c, _d, _f;
37827
- (_a = appComponent.current) === null || _a === void 0 ? void 0 : _a.setAttribute('is-crowdin-loading', 'true');
37816
+ (_a = appComponent.current) === null || _a === void 0 ? void 0 : _a.setLoading('crowdin', true);
37828
37817
  try {
37829
37818
  const restParams = await checkOrigin();
37830
37819
  if (progressiveCrowdinFilesLoading) {
@@ -37866,7 +37855,7 @@ Defaulting to \`null\`.`;
37866
37855
  ]);
37867
37856
  const tree = files.map(transformCrowdinItemToTree);
37868
37857
  crowdinData.current = tree;
37869
- appComponent.current.setCrowdinFilesData(tree);
37858
+ requireRef(appComponent).setCrowdinFilesData(tree);
37870
37859
  project.current = projectData;
37871
37860
  const languagesSorted = project.current.targetLanguages
37872
37861
  .map((language) => ({
@@ -37879,7 +37868,7 @@ Defaulting to \`null\`.`;
37879
37868
  languagesSorted.push({ ...project.current.inContextPseudoLanguage, inContext: true });
37880
37869
  }
37881
37870
  setLanguagesForTranslation(languagesSorted);
37882
- appComponent.current.setCrowdinLanguagesData(languagesSorted);
37871
+ requireRef(appComponent).setCrowdinLanguagesData(languagesSorted);
37883
37872
  }
37884
37873
  if (withCronSync || webhooks) {
37885
37874
  await getSyncSettings('crowdin');
@@ -37889,12 +37878,12 @@ Defaulting to \`null\`.`;
37889
37878
  catchRejection(e, "Can't fetch Crowdin data");
37890
37879
  }
37891
37880
  finally {
37892
- appComponent.current.setAttribute('is-crowdin-loading', false);
37881
+ requireRef(appComponent).setLoading('crowdin', false);
37893
37882
  }
37894
37883
  }
37895
37884
  async function getIntegrationData({ hardReload = false, parentId = '', search = '', page = 0, recursion = false, paginationData } = {}, recursionState = null) {
37896
37885
  if (!paginationData) {
37897
- appComponent.current.setAttribute('is-integration-loading', true);
37886
+ requireRef(appComponent).setLoading('integration', true);
37898
37887
  }
37899
37888
  let recursionStateLocal = recursionState;
37900
37889
  try {
@@ -37909,12 +37898,14 @@ Defaulting to \`null\`.`;
37909
37898
  if ((!paginationData && !parentId && !search) || hardReload) {
37910
37899
  hasLoadMoreElements.current = tree.some((item) => item.node_type === 'load-more');
37911
37900
  }
37912
- const appIntegrationFiles = appComponent.current.querySelector('#integration-files');
37901
+ const appIntegrationFiles = requireRef(appComponent).getFilesHandle('integration');
37913
37902
  if (hardReload) {
37914
- appComponent.current.setIntegrationFilesData(tree);
37903
+ requireRef(appComponent).setIntegrationFilesData(tree);
37915
37904
  }
37916
37905
  else if (tree.length) {
37917
- appComponent.current.pushIntegrationFilesData(tree).then(async () => {
37906
+ requireRef(appComponent)
37907
+ .pushIntegrationFilesData(tree)
37908
+ .then(async () => {
37918
37909
  if (parentId) {
37919
37910
  const selection = await appIntegrationFiles.getSelected();
37920
37911
  const selectedIds = selection === null || selection === void 0 ? void 0 : selection.filter((node) => node).map(({ id }) => id.toString());
@@ -37929,7 +37920,7 @@ Defaulting to \`null\`.`;
37929
37920
  }
37930
37921
  if (search) {
37931
37922
  const openIds = files.filter((e) => !e.type).map((e) => e.id);
37932
- appComponent.current.setIntegrationOpenedFolders(openIds);
37923
+ requireRef(appComponent).setIntegrationOpenedFolders(openIds);
37933
37924
  }
37934
37925
  if (recursion) {
37935
37926
  if (!recursionStateLocal) {
@@ -37937,7 +37928,7 @@ Defaulting to \`null\`.`;
37937
37928
  openedFolders: new Set(),
37938
37929
  calls: 0,
37939
37930
  setLoading(isLoading) {
37940
- appComponent.current.setAttribute('is-integration-loading', isLoading);
37931
+ requireRef(appComponent).setLoading('integration', isLoading);
37941
37932
  },
37942
37933
  };
37943
37934
  recursionStateLocal.setLoading(true);
@@ -37947,8 +37938,8 @@ Defaulting to \`null\`.`;
37947
37938
  }
37948
37939
  const folderItems = files.filter(isFolder$1);
37949
37940
  folderItems.forEach((folder) => recursionStateLocal.openedFolders.add(folder.id));
37950
- const openedFoldersNow = await appComponent.current.getIntegrationOpenedFolders();
37951
- appComponent.current.setIntegrationOpenedFolders([
37941
+ const openedFoldersNow = await requireRef(appComponent).getIntegrationOpenedFolders();
37942
+ requireRef(appComponent).setIntegrationOpenedFolders([
37952
37943
  ...new Set([...openedFoldersNow, ...recursionStateLocal.openedFolders]),
37953
37944
  ]);
37954
37945
  if (folderItems.length > 0) {
@@ -37975,10 +37966,10 @@ Defaulting to \`null\`.`;
37975
37966
  }
37976
37967
  finally {
37977
37968
  if (!recursionStateLocal && !recursion) {
37978
- appComponent.current.setAttribute('is-integration-loading', false);
37969
+ requireRef(appComponent).setLoading('integration', false);
37979
37970
  }
37980
37971
  else if (recursionStateLocal && recursionStateLocal.calls === 0) {
37981
- appComponent.current.setAttribute('is-integration-loading', false);
37972
+ requireRef(appComponent).setLoading('integration', false);
37982
37973
  }
37983
37974
  }
37984
37975
  }
@@ -38039,18 +38030,18 @@ Defaulting to \`null\`.`;
38039
38030
  const res = await checkResponse(await fetch(`/api/sync-settings/${provider}` + restParams));
38040
38031
  if (provider === 'crowdin') {
38041
38032
  if (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) {
38042
- appComponent.current.setCrowdinScheduleSync(res, true, true);
38033
+ requireRef(appComponent).setCrowdinScheduleSync(res, true, true);
38043
38034
  }
38044
38035
  else {
38045
- appComponent.current.setCrowdinScheduleSync(res);
38036
+ requireRef(appComponent).setCrowdinScheduleSync(res);
38046
38037
  }
38047
38038
  }
38048
38039
  else {
38049
38040
  if (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration) {
38050
- appComponent.current.setIntegrationScheduleSync(res, true, true);
38041
+ requireRef(appComponent).setIntegrationScheduleSync(res, true, true);
38051
38042
  }
38052
38043
  else {
38053
- appComponent.current.setIntegrationScheduleSync(res);
38044
+ requireRef(appComponent).setIntegrationScheduleSync(res);
38054
38045
  }
38055
38046
  }
38056
38047
  await applyAutoSyncPausedMarkers(provider, res);
@@ -38063,7 +38054,7 @@ Defaulting to \`null\`.`;
38063
38054
  try {
38064
38055
  const restParams = await checkOrigin();
38065
38056
  const res = await checkResponse(await fetch(`api/crowdin/file-progress/${fileId}` + restParams));
38066
- appComponent.current.addCrowdinFileProgress(Array.isArray(res) ? { [fileId]: res } : res);
38057
+ requireRef(appComponent).addCrowdinFileProgress(Array.isArray(res) ? { [fileId]: res } : res);
38067
38058
  }
38068
38059
  catch (e) {
38069
38060
  catchRejection(e, "Can't fetch file progress");
@@ -38102,7 +38093,7 @@ Defaulting to \`null\`.`;
38102
38093
  showToast('Select templates which will be pushed to Crowdin');
38103
38094
  return;
38104
38095
  }
38105
- appComponent.current.setAttribute('is-to-crowdin-process', true);
38096
+ requireRef(appComponent).setProcess({ toCrowdin: true });
38106
38097
  let req;
38107
38098
  if (integrationOneLevelFetching) {
38108
38099
  req = files.map((f) => ({
@@ -38149,16 +38140,16 @@ Defaulting to \`null\`.`;
38149
38140
  switch (job.type) {
38150
38141
  case JOB_TYPE.updateCrowdin:
38151
38142
  case JOB_TYPE.updateTargetLanguages:
38152
- appComponent.current.setAttribute('is-to-crowdin-process', true);
38143
+ requireRef(appComponent).setProcess({ toCrowdin: true });
38153
38144
  break;
38154
38145
  case JOB_TYPE.updateIntegration:
38155
- appComponent.current.setAttribute('is-to-integration-process', true);
38146
+ requireRef(appComponent).setProcess({ toIntegration: true });
38156
38147
  break;
38157
38148
  case JOB_TYPE.crowdinSyncSettingsSave:
38158
- appComponent.current.setAttribute('is-crowdin-sync-settings-in-progress', true);
38149
+ requireRef(appComponent).setSyncSettingsInProgress('crowdin', true);
38159
38150
  break;
38160
38151
  case JOB_TYPE.integrationSyncSettingsSave:
38161
- appComponent.current.setAttribute('is-integration-sync-settings-in-progress', true);
38152
+ requireRef(appComponent).setSyncSettingsInProgress('integration', true);
38162
38153
  break;
38163
38154
  default:
38164
38155
  }
@@ -38192,24 +38183,24 @@ Defaulting to \`null\`.`;
38192
38183
  case JOB_TYPE.updateTargetLanguages:
38193
38184
  if (!onFinally) {
38194
38185
  onFinally = () => {
38195
- appComponent.current.setAttribute('is-to-crowdin-process', false);
38186
+ requireRef(appComponent).setProcess({ toCrowdin: false });
38196
38187
  getCrowdinData();
38197
38188
  };
38198
38189
  }
38199
38190
  break;
38200
38191
  case JOB_TYPE.updateIntegration:
38201
38192
  if (!onFinally) {
38202
- onFinally = () => appComponent.current.setAttribute('is-to-integration-process', false);
38193
+ onFinally = () => requireRef(appComponent).setProcess({ toIntegration: false });
38203
38194
  }
38204
38195
  break;
38205
38196
  case JOB_TYPE.crowdinSyncSettingsSave:
38206
38197
  if (!onFinally) {
38207
- onFinally = () => appComponent.current.setAttribute('is-crowdin-sync-settings-in-progress', false);
38198
+ onFinally = () => requireRef(appComponent).setSyncSettingsInProgress('crowdin', false);
38208
38199
  }
38209
38200
  break;
38210
38201
  case JOB_TYPE.integrationSyncSettingsSave:
38211
38202
  if (!onFinally) {
38212
- onFinally = () => appComponent.current.setAttribute('is-integration-sync-settings-in-progress', false);
38203
+ onFinally = () => requireRef(appComponent).setSyncSettingsInProgress('integration', false);
38213
38204
  }
38214
38205
  break;
38215
38206
  }
@@ -38288,7 +38279,7 @@ Defaulting to \`null\`.`;
38288
38279
  showToast(`Select files which will be uploaded to ${name}`);
38289
38280
  return;
38290
38281
  }
38291
- appComponent.current.setAttribute('is-to-integration-process', true);
38282
+ requireRef(appComponent).setProcess({ toIntegration: true });
38292
38283
  const req = {};
38293
38284
  Object.keys(files)
38294
38285
  .filter((id) => { var _a; return ((_a = crowdinData.current.find((c) => c.id === id)) === null || _a === void 0 ? void 0 : _a.node_type) === FILE_TYPE; })
@@ -38311,7 +38302,7 @@ Defaulting to \`null\`.`;
38311
38302
  showToast('Select files to sync');
38312
38303
  return;
38313
38304
  }
38314
- appComponent.current.setAttribute('is-to-crowdin-process', true);
38305
+ requireRef(appComponent).setProcess({ toCrowdin: true });
38315
38306
  const req = {};
38316
38307
  Object.keys(files)
38317
38308
  .filter((id) => { var _a; return ((_a = crowdinData.current.find((c) => c.id === id)) === null || _a === void 0 ? void 0 : _a.node_type) === FILE_TYPE; })
@@ -38334,7 +38325,7 @@ Defaulting to \`null\`.`;
38334
38325
  showToast('Select files to sync');
38335
38326
  return;
38336
38327
  }
38337
- appComponent.current.setAttribute('is-to-integration-process', true);
38328
+ requireRef(appComponent).setProcess({ toIntegration: true });
38338
38329
  const req = files
38339
38330
  .filter((f) => f.node_type !== FOLDER_TYPE)
38340
38331
  .map((f) => ({ name: f.name, id: f.id, type: f.type, parentId: f.parent_id }));
@@ -38352,6 +38343,7 @@ Defaulting to \`null\`.`;
38352
38343
  }
38353
38344
  }
38354
38345
  function openLanguageModal() {
38346
+ var _a;
38355
38347
  setLanguageModalState((state) => {
38356
38348
  var _a, _b;
38357
38349
  return ({
@@ -38359,9 +38351,10 @@ Defaulting to \`null\`.`;
38359
38351
  action: 'syncToCrowdin',
38360
38352
  });
38361
38353
  });
38362
- openModal(languageModal.current);
38354
+ (_a = languageModal.current) === null || _a === void 0 ? void 0 : _a.open();
38363
38355
  }
38364
38356
  function openLanguageModalForCrowdinFiles() {
38357
+ var _a;
38365
38358
  setLanguageModalState((state) => {
38366
38359
  var _a, _b;
38367
38360
  return ({
@@ -38369,22 +38362,24 @@ Defaulting to \`null\`.`;
38369
38362
  action: 'updateCrowdinTargetLanguages',
38370
38363
  });
38371
38364
  });
38372
- openModal(languageModal.current);
38365
+ (_a = languageModal.current) === null || _a === void 0 ? void 0 : _a.open();
38373
38366
  }
38374
38367
  async function uploadFilesToCrowdinWithExcludedLanguages() {
38368
+ var _a;
38375
38369
  const selectedLanguages = await languageSelectRef.current.getValue();
38376
- closeModal(languageModal.current);
38370
+ (_a = languageModal.current) === null || _a === void 0 ? void 0 : _a.close();
38377
38371
  uploadFilesToCrowdin({ detail: fileToSync.current }, selectedLanguages);
38378
38372
  }
38379
38373
  async function updateCrowdinFilesTargetLanguages() {
38374
+ var _a;
38380
38375
  const selectedLanguages = await languageSelectRef.current.getValue();
38381
- closeModal(languageModal.current);
38376
+ (_a = languageModal.current) === null || _a === void 0 ? void 0 : _a.close();
38382
38377
  const fileIds = Object.keys(crowdinFilesToUpdateTargetLanguages.current).map((id) => parseInt(id, 10));
38383
38378
  if (fileIds.length === 0) {
38384
38379
  showToast('Select files to update');
38385
38380
  return;
38386
38381
  }
38387
- appComponent.current.setAttribute('is-to-crowdin-process', true);
38382
+ requireRef(appComponent).setProcess({ toCrowdin: true });
38388
38383
  try {
38389
38384
  const restParams = await checkOrigin();
38390
38385
  const res = await checkResponse(await fetch(`api/crowdin/files-target-languages${restParams}`, {
@@ -49450,8 +49445,10 @@ Defaulting to \`null\`.`;
49450
49445
  }
49451
49446
  return (jsxRuntimeExports.jsx("div", { className: row.isWarning ? 'mt-1 text-xs text-destructive' : 'mt-1 text-xs text-muted-foreground', children: row.description }));
49452
49447
  }
49453
- const PermissionsModal = ({ modalRef, isLoading, permissionUserOptions, selectedUsers, isConfirmVisible, permissionsSummary, hasOrganization, zenModeUrl, saveDisabled, onUsersChange, onSave, }) => {
49454
- return (jsxRuntimeExports.jsxs(AppDialog, { ref: modalRef, id: "permissions-modal", title: "Share", description: "Invite people who manage content and give them access to this integration, so they can send new content for translation as soon as it's added.", footer: jsxRuntimeExports.jsx(Button, { id: "confirm-users-btn", disabled: saveDisabled, onClick: onSave, children: "Save" }), children: [jsxRuntimeExports.jsx("div", { className: isLoading ? 'absolute inset-0 z-[4] flex items-center justify-center bg-background/30' : 'hidden', children: jsxRuntimeExports.jsx(Spinner, {}) }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx(UsersMultiSelect, { options: permissionUserOptions, value: selectedUsers, disabled: isLoading, onValueChange: onUsersChange }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("div", { className: isConfirmVisible ? 'mt-4' : 'hidden', children: jsxRuntimeExports.jsxs(Table, { className: "min-w-[640px] table-fixed", children: [jsxRuntimeExports.jsx(TableHeader, { children: jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsx(TableHead, { className: "w-[40%] px-4", children: "Access" }), jsxRuntimeExports.jsx(TableHead, { className: "w-[35%] px-4", children: "Users" }), jsxRuntimeExports.jsx(TableHead, { className: "w-[25%] px-4 text-right", children: "Upcoming changes" })] }) }), jsxRuntimeExports.jsxs(TableBody, { children: [hasOrganization && (jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsxs(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: [jsxRuntimeExports.jsx("p", { className: "m-0 text-sm", children: "Registration in Organization" }), renderPermissionRowDescription(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization)] }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization) }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization) &&
49448
+ const PermissionsModal = ({ modalRef, isLoading, isCheckingUsers = false, permissionUserOptions, selectedUsers, isConfirmVisible, permissionsSummary, hasOrganization, zenModeUrl, saveDisabled, onUsersChange, onSave, }) => {
49449
+ return (jsxRuntimeExports.jsxs(AppDialog, { ref: modalRef, id: "permissions-modal", title: "Share", description: "Invite people who manage content and give them access to this integration, so they can send new content for translation as soon as it's added.", footer: jsxRuntimeExports.jsx(Button, { id: "confirm-users-btn", disabled: saveDisabled, onClick: onSave, children: "Save" }), children: [jsxRuntimeExports.jsx("div", { className: isLoading || isCheckingUsers
49450
+ ? 'absolute inset-0 z-[4] flex items-center justify-center bg-background/30'
49451
+ : 'hidden', children: jsxRuntimeExports.jsx(Spinner, {}) }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx(UsersMultiSelect, { options: permissionUserOptions, value: selectedUsers, disabled: isLoading, onValueChange: onUsersChange }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("div", { className: isConfirmVisible ? 'mt-4' : 'hidden', children: jsxRuntimeExports.jsxs(Table, { className: "min-w-[640px] table-fixed", children: [jsxRuntimeExports.jsx(TableHeader, { children: jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsx(TableHead, { className: "w-[40%] px-4", children: "Access" }), jsxRuntimeExports.jsx(TableHead, { className: "w-[35%] px-4", children: "Users" }), jsxRuntimeExports.jsx(TableHead, { className: "w-[25%] px-4 text-right", children: "Upcoming changes" })] }) }), jsxRuntimeExports.jsxs(TableBody, { children: [hasOrganization && (jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsxs(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: [jsxRuntimeExports.jsx("p", { className: "m-0 text-sm", children: "Registration in Organization" }), renderPermissionRowDescription(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization)] }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization) }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization) &&
49455
49452
  renderPermissionStatus(permissionsSummary.organization.status) })] })), jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: jsxRuntimeExports.jsx("p", { className: "m-0 text-sm", children: "Project Manager Access" }) }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.project) }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.project) &&
49456
49453
  renderPermissionStatus(permissionsSummary.project.status) })] }), jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsxs(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: [jsxRuntimeExports.jsx("p", { className: "m-0 text-sm", children: "Application Visibility Access" }), renderPermissionRowDescription(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationSettings)] }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationSettings) }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationSettings) &&
49457
49454
  renderPermissionStatus(permissionsSummary.applicationSettings.status) })] }), jsxRuntimeExports.jsxs(TableRow, { children: [jsxRuntimeExports.jsxs(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: [jsxRuntimeExports.jsx("p", { className: "m-0 text-sm", children: "Access to the Integration" }), jsxRuntimeExports.jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "This provides access to sync files and modify the current integration settings." })] }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationCredentials) }), jsxRuntimeExports.jsx(TableCell, { className: "whitespace-normal px-4 py-3 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationCredentials) &&
@@ -49492,15 +49489,13 @@ Defaulting to \`null\`.`;
49492
49489
  return null;
49493
49490
  }
49494
49491
  }
49495
- const DisconnectSection = ({ name, isOwner, hasAutoSync, isDisconnecting, onDisconnect, }) => {
49492
+ const DisconnectSection = ({ name, isOwner, owner, hasAutoSync, isDisconnecting, onDisconnect, }) => {
49496
49493
  const [isOpen, setIsOpen] = reactExports.useState(false);
49497
- return (jsxRuntimeExports.jsxs("div", { id: "disconnect-section", className: "flex flex-col gap-4 rounded-lg border border-destructive/20 bg-destructive/5 p-4 sm:flex-row sm:items-center", children: [jsxRuntimeExports.jsx(TriangleAlert, { className: "hidden size-5 shrink-0 self-start text-destructive sm:block" }), jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [jsxRuntimeExports.jsx("p", { className: "m-0 text-sm font-medium text-destructive", children: "Disconnect integration" }), jsxRuntimeExports.jsx("p", { className: "m-0 text-sm text-muted-foreground", children: isOwner
49498
- ? `Disconnects ${name} and removes its saved settings for this project.${hasAutoSync ? ' Auto Sync will stop.' : ''}`
49499
- : 'Only the integration owner can disconnect it.' })] }), jsxRuntimeExports.jsxs(Dialog, { open: isOpen, onOpenChange: (open) => !isDisconnecting && setIsOpen(open), children: [jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: jsxRuntimeExports.jsx(Button, { id: "disconnect-btn", variant: "destructive", disabled: !isOwner, className: "shrink-0 self-start sm:self-auto", children: "Disconnect" }) }), jsxRuntimeExports.jsxs(DialogContent, { role: "alertdialog", showCloseButton: false, className: "sm:max-w-md", children: [jsxRuntimeExports.jsxs(DialogHeader, { className: "items-center text-center sm:items-start sm:text-left", children: [jsxRuntimeExports.jsx("div", { className: "mb-2 flex size-10 items-center justify-center rounded-full bg-destructive/10", children: jsxRuntimeExports.jsx(TriangleAlert, { className: "size-5 text-destructive" }) }), jsxRuntimeExports.jsxs(DialogTitle, { children: ["Disconnect ", name, "?"] }), jsxRuntimeExports.jsxs(DialogDescription, { children: [name, " settings", hasAutoSync ? ', Auto Sync selections,' : '', " and logs for this project will be deleted. To use ", name, " again, you'll need to reconnect and set it up again."] })] }), jsxRuntimeExports.jsxs(DialogFooter, { children: [jsxRuntimeExports.jsx(Button, { variant: "outline", disabled: isDisconnecting, onClick: () => setIsOpen(false), children: "Cancel" }), jsxRuntimeExports.jsxs(Button, { id: "disconnect-confirm-btn", variant: "destructive", disabled: isDisconnecting, onClick: onDisconnect, children: [isDisconnecting && jsxRuntimeExports.jsx(Spinner, {}), "Disconnect"] })] })] })] })] }));
49494
+ return (jsxRuntimeExports.jsxs("div", { id: "disconnect-section", className: "flex flex-col gap-4 rounded-lg border border-destructive/20 bg-destructive/5 p-4 sm:flex-row sm:items-center", children: [jsxRuntimeExports.jsx(TriangleAlert, { className: "hidden size-5 shrink-0 self-start text-destructive sm:block" }), jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [jsxRuntimeExports.jsx("p", { className: "m-0 text-sm font-medium text-destructive", children: "Disconnect integration" }), jsxRuntimeExports.jsx("p", { className: "m-0 text-sm text-muted-foreground", children: isOwner ? (`Disconnects ${name} and removes its saved settings for this project.${hasAutoSync ? ' Auto Sync will stop.' : ''}`) : owner ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Only the integration owner (", jsxRuntimeExports.jsx(Button, { type: "button", variant: "link", id: "integration-owner-link", className: "h-auto p-0 align-baseline font-normal", onClick: () => contactUser(owner.id), children: owner.name }), ") can disconnect it."] })) : ('Only the integration owner can disconnect it.') })] }), jsxRuntimeExports.jsxs(Dialog, { open: isOpen, onOpenChange: (open) => !isDisconnecting && setIsOpen(open), children: [jsxRuntimeExports.jsx(DialogTrigger, { asChild: true, children: jsxRuntimeExports.jsx(Button, { id: "disconnect-btn", variant: "destructive", disabled: !isOwner, className: "shrink-0 self-start sm:self-auto", children: "Disconnect" }) }), jsxRuntimeExports.jsxs(DialogContent, { role: "alertdialog", showCloseButton: false, className: "sm:max-w-md", children: [jsxRuntimeExports.jsxs(DialogHeader, { className: "items-center text-center sm:items-start sm:text-left", children: [jsxRuntimeExports.jsx("div", { className: "mb-2 flex size-10 items-center justify-center rounded-full bg-destructive/10", children: jsxRuntimeExports.jsx(TriangleAlert, { className: "size-5 text-destructive" }) }), jsxRuntimeExports.jsxs(DialogTitle, { children: ["Disconnect ", name, "?"] }), jsxRuntimeExports.jsxs(DialogDescription, { children: [name, " settings", hasAutoSync ? ', Auto Sync selections,' : '', " and logs for this project will be deleted. To use ", name, " again, you'll need to reconnect and set it up again."] })] }), jsxRuntimeExports.jsxs(DialogFooter, { children: [jsxRuntimeExports.jsx(Button, { variant: "outline", disabled: isDisconnecting, onClick: () => setIsOpen(false), children: "Cancel" }), jsxRuntimeExports.jsxs(Button, { id: "disconnect-confirm-btn", variant: "destructive", disabled: isDisconnecting, onClick: onDisconnect, children: [isDisconnecting && jsxRuntimeExports.jsx(Spinner, {}), "Disconnect"] })] })] })] })] }));
49500
49495
  };
49501
- const SettingsModal = ({ modalRef, isLoading, configurationFields, isSaveDisabled, settingsFieldChange, registerSettingsField, fieldErrors, onSave, name, isOwner, hasAutoSync, isDisconnecting, onDisconnect, }) => {
49496
+ const SettingsModal = ({ modalRef, isLoading, configurationFields, isSaveDisabled, settingsFieldChange, registerSettingsField, fieldErrors, onSave, name, isOwner, owner, hasAutoSync, isDisconnecting, onDisconnect, }) => {
49502
49497
  const hasFields = configurationFields.length > 0;
49503
- const disconnectSection = (jsxRuntimeExports.jsx(DisconnectSection, { name: name, isOwner: isOwner, hasAutoSync: hasAutoSync, isDisconnecting: isDisconnecting, onDisconnect: onDisconnect }));
49498
+ const disconnectSection = (jsxRuntimeExports.jsx(DisconnectSection, { name: name, isOwner: isOwner, owner: owner, hasAutoSync: hasAutoSync, isDisconnecting: isDisconnecting, onDisconnect: onDisconnect }));
49504
49499
  const contentRef = reactExports.useRef(null);
49505
49500
  const observerRef = reactExports.useRef(null);
49506
49501
  const [contentHeight, setContentHeight] = reactExports.useState();
@@ -49596,7 +49591,7 @@ Defaulting to \`null\`.`;
49596
49591
  const USER_ERRORS_PER_PAGE = 10;
49597
49592
  const USER_ERRORS_SEARCH_DEBOUNCE = 300;
49598
49593
  const MainPage = (props) => {
49599
- const { name, userId, notice, checkSubscription, isManager, isOwner, infoModal, configurationFields, config: configString, syncNewElements, withCronSync, webhooks, integrationOneLevelFetching, integrationSearchListener, excludedTargetLanguages, filtering, hasOrganization, zenModeUrl, asyncProgress = { checkInterval: 3000 }, reloadOnConfigSave, progressiveCrowdinFilesLoading, integrationButtonMenuItems, crowdinButtonMenuItems, } = props;
49594
+ const { name, userId, notice, checkSubscription, isManager, isOwner, owner, infoModal, configurationFields, config: configString, syncNewElements, withCronSync, webhooks, integrationOneLevelFetching, integrationSearchListener, excludedTargetLanguages, filtering, hasOrganization, zenModeUrl, asyncProgress = { checkInterval: 3000 }, reloadOnConfigSave, progressiveCrowdinFilesLoading, integrationButtonMenuItems, crowdinButtonMenuItems, } = props;
49600
49595
  const config = reactExports.useRef(configString ? JSON.parse(configString.replace(/\\n/g, '\\\\n')) : {});
49601
49596
  const appComponent = reactExports.useRef(null);
49602
49597
  const asyncProgressRef = reactExports.useRef(null);
@@ -49663,13 +49658,12 @@ Defaulting to \`null\`.`;
49663
49658
  });
49664
49659
  reactExports.useEffect(() => {
49665
49660
  const handleKeydown = (event) => {
49661
+ var _a, _b, _c, _d;
49666
49662
  if (event.keyCode === 27) {
49667
- closeModal(permissionsModalRef.current);
49668
- closeModal(infoModalRef.current);
49669
- closeModal(scheduleModalRef.current);
49670
- if (syncOps.languageModalRef.current) {
49671
- closeModal(syncOps.languageModalRef.current);
49672
- }
49663
+ (_a = permissionsModalRef.current) === null || _a === void 0 ? void 0 : _a.close();
49664
+ (_b = infoModalRef.current) === null || _b === void 0 ? void 0 : _b.close();
49665
+ (_c = scheduleModalRef.current) === null || _c === void 0 ? void 0 : _c.close();
49666
+ (_d = syncOps.languageModalRef.current) === null || _d === void 0 ? void 0 : _d.close();
49673
49667
  }
49674
49668
  };
49675
49669
  document.body.addEventListener('keydown', handleKeydown);
@@ -49683,10 +49677,11 @@ Defaulting to \`null\`.`;
49683
49677
  // A 402 from any API call means the subscription lapsed: show the subscribe modal.
49684
49678
  reactExports.useEffect(() => {
49685
49679
  setPaymentRequiredHandler((subscribeLink) => {
49680
+ var _a;
49686
49681
  if (subscribeLink) {
49687
49682
  subscriptionLink.current = subscribeLink;
49688
49683
  }
49689
- openModal(subscriptionModal.current);
49684
+ (_a = subscriptionModal.current) === null || _a === void 0 ? void 0 : _a.open();
49690
49685
  });
49691
49686
  return () => setPaymentRequiredHandler(null);
49692
49687
  }, []);
@@ -49778,10 +49773,11 @@ Defaulting to \`null\`.`;
49778
49773
  loadUserErrors({ currentPage, rowsPerPage, searchText, isSortedAsc });
49779
49774
  }
49780
49775
  async function openUserErrorDetail(item) {
49776
+ var _a, _b;
49781
49777
  // the list response carries no `data` - the heavy payload is loaded for this record only
49782
49778
  const requestId = ++userErrorDetailRequestId.current;
49783
49779
  setSelectedUserError({ ...item, data: null });
49784
- openModal(userErrorDetailModalRef.current);
49780
+ (_a = userErrorDetailModalRef.current) === null || _a === void 0 ? void 0 : _a.open();
49785
49781
  try {
49786
49782
  const restParams = await checkOrigin();
49787
49783
  const res = await checkResponse(await fetch(`api/user-errors/${item.id}` + restParams));
@@ -49793,7 +49789,7 @@ Defaulting to \`null\`.`;
49793
49789
  return;
49794
49790
  }
49795
49791
  catchRejection(e, "Can't fetch error log details");
49796
- closeModal(userErrorDetailModalRef.current);
49792
+ (_b = userErrorDetailModalRef.current) === null || _b === void 0 ? void 0 : _b.close();
49797
49793
  setSelectedUserError(null);
49798
49794
  }
49799
49795
  }
@@ -49810,10 +49806,11 @@ Defaulting to \`null\`.`;
49810
49806
  function showIntegration() {
49811
49807
  setIsErrorLogsVisible(false);
49812
49808
  }
49813
- return (jsxRuntimeExports.jsxs("div", { className: cn('flex flex-col', isErrorLogsVisible ? 'min-h-full' : 'h-full'), children: [jsxRuntimeExports.jsxs("div", { className: "mx-auto flex min-h-0 w-full max-w-[1420px] flex-1 flex-col px-6 py-4", children: [jsxRuntimeExports.jsx(TopBar, { notice: notice, isNoticeVisible: isNoticeVisible, checkSubscription: checkSubscription, subscriptionInfo: subscriptionInfo, isErrorLogsVisible: isErrorLogsVisible, isManager: isManager, infoModal: infoModal, onCloseNotice: closeAlert, onShowIntegration: showIntegration, onShowErrorLogs: showErrorLogs, onShowPermissions: permissions.showPermissionsDialog, onOpenInfoModal: () => openModal(infoModalRef.current), onOpenSettings: () => {
49814
- openModal(settingsModalRef.current);
49809
+ return (jsxRuntimeExports.jsxs("div", { className: cn('flex flex-col', isErrorLogsVisible ? 'min-h-full' : 'h-full'), children: [jsxRuntimeExports.jsxs("div", { className: "mx-auto flex min-h-0 w-full max-w-[1420px] flex-1 flex-col px-6 py-4", children: [jsxRuntimeExports.jsx(TopBar, { notice: notice, isNoticeVisible: isNoticeVisible, checkSubscription: checkSubscription, subscriptionInfo: subscriptionInfo, isErrorLogsVisible: isErrorLogsVisible, isManager: isManager, infoModal: infoModal, onCloseNotice: closeAlert, onShowIntegration: showIntegration, onShowErrorLogs: showErrorLogs, onShowPermissions: permissions.showPermissionsDialog, onOpenInfoModal: () => { var _a; return (_a = infoModalRef.current) === null || _a === void 0 ? void 0 : _a.open(); }, onOpenSettings: () => {
49810
+ var _a;
49811
+ (_a = settingsModalRef.current) === null || _a === void 0 ? void 0 : _a.open();
49815
49812
  setTimeout(settings.fillSettingsForm, 0);
49816
- } }), jsxRuntimeExports.jsx(IntegrationView, { appComponentRef: appComponent, userErrors: userErrors, isUserErrorsLoading: isUserErrorsLoading, userErrorsTotal: userErrorsTotal, userErrorsCurrentPage: userErrorsCurrentPage, userErrorsRowsPerPage: userErrorsRowsPerPage, userErrorsSearchText: userErrorsSearchText, userErrorsIsSortedAsc: userErrorsIsSortedAsc, onSelectUserError: openUserErrorDetail, onUserErrorsOptionsChange: onUserErrorsOptionsChange, name: name, isErrorLogsVisible: isErrorLogsVisible, syncNewElements: syncNewElements, withCronSync: withCronSync, webhooks: webhooks, integrationOneLevelFetching: integrationOneLevelFetching, integrationSearchListener: integrationSearchListener, filtering: filtering, integrationButtonMenuItems: integrationButtonMenuItems, crowdinButtonMenuItems: crowdinButtonMenuItems, onRefreshFilesList: syncOps.handleRefreshFilesList, onFolderToggle: syncOps.handleFolderToggle, onUploadFilesToCrowdin: (detail) => syncOps.uploadFilesToCrowdin({ detail }), onUploadFilesToIntegration: (detail) => syncOps.uploadFilesToIntegration({ detail }), onLoadMore: syncOps.handleLoadMore, onIntegrationFilterChange: syncOps.handleIntegrationFilterChange, onIntegrationScheduleSync: (detail) => schedule.setIntegrationScheduleSync({ detail }), onCrowdinScheduleSync: (detail) => schedule.setCrowdinScheduleSync({ detail }), onIntegrationDisableSync: (detail) => schedule.disableIntegrationSync({ detail }), onCrowdinDisableSync: (detail) => schedule.disableCrowdinSync({ detail }) })] }), jsxRuntimeExports.jsx(Toaster, {}), jsxRuntimeExports.jsx(AsyncProgress, { ref: asyncProgressRef, onCancelJob: syncOps.cancelJob }), jsxRuntimeExports.jsx(SubscriptionModal, { modalRef: subscriptionModal, subscriptionLink: subscriptionLink, name: name, isDisconnecting: isDisconnecting, onLogout: integrationLogout }), jsxRuntimeExports.jsx(PermissionsModal, { modalRef: permissionsModalRef, isLoading: permissions.isLoading, permissionUserOptions: permissions.permissionUserOptions, selectedUsers: permissions.permissionsSelectedUsers, isConfirmVisible: permissions.isPermissionsConfirmVisible, permissionsSummary: permissions.permissionsSummary, hasOrganization: hasOrganization, zenModeUrl: zenModeUrl, saveDisabled: !permissions.isPermissionsLoaded, onUsersChange: permissions.checkUsers, onSave: permissions.inviteUsers }), excludedTargetLanguages && (jsxRuntimeExports.jsx(ExcludedLanguagesModal, { modalRef: syncOps.languageModalRef, languageSelectRef: syncOps.languageSelectRef, languageModalState: syncOps.languageModalState, onUpdateTargetLanguages: syncOps.updateCrowdinFilesTargetLanguages, onSyncToCrowdin: syncOps.uploadFilesToCrowdinWithExcludedLanguages })), infoModal && jsxRuntimeExports.jsx(InfoModal, { modalRef: infoModalRef, infoModal: infoModal }), jsxRuntimeExports.jsx(SettingsModal, { modalRef: settingsModalRef, isLoading: settings.isLoading, configurationFields: configurationFields !== null && configurationFields !== void 0 ? configurationFields : [], isSaveDisabled: settings.isSettingsSaveDisabled, settingsFieldChange: settings.settingsFieldChange, registerSettingsField: settings.registerSettingsField, fieldErrors: settings.fieldErrors, onSave: settings.saveSettings, name: name, isOwner: isOwner, hasAutoSync: !!(withCronSync || webhooks), isDisconnecting: isDisconnecting, onDisconnect: integrationLogout }), ((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) || (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)) && (jsxRuntimeExports.jsx(ScheduleModal, { modalRef: scheduleModalRef, selectedFilesCheckboxRef: schedule.selectedFilesCheckboxRef, allFolderFilesCheckboxRef: schedule.allFolderFilesCheckboxRef, newFilesCheckboxRef: schedule.newFilesCheckboxRef, scheduleModalState: schedule.scheduleModalState, isSaveDisabled: schedule.isScheduleSaveDisabled, onChangeOptions: schedule.onChangeAutoSynchronizationOptions, onSave: schedule.saveScheduleSync })), jsxRuntimeExports.jsx(UserErrorDetailModal, { modalRef: userErrorDetailModalRef, selectedUserError: selectedUserError, onClose: onUserErrorDetailClose })] }));
49813
+ } }), jsxRuntimeExports.jsx(IntegrationView, { appComponentRef: appComponent, userErrors: userErrors, isUserErrorsLoading: isUserErrorsLoading, userErrorsTotal: userErrorsTotal, userErrorsCurrentPage: userErrorsCurrentPage, userErrorsRowsPerPage: userErrorsRowsPerPage, userErrorsSearchText: userErrorsSearchText, userErrorsIsSortedAsc: userErrorsIsSortedAsc, onSelectUserError: openUserErrorDetail, onUserErrorsOptionsChange: onUserErrorsOptionsChange, name: name, isErrorLogsVisible: isErrorLogsVisible, syncNewElements: syncNewElements, withCronSync: withCronSync, webhooks: webhooks, integrationOneLevelFetching: integrationOneLevelFetching, integrationSearchListener: integrationSearchListener, filtering: filtering, integrationButtonMenuItems: integrationButtonMenuItems, crowdinButtonMenuItems: crowdinButtonMenuItems, onRefreshFilesList: syncOps.handleRefreshFilesList, onFolderToggle: syncOps.handleFolderToggle, onUploadFilesToCrowdin: (detail) => syncOps.uploadFilesToCrowdin({ detail }), onUploadFilesToIntegration: (detail) => syncOps.uploadFilesToIntegration({ detail }), onLoadMore: syncOps.handleLoadMore, onIntegrationFilterChange: syncOps.handleIntegrationFilterChange, onIntegrationScheduleSync: (detail) => schedule.setIntegrationScheduleSync({ detail }), onCrowdinScheduleSync: (detail) => schedule.setCrowdinScheduleSync({ detail }), onIntegrationDisableSync: (detail) => schedule.disableIntegrationSync({ detail }), onCrowdinDisableSync: (detail) => schedule.disableCrowdinSync({ detail }) })] }), jsxRuntimeExports.jsx(Toaster, {}), jsxRuntimeExports.jsx(AsyncProgress, { ref: asyncProgressRef, onCancelJob: syncOps.cancelJob }), jsxRuntimeExports.jsx(SubscriptionModal, { modalRef: subscriptionModal, subscriptionLink: subscriptionLink, name: name, isDisconnecting: isDisconnecting, onLogout: integrationLogout }), jsxRuntimeExports.jsx(PermissionsModal, { modalRef: permissionsModalRef, isLoading: permissions.isLoading, isCheckingUsers: permissions.isCheckingUsers, permissionUserOptions: permissions.permissionUserOptions, selectedUsers: permissions.permissionsSelectedUsers, isConfirmVisible: permissions.isPermissionsConfirmVisible, permissionsSummary: permissions.permissionsSummary, hasOrganization: hasOrganization, zenModeUrl: zenModeUrl, saveDisabled: !permissions.isPermissionsLoaded, onUsersChange: permissions.checkUsers, onSave: permissions.inviteUsers }), excludedTargetLanguages && (jsxRuntimeExports.jsx(ExcludedLanguagesModal, { modalRef: syncOps.languageModalRef, languageSelectRef: syncOps.languageSelectRef, languageModalState: syncOps.languageModalState, onUpdateTargetLanguages: syncOps.updateCrowdinFilesTargetLanguages, onSyncToCrowdin: syncOps.uploadFilesToCrowdinWithExcludedLanguages })), infoModal && jsxRuntimeExports.jsx(InfoModal, { modalRef: infoModalRef, infoModal: infoModal }), jsxRuntimeExports.jsx(SettingsModal, { modalRef: settingsModalRef, isLoading: settings.isLoading, configurationFields: configurationFields !== null && configurationFields !== void 0 ? configurationFields : [], isSaveDisabled: settings.isSettingsSaveDisabled, settingsFieldChange: settings.settingsFieldChange, registerSettingsField: settings.registerSettingsField, fieldErrors: settings.fieldErrors, onSave: settings.saveSettings, name: name, isOwner: isOwner, owner: owner, hasAutoSync: !!(withCronSync || webhooks), isDisconnecting: isDisconnecting, onDisconnect: integrationLogout }), ((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) || (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)) && (jsxRuntimeExports.jsx(ScheduleModal, { modalRef: scheduleModalRef, selectedFilesCheckboxRef: schedule.selectedFilesCheckboxRef, allFolderFilesCheckboxRef: schedule.allFolderFilesCheckboxRef, newFilesCheckboxRef: schedule.newFilesCheckboxRef, scheduleModalState: schedule.scheduleModalState, isSaveDisabled: schedule.isScheduleSaveDisabled, onChangeOptions: schedule.onChangeAutoSynchronizationOptions, onSave: schedule.saveScheduleSync })), jsxRuntimeExports.jsx(UserErrorDetailModal, { modalRef: userErrorDetailModalRef, selectedUserError: selectedUserError, onClose: onUserErrorDetailClose })] }));
49817
49814
  };
49818
49815
 
49819
49816
  initializeCrowdinIframeContext();