@duplicati/ngclient 0.0.1

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 (152) hide show
  1. package/.dockerignore +13 -0
  2. package/.github/workflows/npm-publish.yml +59 -0
  3. package/.prettierignore +13 -0
  4. package/.prettierrc +12 -0
  5. package/.vscode/extensions.json +4 -0
  6. package/.vscode/launch.json +13 -0
  7. package/.vscode/settings.json +8 -0
  8. package/.vscode/tasks.json +24 -0
  9. package/Dockerfile +38 -0
  10. package/LICENSE +21 -0
  11. package/README.md +27 -0
  12. package/angular.json +98 -0
  13. package/bun.lockb +0 -0
  14. package/openapi-ts.config.ts +13 -0
  15. package/package.json +46 -0
  16. package/scripts/generate-package-json.ts +15 -0
  17. package/src/app/about/about.component.html +15 -0
  18. package/src/app/about/about.component.scss +19 -0
  19. package/src/app/about/about.component.ts +13 -0
  20. package/src/app/about/changelog/changelog.component.html +3 -0
  21. package/src/app/about/changelog/changelog.component.scss +7 -0
  22. package/src/app/about/changelog/changelog.component.ts +18 -0
  23. package/src/app/about/general/general.component.html +9 -0
  24. package/src/app/about/general/general.component.scss +23 -0
  25. package/src/app/about/general/general.component.ts +30 -0
  26. package/src/app/about/libraries/libraries.component.html +3 -0
  27. package/src/app/about/libraries/libraries.component.scss +7 -0
  28. package/src/app/about/libraries/libraries.component.ts +18 -0
  29. package/src/app/about/logs/logs.component.html +5 -0
  30. package/src/app/about/logs/logs.component.scss +7 -0
  31. package/src/app/about/logs/logs.component.ts +18 -0
  32. package/src/app/about/system-info/system-info.component.html +3 -0
  33. package/src/app/about/system-info/system-info.component.scss +7 -0
  34. package/src/app/about/system-info/system-info.component.ts +17 -0
  35. package/src/app/add-backup/add-backup.component.html +29 -0
  36. package/src/app/add-backup/add-backup.component.scss +38 -0
  37. package/src/app/add-backup/add-backup.component.ts +14 -0
  38. package/src/app/app.component.ts +35 -0
  39. package/src/app/app.config.ts +23 -0
  40. package/src/app/app.routes.ts +121 -0
  41. package/src/app/core/components/file-tree/file-tree.component.html +87 -0
  42. package/src/app/core/components/file-tree/file-tree.component.scss +80 -0
  43. package/src/app/core/components/file-tree/file-tree.component.ts +485 -0
  44. package/src/app/core/components/logo/logo.component.html +22 -0
  45. package/src/app/core/components/logo/logo.component.scss +12 -0
  46. package/src/app/core/components/logo/logo.component.ts +11 -0
  47. package/src/app/core/components/status-bar/status-bar.component.html +38 -0
  48. package/src/app/core/components/status-bar/status-bar.component.scss +27 -0
  49. package/src/app/core/components/status-bar/status-bar.component.ts +33 -0
  50. package/src/app/core/components/status-bar/status-bar.state.ts +182 -0
  51. package/src/app/core/components/toggle-card/toggle-card.component.html +11 -0
  52. package/src/app/core/components/toggle-card/toggle-card.component.scss +49 -0
  53. package/src/app/core/components/toggle-card/toggle-card.component.ts +28 -0
  54. package/src/app/core/interceptors/http.interceptor.ts +69 -0
  55. package/src/app/core/interceptors/websocket.interceptor.ts +66 -0
  56. package/src/app/core/openapi/core/ApiError.ts +21 -0
  57. package/src/app/core/openapi/core/ApiRequestOptions.ts +21 -0
  58. package/src/app/core/openapi/core/ApiResult.ts +7 -0
  59. package/src/app/core/openapi/core/OpenAPI.ts +55 -0
  60. package/src/app/core/openapi/core/request.ts +337 -0
  61. package/src/app/core/openapi/index.ts +6 -0
  62. package/src/app/core/openapi/schemas.gen.ts +3611 -0
  63. package/src/app/core/openapi/services.gen.ts +1460 -0
  64. package/src/app/core/openapi/types.gen.ts +1510 -0
  65. package/src/app/core/pipes/duration.pipe.ts +27 -0
  66. package/src/app/core/pipes/relative-time.pipe.ts +14 -0
  67. package/src/app/core/providers/dayjs.ts +16 -0
  68. package/src/app/core/services/dict.en.ts +0 -0
  69. package/src/app/core/services/dictionary.service.ts +12 -0
  70. package/src/app/core/services/localstorage.token.ts +82 -0
  71. package/src/app/core/services/password-generator.service.ts +39 -0
  72. package/src/app/core/services/relay-websocket.service.ts +268 -0
  73. package/src/app/core/services/timespan-literals.service.ts +25 -0
  74. package/src/app/core/states/app-auth.state.ts +87 -0
  75. package/src/app/core/states/backups.state.ts +71 -0
  76. package/src/app/core/states/relayconfig.state.ts +23 -0
  77. package/src/app/core/states/sysinfo.state.ts +31 -0
  78. package/src/app/core/states/tasks.state.ts +34 -0
  79. package/src/app/core/types/subscribed.ts +7 -0
  80. package/src/app/core/validators/custom.validators.ts +120 -0
  81. package/src/app/create-edit-backup/create-edit-backup.component.html +28 -0
  82. package/src/app/create-edit-backup/create-edit-backup.component.scss +15 -0
  83. package/src/app/create-edit-backup/create-edit-backup.component.ts +33 -0
  84. package/src/app/create-edit-backup/create-edit-backup.state.ts +582 -0
  85. package/src/app/create-edit-backup/destination/destination.component.html +367 -0
  86. package/src/app/create-edit-backup/destination/destination.component.scss +85 -0
  87. package/src/app/create-edit-backup/destination/destination.component.ts +249 -0
  88. package/src/app/create-edit-backup/destination/destination.config.ts +103 -0
  89. package/src/app/create-edit-backup/destination/destination.mapper.ts +177 -0
  90. package/src/app/create-edit-backup/general/general.component.html +108 -0
  91. package/src/app/create-edit-backup/general/general.component.scss +34 -0
  92. package/src/app/create-edit-backup/general/general.component.ts +136 -0
  93. package/src/app/create-edit-backup/options/options.component.html +95 -0
  94. package/src/app/create-edit-backup/options/options.component.scss +42 -0
  95. package/src/app/create-edit-backup/options/options.component.ts +113 -0
  96. package/src/app/create-edit-backup/schedule/schedule.component.html +102 -0
  97. package/src/app/create-edit-backup/schedule/schedule.component.scss +38 -0
  98. package/src/app/create-edit-backup/schedule/schedule.component.ts +137 -0
  99. package/src/app/create-edit-backup/source-data/source-data.component.html +93 -0
  100. package/src/app/create-edit-backup/source-data/source-data.component.scss +41 -0
  101. package/src/app/create-edit-backup/source-data/source-data.component.ts +114 -0
  102. package/src/app/home/backup.const.ts +167 -0
  103. package/src/app/home/home.component.html +98 -0
  104. package/src/app/home/home.component.scss +88 -0
  105. package/src/app/home/home.component.ts +54 -0
  106. package/src/app/layout/layout.component.html +64 -0
  107. package/src/app/layout/layout.component.scss +24 -0
  108. package/src/app/layout/layout.component.ts +51 -0
  109. package/src/app/layout/layout.state.ts +70 -0
  110. package/src/app/login/login.component.html +12 -0
  111. package/src/app/login/login.component.scss +25 -0
  112. package/src/app/login/login.component.ts +34 -0
  113. package/src/app/logout/logout.component.html +1 -0
  114. package/src/app/logout/logout.component.scss +3 -0
  115. package/src/app/logout/logout.component.ts +18 -0
  116. package/src/app/restore/restore.component.html +56 -0
  117. package/src/app/restore/restore.component.scss +37 -0
  118. package/src/app/restore/restore.component.ts +55 -0
  119. package/src/app/restore-flow/options/options.component.html +57 -0
  120. package/src/app/restore-flow/options/options.component.scss +16 -0
  121. package/src/app/restore-flow/options/options.component.ts +58 -0
  122. package/src/app/restore-flow/restore-flow.component.html +14 -0
  123. package/src/app/restore-flow/restore-flow.component.scss +15 -0
  124. package/src/app/restore-flow/restore-flow.component.ts +23 -0
  125. package/src/app/restore-flow/restore-flow.state.ts +120 -0
  126. package/src/app/restore-flow/select-files/select-files.component.html +42 -0
  127. package/src/app/restore-flow/select-files/select-files.component.scss +16 -0
  128. package/src/app/restore-flow/select-files/select-files.component.ts +129 -0
  129. package/src/app/settings/settings.component.html +256 -0
  130. package/src/app/settings/settings.component.scss +106 -0
  131. package/src/app/settings/settings.component.ts +475 -0
  132. package/src/assets/duplicati-logo.png +0 -0
  133. package/src/assets/duplicati-logo.svg +10 -0
  134. package/src/assets/favicon.ico +0 -0
  135. package/src/assets/images/backup.png +0 -0
  136. package/src/assets/images/dark-theme.png +0 -0
  137. package/src/assets/images/folder.png +0 -0
  138. package/src/assets/images/light-theme.png +0 -0
  139. package/src/assets/images/new-backup.png +0 -0
  140. package/src/assets/images/restore.png +0 -0
  141. package/src/assets/images/system-theme.png +0 -0
  142. package/src/assets/spk.css +33 -0
  143. package/src/assets/spk.woff2 +0 -0
  144. package/src/environments/environment-token.ts +4 -0
  145. package/src/environments/environment.prod.ts +6 -0
  146. package/src/environments/environment.ts +6 -0
  147. package/src/index.html +15 -0
  148. package/src/main.ts +6 -0
  149. package/src/proxy.conf.mjs +6 -0
  150. package/src/styles.scss +41 -0
  151. package/tsconfig.app.json +15 -0
  152. package/tsconfig.json +30 -0
