@crowdin/app-project-module 0.17.6 → 0.17.8

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 (79) hide show
  1. package/README.md +5 -9
  2. package/out/handlers/crowdin-file-progress.d.ts +4 -0
  3. package/out/handlers/crowdin-file-progress.js +22 -0
  4. package/out/handlers/crowdin-files.d.ts +4 -0
  5. package/out/handlers/crowdin-files.js +31 -0
  6. package/out/handlers/crowdin-project.d.ts +4 -0
  7. package/out/handlers/crowdin-project.js +22 -0
  8. package/out/handlers/crowdin-update.d.ts +4 -0
  9. package/out/handlers/crowdin-update.js +26 -0
  10. package/out/handlers/custom-file-format/download.d.ts +4 -0
  11. package/out/handlers/custom-file-format/download.js +32 -0
  12. package/out/handlers/custom-file-format/process.d.ts +4 -0
  13. package/out/handlers/custom-file-format/process.js +139 -0
  14. package/out/handlers/custom-mt/translate.d.ts +4 -0
  15. package/out/handlers/custom-mt/translate.js +42 -0
  16. package/out/handlers/install.d.ts +4 -0
  17. package/out/handlers/install.js +46 -0
  18. package/out/handlers/integration-data.d.ts +4 -0
  19. package/out/handlers/integration-data.js +21 -0
  20. package/out/handlers/integration-login.d.ts +4 -0
  21. package/out/handlers/integration-login.js +30 -0
  22. package/out/handlers/integration-logout.d.ts +4 -0
  23. package/out/handlers/integration-logout.js +23 -0
  24. package/out/handlers/integration-update.d.ts +4 -0
  25. package/out/handlers/integration-update.js +25 -0
  26. package/out/handlers/main.d.ts +4 -0
  27. package/out/handlers/main.js +64 -0
  28. package/out/handlers/manifest.d.ts +3 -0
  29. package/out/handlers/manifest.js +126 -0
  30. package/out/handlers/oauth-login.d.ts +4 -0
  31. package/out/handlers/oauth-login.js +69 -0
  32. package/out/handlers/settings-save.d.ts +4 -0
  33. package/out/handlers/settings-save.js +21 -0
  34. package/out/handlers/subscription-info.d.ts +3 -0
  35. package/out/handlers/subscription-info.js +15 -0
  36. package/out/handlers/subscription-paid.d.ts +4 -0
  37. package/out/handlers/subscription-paid.js +22 -0
  38. package/out/handlers/sync-settings-save.d.ts +4 -0
  39. package/out/handlers/sync-settings-save.js +29 -0
  40. package/out/handlers/sync-settings.d.ts +4 -0
  41. package/out/handlers/sync-settings.js +27 -0
  42. package/out/handlers/uninstall.d.ts +4 -0
  43. package/out/handlers/uninstall.js +27 -0
  44. package/out/index.d.ts +5 -0
  45. package/out/index.js +191 -0
  46. package/out/logo.png +0 -0
  47. package/out/middlewares/crowdin-client.d.ts +10 -0
  48. package/out/middlewares/crowdin-client.js +88 -0
  49. package/out/middlewares/integration-credentials.d.ts +4 -0
  50. package/out/middlewares/integration-credentials.js +39 -0
  51. package/out/middlewares/json-response.d.ts +2 -0
  52. package/out/middlewares/json-response.js +7 -0
  53. package/out/middlewares/ui-module.d.ts +4 -0
  54. package/out/middlewares/ui-module.js +39 -0
  55. package/out/models/index.d.ts +549 -0
  56. package/out/models/index.js +41 -0
  57. package/out/static/css/styles.css +57 -0
  58. package/out/static/js/main.js +130 -0
  59. package/out/static/js/polyfills/fetch.js +494 -0
  60. package/out/static/js/polyfills/promise.js +375 -0
  61. package/out/storage/index.d.ts +22 -0
  62. package/out/storage/index.js +319 -0
  63. package/out/util/connection.d.ts +10 -0
  64. package/out/util/connection.js +217 -0
  65. package/out/util/cron.d.ts +3 -0
  66. package/out/util/cron.js +103 -0
  67. package/out/util/defaults.d.ts +5 -0
  68. package/out/util/defaults.js +153 -0
  69. package/out/util/index.d.ts +11 -0
  70. package/out/util/index.js +105 -0
  71. package/out/views/install.handlebars +16 -0
  72. package/out/views/login.handlebars +115 -0
  73. package/out/views/main.handlebars +471 -0
  74. package/out/views/oauth.handlebars +4 -0
  75. package/out/views/partials/head.handlebars +20 -0
  76. package/out/views/subscription.handlebars +26 -0
  77. package/package.json +2 -2
  78. package/.github/workflows/basic.yml +0 -39
  79. package/.github/workflows/publish.yml +0 -34
