@crowdin/app-project-module 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/modules/ai-provider/handlers/chat-completions.js +9 -1
- package/out/modules/ai-provider/handlers/get-model-list.js +3 -0
- package/out/modules/ai-provider/types.d.ts +38 -1
- package/out/modules/integration/handlers/invite-users.js +30 -1
- package/out/modules/integration/handlers/users.js +3 -0
- package/out/static/css/styles.css +1 -1
- package/out/static/ui/form.bundle.js +2331 -723
- package/out/static/ui/form.bundle.js.map +1 -1
- package/out/static/ui/main.bundle.js +150 -35
- package/out/static/ui/main.bundle.js.map +1 -1
- package/out/storage/drizzle/index.d.ts +3 -1
- package/out/storage/drizzle/index.js +104 -66
- package/package.json +1 -1
|
@@ -17758,9 +17758,37 @@
|
|
|
17758
17758
|
}
|
|
17759
17759
|
|
|
17760
17760
|
/// <reference path="../../../../ui/types.d.ts" />
|
|
17761
|
+
const APPLICATION_SETTINGS_DESCRIPTION = 'This can be configured in organization settings (Apps section).';
|
|
17762
|
+
// Crowdin only widens visibility for users the current mode doesn't already cover, so a
|
|
17763
|
+
// share with someone who is an admin already leaves an admins-only app untouched. Per-user
|
|
17764
|
+
// admin status isn't exposed to the dialog, hence copy that states the rule rather than
|
|
17765
|
+
// promising a switch.
|
|
17766
|
+
function getVisibilityDescription({ isAdmin, currentAccessMode }) {
|
|
17767
|
+
if (!isAdmin) {
|
|
17768
|
+
return `${APPLICATION_SETTINGS_DESCRIPTION} Only organization admins have permission to update this setting.`;
|
|
17769
|
+
}
|
|
17770
|
+
if (currentAccessMode === 'owner') {
|
|
17771
|
+
return ('This app is currently available to organization admins only. If any of the users listed here is ' +
|
|
17772
|
+
'not an admin, sharing switches it to Custom Access — all admins keep access, and these users are ' +
|
|
17773
|
+
'added. If they are all admins already, the visibility setting stays unchanged.');
|
|
17774
|
+
}
|
|
17775
|
+
if (currentAccessMode === 'restricted') {
|
|
17776
|
+
return "These users will be added to this app's Custom Access list.";
|
|
17777
|
+
}
|
|
17778
|
+
return APPLICATION_SETTINGS_DESCRIPTION;
|
|
17779
|
+
}
|
|
17761
17780
|
function usePermissions({ userId, hasOrganization, permissionsModalRef }) {
|
|
17762
17781
|
const usersSelectRef = reactExports.useRef(null);
|
|
17782
|
+
const connectionOwnerIdRef = reactExports.useRef(null);
|
|
17783
|
+
const initialManagerIdsRef = reactExports.useRef(new Set());
|
|
17784
|
+
// Distinguishes a deliberate self-removal from a save that merely never included the user.
|
|
17785
|
+
const actingUserPreselectedRef = reactExports.useRef(false);
|
|
17786
|
+
// Monotonic ids so out-of-order validations and slow loads can't clobber newer state.
|
|
17787
|
+
const checkUsersSeqRef = reactExports.useRef(0);
|
|
17788
|
+
const permissionsOpenSeqRef = reactExports.useRef(0);
|
|
17763
17789
|
const [isLoading, setIsLoading] = reactExports.useState(false);
|
|
17790
|
+
// Gates Save until the user list loads, so a failed load can't save an empty list.
|
|
17791
|
+
const [isPermissionsLoaded, setIsPermissionsLoaded] = reactExports.useState(false);
|
|
17764
17792
|
const [permissionUserOptions, setPermissionUserOptions] = reactExports.useState([]);
|
|
17765
17793
|
const [permissionsSelectedValue, setPermissionsSelectedValue] = reactExports.useState('[]');
|
|
17766
17794
|
const [permissionsSummary, setPermissionsSummary] = reactExports.useState(null);
|
|
@@ -17776,7 +17804,10 @@
|
|
|
17776
17804
|
if (!selectElement) {
|
|
17777
17805
|
return;
|
|
17778
17806
|
}
|
|
17779
|
-
const handleChange = () =>
|
|
17807
|
+
const handleChange = () => {
|
|
17808
|
+
enforceOwnerPresence();
|
|
17809
|
+
checkUsers();
|
|
17810
|
+
};
|
|
17780
17811
|
selectElement.addEventListener('change', handleChange);
|
|
17781
17812
|
return () => selectElement.removeEventListener('change', handleChange);
|
|
17782
17813
|
}, []);
|
|
@@ -17797,44 +17828,101 @@
|
|
|
17797
17828
|
setIsPermissionsConfirmVisible(true);
|
|
17798
17829
|
(_a = permissionsModalRef.current) === null || _a === void 0 ? void 0 : _a.removeAttribute('body-overflow-unset');
|
|
17799
17830
|
}
|
|
17831
|
+
// The backend force-keeps the owner anyway, so bounce the removal back instead of
|
|
17832
|
+
// silently dropping it on save.
|
|
17833
|
+
function enforceOwnerPresence() {
|
|
17834
|
+
const select = usersSelectRef.current;
|
|
17835
|
+
const ownerId = connectionOwnerIdRef.current;
|
|
17836
|
+
if (!select || !ownerId || !initialManagerIdsRef.current.has(ownerId)) {
|
|
17837
|
+
return;
|
|
17838
|
+
}
|
|
17839
|
+
let current = [];
|
|
17840
|
+
try {
|
|
17841
|
+
const parsed = JSON.parse(select.value);
|
|
17842
|
+
current = (Array.isArray(parsed) ? parsed : []).map((id) => `${id}`);
|
|
17843
|
+
}
|
|
17844
|
+
catch {
|
|
17845
|
+
current = [];
|
|
17846
|
+
}
|
|
17847
|
+
if (!current.includes(ownerId)) {
|
|
17848
|
+
select.value = JSON.stringify([...current, ownerId]);
|
|
17849
|
+
showToast("The integration owner can't be removed from the access list.");
|
|
17850
|
+
}
|
|
17851
|
+
}
|
|
17800
17852
|
async function showPermissionsDialog() {
|
|
17853
|
+
var _a;
|
|
17801
17854
|
hideConfirmUsersBlock();
|
|
17802
17855
|
openModal(permissionsModalRef.current);
|
|
17803
17856
|
setIsLoading(true);
|
|
17804
17857
|
setPermissionsSelectedValue('[]');
|
|
17858
|
+
// Reset before the async load, so a change event mid-load can't act on the
|
|
17859
|
+
// previous session's state.
|
|
17860
|
+
setIsPermissionsLoaded(false);
|
|
17861
|
+
connectionOwnerIdRef.current = null;
|
|
17862
|
+
initialManagerIdsRef.current = new Set();
|
|
17863
|
+
actingUserPreselectedRef.current = false;
|
|
17864
|
+
checkUsersSeqRef.current++;
|
|
17865
|
+
const openSeq = ++permissionsOpenSeqRef.current;
|
|
17805
17866
|
try {
|
|
17806
|
-
const [
|
|
17807
|
-
new Promise((resolve) => {
|
|
17867
|
+
const [usersData, users] = await Promise.all([
|
|
17868
|
+
new Promise((resolve, reject) => {
|
|
17808
17869
|
checkOrigin()
|
|
17809
17870
|
.then((restParams) => fetch('api/users' + restParams))
|
|
17810
17871
|
.then(checkResponse)
|
|
17811
|
-
.then((res) => resolve(
|
|
17872
|
+
.then((res) => resolve(res.data))
|
|
17873
|
+
.catch(reject);
|
|
17812
17874
|
}),
|
|
17875
|
+
// Includes the current user, so a share auto-includes the person doing it.
|
|
17813
17876
|
new Promise((resolve) => {
|
|
17814
|
-
AP.getUsers((res) =>
|
|
17815
|
-
const users = Object.values(res).filter((user) => user.id !== Number(userId));
|
|
17816
|
-
resolve(users);
|
|
17817
|
-
});
|
|
17877
|
+
AP.getUsers((res) => resolve(Object.values(res)));
|
|
17818
17878
|
}),
|
|
17819
17879
|
]);
|
|
17820
|
-
|
|
17880
|
+
if (openSeq !== permissionsOpenSeqRef.current) {
|
|
17881
|
+
return;
|
|
17882
|
+
}
|
|
17883
|
+
const { managers, ownerId } = usersData || {};
|
|
17884
|
+
const parsedManagers = (managers || []);
|
|
17821
17885
|
const validUserIds = new Set(users.map((user) => `${user.id}`));
|
|
17822
|
-
const
|
|
17886
|
+
const storedManagers = parsedManagers.filter((id) => validUserIds.has(id));
|
|
17887
|
+
// Ids are compared as strings; a missing owner id must stay null, not become "undefined".
|
|
17888
|
+
connectionOwnerIdRef.current = (_a = ownerId === null || ownerId === void 0 ? void 0 : ownerId.toString()) !== null && _a !== void 0 ? _a : null;
|
|
17889
|
+
// Baseline for telling additions from removals: stored managers plus the owner
|
|
17890
|
+
// (who always has access). The acting user is deliberately NOT seeded.
|
|
17891
|
+
initialManagerIdsRef.current = new Set(storedManagers);
|
|
17892
|
+
if (connectionOwnerIdRef.current && validUserIds.has(connectionOwnerIdRef.current)) {
|
|
17893
|
+
initialManagerIdsRef.current.add(connectionOwnerIdRef.current);
|
|
17894
|
+
}
|
|
17895
|
+
const preselected = new Set(storedManagers);
|
|
17896
|
+
if (validUserIds.has(`${userId}`)) {
|
|
17897
|
+
preselected.add(`${userId}`);
|
|
17898
|
+
actingUserPreselectedRef.current = true;
|
|
17899
|
+
}
|
|
17900
|
+
if (connectionOwnerIdRef.current && validUserIds.has(connectionOwnerIdRef.current)) {
|
|
17901
|
+
preselected.add(connectionOwnerIdRef.current);
|
|
17902
|
+
}
|
|
17823
17903
|
setPermissionUserOptions(users.map((user) => ({
|
|
17824
17904
|
id: String(user.id),
|
|
17825
17905
|
label: getUserFullName(user),
|
|
17826
17906
|
})));
|
|
17827
|
-
setPermissionsSelectedValue(JSON.stringify(
|
|
17907
|
+
setPermissionsSelectedValue(JSON.stringify([...preselected]));
|
|
17908
|
+
setIsPermissionsLoaded(true);
|
|
17828
17909
|
}
|
|
17829
17910
|
catch (e) {
|
|
17830
|
-
|
|
17911
|
+
if (openSeq === permissionsOpenSeqRef.current) {
|
|
17912
|
+
catchRejection(e, "Can't fetch users");
|
|
17913
|
+
}
|
|
17831
17914
|
}
|
|
17832
17915
|
finally {
|
|
17833
|
-
|
|
17916
|
+
if (openSeq === permissionsOpenSeqRef.current) {
|
|
17917
|
+
setTimeout(() => setIsLoading(false), 500);
|
|
17918
|
+
}
|
|
17834
17919
|
}
|
|
17835
17920
|
}
|
|
17836
17921
|
async function checkUsers() {
|
|
17837
17922
|
setIsLoading(true);
|
|
17923
|
+
// Stamped on every invocation, the empty-selection early-return included, so a
|
|
17924
|
+
// cleared selection also invalidates a validation still in flight.
|
|
17925
|
+
const seq = ++checkUsersSeqRef.current;
|
|
17838
17926
|
const select = usersSelectRef.current;
|
|
17839
17927
|
if (select.value === '[]') {
|
|
17840
17928
|
hideConfirmUsersBlock();
|
|
@@ -17846,11 +17934,12 @@
|
|
|
17846
17934
|
const emails = users.filter((id) => !parseInt(id));
|
|
17847
17935
|
try {
|
|
17848
17936
|
const [appManagers, checkUsersResponse, allUsers] = await Promise.all([
|
|
17849
|
-
new Promise((resolve) => {
|
|
17937
|
+
new Promise((resolve, reject) => {
|
|
17850
17938
|
checkOrigin()
|
|
17851
17939
|
.then((restParams) => fetch('api/users' + restParams))
|
|
17852
17940
|
.then(checkResponse)
|
|
17853
|
-
.then((usersResponse) => resolve(usersResponse.data.managers))
|
|
17941
|
+
.then((usersResponse) => resolve(usersResponse.data.managers))
|
|
17942
|
+
.catch(reject);
|
|
17854
17943
|
}),
|
|
17855
17944
|
new Promise((resolve) => {
|
|
17856
17945
|
AP.validateUsers({ user_ids, emails }, (res) => resolve(res.data));
|
|
@@ -17859,6 +17948,9 @@
|
|
|
17859
17948
|
AP.getUsers((res) => resolve(res));
|
|
17860
17949
|
}),
|
|
17861
17950
|
]);
|
|
17951
|
+
if (seq !== checkUsersSeqRef.current) {
|
|
17952
|
+
return;
|
|
17953
|
+
}
|
|
17862
17954
|
const newUserEmails = checkUsersResponse.newUserEmails.map((email) => ({ name: email }));
|
|
17863
17955
|
const newProjectManagers = [
|
|
17864
17956
|
...newUserEmails,
|
|
@@ -17873,30 +17965,54 @@
|
|
|
17873
17965
|
const newApplicationManagers = [
|
|
17874
17966
|
...newUserEmails,
|
|
17875
17967
|
...Object.values(allUsers)
|
|
17876
|
-
.filter((user) => users.some((id) => +id === user.id) &&
|
|
17968
|
+
.filter((user) => users.some((id) => +id === user.id) &&
|
|
17969
|
+
!appManagers.some((id) => +id === user.id) &&
|
|
17970
|
+
// The owner always has access, so they are never a genuine grant.
|
|
17971
|
+
`${user.id}` !== connectionOwnerIdRef.current)
|
|
17877
17972
|
.map((user) => ({ name: getUserFullName(user) })),
|
|
17878
17973
|
];
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
|
|
17885
|
-
|
|
17974
|
+
// The preview is only meaningful for users being granted access; pure removals
|
|
17975
|
+
// are still saved, just without it. Compared against the freshly-fetched managers
|
|
17976
|
+
// rather than an open-time snapshot, so users added by email are caught too.
|
|
17977
|
+
const storedManagerSet = new Set(appManagers.map((id) => `${id}`));
|
|
17978
|
+
const hasAdditions = users
|
|
17979
|
+
.map((id) => `${id}`)
|
|
17980
|
+
.some((id) => id !== connectionOwnerIdRef.current && !storedManagerSet.has(id));
|
|
17981
|
+
if (hasAdditions) {
|
|
17982
|
+
prepareUsersConfirmBlock({
|
|
17983
|
+
...checkUsersResponse,
|
|
17984
|
+
newUserEmails,
|
|
17985
|
+
newProjectManagers,
|
|
17986
|
+
newApplicationAccessUsers,
|
|
17987
|
+
newApplicationManagers,
|
|
17988
|
+
});
|
|
17989
|
+
}
|
|
17990
|
+
else {
|
|
17991
|
+
hideConfirmUsersBlock();
|
|
17992
|
+
}
|
|
17886
17993
|
}
|
|
17887
17994
|
catch (e) {
|
|
17888
|
-
|
|
17995
|
+
if (seq === checkUsersSeqRef.current) {
|
|
17996
|
+
catchRejection(e, (e === null || e === void 0 ? void 0 : e.error) || "Can't invite users");
|
|
17997
|
+
}
|
|
17889
17998
|
}
|
|
17890
17999
|
finally {
|
|
17891
|
-
|
|
18000
|
+
if (seq === checkUsersSeqRef.current) {
|
|
18001
|
+
setTimeout(() => setIsLoading(false), 500);
|
|
18002
|
+
}
|
|
17892
18003
|
}
|
|
17893
18004
|
}
|
|
17894
18005
|
function inviteUsers() {
|
|
18006
|
+
var _a;
|
|
17895
18007
|
setIsLoading(true);
|
|
17896
18008
|
const select = usersSelectRef.current;
|
|
17897
18009
|
const users = JSON.parse(select.value);
|
|
17898
18010
|
const user_ids = users.filter((id) => parseInt(id));
|
|
17899
18011
|
const emails = users.filter((id) => !parseInt(id));
|
|
18012
|
+
// The backend force-keeps the acting user unless this flag says otherwise, so an
|
|
18013
|
+
// acting user who is merely absent (e.g. not returned by AP.getUsers) stays protected.
|
|
18014
|
+
const actingUserId = (_a = userId === null || userId === void 0 ? void 0 : userId.toString()) !== null && _a !== void 0 ? _a : null;
|
|
18015
|
+
const allowSelfRemoval = actingUserPreselectedRef.current && !!actingUserId && !users.some((id) => `${id}` === actingUserId);
|
|
17900
18016
|
AP.inviteUsers({ user_ids, emails }, async (res) => {
|
|
17901
18017
|
var _a;
|
|
17902
18018
|
if (!res.success) {
|
|
@@ -17909,7 +18025,7 @@
|
|
|
17909
18025
|
const inviteRes = await checkResponse(await fetch('api/invite-users' + restParams, {
|
|
17910
18026
|
method: 'POST',
|
|
17911
18027
|
headers: { 'Content-Type': 'application/json' },
|
|
17912
|
-
body: JSON.stringify(res.data),
|
|
18028
|
+
body: JSON.stringify({ ...res.data, allowSelfRemoval }),
|
|
17913
18029
|
}));
|
|
17914
18030
|
if (!inviteRes.success) {
|
|
17915
18031
|
catchRejection(inviteRes, (inviteRes === null || inviteRes === void 0 ? void 0 : inviteRes.message) || "Can't invite users");
|
|
@@ -17930,8 +18046,10 @@
|
|
|
17930
18046
|
function prepareUsersConfirmBlock(usersData) {
|
|
17931
18047
|
showConfirmUsersBlock();
|
|
17932
18048
|
const toNames = (users = []) => users.map((user) => user.name);
|
|
17933
|
-
const applicationSettingsDescription = 'This can be configured in organization settings (Apps section).';
|
|
17934
18049
|
const hasApplicationAccessUsers = usersData.newApplicationAccessUsers.length > 0;
|
|
18050
|
+
const visibilityDescription = hasApplicationAccessUsers
|
|
18051
|
+
? getVisibilityDescription(usersData)
|
|
18052
|
+
: APPLICATION_SETTINGS_DESCRIPTION;
|
|
17935
18053
|
setPermissionsSummary({
|
|
17936
18054
|
...(hasOrganization
|
|
17937
18055
|
? {
|
|
@@ -17960,11 +18078,7 @@
|
|
|
17960
18078
|
: 'actionRequired'
|
|
17961
18079
|
: 'granted',
|
|
17962
18080
|
users: toNames(usersData.newApplicationAccessUsers),
|
|
17963
|
-
description:
|
|
17964
|
-
? usersData.isAdmin
|
|
17965
|
-
? applicationSettingsDescription
|
|
17966
|
-
: `${applicationSettingsDescription} Only organization admins have permission to update this setting.`
|
|
17967
|
-
: applicationSettingsDescription,
|
|
18081
|
+
description: visibilityDescription,
|
|
17968
18082
|
isWarning: hasApplicationAccessUsers && !usersData.isAdmin,
|
|
17969
18083
|
},
|
|
17970
18084
|
applicationCredentials: {
|
|
@@ -17976,6 +18090,7 @@
|
|
|
17976
18090
|
return {
|
|
17977
18091
|
usersSelectRef,
|
|
17978
18092
|
isLoading,
|
|
18093
|
+
isPermissionsLoaded,
|
|
17979
18094
|
permissionUserOptions,
|
|
17980
18095
|
permissionsSelectedValue,
|
|
17981
18096
|
permissionsSummary,
|
|
@@ -19250,12 +19365,12 @@
|
|
|
19250
19365
|
? 'mt-1 text-xs text-[var(--crowdin-warning)]'
|
|
19251
19366
|
: 'mt-1 text-xs text-[var(--crowdin-text-muted)]', children: row.description }));
|
|
19252
19367
|
}
|
|
19253
|
-
const PermissionsModal = ({ modalRef, usersSelectRef, isLoading, permissionUserOptions, isConfirmVisible, permissionsSummary, hasOrganization, zenModeUrl, onSave, }) => {
|
|
19368
|
+
const PermissionsModal = ({ modalRef, usersSelectRef, isLoading, permissionUserOptions, isConfirmVisible, permissionsSummary, hasOrganization, zenModeUrl, saveDisabled, onSave, }) => {
|
|
19254
19369
|
return (jsxRuntimeExports.jsxs("crowdin-modal", { ref: modalRef, 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: isLoading ? 'absolute inset-0 z-[4] flex items-center justify-center bg-white/30' : '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: isConfirmVisible ? '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) &&
|
|
19255
19370
|
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) &&
|
|
19256
19371
|
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) &&
|
|
19257
19372
|
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) &&
|
|
19258
|
-
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: onSave, children: "Save" }) })] }));
|
|
19373
|
+
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: onSave, ...(saveDisabled ? { disabled: true } : {}), children: "Save" }) })] }));
|
|
19259
19374
|
};
|
|
19260
19375
|
|
|
19261
19376
|
const ScheduleModal = ({ modalRef, selectedFilesCheckboxRef, allFolderFilesCheckboxRef, newFilesCheckboxRef, scheduleModalState, isSaveDisabled, onChangeOptions, onSave, }) => {
|
|
@@ -19514,7 +19629,7 @@
|
|
|
19514
19629
|
return (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-[1420px] px-6 py-4", children: [jsxRuntimeExports.jsx(TopBar, { notice: notice, isNoticeVisible: isNoticeVisible, checkSubscription: checkSubscription, subscriptionInfo: subscriptionInfo, isErrorLogsVisible: isErrorLogsVisible, isManager: isManager, infoModal: infoModal, hasSettings: !!configurationFields, isOwner: isOwner, onCloseNotice: closeAlert, onShowIntegration: showIntegration, onShowErrorLogs: showErrorLogs, onShowPermissions: permissions.showPermissionsDialog, onOpenInfoModal: () => openModal(infoModalRef.current), onOpenSettings: () => {
|
|
19515
19630
|
openModal(settingsModalRef.current);
|
|
19516
19631
|
settings.fillSettingsForm();
|
|
19517
|
-
}, onLogout: integrationLogout }), jsxRuntimeExports.jsx(IntegrationView, { appComponentRef: appComponent, userErrorsTableRef: userErrorsTableRef, name: name, isErrorLogsVisible: isErrorLogsVisible, syncNewElements: syncNewElements, withCronSync: withCronSync, webhooks: webhooks, integrationOneLevelFetching: integrationOneLevelFetching, integrationSearchListener: integrationSearchListener, integrationPagination: integrationPagination, filtering: filtering, integrationButtonMenuItems: integrationButtonMenuItems, crowdinButtonMenuItems: crowdinButtonMenuItems })] }), jsxRuntimeExports.jsx("crowdin-toasts", {}), jsxRuntimeExports.jsx("crowdin-async-progress", { ref: asyncProgressRef, cancelAsyncAction: "" }), jsxRuntimeExports.jsx(SubscriptionModal, { modalRef: subscriptionModal, subscriptionLink: subscriptionLink, name: name, onLogout: integrationLogout }), jsxRuntimeExports.jsx(PermissionsModal, { modalRef: permissionsModalRef, usersSelectRef: permissions.usersSelectRef, isLoading: permissions.isLoading, permissionUserOptions: permissions.permissionUserOptions, isConfirmVisible: permissions.isPermissionsConfirmVisible, permissionsSummary: permissions.permissionsSummary, hasOrganization: hasOrganization, zenModeUrl: zenModeUrl, onSave: permissions.inviteUsers }), excludedTargetLanguages && (jsxRuntimeExports.jsx(ExcludedLanguagesModal, { modalRef: syncOps.languageModalRef, languageSelectRef: syncOps.languageSelectRef, languageModalState: syncOps.languageModalState, onUpdateTargetLanguages: syncOps.updateCrowdinFilesTargetLanguages, onSyncToCrowdin: syncOps.uploadFilesToCrowdinWithExcludedLanguages })), infoModal && jsxRuntimeExports.jsx(InfoModal, { modalRef: infoModalRef, infoModal: infoModal }), configurationFields && (jsxRuntimeExports.jsx(SettingsModal, { modalRef: settingsModalRef, isLoading: settings.isLoading, configurationFields: configurationFields, isSaveDisabled: settings.isSettingsSaveDisabled, settingsFieldChange: settings.settingsFieldChange, registerSettingsField: settings.registerSettingsField, onSave: settings.saveSettings })), ((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) || (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)) && (jsxRuntimeExports.jsx(ScheduleModal, { modalRef: scheduleModalRef, selectedFilesCheckboxRef: schedule.selectedFilesCheckboxRef, allFolderFilesCheckboxRef: schedule.allFolderFilesCheckboxRef, newFilesCheckboxRef: schedule.newFilesCheckboxRef, scheduleModalState: schedule.scheduleModalState, isSaveDisabled: schedule.isScheduleSaveDisabled, onChangeOptions: schedule.onChangeAutoSynchronizationOptions, onSave: schedule.saveScheduleSync })), jsxRuntimeExports.jsx(UserErrorDetailModal, { modalRef: userErrorDetailModalRef, selectedUserError: selectedUserError })] }));
|
|
19632
|
+
}, onLogout: integrationLogout }), jsxRuntimeExports.jsx(IntegrationView, { appComponentRef: appComponent, userErrorsTableRef: userErrorsTableRef, name: name, isErrorLogsVisible: isErrorLogsVisible, syncNewElements: syncNewElements, withCronSync: withCronSync, webhooks: webhooks, integrationOneLevelFetching: integrationOneLevelFetching, integrationSearchListener: integrationSearchListener, integrationPagination: integrationPagination, filtering: filtering, integrationButtonMenuItems: integrationButtonMenuItems, crowdinButtonMenuItems: crowdinButtonMenuItems })] }), jsxRuntimeExports.jsx("crowdin-toasts", {}), jsxRuntimeExports.jsx("crowdin-async-progress", { ref: asyncProgressRef, cancelAsyncAction: "" }), jsxRuntimeExports.jsx(SubscriptionModal, { modalRef: subscriptionModal, subscriptionLink: subscriptionLink, name: name, onLogout: integrationLogout }), jsxRuntimeExports.jsx(PermissionsModal, { modalRef: permissionsModalRef, usersSelectRef: permissions.usersSelectRef, isLoading: permissions.isLoading, permissionUserOptions: permissions.permissionUserOptions, isConfirmVisible: permissions.isPermissionsConfirmVisible, permissionsSummary: permissions.permissionsSummary, hasOrganization: hasOrganization, zenModeUrl: zenModeUrl, saveDisabled: !permissions.isPermissionsLoaded, onSave: permissions.inviteUsers }), excludedTargetLanguages && (jsxRuntimeExports.jsx(ExcludedLanguagesModal, { modalRef: syncOps.languageModalRef, languageSelectRef: syncOps.languageSelectRef, languageModalState: syncOps.languageModalState, onUpdateTargetLanguages: syncOps.updateCrowdinFilesTargetLanguages, onSyncToCrowdin: syncOps.uploadFilesToCrowdinWithExcludedLanguages })), infoModal && jsxRuntimeExports.jsx(InfoModal, { modalRef: infoModalRef, infoModal: infoModal }), configurationFields && (jsxRuntimeExports.jsx(SettingsModal, { modalRef: settingsModalRef, isLoading: settings.isLoading, configurationFields: configurationFields, isSaveDisabled: settings.isSettingsSaveDisabled, settingsFieldChange: settings.settingsFieldChange, registerSettingsField: settings.registerSettingsField, onSave: settings.saveSettings })), ((syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.crowdin) || (syncNewElements === null || syncNewElements === void 0 ? void 0 : syncNewElements.integration)) && (jsxRuntimeExports.jsx(ScheduleModal, { modalRef: scheduleModalRef, selectedFilesCheckboxRef: schedule.selectedFilesCheckboxRef, allFolderFilesCheckboxRef: schedule.allFolderFilesCheckboxRef, newFilesCheckboxRef: schedule.newFilesCheckboxRef, scheduleModalState: schedule.scheduleModalState, isSaveDisabled: schedule.isScheduleSaveDisabled, onChangeOptions: schedule.onChangeAutoSynchronizationOptions, onSave: schedule.saveScheduleSync })), jsxRuntimeExports.jsx(UserErrorDetailModal, { modalRef: userErrorDetailModalRef, selectedUserError: selectedUserError })] }));
|
|
19518
19633
|
};
|
|
19519
19634
|
|
|
19520
19635
|
initializeCrowdinIframeContext();
|