@@ -0,0 +1,256 @@
1
+ <app-status-bar />
2
+
3
+ <form [formGroup]="settingsForm" class="content" (submit)="submit()">
4
+ <header>
5
+ <div class="title">
6
+ <h2>Settings</h2>
7
+ <p>Configure your backup settings.</p>
8
+ </div>
9
+
10
+ <button type="submit" spk-button class="raised primary">Save changes</button>
11
+ </header>
12
+
13
+ <section>
14
+ <div class="left">
15
+ <h3>Remote access control</h3>
16
+ <p>{{ getRemoteControlStatusText() }}</p>
17
+ </div>
18
+
19
+ <div class="right remote-control">
20
+ @if (remoteControlState() !== 'unknown') {
21
+ <div class="field-row">
22
+ @if (remoteControlState() === 'inactive') {
23
+ <spk-form-field label="Registration URL" for="remoteControlRegisterUrl">
24
+ <input
25
+ type="text"
26
+ spk-input
27
+ id="remoteControlRegisterUrl"
28
+ name="remoteControlRegisterUrl"
29
+ formControlName="remoteControlRegisterUrl" />
30
+ </spk-form-field>
31
+
32
+ <button type="button" spk-button class="raised" (click)="beginRemoteRegistration()">
33
+ Register for remote control
34
+ </button>
35
+ }
36
+
37
+ @if (remoteControlState() === 'registered') {
38
+ <div class="field-col">
39
+ <label>Machine is now registered, open this link to add it to your account:</label>
40
+ <a href="{{ remoteControlClaimUrl() }}" target="_blank">{{ remoteControlClaimUrl() }}</a>
41
+ </div>
42
+ }
43
+
44
+ @if (remoteControlState() === 'registering') {
45
+ <div class="field-col">
46
+ <label>Registering, please wait...</label>
47
+ </div>
48
+ }
49
+
50
+ @if (
51
+ remoteControlState() === 'registering' ||
52
+ remoteControlState() === 'registeringfaulted' ||
53
+ remoteControlState() === 'registered'
54
+ ) {
55
+ <button type="button" spk-button class="raised" (click)="cancelRemoteRegistration()">
56
+ Cancel registration
57
+ </button>
58
+ }
59
+
60
+ @if (remoteControlState() === 'connected' || remoteControlState() === 'enabled') {
61
+ <button type="button" spk-button class="raised" (click)="disableRemoteControl()">
62
+ Disable remote control
63
+ </button>
64
+ }
65
+ @if (remoteControlState() === 'disabled') {
66
+ <button type="button" spk-button class="raised" (click)="enableRemoteControl()">
67
+ Enable remote control
68
+ </button>
69
+
70
+ <button type="button" spk-button class="raised warn" (click)="deleteRemoteControl()">
71
+ Delete remote control setup
72
+ </button>
73
+ }
74
+ </div>
75
+ }
76
+ </div>
77
+ </section>
78
+
79
+ <section>
80
+ <div class="left">
81
+ <h3>Pause after startup or hibernation</h3>
82
+ <p>
83
+ Duplicati will run when started, but will remain in paused state for the duration. Duplicati will occupy minimal
84
+ system resources and no backups will be run.
85
+ </p>
86
+ </div>
87
+
88
+ <div class="right">
89
+ <div class="field-row" formGroupName="pauseSettings">
90
+ <spk-select [displayValue]="typeDisplay(settingsForm.value.pauseSettings?.timeType)">
91
+ <input type="text" formControlName="timeType" />
92
+
93
+ <ng-container options>
94
+ @for (x of timeTypeOptions(); track $index) {
95
+ <option [value]="x.value" (click)="pauseSettings.controls.timeType.setValue(x.value)">
96
+ {{ x.label }}
97
+ </option>
98
+ }
99
+ </ng-container>
100
+ </spk-select>
101
+
102
+ <spk-select>
103
+ <input type="search" formControlName="time" />
104
+
105
+ <ng-container options>
106
+ @for (x of timeOptions(); track $index) {
107
+ <option [value]="x" (click)="pauseSettings.controls.time.setValue(x)">{{ x }}</option>
108
+ }
109
+ </ng-container>
110
+ </spk-select>
111
+ </div>
112
+ </div>
113
+ </section>
114
+
115
+ <section>
116
+ <div class="left">
117
+ <h3>Color theme</h3>
118
+ <p>Customize your application theme</p>
119
+ </div>
120
+
121
+ <div class="right">
122
+ <div class="themes">
123
+ <img
124
+ src="/assets/images/light-theme.png"
125
+ [class.active]="!isDarkMode()"
126
+ alt="light theme"
127
+ (click)="setLightMode()" />
128
+
129
+ <img
130
+ src="/assets/images/dark-theme.png"
131
+ [class.active]="isDarkMode()"
132
+ alt="dark theme"
133
+ (click)="setDarkMode()" />
134
+ <!-- <img src="/assets/images/system-theme.png" alt="system theme" /> -->
135
+ </div>
136
+ </div>
137
+ </section>
138
+
139
+ <!-- <section>
140
+ <div class="left">
141
+ <h3>Language</h3>
142
+ <p>Select a language for the platform</p>
143
+ </div>
144
+
145
+ <div class="right">
146
+ <spk-select [displayValue]="languageDisplay(settingsForm.controls.language.value)">
147
+ <input type="search" formControlName="language" />
148
+
149
+ @for (x of languageOptions(); track $index) {
150
+ <option option [value]="x.value" (click)="settingsForm.controls.language.setValue(x.value)">
151
+ {{ x.label }}
152
+ </option>
153
+ }
154
+ </spk-select>
155
+ </div>
156
+ </section> -->
157
+
158
+ <section>
159
+ <div class="left">
160
+ <h3>Update channel</h3>
161
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
162
+ </div>
163
+
164
+ <div class="right radios">
165
+ <div class="radio-option" (click)="settingsForm.controls.updateChannel.setValue('')">
166
+ <spk-radio class="outlined primary">
167
+ Default ({{ sysinfo()?.DefaultUpdateChannel }})
168
+ <input type="radio" name="updateChannel" value="" formControlName="updateChannel" />
169
+ </spk-radio>
170
+
171
+ <p>Same as the base install version: {{ sysinfo()?.ServerVersionType }}</p>
172
+ </div>
173
+
174
+ <div class="radio-option" (click)="settingsForm.controls.updateChannel.setValue('stable')">
175
+ <spk-radio class="outlined primary">
176
+ Stable
177
+ <input type="radio" name="updateChannel" value="stable" formControlName="updateChannel" />
178
+ </spk-radio>
179
+
180
+ <p>Official releases</p>
181
+ </div>
182
+
183
+ <div class="radio-option" (click)="settingsForm.controls.updateChannel.setValue('beta')">
184
+ <spk-radio class="outlined primary">
185
+ Beta
186
+ <input type="radio" name="updateChannel" value="beta" formControlName="updateChannel" />
187
+ </spk-radio>
188
+
189
+ <p>
190
+ Try out the new features that we are working on. Currently the most stable version available. Test Restore
191
+ data before using this in production environments.
192
+ </p>
193
+ </div>
194
+
195
+ <div class="radio-option" (click)="settingsForm.controls.updateChannel.setValue('experimental')">
196
+ <spk-radio class="outlined primary">
197
+ Experimental
198
+ <input type="radio" name="updateChannel" value="experimental" formControlName="updateChannel" />
199
+ </spk-radio>
200
+
201
+ <p>Specific builds for developers only. Not for use with important data.</p>
202
+ </div>
203
+
204
+ <div class="radio-option" (click)="settingsForm.controls.updateChannel.setValue('canary')">
205
+ <spk-radio class="outlined primary">
206
+ Canary
207
+ <input type="radio" name="updateChannel" value="canary" formControlName="updateChannel" />
208
+ </spk-radio>
209
+
210
+ <p>Individual builds for developers only. Not for use with important data.</p>
211
+ </div>
212
+ </div>
213
+ </section>
214
+
215
+ <section>
216
+ <div class="left">
217
+ <h3>Usage statistics</h3>
218
+ <p>
219
+ Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate
220
+ <a href="#">public usage statistics.</a>
221
+ <br />
222
+ <br />
223
+ All usage reports are sent anonymously and do not contain any personal information. They contain information
224
+ about hardware and operating system, the type of backend, backup duration, overall size of source data and
225
+ similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.
226
+ </p>
227
+ </div>
228
+
229
+ <div class="right">
230
+ <spk-select [displayValue]="usageDisplay(settingsForm.controls.usageStatistics.value)">
231
+ <input type="text" formControlName="usageStatistics" />
232
+
233
+ <ng-container options>
234
+ @for (x of usageStatisticsOptions(); track $index) {
235
+ <option [value]="x.value" (click)="settingsForm.controls.usageStatistics.setValue(x.value)">
236
+ {{ x.label }}
237
+ </option>
238
+ }
239
+ </ng-container>
240
+ </spk-select>
241
+ </div>
242
+ </section>
243
+
244
+ <!-- <section>
245
+ <div class="left">
246
+ <h3>Add advanced options</h3>
247
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
248
+ <spk-button-group>
249
+ <button type="button" [class.active]="editAs() === 'list'" (click)="editAs.set('list')">Edit as list</button>
250
+ <button type="button" [class.active]="editAs() === 'text'" (click)="editAs.set('text')">Edit as text</button>
251
+ </spk-button-group>
252
+ </div>
253
+
254
+ <div class="right">Empty for now</div>
255
+ </section> -->
256
+ </form>
@@ -0,0 +1,106 @@
1
+ @use '@sparkle-ui/core/styles/helpers' as *;
2
+
3
+ :host {
4
+ display: block;
5
+ }
6
+
7
+ .content {
8
+ display: flex;
9
+ flex-direction: column;
10
+ padding: p2r(0 32 32);
11
+ }
12
+
13
+ header {
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ padding: p2r(32 0);
18
+
19
+ .title {
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: p2r(4);
23
+ }
24
+ }
25
+
26
+ section {
27
+ display: grid;
28
+ grid-template-columns: 1fr 1fr;
29
+ gap: p2r(16);
30
+ padding: p2r(32 0);
31
+ border-top: 1px solid var(--base-level-40);
32
+
33
+ .left {
34
+ display: flex;
35
+ flex-direction: column;
36
+ gap: p2r(4);
37
+ align-items: flex-start;
38
+
39
+ spk-button-group {
40
+ margin-top: p2r(4);
41
+ }
42
+
43
+ p {
44
+ text-wrap: balance;
45
+ width: 50%;
46
+ }
47
+ }
48
+ }
49
+
50
+ .themes {
51
+ display: flex;
52
+ gap: p2r(8);
53
+
54
+ img {
55
+ max-width: 240px;
56
+ border-radius: var(--shape-3);
57
+ cursor: pointer;
58
+
59
+ &.active {
60
+ border: 2px solid var(--primary-500);
61
+ }
62
+ }
63
+ }
64
+
65
+ .radios {
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: p2r(16);
69
+ }
70
+
71
+ .radio-option {
72
+ cursor: pointer;
73
+
74
+ spk-radio {
75
+ color: var(--base-level-60);
76
+ margin-bottom: p2r(4);
77
+ }
78
+
79
+ p {
80
+ text-wrap: balance;
81
+ color: var(--base-level-60R);
82
+ }
83
+ }
84
+
85
+ .field-col {
86
+ display: flex;
87
+ flex-direction: column;
88
+ gap: p2r(8);
89
+ }
90
+
91
+ .field-row {
92
+ display: flex;
93
+ gap: p2r(8);
94
+ width: 100%;
95
+
96
+ spk-form-field,
97
+ spk-select {
98
+ flex: 1 0;
99
+ }
100
+ }
101
+
102
+ .remote-control {
103
+ button {
104
+ white-space: nowrap;
105
+ }
106
+ }