@duplicati/ngclient 0.0.1 → 0.0.6

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 (197) hide show
  1. package/chunk-22HCWJS5.js +1 -0
  2. package/chunk-24PLBY6C.js +1 -0
  3. package/chunk-3MM4GLBS.js +1 -0
  4. package/chunk-3MTW6FJP.js +1 -0
  5. package/chunk-4FK75Z4C.js +1 -0
  6. package/chunk-4MMHXTNF.js +1 -0
  7. package/chunk-57M4MADC.js +1 -0
  8. package/chunk-6XUWDRDE.js +1 -0
  9. package/chunk-77NTMJCT.js +1 -0
  10. package/chunk-7X6SBNMU.js +1 -0
  11. package/chunk-A66Z6362.js +1 -0
  12. package/chunk-AC6VDRLC.js +1 -0
  13. package/chunk-BNNZKRIC.js +1 -0
  14. package/chunk-CKPPU3GS.js +2 -0
  15. package/chunk-DYANEO5K.js +1 -0
  16. package/chunk-GJTW7UUU.js +1 -0
  17. package/chunk-GMANGOGH.js +1 -0
  18. package/chunk-I6QIKK6M.js +1 -0
  19. package/chunk-IOWSWUHM.js +1 -0
  20. package/chunk-IQSBPGVL.js +1 -0
  21. package/chunk-L47VTK2X.js +1 -0
  22. package/chunk-LVLU6MPQ.js +1 -0
  23. package/chunk-N5US3SKW.js +1 -0
  24. package/chunk-NIMPOFJV.js +1 -0
  25. package/chunk-ORDBF5MR.js +8 -0
  26. package/chunk-PH6AAOK4.js +1 -0
  27. package/chunk-PY5HJ5U2.js +1 -0
  28. package/chunk-QQDSFTZV.js +1 -0
  29. package/chunk-RANWFSNY.js +1 -0
  30. package/chunk-RLJJFBQ2.js +1 -0
  31. package/chunk-S76TN27U.js +1 -0
  32. package/chunk-UTPCUNNU.js +1 -0
  33. package/chunk-VPEVWKGB.js +1 -0
  34. package/chunk-VVUYO7E4.js +1 -0
  35. package/chunk-WLI4RZYL.js +1 -0
  36. package/chunk-X2NZ4CJ5.js +2 -0
  37. package/chunk-XU7PNEZO.js +1 -0
  38. package/chunk-XYJYUMYL.js +1 -0
  39. package/chunk-YRXI477O.js +1 -0
  40. package/chunk-ZD3JEKWI.js +1 -0
  41. package/index.html +15 -0
  42. package/main-5KJRELCN.js +1 -0
  43. package/package.json +3 -40
  44. package/sparkle-ui-assets/fonts/InterTight-VariableFont_wght.ttf +0 -0
  45. package/sparkle-ui-assets/fonts/InterTight-VariableFont_wght.woff2 +0 -0
  46. package/styles-6W7ZCKNM.css +1 -0
  47. package/.dockerignore +0 -13
  48. package/.github/workflows/npm-publish.yml +0 -59
  49. package/.prettierignore +0 -13
  50. package/.prettierrc +0 -12
  51. package/.vscode/extensions.json +0 -4
  52. package/.vscode/launch.json +0 -13
  53. package/.vscode/settings.json +0 -8
  54. package/.vscode/tasks.json +0 -24
  55. package/Dockerfile +0 -38
  56. package/LICENSE +0 -21
  57. package/README.md +0 -27
  58. package/angular.json +0 -98
  59. package/bun.lockb +0 -0
  60. package/openapi-ts.config.ts +0 -13
  61. package/scripts/generate-package-json.ts +0 -15
  62. package/src/app/about/about.component.html +0 -15
  63. package/src/app/about/about.component.scss +0 -19
  64. package/src/app/about/about.component.ts +0 -13
  65. package/src/app/about/changelog/changelog.component.html +0 -3
  66. package/src/app/about/changelog/changelog.component.scss +0 -7
  67. package/src/app/about/changelog/changelog.component.ts +0 -18
  68. package/src/app/about/general/general.component.html +0 -9
  69. package/src/app/about/general/general.component.scss +0 -23
  70. package/src/app/about/general/general.component.ts +0 -30
  71. package/src/app/about/libraries/libraries.component.html +0 -3
  72. package/src/app/about/libraries/libraries.component.scss +0 -7
  73. package/src/app/about/libraries/libraries.component.ts +0 -18
  74. package/src/app/about/logs/logs.component.html +0 -5
  75. package/src/app/about/logs/logs.component.scss +0 -7
  76. package/src/app/about/logs/logs.component.ts +0 -18
  77. package/src/app/about/system-info/system-info.component.html +0 -3
  78. package/src/app/about/system-info/system-info.component.scss +0 -7
  79. package/src/app/about/system-info/system-info.component.ts +0 -17
  80. package/src/app/add-backup/add-backup.component.html +0 -29
  81. package/src/app/add-backup/add-backup.component.scss +0 -38
  82. package/src/app/add-backup/add-backup.component.ts +0 -14
  83. package/src/app/app.component.ts +0 -35
  84. package/src/app/app.config.ts +0 -23
  85. package/src/app/app.routes.ts +0 -121
  86. package/src/app/core/components/file-tree/file-tree.component.html +0 -87
  87. package/src/app/core/components/file-tree/file-tree.component.scss +0 -80
  88. package/src/app/core/components/file-tree/file-tree.component.ts +0 -485
  89. package/src/app/core/components/logo/logo.component.html +0 -22
  90. package/src/app/core/components/logo/logo.component.scss +0 -12
  91. package/src/app/core/components/logo/logo.component.ts +0 -11
  92. package/src/app/core/components/status-bar/status-bar.component.html +0 -38
  93. package/src/app/core/components/status-bar/status-bar.component.scss +0 -27
  94. package/src/app/core/components/status-bar/status-bar.component.ts +0 -33
  95. package/src/app/core/components/status-bar/status-bar.state.ts +0 -182
  96. package/src/app/core/components/toggle-card/toggle-card.component.html +0 -11
  97. package/src/app/core/components/toggle-card/toggle-card.component.scss +0 -49
  98. package/src/app/core/components/toggle-card/toggle-card.component.ts +0 -28
  99. package/src/app/core/interceptors/http.interceptor.ts +0 -69
  100. package/src/app/core/interceptors/websocket.interceptor.ts +0 -66
  101. package/src/app/core/openapi/core/ApiError.ts +0 -21
  102. package/src/app/core/openapi/core/ApiRequestOptions.ts +0 -21
  103. package/src/app/core/openapi/core/ApiResult.ts +0 -7
  104. package/src/app/core/openapi/core/OpenAPI.ts +0 -55
  105. package/src/app/core/openapi/core/request.ts +0 -337
  106. package/src/app/core/openapi/index.ts +0 -6
  107. package/src/app/core/openapi/schemas.gen.ts +0 -3611
  108. package/src/app/core/openapi/services.gen.ts +0 -1460
  109. package/src/app/core/openapi/types.gen.ts +0 -1510
  110. package/src/app/core/pipes/duration.pipe.ts +0 -27
  111. package/src/app/core/pipes/relative-time.pipe.ts +0 -14
  112. package/src/app/core/providers/dayjs.ts +0 -16
  113. package/src/app/core/services/dict.en.ts +0 -0
  114. package/src/app/core/services/dictionary.service.ts +0 -12
  115. package/src/app/core/services/localstorage.token.ts +0 -82
  116. package/src/app/core/services/password-generator.service.ts +0 -39
  117. package/src/app/core/services/relay-websocket.service.ts +0 -268
  118. package/src/app/core/services/timespan-literals.service.ts +0 -25
  119. package/src/app/core/states/app-auth.state.ts +0 -87
  120. package/src/app/core/states/backups.state.ts +0 -71
  121. package/src/app/core/states/relayconfig.state.ts +0 -23
  122. package/src/app/core/states/sysinfo.state.ts +0 -31
  123. package/src/app/core/states/tasks.state.ts +0 -34
  124. package/src/app/core/types/subscribed.ts +0 -7
  125. package/src/app/core/validators/custom.validators.ts +0 -120
  126. package/src/app/create-edit-backup/create-edit-backup.component.html +0 -28
  127. package/src/app/create-edit-backup/create-edit-backup.component.scss +0 -15
  128. package/src/app/create-edit-backup/create-edit-backup.component.ts +0 -33
  129. package/src/app/create-edit-backup/create-edit-backup.state.ts +0 -582
  130. package/src/app/create-edit-backup/destination/destination.component.html +0 -367
  131. package/src/app/create-edit-backup/destination/destination.component.scss +0 -85
  132. package/src/app/create-edit-backup/destination/destination.component.ts +0 -249
  133. package/src/app/create-edit-backup/destination/destination.config.ts +0 -103
  134. package/src/app/create-edit-backup/destination/destination.mapper.ts +0 -177
  135. package/src/app/create-edit-backup/general/general.component.html +0 -108
  136. package/src/app/create-edit-backup/general/general.component.scss +0 -34
  137. package/src/app/create-edit-backup/general/general.component.ts +0 -136
  138. package/src/app/create-edit-backup/options/options.component.html +0 -95
  139. package/src/app/create-edit-backup/options/options.component.scss +0 -42
  140. package/src/app/create-edit-backup/options/options.component.ts +0 -113
  141. package/src/app/create-edit-backup/schedule/schedule.component.html +0 -102
  142. package/src/app/create-edit-backup/schedule/schedule.component.scss +0 -38
  143. package/src/app/create-edit-backup/schedule/schedule.component.ts +0 -137
  144. package/src/app/create-edit-backup/source-data/source-data.component.html +0 -93
  145. package/src/app/create-edit-backup/source-data/source-data.component.scss +0 -41
  146. package/src/app/create-edit-backup/source-data/source-data.component.ts +0 -114
  147. package/src/app/home/backup.const.ts +0 -167
  148. package/src/app/home/home.component.html +0 -98
  149. package/src/app/home/home.component.scss +0 -88
  150. package/src/app/home/home.component.ts +0 -54
  151. package/src/app/layout/layout.component.html +0 -64
  152. package/src/app/layout/layout.component.scss +0 -24
  153. package/src/app/layout/layout.component.ts +0 -51
  154. package/src/app/layout/layout.state.ts +0 -70
  155. package/src/app/login/login.component.html +0 -12
  156. package/src/app/login/login.component.scss +0 -25
  157. package/src/app/login/login.component.ts +0 -34
  158. package/src/app/logout/logout.component.html +0 -1
  159. package/src/app/logout/logout.component.scss +0 -3
  160. package/src/app/logout/logout.component.ts +0 -18
  161. package/src/app/restore/restore.component.html +0 -56
  162. package/src/app/restore/restore.component.scss +0 -37
  163. package/src/app/restore/restore.component.ts +0 -55
  164. package/src/app/restore-flow/options/options.component.html +0 -57
  165. package/src/app/restore-flow/options/options.component.scss +0 -16
  166. package/src/app/restore-flow/options/options.component.ts +0 -58
  167. package/src/app/restore-flow/restore-flow.component.html +0 -14
  168. package/src/app/restore-flow/restore-flow.component.scss +0 -15
  169. package/src/app/restore-flow/restore-flow.component.ts +0 -23
  170. package/src/app/restore-flow/restore-flow.state.ts +0 -120
  171. package/src/app/restore-flow/select-files/select-files.component.html +0 -42
  172. package/src/app/restore-flow/select-files/select-files.component.scss +0 -16
  173. package/src/app/restore-flow/select-files/select-files.component.ts +0 -129
  174. package/src/app/settings/settings.component.html +0 -256
  175. package/src/app/settings/settings.component.scss +0 -106
  176. package/src/app/settings/settings.component.ts +0 -475
  177. package/src/environments/environment-token.ts +0 -4
  178. package/src/environments/environment.prod.ts +0 -6
  179. package/src/environments/environment.ts +0 -6
  180. package/src/index.html +0 -15
  181. package/src/main.ts +0 -6
  182. package/src/proxy.conf.mjs +0 -6
  183. package/src/styles.scss +0 -41
  184. package/tsconfig.app.json +0 -15
  185. package/tsconfig.json +0 -30
  186. /package/{src/assets → assets}/duplicati-logo.png +0 -0
  187. /package/{src/assets → assets}/duplicati-logo.svg +0 -0
  188. /package/{src/assets → assets}/favicon.ico +0 -0
  189. /package/{src/assets → assets}/images/backup.png +0 -0
  190. /package/{src/assets → assets}/images/dark-theme.png +0 -0
  191. /package/{src/assets → assets}/images/folder.png +0 -0
  192. /package/{src/assets → assets}/images/light-theme.png +0 -0
  193. /package/{src/assets → assets}/images/new-backup.png +0 -0
  194. /package/{src/assets → assets}/images/restore.png +0 -0
  195. /package/{src/assets → assets}/images/system-theme.png +0 -0
  196. /package/{src/assets → assets}/spk.css +0 -0
  197. /package/{src/assets → assets}/spk.woff2 +0 -0