@@ -0,0 +1,549 @@
1
+ import Crowdin, { LanguagesModel, SourceFilesModel, SourceStringsModel } from '@crowdin/crowdin-api-client';
2
+ import { JwtPayload } from '@crowdin/crowdin-apps-functions';
3
+ import { Request } from 'express';
4
+ export interface Config extends ImagePath {
5
+ /**
6
+ * client id that we received when registering the app
7
+ */
8
+ clientId: string;
9
+ /**
10
+ * client secret that we received when registering the app
11
+ */
12
+ clientSecret: string;
13
+ /**
14
+ * Secret to encrypt/decrypt credentials (by default @clientSecret will be used)
15
+ */
16
+ cryptoSecret?: string;
17
+ /**
18
+ * https url where an app is reachable from the internet (e.g. the one that ngrok generates for us)
19
+ */
20
+ baseUrl: string;
21
+ /**
22
+ * define custom Crowdin urls (e.g. to work against local Crowdin server)
23
+ */
24
+ crowdinUrls?: CrowdinUrls;
25
+ /**
26
+ * Set of scopes requested by this app (default 'project')
27
+ */
28
+ scopes?: Scope[];
29
+ /**
30
+ * app name
31
+ */
32
+ name: string;
33
+ /**
34
+ * app identifier
35
+ */
36
+ identifier: string;
37
+ /**
38
+ * app description
39
+ */
40
+ description: string;
41
+ /**
42
+ * port where to start express application
43
+ */
44
+ port?: number;
45
+ /**
46
+ * folder where module will create sqlite db file to persist credentials (e.g. {@example __dirname})
47
+ */
48
+ dbFolder: string;
49
+ /**
50
+ * integration module logic
51
+ */
52
+ projectIntegration?: IntegrationLogic & ImagePath;
53
+ /**
54
+ * custom file format module logic
55
+ */
56
+ customFileFormat?: CustomFileFormatLogic;
57
+ /**
58
+ * custom MT module logic
59
+ */
60
+ customMT?: CustomMTLogic;
61
+ /**
62
+ * resources module
63
+ */
64
+ profileResourcesMenu?: UiModule & ImagePath;
65
+ /**
66
+ * organization-menu module
67
+ */
68
+ organizationMenu?: UiModule & ImagePath;
69
+ /**
70
+ * editor-right-panel module
71
+ */
72
+ editorRightPanel?: EditorPanels;
73
+ /**
74
+ * project menu module
75
+ */
76
+ projectMenu?: UiModule;
77
+ /**
78
+ * tools module
79
+ */
80
+ projectTools?: UiModule & ImagePath;
81
+ /**
82
+ * reports module
83
+ */
84
+ projectReports?: UiModule & ImagePath;
85
+ /**
86
+ * Uninstall hook for cleanup logic
87
+ */
88
+ onUninstall?: (organization: string) => Promise<void>;
89
+ /**
90
+ * Error interceptor (can be used to log error in centralized place)
91
+ */
92
+ onError?: (error: any) => void;
93
+ /**
94
+ * Configuration to log everything that are happening in the app
95
+ */
96
+ logger?: Logger;
97
+ /**
98
+ * Configuration of app pricing
99
+ */
100
+ pricing?: Pricing;
101
+ }
102
+ export interface CrowdinUrls {
103
+ apiUrl?: string;
104
+ accountUrl?: string;
105
+ subscriptionUrl?: string;
106
+ }
107
+ export declare enum Scope {
108
+ ALL_SCOPES = "all",
109
+ NOTIFICATIONS = "notification",
110
+ TRANSLATION_MEMORIES = "tm",
111
+ MACHINE_TRANSLATION_ENGINES = "mt",
112
+ GLOSSARIES = "glossary",
113
+ PROJECTS = "project",
114
+ TASKS = "project.task",
115
+ REPORTS = "project.report",
116
+ TRANSLATION_STATUS = "project.status",
117
+ SOURCE_FILES_AND_STRINGS = "project.source",
118
+ WEBHOOKS = "project.webhook",
119
+ TRANSLATIONS = "project.translation",
120
+ SCREENSHOTS = "project.screenshot"
121
+ }
122
+ export interface IntegrationLogic {
123
+ /**
124
+ * Customize your app login form
125
+ */
126
+ loginForm: LoginForm;
127
+ /**
128
+ * Define login process via OAuth2 protocol
129
+ */
130
+ oauthLogin?: OAuthLogin;
131
+ /**
132
+ * name of the root folder in Crowdin where files from integration will be stored, default your app name, will be ignored in case if {@link withRootFolder} is false
133
+ */
134
+ appFolderName?: string;
135
+ /**
136
+ * flag that defines if the app should have a dedicated root folder in Crowdin files, default 'false'
137
+ */
138
+ withRootFolder?: boolean;
139
+ /**
140
+ * function which will be used to check connection with integration service
141
+ */
142
+ checkConnection?: (apiCredentials: any) => Promise<void>;
143
+ /**
144
+ * function to get crowdin files that are related with this integration
145
+ */
146
+ getCrowdinFiles?: (projectId: number, client: Crowdin, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<TreeItem[]>;
147
+ /**
148
+ * function to get data from integration
149
+ */
150
+ getIntegrationFiles: (apiCredentials: any, config?: any) => Promise<TreeItem[]>;
151
+ /**
152
+ * function to update crowdin files (e.g. pull integration data to crowdin source files)
153
+ */
154
+ updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void>;
155
+ /**
156
+ * function to update integration content (e.g. load crowdin translations and push them to integration service)
157
+ */
158
+ updateIntegration: (projectId: number, client: Crowdin, apiCredentials: any, request: UpdateIntegrationRequest, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void>;
159
+ /**
160
+ * function to define configuration(settings) modal for you app (by default app will not have any custom settings)
161
+ */
162
+ getConfiguration?: (projectId: number, client: Crowdin, apiCredentials: any) => Promise<ConfigurationModalEntity[]>;
163
+ /**
164
+ * flag to turn on auto reload of the tree whenever user updates the configuration
165
+ */
166
+ reloadOnConfigSave?: boolean;
167
+ /**
168
+ * define info modal (help section) for you app (by default app will not have own info section)
169
+ */
170
+ infoModal?: {
171
+ title: string;
172
+ content: string;
173
+ };
174
+ /**
175
+ * background jobs that will be executed for each crowdin project and user
176
+ */
177
+ cronJobs?: CronJob[];
178
+ withCronSync?: {
179
+ crowdin: boolean;
180
+ integration: boolean;
181
+ };
182
+ withWebhookSync?: {
183
+ crowdin: boolean;
184
+ integration: boolean;
185
+ };
186
+ }
187
+ export declare type ConfigurationModalEntity = ConfigurationField | ConfigurationDelimeter;
188
+ export interface ConfigurationField {
189
+ key: string;
190
+ label: string;
191
+ type: 'text' | 'checkbox' | 'select';
192
+ helpText?: string;
193
+ /**
194
+ * only for select
195
+ */
196
+ isMulti?: boolean;
197
+ /**
198
+ * only for select
199
+ */
200
+ options?: {
201
+ label: string;
202
+ value: string;
203
+ }[];
204
+ }
205
+ export interface ConfigurationDelimeter {
206
+ label: string;
207
+ }
208
+ export interface LoginForm {
209
+ fields: FormField[];
210
+ }
211
+ export interface OAuthLogin {
212
+ /**
213
+ * Authorization url (e.g. https://github.com/login/oauth/authorize or https://accounts.google.com/o/oauth2/v2/auth)
214
+ */
215
+ authorizationUrl: string;
216
+ /**
217
+ * Access token url (e.g. https://github.com/login/oauth/access_token)
218
+ */
219
+ accessTokenUrl: string;
220
+ /**
221
+ * Url to refresh token, default will use {@link accessTokenUrl}. Needed when {@link refresh} is enabled
222
+ */
223
+ refreshTokenUrl?: string;
224
+ /**
225
+ * The scopes of access, usually expressed as a list of space-delimited, case-sensitive strings
226
+ */
227
+ scope?: string;
228
+ /**
229
+ * Client id
230
+ */
231
+ clientId: string;
232
+ /**
233
+ * Client secret
234
+ */
235
+ clientSecret: string;
236
+ /**
237
+ * default '/oauth/code'
238
+ */
239
+ redirectUriRoute?: string;
240
+ /**
241
+ * request/response fields mapping
242
+ */
243
+ fieldsMapping?: {
244
+ /**
245
+ * default 'client_id'
246
+ */
247
+ clientId?: string;
248
+ /**
249
+ * default 'client_secret'
250
+ */
251
+ clientSecret?: string;
252
+ /**
253
+ * default 'scope'
254
+ */
255
+ scope?: string;
256
+ /**
257
+ * default 'redirect_uri'
258
+ */
259
+ redirectUri?: string;
260
+ /**
261
+ * default 'code'
262
+ */
263
+ code: string;
264
+ /**
265
+ * default 'access_token'
266
+ */
267
+ accessToken?: string;
268
+ /**
269
+ * default 'refresh_token'
270
+ */
271
+ refreshToken?: string;
272
+ /**
273
+ * default 'expires_in'
274
+ */
275
+ expiresIn?: string;
276
+ };
277
+ /**
278
+ * default 'false' which means that the access token has no expiration date
279
+ */
280
+ refresh?: boolean;
281
+ /**
282
+ * Additional URL parameters for authorizarion url
283
+ */
284
+ extraAutorizationUrlParameters?: {
285
+ [key: string]: string;
286
+ };
287
+ /**
288
+ * Additional parameters for access token request
289
+ */
290
+ extraAccessTokenParameters?: {
291
+ [key: string]: any;
292
+ };
293
+ /**
294
+ * Additional parameters for refresh token request
295
+ */
296
+ extraRefreshTokenParameters?: {
297
+ [key: string]: any;
298
+ };
299
+ /**
300
+ * Override to implement request for retrieving access token (and refresh token if 'refresh' is enabled)
301
+ */
302
+ performGetTokenRequest?: (code: string) => Promise<any>;
303
+ /**
304
+ * Override to implement request for refreshing token (only if 'refresh' is enabled)
305
+ */
306
+ performRefreshTokenRequest?: (currentCredentials: any) => Promise<any>;
307
+ }
308
+ export interface FormField {
309
+ key: string;
310
+ helpText?: string;
311
+ helpTextHtml?: string;
312
+ label: string;
313
+ type?: 'text' | 'password' | 'checkbox';
314
+ }
315
+ export declare type TreeItem = File | Folder;
316
+ export interface File {
317
+ id: string;
318
+ name: string;
319
+ type: SourceFilesModel.FileType;
320
+ parentId?: string;
321
+ }
322
+ export interface Folder {
323
+ id: string;
324
+ name: string;
325
+ parentId?: string;
326
+ }
327
+ export interface IntegrationRequest extends CrowdinClientRequest {
328
+ integrationCredentials: any;
329
+ integrationSettings?: any;
330
+ }
331
+ export interface CrowdinClientRequest extends Request {
332
+ crowdinApiClient: Crowdin;
333
+ crowdinContext: CrowdinContextInfo;
334
+ subscriptionInfo?: SubscriptionInfo;
335
+ }
336
+ export interface CrowdinCredentials {
337
+ id: string;
338
+ appSecret: string;
339
+ domain?: string;
340
+ userId: number;
341
+ organizationId: number;
342
+ baseUrl: string;
343
+ accessToken: string;
344
+ refreshToken: string;
345
+ expire: string;
346
+ type: AccountType;
347
+ }
348
+ export declare enum AccountType {
349
+ NORMAL = "normal",
350
+ ENTERPRISE = "enterprise"
351
+ }
352
+ export interface CrowdinContextInfo {
353
+ jwtPayload: JwtPayload;
354
+ crowdinId: string;
355
+ clientId: string;
356
+ }
357
+ export declare enum SubscriptionInfoType {
358
+ TRIAL = "trial",
359
+ SUBSCRIPTION = "subscription"
360
+ }
361
+ export interface SubscriptionInfo {
362
+ expired: boolean;
363
+ subscribeLink?: string;
364
+ daysLeft?: number;
365
+ type?: SubscriptionInfoType;
366
+ }
367
+ export interface IntegrationCredentials {
368
+ id: string;
369
+ credentials: any;
370
+ crowdinId: string;
371
+ config?: any;
372
+ }
373
+ export interface IntegrationFile {
374
+ id: string;
375
+ name: string;
376
+ type: SourceFilesModel.FileType;
377
+ parentId: string;
378
+ }
379
+ export interface UpdateIntegrationRequest {
380
+ [fileId: string]: string[];
381
+ }
382
+ export interface CronJob {
383
+ task: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void>;
384
+ expression: string;
385
+ }
386
+ export interface CustomFileFormatLogic {
387
+ /**
388
+ * The type parameter value for a custom file format. Used for a custom format file upload via API.
389
+ */
390
+ type: string;
391
+ /**
392
+ * Folder where larger file will be temporary stored (default "{@link dbFolder}/custom-file-format")
393
+ */
394
+ filesFolder?: string;
395
+ /**
396
+ * This parameter is used to combine the content of multiple languages into one request when uploading and downloading translations in your Crowdin project.
397
+ */
398
+ multilingual?: boolean;
399
+ /**
400
+ * Contains fileName and/or fileContent regular expressions used to detect file type when uploading a new source file via UI (or via API without specified type parameter). If the file matches regular expressions, it's labeled as a custom format file.
401
+ */
402
+ signaturePatterns?: SignaturePatterns;
403
+ /**
404
+ * Flag to automatically upload translations
405
+ */
406
+ autoUploadTranslations?: boolean;
407
+ /**
408
+ * Enable strings export
409
+ */
410
+ stringsExport?: boolean;
411
+ /**
412
+ * File extensions (used for strings export)
413
+ */
414
+ extensions?: string[];
415
+ /**
416
+ * Enable custom srx
417
+ */
418
+ customSrxSupported?: boolean;
419
+ /**
420
+ * Used for initial source file upload, source file update, and translation upload
421
+ */
422
+ parseFile?: (fileContent: string | object, req: Omit<ProcessFileRequest, 'jobType' | 'file'>, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<ParseFileResponse>;
423
+ /**
424
+ * Used for translation download
425
+ */
426
+ buildFile?: (fileContent: string | object, req: Omit<ProcessFileRequest, 'jobType' | 'file'>, strings: ProcessFileString[], client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<BuildFileResponse>;
427
+ /**
428
+ * Used for strings export
429
+ */
430
+ exportStrings?: (req: Omit<ProcessFileRequest, 'jobType'>, strings: ProcessFileString[], client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<BuildFileResponse>;
431
+ }
432
+ export interface SignaturePatterns {
433
+ fileName?: string;
434
+ fileContent?: string;
435
+ }
436
+ export interface ProcessFileRequest {
437
+ jobType: ProcessFileJobType;
438
+ file: ProcessFileRecord;
439
+ sourceLanguage: LanguagesModel.Language;
440
+ targetLanguages: LanguagesModel.Language[];
441
+ strings: ProcessFileString[];
442
+ stringsUrl: string;
443
+ }
444
+ export interface ProcessFileRecord {
445
+ content?: string;
446
+ contentUrl?: string;
447
+ path?: string;
448
+ id?: number;
449
+ name?: string;
450
+ }
451
+ export declare enum ProcessFileJobType {
452
+ PARSE_FILE = "parse-file",
453
+ BUILD_FILE = "build-file"
454
+ }
455
+ export interface ParseFileResponse {
456
+ previewFile?: string;
457
+ strings?: ProcessFileString[];
458
+ error?: string;
459
+ }
460
+ export interface BuildFileResponse {
461
+ contentFile: string;
462
+ error?: string;
463
+ }
464
+ export interface ProcessFileString {
465
+ previewId?: number;
466
+ id: number;
467
+ identifier: string;
468
+ context?: string;
469
+ customData?: string;
470
+ maxLength?: number;
471
+ isHidden?: boolean;
472
+ hasPlurals?: boolean;
473
+ labels?: string[];
474
+ text: string | SourceStringsModel.PluralText;
475
+ translations?: StringTranslations;
476
+ }
477
+ export interface StringTranslations {
478
+ [language: string]: {
479
+ text: string | SourceStringsModel.PluralText;
480
+ };
481
+ }
482
+ export interface CustomMTLogic {
483
+ translate: (client: Crowdin, context: CrowdinContextInfo, projectId: number, source: string, target: string, strings: string[]) => Promise<string[]>;
484
+ validate?: (client: Crowdin) => Promise<void>;
485
+ }
486
+ export interface CustomMTRequest {
487
+ strings: string[];
488
+ }
489
+ export interface UiModule {
490
+ /**
491
+ * path to ui folder (e.g. {@example join(__dirname, 'public')})
492
+ */
493
+ uiPath: string;
494
+ /**
495
+ * page name (default index.html)
496
+ */
497
+ fileName?: string;
498
+ }
499
+ export interface EditorPanels extends UiModule {
500
+ /**
501
+ * The Editor's mode list where the module will be available.
502
+ */
503
+ modes: EditorPanelsMode[];
504
+ }
505
+ export declare enum EditorPanelsMode {
506
+ ASSETS = "assets",
507
+ REVIEW = "review",
508
+ TRANSLATE = "TRANSLATE",
509
+ PROOFREAD = "proofread"
510
+ }
511
+ export interface CrowdinAppUtilities {
512
+ saveMetadata: (id: string, metadata: any) => Promise<void>;
513
+ getMetadata: (id: string) => Promise<any | undefined>;
514
+ deleteMetadata: (id: string) => Promise<void>;
515
+ /**
516
+ * Settings that users manage in the integration module
517
+ */
518
+ getUserSettings: (clientId: string) => Promise<any | undefined>;
519
+ establishCrowdinConnection: (jwtToken: string) => Promise<{
520
+ context: CrowdinContextInfo;
521
+ client?: Crowdin;
522
+ }>;
523
+ }
524
+ export interface IntegrationSyncSettings {
525
+ id: string;
526
+ files?: any;
527
+ integrationId: string;
528
+ crowdinId: string;
529
+ provider: string;
530
+ }
531
+ interface ImagePath {
532
+ /**
533
+ * path to app logo (e.g. {@example join(__dirname, 'logo.png')})
534
+ */
535
+ imagePath?: string;
536
+ }
537
+ export interface Logger {
538
+ enabled: boolean;
539
+ log?: (message: string) => void;
540
+ }
541
+ export interface Pricing {
542
+ planType: 'free' | 'recurring';
543
+ trial?: number;
544
+ trialCrowdin?: number;
545
+ trialEnterprise?: number;
546
+ cachingSeconds?: number;
547
+ infoDisplayDaysThreshold?: number;
548
+ }
549
+ export {};
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EditorPanelsMode = exports.ProcessFileJobType = exports.SubscriptionInfoType = exports.AccountType = exports.Scope = void 0;
4
+ var Scope;
5
+ (function (Scope) {
6
+ Scope["ALL_SCOPES"] = "all";
7
+ Scope["NOTIFICATIONS"] = "notification";
8
+ Scope["TRANSLATION_MEMORIES"] = "tm";
9
+ Scope["MACHINE_TRANSLATION_ENGINES"] = "mt";
10
+ Scope["GLOSSARIES"] = "glossary";
11
+ Scope["PROJECTS"] = "project";
12
+ Scope["TASKS"] = "project.task";
13
+ Scope["REPORTS"] = "project.report";
14
+ Scope["TRANSLATION_STATUS"] = "project.status";
15
+ Scope["SOURCE_FILES_AND_STRINGS"] = "project.source";
16
+ Scope["WEBHOOKS"] = "project.webhook";
17
+ Scope["TRANSLATIONS"] = "project.translation";
18
+ Scope["SCREENSHOTS"] = "project.screenshot";
19
+ })(Scope = exports.Scope || (exports.Scope = {}));
20
+ var AccountType;
21
+ (function (AccountType) {
22
+ AccountType["NORMAL"] = "normal";
23
+ AccountType["ENTERPRISE"] = "enterprise";
24
+ })(AccountType = exports.AccountType || (exports.AccountType = {}));
25
+ var SubscriptionInfoType;
26
+ (function (SubscriptionInfoType) {
27
+ SubscriptionInfoType["TRIAL"] = "trial";
28
+ SubscriptionInfoType["SUBSCRIPTION"] = "subscription";
29
+ })(SubscriptionInfoType = exports.SubscriptionInfoType || (exports.SubscriptionInfoType = {}));
30
+ var ProcessFileJobType;
31
+ (function (ProcessFileJobType) {
32
+ ProcessFileJobType["PARSE_FILE"] = "parse-file";
33
+ ProcessFileJobType["BUILD_FILE"] = "build-file";
34
+ })(ProcessFileJobType = exports.ProcessFileJobType || (exports.ProcessFileJobType = {}));
35
+ var EditorPanelsMode;
36
+ (function (EditorPanelsMode) {
37
+ EditorPanelsMode["ASSETS"] = "assets";
38
+ EditorPanelsMode["REVIEW"] = "review";
39
+ EditorPanelsMode["TRANSLATE"] = "TRANSLATE";
40
+ EditorPanelsMode["PROOFREAD"] = "proofread";
41
+ })(EditorPanelsMode = exports.EditorPanelsMode || (exports.EditorPanelsMode = {}));
@@ -0,0 +1,57 @@
1
+ .i_w {
2
+ padding: 16px 24px;
3
+ max-width: 1420px;
4
+ margin: 0 auto;
5
+ }
6
+
7
+ .center {
8
+ text-align: center;
9
+ min-height: calc(100vh - 64px);
10
+ display: flex;
11
+ align-items: center;
12
+ justify-content: space-around;
13
+ }
14
+
15
+ .box-center {
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ }
20
+
21
+ .top {
22
+ text-align: right;
23
+ margin-bottom: 10px;
24
+ }
25
+
26
+ .login {
27
+ margin-bottom: 10px;
28
+ }
29
+
30
+ .login img {
31
+ max-width: 70px;
32
+ max-height: 70px;
33
+ width: auto;
34
+ height: auto;
35
+ }
36
+
37
+ .login crowdin-input {
38
+ margin-bottom: 8px;
39
+ display: block;
40
+ }
41
+
42
+ .login .inputs {
43
+ margin-bottom: 24px;
44
+ text-align: left;
45
+ }
46
+
47
+ .login crowdin-h4 {
48
+ margin: 8px 0 16px;
49
+ }
50
+
51
+ .ml-1 {
52
+ margin-left: 8px;
53
+ }
54
+
55
+ .m-0 {
56
+ margin: 0;
57
+ }