@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
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { Loader2, Plus,
|
|
3
|
+
import { Loader2, Plus, Upload, X } from 'lucide-react';
|
|
4
4
|
import type { ChangeEvent, RefObject } from 'react';
|
|
5
5
|
import { Dialog } from '../../../components/Portal/Dialog';
|
|
6
|
-
import { SecretInput } from '../../../components/SecretInput/SecretInput';
|
|
7
|
-
import { SERVER_LANGUAGE_OPTIONS } from '../../../languages/ServerLanguageRegistry';
|
|
8
|
-
import { CHAT_FEEDBACK_MODE_OPTIONS } from '../../../utils/chatFeedbackMode';
|
|
9
|
-
import { MANAGED_SERVER_ENVIRONMENT_OPTIONS } from './useServersRegistryState';
|
|
10
6
|
import {
|
|
11
|
-
CREATE_SERVER_BOOLEAN_FEATURE_FLAGS,
|
|
12
|
-
CREATE_SERVER_WIZARD_STEPS,
|
|
13
7
|
type CreateServerWizardError,
|
|
14
8
|
type CreateServerWizardState,
|
|
15
|
-
type UpdateCreateServerAdditionalUser,
|
|
16
|
-
type UpdateCreateServerAdminField,
|
|
17
|
-
type UpdateCreateServerInitialSetting,
|
|
18
9
|
type UpdateCreateServerWizardField,
|
|
19
10
|
} from './useCreateServerWizard';
|
|
20
11
|
|
|
@@ -26,13 +17,6 @@ import {
|
|
|
26
17
|
const INPUT_CLASS_NAME =
|
|
27
18
|
'w-full rounded-md border border-gray-300 px-3 py-2 text-sm text-gray-900 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200';
|
|
28
19
|
|
|
29
|
-
/**
|
|
30
|
-
* Shared textarea class used across the create-server dialog.
|
|
31
|
-
*
|
|
32
|
-
* @private function of <ServersClient/>
|
|
33
|
-
*/
|
|
34
|
-
const TEXTAREA_CLASS_NAME = `${INPUT_CLASS_NAME} min-h-[120px]`;
|
|
35
|
-
|
|
36
20
|
/**
|
|
37
21
|
* Shared secondary button styling used by the create-server dialog.
|
|
38
22
|
*
|
|
@@ -49,30 +33,12 @@ const SECONDARY_BUTTON_CLASS_NAME =
|
|
|
49
33
|
const PRIMARY_BUTTON_CLASS_NAME =
|
|
50
34
|
'inline-flex items-center gap-2 rounded-md bg-blue-600 px-3 py-2 text-sm font-semibold text-white hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60';
|
|
51
35
|
|
|
52
|
-
/**
|
|
53
|
-
* Shared destructive button styling used by the create-server dialog.
|
|
54
|
-
*
|
|
55
|
-
* @private function of <ServersClient/>
|
|
56
|
-
*/
|
|
57
|
-
const DANGER_BUTTON_CLASS_NAME =
|
|
58
|
-
'inline-flex items-center gap-2 rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white hover:bg-red-700 disabled:cursor-not-allowed disabled:opacity-60';
|
|
59
|
-
|
|
60
36
|
/**
|
|
61
37
|
* Props consumed by `CreateServerDialog`.
|
|
62
38
|
*
|
|
63
39
|
* @private function of <ServersClient/>
|
|
64
40
|
*/
|
|
65
41
|
type CreateServerDialogProps = {
|
|
66
|
-
/**
|
|
67
|
-
* Adds a new optional bootstrap user row.
|
|
68
|
-
*/
|
|
69
|
-
readonly addAdditionalUser: () => void;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Derived table-prefix preview for the current identifier.
|
|
73
|
-
*/
|
|
74
|
-
readonly derivedWizardTablePrefix: string;
|
|
75
|
-
|
|
76
42
|
/**
|
|
77
43
|
* Persists the current wizard as a new server.
|
|
78
44
|
*/
|
|
@@ -83,21 +49,6 @@ type CreateServerDialogProps = {
|
|
|
83
49
|
*/
|
|
84
50
|
readonly handleIconUpload: (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
|
|
85
51
|
|
|
86
|
-
/**
|
|
87
|
-
* Moves the wizard one step backward.
|
|
88
|
-
*/
|
|
89
|
-
readonly handleWizardBack: () => void;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Moves the wizard one step forward.
|
|
93
|
-
*/
|
|
94
|
-
readonly handleWizardNext: () => Promise<void>;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Jumps to a specific wizard step when allowed.
|
|
98
|
-
*/
|
|
99
|
-
readonly handleWizardStepSelection: (nextStep: number) => Promise<void>;
|
|
100
|
-
|
|
101
52
|
/**
|
|
102
53
|
* Hidden file input reference used for icon uploads.
|
|
103
54
|
*/
|
|
@@ -118,11 +69,6 @@ type CreateServerDialogProps = {
|
|
|
118
69
|
*/
|
|
119
70
|
readonly isUploadingIcon: boolean;
|
|
120
71
|
|
|
121
|
-
/**
|
|
122
|
-
* Removes one optional bootstrap user row.
|
|
123
|
-
*/
|
|
124
|
-
readonly removeAdditionalUser: (index: number) => void;
|
|
125
|
-
|
|
126
72
|
/**
|
|
127
73
|
* Requests closing the dialog while respecting the dirty-state guard.
|
|
128
74
|
*/
|
|
@@ -133,21 +79,6 @@ type CreateServerDialogProps = {
|
|
|
133
79
|
*/
|
|
134
80
|
readonly resetWizard: () => void;
|
|
135
81
|
|
|
136
|
-
/**
|
|
137
|
-
* Updates one optional bootstrap user row.
|
|
138
|
-
*/
|
|
139
|
-
readonly updateAdditionalUser: UpdateCreateServerAdditionalUser;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Updates the required admin user fields.
|
|
143
|
-
*/
|
|
144
|
-
readonly updateAdminUser: UpdateCreateServerAdminField;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Updates one initial settings field.
|
|
148
|
-
*/
|
|
149
|
-
readonly updateInitialSetting: UpdateCreateServerInitialSetting;
|
|
150
|
-
|
|
151
82
|
/**
|
|
152
83
|
* Updates one top-level wizard field.
|
|
153
84
|
*/
|
|
@@ -162,49 +93,6 @@ type CreateServerDialogProps = {
|
|
|
162
93
|
* Current create-server form state.
|
|
163
94
|
*/
|
|
164
95
|
readonly wizardState: CreateServerWizardState;
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Current wizard step index.
|
|
168
|
-
*/
|
|
169
|
-
readonly wizardStep: number;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Props consumed by the profile-step helper.
|
|
174
|
-
*
|
|
175
|
-
* @private function of <ServersClient/>
|
|
176
|
-
*/
|
|
177
|
-
type CreateServerProfileStepProps = {
|
|
178
|
-
readonly derivedWizardTablePrefix: string;
|
|
179
|
-
readonly handleIconUpload: (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
|
|
180
|
-
readonly iconInputRef: RefObject<HTMLInputElement | null>;
|
|
181
|
-
readonly isUploadingIcon: boolean;
|
|
182
|
-
readonly updateWizardField: UpdateCreateServerWizardField;
|
|
183
|
-
readonly wizardState: CreateServerWizardState;
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Props consumed by the users-step helper.
|
|
188
|
-
*
|
|
189
|
-
* @private function of <ServersClient/>
|
|
190
|
-
*/
|
|
191
|
-
type CreateServerUsersStepProps = {
|
|
192
|
-
readonly addAdditionalUser: () => void;
|
|
193
|
-
readonly removeAdditionalUser: (index: number) => void;
|
|
194
|
-
readonly updateAdditionalUser: UpdateCreateServerAdditionalUser;
|
|
195
|
-
readonly updateAdminUser: UpdateCreateServerAdminField;
|
|
196
|
-
readonly wizardState: CreateServerWizardState;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Props consumed by the settings-step helper.
|
|
201
|
-
*
|
|
202
|
-
* @private function of <ServersClient/>
|
|
203
|
-
*/
|
|
204
|
-
type CreateServerSettingsStepProps = {
|
|
205
|
-
readonly derivedWizardTablePrefix: string;
|
|
206
|
-
readonly updateInitialSetting: UpdateCreateServerInitialSetting;
|
|
207
|
-
readonly wizardState: CreateServerWizardState;
|
|
208
96
|
};
|
|
209
97
|
|
|
210
98
|
/**
|
|
@@ -224,23 +112,22 @@ function downloadTextFile(filename: string, content: string): void {
|
|
|
224
112
|
}
|
|
225
113
|
|
|
226
114
|
/**
|
|
227
|
-
* Renders the
|
|
115
|
+
* Renders the visible fields of the simplified create-server flow.
|
|
228
116
|
*
|
|
229
|
-
* @param props -
|
|
230
|
-
* @returns
|
|
117
|
+
* @param props - Form props.
|
|
118
|
+
* @returns Simplified server setup form.
|
|
231
119
|
*/
|
|
232
|
-
function
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
} = props;
|
|
120
|
+
function CreateServerForm(props: {
|
|
121
|
+
readonly handleIconUpload: (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
|
|
122
|
+
readonly iconInputRef: RefObject<HTMLInputElement | null>;
|
|
123
|
+
readonly isUploadingIcon: boolean;
|
|
124
|
+
readonly updateWizardField: UpdateCreateServerWizardField;
|
|
125
|
+
readonly wizardState: CreateServerWizardState;
|
|
126
|
+
}) {
|
|
127
|
+
const { handleIconUpload, iconInputRef, isUploadingIcon, updateWizardField, wizardState } = props;
|
|
241
128
|
|
|
242
129
|
return (
|
|
243
|
-
<div className="
|
|
130
|
+
<div className="space-y-5">
|
|
244
131
|
<div>
|
|
245
132
|
<label htmlFor="create-server-name" className="mb-1 block text-sm font-medium text-gray-700">
|
|
246
133
|
Server name
|
|
@@ -254,53 +141,8 @@ function CreateServerProfileStep(props: CreateServerProfileStepProps) {
|
|
|
254
141
|
placeholder="Acme Support"
|
|
255
142
|
/>
|
|
256
143
|
</div>
|
|
144
|
+
|
|
257
145
|
<div>
|
|
258
|
-
<label htmlFor="create-server-identifier" className="mb-1 block text-sm font-medium text-gray-700">
|
|
259
|
-
Identifier / slug
|
|
260
|
-
</label>
|
|
261
|
-
<input
|
|
262
|
-
id="create-server-identifier"
|
|
263
|
-
type="text"
|
|
264
|
-
value={wizardState.identifier}
|
|
265
|
-
onChange={(event) => updateWizardField('identifier', event.target.value.toLowerCase())}
|
|
266
|
-
className={`${INPUT_CLASS_NAME} font-mono`}
|
|
267
|
-
placeholder="acme-support"
|
|
268
|
-
/>
|
|
269
|
-
<p className="mt-1 text-xs text-gray-500">Use lowercase letters, numbers, and hyphens only.</p>
|
|
270
|
-
</div>
|
|
271
|
-
<div>
|
|
272
|
-
<label htmlFor="create-server-table-prefix" className="mb-1 block text-sm font-medium text-gray-700">
|
|
273
|
-
Derived table prefix
|
|
274
|
-
</label>
|
|
275
|
-
<input
|
|
276
|
-
id="create-server-table-prefix"
|
|
277
|
-
type="text"
|
|
278
|
-
value={derivedWizardTablePrefix}
|
|
279
|
-
readOnly
|
|
280
|
-
className={`${INPUT_CLASS_NAME} bg-gray-50 font-mono text-gray-600`}
|
|
281
|
-
placeholder="server_AcmeSupport_"
|
|
282
|
-
/>
|
|
283
|
-
</div>
|
|
284
|
-
<div>
|
|
285
|
-
<label htmlFor="create-server-environment" className="mb-1 block text-sm font-medium text-gray-700">
|
|
286
|
-
Environment
|
|
287
|
-
</label>
|
|
288
|
-
<select
|
|
289
|
-
id="create-server-environment"
|
|
290
|
-
value={wizardState.environment}
|
|
291
|
-
onChange={(event) =>
|
|
292
|
-
updateWizardField('environment', event.target.value as CreateServerWizardState['environment'])
|
|
293
|
-
}
|
|
294
|
-
className={INPUT_CLASS_NAME}
|
|
295
|
-
>
|
|
296
|
-
{MANAGED_SERVER_ENVIRONMENT_OPTIONS.map((environment) => (
|
|
297
|
-
<option key={environment} value={environment}>
|
|
298
|
-
{environment}
|
|
299
|
-
</option>
|
|
300
|
-
))}
|
|
301
|
-
</select>
|
|
302
|
-
</div>
|
|
303
|
-
<div className="md:col-span-2">
|
|
304
146
|
<label htmlFor="create-server-domain" className="mb-1 block text-sm font-medium text-gray-700">
|
|
305
147
|
Domain
|
|
306
148
|
</label>
|
|
@@ -313,18 +155,19 @@ function CreateServerProfileStep(props: CreateServerProfileStepProps) {
|
|
|
313
155
|
placeholder="acme-support.ptbk.io"
|
|
314
156
|
/>
|
|
315
157
|
</div>
|
|
316
|
-
|
|
158
|
+
|
|
159
|
+
<div>
|
|
317
160
|
<label htmlFor="create-server-icon-url" className="mb-1 block text-sm font-medium text-gray-700">
|
|
318
161
|
Server icon
|
|
319
162
|
</label>
|
|
320
|
-
<div className="flex flex-col gap-3
|
|
163
|
+
<div className="flex flex-col gap-3 sm:flex-row">
|
|
321
164
|
<input
|
|
322
165
|
id="create-server-icon-url"
|
|
323
166
|
type="text"
|
|
324
167
|
value={wizardState.iconUrl}
|
|
325
168
|
onChange={(event) => updateWizardField('iconUrl', event.target.value)}
|
|
326
169
|
className={INPUT_CLASS_NAME}
|
|
327
|
-
placeholder="
|
|
170
|
+
placeholder="Optional icon URL"
|
|
328
171
|
/>
|
|
329
172
|
<input
|
|
330
173
|
ref={iconInputRef}
|
|
@@ -339,8 +182,8 @@ function CreateServerProfileStep(props: CreateServerProfileStepProps) {
|
|
|
339
182
|
disabled={isUploadingIcon}
|
|
340
183
|
className={SECONDARY_BUTTON_CLASS_NAME}
|
|
341
184
|
>
|
|
342
|
-
{isUploadingIcon ? <Loader2 className="h-4 w-4 animate-spin" /> :
|
|
343
|
-
Upload
|
|
185
|
+
{isUploadingIcon ? <Loader2 className="h-4 w-4 animate-spin" /> : <Upload className="h-4 w-4" />}
|
|
186
|
+
Upload
|
|
344
187
|
</button>
|
|
345
188
|
</div>
|
|
346
189
|
{wizardState.iconUrl ? (
|
|
@@ -352,251 +195,21 @@ function CreateServerProfileStep(props: CreateServerProfileStepProps) {
|
|
|
352
195
|
className="h-16 w-16 rounded-lg object-cover"
|
|
353
196
|
/>
|
|
354
197
|
</div>
|
|
355
|
-
) :
|
|
356
|
-
<p className="mt-2 text-xs text-gray-500">
|
|
357
|
-
Leave the icon empty to keep the default branding assets.
|
|
358
|
-
</p>
|
|
359
|
-
)}
|
|
360
|
-
</div>
|
|
361
|
-
</div>
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* Renders the users step of the create-server wizard.
|
|
367
|
-
*
|
|
368
|
-
* @param props - Step props.
|
|
369
|
-
* @returns User-step form fields.
|
|
370
|
-
*/
|
|
371
|
-
function CreateServerUsersStep(props: CreateServerUsersStepProps) {
|
|
372
|
-
const { addAdditionalUser, removeAdditionalUser, updateAdditionalUser, updateAdminUser, wizardState } = props;
|
|
373
|
-
|
|
374
|
-
return (
|
|
375
|
-
<div className="space-y-6">
|
|
376
|
-
<div className="rounded-xl border border-gray-200 bg-gray-50 p-4">
|
|
377
|
-
<div className="mb-4">
|
|
378
|
-
<h3 className="text-base font-semibold text-gray-900">Required admin user</h3>
|
|
379
|
-
<p className="mt-1 text-sm text-gray-500">
|
|
380
|
-
This admin belongs to the new server itself, not necessarily to the creating user.
|
|
381
|
-
</p>
|
|
382
|
-
</div>
|
|
383
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
384
|
-
<div>
|
|
385
|
-
<label
|
|
386
|
-
htmlFor="create-server-admin-username"
|
|
387
|
-
className="mb-1 block text-sm font-medium text-gray-700"
|
|
388
|
-
>
|
|
389
|
-
Admin username
|
|
390
|
-
</label>
|
|
391
|
-
<input
|
|
392
|
-
id="create-server-admin-username"
|
|
393
|
-
type="text"
|
|
394
|
-
value={wizardState.adminUser.username}
|
|
395
|
-
onChange={(event) => updateAdminUser('username', event.target.value)}
|
|
396
|
-
className={INPUT_CLASS_NAME}
|
|
397
|
-
placeholder="admin"
|
|
398
|
-
/>
|
|
399
|
-
</div>
|
|
400
|
-
<SecretInput
|
|
401
|
-
label="Admin password"
|
|
402
|
-
value={wizardState.adminUser.password}
|
|
403
|
-
onChange={(event) => updateAdminUser('password', event.target.value)}
|
|
404
|
-
placeholder="Required"
|
|
405
|
-
helperText="Password validation uses the same rules as the existing server admin flow."
|
|
406
|
-
/>
|
|
407
|
-
</div>
|
|
408
|
-
</div>
|
|
409
|
-
|
|
410
|
-
<div className="space-y-4">
|
|
411
|
-
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
|
412
|
-
<div>
|
|
413
|
-
<h3 className="text-base font-semibold text-gray-900">Additional users</h3>
|
|
414
|
-
<p className="mt-1 text-sm text-gray-500">
|
|
415
|
-
Optional bootstrap users created immediately after migrations finish.
|
|
416
|
-
</p>
|
|
417
|
-
</div>
|
|
418
|
-
<button type="button" onClick={addAdditionalUser} className={SECONDARY_BUTTON_CLASS_NAME}>
|
|
419
|
-
<Plus className="h-4 w-4" />
|
|
420
|
-
Add user
|
|
421
|
-
</button>
|
|
422
|
-
</div>
|
|
423
|
-
|
|
424
|
-
{wizardState.additionalUsers.length === 0 ? (
|
|
425
|
-
<div className="rounded-lg border border-dashed border-gray-300 bg-gray-50 p-4 text-sm text-gray-500">
|
|
426
|
-
No extra users will be created unless you add them here.
|
|
427
|
-
</div>
|
|
428
|
-
) : (
|
|
429
|
-
<div className="space-y-3">
|
|
430
|
-
{wizardState.additionalUsers.map((user, index) => (
|
|
431
|
-
<div
|
|
432
|
-
key={`wizard-user-${index}`}
|
|
433
|
-
className="rounded-xl border border-gray-200 bg-white p-4"
|
|
434
|
-
>
|
|
435
|
-
<div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_160px_auto]">
|
|
436
|
-
<div>
|
|
437
|
-
<label
|
|
438
|
-
htmlFor={`create-server-user-${index}-username`}
|
|
439
|
-
className="mb-1 block text-sm font-medium text-gray-700"
|
|
440
|
-
>
|
|
441
|
-
Username
|
|
442
|
-
</label>
|
|
443
|
-
<input
|
|
444
|
-
id={`create-server-user-${index}-username`}
|
|
445
|
-
type="text"
|
|
446
|
-
value={user.username}
|
|
447
|
-
onChange={(event) =>
|
|
448
|
-
updateAdditionalUser(index, 'username', event.target.value)
|
|
449
|
-
}
|
|
450
|
-
className={INPUT_CLASS_NAME}
|
|
451
|
-
placeholder={`user-${index + 1}`}
|
|
452
|
-
/>
|
|
453
|
-
</div>
|
|
454
|
-
<SecretInput
|
|
455
|
-
label="Password"
|
|
456
|
-
value={user.password}
|
|
457
|
-
onChange={(event) =>
|
|
458
|
-
updateAdditionalUser(index, 'password', event.target.value)
|
|
459
|
-
}
|
|
460
|
-
placeholder="Required"
|
|
461
|
-
/>
|
|
462
|
-
<label className="flex items-center gap-3 rounded-md border border-gray-200 bg-gray-50 px-3 py-2 text-sm font-medium text-gray-700 lg:mt-7">
|
|
463
|
-
<input
|
|
464
|
-
type="checkbox"
|
|
465
|
-
checked={user.isAdmin}
|
|
466
|
-
onChange={(event) =>
|
|
467
|
-
updateAdditionalUser(index, 'isAdmin', event.target.checked)
|
|
468
|
-
}
|
|
469
|
-
className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
|
|
470
|
-
/>
|
|
471
|
-
Admin
|
|
472
|
-
</label>
|
|
473
|
-
<div className="flex items-end">
|
|
474
|
-
<button
|
|
475
|
-
type="button"
|
|
476
|
-
onClick={() => removeAdditionalUser(index)}
|
|
477
|
-
className={`${DANGER_BUTTON_CLASS_NAME} w-full justify-center lg:mt-7`}
|
|
478
|
-
>
|
|
479
|
-
<Trash2 className="h-4 w-4" />
|
|
480
|
-
Remove
|
|
481
|
-
</button>
|
|
482
|
-
</div>
|
|
483
|
-
</div>
|
|
484
|
-
</div>
|
|
485
|
-
))}
|
|
486
|
-
</div>
|
|
487
|
-
)}
|
|
488
|
-
</div>
|
|
489
|
-
</div>
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Renders the settings step of the create-server wizard.
|
|
495
|
-
*
|
|
496
|
-
* @param props - Step props.
|
|
497
|
-
* @returns Settings-step form fields.
|
|
498
|
-
*/
|
|
499
|
-
function CreateServerSettingsStep(props: CreateServerSettingsStepProps) {
|
|
500
|
-
const { derivedWizardTablePrefix, updateInitialSetting, wizardState } = props;
|
|
501
|
-
|
|
502
|
-
return (
|
|
503
|
-
<div className="space-y-6">
|
|
504
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
505
|
-
<div>
|
|
506
|
-
<label htmlFor="create-server-language" className="mb-1 block text-sm font-medium text-gray-700">
|
|
507
|
-
Initial language
|
|
508
|
-
</label>
|
|
509
|
-
<select
|
|
510
|
-
id="create-server-language"
|
|
511
|
-
value={wizardState.initialSettings.language}
|
|
512
|
-
onChange={(event) => updateInitialSetting('language', event.target.value)}
|
|
513
|
-
className={INPUT_CLASS_NAME}
|
|
514
|
-
>
|
|
515
|
-
{SERVER_LANGUAGE_OPTIONS.map((option) => (
|
|
516
|
-
<option key={option.value} value={option.value}>
|
|
517
|
-
{option.label}
|
|
518
|
-
</option>
|
|
519
|
-
))}
|
|
520
|
-
</select>
|
|
521
|
-
</div>
|
|
522
|
-
<div className="rounded-xl border border-gray-200 bg-gray-50 p-4 text-sm text-gray-600">
|
|
523
|
-
<p className="font-semibold text-gray-900">Bootstrap summary</p>
|
|
524
|
-
<p className="mt-2">
|
|
525
|
-
The new server will be created as <strong>{wizardState.name || 'Unnamed server'}</strong> on{' '}
|
|
526
|
-
<strong>{wizardState.domain || 'pending domain'}</strong> with prefix{' '}
|
|
527
|
-
<code>{derivedWizardTablePrefix || 'pending prefix'}</code>.
|
|
528
|
-
</p>
|
|
529
|
-
<p className="mt-2">
|
|
530
|
-
Bootstrap users: <strong>{1 + wizardState.additionalUsers.length}</strong>
|
|
531
|
-
</p>
|
|
532
|
-
</div>
|
|
533
|
-
<div className="md:col-span-2">
|
|
534
|
-
<label
|
|
535
|
-
htmlFor="create-server-homepage-message"
|
|
536
|
-
className="mb-1 block text-sm font-medium text-gray-700"
|
|
537
|
-
>
|
|
538
|
-
Homepage message
|
|
539
|
-
</label>
|
|
540
|
-
<textarea
|
|
541
|
-
id="create-server-homepage-message"
|
|
542
|
-
value={wizardState.initialSettings.homepageMessage}
|
|
543
|
-
onChange={(event) => updateInitialSetting('homepageMessage', event.target.value)}
|
|
544
|
-
className={TEXTAREA_CLASS_NAME}
|
|
545
|
-
placeholder="Optional markdown shown on the new server homepage."
|
|
546
|
-
/>
|
|
547
|
-
</div>
|
|
548
|
-
<div>
|
|
549
|
-
<label
|
|
550
|
-
htmlFor="create-server-feedback-mode"
|
|
551
|
-
className="mb-1 block text-sm font-medium text-gray-700"
|
|
552
|
-
>
|
|
553
|
-
Chat feedback mode
|
|
554
|
-
</label>
|
|
555
|
-
<select
|
|
556
|
-
id="create-server-feedback-mode"
|
|
557
|
-
value={wizardState.initialSettings.feedbackMode}
|
|
558
|
-
onChange={(event) =>
|
|
559
|
-
updateInitialSetting(
|
|
560
|
-
'feedbackMode',
|
|
561
|
-
event.target.value as CreateServerWizardState['initialSettings']['feedbackMode'],
|
|
562
|
-
)
|
|
563
|
-
}
|
|
564
|
-
className={INPUT_CLASS_NAME}
|
|
565
|
-
>
|
|
566
|
-
{CHAT_FEEDBACK_MODE_OPTIONS.map((option) => (
|
|
567
|
-
<option key={option.value} value={option.value}>
|
|
568
|
-
{option.label}
|
|
569
|
-
</option>
|
|
570
|
-
))}
|
|
571
|
-
</select>
|
|
572
|
-
</div>
|
|
198
|
+
) : null}
|
|
573
199
|
</div>
|
|
574
200
|
|
|
575
|
-
<div className="
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
>
|
|
581
|
-
<input
|
|
582
|
-
type="checkbox"
|
|
583
|
-
checked={wizardState.initialSettings[flag.key]}
|
|
584
|
-
onChange={(event) => updateInitialSetting(flag.key, event.target.checked)}
|
|
585
|
-
className="mt-1 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
|
|
586
|
-
/>
|
|
587
|
-
<div>
|
|
588
|
-
<div className="text-sm font-semibold text-gray-900">{flag.title}</div>
|
|
589
|
-
<div className="mt-1 text-sm text-gray-500">{flag.description}</div>
|
|
590
|
-
</div>
|
|
591
|
-
</label>
|
|
592
|
-
))}
|
|
201
|
+
<div className="rounded-lg border border-gray-200 bg-gray-50 p-4 text-sm text-gray-600">
|
|
202
|
+
<p className="font-semibold text-gray-900">Admin user exists</p>
|
|
203
|
+
<p className="mt-1">
|
|
204
|
+
The installer-created <span className="font-mono">admin</span> user is used for this server.
|
|
205
|
+
</p>
|
|
593
206
|
</div>
|
|
594
207
|
</div>
|
|
595
208
|
);
|
|
596
209
|
}
|
|
597
210
|
|
|
598
211
|
/**
|
|
599
|
-
* Renders the
|
|
212
|
+
* Renders the simplified create-server dialog.
|
|
600
213
|
*
|
|
601
214
|
* @param props - Dialog props.
|
|
602
215
|
* @returns Modal dialog when open, otherwise `null`.
|
|
@@ -605,68 +218,30 @@ function CreateServerSettingsStep(props: CreateServerSettingsStepProps) {
|
|
|
605
218
|
*/
|
|
606
219
|
export function CreateServerDialog(props: CreateServerDialogProps) {
|
|
607
220
|
const {
|
|
608
|
-
addAdditionalUser,
|
|
609
|
-
derivedWizardTablePrefix,
|
|
610
221
|
handleCreateServer,
|
|
611
222
|
handleIconUpload,
|
|
612
|
-
handleWizardBack,
|
|
613
|
-
handleWizardNext,
|
|
614
|
-
handleWizardStepSelection,
|
|
615
223
|
iconInputRef,
|
|
616
224
|
isCreatingServer,
|
|
617
225
|
isOpen,
|
|
618
226
|
isUploadingIcon,
|
|
619
|
-
removeAdditionalUser,
|
|
620
227
|
requestClose,
|
|
621
228
|
resetWizard,
|
|
622
|
-
updateAdditionalUser,
|
|
623
|
-
updateAdminUser,
|
|
624
|
-
updateInitialSetting,
|
|
625
229
|
updateWizardField,
|
|
626
230
|
wizardError,
|
|
627
231
|
wizardState,
|
|
628
|
-
wizardStep,
|
|
629
232
|
} = props;
|
|
630
233
|
|
|
631
234
|
if (!isOpen) {
|
|
632
235
|
return null;
|
|
633
236
|
}
|
|
634
237
|
|
|
635
|
-
const currentStepContent =
|
|
636
|
-
wizardStep === 0 ? (
|
|
637
|
-
<CreateServerProfileStep
|
|
638
|
-
derivedWizardTablePrefix={derivedWizardTablePrefix}
|
|
639
|
-
handleIconUpload={handleIconUpload}
|
|
640
|
-
iconInputRef={iconInputRef}
|
|
641
|
-
isUploadingIcon={isUploadingIcon}
|
|
642
|
-
updateWizardField={updateWizardField}
|
|
643
|
-
wizardState={wizardState}
|
|
644
|
-
/>
|
|
645
|
-
) : wizardStep === 1 ? (
|
|
646
|
-
<CreateServerUsersStep
|
|
647
|
-
addAdditionalUser={addAdditionalUser}
|
|
648
|
-
removeAdditionalUser={removeAdditionalUser}
|
|
649
|
-
updateAdditionalUser={updateAdditionalUser}
|
|
650
|
-
updateAdminUser={updateAdminUser}
|
|
651
|
-
wizardState={wizardState}
|
|
652
|
-
/>
|
|
653
|
-
) : (
|
|
654
|
-
<CreateServerSettingsStep
|
|
655
|
-
derivedWizardTablePrefix={derivedWizardTablePrefix}
|
|
656
|
-
updateInitialSetting={updateInitialSetting}
|
|
657
|
-
wizardState={wizardState}
|
|
658
|
-
/>
|
|
659
|
-
);
|
|
660
|
-
|
|
661
238
|
return (
|
|
662
|
-
<Dialog onClose={requestClose} className="mx-4 w-full max-w-
|
|
239
|
+
<Dialog onClose={requestClose} className="mx-4 w-full max-w-2xl overflow-hidden">
|
|
663
240
|
<div className="max-h-[90vh] overflow-y-auto">
|
|
664
241
|
<div className="flex items-start justify-between gap-4 border-b border-gray-200 px-6 py-5">
|
|
665
242
|
<div>
|
|
666
243
|
<h2 className="text-xl font-semibold text-gray-900">Create new server</h2>
|
|
667
|
-
<p className="mt-1 text-sm text-gray-500">
|
|
668
|
-
Create a server with its initial users and settings.
|
|
669
|
-
</p>
|
|
244
|
+
<p className="mt-1 text-sm text-gray-500">Add the public server identity and domain.</p>
|
|
670
245
|
</div>
|
|
671
246
|
<button
|
|
672
247
|
type="button"
|
|
@@ -679,27 +254,6 @@ export function CreateServerDialog(props: CreateServerDialogProps) {
|
|
|
679
254
|
</div>
|
|
680
255
|
|
|
681
256
|
<div className="space-y-6 px-6 py-6">
|
|
682
|
-
<div className="grid gap-3 md:grid-cols-3">
|
|
683
|
-
{CREATE_SERVER_WIZARD_STEPS.map((step, index) => (
|
|
684
|
-
<button
|
|
685
|
-
key={step.title}
|
|
686
|
-
type="button"
|
|
687
|
-
onClick={() => void handleWizardStepSelection(index)}
|
|
688
|
-
className={`rounded-xl border p-4 text-left transition ${
|
|
689
|
-
index === wizardStep
|
|
690
|
-
? 'border-blue-500 bg-blue-50 text-blue-700 shadow-sm'
|
|
691
|
-
: index < wizardStep
|
|
692
|
-
? 'border-emerald-200 bg-emerald-50 text-emerald-700'
|
|
693
|
-
: 'border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50'
|
|
694
|
-
}`}
|
|
695
|
-
>
|
|
696
|
-
<div className="text-xs font-semibold uppercase tracking-wide">Step {index + 1}</div>
|
|
697
|
-
<div className="mt-1 text-base font-semibold">{step.title}</div>
|
|
698
|
-
<div className="mt-1 text-sm text-current/80">{step.description}</div>
|
|
699
|
-
</button>
|
|
700
|
-
))}
|
|
701
|
-
</div>
|
|
702
|
-
|
|
703
257
|
{wizardError ? (
|
|
704
258
|
<div className="rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-800">
|
|
705
259
|
<p className="font-semibold">Server creation failed</p>
|
|
@@ -719,7 +273,7 @@ export function CreateServerDialog(props: CreateServerDialogProps) {
|
|
|
719
273
|
Download SQL dump
|
|
720
274
|
</button>
|
|
721
275
|
<span className="text-xs text-red-700">
|
|
722
|
-
|
|
276
|
+
Send the dump to support@ptbk.io if manual recovery is needed.
|
|
723
277
|
</span>
|
|
724
278
|
</div>
|
|
725
279
|
) : (
|
|
@@ -730,7 +284,13 @@ export function CreateServerDialog(props: CreateServerDialogProps) {
|
|
|
730
284
|
</div>
|
|
731
285
|
) : null}
|
|
732
286
|
|
|
733
|
-
|
|
287
|
+
<CreateServerForm
|
|
288
|
+
handleIconUpload={handleIconUpload}
|
|
289
|
+
iconInputRef={iconInputRef}
|
|
290
|
+
isUploadingIcon={isUploadingIcon}
|
|
291
|
+
updateWizardField={updateWizardField}
|
|
292
|
+
wizardState={wizardState}
|
|
293
|
+
/>
|
|
734
294
|
|
|
735
295
|
<div className="flex flex-col gap-3 border-t border-gray-100 pt-6 sm:flex-row sm:items-center sm:justify-between">
|
|
736
296
|
<p className="text-xs text-gray-500">
|
|
@@ -747,36 +307,17 @@ export function CreateServerDialog(props: CreateServerDialogProps) {
|
|
|
747
307
|
</button>
|
|
748
308
|
<button
|
|
749
309
|
type="button"
|
|
750
|
-
onClick={
|
|
751
|
-
disabled={
|
|
752
|
-
className={
|
|
310
|
+
onClick={() => void handleCreateServer()}
|
|
311
|
+
disabled={isCreatingServer || isUploadingIcon}
|
|
312
|
+
className={PRIMARY_BUTTON_CLASS_NAME}
|
|
753
313
|
>
|
|
754
|
-
|
|
314
|
+
{isCreatingServer ? (
|
|
315
|
+
<Loader2 className="h-4 w-4 animate-spin" />
|
|
316
|
+
) : (
|
|
317
|
+
<Plus className="h-4 w-4" />
|
|
318
|
+
)}
|
|
319
|
+
Create server
|
|
755
320
|
</button>
|
|
756
|
-
{wizardStep < CREATE_SERVER_WIZARD_STEPS.length - 1 ? (
|
|
757
|
-
<button
|
|
758
|
-
type="button"
|
|
759
|
-
onClick={() => void handleWizardNext()}
|
|
760
|
-
disabled={isCreatingServer || isUploadingIcon}
|
|
761
|
-
className={PRIMARY_BUTTON_CLASS_NAME}
|
|
762
|
-
>
|
|
763
|
-
Next
|
|
764
|
-
</button>
|
|
765
|
-
) : (
|
|
766
|
-
<button
|
|
767
|
-
type="button"
|
|
768
|
-
onClick={() => void handleCreateServer()}
|
|
769
|
-
disabled={isCreatingServer || isUploadingIcon}
|
|
770
|
-
className={PRIMARY_BUTTON_CLASS_NAME}
|
|
771
|
-
>
|
|
772
|
-
{isCreatingServer ? (
|
|
773
|
-
<Loader2 className="h-4 w-4 animate-spin" />
|
|
774
|
-
) : (
|
|
775
|
-
<Plus className="h-4 w-4" />
|
|
776
|
-
)}
|
|
777
|
-
Create server
|
|
778
|
-
</button>
|
|
779
|
-
)}
|
|
780
321
|
</div>
|
|
781
322
|
</div>
|
|
782
323
|
</div>
|