@promptbook/cli 0.112.0-96 → 0.112.0-97
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/apps/agents-server/README.md +3 -3
- package/apps/agents-server/playwright.config.ts +2 -1
- package/apps/agents-server/src/app/admin/code-runners/CodeRunnersClient.tsx +358 -19
- package/apps/agents-server/src/app/admin/database/page.tsx +2 -1
- package/apps/agents-server/src/app/admin/servers/CreateServerDialog.tsx +46 -505
- package/apps/agents-server/src/app/admin/servers/ServersClient.tsx +23 -11
- package/apps/agents-server/src/app/admin/servers/ServersRegistryApi.ts +5 -0
- package/apps/agents-server/src/app/admin/servers/ServersRegistryDnsTypes.ts +87 -0
- package/apps/agents-server/src/app/admin/servers/ServersRegistryTable.tsx +258 -128
- package/apps/agents-server/src/app/admin/servers/useCreateServerWizard.ts +46 -334
- package/apps/agents-server/src/app/admin/servers/useServersRegistryState.ts +26 -2
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +435 -0
- package/apps/agents-server/src/app/admin/update/page.tsx +14 -0
- package/apps/agents-server/src/app/api/admin/code-runners/authentication/route.ts +197 -0
- package/apps/agents-server/src/app/api/admin/code-runners/route.ts +4 -35
- package/apps/agents-server/src/app/api/admin/servers/[serverId]/route.ts +10 -5
- package/apps/agents-server/src/app/api/admin/servers/route.ts +97 -6
- package/apps/agents-server/src/app/api/admin/update/route.ts +52 -0
- package/apps/agents-server/src/app/api/auth/login/route.ts +8 -0
- package/apps/agents-server/src/app/api/auth/logout/route.ts +10 -2
- package/apps/agents-server/src/app/page.tsx +10 -0
- package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +6 -0
- package/apps/agents-server/src/database/$provideClientSql.ts +4 -17
- package/apps/agents-server/src/database/$provideDatabaseAdminExecutor.ts +3 -24
- package/apps/agents-server/src/database/$providePostgresPool.ts +27 -0
- package/apps/agents-server/src/database/$provideSupabaseForServer.ts +11 -1
- package/apps/agents-server/src/database/agentsServerDatabaseMode.ts +20 -1
- package/apps/agents-server/src/database/postgres/$provideLocalPostgresSupabase.ts +1261 -0
- package/apps/agents-server/src/languages/ServerTranslationKeys.ts +1 -0
- package/apps/agents-server/src/languages/translations/czech.yaml +1 -0
- package/apps/agents-server/src/languages/translations/english.yaml +1 -0
- package/apps/agents-server/src/middleware.ts +32 -0
- package/apps/agents-server/src/tools/$provideServer.ts +2 -2
- package/apps/agents-server/src/utils/codeRunnerAuthentication.ts +394 -0
- package/apps/agents-server/src/utils/codeRunnerConfiguration.ts +67 -0
- package/apps/agents-server/src/utils/serverManagement/standaloneVpsServerMetadata.ts +145 -0
- package/apps/agents-server/src/utils/serverRegistry.ts +7 -6
- package/apps/agents-server/src/utils/session.ts +37 -9
- package/apps/agents-server/src/utils/shibboleth/createShibbolethAuthenticationLogPayload.ts +173 -0
- package/apps/agents-server/src/utils/shibboleth/writeShibbolethAuthenticationLog.ts +27 -0
- package/apps/agents-server/src/utils/standaloneVpsDnsDiagnostics.ts +258 -0
- package/apps/agents-server/src/utils/standaloneVpsRawIpBootstrap.ts +87 -0
- package/apps/agents-server/src/utils/vpsConfiguration.ts +87 -15
- package/apps/agents-server/src/utils/vpsSelfUpdate.ts +664 -0
- package/esm/apps/agents-server/src/database/agentsServerDatabaseMode.d.ts +9 -1
- package/esm/apps/agents-server/src/utils/serverRegistry.d.ts +1 -1
- package/esm/index.es.js +8 -6
- package/esm/index.es.js.map +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/book-components/Chat/utils/renderMarkdown.ts +1 -3
- package/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.ts +1 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +698 -755
- package/src/scrapers/document/DocumentScraper.ts +1 -1
- package/src/scrapers/document-legacy/LegacyDocumentScraper.ts +1 -1
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/apps/agents-server/src/database/agentsServerDatabaseMode.d.ts +9 -1
- package/umd/apps/agents-server/src/utils/serverRegistry.d.ts +1 -1
- package/umd/index.umd.js +8 -6
- package/umd/index.umd.js.map +1 -1
- package/umd/src/version.d.ts +1 -1
|
@@ -88,7 +88,7 @@ export type CreateServerWizardState = {
|
|
|
88
88
|
name: string;
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
* Safe slug
|
|
91
|
+
* Safe slug derived from the server name.
|
|
92
92
|
*/
|
|
93
93
|
identifier: string;
|
|
94
94
|
|
|
@@ -108,7 +108,7 @@ export type CreateServerWizardState = {
|
|
|
108
108
|
iconUrl: string;
|
|
109
109
|
|
|
110
110
|
/**
|
|
111
|
-
*
|
|
111
|
+
* Installer-managed admin account.
|
|
112
112
|
*/
|
|
113
113
|
adminUser: {
|
|
114
114
|
username: string;
|
|
@@ -154,103 +154,12 @@ export type CreateServerWizardError = {
|
|
|
154
154
|
* @private function of <ServersClient/>
|
|
155
155
|
*/
|
|
156
156
|
export type UpdateCreateServerWizardField = <
|
|
157
|
-
TFieldName extends keyof Pick<
|
|
158
|
-
CreateServerWizardState,
|
|
159
|
-
'name' | 'identifier' | 'environment' | 'domain' | 'iconUrl'
|
|
160
|
-
>,
|
|
157
|
+
TFieldName extends keyof Pick<CreateServerWizardState, 'name' | 'domain' | 'iconUrl'>,
|
|
161
158
|
>(
|
|
162
159
|
fieldName: TFieldName,
|
|
163
160
|
value: CreateServerWizardState[TFieldName],
|
|
164
161
|
) => void;
|
|
165
162
|
|
|
166
|
-
/**
|
|
167
|
-
* Admin-user updater shared with the dialog component.
|
|
168
|
-
*
|
|
169
|
-
* @private function of <ServersClient/>
|
|
170
|
-
*/
|
|
171
|
-
export type UpdateCreateServerAdminField = <TFieldName extends keyof CreateServerWizardState['adminUser']>(
|
|
172
|
-
fieldName: TFieldName,
|
|
173
|
-
value: CreateServerWizardState['adminUser'][TFieldName],
|
|
174
|
-
) => void;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Initial-settings updater shared with the dialog component.
|
|
178
|
-
*
|
|
179
|
-
* @private function of <ServersClient/>
|
|
180
|
-
*/
|
|
181
|
-
export type UpdateCreateServerInitialSetting = <TFieldName extends keyof CreateServerWizardState['initialSettings']>(
|
|
182
|
-
fieldName: TFieldName,
|
|
183
|
-
value: CreateServerWizardState['initialSettings'][TFieldName],
|
|
184
|
-
) => void;
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Additional-user updater shared with the dialog component.
|
|
188
|
-
*
|
|
189
|
-
* @private function of <ServersClient/>
|
|
190
|
-
*/
|
|
191
|
-
export type UpdateCreateServerAdditionalUser = <TFieldName extends keyof WizardUser>(
|
|
192
|
-
index: number,
|
|
193
|
-
fieldName: TFieldName,
|
|
194
|
-
value: WizardUser[TFieldName],
|
|
195
|
-
) => void;
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Step labels shown in the create-server wizard.
|
|
199
|
-
*
|
|
200
|
-
* @private function of <ServersClient/>
|
|
201
|
-
*/
|
|
202
|
-
export const CREATE_SERVER_WIZARD_STEPS = [
|
|
203
|
-
{
|
|
204
|
-
title: 'Profile',
|
|
205
|
-
description: 'Name, identifier, environment, domain, and branding.',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
title: 'Users',
|
|
209
|
-
description: 'Bootstrap admin credentials and optional extra users.',
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
title: 'Settings',
|
|
213
|
-
description: 'Language, homepage message, and initial feature flags.',
|
|
214
|
-
},
|
|
215
|
-
] as const;
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Boolean settings rendered as checkbox cards in the final wizard step.
|
|
219
|
-
*
|
|
220
|
-
* @private function of <ServersClient/>
|
|
221
|
-
*/
|
|
222
|
-
type CreateServerBooleanFeatureFlagKey = keyof Pick<
|
|
223
|
-
CreateServerInitialSettings,
|
|
224
|
-
'isFileAttachmentsEnabled' | 'isExperimentalPwaAppEnabled' | 'isFooterShown'
|
|
225
|
-
>;
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Boolean feature flags exposed in the create-server wizard.
|
|
229
|
-
*
|
|
230
|
-
* @private function of <ServersClient/>
|
|
231
|
-
*/
|
|
232
|
-
export const CREATE_SERVER_BOOLEAN_FEATURE_FLAGS: ReadonlyArray<{
|
|
233
|
-
readonly key: CreateServerBooleanFeatureFlagKey;
|
|
234
|
-
readonly title: string;
|
|
235
|
-
readonly description: string;
|
|
236
|
-
}> = [
|
|
237
|
-
{
|
|
238
|
-
key: 'isFileAttachmentsEnabled',
|
|
239
|
-
title: 'File attachments enabled',
|
|
240
|
-
description: 'Allow chat attachments on the new server.',
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
key: 'isExperimentalPwaAppEnabled',
|
|
244
|
-
title: 'PWA install enabled',
|
|
245
|
-
description: 'Expose the experimental install-as-app option.',
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
key: 'isFooterShown',
|
|
249
|
-
title: 'Footer shown',
|
|
250
|
-
description: 'Render the shared footer on public pages.',
|
|
251
|
-
},
|
|
252
|
-
] as const;
|
|
253
|
-
|
|
254
163
|
/**
|
|
255
164
|
* Hook options used to coordinate post-create refresh behavior.
|
|
256
165
|
*
|
|
@@ -269,16 +178,6 @@ type UseCreateServerWizardOptions = {
|
|
|
269
178
|
* @private function of <ServersClient/>
|
|
270
179
|
*/
|
|
271
180
|
type UseCreateServerWizardResult = {
|
|
272
|
-
/**
|
|
273
|
-
* Adds a new extra bootstrap user row.
|
|
274
|
-
*/
|
|
275
|
-
readonly addAdditionalUser: () => void;
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Derived table-prefix preview for the current identifier.
|
|
279
|
-
*/
|
|
280
|
-
readonly derivedWizardTablePrefix: string;
|
|
281
|
-
|
|
282
181
|
/**
|
|
283
182
|
* Persists the wizard as a new registered server.
|
|
284
183
|
*/
|
|
@@ -289,21 +188,6 @@ type UseCreateServerWizardResult = {
|
|
|
289
188
|
*/
|
|
290
189
|
readonly handleIconUpload: (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
|
|
291
190
|
|
|
292
|
-
/**
|
|
293
|
-
* Moves the wizard one step backward.
|
|
294
|
-
*/
|
|
295
|
-
readonly handleWizardBack: () => void;
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Moves the wizard one step forward after validating the current step.
|
|
299
|
-
*/
|
|
300
|
-
readonly handleWizardNext: () => Promise<void>;
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Navigates to the requested wizard step with step validation.
|
|
304
|
-
*/
|
|
305
|
-
readonly handleWizardStepSelection: (nextStep: number) => Promise<void>;
|
|
306
|
-
|
|
307
191
|
/**
|
|
308
192
|
* Hidden file input used for icon uploads.
|
|
309
193
|
*/
|
|
@@ -334,11 +218,6 @@ type UseCreateServerWizardResult = {
|
|
|
334
218
|
*/
|
|
335
219
|
readonly openDialog: () => void;
|
|
336
220
|
|
|
337
|
-
/**
|
|
338
|
-
* Removes one extra bootstrap user row.
|
|
339
|
-
*/
|
|
340
|
-
readonly removeAdditionalUser: (index: number) => void;
|
|
341
|
-
|
|
342
221
|
/**
|
|
343
222
|
* Closes the dialog while respecting the dirty-state guard.
|
|
344
223
|
*/
|
|
@@ -349,21 +228,6 @@ type UseCreateServerWizardResult = {
|
|
|
349
228
|
*/
|
|
350
229
|
readonly resetWizard: () => void;
|
|
351
230
|
|
|
352
|
-
/**
|
|
353
|
-
* Updates one extra bootstrap user row.
|
|
354
|
-
*/
|
|
355
|
-
readonly updateAdditionalUser: UpdateCreateServerAdditionalUser;
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Updates the required admin-user fields.
|
|
359
|
-
*/
|
|
360
|
-
readonly updateAdminUser: UpdateCreateServerAdminField;
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Updates one initial setting field.
|
|
364
|
-
*/
|
|
365
|
-
readonly updateInitialSetting: UpdateCreateServerInitialSetting;
|
|
366
|
-
|
|
367
231
|
/**
|
|
368
232
|
* Updates one top-level wizard field.
|
|
369
233
|
*/
|
|
@@ -378,26 +242,8 @@ type UseCreateServerWizardResult = {
|
|
|
378
242
|
* Current create-server form state.
|
|
379
243
|
*/
|
|
380
244
|
readonly wizardState: CreateServerWizardState;
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Current wizard step index.
|
|
384
|
-
*/
|
|
385
|
-
readonly wizardStep: number;
|
|
386
245
|
};
|
|
387
246
|
|
|
388
|
-
/**
|
|
389
|
-
* Creates an empty extra-user row for the create-server wizard.
|
|
390
|
-
*
|
|
391
|
-
* @returns Fresh extra-user draft.
|
|
392
|
-
*/
|
|
393
|
-
function createEmptyWizardUser(): WizardUser {
|
|
394
|
-
return {
|
|
395
|
-
username: '',
|
|
396
|
-
password: '',
|
|
397
|
-
isAdmin: false,
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
|
|
401
247
|
/**
|
|
402
248
|
* Creates the initial create-server wizard state.
|
|
403
249
|
*
|
|
@@ -407,7 +253,7 @@ function createInitialWizardState(): CreateServerWizardState {
|
|
|
407
253
|
return {
|
|
408
254
|
name: '',
|
|
409
255
|
identifier: '',
|
|
410
|
-
environment: '
|
|
256
|
+
environment: 'PRODUCTION',
|
|
411
257
|
domain: '',
|
|
412
258
|
iconUrl: '',
|
|
413
259
|
adminUser: {
|
|
@@ -426,6 +272,22 @@ function createInitialWizardState(): CreateServerWizardState {
|
|
|
426
272
|
};
|
|
427
273
|
}
|
|
428
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Derives a URL-safe server identifier from the visible server name.
|
|
277
|
+
*
|
|
278
|
+
* @param name - Raw server name.
|
|
279
|
+
* @returns Lowercase hyphenated identifier.
|
|
280
|
+
*/
|
|
281
|
+
function createServerIdentifierFromName(name: string): string {
|
|
282
|
+
return name
|
|
283
|
+
.normalize('NFKD')
|
|
284
|
+
.replace(/[\u0300-\u036f]/gu, '')
|
|
285
|
+
.toLowerCase()
|
|
286
|
+
.replace(/[^a-z0-9]+/gu, '-')
|
|
287
|
+
.replace(/^-+|-+$/gu, '')
|
|
288
|
+
.replace(/-+/gu, '-');
|
|
289
|
+
}
|
|
290
|
+
|
|
429
291
|
/**
|
|
430
292
|
* Safely derives the table-prefix preview for a wizard identifier.
|
|
431
293
|
*
|
|
@@ -446,60 +308,24 @@ function deriveWizardTablePrefix(identifier: string): string {
|
|
|
446
308
|
}
|
|
447
309
|
|
|
448
310
|
/**
|
|
449
|
-
* Validates the create-server wizard
|
|
311
|
+
* Validates the simplified create-server wizard.
|
|
450
312
|
*
|
|
451
313
|
* @param wizardState - Current wizard form data.
|
|
452
|
-
* @param derivedTablePrefix - Derived prefix preview for the
|
|
453
|
-
* @param upToStep - Highest wizard step that must be valid.
|
|
314
|
+
* @param derivedTablePrefix - Derived prefix preview for the generated identifier.
|
|
454
315
|
* @returns User-facing validation message or `null` when valid.
|
|
455
316
|
*/
|
|
456
317
|
function getCreateServerWizardValidationMessage(
|
|
457
318
|
wizardState: CreateServerWizardState,
|
|
458
319
|
derivedTablePrefix: string,
|
|
459
|
-
upToStep: number,
|
|
460
320
|
): string | null {
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
return 'Server name is required.';
|
|
464
|
-
}
|
|
465
|
-
if (wizardState.identifier.trim() === '') {
|
|
466
|
-
return 'Server identifier is required.';
|
|
467
|
-
}
|
|
468
|
-
if (!derivedTablePrefix) {
|
|
469
|
-
return 'Server identifier must contain only lowercase letters, numbers, and hyphens.';
|
|
470
|
-
}
|
|
471
|
-
if (wizardState.domain.trim() === '') {
|
|
472
|
-
return 'Server domain is required.';
|
|
473
|
-
}
|
|
321
|
+
if (wizardState.name.trim() === '') {
|
|
322
|
+
return 'Server name is required.';
|
|
474
323
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
if (wizardState.adminUser.username.trim() === '') {
|
|
478
|
-
return 'Admin username is required.';
|
|
479
|
-
}
|
|
480
|
-
if (wizardState.adminUser.password === '') {
|
|
481
|
-
return 'Admin password is required.';
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
const seenUsernames = new Set<string>([wizardState.adminUser.username.trim().toLowerCase()]);
|
|
485
|
-
for (const [index, user] of wizardState.additionalUsers.entries()) {
|
|
486
|
-
if (user.username.trim() === '') {
|
|
487
|
-
return `Additional user ${index + 1} must have a username.`;
|
|
488
|
-
}
|
|
489
|
-
if (user.password === '') {
|
|
490
|
-
return `Additional user ${index + 1} must have a password.`;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const normalizedUsername = user.username.trim().toLowerCase();
|
|
494
|
-
if (seenUsernames.has(normalizedUsername)) {
|
|
495
|
-
return `Username "${user.username.trim()}" is duplicated in the bootstrap users list.`;
|
|
496
|
-
}
|
|
497
|
-
seenUsernames.add(normalizedUsername);
|
|
498
|
-
}
|
|
324
|
+
if (wizardState.identifier.trim() === '' || !derivedTablePrefix) {
|
|
325
|
+
return 'Server name must contain at least one letter or number.';
|
|
499
326
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
return 'Initial language is required.';
|
|
327
|
+
if (wizardState.domain.trim() === '') {
|
|
328
|
+
return 'Server domain is required.';
|
|
503
329
|
}
|
|
504
330
|
|
|
505
331
|
return null;
|
|
@@ -509,40 +335,21 @@ function getCreateServerWizardValidationMessage(
|
|
|
509
335
|
* Returns whether the create-server wizard contains unsaved values.
|
|
510
336
|
*
|
|
511
337
|
* @param wizardState - Current wizard form state.
|
|
512
|
-
* @returns `true` when any wizard field differs from its initial value.
|
|
338
|
+
* @returns `true` when any visible wizard field differs from its initial value.
|
|
513
339
|
*/
|
|
514
340
|
function hasCreateServerWizardChanges(wizardState: CreateServerWizardState): boolean {
|
|
515
341
|
const initialWizardState = createInitialWizardState();
|
|
516
342
|
|
|
517
|
-
|
|
343
|
+
return (
|
|
518
344
|
wizardState.name !== initialWizardState.name ||
|
|
519
345
|
wizardState.identifier !== initialWizardState.identifier ||
|
|
520
|
-
wizardState.environment !== initialWizardState.environment ||
|
|
521
346
|
wizardState.domain !== initialWizardState.domain ||
|
|
522
|
-
wizardState.iconUrl !== initialWizardState.iconUrl
|
|
523
|
-
|
|
524
|
-
wizardState.adminUser.password !== initialWizardState.adminUser.password ||
|
|
525
|
-
wizardState.initialSettings.language !== initialWizardState.initialSettings.language ||
|
|
526
|
-
wizardState.initialSettings.homepageMessage !== initialWizardState.initialSettings.homepageMessage ||
|
|
527
|
-
wizardState.initialSettings.feedbackMode !== initialWizardState.initialSettings.feedbackMode ||
|
|
528
|
-
wizardState.initialSettings.isFileAttachmentsEnabled !==
|
|
529
|
-
initialWizardState.initialSettings.isFileAttachmentsEnabled ||
|
|
530
|
-
wizardState.initialSettings.isExperimentalPwaAppEnabled !==
|
|
531
|
-
initialWizardState.initialSettings.isExperimentalPwaAppEnabled ||
|
|
532
|
-
wizardState.initialSettings.isFooterShown !== initialWizardState.initialSettings.isFooterShown
|
|
533
|
-
) {
|
|
534
|
-
return true;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
if (wizardState.additionalUsers.length !== initialWizardState.additionalUsers.length) {
|
|
538
|
-
return true;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
return wizardState.additionalUsers.some((user) => user.username !== '' || user.password !== '' || user.isAdmin);
|
|
347
|
+
wizardState.iconUrl !== initialWizardState.iconUrl
|
|
348
|
+
);
|
|
542
349
|
}
|
|
543
350
|
|
|
544
351
|
/**
|
|
545
|
-
* Encapsulates the
|
|
352
|
+
* Encapsulates the simplified create-server dialog state and side effects.
|
|
546
353
|
*
|
|
547
354
|
* @param options - Hook options.
|
|
548
355
|
* @returns Dialog state, derived values, and event handlers.
|
|
@@ -552,7 +359,6 @@ function hasCreateServerWizardChanges(wizardState: CreateServerWizardState): boo
|
|
|
552
359
|
export function useCreateServerWizard(options: UseCreateServerWizardOptions): UseCreateServerWizardResult {
|
|
553
360
|
const { onServerCreated } = options;
|
|
554
361
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
555
|
-
const [wizardStep, setWizardStep] = useState(0);
|
|
556
362
|
const [wizardState, setWizardState] = useState<CreateServerWizardState>(createInitialWizardState);
|
|
557
363
|
const [isCreatingServer, setIsCreatingServer] = useState(false);
|
|
558
364
|
const [wizardError, setWizardError] = useState<CreateServerWizardError | null>(null);
|
|
@@ -566,7 +372,6 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
|
|
|
566
372
|
const isDirty = useMemo(() => hasCreateServerWizardChanges(wizardState), [wizardState]);
|
|
567
373
|
|
|
568
374
|
const resetWizard = useCallback(() => {
|
|
569
|
-
setWizardStep(0);
|
|
570
375
|
setWizardState(createInitialWizardState());
|
|
571
376
|
setWizardError(null);
|
|
572
377
|
|
|
@@ -593,53 +398,20 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
|
|
|
593
398
|
}, [resetWizard]);
|
|
594
399
|
|
|
595
400
|
const updateWizardField = useCallback<UpdateCreateServerWizardField>((fieldName, value) => {
|
|
596
|
-
setWizardState((previous) =>
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
...previous,
|
|
605
|
-
adminUser: {
|
|
606
|
-
...previous.adminUser,
|
|
607
|
-
[fieldName]: value,
|
|
608
|
-
},
|
|
609
|
-
}));
|
|
610
|
-
}, []);
|
|
401
|
+
setWizardState((previous) => {
|
|
402
|
+
if (fieldName === 'name') {
|
|
403
|
+
return {
|
|
404
|
+
...previous,
|
|
405
|
+
name: value,
|
|
406
|
+
identifier: createServerIdentifierFromName(value),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
611
409
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
...previous,
|
|
615
|
-
initialSettings: {
|
|
616
|
-
...previous.initialSettings,
|
|
410
|
+
return {
|
|
411
|
+
...previous,
|
|
617
412
|
[fieldName]: value,
|
|
618
|
-
}
|
|
619
|
-
})
|
|
620
|
-
}, []);
|
|
621
|
-
|
|
622
|
-
const updateAdditionalUser = useCallback<UpdateCreateServerAdditionalUser>((index, fieldName, value) => {
|
|
623
|
-
setWizardState((previous) => ({
|
|
624
|
-
...previous,
|
|
625
|
-
additionalUsers: previous.additionalUsers.map((user, userIndex) =>
|
|
626
|
-
userIndex === index ? { ...user, [fieldName]: value } : user,
|
|
627
|
-
),
|
|
628
|
-
}));
|
|
629
|
-
}, []);
|
|
630
|
-
|
|
631
|
-
const addAdditionalUser = useCallback(() => {
|
|
632
|
-
setWizardState((previous) => ({
|
|
633
|
-
...previous,
|
|
634
|
-
additionalUsers: [...previous.additionalUsers, createEmptyWizardUser()],
|
|
635
|
-
}));
|
|
636
|
-
}, []);
|
|
637
|
-
|
|
638
|
-
const removeAdditionalUser = useCallback((index: number) => {
|
|
639
|
-
setWizardState((previous) => ({
|
|
640
|
-
...previous,
|
|
641
|
-
additionalUsers: previous.additionalUsers.filter((_, userIndex) => userIndex !== index),
|
|
642
|
-
}));
|
|
413
|
+
};
|
|
414
|
+
});
|
|
643
415
|
}, []);
|
|
644
416
|
|
|
645
417
|
const handleIconUpload = useCallback(
|
|
@@ -686,11 +458,7 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
|
|
|
686
458
|
);
|
|
687
459
|
|
|
688
460
|
const handleCreateServer = useCallback(async () => {
|
|
689
|
-
const validationMessage = getCreateServerWizardValidationMessage(
|
|
690
|
-
wizardState,
|
|
691
|
-
derivedWizardTablePrefix,
|
|
692
|
-
CREATE_SERVER_WIZARD_STEPS.length - 1,
|
|
693
|
-
);
|
|
461
|
+
const validationMessage = getCreateServerWizardValidationMessage(wizardState, derivedWizardTablePrefix);
|
|
694
462
|
if (validationMessage) {
|
|
695
463
|
await showAlert({
|
|
696
464
|
title: 'Create server',
|
|
@@ -739,75 +507,19 @@ export function useCreateServerWizard(options: UseCreateServerWizardOptions): Us
|
|
|
739
507
|
}
|
|
740
508
|
}, [closeDialog, derivedWizardTablePrefix, onServerCreated, wizardState]);
|
|
741
509
|
|
|
742
|
-
const handleWizardBack = useCallback(() => {
|
|
743
|
-
setWizardStep((previous) => Math.max(0, previous - 1));
|
|
744
|
-
}, []);
|
|
745
|
-
|
|
746
|
-
const handleWizardNext = useCallback(async () => {
|
|
747
|
-
const validationMessage = getCreateServerWizardValidationMessage(
|
|
748
|
-
wizardState,
|
|
749
|
-
derivedWizardTablePrefix,
|
|
750
|
-
wizardStep,
|
|
751
|
-
);
|
|
752
|
-
if (validationMessage) {
|
|
753
|
-
await showAlert({
|
|
754
|
-
title: 'Create server',
|
|
755
|
-
message: validationMessage,
|
|
756
|
-
}).catch(() => undefined);
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
setWizardStep((previous) => Math.min(CREATE_SERVER_WIZARD_STEPS.length - 1, previous + 1));
|
|
761
|
-
}, [derivedWizardTablePrefix, wizardState, wizardStep]);
|
|
762
|
-
|
|
763
|
-
const handleWizardStepSelection = useCallback(
|
|
764
|
-
async (nextStep: number) => {
|
|
765
|
-
if (nextStep <= wizardStep) {
|
|
766
|
-
setWizardStep(nextStep);
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
const validationMessage = getCreateServerWizardValidationMessage(
|
|
771
|
-
wizardState,
|
|
772
|
-
derivedWizardTablePrefix,
|
|
773
|
-
wizardStep,
|
|
774
|
-
);
|
|
775
|
-
if (validationMessage) {
|
|
776
|
-
await showAlert({
|
|
777
|
-
title: 'Create server',
|
|
778
|
-
message: validationMessage,
|
|
779
|
-
}).catch(() => undefined);
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
setWizardStep(nextStep);
|
|
784
|
-
},
|
|
785
|
-
[derivedWizardTablePrefix, wizardState, wizardStep],
|
|
786
|
-
);
|
|
787
|
-
|
|
788
510
|
return {
|
|
789
|
-
addAdditionalUser,
|
|
790
|
-
derivedWizardTablePrefix,
|
|
791
511
|
handleCreateServer,
|
|
792
512
|
handleIconUpload,
|
|
793
|
-
handleWizardBack,
|
|
794
|
-
handleWizardNext,
|
|
795
|
-
handleWizardStepSelection,
|
|
796
513
|
iconInputRef,
|
|
797
514
|
isCreatingServer,
|
|
798
515
|
isDialogOpen,
|
|
799
516
|
isDirty,
|
|
800
517
|
isUploadingIcon,
|
|
801
518
|
openDialog,
|
|
802
|
-
removeAdditionalUser,
|
|
803
519
|
requestClose,
|
|
804
520
|
resetWizard,
|
|
805
|
-
updateAdditionalUser,
|
|
806
|
-
updateAdminUser,
|
|
807
|
-
updateInitialSetting,
|
|
808
521
|
updateWizardField,
|
|
809
522
|
wizardError,
|
|
810
523
|
wizardState,
|
|
811
|
-
wizardStep,
|
|
812
524
|
};
|
|
813
525
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import { showAlert, showConfirm, showPrompt } from '../../../components/AsyncDialogs/asyncDialogs';
|
|
5
|
+
import type { ManagedServerDnsDiagnostic } from './ServersRegistryDnsTypes';
|
|
5
6
|
import { ServersRegistryApi } from './ServersRegistryApi';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -63,6 +64,11 @@ export type ManagedServerRow = {
|
|
|
63
64
|
* Last update timestamp.
|
|
64
65
|
*/
|
|
65
66
|
readonly updatedAt: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Optional standalone-VPS DNS verification details for the domain.
|
|
70
|
+
*/
|
|
71
|
+
readonly dnsDiagnostic?: ManagedServerDnsDiagnostic | null;
|
|
66
72
|
};
|
|
67
73
|
|
|
68
74
|
/**
|
|
@@ -178,6 +184,11 @@ type UseServersRegistryStateResult = {
|
|
|
178
184
|
*/
|
|
179
185
|
readonly loading: boolean;
|
|
180
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Whether the registry rows are virtual standalone VPS domains.
|
|
189
|
+
*/
|
|
190
|
+
readonly isStandaloneVps: boolean;
|
|
191
|
+
|
|
181
192
|
/**
|
|
182
193
|
* Server id currently running migrations.
|
|
183
194
|
*/
|
|
@@ -433,6 +444,7 @@ function useServersRegistryDraftState(servers: ReadonlyArray<ManagedServerRow>)
|
|
|
433
444
|
* @private function of useServersRegistryState
|
|
434
445
|
*/
|
|
435
446
|
function useServersRegistryReloadAction(options: {
|
|
447
|
+
readonly setIsStandaloneVps: (isStandaloneVps: boolean) => void;
|
|
436
448
|
readonly replaceServerDrafts: (servers: ReadonlyArray<ManagedServerRow>) => void;
|
|
437
449
|
readonly setCanEdit: (canEdit: boolean) => void;
|
|
438
450
|
readonly setCurrentServerId: (currentServerId: number | null) => void;
|
|
@@ -440,7 +452,15 @@ function useServersRegistryReloadAction(options: {
|
|
|
440
452
|
readonly setLoading: (isLoading: boolean) => void;
|
|
441
453
|
readonly setServers: (servers: ManagedServerRow[]) => void;
|
|
442
454
|
}) {
|
|
443
|
-
const {
|
|
455
|
+
const {
|
|
456
|
+
replaceServerDrafts,
|
|
457
|
+
setCanEdit,
|
|
458
|
+
setCurrentServerId,
|
|
459
|
+
setError,
|
|
460
|
+
setIsStandaloneVps,
|
|
461
|
+
setLoading,
|
|
462
|
+
setServers,
|
|
463
|
+
} = options;
|
|
444
464
|
|
|
445
465
|
return useCallback(async () => {
|
|
446
466
|
setLoading(true);
|
|
@@ -451,13 +471,14 @@ function useServersRegistryReloadAction(options: {
|
|
|
451
471
|
setServers([...payload.servers]);
|
|
452
472
|
setCurrentServerId(payload.currentServerId);
|
|
453
473
|
setCanEdit(payload.canEdit);
|
|
474
|
+
setIsStandaloneVps(payload.isStandaloneVps === true);
|
|
454
475
|
replaceServerDrafts(payload.servers);
|
|
455
476
|
} catch (loadError) {
|
|
456
477
|
setError(resolveServersRegistryActionErrorMessage(loadError, 'Failed to load servers.'));
|
|
457
478
|
} finally {
|
|
458
479
|
setLoading(false);
|
|
459
480
|
}
|
|
460
|
-
}, [replaceServerDrafts, setCanEdit, setCurrentServerId, setError, setLoading, setServers]);
|
|
481
|
+
}, [replaceServerDrafts, setCanEdit, setCurrentServerId, setError, setIsStandaloneVps, setLoading, setServers]);
|
|
461
482
|
}
|
|
462
483
|
|
|
463
484
|
/**
|
|
@@ -626,6 +647,7 @@ function useDeleteCurrentServerAction(options: {
|
|
|
626
647
|
export function useServersRegistryState(): UseServersRegistryStateResult {
|
|
627
648
|
const [servers, setServers] = useState<ManagedServerRow[]>([]);
|
|
628
649
|
const [canEdit, setCanEdit] = useState(false);
|
|
650
|
+
const [isStandaloneVps, setIsStandaloneVps] = useState(false);
|
|
629
651
|
const [loading, setLoading] = useState(true);
|
|
630
652
|
const [error, setError] = useState<string | null>(null);
|
|
631
653
|
const [currentServerId, setCurrentServerId] = useState<number | null>(null);
|
|
@@ -646,6 +668,7 @@ export function useServersRegistryState(): UseServersRegistryStateResult {
|
|
|
646
668
|
setCanEdit,
|
|
647
669
|
setCurrentServerId,
|
|
648
670
|
setError,
|
|
671
|
+
setIsStandaloneVps,
|
|
649
672
|
setLoading,
|
|
650
673
|
setServers,
|
|
651
674
|
});
|
|
@@ -688,6 +711,7 @@ export function useServersRegistryState(): UseServersRegistryStateResult {
|
|
|
688
711
|
error,
|
|
689
712
|
hasDirtyServerDrafts,
|
|
690
713
|
isServerDraftDirty,
|
|
714
|
+
isStandaloneVps,
|
|
691
715
|
loading,
|
|
692
716
|
migrateServer,
|
|
693
717
|
migratingServerId,
|