@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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.31.1](https://github.com/plutocms/supabase/compare/v0.31.0...v0.31.1) (2026-11-14)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **supabase, supabase-blog:** type the translate helpers with the t of core ([#318](https://github.com/plutocms/supabase/issues/318)) ([ccdecaf](https://github.com/plutocms/supabase/commit/ccdecafea563fe43e29874b8ffb101d4cf8b8a75))
9
+
10
+ ## [0.31.0](https://github.com/plutocms/supabase/compare/v0.30.0...v0.31.0) (2026-11-12)
11
+
12
+
13
+ ### Features
14
+
15
+ * admin UI round 5: tooltips, a playground site, new tab links; core 0.68 ([#302](https://github.com/plutocms/supabase/issues/302)) ([441d322](https://github.com/plutocms/supabase/commit/441d322a52cf31712cd7510b0876ca885698fda7))
16
+
3
17
  ## [0.30.0](https://github.com/plutocms/supabase/compare/v0.29.0...v0.30.0) (2026-11-10)
4
18
 
5
19
 
@@ -43,7 +43,7 @@ async function copyEnvLine() {
43
43
  <UAlert
44
44
  :title="t('supabase.envWarning.title')"
45
45
  color="warning"
46
- variant="outline"
46
+ variant="subtle"
47
47
  icon="lucide:triangle-alert"
48
48
  >
49
49
  <template #description>
@@ -84,14 +84,16 @@ async function copyEnvLine() {
84
84
  {{ envLine }}
85
85
  </code>
86
86
 
87
- <UButton
88
- :aria-label="t('supabase.envWarning.copyLine')"
89
- icon="lucide:copy"
90
- variant="soft"
91
- color="neutral"
92
- size="sm"
93
- @click="copyEnvLine"
94
- />
87
+ <UTooltip :text="t('supabase.envWarning.copyLine')">
88
+ <UButton
89
+ :aria-label="t('supabase.envWarning.copyLine')"
90
+ icon="lucide:copy"
91
+ variant="soft"
92
+ color="neutral"
93
+ size="sm"
94
+ @click="copyEnvLine"
95
+ />
96
+ </UTooltip>
95
97
  </div>
96
98
  </div>
97
99
  </template>
@@ -0,0 +1,47 @@
1
+ <script setup lang="ts">
2
+ // The mark of Supabase, in its brand colors, for a page that connects Pluto to it (the database
3
+ // setup). Size it with a class, such as `size-6`.
4
+ const id = useId()
5
+ </script>
6
+
7
+ <template>
8
+ <svg viewBox="0 0 109 113" fill="none" xmlns="http://www.w3.org/2000/svg">
9
+ <path
10
+ :fill="`url(#${id}-a)`"
11
+ d="M63.7076 110.284C60.8481 113.885 55.0502 111.912 54.9813 107.314L53.9738 40.0627L99.1935 40.0627C107.384 40.0627 111.952 49.5228 106.859 55.9374L63.7076 110.284Z"
12
+ />
13
+ <path
14
+ :fill="`url(#${id}-b)`"
15
+ d="M63.7076 110.284C60.8481 113.885 55.0502 111.912 54.9813 107.314L53.9738 40.0627L99.1935 40.0627C107.384 40.0627 111.952 49.5228 106.859 55.9374L63.7076 110.284Z"
16
+ fill-opacity="0.2"
17
+ />
18
+ <path
19
+ d="M45.317 2.07103C48.1765 -1.53037 53.9745 0.442937 54.0434 5.041L54.4849 72.2922H9.83113C1.64038 72.2922 -2.92775 62.8321 2.1655 56.4175L45.317 2.07103Z"
20
+ fill="#3ECF8E"
21
+ />
22
+ <defs>
23
+ <linearGradient
24
+ :id="`${id}-a`"
25
+ x1="53.9738"
26
+ y1="54.974"
27
+ x2="94.1635"
28
+ y2="71.8295"
29
+ gradientUnits="userSpaceOnUse"
30
+ >
31
+ <stop stop-color="#249361" />
32
+ <stop offset="1" stop-color="#3ECF8E" />
33
+ </linearGradient>
34
+ <linearGradient
35
+ :id="`${id}-b`"
36
+ x1="36.1558"
37
+ y1="30.578"
38
+ x2="54.4844"
39
+ y2="65.0806"
40
+ gradientUnits="userSpaceOnUse"
41
+ >
42
+ <stop />
43
+ <stop offset="1" stop-opacity="0" />
44
+ </linearGradient>
45
+ </defs>
46
+ </svg>
47
+ </template>
@@ -43,7 +43,7 @@ const host = (() => {
43
43
  :label="t('supabase.backend.openDashboard')"
44
44
  :to="dashboard"
45
45
  color="neutral"
46
- icon="i-lucide-external-link"
46
+ trailing-icon="i-lucide-arrow-up-right"
47
47
  size="xs"
48
48
  target="_blank"
49
49
  variant="outline"
@@ -72,7 +72,7 @@ const dashboardLinks = computed(() =>
72
72
  key: 'project',
73
73
  label: t('supabase.mail.authEmails.dashboardHome'),
74
74
  to: links.value.project,
75
- icon: 'lucide:external-link',
75
+ icon: 'lucide:layout-dashboard',
76
76
  },
77
77
  ]
78
78
  : []
@@ -95,7 +95,7 @@ const dashboardLinks = computed(() =>
95
95
  :to="RESEND_SUPABASE_INTEGRATION_URL"
96
96
  target="_blank"
97
97
  rel="noopener noreferrer"
98
- icon="lucide:external-link"
98
+ trailing-icon="i-lucide-arrow-up-right"
99
99
  color="neutral"
100
100
  variant="outline"
101
101
  >
@@ -149,6 +149,7 @@ const dashboardLinks = computed(() =>
149
149
  :icon="link.icon"
150
150
  target="_blank"
151
151
  rel="noopener noreferrer"
152
+ trailing-icon="i-lucide-arrow-up-right"
152
153
  color="neutral"
153
154
  variant="outline"
154
155
  size="sm"
@@ -18,14 +18,14 @@ const { status, fetchStatus, pendingCount, refresh, runMigrations } =
18
18
  const isDev = import.meta.dev
19
19
 
20
20
  // The text of each result status that the server returns.
21
- const statusLabels: Record<string, string> = {
21
+ const statusLabels = {
22
22
  applied: 'supabase.migrations.status.applied',
23
23
  skipped: 'supabase.migrations.status.skipped',
24
24
  failed: 'supabase.migrations.status.failed',
25
- }
25
+ } as const
26
26
 
27
27
  function statusText(status: string): string {
28
- const key = statusLabels[status]
28
+ const key = statusLabels[status as keyof typeof statusLabels]
29
29
 
30
30
  return key ? t(key) : status
31
31
  }
@@ -188,17 +188,20 @@ async function applyMigrations(useForm: boolean) {
188
188
  </script>
189
189
 
190
190
  <template>
191
- <AdminView>
192
- <h1 class="text-3xl font-bold lg:text-4xl">
193
- {{ t('supabase.migrations.title') }}
194
- </h1>
191
+ <PlutoViewAdminPanel>
192
+ <template #toolbar>
193
+ <PlutoViewToolbar
194
+ :title="t('supabase.migrations.title')"
195
+ icon="lucide:database-zap"
196
+ />
197
+ </template>
195
198
 
196
199
  <UAlert
197
200
  v-if="isReconnecting"
198
201
  :title="t('supabase.connection.restarting')"
199
202
  :description="t('supabase.migrations.reconnectingBanner')"
200
203
  color="info"
201
- variant="outline"
204
+ variant="subtle"
202
205
  icon="lucide:refresh-cw"
203
206
  />
204
207
 
@@ -218,7 +221,7 @@ async function applyMigrations(useForm: boolean) {
218
221
  :title="t('supabase.migrations.upToDate')"
219
222
  :description="t('supabase.migrations.upToDateDescription')"
220
223
  color="success"
221
- variant="outline"
224
+ variant="subtle"
222
225
  icon="lucide:check-circle"
223
226
  />
224
227
 
@@ -284,14 +287,12 @@ async function applyMigrations(useForm: boolean) {
284
287
  :message="t('supabase.connection.connectionStringHelp')"
285
288
  >
286
289
  <template #link>
287
- <ULink
290
+ <PlutoExternalLink
288
291
  :to="`https://supabase.com/dashboard/project/${projectId}/database/settings?showConnect=true&connectTab=direct&method=transaction`"
289
- target="_blank"
290
292
  class="underline"
291
- external
292
293
  >
293
294
  {{ t('supabase.connection.connectionStringHelpLink') }}
294
- </ULink>
295
+ </PlutoExternalLink>
295
296
  </template>
296
297
  </SupabaseMessageParts>
297
298
  </template>
@@ -310,19 +311,18 @@ async function applyMigrations(useForm: boolean) {
310
311
  <UAlert
311
312
  color="secondary"
312
313
  icon="lucide:badge-info"
313
- variant="outline"
314
+ variant="subtle"
314
315
  >
315
316
  <template #description>
316
317
  <SupabaseMessageParts
317
318
  :message="t('supabase.connection.passwordInfo')"
318
319
  >
319
320
  <template #link>
320
- <ULink
321
+ <PlutoExternalLink
321
322
  to="https://supabase.com/dashboard/project/_/database/settings"
322
- target="_blank"
323
323
  >
324
324
  {{ t('supabase.connection.passwordInfoLink') }}
325
- </ULink>
325
+ </PlutoExternalLink>
326
326
  </template>
327
327
  </SupabaseMessageParts>
328
328
  </template>
@@ -332,7 +332,7 @@ async function applyMigrations(useForm: boolean) {
332
332
  :title="t('supabase.connection.whyTitle')"
333
333
  :description="t('supabase.migrations.why')"
334
334
  color="warning"
335
- variant="outline"
335
+ variant="subtle"
336
336
  icon="lucide:info"
337
337
  />
338
338
 
@@ -341,7 +341,7 @@ async function applyMigrations(useForm: boolean) {
341
341
  :title="t('supabase.connection.restartTitle')"
342
342
  :description="t('supabase.migrations.restartDescription')"
343
343
  color="info"
344
- variant="outline"
344
+ variant="subtle"
345
345
  icon="lucide:refresh-cw"
346
346
  />
347
347
 
@@ -374,11 +374,13 @@ async function applyMigrations(useForm: boolean) {
374
374
  </UCard>
375
375
 
376
376
  <UCard v-if="lastRun">
377
- <div class="flex flex-col gap-y-4">
377
+ <template #header>
378
378
  <h2 class="font-semibold">
379
379
  {{ t('supabase.migrations.lastRun') }}
380
380
  </h2>
381
+ </template>
381
382
 
383
+ <div class="flex flex-col gap-y-4">
382
384
  <EnvPersistWarning
383
385
  v-if="lastRun.success && lastRun.persisted === false"
384
386
  :connection-string="lastConnectionString"
@@ -410,7 +412,7 @@ async function applyMigrations(useForm: boolean) {
410
412
  :title="t('supabase.migrations.loadFailed')"
411
413
  :description="t('supabase.migrations.loadFailedDescription')"
412
414
  color="error"
413
- variant="outline"
415
+ variant="subtle"
414
416
  icon="lucide:circle-x"
415
417
  >
416
418
  <template #actions>
@@ -424,5 +426,5 @@ async function applyMigrations(useForm: boolean) {
424
426
  </UButton>
425
427
  </template>
426
428
  </UAlert>
427
- </AdminView>
429
+ </PlutoViewAdminPanel>
428
430
  </template>
@@ -124,140 +124,138 @@ function menuItems(role: AccessRole): DropdownMenuItem[][] {
124
124
  </script>
125
125
 
126
126
  <template>
127
- <main>
128
- <AdminView>
129
- <!-- The section (the Users item of the menu) and its tabs, like Settings. -->
130
- <h1 class="text-3xl font-bold lg:text-4xl">
131
- {{ t('supabase.access.users.title') }}
132
- </h1>
127
+ <PlutoViewAdminPanel>
128
+ <!-- The section (the Users item of the menu) and its tabs, like Settings. -->
129
+ <template #toolbar>
130
+ <PlutoViewToolbar
131
+ :title="t('supabase.access.users.title')"
132
+ icon="lucide:users"
133
+ >
134
+ <template #right>
135
+ <UButton icon="lucide:plus" @click="openRole(null)">
136
+ {{ t('supabase.access.roles.create') }}
137
+ </UButton>
138
+ </template>
139
+ </PlutoViewToolbar>
133
140
 
134
141
  <PlutoAdminNavTabs />
142
+ </template>
135
143
 
136
- <div class="flex flex-wrap items-start justify-between gap-4">
137
- <div>
138
- <h2 class="text-xl font-semibold">
139
- {{ t('supabase.access.roles.title') }}
140
- </h2>
141
- <p class="text-muted text-sm">
142
- {{ t('supabase.access.roles.description') }}
143
- </p>
144
- </div>
144
+ <p class="text-muted text-sm">
145
+ {{ t('supabase.access.roles.description') }}
146
+ </p>
145
147
 
146
- <UButton icon="lucide:plus" @click="openRole(null)">
147
- {{ t('supabase.access.roles.create') }}
148
- </UButton>
149
- </div>
148
+ <UAlert
149
+ v-if="!allowed"
150
+ :title="t('pluto.settings.noPermission.title')"
151
+ :description="
152
+ t('pluto.settings.noPermission.description', {
153
+ page: t('supabase.access.roles.title'),
154
+ })
155
+ "
156
+ icon="lucide:lock"
157
+ color="warning"
158
+ />
150
159
 
151
- <UAlert
152
- v-if="!allowed"
153
- :title="t('pluto.settings.noPermission.title')"
154
- :description="
155
- t('pluto.settings.noPermission.description', {
156
- page: t('supabase.access.roles.title'),
157
- })
158
- "
159
- icon="lucide:lock"
160
- color="warning"
161
- />
162
-
163
- <!-- Loading -->
164
- <div
165
- v-else-if="status === 'loading'"
166
- class="flex flex-col gap-y-3"
167
- aria-busy="true"
168
- >
169
- <USkeleton v-for="row in 3" :key="row" class="h-12 w-full" />
170
- </div>
160
+ <!-- Loading -->
161
+ <div
162
+ v-else-if="status === 'loading'"
163
+ class="flex flex-col gap-y-3"
164
+ aria-busy="true"
165
+ >
166
+ <USkeleton v-for="row in 3" :key="row" class="h-12 w-full" />
167
+ </div>
171
168
 
172
- <!-- Error -->
173
- <UAlert
174
- v-else-if="status === 'error'"
175
- :title="t('supabase.access.roles.error.title')"
176
- :description="loadError"
177
- :actions="[
178
- {
179
- label: t('pluto.common.tryAgain'),
180
- color: 'neutral',
181
- variant: 'outline',
182
- onClick: load,
183
- },
184
- ]"
185
- color="error"
186
- variant="subtle"
187
- icon="lucide:circle-x"
188
- />
169
+ <!-- Error -->
170
+ <UAlert
171
+ v-else-if="status === 'error'"
172
+ :title="t('supabase.access.roles.error.title')"
173
+ :description="loadError"
174
+ :actions="[
175
+ {
176
+ label: t('pluto.common.tryAgain'),
177
+ color: 'neutral',
178
+ variant: 'outline',
179
+ onClick: load,
180
+ },
181
+ ]"
182
+ color="error"
183
+ variant="subtle"
184
+ icon="lucide:circle-x"
185
+ />
189
186
 
190
- <!-- The list -->
191
- <UTable
192
- v-else
193
- :data="roles"
194
- :columns="columns"
195
- class="border-default rounded-lg border"
196
- >
197
- <template #role-cell="{ row }">
198
- <div class="flex min-w-0 flex-col">
199
- <span class="flex items-center gap-2">
200
- <span class="text-highlighted truncate font-medium">{{
201
- row.original.label
202
- }}</span>
203
- <UBadge
204
- v-if="row.original.is_builtin"
205
- :label="t('supabase.access.roles.builtin')"
206
- color="neutral"
207
- variant="subtle"
208
- size="sm"
209
- />
210
- </span>
211
- <code class="text-muted truncate font-mono text-xs">{{
212
- row.original.key
213
- }}</code>
214
- </div>
215
- </template>
216
-
217
- <template #permissions-cell="{ row }">
218
- <span v-if="isFullAccess(row.original)" class="text-sm">
219
- {{ t('supabase.access.roles.fullAccess') }}
220
- </span>
221
- <span v-else class="text-sm">
222
- {{
223
- t(
224
- 'supabase.access.roles.permissionCount',
225
- row.original.capabilities.length
226
- )
227
- }}
187
+ <!-- The list -->
188
+ <UTable
189
+ v-else
190
+ :data="roles"
191
+ :columns="columns"
192
+ class="border-default rounded-lg border"
193
+ >
194
+ <template #role-cell="{ row }">
195
+ <div class="flex min-w-0 flex-col">
196
+ <span class="flex items-center gap-2">
197
+ <span class="text-highlighted truncate font-medium">{{
198
+ row.original.label
199
+ }}</span>
200
+ <UBadge
201
+ v-if="row.original.is_builtin"
202
+ :label="t('supabase.access.roles.builtin')"
203
+ color="neutral"
204
+ variant="subtle"
205
+ size="sm"
206
+ />
228
207
  </span>
229
- </template>
208
+ <code class="text-muted truncate font-mono text-xs">{{
209
+ row.original.key
210
+ }}</code>
211
+ </div>
212
+ </template>
230
213
 
231
- <template #users-cell="{ row }">
232
- <span class="text-sm">{{
233
- t('supabase.access.roles.userCount', row.original.user_count)
234
- }}</span>
235
- </template>
214
+ <template #permissions-cell="{ row }">
215
+ <span v-if="isFullAccess(row.original)" class="text-sm">
216
+ {{ t('supabase.access.roles.fullAccess') }}
217
+ </span>
218
+ <span v-else class="text-sm">
219
+ {{
220
+ t(
221
+ 'supabase.access.roles.permissionCount',
222
+ row.original.capabilities.length
223
+ )
224
+ }}
225
+ </span>
226
+ </template>
227
+
228
+ <template #users-cell="{ row }">
229
+ <span class="text-sm">{{
230
+ t('supabase.access.roles.userCount', row.original.user_count)
231
+ }}</span>
232
+ </template>
236
233
 
237
- <template #actions-cell="{ row }">
238
- <div class="flex justify-end">
239
- <UDropdownMenu
240
- :items="menuItems(row.original)"
241
- :content="{ align: 'end' }"
242
- >
234
+ <template #actions-cell="{ row }">
235
+ <div class="flex justify-end">
236
+ <UDropdownMenu
237
+ :items="menuItems(row.original)"
238
+ :content="{ align: 'end' }"
239
+ >
240
+ <UTooltip :text="row.original.label">
243
241
  <UButton
244
242
  :aria-label="row.original.label"
245
243
  icon="lucide:ellipsis"
246
244
  color="neutral"
247
245
  variant="ghost"
248
246
  />
249
- </UDropdownMenu>
250
- </div>
251
- </template>
252
- </UTable>
247
+ </UTooltip>
248
+ </UDropdownMenu>
249
+ </div>
250
+ </template>
251
+ </UTable>
253
252
 
254
- <!-- Lazy: the chunk loads on the first open. -->
255
- <RoleSlideover
256
- v-if="slideoverMounted"
257
- v-model:open="slideoverOpen"
258
- :role="editing"
259
- @saved="load"
260
- />
261
- </AdminView>
262
- </main>
253
+ <!-- Lazy: the chunk loads on the first open. -->
254
+ <RoleSlideover
255
+ v-if="slideoverMounted"
256
+ v-model:open="slideoverOpen"
257
+ :role="editing"
258
+ @saved="load"
259
+ />
260
+ </PlutoViewAdminPanel>
263
261
  </template>