@@ -1,582 +0,0 @@
1
- import { computed, inject, Injectable, signal } from '@angular/core';
2
- import { toSignal } from '@angular/core/rxjs-interop';
3
- import { FormArray, FormBuilder, Validators } from '@angular/forms';
4
- import { Router } from '@angular/router';
5
- import { finalize, take } from 'rxjs';
6
- import {
7
- ArgumentType,
8
- BackupAndScheduleInputDto,
9
- BackupDto,
10
- DuplicatiServerService,
11
- IDynamicModule,
12
- ScheduleDto,
13
- } from '../core/openapi';
14
- import { TimespanLiteralsService } from '../core/services/timespan-literals.service';
15
- import { SysinfoState } from '../core/states/sysinfo.state';
16
- import { createDestinationForm, createDestinationFormGroup, Size } from './destination/destination.component';
17
- import { DESTINATION_CONFIG, FormView } from './destination/destination.config';
18
- import { DestinationFormGroup, fromTargetPath, toTargetPath } from './destination/destination.mapper';
19
- import { createGeneralForm, NONE_OPTION } from './general/general.component';
20
- import { createAdvancedOption, createOptionsForm } from './options/options.component';
21
- import { createScheduleForm, Days, ScheduleFormValue } from './schedule/schedule.component';
22
- import { createSourceDataForm } from './source-data/source-data.component';
23
-
24
- const fb = new FormBuilder();
25
-
26
- export type DestinationFormPair = {
27
- oauthField: string | null;
28
- custom: FormView[];
29
- dynamic: FormView[];
30
- advanced: FormView[];
31
- };
32
-
33
- type DestinationDefault = {
34
- custom: {
35
- [key: string]: any;
36
- };
37
- dynamic: {
38
- [key: string]: any;
39
- };
40
- advanced: {
41
- [key: string]: any;
42
- };
43
- };
44
-
45
- @Injectable({
46
- providedIn: 'root',
47
- })
48
- export class CreateEditBackupState {
49
- #router = inject(Router);
50
- #sysinfo = inject(SysinfoState);
51
- #dupServer = inject(DuplicatiServerService);
52
- #timespanLiteralService = inject(TimespanLiteralsService);
53
- destinationOptions = this.#sysinfo.backendModules;
54
-
55
- backupId = signal<'new' | 'string' | null>(null);
56
- isSubmitting = signal(false);
57
- loadingBackup = signal(false);
58
- loadingDefaults = signal(true);
59
- destinationIsLoaded = signal(false);
60
- isNew = computed(() => this.backupId() === 'new');
61
- backupDefaults = signal<any>(null);
62
- generalForm = createGeneralForm();
63
- sourceDataForm = createSourceDataForm();
64
- scheduleForm = createScheduleForm();
65
- destinationForm = createDestinationForm();
66
- optionsForm = createOptionsForm();
67
-
68
- selectedAdvancedFormPair = signal<FormView[]>([]);
69
- notSelectedAdvancedFormPair = signal<FormView[]>([]);
70
- destinationFormPair = signal<DestinationFormPair>({
71
- oauthField: null,
72
- custom: [],
73
- dynamic: [],
74
- advanced: [],
75
- });
76
- sourceDataFormSignal = toSignal(this.sourceDataForm.valueChanges);
77
- destinationFormSignal = toSignal(this.destinationForm.valueChanges);
78
- encryptionFieldSignal = toSignal(this.generalForm.controls.encryption.valueChanges);
79
- scheduleFormSignal = toSignal(this.scheduleForm.valueChanges);
80
- encryptionOptions = computed(() => {
81
- const encryptionOptions = this.#sysinfo.systemInfo()?.EncryptionModules ?? [];
82
- return [NONE_OPTION, ...encryptionOptions];
83
- });
84
-
85
- init(id: 'new' | 'string' = 'new') {
86
- this.backupId.set(id);
87
-
88
- if (id !== 'new') {
89
- this.getBackup(id);
90
- } else {
91
- this.getDefaults();
92
- }
93
- }
94
-
95
- submit() {
96
- // TODOS
97
- // - Create/update backup
98
- this.isSubmitting.set(true);
99
-
100
- const backup = this.#mapFormsToBackup();
101
- const backupId = this.backupId();
102
-
103
- if (backupId === 'new' || !backupId) {
104
- this.#dupServer
105
- .postApiV1Backups({
106
- requestBody: backup,
107
- })
108
- .pipe(finalize(() => this.isSubmitting.set(false)))
109
- .subscribe({
110
- next: (res) => {
111
- console.log('submitted res', res);
112
-
113
- this.exit();
114
- },
115
- error: (err) => {
116
- console.error('submitted error', err);
117
- },
118
- });
119
- } else {
120
- // TODO
121
- // - Add ID to backup
122
- // - Update backup
123
- //
124
- this.#dupServer
125
- .putApiV1BackupById({
126
- id: backupId,
127
- requestBody: backup,
128
- })
129
- .pipe(finalize(() => this.isSubmitting.set(false)))
130
- .subscribe({
131
- next: (res) => {
132
- console.log('submitted res', res);
133
-
134
- this.exit();
135
- },
136
- error: (err) => {
137
- console.error('submitted error', err);
138
- },
139
- });
140
- }
141
- }
142
-
143
- exit() {
144
- // TODOS
145
- // - Are you sure dialog
146
- this.#resetAllForms();
147
- this.#router.navigate(['/']);
148
- }
149
-
150
- getDefaults() {
151
- this.loadingDefaults.set(true);
152
-
153
- this.#dupServer
154
- .getApiV1Backupdefaults()
155
- .pipe(
156
- take(1),
157
- finalize(() => this.loadingDefaults.set(false))
158
- )
159
- .subscribe({
160
- next: (res: any) => {
161
- this.#mapScheduleToForm(res.Schedule);
162
- this.#mapOptionsToForms(res.Backup);
163
- this.backupDefaults.set(res);
164
- this.destinationIsLoaded.set(true);
165
- },
166
- });
167
- }
168
-
169
- getBackup(id: string) {
170
- this.loadingBackup.set(true);
171
-
172
- this.#dupServer
173
- .getApiV1BackupById({
174
- id,
175
- })
176
- .pipe(finalize(() => this.loadingBackup.set(false)))
177
- .subscribe({
178
- next: (res) => {
179
- this.#mapScheduleToForm(res.Schedule ?? null);
180
-
181
- if (res.Backup) {
182
- this.#mapGeneralToForm(res.Backup);
183
- this.#mapDestinationToForm(res.Backup);
184
- this.#mapSourceDataToForm(res.Backup);
185
- this.#mapOptionsToForms(res.Backup);
186
- }
187
-
188
- this.destinationIsLoaded.set(true);
189
- },
190
- });
191
- }
192
-
193
- #mapSourceDataToForm(backup: BackupDto) {
194
- const path = backup.Sources ?? '';
195
- const filters = backup.Filters?.map((x) => `${x.Include ? '' : '-'}${x.Expression}`) ?? [];
196
- const excludes = backup.Settings?.find((x) => x.Name === '--exclude-files-attributes')?.Value ?? '';
197
- const filesLargerThan = backup.Settings?.find((x) => x.Name === '--skip-files-larger-than') ?? null;
198
-
199
- const withNoDigits = (filesLargerThan?.Value!.replace(/[0-9]/g, '') as Size) ?? null;
200
- const onlyDigits = filesLargerThan?.Value!.replace(/[^0-9]/g, '') ?? null;
201
-
202
- const sourceObj = {
203
- path: [...path, ...filters].join('\0'),
204
- excludes: {
205
- hiddenFiles: excludes.includes('hidden'),
206
- systemFiles: excludes.includes('system'),
207
- tempFiles: excludes.includes('temporary'),
208
- filesLargerThan:
209
- withNoDigits && onlyDigits
210
- ? {
211
- size: parseInt(onlyDigits),
212
- unit: withNoDigits.toUpperCase(),
213
- }
214
- : null,
215
- },
216
- };
217
-
218
- this.sourceDataForm.patchValue(sourceObj as any);
219
- }
220
-
221
- #mapDestinationToForm(backup: BackupDto) {
222
- const targetUrlData = backup.TargetURL ? fromTargetPath(backup.TargetURL) : null;
223
-
224
- if (targetUrlData) {
225
- this.addDestinationFormGroup(targetUrlData.destinationType, {
226
- custom: targetUrlData.custom,
227
- dynamic: targetUrlData.dynamic,
228
- advanced: targetUrlData.advanced,
229
- });
230
- }
231
- }
232
-
233
- #mapGeneralToForm(backup: BackupDto) {
234
- const encryptionModule = backup.Settings?.find((x) => x.Name === 'encryption-module');
235
- const encryption = encryptionModule?.Value && encryptionModule.Value.length ? encryptionModule.Value : 'none';
236
-
237
- this.generalForm.patchValue({
238
- name: backup.Name ?? '',
239
- description: backup.Description ?? '',
240
- encryption,
241
- });
242
- }
243
-
244
- #mapScheduleToForm(schedule: ScheduleDto | null) {
245
- if (!schedule) {
246
- this.scheduleForm.patchValue({
247
- autoRun: true,
248
- });
249
-
250
- return;
251
- }
252
-
253
- const res = this.#timespanLiteralService.fromString(schedule.Repeat) ?? null;
254
- const nextTime = this.#evaluateTimeString(schedule.Time);
255
-
256
- const patchObj: ScheduleFormValue = {
257
- nextTime,
258
- runAgain: {
259
- repeatValue: res?.value ?? 1,
260
- repeatUnit: res?.unit ?? 'D',
261
- allowedDays: {
262
- mon: schedule.AllowedDays?.includes('mon') ?? false,
263
- tue: schedule.AllowedDays?.includes('tue') ?? false,
264
- wed: schedule.AllowedDays?.includes('wed') ?? false,
265
- thu: schedule.AllowedDays?.includes('thu') ?? false,
266
- fri: schedule.AllowedDays?.includes('fri') ?? false,
267
- sat: schedule.AllowedDays?.includes('sat') ?? false,
268
- sun: schedule.AllowedDays?.includes('sun') ?? false,
269
- },
270
- },
271
- };
272
-
273
- this.scheduleForm.patchValue(patchObj);
274
- }
275
-
276
- #mapOptionsToForms(backup: BackupDto) {
277
- const modulesToIgnore = ['--no-encryption', '--exclude-files-attributes', '--skip-files-larger-than'];
278
- backup.Settings?.forEach((x) => {
279
- if (x.Name === 'encryption-module') {
280
- return this.generalForm.controls.encryption.setValue(x.Value ?? 'None');
281
- }
282
-
283
- if (x.Name && modulesToIgnore.includes(x.Name)) return;
284
-
285
- if (x.Name && x.Value) {
286
- this.optionsForm.controls.advancedOptions.push(createAdvancedOption(x.Name, x.Value));
287
- }
288
- });
289
- }
290
-
291
- mapPub() {
292
- this.#mapFormsToBackup();
293
- }
294
-
295
- #mapFormsToBackup() {
296
- const generalFormValue = this.generalForm.value;
297
- const optionsFormValue = this.optionsForm.value;
298
- const scheduleFormValue = this.scheduleForm.value;
299
- const sourceDataFormValue = this.sourceDataForm.value;
300
- const destinationFormValue = this.destinationForm.value;
301
-
302
- const targetUrl = destinationFormValue.destinations?.length
303
- ? this.#getTargetUrl(this.destinationForm.controls.destinations as any)
304
- : [];
305
-
306
- let scheduleRepeat: string | null = null;
307
-
308
- if (scheduleFormValue.runAgain?.repeatUnit && scheduleFormValue.runAgain?.repeatValue) {
309
- scheduleRepeat = this.#timespanLiteralService.toString(
310
- scheduleFormValue.runAgain.repeatValue,
311
- scheduleFormValue.runAgain.repeatUnit
312
- );
313
- }
314
-
315
- const allowedDays = scheduleFormValue.runAgain?.allowedDays
316
- ? Object.entries(scheduleFormValue.runAgain?.allowedDays)
317
- .filter(([_, status]) => status)
318
- .map(([day, _]) => day as Days)
319
- : [];
320
-
321
- const pathFilters = sourceDataFormValue.path?.split('\0') ?? [];
322
- const advancedOptions =
323
- optionsFormValue.advancedOptions?.map((x) => ({
324
- Name: x.name ?? null,
325
- Value: x.value && x.value.length ? x.value.toString() : null,
326
- })) ?? [];
327
-
328
- const encryption =
329
- generalFormValue.encryption === 'none'
330
- ? {
331
- Name: '--no-encryption',
332
- Value: 'True',
333
- }
334
- : {
335
- Name: 'encryption-module',
336
- Value: generalFormValue.encryption ?? null,
337
- };
338
-
339
- const settings = [encryption, ...advancedOptions.filter((x) => x.Name && x.Value)];
340
- const excludes = Object.entries(sourceDataFormValue.excludes ?? {})
341
- .filter(([key, val]) => val && key !== 'filesLargerThan')
342
- .map(([key]) => key);
343
-
344
- const filesLargerThan = sourceDataFormValue.excludes?.filesLargerThan;
345
-
346
- if (excludes.length) {
347
- settings.push({
348
- Name: '--exclude-files-attributes',
349
- Value: excludes.join(','),
350
- });
351
- }
352
- if (filesLargerThan && filesLargerThan.size !== null && filesLargerThan.unit !== null) {
353
- settings.push({
354
- Name: '--skip-files-larger-than',
355
- Value: `${filesLargerThan.size}${filesLargerThan.unit}`,
356
- });
357
- }
358
-
359
- return <BackupAndScheduleInputDto>{
360
- Backup: {
361
- Name: generalFormValue.name,
362
- Description: generalFormValue.description,
363
- TargetURL: targetUrl[0] ?? null,
364
- Sources: pathFilters.filter((x) => !x.startsWith('-')),
365
- Settings: settings,
366
- Filters: pathFilters
367
- .filter((x) => x.startsWith('-'))
368
- .map((x, index) => ({
369
- Order: index,
370
- Include: false,
371
- Expression: x.slice(1),
372
- })),
373
- },
374
- Schedule: scheduleFormValue.autoRun
375
- ? null
376
- : {
377
- Repeat: scheduleRepeat,
378
- Time: scheduleFormValue.nextTime?.date
379
- ? new Date(
380
- `${scheduleFormValue.nextTime.date}T${scheduleFormValue.nextTime?.time || '00:00:00'}`
381
- ).toISOString()
382
- : null,
383
- AllowedDays: allowedDays,
384
- },
385
- // ExtraOptions: {
386
- // BackupID: this.backupId(),
387
- // Operation: this.backupId() ? 'Update' : 'Create',
388
- // },
389
- };
390
- }
391
-
392
- #getTargetUrl(destinationFormArray: FormArray<DestinationFormGroup>) {
393
- return destinationFormArray.controls.map((control) => {
394
- if (!control.controls['advanced']) return toTargetPath(control.value);
395
-
396
- const dirtyFields = Object.keys(control.controls['advanced'].controls).filter(
397
- (controlName) => control.controls['advanced'].controls[controlName].dirty
398
- );
399
-
400
- return toTargetPath({
401
- ...control.value,
402
- advanced: dirtyFields.reduce((acc, key) => {
403
- // @ts-ignore
404
- acc[key] = control.controls['advanced'].controls[key].value;
405
- return acc;
406
- }, {}),
407
- });
408
- });
409
- }
410
-
411
- #evaluateTimeString(t: string | undefined) {
412
- if (!t || t?.indexOf('T') === -1) {
413
- return {
414
- time: t ?? '13:00',
415
- };
416
- }
417
-
418
- const date = new Date(t);
419
- const newObj: ScheduleFormValue['nextTime'] = {
420
- time: `${('' + date.getHours()).padStart(2, '0')}:${('' + date.getMinutes()).padStart(2, '0')}`,
421
- };
422
-
423
- if (t.indexOf('T') !== -1) {
424
- newObj.date = date.toISOString().split('T')[0];
425
- }
426
-
427
- return newObj;
428
- }
429
-
430
- addDestinationFormGroup(key: IDynamicModule['Key'], defaults?: DestinationDefault) {
431
- const item = this.destinationOptions().find((x) => x.Key === key);
432
-
433
- if (!item || !item.Options) return;
434
-
435
- const destinationConfig = DESTINATION_CONFIG.hasOwnProperty(key as string) && DESTINATION_CONFIG[key as string];
436
- const customFields = destinationConfig && destinationConfig.customFields ? destinationConfig.customFields : {};
437
- const dynamicFields = destinationConfig && destinationConfig.dynamicFields ? destinationConfig.dynamicFields : [];
438
- const advancedFields =
439
- destinationConfig && destinationConfig.advancedFields ? destinationConfig.advancedFields : [];
440
- const oauthField = destinationConfig && destinationConfig.oauthField ? destinationConfig.oauthField : null;
441
-
442
- this.destinationFormPair.set({
443
- oauthField,
444
- custom: [],
445
- dynamic: [],
446
- advanced: [],
447
- });
448
- this.selectedAdvancedFormPair.set([]);
449
-
450
- const customGroup = fb.group({});
451
- const dynamicGroup = fb.group({});
452
- const advancedGroup = fb.group({});
453
-
454
- if (customFields) {
455
- for (key in customFields) {
456
- const { formElement, ...val } = customFields[key];
457
-
458
- customGroup.addControl(key, formElement(defaults?.custom[key]));
459
-
460
- this.destinationFormPair.update((y) => {
461
- y.custom.push(val);
462
-
463
- return y;
464
- });
465
- }
466
- }
467
-
468
- for (let index = 0; index < item.Options.length; index++) {
469
- const element = item.Options[index];
470
-
471
- if (element.Deprecated) continue;
472
-
473
- const isDynamic = dynamicFields.includes(element.Name as string);
474
- const group = isDynamic ? dynamicGroup : advancedGroup;
475
-
476
- this.destinationFormPair.update((y) => {
477
- y[isDynamic ? 'dynamic' : 'advanced'].push({
478
- name: element.Name as string,
479
- type: element.Type as ArgumentType,
480
- shortDescription: element.ShortDescription ?? undefined,
481
- longDescription: element.LongDescription ?? undefined,
482
- options: element.ValidValues,
483
- });
484
-
485
- return y;
486
- });
487
-
488
- const passedDefaultValue = isDynamic
489
- ? defaults?.dynamic[element.Name as string]
490
- : defaults?.advanced[element.Name as string];
491
- const defaultValue = passedDefaultValue ?? element.DefaultValue;
492
-
493
- if (
494
- element.Type === 'String' ||
495
- element.Type === 'Password' ||
496
- element.Type === 'Enumeration' ||
497
- element.Type === 'Path'
498
- ) {
499
- group.addControl(element.Name as string, fb.control(defaultValue));
500
-
501
- continue;
502
- }
503
-
504
- if (element.Type === 'Size') {
505
- const withNoDigits = defaultValue!.replace(/[0-9]/g, '') as Size | undefined;
506
- const onlyDigits = defaultValue!.replace(/[^0-9]/g, '');
507
-
508
- group.addControl(
509
- element.Name as string,
510
- fb.group({
511
- size: fb.control<number>(onlyDigits ? parseInt(onlyDigits) : 50),
512
- unit: fb.control<string>(withNoDigits ? withNoDigits.toUpperCase() : 'MB'),
513
- })
514
- );
515
- }
516
-
517
- if (element.Type === 'Integer') {
518
- group.addControl(element.Name as string, fb.control<number>(defaultValue ? parseInt(defaultValue) : 0));
519
-
520
- continue;
521
- }
522
-
523
- if (element.Type === 'Boolean') {
524
- group.addControl(element.Name as string, fb.control(defaultValue === 'true'));
525
-
526
- continue;
527
- }
528
-
529
- if (element.Type === 'Flags') {
530
- group.addControl(element.Name as string, fb.control<string>(defaultValue ?? ''));
531
-
532
- continue;
533
- }
534
-
535
- if (element.Type === 'Timespan') {
536
- group.addControl(
537
- element.Name as string,
538
- fb.control<string>(defaultValue as string, [Validators.pattern(/([-+]?\d{1,3}[smhDWMY])+/)])
539
- );
540
- }
541
- }
542
-
543
- if (this.destinationForm.controls.destinations.length !== 0) {
544
- this.destinationForm.controls.destinations.removeAt(0);
545
- }
546
-
547
- this.destinationFormPair.update((y) => ({
548
- oauthField: y.oauthField,
549
- custom: y.custom,
550
- dynamic: y.dynamic.sort((a, b) => dynamicFields.indexOf(a.name) - dynamicFields.indexOf(b.name)),
551
- advanced: y.advanced.sort((a, b) => {
552
- const indexA = advancedFields.indexOf(a.name);
553
- const indexB = advancedFields.indexOf(b.name);
554
- if (indexA === -1 && indexB !== -1) {
555
- return 1; // Move `a` to the back
556
- } else if (indexA !== -1 && indexB === -1) {
557
- return -1; // Move `b` to the back
558
- }
559
-
560
- return indexA - indexB;
561
- }),
562
- }));
563
-
564
- this.notSelectedAdvancedFormPair.set(this.destinationFormPair().advanced);
565
- this.destinationForm.controls.destinations.push(
566
- createDestinationFormGroup({
567
- key: item.Key as string,
568
- customGroup,
569
- dynamicGroup,
570
- advancedGroup,
571
- })
572
- );
573
- }
574
-
575
- #resetAllForms() {
576
- this.generalForm.reset();
577
- this.sourceDataForm.reset();
578
- this.scheduleForm.reset();
579
- this.destinationForm.reset();
580
- this.optionsForm.reset();
581
- }
582
- }