@crowdin/app-project-module 2.1.0 → 2.3.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.
Files changed (59) hide show
  1. package/out/index.d.ts +1 -0
  2. package/out/index.js +5 -1
  3. package/out/middlewares/ui-module.js +1 -2
  4. package/out/modules/about.d.ts +4 -0
  5. package/out/modules/about.js +25 -3
  6. package/out/modules/advisor-inspector/handlers/recheck.d.ts +4 -0
  7. package/out/modules/advisor-inspector/handlers/recheck.js +44 -0
  8. package/out/modules/advisor-inspector/index.d.ts +6 -0
  9. package/out/modules/advisor-inspector/index.js +35 -0
  10. package/out/modules/advisor-inspector/key.d.ts +4 -0
  11. package/out/modules/advisor-inspector/key.js +13 -0
  12. package/out/modules/advisor-inspector/report-insight.d.ts +3 -0
  13. package/out/modules/advisor-inspector/report-insight.js +61 -0
  14. package/out/modules/advisor-inspector/types.d.ts +59 -0
  15. package/out/modules/advisor-inspector/types.js +2 -0
  16. package/out/modules/manifest.js +15 -0
  17. package/out/static/css/styles.css +2 -342
  18. package/out/static/ui/about.bundle.js +542 -0
  19. package/out/static/ui/about.bundle.js.map +1 -0
  20. package/out/static/ui/error.bundle.js +120 -2
  21. package/out/static/ui/error.bundle.js.map +1 -1
  22. package/out/static/ui/form.bundle.js +164 -12
  23. package/out/static/ui/form.bundle.js.map +1 -1
  24. package/out/static/ui/install.bundle.js +8 -2
  25. package/out/static/ui/install.bundle.js.map +1 -1
  26. package/out/static/ui/login.bundle.js +425 -35
  27. package/out/static/ui/login.bundle.js.map +1 -1
  28. package/out/static/ui/main.bundle.js +718 -366
  29. package/out/static/ui/main.bundle.js.map +1 -1
  30. package/out/static/ui/oauth.bundle.js +8 -2
  31. package/out/static/ui/oauth.bundle.js.map +1 -1
  32. package/out/static/ui/subscription.bundle.js +542 -0
  33. package/out/static/ui/subscription.bundle.js.map +1 -0
  34. package/out/storage/drizzle/postgresql/migrations/0002_equal_skrulls.sql +3 -0
  35. package/out/storage/drizzle/postgresql/migrations/meta/0002_snapshot.json +646 -0
  36. package/out/storage/drizzle/postgresql/migrations/meta/_journal.json +7 -0
  37. package/out/storage/drizzle/postgresql/schema.js +2 -1
  38. package/out/storage/drizzle/sqlite/migrations/0001_new_rhodey.sql +26 -0
  39. package/out/storage/drizzle/sqlite/migrations/meta/0001_snapshot.json +687 -0
  40. package/out/storage/drizzle/sqlite/migrations/meta/_journal.json +7 -0
  41. package/out/storage/drizzle/sqlite/schema.js +2 -1
  42. package/out/types.d.ts +6 -0
  43. package/out/util/jsx-renderer.d.ts +2 -1
  44. package/out/util/jsx-renderer.js +8 -8
  45. package/out/views/FormPage.js +2 -2
  46. package/out/views/index.d.ts +0 -2
  47. package/out/views/index.js +1 -5
  48. package/out/views/layout/Head.js +0 -10
  49. package/package.json +5 -2
  50. package/out/static/css/about.css +0 -128
  51. package/out/static/css/crowdin-ui-colors.css +0 -115
  52. package/out/static/js/dependent.js +0 -315
  53. package/out/static/js/main.js +0 -96
  54. package/out/static/js/polyfills/fetch.js +0 -494
  55. package/out/static/js/polyfills/promise.js +0 -375
  56. package/out/views/AboutPage.d.ts +0 -10
  57. package/out/views/AboutPage.js +0 -88
  58. package/out/views/SubscriptionPage.d.ts +0 -7
  59. package/out/views/SubscriptionPage.js +0 -26
@@ -518,9 +518,374 @@
518
518
 
519
519
  var clientExports = requireClient();
520
520
 
521
+ /// <reference path="../types.d.ts" />
522
+ const postPromises = {};
523
+ let isInitialized = false;
524
+ let origin = null;
525
+ let clientId = null;
526
+ let restParams = '';
527
+ function parseJson(value) {
528
+ try {
529
+ return JSON.parse(value);
530
+ }
531
+ catch {
532
+ return undefined;
533
+ }
534
+ }
535
+ function handleMessage(event) {
536
+ if (event.origin !== window.location.origin || typeof event.data !== 'string') {
537
+ return;
538
+ }
539
+ const eventData = parseJson(event.data);
540
+ if (!(eventData === null || eventData === void 0 ? void 0 : eventData.uid)) {
541
+ return;
542
+ }
543
+ const postPromise = postPromises[eventData.uid];
544
+ if (postPromise) {
545
+ delete postPromises[eventData.uid];
546
+ if (postPromise.timer) {
547
+ clearTimeout(postPromise.timer);
548
+ }
549
+ postPromise.resolve(eventData.data);
550
+ }
551
+ }
552
+ function initializeCrowdinIframeContext() {
553
+ if (isInitialized) {
554
+ return;
555
+ }
556
+ const urlParams = new URLSearchParams(window.location.search);
557
+ origin = urlParams.get('origin');
558
+ clientId = urlParams.get('client_id');
559
+ restParams = window.location.search;
560
+ JSON.parse(window.name);
561
+ window.addEventListener('message', handleMessage);
562
+ isInitialized = true;
563
+ }
564
+ function ensureInitialized() {
565
+ if (!isInitialized) {
566
+ initializeCrowdinIframeContext();
567
+ }
568
+ }
569
+ function showToast(message) {
570
+ if (message) {
571
+ const toasts = document.querySelector('crowdin-toasts');
572
+ if (toasts && toasts.pushToasts) {
573
+ toasts.pushToasts([message]);
574
+ }
575
+ }
576
+ }
577
+ function reloadLocation() {
578
+ ensureInitialized();
579
+ window.location.href =
580
+ window.location.protocol + '//' + window.location.host + window.location.pathname + restParams;
581
+ }
582
+ function catchRejection(e, message) {
583
+ var _a;
584
+ // session expired
585
+ if (e.code && e.code === 401) {
586
+ reloadLocation();
587
+ return;
588
+ }
589
+ // payment required
590
+ if (e.code && e.code === 402 && ((_a = window.app) === null || _a === void 0 ? void 0 : _a.subscriptionModal.current)) {
591
+ if (window.app.subscriptionLink) {
592
+ window.app.subscriptionLink.current = e.message || message;
593
+ }
594
+ window.app.openModal(window.app.subscriptionModal.current);
595
+ return;
596
+ }
597
+ showToast(e.message || message);
598
+ }
599
+ function checkResponse(response) {
600
+ return new Promise((resolve, reject) => {
601
+ if (response.status === 204) {
602
+ return resolve(undefined);
603
+ }
604
+ response
605
+ .json()
606
+ .then((res) => {
607
+ if (![200, 201, 202, 304].includes(response.status)) {
608
+ reject(res);
609
+ }
610
+ else {
611
+ if (res.message) {
612
+ setTimeout(() => showToast(res.message), 100);
613
+ }
614
+ resolve(res);
615
+ }
616
+ })
617
+ .catch((e) => {
618
+ reject(e);
619
+ });
620
+ });
621
+ }
622
+ function checkOrigin() {
623
+ ensureInitialized();
624
+ return new Promise((resolve) => {
625
+ AP.getJwtToken((jwtToken) => {
626
+ restParams = `?origin=${origin}&client_id=${clientId}&jwtToken=${jwtToken}`;
627
+ resolve(restParams);
628
+ });
629
+ });
630
+ }
631
+
632
+ function readPageProps() {
633
+ const element = document.getElementById('__PAGE_PROPS__');
634
+ return JSON.parse((element === null || element === void 0 ? void 0 : element.textContent) || '{}');
635
+ }
636
+
521
637
  var reactExports = requireReact();
522
638
 
