@crowdin/app-project-module 0.71.2 → 0.73.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/middlewares/integration-credentials.js +6 -9
- package/out/modules/integration/handlers/invite-users.d.ts +3 -0
- package/out/modules/integration/handlers/invite-users.js +268 -0
- package/out/modules/integration/handlers/main.js +11 -5
- package/out/modules/integration/handlers/users.d.ts +13 -0
- package/out/modules/integration/handlers/users.js +102 -0
- package/out/modules/integration/index.js +14 -0
- package/out/modules/integration/types.d.ts +1 -0
- package/out/modules/integration/util/defaults.js +0 -48
- package/out/modules/manifest.js +5 -2
- package/out/modules/webhooks/handlers/webhook-handler.js +1 -3
- package/out/modules/webhooks/types.d.ts +1 -1
- package/out/modules/workflow-step-type/types.d.ts +9 -0
- package/out/modules/workflow-step-type/types.js +7 -0
- package/out/static/css/styles.css +77 -0
- package/out/storage/index.d.ts +1 -0
- package/out/storage/mysql.d.ts +1 -0
- package/out/storage/mysql.js +10 -3
- package/out/storage/postgre.d.ts +1 -0
- package/out/storage/postgre.js +10 -3
- package/out/storage/sqlite.d.ts +2 -0
- package/out/storage/sqlite.js +28 -3
- package/out/types.d.ts +4 -2
- package/out/types.js +2 -0
- package/out/util/index.d.ts +1 -0
- package/out/util/index.js +12 -1
- package/out/views/main.handlebars +274 -14
- package/package.json +1 -1
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
<div id="buttons">
|
|
37
37
|
<crowdin-button id="show-integration-btn" class="hidden" icon-before="arrow_back" onclick="showIntegration();">Integration</crowdin-button>
|
|
38
38
|
<crowdin-button id="show-error-logs-btn" icon-before="list" onclick="showErrorLogs();">Error logs</crowdin-button>
|
|
39
|
+
<crowdin-button icon-before="manage_accounts" onclick="showPermissionsDialog()">Permissions</crowdin-button>
|
|
39
40
|
{{#if infoModal}}
|
|
40
41
|
<crowdin-button icon-before="info" onclick="openModal(infoModal);">{{infoModal.title}}</crowdin-button>
|
|
41
42
|
{{/if}}
|
|
@@ -115,19 +116,113 @@
|
|
|
115
116
|
<crowdin-button class="ml-10" secondary onclick="integrationLogout()">Log out</crowdin-button>
|
|
116
117
|
</div>
|
|
117
118
|
</crowdin-modal>
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
<crowdin-modal
|
|
120
121
|
style="display: none;"
|
|
121
|
-
id="
|
|
122
|
-
modal-
|
|
123
|
-
modal-title="{{infoModal.title}}"
|
|
122
|
+
id="permissions-modal"
|
|
123
|
+
modal-title="Permissions"
|
|
124
124
|
close-button-title="Close"
|
|
125
|
+
close-button
|
|
126
|
+
body-overflow-unset
|
|
125
127
|
>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
<div class="loader hidden">
|
|
129
|
+
<crowdin-progress-indicator></crowdin-progress-indicator>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="permissions-modal-content">
|
|
132
|
+
<div class="select-users-block">
|
|
133
|
+
<crowdin-users-select
|
|
134
|
+
allow-new-options
|
|
135
|
+
is-multi
|
|
136
|
+
is-searchable
|
|
137
|
+
id="users"
|
|
138
|
+
key="users"
|
|
139
|
+
label="Users"
|
|
140
|
+
help-text="Search for members by name, username, email, or invite new ones using their email."
|
|
141
|
+
is-position-fixed
|
|
142
|
+
onchange="inviteUsers()"
|
|
143
|
+
>
|
|
144
|
+
</crowdin-select>
|
|
145
|
+
</div>
|
|
146
|
+
<div class="select-users-info">
|
|
147
|
+
<div class="confirm-users-block mt-2 hidden">
|
|
148
|
+
<table>
|
|
149
|
+
<thead>
|
|
150
|
+
<tr>
|
|
151
|
+
<th style="width: 40%;">Permission Type (Upcoming changes)</th>
|
|
152
|
+
<th style="width: 35%;">Users</th>
|
|
153
|
+
<th class="status" style="width: 20%;">Status</th>
|
|
154
|
+
</tr>
|
|
155
|
+
</thead>
|
|
156
|
+
<tbody>
|
|
157
|
+
{{#if hasOrganization}}
|
|
158
|
+
<tr class="organization-invite">
|
|
159
|
+
<td>
|
|
160
|
+
<crowdin-p>Registration in Organization</crowdin-p>
|
|
161
|
+
</td>
|
|
162
|
+
<td class="affected-users"></td>
|
|
163
|
+
<td class="status"></td>
|
|
164
|
+
</tr>
|
|
165
|
+
{{/if}}
|
|
166
|
+
<tr class="project-invite">
|
|
167
|
+
<td>
|
|
168
|
+
<crowdin-p>Project Manager Access</crowdin-p>
|
|
169
|
+
</td>
|
|
170
|
+
<td class="affected-users"></td>
|
|
171
|
+
<td class="status"></td>
|
|
172
|
+
</tr>
|
|
173
|
+
<tr class="application-settings-invite">
|
|
174
|
+
<td>
|
|
175
|
+
<crowdin-p>Application Access</crowdin-p>
|
|
176
|
+
<div class="permission-description">{{name}} installation settings will be updated.</div>
|
|
177
|
+
</td>
|
|
178
|
+
<td class="affected-users"></td>
|
|
179
|
+
<td class="status"></td>
|
|
180
|
+
</tr>
|
|
181
|
+
<tr class="application-credentials-invite">
|
|
182
|
+
<td>
|
|
183
|
+
<crowdin-p>Access to the Integration</crowdin-p>
|
|
184
|
+
<div class="permission-description">{{name}} settings will be updated.</div>
|
|
185
|
+
</td>
|
|
186
|
+
<td class="affected-users"></td>
|
|
187
|
+
<td class="status"></td>
|
|
188
|
+
</tr>
|
|
189
|
+
</tbody>
|
|
190
|
+
</table>
|
|
191
|
+
</div>
|
|
192
|
+
{{#if zenModeUrl}}
|
|
193
|
+
<div class="mt-2">
|
|
194
|
+
<crowdin-input
|
|
195
|
+
with-fixed-height
|
|
196
|
+
label="Zen Mode link"
|
|
197
|
+
help-text="This focused view allows you to concentrate solely on the Integrations section, eliminating distractions and providing a streamlined experience for managing your project integrations."
|
|
198
|
+
value="{{zenModeUrl}}"
|
|
199
|
+
name="zenModeLink"
|
|
200
|
+
with-copy-button
|
|
201
|
+
></crowdin-input>
|
|
202
|
+
</div>
|
|
203
|
+
{{/if}}
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div slot="footer">
|
|
208
|
+
<crowdin-button id="confirm-users-btn" outlined onclick="inviteUsers(false)">Save</crowdin-button>
|
|
209
|
+
</div>
|
|
129
210
|
</crowdin-modal>
|
|
211
|
+
|
|
212
|
+
{{#if infoModal}}
|
|
213
|
+
<crowdin-modal
|
|
214
|
+
style="display: none;"
|
|
215
|
+
id="info-modal"
|
|
216
|
+
modal-width="50"
|
|
217
|
+
modal-title="{{infoModal.title}}"
|
|
218
|
+
close-button-title="Close"
|
|
219
|
+
>
|
|
220
|
+
<div>
|
|
221
|
+
{{{infoModal.content}}}
|
|
222
|
+
</div>
|
|
223
|
+
</crowdin-modal>
|
|
130
224
|
{{/if}}
|
|
225
|
+
|
|
131
226
|
{{#if configurationFields}}
|
|
132
227
|
<crowdin-modal
|
|
133
228
|
style="display: none;"
|
|
@@ -785,7 +880,7 @@
|
|
|
785
880
|
}
|
|
786
881
|
|
|
787
882
|
function saveSettings() {
|
|
788
|
-
setLoader();
|
|
883
|
+
setLoader('#settings-modal');
|
|
789
884
|
const settingsElements = Array.from(document.getElementById('modal-content').children);
|
|
790
885
|
const tags = ['crowdin-checkbox', 'crowdin-select', 'crowdin-input'];
|
|
791
886
|
const configReq = {};
|
|
@@ -820,7 +915,7 @@
|
|
|
820
915
|
})
|
|
821
916
|
.catch(e => catchRejection(e, 'Can\'t save settings'))
|
|
822
917
|
.finally(() => {
|
|
823
|
-
unsetLoader();
|
|
918
|
+
unsetLoader('#settings-modal');
|
|
824
919
|
settingsSaveBtn.removeAttribute('disabled');
|
|
825
920
|
closeModal(settingsModal);
|
|
826
921
|
{{#if reloadOnConfigSave}}
|
|
@@ -830,13 +925,174 @@
|
|
|
830
925
|
});
|
|
831
926
|
}
|
|
832
927
|
|
|
833
|
-
function
|
|
834
|
-
const
|
|
928
|
+
function showConfirmUsersBlock() {
|
|
929
|
+
const confirmUsersBlock = document.querySelector('.confirm-users-block');
|
|
930
|
+
confirmUsersBlock.classList.remove('hidden');
|
|
931
|
+
|
|
932
|
+
const permissionsModal = document.getElementById('permissions-modal');
|
|
933
|
+
permissionsModal.removeAttribute('body-overflow-unset')
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
function hideConfirmUsersBlock() {
|
|
937
|
+
const confirmUsersBlock = document.querySelector('.confirm-users-block');
|
|
938
|
+
confirmUsersBlock.classList.add('hidden');
|
|
939
|
+
|
|
940
|
+
const permissionsModal = document.getElementById('permissions-modal');
|
|
941
|
+
permissionsModal.setAttribute('body-overflow-unset', true)
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
function showPermissionsDialog() {
|
|
945
|
+
hideConfirmUsersBlock();
|
|
946
|
+
openModal(permissions)
|
|
947
|
+
setLoader('#permissions-modal');
|
|
948
|
+
const select = document.getElementById('users');
|
|
949
|
+
|
|
950
|
+
select.value = '[]';
|
|
951
|
+
|
|
952
|
+
checkOrigin()
|
|
953
|
+
.then(restParams => fetch('api/users' + restParams))
|
|
954
|
+
.then(checkResponse)
|
|
955
|
+
.then((res) => {
|
|
956
|
+
console.log(res)
|
|
957
|
+
let userOptions = res.data.users.map(user => `<option value="${user.id}">${user.name}</option>`).join('');
|
|
958
|
+
select.innerHTML = userOptions;
|
|
959
|
+
select.value = JSON.stringify(res.data.managers);
|
|
960
|
+
})
|
|
961
|
+
.catch(e => catchRejection(e, 'Can\'t fetch users'))
|
|
962
|
+
.finally(() => unsetLoader('#permissions-modal'));
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
async function inviteUsers(onlyCheck = true) {
|
|
966
|
+
setLoader('#permissions-modal');
|
|
967
|
+
|
|
968
|
+
const select = document.getElementById('users');
|
|
969
|
+
|
|
970
|
+
if (onlyCheck && select.value === '[]') {
|
|
971
|
+
hideConfirmUsersBlock();
|
|
972
|
+
unsetLoader('#permissions-modal');
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
const params = {
|
|
977
|
+
users: JSON.parse(select.value),
|
|
978
|
+
onlyCheck,
|
|
979
|
+
};
|
|
980
|
+
|
|
981
|
+
checkOrigin()
|
|
982
|
+
.then(restParams => fetch('api/invite-users' + restParams, {
|
|
983
|
+
method: 'POST',
|
|
984
|
+
headers: { 'Content-Type': 'application/json' },
|
|
985
|
+
body: JSON.stringify(params)
|
|
986
|
+
}))
|
|
987
|
+
.then(checkResponse)
|
|
988
|
+
.then((response) => {
|
|
989
|
+
if (!onlyCheck) {
|
|
990
|
+
showToast('Users successfully updated');
|
|
991
|
+
hideConfirmUsersBlock();
|
|
992
|
+
closeModal(permissions);
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
prepareUsersConfirmBlock(response.data);
|
|
997
|
+
})
|
|
998
|
+
.catch(e => {
|
|
999
|
+
catchRejection(e, e?.error || 'Can\'t invite users')
|
|
1000
|
+
})
|
|
1001
|
+
.finally(() => unsetLoader('#permissions-modal'));
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
function prepareUsersConfirmBlock(usersData) {
|
|
1005
|
+
showConfirmUsersBlock();
|
|
1006
|
+
|
|
1007
|
+
const organizationInvite = document.querySelector('.organization-invite');
|
|
1008
|
+
const projectInvite = document.querySelector('.project-invite');
|
|
1009
|
+
const applicationCredentialsInvite = document.querySelector('.application-credentials-invite');
|
|
1010
|
+
|
|
1011
|
+
const grantedElement = '<span class="badge badge-granted">Available</span>';
|
|
1012
|
+
const willGrantedElement = '<span class="badge badge-will-be-granted">Will Be Granted</span>';
|
|
1013
|
+
const notAvailableElement = '<span class="badge badge-not-available">Manual Action Required</span>';
|
|
1014
|
+
|
|
1015
|
+
// only in enterprise
|
|
1016
|
+
if (organizationInvite) {
|
|
1017
|
+
const organizationWillGrantElement = '<span class="badge badge-will-be-granted">Will be registered</span>';
|
|
1018
|
+
|
|
1019
|
+
processUsersWhoWillBeInvited(organizationInvite, usersData.usersWhoWillBeInvitedToOrganization, organizationWillGrantElement, grantedElement);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
processUsersWhoWillBeInvited(projectInvite, usersData.usersWhoWillBeInvitedToProject, willGrantedElement, grantedElement);
|
|
1023
|
+
processUsersWhoWillBeInvited(applicationCredentialsInvite, usersData.usersWhoNotIssetInIntegration, willGrantedElement, grantedElement);
|
|
1024
|
+
|
|
1025
|
+
processUsersWhoWillBeInvitedApplicationSettings(usersData, willGrantedElement, grantedElement, notAvailableElement);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
function processUsersWhoWillBeInvited(element, users, grantMessage, alreadyGrantedMessage) {
|
|
1029
|
+
const tooltip = element.querySelector('.status');
|
|
1030
|
+
const userList = element.querySelector('.affected-users');
|
|
1031
|
+
|
|
1032
|
+
if (users.length) {
|
|
1033
|
+
tooltip.innerHTML = grantMessage;
|
|
1034
|
+
|
|
1035
|
+
let affectedUsers = '<ul>';
|
|
1036
|
+
for (const user of users) {
|
|
1037
|
+
affectedUsers += `<li><crowdin-p>${user.name}</crowdin-p></li>`;
|
|
1038
|
+
}
|
|
1039
|
+
affectedUsers += '</ul>';
|
|
1040
|
+
userList.innerHTML = affectedUsers;
|
|
1041
|
+
} else {
|
|
1042
|
+
tooltip.innerHTML = alreadyGrantedMessage;
|
|
1043
|
+
userList.innerHTML = '<crowdin-p>―</crowdin-p>';
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
function processUsersWhoWillBeInvitedApplicationSettings(usersData, willGrantedElement, grantedElement, notAvailableElement) {
|
|
1048
|
+
const applicationSettingsInvite = document.querySelector('.application-settings-invite');
|
|
1049
|
+
|
|
1050
|
+
const tooltip = applicationSettingsInvite.querySelector('.status');
|
|
1051
|
+
const userList = applicationSettingsInvite.querySelector('.affected-users');
|
|
1052
|
+
|
|
1053
|
+
let affectedUsers = '<ul>';
|
|
1054
|
+
|
|
1055
|
+
if (!usersData.editApplicationAvailable) {
|
|
1056
|
+
tooltip.innerHTML = `<crowdin-tooltip
|
|
1057
|
+
position="left"
|
|
1058
|
+
tooltip=">The application doesn't have permission to update this setting.">
|
|
1059
|
+
${notAvailableElement}
|
|
1060
|
+
</crowdin-tooltip>`;
|
|
1061
|
+
for (const user of usersData.usersWhoNotIssetInApplicationInstallation) {
|
|
1062
|
+
affectedUsers += `<li><crowdin-p>${user.name}</crowdin-p></li>`;
|
|
1063
|
+
}
|
|
1064
|
+
userList.innerHTML = affectedUsers + '</ul>';
|
|
1065
|
+
} else if (!usersData.usersWhoNotIssetInApplicationInstallation.length) {
|
|
1066
|
+
tooltip.innerHTML = grantedElement;
|
|
1067
|
+
userList.innerHTML = '<crowdin-p>―</crowdin-p>';
|
|
1068
|
+
} else {
|
|
1069
|
+
if (usersData.isAdmin) {
|
|
1070
|
+
tooltip.innerHTML = willGrantedElement;
|
|
1071
|
+
for (const user of usersData.usersWhoNotIssetInApplicationInstallation) {
|
|
1072
|
+
affectedUsers += `<li><crowdin-p>${user.name}</crowdin-p></li>`;
|
|
1073
|
+
}
|
|
1074
|
+
userList.innerHTML = affectedUsers + '</ul>';
|
|
1075
|
+
} else {
|
|
1076
|
+
tooltip.innerHTML = `<crowdin-tooltip
|
|
1077
|
+
position="left"
|
|
1078
|
+
tooltip="Only organization admins have permission to update this setting.">
|
|
1079
|
+
${notAvailableElement}
|
|
1080
|
+
</crowdin-tooltip>`;
|
|
1081
|
+
for (const user of usersData.usersWhoNotIssetInApplicationInstallation) {
|
|
1082
|
+
affectedUsers += `<li><crowdin-p>${user.name}</crowdin-p></li>`;
|
|
1083
|
+
}
|
|
1084
|
+
userList.innerHTML = affectedUsers + '</ul>';
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
function setLoader(id) {
|
|
1090
|
+
const loader = document.querySelector(`${id} .loader`);
|
|
835
1091
|
loader.classList.remove('hidden');
|
|
836
1092
|
}
|
|
837
1093
|
|
|
838
|
-
function unsetLoader() {
|
|
839
|
-
const loader = document.querySelector(
|
|
1094
|
+
function unsetLoader(id) {
|
|
1095
|
+
const loader = document.querySelector(`${id} .loader`);
|
|
840
1096
|
setTimeout(function() {
|
|
841
1097
|
loader.classList.add('hidden');
|
|
842
1098
|
}, 500)
|
|
@@ -845,6 +1101,8 @@
|
|
|
845
1101
|
const settingsModal = undefined;
|
|
846
1102
|
{{/if}}
|
|
847
1103
|
|
|
1104
|
+
const permissions = document.getElementById('permissions-modal');
|
|
1105
|
+
|
|
848
1106
|
{{#if infoModal}}
|
|
849
1107
|
const infoModal = document.getElementById('info-modal');
|
|
850
1108
|
{{else}}
|
|
@@ -853,7 +1111,9 @@
|
|
|
853
1111
|
|
|
854
1112
|
document.addEventListener('keydown', (event) => {
|
|
855
1113
|
if (event.keyCode == 27) {
|
|
856
|
-
|
|
1114
|
+
if (users) {
|
|
1115
|
+
closeModal(permissions);
|
|
1116
|
+
}
|
|
857
1117
|
if (infoModal) {
|
|
858
1118
|
closeModal(infoModal);
|
|
859
1119
|
}
|
package/package.json
CHANGED