@plutocms/supabase 0.30.0 → 0.31.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.
@@ -1,11 +1,10 @@
1
1
  <script setup lang="ts">
2
- import type { StepperItem } from '@nuxt/ui'
3
-
2
+ // Before any account exists: the layout and the card of the admin auth pages.
4
3
  definePageMeta({
5
- layout: 'setup',
4
+ layout: 'auth',
6
5
  })
7
6
 
8
- const { t, uiLocale } = usePlutoI18n()
7
+ const { t } = usePlutoI18n()
9
8
 
10
9
  useHead({
11
10
  title: () => t('supabase.setup.title'),
@@ -20,21 +19,9 @@ const toast = useToast()
20
19
 
21
20
  const isDev = import.meta.dev
22
21
 
23
- const items = computed<StepperItem[]>(() => [
24
- {
25
- title: t('supabase.setup.steps.database'),
26
- icon: 'i-lucide-database',
27
- },
28
-
29
- {
30
- title: t('supabase.setup.steps.complete'),
31
- icon: 'i-lucide-check',
32
- },
33
- ])
34
-
35
- const stepper = useTemplateRef('stepper')
36
-
37
- const currentStep = ref<number>(0)
22
+ // The form, then the result (after a setup that worked).
23
+ const done = ref(false)
24
+ const detailsOpen = ref(false)
38
25
 
39
26
  const isSettingUpDatabase = ref(false)
40
27
 
@@ -49,33 +36,9 @@ const databaseForm = ref({
49
36
  const envNotPersisted = ref(false)
50
37
  const submittedConnectionString = ref('')
51
38
 
52
- const currentLoading = computed(() => {
53
- if (currentStep.value === 0) {
54
- return isSettingUpDatabase.value
55
- }
56
-
57
- return false
58
- })
59
-
60
- const currentStepId = computed(() => {
61
- if (currentStep.value === 0) {
62
- return 'database-setup-form'
63
- }
64
-
65
- return undefined
66
- })
67
-
68
- const currentStepSubmitLabel = computed(() => {
69
- if (currentStep.value === 0) {
70
- return t('supabase.setup.submit')
71
- }
72
-
73
- return t('supabase.setup.next')
74
- })
75
-
76
39
  /**
77
40
  * Polls /api/_pluto/supabase/setup until the dev server responds again, and
78
- * advances the stepper once it does.
41
+ * shows the result once it does.
79
42
  *
80
43
  * Used only to wait out the restart described in the `catch` block of
81
44
  * `completeDatabaseSetup` — the server is expected to come back within a
@@ -98,7 +61,7 @@ async function waitForServerAndAdvance(): Promise<boolean> {
98
61
  color: 'success',
99
62
  })
100
63
 
101
- stepper.value?.next()
64
+ done.value = true
102
65
 
103
66
  return true
104
67
  } catch {
@@ -137,7 +100,7 @@ async function completeDatabaseSetup() {
137
100
  color: 'success',
138
101
  })
139
102
 
140
- stepper.value?.next()
103
+ done.value = true
141
104
  } catch (error) {
142
105
  // The route answers a failed setup with an HTTP error that carries the
143
106
  // scrubbed database error in its data.
@@ -203,238 +166,164 @@ async function completeDatabaseSetup() {
203
166
  isSettingUpDatabase.value = false
204
167
  }
205
168
  }
206
-
207
- function handleStepChange(step: number) {
208
- if (step === 0) {
209
- completeDatabaseSetup()
210
- }
211
- }
212
169
  </script>
213
170
 
214
171
  <template>
215
- <UApp :locale="uiLocale">
216
- <div class="flex min-h-dvh items-center justify-center p-4">
217
- <UCard class="w-full max-w-125">
218
- <div class="flex flex-col gap-y-8">
219
- <UStepper ref="stepper" v-model="currentStep" :items="items" linear />
220
-
221
- <div>
222
- <section v-if="currentStep === 0">
223
- <UForm
224
- id="database-setup-form"
225
- class="flex flex-col gap-y-4"
226
- @submit="handleStepChange(currentStep)"
172
+ <PlutoAdminAuthCard
173
+ :title="done ? t('supabase.setup.doneTitle') : t('supabase.setup.title')"
174
+ :description="
175
+ done
176
+ ? t('supabase.setup.doneDescription')
177
+ : t('supabase.setup.description')
178
+ "
179
+ wide
180
+ >
181
+ <template #partner>
182
+ <UIcon
183
+ name="i-lucide-arrow-right"
184
+ class="text-dimmed size-4 shrink-0"
185
+ aria-hidden="true"
186
+ />
187
+ <SupabaseLogo class="size-7 shrink-0" role="img" aria-label="Supabase" />
188
+ </template>
189
+
190
+ <template v-if="done">
191
+ <EnvPersistWarning
192
+ v-if="envNotPersisted"
193
+ :connection-string="submittedConnectionString"
194
+ />
195
+
196
+ <UButton
197
+ :label="t('supabase.setup.goToSignup')"
198
+ to="/admin/signup"
199
+ trailing-icon="lucide:arrow-right"
200
+ class="w-full justify-center"
201
+ />
202
+ </template>
203
+
204
+ <UForm v-else class="flex flex-col gap-y-5" @submit="completeDatabaseSetup">
205
+ <UFormField :label="t('supabase.connection.connectionString')" required>
206
+ <UInput
207
+ v-model="databaseForm.connectionString"
208
+ :disabled="isSettingUpDatabase"
209
+ placeholder="postgresql://"
210
+ class="w-full"
211
+ autofocus
212
+ required
213
+ />
214
+
215
+ <template #help>
216
+ <SupabaseMessageParts :message="t('supabase.setup.connectionHelp')">
217
+ <template #link>
218
+ <PlutoExternalLink
219
+ :to="`https://supabase.com/dashboard/project/${projectId}/database/settings?showConnect=true&method=transaction`"
220
+ class="text-default underline"
221
+ >
222
+ {{ t('supabase.setup.connectionHelpLink') }}
223
+ </PlutoExternalLink>
224
+ </template>
225
+ </SupabaseMessageParts>
226
+ </template>
227
+ </UFormField>
228
+
229
+ <UFormField :label="t('supabase.connection.password')" required>
230
+ <UInput
231
+ v-model="databaseForm.password"
232
+ :disabled="isSettingUpDatabase"
233
+ type="password"
234
+ placeholder="• • • • •"
235
+ class="w-full"
236
+ required
237
+ />
238
+
239
+ <template #help>
240
+ <SupabaseMessageParts :message="t('supabase.setup.passwordHelp')">
241
+ <template #placeholder>
242
+ <code>[YOUR-PASSWORD]</code>
243
+ </template>
244
+
245
+ <template #link>
246
+ <PlutoExternalLink
247
+ :to="`https://supabase.com/dashboard/project/${projectId ?? '_'}/database/settings`"
248
+ class="text-default underline"
227
249
  >
228
- <UFormField
229
- :label="t('supabase.connection.connectionString')"
230
- required
250
+ {{ t('supabase.setup.passwordHelpLink') }}
251
+ </PlutoExternalLink>
252
+ </template>
253
+ </SupabaseMessageParts>
254
+ </template>
255
+ </UFormField>
256
+
257
+ <!-- Where the connection goes, and how the setup works (folded). -->
258
+ <div
259
+ class="bg-elevated/50 ring-default flex flex-col gap-y-1 rounded-md p-3 ring"
260
+ >
261
+ <div class="flex gap-x-2 text-sm">
262
+ <UIcon name="lucide:lock" class="text-muted mt-0.5 size-4 shrink-0" />
263
+ <p class="text-muted">
264
+ <PlutoCodeText :text="t('supabase.setup.stored')" />
265
+ </p>
266
+ </div>
267
+
268
+ <UCollapsible v-model:open="detailsOpen">
269
+ <UButton
270
+ :label="t('supabase.setup.howItWorks')"
271
+ :trailing-icon="
272
+ detailsOpen ? 'lucide:chevron-up' : 'lucide:chevron-down'
273
+ "
274
+ color="neutral"
275
+ variant="link"
276
+ size="sm"
277
+ class="ms-4 px-2"
278
+ />
279
+
280
+ <template #content>
281
+ <ul
282
+ class="text-muted ms-6 flex list-disc flex-col gap-y-1 ps-4 pt-1 text-sm"
283
+ >
284
+ <li>
285
+ <SupabaseMessageParts
286
+ :message="t('supabase.setup.detailsRequest')"
231
287
  >
232
- <UInput
233
- v-model="databaseForm.connectionString"
234
- :disabled="isSettingUpDatabase"
235
- placeholder="postgresql://"
236
- autofocus
237
- required
238
- />
239
-
240
- <template #help>
241
- <SupabaseMessageParts
242
- :message="t('supabase.connection.connectionStringHelp')"
288
+ <template #route>
289
+ <PlutoExternalLink
290
+ to="https://github.com/plutocms/supabase/blob/main/packages/supabase/server/api/_pluto/supabase/setup/index.post.ts"
291
+ class="text-default underline"
243
292
  >
244
- <template #link>
245
- <ULink
246
- :to="`https://supabase.com/dashboard/project/${projectId}/database/settings?showConnect=true&method=transaction`"
247
- target="_blank"
248
- class="underline"
249
- external
250
- >
251
- {{
252
- t('supabase.connection.connectionStringHelpLink')
253
- }}
254
- </ULink>
255
- </template>
256
- </SupabaseMessageParts>
293
+ {{ t('supabase.setup.detailsRoute') }}
294
+ </PlutoExternalLink>
257
295
  </template>
258
- </UFormField>
259
-
260
- <UFormField :label="t('supabase.connection.password')" required>
261
- <UInput
262
- v-model="databaseForm.password"
263
- :disabled="isSettingUpDatabase"
264
- type="password"
265
- placeholder="• • • • •"
266
- required
267
- />
268
- </UFormField>
269
-
270
- <UAlert
271
- color="secondary"
272
- icon="lucide:badge-info"
273
- variant="outline"
274
- >
275
- <template #description>
276
- <SupabaseMessageParts
277
- :message="t('supabase.connection.passwordInfo')"
296
+ </SupabaseMessageParts>
297
+ </li>
298
+ <li>
299
+ <SupabaseMessageParts :message="t('supabase.setup.detailsRun')">
300
+ <template #files>
301
+ <PlutoExternalLink
302
+ to="https://github.com/plutocms/supabase/tree/main/packages/supabase/db/migrations"
303
+ class="text-default underline"
278
304
  >
279
- <template #link>
280
- <ULink
281
- to="https://supabase.com/dashboard/project/_/database/settings"
282
- target="_blank"
283
- >
284
- {{ t('supabase.connection.passwordInfoLink') }}
285
- </ULink>
286
- </template>
287
- </SupabaseMessageParts>
305
+ {{ t('supabase.setup.detailsFiles') }}
306
+ </PlutoExternalLink>
288
307
  </template>
289
- </UAlert>
290
-
291
- <UAlert
292
- :title="t('supabase.connection.whyTitle')"
293
- color="warning"
294
- variant="outline"
295
- icon="lucide:info"
296
- >
297
- <template #description>
298
- <div class="flex flex-col gap-y-4">
299
- <p>
300
- <SupabaseMessageParts
301
- :message="t('supabase.setup.why')"
302
- >
303
- <template #promise>
304
- <UTooltip
305
- :text="t('supabase.setup.promiseTooltip')"
306
- >
307
- <span
308
- class="underline decoration-dotted cursor-help"
309
- >
310
- {{ t('supabase.setup.promise') }}</span
311
- ></UTooltip
312
- >
313
- </template>
314
- </SupabaseMessageParts>
315
- </p>
316
-
317
- <div>
318
- <UPopover :content="{ side: 'bottom' }" arrow>
319
- <UButton
320
- :label="t('supabase.setup.technicalDetails')"
321
- icon="lucide:lightbulb"
322
- color="info"
323
- variant="subtle"
324
- class="w-fit"
325
- size="sm"
326
- />
327
-
328
- <template #content>
329
- <div
330
- class="flex flex-col gap-y-4 max-w-xs p-4 text-white text-sm"
331
- >
332
- <p>
333
- <SupabaseMessageParts
334
- :message="
335
- t('supabase.setup.technicalDetailsRequest')
336
- "
337
- >
338
- <template #route>
339
- <ULink
340
- to="https://github.com/plutocms/supabase/blob/main/server/api/_pluto/supabase/setup/index.post.ts"
341
- target="_blank"
342
- class="underline"
343
- >
344
- {{
345
- t(
346
- 'supabase.setup.technicalDetailsRoute'
347
- )
348
- }}</ULink
349
- >
350
- </template>
351
- <template #files>
352
- <ULink
353
- to="https://github.com/plutocms/supabase/tree/main/db/migrations"
354
- target="_blank"
355
- class="underline"
356
- >
357
- {{
358
- t(
359
- 'supabase.setup.technicalDetailsFiles'
360
- )
361
- }}</ULink
362
- >
363
- </template>
364
- </SupabaseMessageParts>
365
- </p>
366
-
367
- <p>
368
- {{ t('supabase.setup.technicalDetailsStored') }}
369
- </p>
370
- </div>
371
- </template>
372
- </UPopover>
373
- </div>
374
- </div>
375
- </template>
376
- </UAlert>
377
-
378
- <UAlert
379
- v-if="isDev"
380
- :title="t('supabase.connection.restartTitle')"
381
- :description="t('supabase.setup.restartDescription')"
382
- color="info"
383
- variant="outline"
384
- icon="lucide:refresh-cw"
385
- />
386
- </UForm>
387
- </section>
388
-
389
- <section v-if="currentStep === 1">
390
- <div class="flex flex-col gap-y-4">
391
- <hgroup class="text-center">
392
- <span class="text-3xl">🎉</span>
393
-
394
- <h1 class="font-bold text-2xl">
395
- {{ t('supabase.setup.doneTitle') }}
396
- </h1>
397
- </hgroup>
398
-
399
- <p class="text-balance text-center text-lg">
400
- {{ t('supabase.setup.doneDescription') }}
401
- </p>
402
-
403
- <EnvPersistWarning
404
- v-if="envNotPersisted"
405
- :connection-string="submittedConnectionString"
406
- />
407
-
408
- <p class="text-center">
409
- <UButton
410
- icon="lucide:arrow-right"
411
- to="/admin/signup"
412
- color="primary"
413
- trailing
414
- >
415
- {{ t('supabase.setup.goToSignup') }}
416
- </UButton>
417
- </p>
418
- </div>
419
- </section>
420
- </div>
421
-
422
- <div class="flex justify-end">
423
- <div class="w-full sm:w-auto">
424
- <UButton
425
- v-if="stepper?.hasNext"
426
- :form="currentStepId"
427
- :loading="currentLoading"
428
- leading-icon="lucide:check"
429
- type="submit"
430
- class="w-full justify-center sm:w-auto"
431
- >
432
- {{ currentStepSubmitLabel }}
433
- </UButton>
434
- </div>
435
- </div>
436
- </div>
437
- </UCard>
438
- </div>
439
- </UApp>
308
+ </SupabaseMessageParts>
309
+ </li>
310
+ </ul>
311
+ </template>
312
+ </UCollapsible>
313
+ </div>
314
+
315
+ <p v-if="isDev" class="text-muted flex gap-x-2 text-xs">
316
+ <UIcon name="lucide:refresh-cw" class="mt-0.5 size-3.5 shrink-0" />
317
+ <span><PlutoCodeText :text="t('supabase.setup.restartNote')" /></span>
318
+ </p>
319
+
320
+ <UButton
321
+ :label="t('supabase.setup.submit')"
322
+ :loading="isSettingUpDatabase"
323
+ icon="lucide:database"
324
+ type="submit"
325
+ class="w-full justify-center"
326
+ />
327
+ </UForm>
328
+ </PlutoAdminAuthCard>
440
329
  </template>