523
- const renderConfigField = (field, settingsFieldChange, suffix = 'settings') => {
639
+ const dependencyShowClassName = 'dependency-show';
640
+ const events = ['input', 'change'];
641
+ function useFieldDependencies(refreshKey) {
642
+ const cleanupRef = reactExports.useRef(() => undefined);
643
+ const refreshDependencies = reactExports.useCallback(() => {
644
+ cleanupRef.current();
645
+ cleanupRef.current = initializeFieldDependencies();
646
+ }, []);
647
+ reactExports.useEffect(() => {
648
+ refreshDependencies();
649
+ return () => {
650
+ cleanupRef.current();
651
+ cleanupRef.current = () => undefined;
652
+ };
653
+ }, [refreshDependencies, refreshKey]);
654
+ return refreshDependencies;
655
+ }
656
+ function initializeFieldDependencies(root = document) {
657
+ const cleanupCallbacks = [];
658
+ const fields = Array.from(root.querySelectorAll('[data-dependency]'));
659
+ fields.forEach((field) => {
660
+ const dependency = field.dataset.dependency;
661
+ if (!dependency) {
662
+ return;
663
+ }
664
+ try {
665
+ const conditions = JSON.parse(dependency);
666
+ applyDependencyState(field, conditions);
667
+ cleanupCallbacks.push(...bindDependencyListeners(field, conditions));
668
+ }
669
+ catch (e) {
670
+ console.error('[Dependencies] Error parsing conditions for field:', field, e);
671
+ }
672
+ });
673
+ return () => {
674
+ cleanupCallbacks.forEach((cleanup) => cleanup());
675
+ };
676
+ }
677
+ function bindDependencyListeners(field, conditions) {
678
+ const cleanupCallbacks = [];
679
+ conditions.forEach((rules) => {
680
+ Object.keys(rules).forEach((selector) => {
681
+ const element = document.querySelector(selector);
682
+ if (!element) {
683
+ return;
684
+ }
685
+ events.forEach((event) => {
686
+ const listener = () => applyDependencyState(field, conditions);
687
+ element.addEventListener(event, listener);
688
+ cleanupCallbacks.push(() => element.removeEventListener(event, listener));
689
+ });
690
+ });
691
+ });
692
+ return cleanupCallbacks;
693
+ }
694
+ function applyDependencyState(field, conditions) {
695
+ if (checkConditions(conditions)) {
696
+ field.classList.add(dependencyShowClassName);
697
+ }
698
+ else {
699
+ field.classList.remove(dependencyShowClassName);
700
+ }
701
+ }
702
+ function checkConditions(conditions) {
703
+ return conditions.every((conditionObj) => {
704
+ const selectors = Object.keys(conditionObj);
705
+ return selectors.every((selector) => evaluateDependencyRule(selector, conditionObj[selector]));
706
+ });
707
+ }
708
+ function evaluateDependencyRule(selector, condition) {
709
+ const type = condition.type;
710
+ const currentValue = getValue(selector);
711
+ const checkValue = typeof condition.value === 'undefined' ? false : condition.value;
712
+ let minValue = typeof condition.min === 'undefined' ? false : Number.parseInt(String(condition.min), 10);
713
+ let maxValue = typeof condition.max === 'undefined' ? false : Number.parseInt(String(condition.max), 10);
714
+ const allowEmpty = typeof condition.empty === 'undefined' ? false : condition.empty;
715
+ const isEmpty = !allowEmpty && currentValue.length < 1;
716
+ const likeSelector = typeof condition.like === 'undefined' ? false : condition.like;
717
+ const likeSelectorValue = getValue(likeSelector);
718
+ const regExpPattern = typeof condition.pattern === 'undefined' ? false : condition.pattern;
719
+ const regExpModifier = typeof condition.modifier === 'undefined' ? 'gi' : condition.modifier;
720
+ const sign = typeof condition.sign === 'undefined' ? false : condition.sign;
721
+ const strict = typeof condition.strict === 'undefined' ? false : condition.strict;
722
+ const emptyTypes = ['empty', 'blank'];
723
+ const notEmptyTypes = ['!empty', 'notEmpty', 'not-empty', 'notempty'];
724
+ const equalTypes = ['equal', '=', '==', '==='];
725
+ const notEqualTypes = ['!equal', '!=', '!==', '!===', 'notEqual', 'not-equal', 'notequal'];
726
+ const regularExpressionTypes = ['regexp', 'exp', 'expression', 'match'];
727
+ if (type && emptyTypes.includes(type)) {
728
+ return currentValue.length < 1;
729
+ }
730
+ if (type && notEmptyTypes.includes(type)) {
731
+ return currentValue.length > 0;
732
+ }
733
+ if (type && equalTypes.includes(type)) {
734
+ if (isEmpty) {
735
+ return false;
736
+ }
737
+ if (likeSelector) {
738
+ return strict
739
+ ? likeSelectorValue.every((value) => currentValue.includes(value))
740
+ : likeSelectorValue.some((value) => currentValue.includes(value));
741
+ }
742
+ if (strict) {
743
+ if (checkValue && Array.isArray(checkValue)) {
744
+ return checkValue.every((value) => currentValue.includes(value));
745
+ }
746
+ if (checkValue && !Array.isArray(checkValue)) {
747
+ return currentValue.includes(checkValue);
748
+ }
749
+ }
750
+ else {
751
+ if (checkValue && Array.isArray(checkValue)) {
752
+ return checkValue.some((value) => currentValue.includes(value));
753
+ }
754
+ if (checkValue && !Array.isArray(checkValue)) {
755
+ return currentValue.includes(checkValue);
756
+ }
757
+ }
758
+ }
759
+ if (type && notEqualTypes.includes(type)) {
760
+ if (isEmpty) {
761
+ return false;
762
+ }
763
+ if (likeSelector) {
764
+ return strict
765
+ ? likeSelectorValue.every((value) => !currentValue.includes(value))
766
+ : likeSelectorValue.some((value) => !currentValue.includes(value));
767
+ }
768
+ if (strict) {
769
+ if (checkValue && Array.isArray(checkValue)) {
770
+ return checkValue.every((value) => !currentValue.includes(value));
771
+ }
772
+ if (checkValue && !Array.isArray(checkValue)) {
773
+ return !currentValue.includes(checkValue);
774
+ }
775
+ }
776
+ else {
777
+ if (checkValue && Array.isArray(checkValue)) {
778
+ return checkValue.some((value) => !currentValue.includes(value));
779
+ }
780
+ if (checkValue && !Array.isArray(checkValue)) {
781
+ return !currentValue.includes(checkValue);
782
+ }
783
+ }
784
+ }
785
+ if (type && regularExpressionTypes.includes(type) && regExpPattern) {
786
+ if (isEmpty) {
787
+ return false;
788
+ }
789
+ const exp = new RegExp(regExpPattern, regExpModifier);
790
+ return currentValue.every((value) => exp.test(String(value)));
791
+ }
792
+ if (type === 'length') {
793
+ if (isEmpty) {
794
+ return false;
795
+ }
796
+ if (checkValue && Array.isArray(checkValue)) {
797
+ minValue = Number.parseInt(String(checkValue[0]), 10);
798
+ maxValue = typeof checkValue[1] === 'undefined' ? false : Number.parseInt(String(checkValue[1]), 10);
799
+ }
800
+ if (checkValue && !Array.isArray(checkValue)) {
801
+ minValue = Number.parseInt(String(checkValue), 10);
802
+ maxValue = false;
803
+ }
804
+ const minBoundary = minValue === false ? 0 : minValue;
805
+ const maxBoundary = maxValue === false ? 0 : maxValue;
806
+ return currentValue.every((value) => {
807
+ const valueLength = String(value).length;
808
+ if (!maxValue) {
809
+ return valueLength >= minBoundary;
810
+ }
811
+ if (!minValue) {
812
+ return valueLength <= maxBoundary;
813
+ }
814
+ return valueLength >= minBoundary && valueLength <= maxBoundary;
815
+ });
816
+ }
817
+ if (type === 'range') {
818
+ if (isEmpty) {
819
+ return false;
820
+ }
821
+ if (checkValue && Array.isArray(checkValue)) {
822
+ minValue = Number.parseInt(String(checkValue[0]), 10);
823
+ maxValue = typeof checkValue[1] === 'undefined' ? false : Number.parseInt(String(checkValue[1]), 10);
824
+ }
825
+ const minBoundary = minValue === false ? 0 : minValue;
826
+ const maxBoundary = maxValue === false ? 0 : maxValue;
827
+ return currentValue.every((value) => {
828
+ const numericValue = Number.parseInt(String(value), 10);
829
+ if (!maxValue) {
830
+ return numericValue > minBoundary;
831
+ }
832
+ if (!minValue) {
833
+ return numericValue < maxBoundary;
834
+ }
835
+ return numericValue > minBoundary && numericValue < maxBoundary;
836
+ });
837
+ }
838
+ if (type === 'compare' && sign && checkValue) {
839
+ if (isEmpty) {
840
+ return false;
841
+ }
842
+ const numericCheckValue = Number.parseInt(String(checkValue), 10);
843
+ switch (sign) {
844
+ case '<':
845
+ return currentValue.every((value) => Number.parseInt(String(value), 10) < numericCheckValue);
846
+ case '<=':
847
+ return currentValue.every((value) => Number.parseInt(String(value), 10) <= numericCheckValue);
848
+ case '>':
849
+ return currentValue.every((value) => Number.parseInt(String(value), 10) > numericCheckValue);
850
+ case '>=':
851
+ return currentValue.every((value) => Number.parseInt(String(value), 10) >= numericCheckValue);
852
+ case '=':
853
+ case '==':
854
+ return currentValue.every((value) => Number.parseInt(String(value), 10) === numericCheckValue);
855
+ }
856
+ }
857
+ return false;
858
+ }
859
+ function getValue(selector) {
860
+ const values = [];
861
+ if (selector && document.querySelector(selector)) {
862
+ const inputType = document.querySelector(selector).tagName.toLowerCase();
863
+ let currentSelector = selector;
864
+ if (inputType === 'crowdin-select') {
865
+ currentSelector = `${selector} option:checked`;
866
+ }
867
+ if (inputType === 'crowdin-checkbox') {
868
+ currentSelector = `${selector}:not(input)`;
869
+ }
870
+ document.querySelectorAll(currentSelector).forEach((element) => {
871
+ const value = element.value || element.checked;
872
+ values.push(value);
873
+ });
874
+ }
875
+ return values.filter((value) => value !== '');
876
+ }
877
+
878
+ const EMPTY_PERMISSION_VALUE = '\u2015';
879
+ const getDefaultScheduleModalState = () => ({
880
+ type: null,
881
+ showNewFiles: true,
882
+ showAllFolderFiles: false,
883
+ newFiles: false,
884
+ newFilesClearSelection: false,
885
+ selectedFiles: true,
886
+ allFolderFiles: false,
887
+ });
888
+ const renderConfigField = (field, settingsFieldChange, registerSettingsField, suffix = 'settings') => {
524
889
  var _a;
525
890
  if (!field.key) {
526
891
  return field.labelHtml ? (jsxRuntimeExports.jsx("crowdin-p", { ...(field.dependencySettings ? { 'data-dependency': field.dependencySettings } : {}), dangerouslySetInnerHTML: { __html: field.labelHtml } })) : (jsxRuntimeExports.jsx("crowdin-p", { ...(field.dependencySettings ? { 'data-dependency': field.dependencySettings } : {}), children: field.label }));
@@ -535,18 +900,18 @@
535
900
  };
536
901
  switch (field.type) {
537
902
  case 'checkbox':
538
- return (jsxRuntimeExports.jsx("crowdin-checkbox", { ...commonProps, value: "false", "use-switch": true, ...(field.defaultValue === true ? { checked: String(field.defaultValue) } : {}), onChange: settingsFieldChange }));
903
+ return (jsxRuntimeExports.jsx("crowdin-checkbox", { ref: registerSettingsField(field.key), ...commonProps, value: "false", "use-switch": true, ...(field.defaultValue === true ? { checked: String(field.defaultValue) } : {}), onChange: settingsFieldChange }));
539
904
  case 'select':
540
- return (jsxRuntimeExports.jsx("crowdin-select", { ...commonProps, ...(field.isMulti ? { 'is-multi': true, 'close-on-select': 'false' } : {}), ...(field.isSearchable ? { 'is-searchable': true } : {}), "is-position-fixed": true, onChange: settingsFieldChange, children: (_a = field.options) === null || _a === void 0 ? void 0 : _a.map((option) => {
905
+ return (jsxRuntimeExports.jsx("crowdin-select", { ref: registerSettingsField(field.key), ...commonProps, ...(field.isMulti ? { 'is-multi': true, 'close-on-select': 'false' } : {}), ...(field.isSearchable ? { 'is-searchable': true } : {}), "is-position-fixed": true, onChange: settingsFieldChange, children: (_a = field.options) === null || _a === void 0 ? void 0 : _a.map((option) => {
541
906
  const isSelected = Array.isArray(field.defaultValue)
542
907
  ? field.defaultValue.includes(option.value)
543
908
  : field.defaultValue === option.value;
544
909
  return (jsxRuntimeExports.jsx("option", { value: option.value, ...(isSelected ? { selected: true } : {}), children: option.label }, option.value));
545
910
  }) }));
546
911
  case 'text':
547
- return (jsxRuntimeExports.jsx("crowdin-input", { ...commonProps, "with-fixed-height": true, value: field.defaultValue || '', onChange: settingsFieldChange }));
912
+ return (jsxRuntimeExports.jsx("crowdin-input", { ref: registerSettingsField(field.key), ...commonProps, "with-fixed-height": true, value: field.defaultValue || '', onChange: settingsFieldChange }));
548
913
  case 'textarea':
549
- return (jsxRuntimeExports.jsx("crowdin-textarea", { ...commonProps, value: field.defaultValue || '', onChange: settingsFieldChange }));
914
+ return (jsxRuntimeExports.jsx("crowdin-textarea", { ref: registerSettingsField(field.key), ...commonProps, value: field.defaultValue || '', onChange: settingsFieldChange }));
550
915
  case 'notice':
551
916
  return (jsxRuntimeExports.jsx("crowdin-alert", { ...(field.noticeType ? { type: field.noticeType } : {}), ...(field.label ? { title: field.label } : {}), ...(field.noIcon ? { 'no-icon': String(field.noIcon) } : {}), ...(field.dependencySettings ? { 'data-dependency': field.dependencySettings } : {}), dangerouslySetInnerHTML: { __html: field.helpTextHtml || field.helpText || '' } }));
552
917
  default:
@@ -577,9 +942,22 @@
577
942
  };
578
943
  const silentJobs = [JOB_TYPE.integrationSettingsSave];
579
944
  const appComponent = reactExports.useRef(null);
945
+ const asyncProgressRef = reactExports.useRef(null);
946
+ const infoModalRef = reactExports.useRef(null);
580
947
  const subscriptionModal = reactExports.useRef(null);
948
+ const settingsModalRef = reactExports.useRef(null);
949
+ const scheduleModalRef = reactExports.useRef(null);
950
+ const selectedFilesCheckboxRef = reactExports.useRef(null);
951
+ const allFolderFilesCheckboxRef = reactExports.useRef(null);
952
+ const newFilesCheckboxRef = reactExports.useRef(null);
581
953
  const languageModal = reactExports.useRef(null);
954
+ const languageSelectRef = reactExports.useRef(null);
955
+ const permissionsModalRef = reactExports.useRef(null);
956
+ const userErrorsTableRef = reactExports.useRef(null);
957
+ const userErrorDetailModalRef = reactExports.useRef(null);
582
958
  const usersSelectRef = reactExports.useRef(null);
959
+ const settingsFieldRefs = reactExports.useRef({});
960
+ const refreshDependencies = useFieldDependencies(configurationFields);
583
961
  const crowdinFilesToUpdateTargetLanguages = reactExports.useRef([]);
584
962
  const asyncJobs = reactExports.useRef({});
585
963
  const project = reactExports.useRef({});
@@ -590,6 +968,19 @@
590
968
  const hasLoadMoreElements = reactExports.useRef(false);
591
969
  const savedIntegrationData = reactExports.useRef(null);
592
970
  const currentOpenedFolders = reactExports.useRef(null);
971
+ const [modalLoaders, setModalLoaders] = reactExports.useState({});
972
+ const [languageModalState, setLanguageModalState] = reactExports.useState(null);
973
+ const [permissionUserOptions, setPermissionUserOptions] = reactExports.useState([]);
974
+ const [permissionsSelectedValue, setPermissionsSelectedValue] = reactExports.useState('[]');
975
+ const [permissionsSummary, setPermissionsSummary] = reactExports.useState(null);
976
+ const [isPermissionsConfirmVisible, setIsPermissionsConfirmVisible] = reactExports.useState(false);
977
+ const [isNoticeVisible, setIsNoticeVisible] = reactExports.useState(false);
978
+ const [isSettingsSaveDisabled, setIsSettingsSaveDisabled] = reactExports.useState(false);
979
+ const [scheduleModalState, setScheduleModalState] = reactExports.useState(getDefaultScheduleModalState);
980
+ const [isScheduleSaveDisabled, setIsScheduleSaveDisabled] = reactExports.useState(false);
981
+ const [subscriptionInfo, setSubscriptionInfo] = reactExports.useState(null);
982
+ const [isErrorLogsVisible, setIsErrorLogsVisible] = reactExports.useState(false);
983
+ const [selectedUserError, setSelectedUserError] = reactExports.useState(null);
593
984
  reactExports.useEffect(() => {
594
985
  // Event listeners
595
986
  const listeners = {
@@ -618,28 +1009,22 @@
618
1009
  },
619
1010
  keydown: (event) => {
620
1011
  if (event.keyCode === 27) {
621
- const permissions = document.getElementById('permissions-modal');
622
- // not sure where we get users from here
623
- // @ts-ignore
624
- if (users) {
625
- closeModal(permissions);
626
- }
627
- const infoModalEl = document.getElementById('info-modal');
628
- if (infoModalEl) {
629
- closeModal(infoModalEl);
630
- }
631
- const settingsModal = document.getElementById('settings-modal');
632
- if (settingsModal) {
633
- closeModal(settingsModal);
634
- }
1012
+ closeModal(permissionsModalRef.current);
1013
+ closeModal(infoModalRef.current);
1014
+ closeModal(settingsModalRef.current);
1015
+ closeModal(scheduleModalRef.current);
635
1016
  if (languageModal.current) {
636
1017
  closeModal(languageModal.current);
637
1018
  }
638
1019
  }
639
1020
  },
640
1021
  loadMoreClick: async (e) => {
1022
+ var _a;
641
1023
  const loadMoreFile = e.detail;
642
- const fileComponent = document.getElementById('integration-files');
1024
+ const fileComponent = (_a = appComponent.current) === null || _a === void 0 ? void 0 : _a.querySelector('#integration-files');
1025
+ if (!fileComponent) {
1026
+ return;
1027
+ }
643
1028
  await fileComponent.setLoadMoreLoading(loadMoreFile.id, true);
644
1029
  getIntegrationData({ parentId: e.detail.parent_id, paginationData: e.detail.pagination }).finally(async () => {
645
1030
  await fileComponent.setLoadMoreLoading(loadMoreFile.id, false);
@@ -682,16 +1067,39 @@
682
1067
  if (checkSubscription) {
683
1068
  getSubscriptionInfo();
684
1069
  }
685
- if (notice) {
686
- const noticeEl = document.getElementById('notice');
687
- checkAlert(noticeEl, 'notice');
688
- }
1070
+ setIsNoticeVisible(Boolean(notice) && localStorage.getItem('revised_notice') !== '1');
689
1071
  return () => {
690
1072
  for (const [event, handler] of Object.entries(listeners)) {
691
1073
  document.body.removeEventListener(event, handler);
692
1074
  }
693
1075
  };
694
1076
  }, []);
1077
+ reactExports.useEffect(() => {
1078
+ var _a;
1079
+ if (!languageModalState || !((_a = languageSelectRef.current) === null || _a === void 0 ? void 0 : _a.setValue)) {
1080
+ return;
1081
+ }
1082
+ languageSelectRef.current.setValue(languageModalState.languages.map((language) => language.id));
1083
+ }, [languageModalState]);
1084
+ reactExports.useEffect(() => {
1085
+ if (usersSelectRef.current) {
1086
+ usersSelectRef.current.value = permissionsSelectedValue;
1087
+ }
1088
+ }, [permissionUserOptions, permissionsSelectedValue]);
1089
+ reactExports.useEffect(() => {
1090
+ syncScheduleCheckbox(selectedFilesCheckboxRef.current, {
1091
+ checked: scheduleModalState.selectedFiles,
1092
+ });
1093
+ syncScheduleCheckbox(allFolderFilesCheckboxRef.current, {
1094
+ checked: scheduleModalState.allFolderFiles,
1095
+ hidden: !scheduleModalState.showAllFolderFiles,
1096
+ });
1097
+ syncScheduleCheckbox(newFilesCheckboxRef.current, {
1098
+ checked: scheduleModalState.newFiles,
1099
+ hidden: !scheduleModalState.showNewFiles,
1100
+ clearSelection: scheduleModalState.newFilesClearSelection,
1101
+ });
1102
+ }, [scheduleModalState]);
695
1103
  // Expose centralized API to global scope for main.js compatibility
696
1104
  reactExports.useEffect(() => {
697
1105
  window.app = {
@@ -1234,7 +1642,7 @@
1234
1642
  });
1235
1643
  }
1236
1644
  function pushJobs(jobs) {
1237
- const el = document.querySelector('crowdin-async-progress');
1645
+ const el = asyncProgressRef.current;
1238
1646
  if (el && el.pushJobs) {
1239
1647
  el.pushJobs(jobs);
1240
1648
  jobs.forEach((job) => (asyncJobs.current[job.id] = job));
@@ -1348,33 +1756,32 @@
1348
1756
  .catch((e) => catchRejection(e, `Can't sync translations to ${name}`));
1349
1757
  }
1350
1758
  function openLanguageModal() {
1759
+ setLanguageModalState((state) => {
1760
+ var _a, _b;
1761
+ return ({
1762
+ languages: (_b = (_a = state === null || state === void 0 ? void 0 : state.languages) !== null && _a !== void 0 ? _a : project.current.targetLanguages) !== null && _b !== void 0 ? _b : [],
1763
+ action: 'syncToCrowdin',
1764
+ });
1765
+ });
1351
1766
  openModal(languageModal.current);
1352
1767
  }
1353
1768
  function openLanguageModalForCrowdinFiles() {
1354
- const languages = project.current.targetLanguages || [];
1355
- const buttonHtml = `
1356
- <crowdin-button id="update-crowdin-target-languages" outlined">
1357
- Update Target Languages
1358
- </crowdin-button>
1359
- `;
1360
- setTimeout(() => {
1361
- const btn = document.querySelector('#update-crowdin-target-languages');
1362
- if (btn) {
1363
- btn.addEventListener('click', () => updateCrowdinFilesTargetLanguages());
1364
- }
1365
- }, 0);
1366
- setLanguagesForTranslation(languages, buttonHtml);
1769
+ setLanguageModalState((state) => {
1770
+ var _a, _b;
1771
+ return ({
1772
+ languages: (_b = (_a = state === null || state === void 0 ? void 0 : state.languages) !== null && _a !== void 0 ? _a : project.current.targetLanguages) !== null && _b !== void 0 ? _b : [],
1773
+ action: 'updateCrowdinTargetLanguages',
1774
+ });
1775
+ });
1367
1776
  openModal(languageModal.current);
1368
1777
  }
1369
1778
  async function uploadFilesToCrowdinWithExcludedLanguages() {
1370
- const languageSelect = document.querySelector('#language-select');
1371
- const selectedLanguages = await languageSelect.getValue();
1779
+ const selectedLanguages = await languageSelectRef.current.getValue();
1372
1780
  closeModal(languageModal.current);
1373
1781
  uploadFilesToCrowdin({ detail: fileToSync.current }, selectedLanguages);
1374
1782
  }
1375
1783
  async function updateCrowdinFilesTargetLanguages() {
1376
- const languageSelect = document.querySelector('#language-select');
1377
- const selectedLanguages = await languageSelect.getValue();
1784
+ const selectedLanguages = await languageSelectRef.current.getValue();
1378
1785
  closeModal(languageModal.current);
1379
1786
  const fileIds = Object.keys(crowdinFilesToUpdateTargetLanguages.current).map((id) => parseInt(id, 10));
1380
1787
  if (fileIds.length === 0) {
@@ -1397,54 +1804,13 @@
1397
1804
  })
1398
1805
  .catch((e) => catchRejection(e, "Can't update files target languages"));
1399
1806
  }
1400
- async function setLanguagesForTranslation(languages, buttonHtml) {
1401
- const defaultButtonHtml = `
1402
- <crowdin-button id="upload-exclude-languages" outlined">
1403
- <div class="integration-icon-button">
1404
- <span>Sync to</span>
1405
- <crowdin-logo is-icon/>
1406
- </div>
1407
- </crowdin-button>
1408
- `;
1409
- setTimeout(() => {
1410
- const btn = document.querySelector('#upload-exclude-languages');
1411
- if (btn) {
1412
- btn.addEventListener('click', () => uploadFilesToCrowdinWithExcludedLanguages());
1413
- }
1414
- }, 0);
1415
- const languageIds = languages.map((language) => language.id);
1416
- if (languageModal.current) {
1417
- let modalContent = `<div>
1418
- <crowdin-select
1419
- is-multi
1420
- is-searchable
1421
- is-position-fixed
1422
- close-on-select="false"
1423
- name="languages"
1424
- id="language-select"
1425
- label="Languages"
1426
- >
1427
- `;
1428
- for (const language of languages) {
1429
- modalContent += `<option value="${language.id}">${language.name}</option>`;
1430
- }
1431
- modalContent += `
1432
- </crowdin-select>
1433
- </div>
1434
- <div slot="footer">
1435
- ${buttonHtml || defaultButtonHtml}
1436
- </div>
1437
- `;
1438
- languageModal.current.innerHTML = modalContent;
1439
- const select = document.querySelector('#language-select');
1440
- await select.setValue(languageIds);
1441
- }
1807
+ function setLanguagesForTranslation(languages, action = 'syncToCrowdin') {
1808
+ setLanguageModalState({ languages, action });
1442
1809
  }
1443
1810
  function hideConfirmUsersBlock() {
1444
- const confirmUsersBlock = document.querySelector('.confirm-users-block');
1445
- confirmUsersBlock.classList.add('hidden');
1446
- const permissionsModal = document.getElementById('permissions-modal');
1447
- permissionsModal.setAttribute('body-overflow-unset', true);
1811
+ var _a;
1812
+ setIsPermissionsConfirmVisible(false);
1813
+ (_a = permissionsModalRef.current) === null || _a === void 0 ? void 0 : _a.setAttribute('body-overflow-unset', true);
1448
1814
  }
1449
1815
  function getUserFullName(user) {
1450
1816
  if (user.full_name) {
@@ -1454,12 +1820,10 @@
1454
1820
  return !!ownerFullName && (user === null || user === void 0 ? void 0 : user.login) !== ownerFullName ? `${ownerFullName} (${user === null || user === void 0 ? void 0 : user.login})` : user === null || user === void 0 ? void 0 : user.login;
1455
1821
  }
1456
1822
  function showPermissionsDialog() {
1457
- const permissions = document.getElementById('permissions-modal');
1458
1823
  hideConfirmUsersBlock();
1459
- openModal(permissions);
1824
+ openModal(permissionsModalRef.current);
1460
1825
  setLoader('#permissions-modal');
1461
- const select = document.getElementById('users');
1462
- select.value = '[]';
1826
+ setPermissionsSelectedValue('[]');
1463
1827
  Promise.all([
1464
1828
  new Promise((resolve) => {
1465
1829
  checkOrigin()
@@ -1481,23 +1845,23 @@
1481
1845
  const availableUsers = users;
1482
1846
  const validUserIds = new Set(availableUsers.map((user) => `${user.id}`));
1483
1847
  const filteredManagers = parsedManagers.filter((id) => validUserIds.has(id));
1484
- select.innerHTML = availableUsers
1485
- .map((user) => `<option value="${user.id}">${sanitizeHTML(getUserFullName(user))}</option>`)
1486
- .join('');
1487
- select.value = JSON.stringify(filteredManagers);
1848
+ setPermissionUserOptions(availableUsers.map((user) => ({
1849
+ id: String(user.id),
1850
+ label: getUserFullName(user),
1851
+ })));
1852
+ setPermissionsSelectedValue(JSON.stringify(filteredManagers));
1488
1853
  })
1489
1854
  .catch((e) => catchRejection(e, "Can't fetch users"))
1490
1855
  .finally(() => unsetLoader('#permissions-modal'));
1491
1856
  }
1492
1857
  function showConfirmUsersBlock() {
1493
- const confirmUsersBlock = document.querySelector('.confirm-users-block');
1494
- confirmUsersBlock.classList.remove('hidden');
1495
- const permissionsModal = document.getElementById('permissions-modal');
1496
- permissionsModal.removeAttribute('body-overflow-unset');
1858
+ var _a;
1859
+ setIsPermissionsConfirmVisible(true);
1860
+ (_a = permissionsModalRef.current) === null || _a === void 0 ? void 0 : _a.removeAttribute('body-overflow-unset');
1497
1861
  }
1498
1862
  function checkUsers() {
1499
1863
  setLoader('#permissions-modal');
1500
- const select = document.getElementById('users');
1864
+ const select = usersSelectRef.current;
1501
1865
  if (select.value === '[]') {
1502
1866
  hideConfirmUsersBlock();
1503
1867
  unsetLoader('#permissions-modal');
@@ -1560,7 +1924,7 @@
1560
1924
  }
1561
1925
  function inviteUsers() {
1562
1926
  setLoader('#permissions-modal');
1563
- const select = document.getElementById('users');
1927
+ const select = usersSelectRef.current;
1564
1928
  const users = JSON.parse(select.value);
1565
1929
  const user_ids = users.filter((id) => parseInt(id));
1566
1930
  const emails = users.filter((id) => !parseInt(id));
@@ -1580,14 +1944,13 @@
1580
1944
  }))
1581
1945
  .then(checkResponse)
1582
1946
  .then((res) => {
1583
- const permissions = document.getElementById('permissions-modal');
1584
1947
  if (!res.success) {
1585
1948
  catchRejection(res, (res === null || res === void 0 ? void 0 : res.message) || "Can't invite users");
1586
1949
  return;
1587
1950
  }
1588
1951
  showToast('Users successfully updated');
1589
1952
  hideConfirmUsersBlock();
1590
- closeModal(permissions);
1953
+ closeModal(permissionsModalRef.current);
1591
1954
  })
1592
1955
  .catch((e) => catchRejection(e, (e === null || e === void 0 ? void 0 : e.error) || "Can't invite users"))
1593
1956
  .finally(() => unsetLoader('#permissions-modal'));
@@ -1595,107 +1958,58 @@
1595
1958
  }
1596
1959
  function prepareUsersConfirmBlock(usersData) {
1597
1960
  showConfirmUsersBlock();
1598
- const organizationInvite = document.querySelector('.organization-invite');
1599
- const projectInvite = document.querySelector('.project-invite');
1600
- const applicationCredentialsInvite = document.querySelector('.application-credentials-invite');
1601
- const grantedElement = '<crowdin-p>&horbar;</crowdin-p>';
1602
- const willGrantedElement = '<span class="badge badge-will-be-granted">Will Be Granted</span>';
1603
- const notAvailableElement = '<span class="badge badge-not-available">Action Required</span>';
1604
- // only in enterprise
1605
- if (organizationInvite) {
1606
- const organizationWillGrantElement = '<span class="badge badge-will-be-granted">Will Be Registered</span>';
1607
- processUsersWhoWillBeInvitedToOrganization(organizationInvite, usersData, organizationWillGrantElement, grantedElement, notAvailableElement);
1608
- }
1609
- processUsersWhoWillBeInvited(projectInvite, usersData.newProjectManagers, willGrantedElement, grantedElement);
1610
- processUsersWhoWillBeInvited(applicationCredentialsInvite, usersData.newApplicationManagers, willGrantedElement, grantedElement);
1611
- processUsersWhoWillBeInvitedApplicationSettings(usersData, willGrantedElement, grantedElement, notAvailableElement);
1612
- }
1613
- function processUsersWhoWillBeInvitedToOrganization(element, usersData, willGrantedElement, alreadyGrantedMessage, notAvailableElement) {
1614
- const tooltip = element.querySelector('.status');
1615
- const description = element.querySelector('.permission-description');
1616
- const userList = element.querySelector('.affected-users');
1617
- description.classList.remove('text-warning');
1618
- description.innerText = '';
1619
- const users = usersData.newUserEmails;
1620
- if (users.length) {
1621
- if (usersData.inviteRestricted) {
1622
- description.classList.add('text-warning');
1623
- description.innerText = 'New user invitations are restricted to administrators.';
1624
- tooltip.innerHTML = notAvailableElement;
1625
- }
1626
- else {
1627
- tooltip.innerHTML = willGrantedElement;
1628
- }
1629
- let affectedUsers = '<ul>';
1630
- for (const user of users) {
1631
- affectedUsers += `<li><crowdin-p>${sanitizeHTML(user.name)}</crowdin-p></li>`;
1632
- }
1633
- affectedUsers += '</ul>';
1634
- userList.innerHTML = affectedUsers;
1635
- }
1636
- else {
1637
- tooltip.innerHTML = alreadyGrantedMessage;
1638
- userList.innerHTML = alreadyGrantedMessage;
1639
- }
1640
- }
1641
- function processUsersWhoWillBeInvited(element, users, grantMessage, alreadyGrantedMessage) {
1642
- const tooltip = element.querySelector('.status');
1643
- const userList = element.querySelector('.affected-users');
1644
- if (users.length) {
1645
- tooltip.innerHTML = grantMessage;
1646
- let affectedUsers = '<ul>';
1647
- for (const user of users) {
1648
- affectedUsers += `<li><crowdin-p>${sanitizeHTML(user.name)}</crowdin-p></li>`;
1649
- }
1650
- affectedUsers += '</ul>';
1651
- userList.innerHTML = affectedUsers;
1652
- }
1653
- else {
1654
- tooltip.innerHTML = alreadyGrantedMessage;
1655
- userList.innerHTML = alreadyGrantedMessage;
1656
- }
1657
- }
1658
- function processUsersWhoWillBeInvitedApplicationSettings(usersData, willGrantedElement, grantedElement, notAvailableElement) {
1659
- const applicationSettingsInvite = document.querySelector('.application-settings-invite');
1660
- const tooltip = applicationSettingsInvite.querySelector('.status');
1661
- const description = applicationSettingsInvite.querySelector('.permission-description');
1662
- const userList = applicationSettingsInvite.querySelector('.affected-users');
1663
- let descriptionMessage = 'This can be configured in organization settings (Apps section).';
1664
- description.classList.remove('text-warning');
1665
- description.innerText = descriptionMessage;
1666
- let affectedUsers = '<ul>';
1667
- if (!usersData.newApplicationAccessUsers.length) {
1668
- tooltip.innerHTML = grantedElement;
1669
- userList.innerHTML = grantedElement;
1670
- }
1671
- else {
1672
- if (usersData.isAdmin) {
1673
- tooltip.innerHTML = willGrantedElement;
1674
- for (const user of usersData.newApplicationAccessUsers) {
1675
- affectedUsers += `<li><crowdin-p>${sanitizeHTML(user.name)}</crowdin-p></li>`;
1676
- }
1677
- userList.innerHTML = affectedUsers + '</ul>';
1678
- }
1679
- else {
1680
- descriptionMessage += ' Only organization admins have permission to update this setting.';
1681
- description.classList.add('text-warning');
1682
- description.innerText = descriptionMessage;
1683
- tooltip.innerHTML = notAvailableElement;
1684
- for (const user of usersData.newApplicationAccessUsers) {
1685
- affectedUsers += `<li><crowdin-p>${sanitizeHTML(user.name)}</crowdin-p></li>`;
1961
+ const toNames = (users = []) => users.map((user) => user.name);
1962
+ const applicationSettingsDescription = 'This can be configured in organization settings (Apps section).';
1963
+ const hasApplicationAccessUsers = usersData.newApplicationAccessUsers.length > 0;
1964
+ setPermissionsSummary({
1965
+ ...(hasOrganization
1966
+ ? {
1967
+ organization: {
1968
+ status: usersData.newUserEmails.length
1969
+ ? usersData.inviteRestricted
1970
+ ? 'actionRequired'
1971
+ : 'willBeRegistered'
1972
+ : 'granted',
1973
+ users: toNames(usersData.newUserEmails),
1974
+ description: usersData.inviteRestricted
1975
+ ? 'New user invitations are restricted to administrators.'
1976
+ : '',
1977
+ isWarning: usersData.inviteRestricted,
1978
+ },
1686
1979
  }
1687
- userList.innerHTML = affectedUsers + '</ul>';
1688
- }
1689
- }
1980
+ : {}),
1981
+ project: {
1982
+ status: usersData.newProjectManagers.length ? 'willBeGranted' : 'granted',
1983
+ users: toNames(usersData.newProjectManagers),
1984
+ },
1985
+ applicationSettings: {
1986
+ status: hasApplicationAccessUsers
1987
+ ? usersData.isAdmin
1988
+ ? 'willBeGranted'
1989
+ : 'actionRequired'
1990
+ : 'granted',
1991
+ users: toNames(usersData.newApplicationAccessUsers),
1992
+ description: hasApplicationAccessUsers
1993
+ ? usersData.isAdmin
1994
+ ? applicationSettingsDescription
1995
+ : `${applicationSettingsDescription} Only organization admins have permission to update this setting.`
1996
+ : applicationSettingsDescription,
1997
+ isWarning: hasApplicationAccessUsers && !usersData.isAdmin,
1998
+ },
1999
+ applicationCredentials: {
2000
+ status: usersData.newApplicationManagers.length ? 'willBeGranted' : 'granted',
2001
+ users: toNames(usersData.newApplicationManagers),
2002
+ },
2003
+ });
1690
2004
  }
1691
2005
  function setLoader(id) {
1692
- const loader = document.querySelector(`${id} .loader`);
1693
- loader.classList.remove('hidden');
2006
+ const loaderKey = id.replace(/^#/, '');
2007
+ setModalLoaders((currentLoaders) => ({ ...currentLoaders, [loaderKey]: true }));
1694
2008
  }
1695
2009
  function unsetLoader(id) {
1696
- const loader = document.querySelector(`${id} .loader`);
2010
+ const loaderKey = id.replace(/^#/, '');
1697
2011
  setTimeout(function () {
1698
- loader.classList.add('hidden');
2012
+ setModalLoaders((currentLoaders) => ({ ...currentLoaders, [loaderKey]: false }));
1699
2013
  }, 500);
1700
2014
  }
1701
2015
  function triggerEvent(el, type) {
@@ -1703,9 +2017,56 @@
1703
2017
  e.initEvent(type, false, true);
1704
2018
  el.dispatchEvent(e);
1705
2019
  }
2020
+ function parseCrowdinSelectValue(value) {
2021
+ if (Array.isArray(value)) {
2022
+ return value;
2023
+ }
2024
+ if (value === undefined || value === null || value === '') {
2025
+ return [];
2026
+ }
2027
+ try {
2028
+ const parsedValue = JSON.parse(value);
2029
+ return Array.isArray(parsedValue) ? parsedValue : [parsedValue];
2030
+ }
2031
+ catch (e) {
2032
+ return [value];
2033
+ }
2034
+ }
2035
+ function registerSettingsField(key) {
2036
+ return (element) => {
2037
+ if (!key) {
2038
+ return;
2039
+ }
2040
+ if (element) {
2041
+ settingsFieldRefs.current[key] = element;
2042
+ }
2043
+ else {
2044
+ delete settingsFieldRefs.current[key];
2045
+ }
2046
+ };
2047
+ }
2048
+ function syncScheduleCheckbox(checkbox, { checked, hidden = false, clearSelection = false, }) {
2049
+ if (!checkbox) {
2050
+ return;
2051
+ }
2052
+ checkbox.checked = checked;
2053
+ checkbox.value = checked;
2054
+ if (hidden) {
2055
+ checkbox.setAttribute('hidden', '');
2056
+ }
2057
+ else {
2058
+ checkbox.removeAttribute('hidden');
2059
+ }
2060
+ if (clearSelection) {
2061
+ checkbox.setAttribute('clear-selection', '');
2062
+ }
2063
+ else {
2064
+ checkbox.removeAttribute('clear-selection');
2065
+ }
2066
+ }
1706
2067
  function fillSettingsForm() {
1707
2068
  Object.entries(config.current).forEach(([key, value]) => {
1708
- const el = document.getElementById(`${key}-settings`);
2069
+ const el = settingsFieldRefs.current[key];
1709
2070
  if (el && (value || el.tagName.toLowerCase() === 'crowdin-checkbox')) {
1710
2071
  if (el.tagName.toLowerCase() === 'crowdin-select') {
1711
2072
  if (el.hasAttribute('is-multi')) {
@@ -1728,45 +2089,37 @@
1728
2089
  triggerEvent(el, 'change');
1729
2090
  }
1730
2091
  });
1731
- // Reinitialize dependencies after form is filled
1732
- setTimeout(() => {
1733
- if (window.initializeDependencies) {
1734
- window.initializeDependencies();
1735
- }
1736
- }, 100);
2092
+ setTimeout(refreshDependencies, 100);
1737
2093
  }
1738
2094
  function saveSettings() {
1739
- const settingsSaveBtn = document.getElementById('settings-save-btn');
1740
2095
  setLoader('#settings-modal');
1741
- const settingsElements = Array.from(document.querySelectorAll('#modal-content crowdin-tabs > div'));
1742
- const tags = ['crowdin-checkbox', 'crowdin-select', 'crowdin-input', 'crowdin-textarea'];
1743
2096
  const configReq = {};
1744
- settingsElements.forEach((tab) => {
1745
- const formElements = Array.from(tab.querySelectorAll('.crowdin-form > *'));
1746
- formElements
1747
- .filter((e) => tags.includes(e.tagName.toLowerCase()))
1748
- .forEach((e) => {
1749
- const key = e.getAttribute('_key');
1750
- let value;
1751
- if (e.tagName.toLowerCase() === 'crowdin-select') {
1752
- value = JSON.parse(e.value);
1753
- if (!e.hasAttribute('is-multi')) {
1754
- value = value.length > 0 ? value[0] : undefined;
1755
- }
2097
+ configurationFields === null || configurationFields === void 0 ? void 0 : configurationFields.forEach((tab) => {
2098
+ tab.fields.forEach((field) => {
2099
+ if (!field.key) {
2100
+ return;
2101
+ }
2102
+ const el = settingsFieldRefs.current[field.key];
2103
+ if (!el) {
2104
+ return;
1756
2105
  }
1757
- else if (e.tagName.toLowerCase() === 'crowdin-checkbox') {
1758
- value = !!e.checked;
2106
+ const tagName = el.tagName.toLowerCase();
2107
+ if (tagName === 'crowdin-select') {
2108
+ const value = parseCrowdinSelectValue(el.value);
2109
+ configReq[field.key] = el.hasAttribute('is-multi') ? value : value[0];
2110
+ return;
1759
2111
  }
1760
- else {
1761
- value = e.value;
2112
+ if (tagName === 'crowdin-checkbox') {
2113
+ configReq[field.key] = !!el.checked;
2114
+ return;
1762
2115
  }
1763
- configReq[key] = value;
2116
+ configReq[field.key] = el.value;
1764
2117
  });
1765
2118
  });
1766
2119
  let isValidationError = false;
1767
2120
  let isSettingsSaveJobPending = false;
1768
2121
  let isSettingsSaveFailed = false;
1769
- settingsSaveBtn.setAttribute('disabled', true);
2122
+ setIsSettingsSaveDisabled(true);
1770
2123
  checkOrigin()
1771
2124
  .then((restParams) => fetch('api/settings' + restParams, {
1772
2125
  method: 'POST',
@@ -1791,10 +2144,9 @@
1791
2144
  },
1792
2145
  onFinally: () => {
1793
2146
  unsetLoader('#settings-modal');
1794
- settingsSaveBtn.removeAttribute('disabled');
2147
+ setIsSettingsSaveDisabled(false);
1795
2148
  if (!isValidationError && !isSettingsSaveFailed) {
1796
- const settingsModal = document.getElementById('settings-modal');
1797
- closeModal(settingsModal);
2149
+ closeModal(settingsModalRef.current);
1798
2150
  if (reloadOnConfigSave) {
1799
2151
  getIntegrationData({ hardReload: true });
1800
2152
  getCrowdinData();
@@ -1813,7 +2165,7 @@
1813
2165
  if ((e === null || e === void 0 ? void 0 : e.error) && ((_a = e === null || e === void 0 ? void 0 : e.error) === null || _a === void 0 ? void 0 : _a.type) === 'validation_error') {
1814
2166
  Object.keys((_b = e === null || e === void 0 ? void 0 : e.error) === null || _b === void 0 ? void 0 : _b.details).forEach((key) => {
1815
2167
  var _a;
1816
- const el = document.getElementById(`${key}-settings`);
2168
+ const el = settingsFieldRefs.current[key];
1817
2169
  if (el) {
1818
2170
  el.setAttribute('error', 'true');
1819
2171
  el.setAttribute('error-text', (_a = e === null || e === void 0 ? void 0 : e.error) === null || _a === void 0 ? void 0 : _a.details[key]);
@@ -1821,7 +2173,7 @@
1821
2173
  });
1822
2174
  isValidationError = true;
1823
2175
  showToast(((_d = (_c = e === null || e === void 0 ? void 0 : e.error) === null || _c === void 0 ? void 0 : _c.details) === null || _d === void 0 ? void 0 : _d.message) || "Can't save settings");
1824
- settingsSaveBtn.removeAttribute('disabled');
2176
+ setIsSettingsSaveDisabled(false);
1825
2177
  return;
1826
2178
  }
1827
2179
  catchRejection(e, "Can't save settings");
@@ -1831,10 +2183,9 @@
1831
2183
  return;
1832
2184
  }
1833
2185
  unsetLoader('#settings-modal');
1834
- settingsSaveBtn.removeAttribute('disabled');
2186
+ setIsSettingsSaveDisabled(false);
1835
2187
  if (!isValidationError) {
1836
- const settingsModal = document.getElementById('settings-modal');
1837
- closeModal(settingsModal);
2188
+ closeModal(settingsModalRef.current);
1838
2189
  if (reloadOnConfigSave) {
1839
2190
  getIntegrationData({ hardReload: true });
1840
2191
  getCrowdinData();
@@ -1855,11 +2206,7 @@
1855
2206
  : [];
1856
2207
  }
1857
2208
  async function saveScheduleSync() {
1858
- const scheduleModal = document.getElementById('confirm-schedule-modal');
1859
- const newFile = scheduleModal.querySelector('#new-files').checked || false;
1860
- const selectedFiles = scheduleModal.querySelector('#selected-files').checked || false;
1861
- const allFolderFiles = scheduleModal.querySelector('#all-folder-files').checked || false;
1862
- const type = scheduleModal.getAttribute('data-type');
2209
+ const { type, newFiles: newFile, selectedFiles, allFolderFiles } = scheduleModalState;
1863
2210
  if (type === 'crowdin') {
1864
2211
  const crowdinFiles = await appComponent.current.getCrowdinFilesData();
1865
2212
  const syncedFileIds = Object.keys(syncData.current);
@@ -1902,19 +2249,15 @@
1902
2249
  }
1903
2250
  }
1904
2251
  }
1905
- closeModal(scheduleModal);
2252
+ closeModal(scheduleModalRef.current);
1906
2253
  }
1907
2254
  async function openScheduleModal(type, options = {}) {
1908
- var _a, _b;
1909
- const scheduleModal = document.getElementById('confirm-schedule-modal');
2255
+ var _a, _b, _c, _d;
1910
2256
  const { showAllFolderFiles = false, showNewFiles = true } = options;
1911
- const newFile = scheduleModal.querySelector('#new-files');
1912
- const selectedFiles = scheduleModal.querySelector('#selected-files');
1913
- const allFolderFiles = scheduleModal.querySelector('#all-folder-files');
1914
2257
  let newFileStatus = 'unChecked';
1915
- const integrationSyncFolders = ((await ((_a = document.querySelector('crowdin-simple-integration')) === null || _a === void 0 ? void 0 : _a.getIntegrationScheduleSync(true))) ||
1916
- []).filter((elements) => elements.node_type === '0');
1917
- const selectedIntegrationFolders = ((await ((_b = document.getElementById('integration-files')) === null || _b === void 0 ? void 0 : _b.getSelected(true))) || []).filter((elements) => elements.node_type === '0');
2258
+ 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 === '0');
2259
+ const integrationFiles = (_c = appComponent.current) === null || _c === void 0 ? void 0 : _c.querySelector('#integration-files');
2260
+ 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 === '0');
1918
2261
  for (let i = 0; i < selectedIntegrationFolders.length; i++) {
1919
2262
  const selectedElement = selectedIntegrationFolders[i];
1920
2263
  const found = integrationSyncFolders.some((integrationElement) => integrationElement.id === selectedElement.id);
@@ -1929,56 +2272,33 @@
1929
2272
  newFileStatus = 'unChecked';
1930
2273
  }
1931
2274
  }
1932
- if (showNewFiles) {
1933
- newFile.removeAttribute('hidden');
1934
- if (newFileStatus === 'checked') {
1935
- newFile[newFileStatus] = true;
1936
- newFile.value = true;
1937
- newFile.removeAttribute('clear-selection');
1938
- }
1939
- else if (newFileStatus === 'clear-selection') {
1940
- newFile.checked = false;
1941
- newFile.value = false;
1942
- newFile.setAttribute(newFileStatus, '');
1943
- }
1944
- else {
1945
- newFile.checked = false;
1946
- newFile.value = false;
1947
- newFile.removeAttribute('clear-selection');
1948
- }
1949
- }
1950
- else {
1951
- newFile.setAttribute('hidden', '');
1952
- newFile.checked = false;
1953
- }
1954
- if (showAllFolderFiles) {
1955
- allFolderFiles.removeAttribute('hidden');
1956
- allFolderFiles.checked = false;
1957
- allFolderFiles.value = false;
1958
- }
1959
- else {
1960
- allFolderFiles.setAttribute('hidden', '');
1961
- allFolderFiles.checked = false;
1962
- }
1963
- selectedFiles.checked = true;
1964
- selectedFiles.value = true;
1965
- scheduleModal.querySelector('#save-schedule-sync').setAttribute('disabled', false);
1966
- scheduleModal.setAttribute('data-type', type);
1967
- openModal(scheduleModal);
2275
+ setScheduleModalState({
2276
+ type,
2277
+ showAllFolderFiles,
2278
+ showNewFiles,
2279
+ newFiles: showNewFiles && newFileStatus === 'checked',
2280
+ newFilesClearSelection: showNewFiles && newFileStatus === 'clear-selection',
2281
+ selectedFiles: true,
2282
+ allFolderFiles: false,
2283
+ });
2284
+ setIsScheduleSaveDisabled(false);
2285
+ openModal(scheduleModalRef.current);
1968
2286
  }
1969
2287
  function onChangeAutoSynchronizationOptions() {
1970
- const newFiles = document.getElementById('new-files');
1971
- newFiles.removeAttribute('clear-selection');
1972
- const newFilesStatus = newFiles.checked || false;
1973
- const selectedFiles = document.getElementById('selected-files').checked || false;
1974
- const allFolderFiles = document.getElementById('all-folder-files').checked || false;
1975
- const buttonSaveScheduleSync = document.getElementById('save-schedule-sync');
1976
- if (newFilesStatus || selectedFiles || allFolderFiles) {
1977
- buttonSaveScheduleSync.removeAttribute('disabled');
1978
- }
1979
- else {
1980
- buttonSaveScheduleSync.setAttribute('disabled', true);
1981
- }
2288
+ var _a, _b, _c;
2289
+ const nextState = {
2290
+ newFiles: scheduleModalState.showNewFiles ? !!((_a = newFilesCheckboxRef.current) === null || _a === void 0 ? void 0 : _a.checked) : false,
2291
+ selectedFiles: !!((_b = selectedFilesCheckboxRef.current) === null || _b === void 0 ? void 0 : _b.checked),
2292
+ allFolderFiles: scheduleModalState.showAllFolderFiles
2293
+ ? !!((_c = allFolderFilesCheckboxRef.current) === null || _c === void 0 ? void 0 : _c.checked)
2294
+ : false,
2295
+ };
2296
+ setScheduleModalState((currentState) => ({
2297
+ ...currentState,
2298
+ ...nextState,
2299
+ newFilesClearSelection: false,
2300
+ }));
2301
+ setIsScheduleSaveDisabled(!nextState.newFiles && !nextState.selectedFiles && !nextState.allFolderFiles);
1982
2302
  }
1983
2303
  async function hasFolder(selectedFiles) {
1984
2304
  let isFolder;
@@ -2122,46 +2442,31 @@
2122
2442
  .catch((e) => catchRejection(e, "Can't save schedule sync settings"));
2123
2443
  }
2124
2444
  function getSubscriptionInfo() {
2125
- const subscriptionInfo = document.getElementById('subscription-info');
2126
- const subscriptionInfoText = subscriptionInfo.getElementsByTagName('p')[0];
2127
2445
  checkOrigin()
2128
2446
  .then((restParams) => fetch('api/subscription-info' + restParams))
2129
2447
  .then(checkResponse)
2130
2448
  .then((res) => {
2131
2449
  if (res.showInfo) {
2132
2450
  subscriptionLink.current = res.subscribeLink;
2133
- subscriptionInfoText.textContent = `Your trial expires in ${res.daysLeft} days.`;
2134
- subscriptionInfo.style.display = 'block';
2451
+ setSubscriptionInfo({ daysLeft: res.daysLeft, subscribeLink: res.subscribeLink });
2135
2452
  }
2136
2453
  });
2137
2454
  }
2138
- function checkAlert(alert, suffix) {
2139
- const name = suffix ;
2140
- const revised = localStorage.getItem(`revised_${name}`) === '1';
2141
- if (!revised) {
2142
- alert.style.display = 'block';
2143
- }
2144
- }
2145
- function closeAlert(el, suffix) {
2146
- const name = suffix ;
2147
- const alert = el.closest('crowdin-alert');
2148
- alert.style.display = 'none';
2149
- localStorage.setItem(`revised_${name}`, 1);
2455
+ function closeAlert(suffix) {
2456
+ const alertName = suffix ;
2457
+ setIsNoticeVisible(false);
2458
+ localStorage.setItem(`revised_${alertName}`, '1');
2150
2459
  }
2151
2460
  function showErrorLogs() {
2152
- document.getElementById('show-error-logs-btn').classList.add('hidden');
2153
- document.getElementById('show-integration-btn').classList.remove('hidden');
2154
- appComponent.current.classList.add('hidden');
2155
- document.getElementById('user-errors').classList.remove('hidden');
2461
+ setIsErrorLogsVisible(true);
2156
2462
  checkOrigin()
2157
2463
  .then((restParams) => fetch('api/user-errors' + restParams))
2158
2464
  .then(checkResponse)
2159
2465
  .then((res) => {
2160
- const table = document.getElementById('user-errors-table');
2466
+ const table = userErrorsTableRef.current;
2161
2467
  const clickRow = (field, index, item) => {
2162
- const modal = document.getElementById('user-error-detail');
2163
- openModal(modal);
2164
- modal.innerHTML = getUserErrorDetail(item);
2468
+ setSelectedUserError(item);
2469
+ openModal(userErrorDetailModalRef.current);
2165
2470
  };
2166
2471
  const formatDate = (field, index, item) => {
2167
2472
  return item.formattedDate;
@@ -2197,10 +2502,7 @@
2197
2502
  .catch((e) => catchRejection(e, "Can't fetch error logs"));
2198
2503
  }
2199
2504
  function showIntegration() {
2200
- document.getElementById('show-error-logs-btn').classList.remove('hidden');
2201
- document.getElementById('show-integration-btn').classList.add('hidden');
2202
- appComponent.current.classList.remove('hidden');
2203
- document.getElementById('user-errors').classList.add('hidden');
2505
+ setIsErrorLogsVisible(false);
2204
2506
  }
2205
2507
  function isJSON(string) {
2206
2508
  try {
@@ -2213,79 +2515,129 @@
2213
2515
  }
2214
2516
  function getUserErrorDetail(error) {
2215
2517
  const data = JSON.parse(error.data);
2216
- let html = '<div class="error-detail-table"><table>';
2217
- html += `<tr><td>Action</td><td>${sanitizeHTML(error.action)}</td></tr>`;
2218
- if (isJSON(error.message)) {
2219
- html += `<tr><td>Message</td><td><pre>${sanitizeHTML(error.message)}<pre></td></tr>`;
2220
- }
2221
- else {
2222
- html += `<tr><td>Message</td><td>${sanitizeHTML(error.message)}</td></tr>`;
2223
- }
2224
- html += `<tr><td>Date/time</td><td>${sanitizeHTML(error.formattedDate)}</td></tr>`;
2518
+ const preClassName = 'block rounded bg-[#eceff1] p-4 text-[87.5%] text-[#212529]';
2519
+ const rows = [
2520
+ { label: 'Action', value: error.action },
2521
+ {
2522
+ label: 'Message',
2523
+ value: isJSON(error.message) ? jsxRuntimeExports.jsx("pre", { className: preClassName, children: error.message }) : error.message,
2524
+ },
2525
+ { label: 'Date/time', value: error.formattedDate },
2526
+ ];
2225
2527
  if (data.requestParams) {
2226
- html += `<tr><td>Method</td><td>${sanitizeHTML(data.requestParams.method)}</td></tr>`;
2528
+ rows.push({ label: 'Method', value: data.requestParams.method });
2227
2529
  }
2228
2530
  if (data.responseData) {
2229
- html += `<tr><td>Response Data</td><td><pre>${sanitizeHTML(JSON.stringify(data.responseData, null, 2))}</pre></td></tr>`;
2531
+ rows.push({
2532
+ label: 'Response Data',
2533
+ value: jsxRuntimeExports.jsx("pre", { className: preClassName, children: JSON.stringify(data.responseData, null, 2) }),
2534
+ });
2230
2535
  }
2231
2536
  if (data.appData) {
2232
2537
  if (Array.isArray(data.appData)) {
2233
- html += `<tr><td>App Data</td><td><pre>${sanitizeHTML(JSON.stringify(data.appData, null, 2))}</pre></td></tr>`;
2538
+ rows.push({
2539
+ label: 'App Data',
2540
+ value: jsxRuntimeExports.jsx("pre", { className: preClassName, children: JSON.stringify(data.appData, null, 2) }),
2541
+ });
2234
2542
  }
2235
2543
  else if (typeof data.appData === 'object') {
2236
2544
  for (const key in data.appData) {
2237
- html += `<tr><td>${sanitizeHTML(key.charAt(0).toUpperCase() + key.slice(1))}</td><td><pre>${sanitizeHTML(JSON.stringify(data.appData[key], null, 2))}</pre></td></tr>`;
2545
+ rows.push({
2546
+ label: key.charAt(0).toUpperCase() + key.slice(1),
2547
+ value: jsxRuntimeExports.jsx("pre", { className: preClassName, children: JSON.stringify(data.appData[key], null, 2) }),
2548
+ });
2238
2549
  }
2239
2550
  }
2240
2551
  else {
2241
- html += `<tr><td>App Data</td><td>${sanitizeHTML(data.appData)}</td></tr>`;
2552
+ rows.push({ label: 'App Data', value: data.appData });
2242
2553
  }
2243
2554
  }
2244
- html += '</table></div>';
2245
- return html;
2555
+ return (jsxRuntimeExports.jsx("div", { className: "-m-6 h-auto max-h-[579px] overflow-auto", children: jsxRuntimeExports.jsx("table", { className: "w-full border-separate border-spacing-0", children: jsxRuntimeExports.jsx("tbody", { children: rows.map((row) => (jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsx("td", { className: "min-w-[200px] p-2 px-6 align-top font-medium", children: row.label }), jsxRuntimeExports.jsx("td", { className: "break-all bg-[var(--crowdin-primary-blue-gray,#f6f6f6)] p-2 px-6 text-[var(--crowdin-body-color,rgba(38,50,56,0.87))]", children: row.value })] }, row.label))) }) }) }));
2556
+ }
2557
+ function renderPermissionStatus(status) {
2558
+ switch (status) {
2559
+ case 'willBeGranted':
2560
+ return (jsxRuntimeExports.jsx("span", { className: "inline-block cursor-default rounded-[15px] bg-[var(--crowdin-info)] px-3 py-1 text-center text-xs font-medium text-[var(--crowdin-white)]", children: "Will Be Granted" }));
2561
+ case 'willBeRegistered':
2562
+ return (jsxRuntimeExports.jsx("span", { className: "inline-block cursor-default rounded-[15px] bg-[var(--crowdin-info)] px-3 py-1 text-center text-xs font-medium text-[var(--crowdin-white)]", children: "Will Be Registered" }));
2563
+ case 'actionRequired':
2564
+ return (jsxRuntimeExports.jsx("span", { className: "inline-block cursor-default rounded-[15px] bg-[var(--crowdin-warning-bg)] px-3 py-1 text-center text-xs font-medium text-[var(--crowdin-warning)]", children: "Action Required" }));
2565
+ case 'granted':
2566
+ default:
2567
+ return jsxRuntimeExports.jsx("crowdin-p", { children: EMPTY_PERMISSION_VALUE });
2568
+ }
2246
2569
  }
2247
- function sanitizeHTML(str) {
2248
- const tempDiv = document.createElement('div');
2249
- tempDiv.textContent = str;
2250
- return tempDiv.innerHTML;
2570
+ function renderPermissionUsers(row) {
2571
+ if (!row || row.users.length === 0) {
2572
+ return row ? renderPermissionStatus(row.status) : null;
2573
+ }
2574
+ return (jsxRuntimeExports.jsx("ul", { className: "m-0 list-none p-0", children: row.users.map((user) => (jsxRuntimeExports.jsx("li", { className: "mb-1 text-sm last:mb-0", children: jsxRuntimeExports.jsx("crowdin-p", { children: user }) }, user))) }));
2575
+ }
2576
+ function renderPermissionRowDescription(row) {
2577
+ if (!(row === null || row === void 0 ? void 0 : row.description)) {
2578
+ return null;
2579
+ }
2580
+ return (jsxRuntimeExports.jsx("div", { className: row.isWarning
2581
+ ? 'mt-1 text-xs text-[var(--crowdin-warning)]'
2582
+ : 'mt-1 text-xs text-[var(--crowdin-text-muted)]', children: row.description }));
2251
2583
  }
2252
2584
  function openModal(modal) {
2585
+ if (!modal) {
2586
+ return;
2587
+ }
2253
2588
  modal.style.display = 'block';
2254
2589
  modal.open();
2255
2590
  }
2256
2591
  function closeModal(modal) {
2592
+ if (!modal) {
2593
+ return;
2594
+ }
2257
2595
  modal.style.display = 'none';
2258
2596
  modal.close();
2259
2597
  }
2260
- function settingsFieldChange(el) {
2261
- el.removeAttribute('error');
2262
- el.removeAttribute('error-text');
2598
+ function settingsFieldChange(eventOrElement) {
2599
+ var _a, _b;
2600
+ const el = (eventOrElement === null || eventOrElement === void 0 ? void 0 : eventOrElement.currentTarget) || (eventOrElement === null || eventOrElement === void 0 ? void 0 : eventOrElement.target) || eventOrElement;
2601
+ (_a = el === null || el === void 0 ? void 0 : el.removeAttribute) === null || _a === void 0 ? void 0 : _a.call(el, 'error');
2602
+ (_b = el === null || el === void 0 ? void 0 : el.removeAttribute) === null || _b === void 0 ? void 0 : _b.call(el, 'error-text');
2263
2603
  }
2264
2604
  function isFolder(e) {
2265
2605
  return !e.type && (e.nodeType === undefined || e.nodeType === folderType || e.nodeType === branchType);
2266
2606
  }
2267
- return (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("div", { className: "i_w", children: [jsxRuntimeExports.jsxs("div", { className: "top", children: [notice && (jsxRuntimeExports.jsxs("crowdin-alert", { id: "notice", title: notice.title, ...(!notice.icon ? { 'no-icon': 'true' } : {}), ...(notice.type ? { type: notice.type } : {}), style: { display: 'none', marginBottom: '12px' }, children: [jsxRuntimeExports.jsx("div", { className: "box-center", children: jsxRuntimeExports.jsx("p", { className: "m-0", dangerouslySetInnerHTML: { __html: notice.content } }) }), notice.close && (jsxRuntimeExports.jsx("crowdin-button", { onClick: (e) => closeAlert(e, 'notice'), class: "dismiss-alert", icon: true, children: "close" }))] })), checkSubscription && (jsxRuntimeExports.jsx("crowdin-alert", { id: "subscription-info", "no-icon": "true", type: "warning", style: { display: 'none', marginBottom: '12px' }, children: jsxRuntimeExports.jsxs("div", { className: "box-center", children: [jsxRuntimeExports.jsx("p", { className: "m-0" }), jsxRuntimeExports.jsx("crowdin-button", { class: "ml-1", primary: true, onClick: () => window.open(subscriptionLink.current, '_blank'), children: "Subscribe" })] }) })), jsxRuntimeExports.jsxs("div", { id: "buttons", children: [jsxRuntimeExports.jsx("crowdin-button", { id: "show-integration-btn", class: "hidden", "icon-before": "arrow_back", onClick: () => showIntegration(), children: "Integration" }), jsxRuntimeExports.jsx("crowdin-button", { id: "show-error-logs-btn", "icon-before": "list", onClick: () => showErrorLogs(), children: "Error logs" }), isManager && (jsxRuntimeExports.jsx("crowdin-button", { "icon-before": "link", onClick: () => showPermissionsDialog(), children: "Share" })), infoModal && (jsxRuntimeExports.jsx("crowdin-button", { "icon-before": "info", onClick: () => {
2268
- const infoModalEl = document.getElementById('info-modal');
2269
- openModal(infoModalEl);
2270
- }, children: infoModal.title })), configurationFields && (jsxRuntimeExports.jsx("crowdin-button", { "icon-before": "settings", onClick: () => {
2271
- const settingsModal = document.getElementById('settings-modal');
2272
- openModal(settingsModal);
2607
+ return (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-[1420px] px-6 py-4", children: [jsxRuntimeExports.jsxs("div", { className: "mb-2.5 text-right", children: [notice && (jsxRuntimeExports.jsxs("crowdin-alert", { id: "notice", title: notice.title, ...(!notice.icon ? { 'no-icon': 'true' } : {}), ...(notice.type ? { type: notice.type } : {}), style: { display: isNoticeVisible ? 'block' : 'none', marginBottom: '12px' }, children: [jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center", children: jsxRuntimeExports.jsx("p", { className: "m-0", dangerouslySetInnerHTML: { __html: notice.content } }) }), notice.close && (jsxRuntimeExports.jsx("crowdin-button", { onClick: () => closeAlert('notice'), class: "absolute top-0 right-0", icon: true, children: "close" }))] })), checkSubscription && (jsxRuntimeExports.jsx("crowdin-alert", { id: "subscription-info", "no-icon": "true", type: "warning", style: { display: subscriptionInfo ? 'block' : 'none', marginBottom: '12px' }, children: jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center", children: [jsxRuntimeExports.jsx("p", { className: "m-0", children: subscriptionInfo ? `Your trial expires in ${subscriptionInfo.daysLeft} days.` : '' }), jsxRuntimeExports.jsx("crowdin-button", { class: "ml-2", primary: true, onClick: () => {
2608
+ if (subscriptionInfo === null || subscriptionInfo === void 0 ? void 0 : subscriptionInfo.subscribeLink) {
2609
+ window.open(subscriptionInfo.subscribeLink, '_blank', 'noopener,noreferrer');
2610
+ }
2611
+ }, children: "Subscribe" })] }) })), jsxRuntimeExports.jsxs("div", { id: "buttons", className: "flex w-full items-center justify-between", children: [jsxRuntimeExports.jsxs("div", { className: "mr-auto", children: [jsxRuntimeExports.jsx("span", { style: { display: isErrorLogsVisible ? undefined : 'none' }, children: jsxRuntimeExports.jsx("crowdin-button", { id: "show-integration-btn", "icon-before": "arrow_back", onClick: () => showIntegration(), children: "Integration" }) }), jsxRuntimeExports.jsx("span", { style: { display: isErrorLogsVisible ? 'none' : undefined }, children: jsxRuntimeExports.jsx("crowdin-button", { id: "show-error-logs-btn", "icon-before": "list", onClick: () => showErrorLogs(), children: "Error logs" }) })] }), isManager && (jsxRuntimeExports.jsx("crowdin-button", { "icon-before": "link", onClick: () => showPermissionsDialog(), children: "Share" })), infoModal && (jsxRuntimeExports.jsx("crowdin-button", { "icon-before": "info", onClick: () => openModal(infoModalRef.current), children: infoModal.title })), configurationFields && (jsxRuntimeExports.jsx("crowdin-button", { "icon-before": "settings", onClick: () => {
2612
+ openModal(settingsModalRef.current);
2273
2613
  fillSettingsForm();
2274
- }, children: "Settings" })), jsxRuntimeExports.jsx("crowdin-button", { ...(!isOwner ? { disabled: true, title: 'Only the owner can log out' } : {}), "icon-before": "account_circle", onClick: () => integrationLogout(), children: "Log out" })] })] }), jsxRuntimeExports.jsx("crowdin-simple-integration", { ref: appComponent, "async-progress": true, ...((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) ? { 'skip-crowdin-auto-schedule': true } : {}), ...((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration) ? { 'skip-integration-auto-schedule': true } : {}), ...((withCronSync === null || withCronSync === void 0 ? void 0 : withCronSync.crowdin) || (webhooks === null || webhooks === void 0 ? void 0 : webhooks.crowdin) ? { 'crowdin-schedule': 'true' } : {}), ...((withCronSync === null || withCronSync === void 0 ? void 0 : withCronSync.integration) || (webhooks === null || webhooks === void 0 ? void 0 : webhooks.integration) ? { 'integration-schedule': 'true' } : {}), ...(integrationOneLevelFetching ? { 'integration-one-level-fetching': 'true' } : {}), ...(integrationSearchListener ? { 'allow-integration-filter-change-listener': 'true' } : {}), ...(integrationPagination ? { 'integration-load-more-files': 'true' } : {}), "integration-name": name, "integration-logo": "logo.png", ...(((_a = integrationButtonMenuItems === null || integrationButtonMenuItems === void 0 ? void 0 : integrationButtonMenuItems.length) !== null && _a !== void 0 ? _a : 0) > 0
2275
- ? { 'integration-button-menu-items': integrationButtonMenuItems }
2276
- : {}), ...(((_b = crowdinButtonMenuItems === null || crowdinButtonMenuItems === void 0 ? void 0 : crowdinButtonMenuItems.length) !== null && _b !== void 0 ? _b : 0) > 0
2277
- ? { 'crowdin-button-menu-items': crowdinButtonMenuItems }
2278
- : {}), ...((filtering === null || filtering === void 0 ? void 0 : filtering.crowdinLanguages) ? { 'crowdin-filter': true } : {}), ...((filtering === null || filtering === void 0 ? void 0 : filtering.integrationFilterConfig)
2279
- ? {
2280
- 'integration-filter': true,
2281
- 'integration-filter-config': filtering.integrationFilterConfig,
2282
- }
2283
- : {}) }), jsxRuntimeExports.jsxs("div", { id: "user-errors", className: "hidden", children: [jsxRuntimeExports.jsx("crowdin-show-as-table", { "is-loading": true, id: "user-errors-table", "is-searchable": true, "total-records": "25", "search-placeholder": "Search something" }), jsxRuntimeExports.jsx("crowdin-alert", { children: "This table displays the most recent error logs from the past month. Logs older than one month will be automatically deleted." })] })] }), jsxRuntimeExports.jsx("crowdin-toasts", {}), jsxRuntimeExports.jsx("crowdin-async-progress", { cancelAsyncAction: "" }), jsxRuntimeExports.jsxs("crowdin-modal", { ref: subscriptionModal, style: { display: 'none' }, id: "subscription-modal", "modal-width": "50", "close-button": "false", children: [jsxRuntimeExports.jsx("div", { children: jsxRuntimeExports.jsxs("crowdin-alert", { type: "warning", children: ["Subscribe to continue using the ", name, " app."] }) }), jsxRuntimeExports.jsxs("div", { slot: "footer", children: [jsxRuntimeExports.jsx("crowdin-button", { primary: true, onClick: () => window.open(subscriptionLink.current, '_blank'), children: "Subscribe" }), jsxRuntimeExports.jsx("crowdin-button", { outlined: true, onClick: () => window.open('https://crowdin.com/contacts', '_blank'), children: "Contact us" }), jsxRuntimeExports.jsx("crowdin-button", { class: "ml-10", secondary: true, onClick: () => integrationLogout(), children: "Log out" })] })] }), jsxRuntimeExports.jsxs("crowdin-modal", { style: { display: 'none' }, id: "permissions-modal", "modal-title": "Share", "close-button-title": "Close", "close-button": true, "body-overflow-unset": true, children: [jsxRuntimeExports.jsx("div", { className: "loader hidden", children: jsxRuntimeExports.jsx("crowdin-progress-indicator", {}) }), jsxRuntimeExports.jsxs("div", { className: "permissions-modal-content", children: [jsxRuntimeExports.jsx("div", { className: "select-users-block", children: jsxRuntimeExports.jsx("crowdin-users-select", { ref: usersSelectRef, "allow-new-options": true, "is-multi": true, "is-searchable": true, id: "users", label: "Users", "help-text": "Search for members by name, username, email, or invite new ones using their email.", "is-position-fixed": true }, "users") }), jsxRuntimeExports.jsxs("div", { className: "select-users-info", children: [jsxRuntimeExports.jsx("div", { className: "confirm-users-block mt-2 hidden", children: jsxRuntimeExports.jsxs("table", { children: [jsxRuntimeExports.jsx("thead", { children: jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsx("th", { style: { width: '40%' }, children: "Access" }), jsxRuntimeExports.jsx("th", { style: { width: '35%' }, children: "Users" }), jsxRuntimeExports.jsx("th", { className: "status", style: { width: '20%' }, children: "Upcoming changes" })] }) }), jsxRuntimeExports.jsxs("tbody", { children: [hasOrganization && (jsxRuntimeExports.jsxs("tr", { className: "organization-invite", children: [jsxRuntimeExports.jsxs("td", { children: [jsxRuntimeExports.jsx("crowdin-p", { children: "Registration in Organization" }), jsxRuntimeExports.jsx("div", { className: "permission-description" })] }), jsxRuntimeExports.jsx("td", { className: "affected-users" }), jsxRuntimeExports.jsx("td", { className: "status" })] })), jsxRuntimeExports.jsxs("tr", { className: "project-invite", children: [jsxRuntimeExports.jsx("td", { children: jsxRuntimeExports.jsx("crowdin-p", { children: "Project Manager Access" }) }), jsxRuntimeExports.jsx("td", { className: "affected-users" }), jsxRuntimeExports.jsx("td", { className: "status" })] }), jsxRuntimeExports.jsxs("tr", { className: "application-settings-invite", children: [jsxRuntimeExports.jsxs("td", { children: [jsxRuntimeExports.jsx("crowdin-p", { children: "Application Visibility Access" }), jsxRuntimeExports.jsx("div", { className: "permission-description" })] }), jsxRuntimeExports.jsx("td", { className: "affected-users" }), jsxRuntimeExports.jsx("td", { className: "status" })] }), jsxRuntimeExports.jsxs("tr", { className: "application-credentials-invite", children: [jsxRuntimeExports.jsxs("td", { children: [jsxRuntimeExports.jsx("crowdin-p", { children: "Access to the Integration" }), jsxRuntimeExports.jsx("div", { className: "permission-description", children: "This provides access to sync files and modify the current integration settings." })] }), jsxRuntimeExports.jsx("td", { className: "affected-users" }), jsxRuntimeExports.jsx("td", { className: "status" })] })] })] }) }), zenModeUrl && (jsxRuntimeExports.jsx("div", { className: "mt-2", children: jsxRuntimeExports.jsx("crowdin-input", { "with-fixed-height": true, label: "Zen Mode link", "help-text": "This focused view allows you to concentrate solely on the Integrations section, eliminating other distractions.", value: zenModeUrl, name: "zenModeLink", "with-copy-button": true }) }))] })] }), jsxRuntimeExports.jsx("div", { slot: "footer", children: jsxRuntimeExports.jsx("crowdin-button", { id: "confirm-users-btn", outlined: true, onClick: () => inviteUsers(), children: "Save" }) })] }), excludedTargetLanguages && (jsxRuntimeExports.jsx("crowdin-modal", { ref: languageModal, "modal-width": "50", "modal-title": "Select Target Languages for Translation", id: "excluded-languages" })), infoModal && (jsxRuntimeExports.jsx("crowdin-modal", { style: { display: 'none' }, id: "info-modal", "modal-width": "50", "modal-title": infoModal.title, "close-button-title": "Close", children: jsxRuntimeExports.jsx("div", { dangerouslySetInnerHTML: { __html: infoModal.content } }) })), configurationFields && (jsxRuntimeExports.jsxs("crowdin-modal", { style: { display: 'none' }, id: "settings-modal", "modal-width": "65", "modal-title": "Settings", "close-button-title": "Close", children: [jsxRuntimeExports.jsx("div", { className: "loader hidden", children: jsxRuntimeExports.jsx("crowdin-progress-indicator", {}) }), jsxRuntimeExports.jsx("div", { id: "modal-content", children: jsxRuntimeExports.jsx("crowdin-tabs", { "tabs-config": JSON.stringify(configurationFields.map((f) => f.name)), "active-tab": "1", children: configurationFields.map((tab, tabIndex) => (jsxRuntimeExports.jsx("div", { slot: `tab-${tabIndex + 1}`, children: jsxRuntimeExports.jsx("div", { className: "crowdin-form", children: tab.fields.map((field) => (jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [renderConfigField(field, settingsFieldChange), jsxRuntimeExports.jsx("div", { style: { padding: '8px' }, ...(field.dependencySettings
2614
+ }, children: "Settings" })), jsxRuntimeExports.jsx("crowdin-button", { ...(!isOwner ? { disabled: true, title: 'Only the owner can log out' } : {}), "icon-before": "account_circle", onClick: () => integrationLogout(), children: "Log out" })] })] }), jsxRuntimeExports.jsx("div", { style: { display: isErrorLogsVisible ? 'none' : undefined }, children: jsxRuntimeExports.jsx("crowdin-simple-integration", { ref: appComponent, "async-progress": true, ...((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) ? { 'skip-crowdin-auto-schedule': true } : {}), ...((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration) ? { 'skip-integration-auto-schedule': true } : {}), ...((withCronSync === null || withCronSync === void 0 ? void 0 : withCronSync.crowdin) || (webhooks === null || webhooks === void 0 ? void 0 : webhooks.crowdin) ? { 'crowdin-schedule': 'true' } : {}), ...((withCronSync === null || withCronSync === void 0 ? void 0 : withCronSync.integration) || (webhooks === null || webhooks === void 0 ? void 0 : webhooks.integration)
2615
+ ? { 'integration-schedule': 'true' }
2616
+ : {}), ...(integrationOneLevelFetching ? { 'integration-one-level-fetching': 'true' } : {}), ...(integrationSearchListener ? { 'allow-integration-filter-change-listener': 'true' } : {}), ...(integrationPagination ? { 'integration-load-more-files': 'true' } : {}), "integration-name": name, "integration-logo": "logo.png", ...(((_a = integrationButtonMenuItems === null || integrationButtonMenuItems === void 0 ? void 0 : integrationButtonMenuItems.length) !== null && _a !== void 0 ? _a : 0) > 0
2617
+ ? { 'integration-button-menu-items': integrationButtonMenuItems }
2618
+ : {}), ...(((_b = crowdinButtonMenuItems === null || crowdinButtonMenuItems === void 0 ? void 0 : crowdinButtonMenuItems.length) !== null && _b !== void 0 ? _b : 0) > 0
2619
+ ? { 'crowdin-button-menu-items': crowdinButtonMenuItems }
2620
+ : {}), ...((filtering === null || filtering === void 0 ? void 0 : filtering.crowdinLanguages) ? { 'crowdin-filter': true } : {}), ...((filtering === null || filtering === void 0 ? void 0 : filtering.integrationFilterConfig)
2621
+ ? {
2622
+ 'integration-filter': true,
2623
+ 'integration-filter-config': filtering.integrationFilterConfig,
2624
+ }
2625
+ : {}) }) }), jsxRuntimeExports.jsxs("div", { id: "user-errors", style: { display: isErrorLogsVisible ? undefined : 'none' }, children: [jsxRuntimeExports.jsx("crowdin-show-as-table", { ref: userErrorsTableRef, "is-loading": true, id: "user-errors-table", "is-searchable": true, "total-records": "25", "search-placeholder": "Search something" }), jsxRuntimeExports.jsx("crowdin-alert", { children: "This table displays the most recent error logs from the past month. Logs older than one month will be automatically deleted." })] })] }), jsxRuntimeExports.jsx("crowdin-toasts", {}), jsxRuntimeExports.jsx("crowdin-async-progress", { ref: asyncProgressRef, cancelAsyncAction: "" }), jsxRuntimeExports.jsxs("crowdin-modal", { ref: subscriptionModal, style: { display: 'none' }, id: "subscription-modal", "modal-width": "50", "close-button": "false", children: [jsxRuntimeExports.jsx("div", { children: jsxRuntimeExports.jsxs("crowdin-alert", { type: "warning", children: ["Subscribe to continue using the ", name, " app."] }) }), jsxRuntimeExports.jsxs("div", { slot: "footer", children: [jsxRuntimeExports.jsx("crowdin-button", { primary: true, onClick: () => window.open(subscriptionLink.current, '_blank', 'noopener,noreferrer'), children: "Subscribe" }), jsxRuntimeExports.jsx("crowdin-button", { outlined: true, onClick: () => window.open('https://crowdin.com/contacts', '_blank', 'noopener,noreferrer'), children: "Contact us" }), jsxRuntimeExports.jsx("crowdin-button", { class: "ml-2.5", secondary: true, onClick: () => integrationLogout(), children: "Log out" })] })] }), jsxRuntimeExports.jsxs("crowdin-modal", { ref: permissionsModalRef, style: { display: 'none' }, id: "permissions-modal", "modal-title": "Share", "close-button-title": "Close", "close-button": true, "body-overflow-unset": true, children: [jsxRuntimeExports.jsx("div", { className: modalLoaders['permissions-modal']
2626
+ ? 'absolute inset-0 z-[4] flex items-center justify-center bg-white/30'
2627
+ : 'hidden', children: jsxRuntimeExports.jsx("crowdin-progress-indicator", {}) }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("div", { children: jsxRuntimeExports.jsx("crowdin-users-select", { ref: usersSelectRef, "allow-new-options": true, "is-multi": true, "is-searchable": true, id: "users", label: "Users", "help-text": "Search for members by name, username, email, or invite new ones using their email.", "is-position-fixed": true, children: permissionUserOptions.map((option) => (jsxRuntimeExports.jsx("option", { value: option.id, children: option.label }, option.id))) }, "users") }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("div", { className: isPermissionsConfirmVisible ? 'mt-4' : 'hidden', children: jsxRuntimeExports.jsxs("table", { className: "w-full border-separate border-spacing-0", children: [jsxRuntimeExports.jsx("thead", { children: jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsx("th", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left text-sm", style: { width: '40%' }, children: "Access" }), jsxRuntimeExports.jsx("th", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left text-sm", style: { width: '35%' }, children: "Users" }), jsxRuntimeExports.jsx("th", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-right text-sm", style: { width: '20%' }, children: "Upcoming changes" })] }) }), jsxRuntimeExports.jsxs("tbody", { children: [hasOrganization && (jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsxs("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: [jsxRuntimeExports.jsx("crowdin-p", { children: "Registration in Organization" }), renderPermissionRowDescription(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization)] }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization) }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.organization) &&
2628
+ renderPermissionStatus(permissionsSummary.organization.status) })] })), jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: jsxRuntimeExports.jsx("crowdin-p", { children: "Project Manager Access" }) }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.project) }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.project) &&
2629
+ renderPermissionStatus(permissionsSummary.project.status) })] }), jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsxs("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: [jsxRuntimeExports.jsx("crowdin-p", { children: "Application Visibility Access" }), renderPermissionRowDescription(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationSettings)] }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationSettings) }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationSettings) &&
2630
+ renderPermissionStatus(permissionsSummary.applicationSettings.status) })] }), jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsxs("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: [jsxRuntimeExports.jsx("crowdin-p", { children: "Access to the Integration" }), jsxRuntimeExports.jsx("div", { className: "mt-1 text-xs text-[var(--crowdin-text-muted)]", children: "This provides access to sync files and modify the current integration settings." })] }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-left align-top", children: renderPermissionUsers(permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationCredentials) }), jsxRuntimeExports.jsx("td", { className: "border-b border-[var(--crowdin-border-color)] p-4 text-right align-top", children: (permissionsSummary === null || permissionsSummary === void 0 ? void 0 : permissionsSummary.applicationCredentials) &&
2631
+ renderPermissionStatus(permissionsSummary.applicationCredentials.status) })] })] })] }) }), zenModeUrl && (jsxRuntimeExports.jsx("div", { className: "mt-4", children: jsxRuntimeExports.jsx("crowdin-input", { "with-fixed-height": true, label: "Zen Mode link", "help-text": "This focused view allows you to concentrate solely on the Integrations section, eliminating other distractions.", value: zenModeUrl, name: "zenModeLink", "with-copy-button": true }) }))] })] }), jsxRuntimeExports.jsx("div", { slot: "footer", children: jsxRuntimeExports.jsx("crowdin-button", { id: "confirm-users-btn", outlined: true, onClick: () => inviteUsers(), children: "Save" }) })] }), excludedTargetLanguages && (jsxRuntimeExports.jsx("crowdin-modal", { ref: languageModal, style: { display: 'none' }, "modal-width": "50", "modal-title": "Select Target Languages for Translation", id: "excluded-languages", children: languageModalState && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("div", { children: jsxRuntimeExports.jsx("crowdin-select", { ref: languageSelectRef, "is-multi": true, "is-searchable": true, "is-position-fixed": true, "close-on-select": "false", name: "languages", id: "language-select", label: "Languages", children: languageModalState.languages.map((language) => (jsxRuntimeExports.jsx("option", { value: language.id, children: language.name }, language.id))) }) }), jsxRuntimeExports.jsxs("div", { slot: "footer", children: [jsxRuntimeExports.jsx("span", { hidden: languageModalState.action !== 'updateCrowdinTargetLanguages', children: jsxRuntimeExports.jsx("crowdin-button", { id: "update-crowdin-target-languages", outlined: true, onClick: () => updateCrowdinFilesTargetLanguages(), children: "Update Target Languages" }) }), jsxRuntimeExports.jsx("span", { hidden: languageModalState.action !== 'syncToCrowdin', children: jsxRuntimeExports.jsx("crowdin-button", { id: "upload-exclude-languages", outlined: true, onClick: () => uploadFilesToCrowdinWithExcludedLanguages(), children: jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-1", children: [jsxRuntimeExports.jsx("span", { children: "Sync to" }), jsxRuntimeExports.jsx("crowdin-logo", { "is-icon": true })] }) }) })] })] })) })), infoModal && (jsxRuntimeExports.jsx("crowdin-modal", { ref: infoModalRef, style: { display: 'none' }, id: "info-modal", "modal-width": "50", "modal-title": infoModal.title, "close-button-title": "Close", children: jsxRuntimeExports.jsx("div", { dangerouslySetInnerHTML: { __html: infoModal.content } }) })), configurationFields && (jsxRuntimeExports.jsxs("crowdin-modal", { ref: settingsModalRef, style: { display: 'none' }, id: "settings-modal", "modal-width": "65", "modal-title": "Settings", "close-button-title": "Close", children: [jsxRuntimeExports.jsx("div", { className: modalLoaders['settings-modal']
2632
+ ? 'absolute inset-0 z-[4] flex items-center justify-center bg-white/30'
2633
+ : 'hidden', children: jsxRuntimeExports.jsx("crowdin-progress-indicator", {}) }), jsxRuntimeExports.jsx("div", { id: "modal-content", children: jsxRuntimeExports.jsx("crowdin-tabs", { "tabs-config": JSON.stringify(configurationFields.map((f) => f.name)), "active-tab": "1", children: configurationFields.map((tab, tabIndex) => (jsxRuntimeExports.jsx("div", { slot: `tab-${tabIndex + 1}`, children: jsxRuntimeExports.jsx("div", { children: tab.fields.map((field, fieldIndex) => (jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [renderConfigField(field, settingsFieldChange, registerSettingsField), jsxRuntimeExports.jsx("div", { style: { padding: '8px' }, ...(field.dependencySettings
2284
2634
  ? { 'data-dependency': field.dependencySettings }
2285
- : {}) })] }, field.key))) }) }, tabIndex))) }) }), jsxRuntimeExports.jsx("div", { slot: "footer", children: jsxRuntimeExports.jsx("crowdin-button", { id: "settings-save-btn", outlined: true, onClick: () => saveSettings(), children: "Save" }) })] })), ((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) || (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)) && (jsxRuntimeExports.jsxs("crowdin-modal", { style: { display: 'none' }, id: "confirm-schedule-modal", "modal-width": "50", "modal-title": "Synchronization options", "close-button-title": "Close", "close-button": "true", "body-overflow-unset": true, children: [jsxRuntimeExports.jsx("crowdin-checkbox", { id: "selected-files", name: "selected-files", label: "Selected files", class: "hydrated", onChange: () => onChangeAutoSynchronizationOptions() }), jsxRuntimeExports.jsx("crowdin-checkbox", { id: "all-folder-files", name: "all-folder-files", label: "All files in the folder", class: "hydrated", hidden: true, onChange: () => onChangeAutoSynchronizationOptions() }), jsxRuntimeExports.jsx("crowdin-checkbox", { id: "new-files", name: "new-files", label: "New files", class: "hydrated", onChange: () => onChangeAutoSynchronizationOptions() }), jsxRuntimeExports.jsx("div", { slot: "footer", children: jsxRuntimeExports.jsx("crowdin-button", { outlined: true, id: "save-schedule-sync", onClick: () => saveScheduleSync(), children: "Save" }) })] })), jsxRuntimeExports.jsx("crowdin-modal", { style: { display: 'none' }, id: "user-error-detail", "close-button-title": "Close", "close-button": "true" })] }));
2635
+ : {}) })] }, field.key || `${tabIndex}-${fieldIndex}`))) }) }, tabIndex))) }) }), jsxRuntimeExports.jsx("div", { slot: "footer", children: jsxRuntimeExports.jsx("crowdin-button", { id: "settings-save-btn", outlined: true, disabled: isSettingsSaveDisabled, onClick: () => saveSettings(), children: "Save" }) })] })), ((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) || (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)) && (jsxRuntimeExports.jsxs("crowdin-modal", { ref: scheduleModalRef, style: { display: 'none' }, id: "confirm-schedule-modal", "modal-width": "50", "modal-title": "Synchronization options", "close-button-title": "Close", "close-button": "true", "body-overflow-unset": true, children: [jsxRuntimeExports.jsx("crowdin-checkbox", { ref: selectedFilesCheckboxRef, id: "selected-files", name: "selected-files", label: "Selected files", class: "hydrated", checked: scheduleModalState.selectedFiles, value: String(scheduleModalState.selectedFiles), onChange: () => onChangeAutoSynchronizationOptions() }), jsxRuntimeExports.jsx("crowdin-checkbox", { ref: allFolderFilesCheckboxRef, id: "all-folder-files", name: "all-folder-files", label: "All files in the folder", class: "hydrated", hidden: !scheduleModalState.showAllFolderFiles, checked: scheduleModalState.allFolderFiles, value: String(scheduleModalState.allFolderFiles), onChange: () => onChangeAutoSynchronizationOptions() }), jsxRuntimeExports.jsx("crowdin-checkbox", { ref: newFilesCheckboxRef, id: "new-files", name: "new-files", label: "New files", class: "hydrated", hidden: !scheduleModalState.showNewFiles, checked: scheduleModalState.newFiles, value: String(scheduleModalState.newFiles), ...(scheduleModalState.newFilesClearSelection ? { 'clear-selection': '' } : {}), onChange: () => onChangeAutoSynchronizationOptions() }), jsxRuntimeExports.jsx("div", { slot: "footer", children: jsxRuntimeExports.jsx("crowdin-button", { outlined: true, id: "save-schedule-sync", disabled: isScheduleSaveDisabled, onClick: () => saveScheduleSync(), children: "Save" }) })] })), jsxRuntimeExports.jsx("crowdin-modal", { ref: userErrorDetailModalRef, style: { display: 'none' }, id: "user-error-detail", "close-button-title": "Close", "close-button": "true", children: selectedUserError && getUserErrorDetail(selectedUserError) })] }));
2286
2636
  };
2287
2637
 
2288
- clientExports.createRoot(document.getElementById('root')).render(jsxRuntimeExports.jsx(MainPage, { ...window.__PAGE_PROPS__ }));
2638
+ initializeCrowdinIframeContext();
2639
+ const props = readPageProps();
2640
+ clientExports.createRoot(document.getElementById('root')).render(jsxRuntimeExports.jsx(MainPage, { ...props }));
2289
2641
 
2290
2642
  })();
2291
2643
  //# sourceMappingURL=main.bundle.js.map