@crowdin/app-project-module 0.73.0 → 0.73.2
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
/// <reference types="qs" />
|
|
2
2
|
import { Response } from 'express';
|
|
3
|
-
|
|
3
|
+
import { Config } from '../../../types';
|
|
4
|
+
export default function handle(config: Config): (req: import("../../../types").CrowdinClientRequest | import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -12,6 +12,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const types_1 = require("../util/types");
|
|
13
13
|
const util_1 = require("../../../util");
|
|
14
14
|
const storage_1 = require("../../../storage");
|
|
15
|
+
const cron_1 = require("../util/cron");
|
|
16
|
+
const defaults_1 = require("../util/defaults");
|
|
17
|
+
const connection_1 = require("../../../util/connection");
|
|
18
|
+
const MINUTES = 60;
|
|
15
19
|
function getHumanETA(ms) {
|
|
16
20
|
const seconds = Math.floor(ms / 1000);
|
|
17
21
|
let minutes = Math.floor(seconds / 60);
|
|
@@ -29,7 +33,7 @@ function getHumanETA(ms) {
|
|
|
29
33
|
}
|
|
30
34
|
return `About ${timeParts.join(' and ')} remaining`;
|
|
31
35
|
}
|
|
32
|
-
function handle() {
|
|
36
|
+
function handle(config) {
|
|
33
37
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
34
38
|
const id = req.query.job_id || req.body.job_id;
|
|
35
39
|
if (!id) {
|
|
@@ -47,6 +51,37 @@ function handle() {
|
|
|
47
51
|
job.eta = ((Date.now() - job.createdAt) / job.progress) * (100 - job.progress);
|
|
48
52
|
job.info = getHumanETA(job.eta) + (job.info ? `\n${job.info}` : '');
|
|
49
53
|
}
|
|
54
|
+
if (job && (job === null || job === void 0 ? void 0 : job.updatedAt) && Date.now() - job.updatedAt >= MINUTES * 60 * 1000) {
|
|
55
|
+
const context = req.crowdinContext;
|
|
56
|
+
const projectId = context.jwtPayload.context.project_id;
|
|
57
|
+
const integration = config.projectIntegration;
|
|
58
|
+
const crowdinId = req.crowdinContext.crowdinId;
|
|
59
|
+
const integrationId = req.crowdinContext.clientId;
|
|
60
|
+
const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(integrationId);
|
|
61
|
+
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
62
|
+
const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(integrationId);
|
|
63
|
+
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config)
|
|
64
|
+
? JSON.parse(integrationConfig.config)
|
|
65
|
+
: { schedule: '0', condition: '0' };
|
|
66
|
+
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
|
|
67
|
+
req.logInfo(`Restarting the job after no updates for more than ${MINUTES} minutes.`);
|
|
68
|
+
return (0, cron_1.runUpdateProviderJob)({
|
|
69
|
+
integrationId,
|
|
70
|
+
crowdinId,
|
|
71
|
+
type: job.type,
|
|
72
|
+
title: job.title,
|
|
73
|
+
payload: JSON.parse(job.payload),
|
|
74
|
+
jobType: types_1.JobClientType.RERUN,
|
|
75
|
+
projectId,
|
|
76
|
+
client: req.crowdinApiClient,
|
|
77
|
+
integration,
|
|
78
|
+
context,
|
|
79
|
+
credentials,
|
|
80
|
+
rootFolder,
|
|
81
|
+
appSettings: intConfig,
|
|
82
|
+
reRunJobId: id,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
50
85
|
req.logInfo(`Returning job info ${JSON.stringify(job, null, 2)}`);
|
|
51
86
|
res.send(job);
|
|
52
87
|
}));
|
|
@@ -93,7 +93,7 @@ function register({ config, app }) {
|
|
|
93
93
|
optional: false,
|
|
94
94
|
checkSubscriptionExpiration: true,
|
|
95
95
|
moduleKey: integrationLogic.key,
|
|
96
|
-
}), (0, job_info_1.default)());
|
|
96
|
+
}), (0, job_info_1.default)(config));
|
|
97
97
|
app.delete('/api/jobs', json_response_1.default, (0, crowdin_client_1.default)({
|
|
98
98
|
config,
|
|
99
99
|
optional: false,
|
|
@@ -323,16 +323,20 @@ th {
|
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
.badge-will-be-granted {
|
|
326
|
-
background-color: var(--crowdin-
|
|
327
|
-
color: var(--crowdin-
|
|
326
|
+
background-color: var(--crowdin-info);
|
|
327
|
+
color: var(--crowdin-white);
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
.badge-not-available {
|
|
331
|
-
background-color: var(--crowdin-
|
|
332
|
-
color: var(--crowdin-
|
|
331
|
+
background-color: var(--crowdin-warning-bg);
|
|
332
|
+
color: var(--crowdin-warning);
|
|
333
333
|
}
|
|
334
334
|
|
|
335
335
|
.status {
|
|
336
336
|
position: relative;
|
|
337
337
|
text-align: right;
|
|
338
338
|
}
|
|
339
|
+
|
|
340
|
+
.text-warning {
|
|
341
|
+
color: var(--crowdin-warning) !important;
|
|
342
|
+
}
|
|
@@ -36,7 +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="
|
|
39
|
+
<crowdin-button icon-before="link" onclick="showPermissionsDialog()">Share</crowdin-button>
|
|
40
40
|
{{#if infoModal}}
|
|
41
41
|
<crowdin-button icon-before="info" onclick="openModal(infoModal);">{{infoModal.title}}</crowdin-button>
|
|
42
42
|
{{/if}}
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
<crowdin-modal
|
|
121
121
|
style="display: none;"
|
|
122
122
|
id="permissions-modal"
|
|
123
|
-
modal-title="
|
|
123
|
+
modal-title="Share"
|
|
124
124
|
close-button-title="Close"
|
|
125
125
|
close-button
|
|
126
126
|
body-overflow-unset
|
|
@@ -148,9 +148,9 @@
|
|
|
148
148
|
<table>
|
|
149
149
|
<thead>
|
|
150
150
|
<tr>
|
|
151
|
-
<th style="width: 40%;">
|
|
151
|
+
<th style="width: 40%;">Access</th>
|
|
152
152
|
<th style="width: 35%;">Users</th>
|
|
153
|
-
<th class="status" style="width: 20%;">
|
|
153
|
+
<th class="status" style="width: 20%;">Upcoming changes</th>
|
|
154
154
|
</tr>
|
|
155
155
|
</thead>
|
|
156
156
|
<tbody>
|
|
@@ -172,8 +172,8 @@
|
|
|
172
172
|
</tr>
|
|
173
173
|
<tr class="application-settings-invite">
|
|
174
174
|
<td>
|
|
175
|
-
<crowdin-p>Application Access</crowdin-p>
|
|
176
|
-
<div class="permission-description"
|
|
175
|
+
<crowdin-p>Application Visibility Access</crowdin-p>
|
|
176
|
+
<div class="permission-description"></div>
|
|
177
177
|
</td>
|
|
178
178
|
<td class="affected-users"></td>
|
|
179
179
|
<td class="status"></td>
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
<tr class="application-credentials-invite">
|
|
182
182
|
<td>
|
|
183
183
|
<crowdin-p>Access to the Integration</crowdin-p>
|
|
184
|
-
<div class="permission-description">
|
|
184
|
+
<div class="permission-description">This provides access to sync files and modify the current integration settings.</div>
|
|
185
185
|
</td>
|
|
186
186
|
<td class="affected-users"></td>
|
|
187
187
|
<td class="status"></td>
|
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
<crowdin-input
|
|
195
195
|
with-fixed-height
|
|
196
196
|
label="Zen Mode link"
|
|
197
|
-
help-text="This focused view allows you to concentrate solely on the Integrations section, eliminating distractions
|
|
197
|
+
help-text="This focused view allows you to concentrate solely on the Integrations section, eliminating other distractions."
|
|
198
198
|
value="{{zenModeUrl}}"
|
|
199
199
|
name="zenModeLink"
|
|
200
200
|
with-copy-button
|
|
@@ -953,7 +953,6 @@
|
|
|
953
953
|
.then(restParams => fetch('api/users' + restParams))
|
|
954
954
|
.then(checkResponse)
|
|
955
955
|
.then((res) => {
|
|
956
|
-
console.log(res)
|
|
957
956
|
let userOptions = res.data.users.map(user => `<option value="${user.id}">${user.name}</option>`).join('');
|
|
958
957
|
select.innerHTML = userOptions;
|
|
959
958
|
select.value = JSON.stringify(res.data.managers);
|
|
@@ -1008,13 +1007,13 @@
|
|
|
1008
1007
|
const projectInvite = document.querySelector('.project-invite');
|
|
1009
1008
|
const applicationCredentialsInvite = document.querySelector('.application-credentials-invite');
|
|
1010
1009
|
|
|
1011
|
-
const grantedElement = '<
|
|
1010
|
+
const grantedElement = '<crowdin-p>―</crowdin-p>';
|
|
1012
1011
|
const willGrantedElement = '<span class="badge badge-will-be-granted">Will Be Granted</span>';
|
|
1013
|
-
const notAvailableElement = '<span class="badge badge-not-available">
|
|
1012
|
+
const notAvailableElement = '<span class="badge badge-not-available">Action Required</span>';
|
|
1014
1013
|
|
|
1015
1014
|
// only in enterprise
|
|
1016
1015
|
if (organizationInvite) {
|
|
1017
|
-
|
|
1016
|
+
const organizationWillGrantElement = `<span class="badge badge-will-be-granted">Will Be Registered</span>`;
|
|
1018
1017
|
|
|
1019
1018
|
processUsersWhoWillBeInvited(organizationInvite, usersData.usersWhoWillBeInvitedToOrganization, organizationWillGrantElement, grantedElement);
|
|
1020
1019
|
}
|
|
@@ -1040,7 +1039,7 @@
|
|
|
1040
1039
|
userList.innerHTML = affectedUsers;
|
|
1041
1040
|
} else {
|
|
1042
1041
|
tooltip.innerHTML = alreadyGrantedMessage;
|
|
1043
|
-
userList.innerHTML =
|
|
1042
|
+
userList.innerHTML = alreadyGrantedMessage;
|
|
1044
1043
|
}
|
|
1045
1044
|
}
|
|
1046
1045
|
|
|
@@ -1048,23 +1047,30 @@
|
|
|
1048
1047
|
const applicationSettingsInvite = document.querySelector('.application-settings-invite');
|
|
1049
1048
|
|
|
1050
1049
|
const tooltip = applicationSettingsInvite.querySelector('.status');
|
|
1050
|
+
const description = applicationSettingsInvite.querySelector('.permission-description');
|
|
1051
1051
|
const userList = applicationSettingsInvite.querySelector('.affected-users');
|
|
1052
1052
|
|
|
1053
|
+
let descriptionMessage = 'This can be configured in organization settings (Apps section).';
|
|
1054
|
+
description.classList.remove('text-warning');
|
|
1055
|
+
description.innerText = descriptionMessage;
|
|
1056
|
+
|
|
1053
1057
|
let affectedUsers = '<ul>';
|
|
1054
1058
|
|
|
1055
1059
|
if (!usersData.editApplicationAvailable) {
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1060
|
+
descriptionMessage += ' The application doesn\'t have permission to update this setting.';
|
|
1061
|
+
descriptionMessage += usersData.isAdmin ? ' Please reinstall the app.' : ' Please ask the organization admin to reinstall the app.';
|
|
1062
|
+
|
|
1063
|
+
description.classList.add('text-warning');
|
|
1064
|
+
description.innerText = descriptionMessage;
|
|
1065
|
+
|
|
1066
|
+
tooltip.innerHTML = notAvailableElement;
|
|
1061
1067
|
for (const user of usersData.usersWhoNotIssetInApplicationInstallation) {
|
|
1062
1068
|
affectedUsers += `<li><crowdin-p>${user.name}</crowdin-p></li>`;
|
|
1063
1069
|
}
|
|
1064
1070
|
userList.innerHTML = affectedUsers + '</ul>';
|
|
1065
1071
|
} else if (!usersData.usersWhoNotIssetInApplicationInstallation.length) {
|
|
1066
1072
|
tooltip.innerHTML = grantedElement;
|
|
1067
|
-
userList.innerHTML =
|
|
1073
|
+
userList.innerHTML = grantedElement;
|
|
1068
1074
|
} else {
|
|
1069
1075
|
if (usersData.isAdmin) {
|
|
1070
1076
|
tooltip.innerHTML = willGrantedElement;
|
|
@@ -1073,11 +1079,12 @@
|
|
|
1073
1079
|
}
|
|
1074
1080
|
userList.innerHTML = affectedUsers + '</ul>';
|
|
1075
1081
|
} else {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1082
|
+
descriptionMessage += ' Only organization admins have permission to update this setting.';
|
|
1083
|
+
|
|
1084
|
+
description.classList.add('text-warning');
|
|
1085
|
+
description.innerText = descriptionMessage;
|
|
1086
|
+
|
|
1087
|
+
tooltip.innerHTML = notAvailableElement;
|
|
1081
1088
|
for (const user of usersData.usersWhoNotIssetInApplicationInstallation) {
|
|
1082
1089
|
affectedUsers += `<li><crowdin-p>${user.name}</crowdin-p></li>`;
|
|
1083
1090
|
}
|
package/package.json
CHANGED