mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 04:45:08 +03:00
Merge branch 'master' into lw-7-day-5-blog-dbdev
This commit is contained in:
commit
28917de0bb
43 files changed
+653
-201
No files matched your search
@@ -5,12 +5,12 @@ name: Studio Unit Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [master, studio]
|
||||
paths:
|
||||
- 'studio/**'
|
||||
- 'package-lock.json'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
branches: [master, studio]
|
||||
paths:
|
||||
- 'studio/**'
|
||||
- 'package-lock.json'
|
||||
|
||||
@@ -45,7 +45,7 @@ You can use any standard React components in these `.mdx` files without having t
|
||||
|
||||
### Reference docs for client libraries
|
||||
|
||||
We maintain client libraries for [Javascript](https://supabase.com/docs/reference/javascript) and [Flutter/Dart](https://supabase.com/docs/reference/dart) (with more to come). These reference docs document every object and method available for developers to use. The are assembled from different sources and work much differently than the `.mdx` Guides we just looked at.
|
||||
We maintain client libraries for [JavaScript](https://supabase.com/docs/reference/javascript) and [Flutter/Dart](https://supabase.com/docs/reference/dart) (with more to come). These reference docs document every object and method available for developers to use. They are assembled from different sources and work much differently than the `.mdx` Guides we just looked at.
|
||||
|
||||
The client libraries are essentially wrappers around the clients for the various tools we use — GoTrue, PostgREST, Storage, Functions, and Realtime. The easiest way to describe how the things fit together is to look at an example and trace where the various pieces of information are coming from.
|
||||
|
||||
|
||||
@@ -578,6 +578,7 @@ export const functions = {
|
||||
name: 'Connecting directly to Postgres',
|
||||
url: '/guides/functions/connect-to-postgres',
|
||||
},
|
||||
{ name: 'Dart Edge on Supabase', url: '/guides/functions/dart-edge' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -78,8 +78,8 @@ We'll create a database table called `todos` for storing tasks. This creates a c
|
||||
-- Allow anonymous access
|
||||
create policy "Allow anonymous access"
|
||||
on todos
|
||||
to anon
|
||||
for select
|
||||
to anon
|
||||
using (true);
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
import Layout from '~/layouts/DefaultGuideLayout'
|
||||
|
||||
export const meta = {
|
||||
id: 'functions-dart-edge',
|
||||
title: 'Dart Edge',
|
||||
description: 'Write your functions using Dart.',
|
||||
}
|
||||
|
||||
[Dart Edge](https://docs.dartedge.dev/), a project built and maintained by [Invertase](https://invertase.io/), enables Dart code to be run on different edge environments. This guide will walk you through how you can start using Dart Edge to write your backend code using Dart and run it on Supabase.
|
||||
|
||||
> ⚠️ WARNING: Dart Edge is an experimental project - it's probably not ready for production usage unless you're okay with living on the 'edge'. Open issues on [Dart Edge repo](https://github.com/invertase/dart_edge) if you encounter any issues.
|
||||
|
||||
## **Pre requirements**
|
||||
|
||||
Make sure you have [the edge CLI](https://docs.dartedge.dev/#getting-started) installed in addition to [the Supabase CLI](https://supabase.com/docs/guides/cli#installation).
|
||||
|
||||
```bash
|
||||
# install the edge CLI
|
||||
dart pub global activate edge
|
||||
```
|
||||
|
||||
## **Setting up your first Dart Edge project**
|
||||
|
||||
Create a new Dart Edge project using the `new` command on the edge CLI. This will create a familiar boilerplate for your Dart Edge project such as `main.dart` and `pubspec.yaml` file.
|
||||
|
||||
```bash
|
||||
edge new supabase_functions new_project
|
||||
```
|
||||
|
||||
`cd` into the project and initialize a new Supabase project inside the project you just created.
|
||||
|
||||
```bash
|
||||
cd new_project
|
||||
supabase init
|
||||
```
|
||||
|
||||
Run `pub get` to install the dependencies.
|
||||
|
||||
```bash
|
||||
dart pub get
|
||||
```
|
||||
|
||||
Open the `lib/main.dart` and look at the initial template.
|
||||
|
||||
```dart
|
||||
void main() {
|
||||
SupabaseFunctions(fetch: (request) {
|
||||
return Response("Hello from Supabase Edge Functions!");
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
`SupabaseFunctions` class has a `fetch` handler, which is expected to return a `Response` object, and has a `request` parameter, which contains information about the request such as body and headers.
|
||||
|
||||
## Using Supabase Client
|
||||
|
||||
Now let’s try to interact with our Supabase database. We will start by installing the dependencies.
|
||||
|
||||
### Add dependencies
|
||||
|
||||
Add [supabase](https://pub.dev/packages/supabase) to interact with Supabase service.
|
||||
|
||||
```bash
|
||||
dart pub add supabase
|
||||
```
|
||||
|
||||
We also need to use a special HTTP client to HTTP requests in the edge environment.
|
||||
|
||||
```bash
|
||||
dart pub add edge_http_client
|
||||
```
|
||||
|
||||
We also need to add the `yet_another_json_isolate` package, which is the JSON encoder/decoder that utilizes isolate.
|
||||
|
||||
```bash
|
||||
dart pub add yet_another_json_isolate
|
||||
```
|
||||
|
||||
### Override the JSON isolate
|
||||
|
||||
Since isolates are not supported in the edge, we have to override its behavior to handle JSON serialization using the main thread.
|
||||
|
||||
```dart
|
||||
import 'package:yet_another_json_isolate/yet_another_json_isolate.dart';
|
||||
|
||||
class EdgeIsolate implements YAJsonIsolate {
|
||||
@override
|
||||
Future decode(String json) {
|
||||
return Future.value(jsonDecode(json));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
|
||||
@override
|
||||
Future<String> encode(Object? json) {
|
||||
return Future.value(jsonEncode(json));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> initialize() async {}
|
||||
}
|
||||
```
|
||||
|
||||
### Initialize SupabaseClient
|
||||
|
||||
At this point, you can initialize a `SupabaseClient` by passing the [EdgeHttpClient](https://pub.dev/packages/edge_http_client) and the `EdgeIsolate`. We can access the Supabase credentials through the [environment variables](https://supabase.com/docs/guides/functions/secrets) using `Deno.env.get()` method. Note that [Supabase credentials are available by default](https://supabase.com/docs/guides/functions/secrets), so no configurations are necessary.
|
||||
|
||||
Combining the isolates we overrode earlier, we have the following sample functions code to query Supabase database using the Supabase client.
|
||||
|
||||
```dart
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:supabase_functions/supabase_functions.dart';
|
||||
import 'package:edge_http_client/edge_http_client.dart';
|
||||
import 'package:supabase/supabase.dart';
|
||||
import 'package:yet_another_json_isolate/yet_another_json_isolate.dart';
|
||||
|
||||
void main() {
|
||||
final supabase = SupabaseClient(
|
||||
Deno.env.get('SUPABASE_URL')!,
|
||||
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!, // Use service role key to bypass RLS
|
||||
httpClient: EdgeHttpClient(),
|
||||
isolate: EdgeIsolate(),
|
||||
);
|
||||
|
||||
SupabaseFunctions(fetch: (request) async {
|
||||
// You can query `public.users` table for example.
|
||||
final List users = await supabase.from('users').select().limit(10);
|
||||
return Response.json(users);
|
||||
});
|
||||
}
|
||||
|
||||
class EdgeIsolate implements YAJsonIsolate {
|
||||
@override
|
||||
Future decode(String json) {
|
||||
return Future.value(jsonDecode(json));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
|
||||
@override
|
||||
Future<String> encode(Object? json) {
|
||||
return Future.value(jsonEncode(json));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> initialize() async {}
|
||||
}
|
||||
```
|
||||
|
||||
## Run the Functions
|
||||
|
||||
### Run locally
|
||||
|
||||
Run the following command to compile your Dart code. This command will start a watcher that will recompile anytime you make changes to your code.
|
||||
|
||||
```bash
|
||||
edge build supabase_functions --dev
|
||||
```
|
||||
|
||||
With docker running, start your local Supabase with the following command
|
||||
|
||||
```bash
|
||||
supabase start
|
||||
```
|
||||
|
||||
While you have the above code running, open another terminal and run the following to start the Supabase local development environment.
|
||||
|
||||
```bash
|
||||
supabase functions serve dart_edge --no-verify-jwt
|
||||
```
|
||||
|
||||
You should be able to access your local function here:
|
||||
|
||||
[http://localhost:54321/functions/v1/dart_edge](http://localhost:54321/functions/v1/dart_edge)
|
||||
|
||||
### Deploy to the Edge
|
||||
|
||||
Run the following commands to compile and deploy your function on Supabase Edge functions.
|
||||
|
||||
```bash
|
||||
edge build supabase_functions
|
||||
supabase functions deploy dart_edge
|
||||
```
|
||||
|
||||
You will be asked to provide the project reference of your Supabase instance to which you want to deploy the function. You can [link your local project to your Supabase instance](https://supabase.com/docs/guides/cli/local-development#link-your-project) to avoid having to provide the Supabase reference every time you deploy.
|
||||
|
||||
export const Page = ({ children }) => <Layout meta={meta} children={children} />
|
||||
|
||||
export default Page
|
||||
@@ -1,23 +0,0 @@
|
||||
import Layout from '~/layouts/DefaultGuideLayout'
|
||||
|
||||
export const meta = {
|
||||
id: 'support',
|
||||
title: 'Support',
|
||||
description: 'Supabase Support',
|
||||
}
|
||||
|
||||
How can we help?
|
||||
|
||||
## Community Support
|
||||
|
||||
For help and questions about best practices, we have a discussion forum set up on GitHub: https://github.com/supabase/supabase/discussions
|
||||
|
||||
## Business Support
|
||||
|
||||
We offer email based support for business users. You can email us at support@supabase.com.
|
||||
|
||||
If you need SLAs, guaranteed response times, or other enterprise level services, please contact us at this email address.
|
||||
|
||||
## Slack Support
|
||||
|
||||
If you are building with Supabase and you would like to set up a shared Slack channel (via [Slack Connect](https://slack.com/connect)), please reach out to us at support@supabase.com.
|
||||
@@ -33,7 +33,11 @@ After exploring a variety of text prompts, blends, and styles, we decided that m
|
||||
|
||||
After what-seemed-like hours (okay, just a few), we were able to generate some interesting artwork that could be useful. We chose purple hues and simpler swirls - minimalist visuals that could serve as backgrounds for our tickets and landing page.
|
||||
|
||||

|
||||
<Img
|
||||
src="/images/blog/launch-week-7/designing-with-ai-midjourney/midjourney-variations.png"
|
||||
caption="Final AI generated images"
|
||||
wide={true}
|
||||
/>
|
||||
|
||||
### Chasing Gold Behind the Scenes
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ toc_depth: 2
|
||||
|
||||
With Easter just around the corner, [Launch Week](https://supabase.com/launch-week) is about to start and, as usual, we're running an async hackathon alongside it. This time it’s AI-themed!
|
||||
|
||||
The hackathon starts **now** and ends Monday 16th April at 11:59 pm. You can win extremely limited edition Launch Week themed mechanical keyboards and limited edition Supabase swag.
|
||||
The hackathon starts **now** and ends Sunday 16th April at 11:59 pm. You can win extremely limited edition Launch Week themed mechanical keyboards and limited edition Supabase swag.
|
||||
|
||||
For some inspiration check out the [Next.js OpenAI Doc Search template](https://github.com/supabase-community/nextjs-openai-doc-search?og=v2) released yesterday and [storing embeddings on Supabase article](https://supabase.com/blog/openai-embeddings-postgres-vector).
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@ thumb: launch-week-7/day-4-supabase-auth-sso-pkce/supabase-auth-sso-pkce-og.jpg
|
||||
|
||||
Today we're excited to announce a few new features for Supabase Auth:
|
||||
|
||||
1. Easily add Single Sign-On support to your projects using SAML 2.0.
|
||||
2. Better support for server-side rendering and mobile apps using PKCE.
|
||||
1. [Easily add Single Sign-On support to your projects using SAML 2.0](/blog/supabase-auth-sso-pkce#single-sign-on-support-using-saml-20)
|
||||
2. [Better support for server-side rendering and mobile apps using PKCE](/blog/supabase-auth-sso-pkce#server-side-and-mobile-auth)
|
||||
3. [Native Apple login on iOS](/blog/supabase-auth-sso-pkce#native-apple-login-on-ios)
|
||||
|
||||
## Single Sign-On Support using SAML 2.0
|
||||
|
||||
@@ -22,7 +23,7 @@ With Single Sign-On (SSO), your users can login with their company's identity pr
|
||||
|
||||
Every developer building a B2B application eventually needs the SSO authentication flow to onboard enterprise customers. SSO is a requirement for larger Enterprise customers because it's a standard request in Enterprise Security Policies. Over the past few months, we've been [dogfooding SSO for our own Enterprise customers](https://supabase.com/docs/guides/platform/sso), and today we're releasing it for you to do the same.
|
||||
|
||||
Building SSO into your application isn't necessarily hard, but does come with some complexity. A lot of time can be spent understanding the nuances and details of the protocol - from dissecting the jargon to testing the implementation heavily. It took us months to build it for ourselves. With this release, you will have SSO set up and running in less than an hour so that you can focus on shipping the core features of your product. This feature is available for the [Pro-tier and above](https://supabase.com/pricing), starting today.
|
||||
Building SSO into your application isn't necessarily hard, but does come with some complexity. A lot of time can be spent understanding the nuances and details of the protocol - from dissecting the jargon to testing the implementation heavily. It took us months to build it for ourselves. With this release, you will have SSO set up and running in less than an hour so that you can focus on shipping the core features of your product. This feature is available for the [Pro-tier and above](https://supabase.com/pricing), starting today. This will also be available on the self-hosted version.
|
||||
|
||||
<div className="video-container">
|
||||
<iframe
|
||||
@@ -71,7 +72,7 @@ For example, you can use Row Level Security (RLS) to build multi-tenant applicat
|
||||
|
||||
```sql
|
||||
create policy "Only allow read-write access to tenants" on tablename as restrictive to authenticated using (
|
||||
tenant_id = (auth.jwt () - > 'app_metadata' - > > 'provider')
|
||||
tenant_id = (auth.jwt () -> 'app_metadata' ->> 'provider')
|
||||
);
|
||||
```
|
||||
|
||||
@@ -228,7 +229,7 @@ Since this is a major update that touches many of the authentication routes, we
|
||||
|
||||
While PKCE support is great, that is not the only news for you mobile app developers out there.
|
||||
|
||||
Building apps for iOS requires support for native _Sign in with Apple_. We heard the community's requests for native sign-in. We hope you join our excitement to officially announce support for native _Sign in with Apple_.
|
||||
Building apps for iOS requires [^1] support for native _Sign in with Apple_. We heard the community's requests for native sign-in. We hope you join our excitement to officially announce support for native _Sign in with Apple_.
|
||||
|
||||
Your app's iOS Bundle ID can now be configured in the Apple provider section of your project's dashboard.
|
||||
|
||||
@@ -247,3 +248,5 @@ We're just starting with Apple login, and soon add support for Google login.
|
||||
## Wrapping Up
|
||||
|
||||
Supabase Auth aims to continue developing auth features that are secure by default yet simple to implement. We use Supabase Auth for our hosted platform and continuously dogfood the latest version on it. If you are interested to migrate to Supabase Auth, you can check out this blog post on how [Parqet migrated 125,000 users from Auth0 to Supabase Auth](https://kevcodez.medium.com/migrating-125-000-users-from-auth0-to-supabase-81c0568de307).
|
||||
|
||||
[^1]: [App store review guidelines](https://developer.apple.com/app-store/review/guidelines/#sign-in-with-apple)
|
||||
@@ -1,5 +1,6 @@
|
||||
import authors from 'lib/authors.json'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import Author from '~/types/author'
|
||||
import PostTypes from '~/types/post'
|
||||
@@ -24,8 +25,8 @@ const BlogListItem = ({ post }: Props) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<a href={`${post.path}`}>
|
||||
<div className="group inline-block min-w-full">
|
||||
<Link href={post.path}>
|
||||
<a className="group inline-block min-w-full">
|
||||
<div className="flex flex-col space-y-6">
|
||||
<div className="flex flex-col space-y-3">
|
||||
<div
|
||||
@@ -69,8 +70,8 @@ const BlogListItem = ({ post }: Props) => {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ const BlogLinks = () => {
|
||||
<div className="relative z-10 flex items-center text-lg flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<div
|
||||
className={[
|
||||
'text-transparent bg-clip-text bg-gradient-to-r from-[#F4FFFA] to-[#B7B2C9] drop-shadow-lg',
|
||||
step.break_thumb_title && 'max-w-[270px]',
|
||||
'text-transparent bg-clip-text bg-gradient-to-r text-base from-[#F4FFFA] to-[#B7B2C9] drop-shadow-lg',
|
||||
step.break_thumb_title && 'max-w-[240px]',
|
||||
].join(' ')}
|
||||
>
|
||||
{step.title}
|
||||
|
||||
@@ -277,7 +277,7 @@ export default function LW7Releases() {
|
||||
background: `radial-gradient(90% 130px at 80% 0px, #4635A7, transparent)`,
|
||||
}}
|
||||
/>
|
||||
<div className="flex items-center text-center lg:text-left lg: justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-white">
|
||||
<div className="flex items-center text-center lg:text-left justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-white">
|
||||
<CartTitle>{preRelease.steps[0].title}</CartTitle>
|
||||
<StyledArticleBadge className="lg:ml-2">Guide</StyledArticleBadge>
|
||||
</div>
|
||||
@@ -401,13 +401,13 @@ export default function LW7Releases() {
|
||||
<motion.div
|
||||
className={`
|
||||
relative overflow-hidden group/2 flex-1 flex flex-col items-center gap-5 lg:items-start justify-between
|
||||
w-full border border-[#232323] rounded-xl h-full px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
w-full border border-[#232323] rounded-xl h-full px-4 sm:px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
`}
|
||||
initial="default"
|
||||
animate="default"
|
||||
whileHover="hover"
|
||||
>
|
||||
<div className="flex items-center text-center lg:text-left lg: justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-white">
|
||||
<div className="flex items-center text-center lg:text-left justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-white">
|
||||
<CartTitle>{day1.steps[0].title}</CartTitle>
|
||||
<StyledArticleBadge className="lg:ml-2">New</StyledArticleBadge>
|
||||
</div>
|
||||
@@ -489,13 +489,13 @@ export default function LW7Releases() {
|
||||
<motion.div
|
||||
className={`
|
||||
relative overflow-hidden group/2 flex-1 flex flex-col items-center gap-5 lg:items-start justify-between
|
||||
w-full border rounded-xl h-full px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
w-full border rounded-xl h-full px-4 sm:px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
`}
|
||||
initial="default"
|
||||
animate="default"
|
||||
whileHover="hover"
|
||||
>
|
||||
<div className="flex items-center text-center lg:text-left lg: justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<div className="flex items-center text-center lg:text-left justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<CartTitle>{day2.steps[0].title}</CartTitle>
|
||||
<StyledArticleBadge className="lg:ml-2">New</StyledArticleBadge>
|
||||
</div>
|
||||
@@ -577,13 +577,13 @@ export default function LW7Releases() {
|
||||
<motion.div
|
||||
className={`
|
||||
relative overflow-hidden group/2 flex-1 flex flex-col items-center gap-5 lg:items-start justify-between
|
||||
w-full border rounded-xl h-full px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
w-full border rounded-xl h-full px-4 sm:px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
`}
|
||||
initial="default"
|
||||
animate="default"
|
||||
whileHover="hover"
|
||||
>
|
||||
<div className="flex items-center text-center lg:text-left lg: justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<div className="flex items-center text-center lg:text-left justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<CartTitle>{day3.steps[0].title}</CartTitle>
|
||||
<StyledArticleBadge className="lg:ml-2">Updated</StyledArticleBadge>
|
||||
</div>
|
||||
@@ -664,13 +664,13 @@ export default function LW7Releases() {
|
||||
<motion.div
|
||||
className={`
|
||||
relative overflow-hidden group/2 flex-1 flex flex-col items-center gap-5 lg:items-start justify-between
|
||||
w-full border rounded-xl h-full px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
w-full border rounded-xl h-full px-4 sm:px-8 lg:px-14 py-14 xs:text-2xl text-xl text-center shadow-lg
|
||||
`}
|
||||
initial="default"
|
||||
animate="default"
|
||||
whileHover="hover"
|
||||
>
|
||||
<div className="flex items-center text-center lg:text-left lg: justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<div className="flex items-center text-center lg:text-left justify-between flex-col-reverse lg:flex-row lg:justify-start gap-2 text-black dark:text-white">
|
||||
<CartTitle>{day4.steps[0].title}</CartTitle>
|
||||
<StyledArticleBadge className="lg:ml-2">New</StyledArticleBadge>
|
||||
</div>
|
||||
@@ -678,6 +678,8 @@ export default function LW7Releases() {
|
||||
docs={day4.steps[0].docs}
|
||||
blog={day4.steps[0].blog}
|
||||
video={day4.steps[0].video}
|
||||
hackernews={day4.steps[0].hackernews}
|
||||
mobileGrid
|
||||
/>
|
||||
{day4.steps[0].bg_layers &&
|
||||
day4.steps[0].bg_layers?.map((layer, i) =>
|
||||
|
||||
@@ -175,6 +175,7 @@ export const SectionButtons = ({
|
||||
github,
|
||||
url,
|
||||
hackernews,
|
||||
mobileGrid,
|
||||
}: {
|
||||
blog?: string
|
||||
docs?: string
|
||||
@@ -182,9 +183,15 @@ export const SectionButtons = ({
|
||||
github?: string
|
||||
url?: string
|
||||
hackernews?: string
|
||||
mobileGrid?: boolean
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex w-full md:w-auto justify-center gap-2 z-10">
|
||||
<div
|
||||
className={[
|
||||
'flex w-full md:w-auto justify-center gap-2 z-10',
|
||||
mobileGrid && 'grid grid-cols-2 gap-2 sm:flex',
|
||||
].join(' ')}
|
||||
>
|
||||
{!!blog && (
|
||||
<ChipLink href={blog}>
|
||||
Blog post
|
||||
|
||||
@@ -222,6 +222,7 @@ const days: WeekDayProps[] = [
|
||||
thumb: images['04-sso-thumb'],
|
||||
video: 'https://www.youtube.com/watch?v=hAwJeR6mhB0',
|
||||
docs: '/docs/guides/auth/sso/auth-sso-saml',
|
||||
hackernews: 'https://news.ycombinator.com/item?id=35555263',
|
||||
bg_layers: [
|
||||
{
|
||||
img: images['04-sso-01'],
|
||||
|
||||
@@ -11,12 +11,17 @@ export default function Quote(props: Props) {
|
||||
const { children, caption, img } = props
|
||||
|
||||
return (
|
||||
<figure className="border border-gray-100 p-8 dark:border-gray-600">
|
||||
<div className="flex flex-col gap-5">
|
||||
<blockquote className="text-scale-1200 mb-4 border-none" style={{ margin: 0, padding: 0 }}>
|
||||
<figure className="quote-figure p-0 mt-8">
|
||||
<div className="relative flex flex-col gap-5 pl-8 py-2">
|
||||
<p className="text-scale-1100 text-lg border-none" style={{ margin: 0, padding: 0 }}>
|
||||
{children}
|
||||
</blockquote>
|
||||
<Avatar caption={caption} img={img} />
|
||||
</p>
|
||||
{caption && img && (
|
||||
<div className="mt-4">
|
||||
<Avatar caption={caption} img={img} />
|
||||
</div>
|
||||
)}
|
||||
<div className="absolute rounded-full w-1 h-full inset-0 right-auto bg-brand-900" />
|
||||
</div>
|
||||
</figure>
|
||||
)
|
||||
|
||||
@@ -30,7 +30,7 @@ const data: CommunityItem[] = [
|
||||
},
|
||||
{
|
||||
title: 'GitHub',
|
||||
stat: '46,000+',
|
||||
stat: '48,000+',
|
||||
statLabel: 'GitHub stars',
|
||||
img: 'github.png',
|
||||
invertImgDarkMode: true,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { isBrowser, stripEmojis } from '~/lib/helpers'
|
||||
|
||||
const useActiveAnchors = (
|
||||
anchorsQuerySelector: string = 'h2',
|
||||
tocQuerySelector: string = '.prose-toc a',
|
||||
offset: number = 200
|
||||
) => {
|
||||
const router = useRouter()
|
||||
const anchors = useRef<NodeListOf<HTMLHeadingElement> | null>(null)
|
||||
const toc = useRef<NodeListOf<HTMLHeadingElement> | null>(null)
|
||||
|
||||
@@ -20,11 +23,13 @@ const useActiveAnchors = (
|
||||
|
||||
toc.current?.forEach((link) => {
|
||||
link.classList.remove('toc-animate')
|
||||
// TODO: escape emojis
|
||||
// The problem is that MDXRemote strips out emojis on slugs
|
||||
// but ReactMarkdown doesn't,instead it encodes them
|
||||
const sanitizedHref = (link.getAttribute('href') ?? '').replace('#', '')
|
||||
const isMatch = sanitizedHref === newActiveAnchor
|
||||
|
||||
// Need to decodeURI the href to get emojis, then strip them off and remove "--""
|
||||
// to make toc hrefs and content headings ids match
|
||||
const sanitizedHref = stripEmojis(
|
||||
decodeURI(link.getAttribute('href') ?? '').replace('#', '')
|
||||
).replaceAll('-', '')
|
||||
const isMatch = sanitizedHref === newActiveAnchor.replaceAll('-', '')
|
||||
|
||||
if (isMatch) {
|
||||
link.classList.add('toc-animate')
|
||||
@@ -33,6 +38,7 @@ const useActiveAnchors = (
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isBrowser || !router.isReady) return
|
||||
anchors.current = document.querySelectorAll(anchorsQuerySelector)
|
||||
toc.current = document.querySelectorAll(tocQuerySelector)
|
||||
|
||||
@@ -41,7 +47,7 @@ const useActiveAnchors = (
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [])
|
||||
}, [router])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -31,3 +31,12 @@ export const toPixels = (value: string | number) => {
|
||||
}
|
||||
|
||||
export const isBrowser = typeof window !== 'undefined'
|
||||
|
||||
export const stripEmojis = (str: string) =>
|
||||
str
|
||||
.replace(
|
||||
/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g,
|
||||
''
|
||||
)
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
@@ -12,6 +12,18 @@ import { Badge } from 'ui'
|
||||
|
||||
const ignoreClass = 'ignore-on-export'
|
||||
|
||||
const getCaptionAlign = (align?: 'left' | 'center' | 'right') => {
|
||||
switch (align) {
|
||||
case 'left':
|
||||
return 'text-left'
|
||||
case 'right':
|
||||
return 'text-right'
|
||||
case 'center':
|
||||
default:
|
||||
return 'text-center'
|
||||
}
|
||||
}
|
||||
|
||||
export default function mdxComponents(type?: 'blog' | 'lp' | undefined) {
|
||||
const components = {
|
||||
CodeBlock,
|
||||
@@ -43,6 +55,22 @@ export default function mdxComponents(type?: 'blog' | 'lp' | undefined) {
|
||||
}
|
||||
return <img {...props} />
|
||||
},
|
||||
Img: (props: any) => (
|
||||
<figure>
|
||||
<span className={['next-image--dynamic-fill', props.wide && 'wide'].join(' ')}>
|
||||
<Image
|
||||
{...props}
|
||||
className={[type === 'blog' ? 'rounded-md border' : ''].join(' ')}
|
||||
layout="fill"
|
||||
/>
|
||||
</span>
|
||||
{props.caption && (
|
||||
<figcaption className={[getCaptionAlign(props.captionAlign)].join(' ')}>
|
||||
{props.caption}
|
||||
</figcaption>
|
||||
)}
|
||||
</figure>
|
||||
),
|
||||
code: (props: any) => <InlineCodeTag>{props.children}</InlineCodeTag>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1903,4 +1903,9 @@ module.exports = [
|
||||
source: '/docs/guides/integrations/dashibase',
|
||||
destination: '/docs',
|
||||
},
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/support',
|
||||
destination: '/support',
|
||||
},
|
||||
]
|
||||
@@ -4,9 +4,7 @@ export default class MyDocument extends Document {
|
||||
render() {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head>
|
||||
<script async src="https://platform.twitter.com/widgets.js" />
|
||||
</Head>
|
||||
<Head></Head>
|
||||
<body className="dark">
|
||||
<Main />
|
||||
<NextScript />
|
||||
|
||||
@@ -12,7 +12,7 @@ import DefaultLayout from '~/components/Layouts/Default'
|
||||
import BlogLinks from '~/components/LaunchWeek/7/BlogLinks'
|
||||
import { generateReadingTime } from '~/lib/helpers'
|
||||
import ShareArticleActions from '~/components/Blog/ShareArticleActions'
|
||||
// import useActiveAnchors from '~/hooks/useActiveAnchors'
|
||||
import useActiveAnchors from '~/hooks/useActiveAnchors'
|
||||
import mdxComponents from '~/lib/mdx/mdxComponents'
|
||||
import { mdxSerialize } from '~/lib/mdx/mdxSerialize'
|
||||
import { getAllPostSlugs, getPostdata, getSortedPosts } from '~/lib/posts'
|
||||
@@ -56,9 +56,9 @@ export async function getStaticProps({ params }: any) {
|
||||
relatedPosts,
|
||||
blog: {
|
||||
slug: `${params.slug}`,
|
||||
content: mdxSource,
|
||||
source: content,
|
||||
...data,
|
||||
content: mdxSource,
|
||||
toc: toc(content, { maxdepth: data.toc_depth ? data.toc_depth : 2 }),
|
||||
},
|
||||
},
|
||||
@@ -68,7 +68,7 @@ export async function getStaticProps({ params }: any) {
|
||||
function BlogPostPage(props: any) {
|
||||
const content = props.blog.content
|
||||
const authorArray = props.blog.author.split(',')
|
||||
// useActiveAnchors('h2, h3, h4')
|
||||
useActiveAnchors('h2, h3, h4', '.prose-toc a')
|
||||
const isLaunchWeek7 = props.blog.launchweek === 7
|
||||
|
||||
const author = []
|
||||
|
||||
@@ -10,7 +10,7 @@ export const meta = {
|
||||
|
||||
# Privacy Policy
|
||||
|
||||
_Last Modified: 27 March 2021_
|
||||
_Last Modified: 14 April 2023_
|
||||
|
||||
Thank you for your interest in Supabase, Inc., ("**_Supabase_**," "**_we_**", "**_our_**" or "**_us_**"). Supabase provides a suite of open source tools, stitched together to build a seamless developer experience. This Privacy Notice explains how information about you, that directly identifies you, or that makes you identifiable ("**_personal information_**") is collected, used and disclosed by Supabase in connection with our website at [supabase.com](https://supabase.com) (the "**_Site_**") and our services offered in connection with the Site (collectively with the Site, the "**_Service_**").
|
||||
|
||||
@@ -298,6 +298,15 @@ Some browsers also give you the option of downloading and installing extensions
|
||||
| <p>a0:state</p><p></p> | Strictly necessary | 2 Hours | Authentication Purposes. |
|
||||
| <p>youtube-nocookie</p><p></p> | Strictly necessary | Persistent | <p>Privacy-enhanced cookie, essential for embedded videos. [Link.](https://support.google.com/youtube/answer/171780)</p><p><blockquote><small>Privacy Enhanced Mode allows you to embed YouTube videos without using cookies that track viewing behavior. This means no activity is collected to personalize the viewing experience.</small></blockquote></p> |
|
||||
|
||||
## Annex 4 - Information you submit through our Supabase AI tool
|
||||
|
||||
When you submit a support query through our chatbot tool, we will collect the content of your query and information about the databases and other content you manage through the Service. We will only collect information about the structure of your databases and content, such as column and row headings or other information about how that content is organized. We will not access the content of the databases itself or the information you manage through the Service.
|
||||
|
||||
| **How we use the Personal Information** | **Legal Bases for Processing** | **Recipients of Personal Information** |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| When you use the chatbot to submit queries through your own individual account, we will use this information to generate automated responses to your query. | The processing is necessary for the performance of a contract with you, namely our Terms of Service. | We may share this information with the following service providers through the provision of the Service: OpenAI, LLC and its affiliates. |
|
||||
| We use this information to assess the performance of the chatbot tool and improve the Service. | The processing is necessary for our legitimate interests (to develop and improve our service). | We may share this information with the following service providers through the provision of the Service: OpenAI, LLC and its affiliates. |
|
||||
|
||||
</SectionContainer>
|
||||
|
||||
export default (context) => <Layout meta={meta} children={context.children} context={context} />
|
||||
+3
-3
@@ -26,12 +26,12 @@
|
||||
<rect x="572.088" y="744.622" width="206" height="24" rx="12" transform="rotate(-90 572.088 744.622)" stroke="#D16BCD" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M649.088 629.622C649.088 629.622 665.088 621.622 665.088 609.622V595.622L649.088 589.622L633.088 595.622V609.622C633.088 621.622 649.088 629.622 649.088 629.622Z" stroke="#EDEDED" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M633.584 682.91C635.6 682.91 637.136 682.07 638.384 680.63L637.232 679.406C636.224 680.534 635.144 681.158 633.704 681.158C630.68 681.158 628.736 678.638 628.736 674.654C628.736 670.718 630.68 668.246 633.704 668.246C635.024 668.246 636.056 668.822 636.872 669.686L638 668.414C637.088 667.406 635.6 666.494 633.704 666.494C629.6 666.494 626.672 669.614 626.672 674.702C626.672 679.862 629.624 682.91 633.584 682.91ZM643.079 682.622H645.071V675.926H647.879L651.671 682.622H653.951L649.943 675.71C652.079 675.158 653.471 673.694 653.471 671.222C653.471 667.934 651.167 666.782 647.975 666.782H643.079V682.622ZM645.071 674.294V668.39H647.687C650.135 668.39 651.479 669.134 651.479 671.222C651.479 673.286 650.135 674.294 647.687 674.294H645.071ZM659.03 682.622H668.99V680.918H661.046V675.158H667.55V673.454H661.046V668.462H668.75V666.782H659.03V682.622ZM672.628 682.622H674.668L676.18 677.774H681.892L683.38 682.622H685.492L680.188 666.782H677.932L672.628 682.622ZM676.684 676.166L677.428 673.742C677.98 671.966 678.484 670.262 678.988 668.414H679.084C679.588 670.262 680.092 671.966 680.644 673.742L681.388 676.166H676.684ZM693.643 682.622H695.659V668.462H700.843V666.782H688.459V668.462H693.643V682.622ZM705.802 682.622H715.762V680.918H707.818V675.158H714.322V673.454H707.818V668.462H715.522V666.782H705.802V682.622ZM736.623 682.622H738.615V675.926H741.423L745.215 682.622H747.495L743.487 675.71C745.623 675.158 747.015 673.694 747.015 671.222C747.015 667.934 744.711 666.782 741.519 666.782H736.623V682.622ZM738.615 674.294V668.39H741.231C743.679 668.39 745.023 669.134 745.023 671.222C745.023 673.286 743.679 674.294 741.231 674.294H738.615ZM750.581 682.622H752.621L754.133 677.774H759.845L761.333 682.622H763.445L758.141 666.782H755.885L750.581 682.622ZM754.637 676.166L755.381 673.742C755.933 671.966 756.437 670.262 756.941 668.414H757.037C757.541 670.262 758.045 671.966 758.597 673.742L759.341 676.166H754.637ZM767.396 682.622H769.292V674.318C769.292 672.686 769.1 670.982 769.028 669.374H769.076L770.66 672.614L775.772 682.622H777.812V666.782H775.916V675.014C775.916 676.67 776.108 678.47 776.18 680.03H776.132L774.548 676.79L769.436 666.782H767.396V682.622ZM783.035 682.622H786.971C791.627 682.622 794.171 679.67 794.171 674.63C794.171 669.614 791.627 666.782 786.875 666.782H783.035V682.622ZM785.027 680.99V668.414H786.755C790.331 668.414 792.107 670.646 792.107 674.63C792.107 678.638 790.331 680.99 786.755 680.99H785.027ZM803.785 682.91C807.337 682.91 809.833 679.718 809.833 674.63C809.833 669.59 807.337 666.494 803.785 666.494C800.233 666.494 797.737 669.566 797.737 674.63C797.737 679.718 800.233 682.91 803.785 682.91ZM803.785 681.158C801.385 681.158 799.801 678.59 799.801 674.63C799.801 670.694 801.385 668.246 803.785 668.246C806.185 668.246 807.769 670.694 807.769 674.63C807.769 678.59 806.185 681.158 803.785 681.158ZM814 682.622H815.8V673.67C815.8 672.374 815.632 670.094 815.536 668.822H815.608L816.76 672.206L819.304 678.326H820.408L822.928 672.206L824.032 668.822H824.128C824.032 670.094 823.888 672.374 823.888 673.67V682.622H825.712V666.782H823.36L820.792 673.526L819.928 676.094H819.832L818.92 673.526L816.352 666.782H814V682.622ZM852.814 682.91C854.83 682.91 856.366 682.07 857.614 680.63L856.462 679.406C855.454 680.534 854.374 681.158 852.934 681.158C849.91 681.158 847.966 678.638 847.966 674.654C847.966 670.718 849.91 668.246 852.934 668.246C854.254 668.246 855.286 668.822 856.102 669.686L857.23 668.414C856.318 667.406 854.83 666.494 852.934 666.494C848.83 666.494 845.902 669.614 845.902 674.702C845.902 679.862 848.854 682.91 852.814 682.91ZM867.109 682.91C870.661 682.91 873.157 679.718 873.157 674.63C873.157 669.59 870.661 666.494 867.109 666.494C863.557 666.494 861.061 669.566 861.061 674.63C861.061 679.718 863.557 682.91 867.109 682.91ZM867.109 681.158C864.709 681.158 863.125 678.59 863.125 674.63C863.125 670.694 864.709 668.246 867.109 668.246C869.509 668.246 871.093 670.694 871.093 674.63C871.093 678.59 869.509 681.158 867.109 681.158ZM877.539 682.622H881.475C886.131 682.622 888.675 679.67 888.675 674.63C888.675 669.614 886.131 666.782 881.379 666.782H877.539V682.622ZM879.531 680.99V668.414H881.259C884.835 668.414 886.611 670.646 886.611 674.63C886.611 678.638 884.835 680.99 881.259 680.99H879.531ZM893.85 682.622H903.81V680.918H895.866V675.158H902.37V673.454H895.866V668.462H903.57V666.782H893.85V682.622ZM928.319 682.622H930.647L935.639 666.782H933.599L931.079 675.35C930.527 677.222 930.143 678.71 929.567 680.582H929.471C928.895 678.71 928.511 677.222 927.959 675.35L925.415 666.782H923.303L928.319 682.622ZM940.622 682.622H950.582V680.918H942.638V675.158H949.142V673.454H942.638V668.462H950.342V666.782H940.622V682.622ZM955.852 682.622H957.844V675.926H960.652L964.444 682.622H966.724L962.716 675.71C964.852 675.158 966.244 673.694 966.244 671.222C966.244 667.934 963.94 666.782 960.748 666.782H955.852V682.622ZM957.844 674.294V668.39H960.46C962.908 668.39 964.252 669.134 964.252 671.222C964.252 673.286 962.908 674.294 960.46 Line truncated
|
||||
<path d="M610.472 1386.75C610.472 1377.91 617.636 1370.75 626.472 1370.75H1277.47C1295.15 1370.75 1309.47 1385.08 1309.47 1402.75V1594.75C1309.47 1612.42 1295.15 1626.75 1277.47 1626.75H626.472C617.636 1626.75 610.472 1619.59 610.472 1610.75V1386.75Z" fill="#D16BCD" fill-opacity="0.05"/>
|
||||
<path d="M610.472 1386.75C610.472 1377.91 617.636 1370.75 626.472 1370.75H1277.47C1295.15 1370.75 1309.47 1385.08 1309.47 1402.75V1594.75C1309.47 1612.42 1295.15 1626.75 1277.47 1626.75H626.472C617.636 1626.75 610.472 1619.59 610.472 1610.75V1386.75Z" fill="#3DCF8E" fill-opacity="0.05"/>
|
||||
<path d="M676.472 1440.75L682.472 1446.75L702.472 1426.75" stroke="#EDEDED" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M700.472 1442.75V1456.75C700.472 1457.81 700.051 1458.83 699.301 1459.58C698.55 1460.33 697.533 1460.75 696.472 1460.75H668.472C667.411 1460.75 666.394 1460.33 665.644 1459.58C664.894 1458.83 664.472 1457.81 664.472 1456.75V1428.75C664.472 1427.69 664.894 1426.67 665.644 1425.92C666.394 1425.17 667.411 1424.75 668.472 1424.75H690.472" stroke="#EDEDED" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M666.968 1516.04C668.984 1516.04 670.52 1515.2 671.768 1513.76L670.616 1512.54C669.608 1513.66 668.528 1514.29 667.088 1514.29C664.064 1514.29 662.12 1511.77 662.12 1507.78C662.12 1503.85 664.064 1501.38 667.088 1501.38C668.408 1501.38 669.44 1501.95 670.256 1502.82L671.384 1501.54C670.472 1500.54 668.984 1499.62 667.088 1499.62C662.984 1499.62 660.056 1502.74 660.056 1507.83C660.056 1512.99 663.008 1516.04 666.968 1516.04ZM681.263 1516.04C684.815 1516.04 687.311 1512.85 687.311 1507.76C687.311 1502.72 684.815 1499.62 681.263 1499.62C677.711 1499.62 675.215 1502.7 675.215 1507.76C675.215 1512.85 677.711 1516.04 681.263 1516.04ZM681.263 1514.29C678.863 1514.29 677.279 1511.72 677.279 1507.76C677.279 1503.82 678.863 1501.38 681.263 1501.38C683.663 1501.38 685.247 1503.82 685.247 1507.76C685.247 1511.72 683.663 1514.29 681.263 1514.29ZM691.693 1515.75H695.629C700.285 1515.75 702.829 1512.8 702.829 1507.76C702.829 1502.74 700.285 1499.91 695.533 1499.91H691.693V1515.75ZM693.685 1514.12V1501.54H695.413C698.989 1501.54 700.765 1503.78 700.765 1507.76C700.765 1511.77 698.989 1514.12 695.413 1514.12H693.685ZM708.004 1515.75H717.964V1514.05H710.02V1508.29H716.524V1506.58H710.02V1501.59H717.724V1499.91H708.004V1515.75ZM742.473 1515.75H744.801L749.793 1499.91H747.753L745.233 1508.48C744.681 1510.35 744.297 1511.84 743.721 1513.71H743.625C743.049 1511.84 742.665 1510.35 742.113 1508.48L739.569 1499.91H737.457L742.473 1515.75ZM754.776 1515.75H764.736V1514.05H756.792V1508.29H763.296V1506.58H756.792V1501.59H764.496V1499.91H754.776V1515.75ZM770.007 1515.75H771.999V1509.06H774.807L778.599 1515.75H780.879L776.871 1508.84C779.007 1508.29 780.399 1506.82 780.399 1504.35C780.399 1501.06 778.095 1499.91 774.903 1499.91H770.007V1515.75ZM771.999 1507.42V1501.52H774.615C777.063 1501.52 778.407 1502.26 778.407 1504.35C778.407 1506.42 777.063 1507.42 774.615 1507.42H771.999ZM785.477 1515.75H795.317V1514.05H791.405V1501.59H795.317V1499.91H785.477V1501.59H789.389V1514.05H785.477V1515.75ZM802.028 1515.75H804.02V1508.65H810.476V1506.97H804.02V1501.59H811.652V1499.91H802.028V1515.75ZM816.658 1515.75H826.498V1514.05H822.586V1501.59H826.498V1499.91H816.658V1501.59H820.57V1514.05H816.658V1515.75ZM832.729 1515.75H842.689V1514.05H834.745V1508.29H841.249V1506.58H834.745V1501.59H842.449V1499.91H832.729V1515.75ZM847.96 1515.75H849.952V1509.06H852.76L856.552 1515.75H858.832L854.824 1508.84C856.96 1508.29 858.352 1506.82 858.352 1504.35C858.352 1501.06 856.048 1499.91 852.856 1499.91H847.96V1515.75ZM849.952 1507.42V1501.52H852.568C855.016 1501.52 856.36 1502.26 856.36 1504.35C856.36 1506.42 855.016 1507.42 852.568 1507.42H849.952ZM878.565 1515.75H880.365V1506.8C880.365 1505.5 880.197 1503.22 880.101 1501.95H880.173L881.325 1505.34L883.869 1511.46H884.973L887.493 1505.34L888.597 1501.95H888.693C888.597 1503.22 888.453 1505.5 888.453 1506.8V1515.75H890.277V1499.91H887.925L885.357 1506.66L884.493 1509.22H884.397L883.485 1506.66L880.917 1499.91H878.565V1515.75ZM894.06 1515.75H896.1L897.612 1510.9H903.324L904.812 1515.75H906.924L901.62 1499.91H899.364L894.06 1515.75ZM898.116 1509.3L898.86 1506.87C899.412 1505.1 899.916 1503.39 900.42 1501.54H900.516C901.02 1503.39 901.524 1505.1 902.076 1506.87L902.82 1509.3H898.116ZM915.075 1515.75H917.091V1501.59H922.275V1499.91H909.891V1501.59H915.075V1515.75ZM932.97 1516.04C934.986 1516.04 936.522 1515.2 937.77 1513.76L936.618 1512.54C935.61 1513.66 934.53 1514.29 933.09 1514.29C930.066 1514.29 928.122 1511.77 928.122 1507.78C928.122 1503.85 930.066 1501.38 933.09 1501.38C934.41 1501.38 935.442 1501.95 936.258 1502.82L937.386 1501.54C936.474 1500.54 934.986 1499.62 933.09 1499.62C928.986 1499.62 926.058 1502.74 926.058 1507.83C926.058 1512.99 929.01 1516.04 932.97 1516.04ZM941.96 1515.75H943.976V1508.29H950.552V1515.75H952.568V1499.91H950.552V1506.56H943.976V1499.91H941.96V1515.75ZM958.415 1515.75H968.375V1514.05H960.431V1508.29H966.935V1506.58H960.431V1501.59H968.135V1499.91H958.415V1515.75ZM978.566 1516.04C982.022 1516.04 984.134 1514.05 984.134 1511.53C984.134 1509.18 982.574 1508.14 980.654 1507.3L978.446 1506.34C977.102 1505.77 975.638 1505.22 975.638 1503.7C975.638 1502.26 976.862 1501.38 978.758 1501.38C980.318 1501.38 981.518 1501.95 982.55 1502.86L983.606 1501.57C982.454 1500.42 980.726 1499.62 978.758 1499.62C975.758 1499.62 973.598 1501.4 973.598 1503.82C973.598 1506.13 975.422 1507.28 977.006 1507.9L979.262 1508.89C980.87 1509.58 982.094 1510.06 982.094 1511.7C982.094 1513.26 980.822 1514.29 978.59 1514.29C976.862 1514.29 975.23 1513.5 974.054 1512.3L972.854 1513.69C974.27 1515.13 976.262 1516.04 978.566 1516.04ZM1010.92 1516.04C1012.94 1516.04 1014.47 1515.2 1015.72 1513.76L1014.57 1512.54C1013.56 1513.66 1012.48 1514.29 1011.04 1514.29C1008.02 1514.29 1006.07 1511.77 1006.07 1507.78C1006.07 1503.85 1008.02 1501.38 1011.04 1501.38C1012.36 1501.38 1013.39 1501.95 1014.21 1502.82L1015.34 1501.54C1014.43 1500.54 1012.94 1499.62 1011.04 1499.62C1006.94 1499.62 1004.01 1502.74 1004.01 1507.83C1004.Line truncated
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" fill="#462944"/>
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" stroke="#D16BCD" stroke-width="2" stroke-linecap="round"/>
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" fill="#204532"/>
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" stroke="#3ECF8E" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M164.102 1818.29C167.174 1818.29 169.382 1816.56 169.382 1812.02V1802.16H167.438V1812.05C167.438 1815.36 165.998 1816.54 164.102 1816.54C162.206 1816.54 160.79 1815.36 160.79 1812.05V1802.16H158.774V1812.02C158.774 1816.56 161.006 1818.29 164.102 1818.29ZM179.789 1818.29C183.245 1818.29 185.357 1816.3 185.357 1813.78C185.357 1811.42 183.797 1810.39 181.877 1809.55L179.669 1808.59C178.325 1808.02 176.861 1807.46 176.861 1805.95C176.861 1804.51 178.085 1803.62 179.981 1803.62C181.541 1803.62 182.741 1804.2 183.773 1805.11L184.829 1803.82C183.677 1802.66 181.949 1801.87 179.981 1801.87C176.981 1801.87 174.821 1803.65 174.821 1806.07C174.821 1808.38 176.645 1809.53 178.229 1810.15L180.485 1811.14C182.093 1811.83 183.317 1812.31 183.317 1813.94C183.317 1815.5 182.045 1816.54 179.813 1816.54C178.085 1816.54 176.453 1815.74 175.277 1814.54L174.077 1815.94C175.493 1817.38 177.485 1818.29 179.789 1818.29ZM190.819 1818H200.779V1816.3H192.835V1810.54H199.339V1808.83H192.835V1803.84H200.539V1802.16H190.819V1818ZM206.05 1818H208.042V1811.3H210.85L214.642 1818H216.922L212.914 1811.09C215.05 1810.54 216.442 1809.07 216.442 1806.6C216.442 1803.31 214.138 1802.16 210.946 1802.16H206.05V1818ZM208.042 1809.67V1803.77H210.658C213.106 1803.77 214.45 1804.51 214.45 1806.6C214.45 1808.66 213.106 1809.67 210.658 1809.67H208.042ZM243.327 1818.29C245.343 1818.29 246.879 1817.45 248.127 1816.01L246.975 1814.78C245.967 1815.91 244.887 1816.54 243.447 1816.54C240.423 1816.54 238.479 1814.02 238.479 1810.03C238.479 1806.1 240.423 1803.62 243.447 1803.62C244.767 1803.62 245.799 1804.2 246.615 1805.06L247.743 1803.79C246.831 1802.78 245.343 1801.87 243.447 1801.87C239.343 1801.87 236.415 1804.99 236.415 1810.08C236.415 1815.24 239.367 1818.29 243.327 1818.29ZM251.19 1818H253.23L254.742 1813.15H260.454L261.942 1818H264.054L258.75 1802.16H256.494L251.19 1818ZM255.246 1811.54L255.99 1809.12C256.542 1807.34 257.046 1805.64 257.55 1803.79H257.646C258.15 1805.64 258.654 1807.34 259.206 1809.12L259.95 1811.54H255.246ZM268.004 1818H269.9V1809.7C269.9 1808.06 269.708 1806.36 269.636 1804.75H269.684L271.268 1807.99L276.38 1818H278.42V1802.16H276.524V1810.39C276.524 1812.05 276.716 1813.85 276.788 1815.41H276.74L275.156 1812.17L270.044 1802.16H268.004V1818ZM299.186 1818H301.082V1809.7C301.082 1808.06 300.89 1806.36 300.818 1804.75H300.866L302.45 1807.99L307.562 1818H309.602V1802.16H307.706V1810.39C307.706 1812.05 307.898 1813.85 307.97 1815.41H307.922L306.338 1812.17L301.226 1802.16H299.186V1818ZM319.984 1818.29C323.536 1818.29 326.032 1815.1 326.032 1810.01C326.032 1804.97 323.536 1801.87 319.984 1801.87C316.432 1801.87 313.936 1804.94 313.936 1810.01C313.936 1815.1 316.432 1818.29 319.984 1818.29ZM319.984 1816.54C317.584 1816.54 316 1813.97 316 1810.01C316 1806.07 317.584 1803.62 319.984 1803.62C322.384 1803.62 323.968 1806.07 323.968 1810.01C323.968 1813.97 322.384 1816.54 319.984 1816.54ZM331.039 1818H333.199L334.927 1811.35C335.167 1810.42 335.359 1809.43 335.551 1808.5H335.623C335.791 1809.43 335.983 1810.42 336.199 1811.35L337.999 1818H340.207L342.535 1802.14H340.639L339.439 1812.1C339.343 1813.39 339.199 1814.71 339.103 1816.01H339.007C338.671 1814.71 338.311 1813.37 338.023 1812.1L336.367 1806.24H334.951L333.295 1812.1C332.983 1813.39 332.623 1814.71 332.287 1816.01H332.215C332.119 1814.71 331.951 1813.42 331.879 1812.1L330.607 1802.14H328.615L331.039 1818ZM361.38 1818H363.18V1809.05C363.18 1807.75 363.012 1805.47 362.916 1804.2H362.988L364.14 1807.58L366.684 1813.7H367.788L370.308 1807.58L371.412 1804.2H371.508C371.412 1805.47 371.268 1807.75 371.268 1809.05V1818H373.092V1802.16H370.74L368.172 1808.9L367.308 1811.47H367.212L366.3 1808.9L363.732 1802.16H361.38V1818ZM376.876 1818H378.916L380.428 1813.15H386.14L387.628 1818H389.74L384.436 1802.16H382.18L376.876 1818ZM380.932 1811.54L381.676 1809.12C382.228 1807.34 382.732 1805.64 383.236 1803.79H383.332C383.836 1805.64 384.34 1807.34 384.892 1809.12L385.636 1811.54H380.932ZM394.05 1818H396.066V1812.96L398.802 1809.74L403.362 1818H405.594L400.05 1808.18L405.018 1802.16H402.762L396.138 1810.1H396.066V1802.16H394.05V1818ZM410.049 1818H420.009V1816.3H412.065V1810.54H418.569V1808.83H412.065V1803.84H419.769V1802.16H410.049V1818ZM157.646 1854H159.686L161.198 1849.15H166.91L168.398 1854H170.51L165.206 1838.16H162.95L157.646 1854ZM161.702 1847.54L162.446 1845.12C162.998 1843.34 163.502 1841.64 164.006 1839.79H164.102C164.606 1841.64 165.11 1843.34 165.662 1845.12L166.406 1847.54H161.702ZM179.693 1854.29C182.765 1854.29 184.973 1852.56 184.973 1848.02V1838.16H183.029V1848.05C183.029 1851.36 181.589 1852.54 179.693 1852.54C177.797 1852.54 176.381 1851.36 176.381 1848.05V1838.16H174.365V1848.02C174.365 1852.56 176.597 1854.29 179.693 1854.29ZM194.251 1854H196.267V1839.84H201.451V1838.16H189.067V1839.84H194.251V1854ZM205.546 1854H207.562V1846.54H214.138V1854H216.154V1838.16H214.138V1844.81H207.562V1838.16H205.546V1854ZM222 1854H231.96V1852.3H224.016V1846.54H230.52V1844.83H224.016V1839.84H231.72VLine truncated
|
||||
<circle cx="103.588" cy="1822.5" r="36" fill="url(#paint0_radial_26_19432)"/>
|
||||
<circle cx="103.588" cy="1822.5" r="20.5" fill="#3ECF8E"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
+3
-3
@@ -26,12 +26,12 @@
|
||||
<rect x="572.088" y="744.622" width="206" height="24" rx="12" transform="rotate(-90 572.088 744.622)" stroke="#D16BCD" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M649.088 629.622C649.088 629.622 665.088 621.622 665.088 609.622V595.622L649.088 589.622L633.088 595.622V609.622C633.088 621.622 649.088 629.622 649.088 629.622Z" stroke="#171717" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M633.584 682.91C635.6 682.91 637.136 682.07 638.384 680.63L637.232 679.406C636.224 680.534 635.144 681.158 633.704 681.158C630.68 681.158 628.736 678.638 628.736 674.654C628.736 670.718 630.68 668.246 633.704 668.246C635.024 668.246 636.056 668.822 636.872 669.686L638 668.414C637.088 667.406 635.6 666.494 633.704 666.494C629.6 666.494 626.672 669.614 626.672 674.702C626.672 679.862 629.624 682.91 633.584 682.91ZM643.079 682.622H645.071V675.926H647.879L651.671 682.622H653.951L649.943 675.71C652.079 675.158 653.471 673.694 653.471 671.222C653.471 667.934 651.167 666.782 647.975 666.782H643.079V682.622ZM645.071 674.294V668.39H647.687C650.135 668.39 651.479 669.134 651.479 671.222C651.479 673.286 650.135 674.294 647.687 674.294H645.071ZM659.03 682.622H668.99V680.918H661.046V675.158H667.55V673.454H661.046V668.462H668.75V666.782H659.03V682.622ZM672.628 682.622H674.668L676.18 677.774H681.892L683.38 682.622H685.492L680.188 666.782H677.932L672.628 682.622ZM676.684 676.166L677.428 673.742C677.98 671.966 678.484 670.262 678.988 668.414H679.084C679.588 670.262 680.092 671.966 680.644 673.742L681.388 676.166H676.684ZM693.643 682.622H695.659V668.462H700.843V666.782H688.459V668.462H693.643V682.622ZM705.802 682.622H715.762V680.918H707.818V675.158H714.322V673.454H707.818V668.462H715.522V666.782H705.802V682.622ZM736.623 682.622H738.615V675.926H741.423L745.215 682.622H747.495L743.487 675.71C745.623 675.158 747.015 673.694 747.015 671.222C747.015 667.934 744.711 666.782 741.519 666.782H736.623V682.622ZM738.615 674.294V668.39H741.231C743.679 668.39 745.023 669.134 745.023 671.222C745.023 673.286 743.679 674.294 741.231 674.294H738.615ZM750.581 682.622H752.621L754.133 677.774H759.845L761.333 682.622H763.445L758.141 666.782H755.885L750.581 682.622ZM754.637 676.166L755.381 673.742C755.933 671.966 756.437 670.262 756.941 668.414H757.037C757.541 670.262 758.045 671.966 758.597 673.742L759.341 676.166H754.637ZM767.396 682.622H769.292V674.318C769.292 672.686 769.1 670.982 769.028 669.374H769.076L770.66 672.614L775.772 682.622H777.812V666.782H775.916V675.014C775.916 676.67 776.108 678.47 776.18 680.03H776.132L774.548 676.79L769.436 666.782H767.396V682.622ZM783.035 682.622H786.971C791.627 682.622 794.171 679.67 794.171 674.63C794.171 669.614 791.627 666.782 786.875 666.782H783.035V682.622ZM785.027 680.99V668.414H786.755C790.331 668.414 792.107 670.646 792.107 674.63C792.107 678.638 790.331 680.99 786.755 680.99H785.027ZM803.785 682.91C807.337 682.91 809.833 679.718 809.833 674.63C809.833 669.59 807.337 666.494 803.785 666.494C800.233 666.494 797.737 669.566 797.737 674.63C797.737 679.718 800.233 682.91 803.785 682.91ZM803.785 681.158C801.385 681.158 799.801 678.59 799.801 674.63C799.801 670.694 801.385 668.246 803.785 668.246C806.185 668.246 807.769 670.694 807.769 674.63C807.769 678.59 806.185 681.158 803.785 681.158ZM814 682.622H815.8V673.67C815.8 672.374 815.632 670.094 815.536 668.822H815.608L816.76 672.206L819.304 678.326H820.408L822.928 672.206L824.032 668.822H824.128C824.032 670.094 823.888 672.374 823.888 673.67V682.622H825.712V666.782H823.36L820.792 673.526L819.928 676.094H819.832L818.92 673.526L816.352 666.782H814V682.622ZM852.814 682.91C854.83 682.91 856.366 682.07 857.614 680.63L856.462 679.406C855.454 680.534 854.374 681.158 852.934 681.158C849.91 681.158 847.966 678.638 847.966 674.654C847.966 670.718 849.91 668.246 852.934 668.246C854.254 668.246 855.286 668.822 856.102 669.686L857.23 668.414C856.318 667.406 854.83 666.494 852.934 666.494C848.83 666.494 845.902 669.614 845.902 674.702C845.902 679.862 848.854 682.91 852.814 682.91ZM867.109 682.91C870.661 682.91 873.157 679.718 873.157 674.63C873.157 669.59 870.661 666.494 867.109 666.494C863.557 666.494 861.061 669.566 861.061 674.63C861.061 679.718 863.557 682.91 867.109 682.91ZM867.109 681.158C864.709 681.158 863.125 678.59 863.125 674.63C863.125 670.694 864.709 668.246 867.109 668.246C869.509 668.246 871.093 670.694 871.093 674.63C871.093 678.59 869.509 681.158 867.109 681.158ZM877.539 682.622H881.475C886.131 682.622 888.675 679.67 888.675 674.63C888.675 669.614 886.131 666.782 881.379 666.782H877.539V682.622ZM879.531 680.99V668.414H881.259C884.835 668.414 886.611 670.646 886.611 674.63C886.611 678.638 884.835 680.99 881.259 680.99H879.531ZM893.85 682.622H903.81V680.918H895.866V675.158H902.37V673.454H895.866V668.462H903.57V666.782H893.85V682.622ZM928.319 682.622H930.647L935.639 666.782H933.599L931.079 675.35C930.527 677.222 930.143 678.71 929.567 680.582H929.471C928.895 678.71 928.511 677.222 927.959 675.35L925.415 666.782H923.303L928.319 682.622ZM940.622 682.622H950.582V680.918H942.638V675.158H949.142V673.454H942.638V668.462H950.342V666.782H940.622V682.622ZM955.852 682.622H957.844V675.926H960.652L964.444 682.622H966.724L962.716 675.71C964.852 675.158 966.244 673.694 966.244 671.222C966.244 667.934 963.94 666.782 960.748 666.782H955.852V682.622ZM957.844 674.294V668.39H960.46C962.908 668.39 964.252 669.134 964.252 671.222C964.252 673.286 962.908 674.294 960.46 Line truncated
|
||||
<path d="M610.472 1386.75C610.472 1377.91 617.636 1370.75 626.472 1370.75H1277.47C1295.15 1370.75 1309.47 1385.08 1309.47 1402.75V1594.75C1309.47 1612.42 1295.15 1626.75 1277.47 1626.75H626.472C617.636 1626.75 610.472 1619.59 610.472 1610.75V1386.75Z" fill="#D16BCD" fill-opacity="0.05"/>
|
||||
<path d="M610.472 1386.75C610.472 1377.91 617.636 1370.75 626.472 1370.75H1277.47C1295.15 1370.75 1309.47 1385.08 1309.47 1402.75V1594.75C1309.47 1612.42 1295.15 1626.75 1277.47 1626.75H626.472C617.636 1626.75 610.472 1619.59 610.472 1610.75V1386.75Z" fill="#3DCF8E" fill-opacity="0.05"/>
|
||||
<path d="M676.472 1440.75L682.472 1446.75L702.472 1426.75" stroke="#171717" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M700.472 1442.75V1456.75C700.472 1457.81 700.051 1458.83 699.301 1459.58C698.55 1460.33 697.533 1460.75 696.472 1460.75H668.472C667.411 1460.75 666.394 1460.33 665.644 1459.58C664.894 1458.83 664.472 1457.81 664.472 1456.75V1428.75C664.472 1427.69 664.894 1426.67 665.644 1425.92C666.394 1425.17 667.411 1424.75 668.472 1424.75H690.472" stroke="#171717" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M666.968 1516.04C668.984 1516.04 670.52 1515.2 671.768 1513.76L670.616 1512.54C669.608 1513.66 668.528 1514.29 667.088 1514.29C664.064 1514.29 662.12 1511.77 662.12 1507.78C662.12 1503.85 664.064 1501.38 667.088 1501.38C668.408 1501.38 669.44 1501.95 670.256 1502.82L671.384 1501.54C670.472 1500.54 668.984 1499.62 667.088 1499.62C662.984 1499.62 660.056 1502.74 660.056 1507.83C660.056 1512.99 663.008 1516.04 666.968 1516.04ZM681.263 1516.04C684.815 1516.04 687.311 1512.85 687.311 1507.76C687.311 1502.72 684.815 1499.62 681.263 1499.62C677.711 1499.62 675.215 1502.7 675.215 1507.76C675.215 1512.85 677.711 1516.04 681.263 1516.04ZM681.263 1514.29C678.863 1514.29 677.279 1511.72 677.279 1507.76C677.279 1503.82 678.863 1501.38 681.263 1501.38C683.663 1501.38 685.247 1503.82 685.247 1507.76C685.247 1511.72 683.663 1514.29 681.263 1514.29ZM691.693 1515.75H695.629C700.285 1515.75 702.829 1512.8 702.829 1507.76C702.829 1502.74 700.285 1499.91 695.533 1499.91H691.693V1515.75ZM693.685 1514.12V1501.54H695.413C698.989 1501.54 700.765 1503.78 700.765 1507.76C700.765 1511.77 698.989 1514.12 695.413 1514.12H693.685ZM708.004 1515.75H717.964V1514.05H710.02V1508.29H716.524V1506.58H710.02V1501.59H717.724V1499.91H708.004V1515.75ZM742.473 1515.75H744.801L749.793 1499.91H747.753L745.233 1508.48C744.681 1510.35 744.297 1511.84 743.721 1513.71H743.625C743.049 1511.84 742.665 1510.35 742.113 1508.48L739.569 1499.91H737.457L742.473 1515.75ZM754.776 1515.75H764.736V1514.05H756.792V1508.29H763.296V1506.58H756.792V1501.59H764.496V1499.91H754.776V1515.75ZM770.007 1515.75H771.999V1509.06H774.807L778.599 1515.75H780.879L776.871 1508.84C779.007 1508.29 780.399 1506.82 780.399 1504.35C780.399 1501.06 778.095 1499.91 774.903 1499.91H770.007V1515.75ZM771.999 1507.42V1501.52H774.615C777.063 1501.52 778.407 1502.26 778.407 1504.35C778.407 1506.42 777.063 1507.42 774.615 1507.42H771.999ZM785.477 1515.75H795.317V1514.05H791.405V1501.59H795.317V1499.91H785.477V1501.59H789.389V1514.05H785.477V1515.75ZM802.028 1515.75H804.02V1508.65H810.476V1506.97H804.02V1501.59H811.652V1499.91H802.028V1515.75ZM816.658 1515.75H826.498V1514.05H822.586V1501.59H826.498V1499.91H816.658V1501.59H820.57V1514.05H816.658V1515.75ZM832.729 1515.75H842.689V1514.05H834.745V1508.29H841.249V1506.58H834.745V1501.59H842.449V1499.91H832.729V1515.75ZM847.96 1515.75H849.952V1509.06H852.76L856.552 1515.75H858.832L854.824 1508.84C856.96 1508.29 858.352 1506.82 858.352 1504.35C858.352 1501.06 856.048 1499.91 852.856 1499.91H847.96V1515.75ZM849.952 1507.42V1501.52H852.568C855.016 1501.52 856.36 1502.26 856.36 1504.35C856.36 1506.42 855.016 1507.42 852.568 1507.42H849.952ZM878.565 1515.75H880.365V1506.8C880.365 1505.5 880.197 1503.22 880.101 1501.95H880.173L881.325 1505.34L883.869 1511.46H884.973L887.493 1505.34L888.597 1501.95H888.693C888.597 1503.22 888.453 1505.5 888.453 1506.8V1515.75H890.277V1499.91H887.925L885.357 1506.66L884.493 1509.22H884.397L883.485 1506.66L880.917 1499.91H878.565V1515.75ZM894.06 1515.75H896.1L897.612 1510.9H903.324L904.812 1515.75H906.924L901.62 1499.91H899.364L894.06 1515.75ZM898.116 1509.3L898.86 1506.87C899.412 1505.1 899.916 1503.39 900.42 1501.54H900.516C901.02 1503.39 901.524 1505.1 902.076 1506.87L902.82 1509.3H898.116ZM915.075 1515.75H917.091V1501.59H922.275V1499.91H909.891V1501.59H915.075V1515.75ZM932.97 1516.04C934.986 1516.04 936.522 1515.2 937.77 1513.76L936.618 1512.54C935.61 1513.66 934.53 1514.29 933.09 1514.29C930.066 1514.29 928.122 1511.77 928.122 1507.78C928.122 1503.85 930.066 1501.38 933.09 1501.38C934.41 1501.38 935.442 1501.95 936.258 1502.82L937.386 1501.54C936.474 1500.54 934.986 1499.62 933.09 1499.62C928.986 1499.62 926.058 1502.74 926.058 1507.83C926.058 1512.99 929.01 1516.04 932.97 1516.04ZM941.96 1515.75H943.976V1508.29H950.552V1515.75H952.568V1499.91H950.552V1506.56H943.976V1499.91H941.96V1515.75ZM958.415 1515.75H968.375V1514.05H960.431V1508.29H966.935V1506.58H960.431V1501.59H968.135V1499.91H958.415V1515.75ZM978.566 1516.04C982.022 1516.04 984.134 1514.05 984.134 1511.53C984.134 1509.18 982.574 1508.14 980.654 1507.3L978.446 1506.34C977.102 1505.77 975.638 1505.22 975.638 1503.7C975.638 1502.26 976.862 1501.38 978.758 1501.38C980.318 1501.38 981.518 1501.95 982.55 1502.86L983.606 1501.57C982.454 1500.42 980.726 1499.62 978.758 1499.62C975.758 1499.62 973.598 1501.4 973.598 1503.82C973.598 1506.13 975.422 1507.28 977.006 1507.9L979.262 1508.89C980.87 1509.58 982.094 1510.06 982.094 1511.7C982.094 1513.26 980.822 1514.29 978.59 1514.29C976.862 1514.29 975.23 1513.5 974.054 1512.3L972.854 1513.69C974.27 1515.13 976.262 1516.04 978.566 1516.04ZM1010.92 1516.04C1012.94 1516.04 1014.47 1515.2 1015.72 1513.76L1014.57 1512.54C1013.56 1513.66 1012.48 1514.29 1011.04 1514.29C1008.02 1514.29 1006.07 1511.77 1006.07 1507.78C1006.07 1503.85 1008.02 1501.38 1011.04 1501.38C1012.36 1501.38 1013.39 1501.95 1014.21 1502.82L1015.34 1501.54C1014.43 1500.54 1012.94 1499.62 1011.04 1499.62C1006.94 1499.62 1004.01 1502.74 1004.01 1507.83C1004.Line truncated
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" fill="#F2CCEE"/>
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" stroke="#D16BCD" stroke-width="2" stroke-linecap="round"/>
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" fill="#C5F0D7"/>
|
||||
<rect x="1284.47" y="1625.75" width="254" height="24" rx="12" transform="rotate(-90 1284.47 1625.75)" stroke="#3ECF8E" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M164.102 1818.29C167.174 1818.29 169.382 1816.56 169.382 1812.02V1802.16H167.438V1812.05C167.438 1815.36 165.998 1816.54 164.102 1816.54C162.206 1816.54 160.79 1815.36 160.79 1812.05V1802.16H158.774V1812.02C158.774 1816.56 161.006 1818.29 164.102 1818.29ZM179.789 1818.29C183.245 1818.29 185.357 1816.3 185.357 1813.78C185.357 1811.42 183.797 1810.39 181.877 1809.55L179.669 1808.59C178.325 1808.02 176.861 1807.46 176.861 1805.95C176.861 1804.51 178.085 1803.62 179.981 1803.62C181.541 1803.62 182.741 1804.2 183.773 1805.11L184.829 1803.82C183.677 1802.66 181.949 1801.87 179.981 1801.87C176.981 1801.87 174.821 1803.65 174.821 1806.07C174.821 1808.38 176.645 1809.53 178.229 1810.15L180.485 1811.14C182.093 1811.83 183.317 1812.31 183.317 1813.94C183.317 1815.5 182.045 1816.54 179.813 1816.54C178.085 1816.54 176.453 1815.74 175.277 1814.54L174.077 1815.94C175.493 1817.38 177.485 1818.29 179.789 1818.29ZM190.819 1818H200.779V1816.3H192.835V1810.54H199.339V1808.83H192.835V1803.84H200.539V1802.16H190.819V1818ZM206.05 1818H208.042V1811.3H210.85L214.642 1818H216.922L212.914 1811.09C215.05 1810.54 216.442 1809.07 216.442 1806.6C216.442 1803.31 214.138 1802.16 210.946 1802.16H206.05V1818ZM208.042 1809.67V1803.77H210.658C213.106 1803.77 214.45 1804.51 214.45 1806.6C214.45 1808.66 213.106 1809.67 210.658 1809.67H208.042ZM243.327 1818.29C245.343 1818.29 246.879 1817.45 248.127 1816.01L246.975 1814.78C245.967 1815.91 244.887 1816.54 243.447 1816.54C240.423 1816.54 238.479 1814.02 238.479 1810.03C238.479 1806.1 240.423 1803.62 243.447 1803.62C244.767 1803.62 245.799 1804.2 246.615 1805.06L247.743 1803.79C246.831 1802.78 245.343 1801.87 243.447 1801.87C239.343 1801.87 236.415 1804.99 236.415 1810.08C236.415 1815.24 239.367 1818.29 243.327 1818.29ZM251.19 1818H253.23L254.742 1813.15H260.454L261.942 1818H264.054L258.75 1802.16H256.494L251.19 1818ZM255.246 1811.54L255.99 1809.12C256.542 1807.34 257.046 1805.64 257.55 1803.79H257.646C258.15 1805.64 258.654 1807.34 259.206 1809.12L259.95 1811.54H255.246ZM268.004 1818H269.9V1809.7C269.9 1808.06 269.708 1806.36 269.636 1804.75H269.684L271.268 1807.99L276.38 1818H278.42V1802.16H276.524V1810.39C276.524 1812.05 276.716 1813.85 276.788 1815.41H276.74L275.156 1812.17L270.044 1802.16H268.004V1818ZM299.186 1818H301.082V1809.7C301.082 1808.06 300.89 1806.36 300.818 1804.75H300.866L302.45 1807.99L307.562 1818H309.602V1802.16H307.706V1810.39C307.706 1812.05 307.898 1813.85 307.97 1815.41H307.922L306.338 1812.17L301.226 1802.16H299.186V1818ZM319.984 1818.29C323.536 1818.29 326.032 1815.1 326.032 1810.01C326.032 1804.97 323.536 1801.87 319.984 1801.87C316.432 1801.87 313.936 1804.94 313.936 1810.01C313.936 1815.1 316.432 1818.29 319.984 1818.29ZM319.984 1816.54C317.584 1816.54 316 1813.97 316 1810.01C316 1806.07 317.584 1803.62 319.984 1803.62C322.384 1803.62 323.968 1806.07 323.968 1810.01C323.968 1813.97 322.384 1816.54 319.984 1816.54ZM331.039 1818H333.199L334.927 1811.35C335.167 1810.42 335.359 1809.43 335.551 1808.5H335.623C335.791 1809.43 335.983 1810.42 336.199 1811.35L337.999 1818H340.207L342.535 1802.14H340.639L339.439 1812.1C339.343 1813.39 339.199 1814.71 339.103 1816.01H339.007C338.671 1814.71 338.311 1813.37 338.023 1812.1L336.367 1806.24H334.951L333.295 1812.1C332.983 1813.39 332.623 1814.71 332.287 1816.01H332.215C332.119 1814.71 331.951 1813.42 331.879 1812.1L330.607 1802.14H328.615L331.039 1818ZM361.38 1818H363.18V1809.05C363.18 1807.75 363.012 1805.47 362.916 1804.2H362.988L364.14 1807.58L366.684 1813.7H367.788L370.308 1807.58L371.412 1804.2H371.508C371.412 1805.47 371.268 1807.75 371.268 1809.05V1818H373.092V1802.16H370.74L368.172 1808.9L367.308 1811.47H367.212L366.3 1808.9L363.732 1802.16H361.38V1818ZM376.876 1818H378.916L380.428 1813.15H386.14L387.628 1818H389.74L384.436 1802.16H382.18L376.876 1818ZM380.932 1811.54L381.676 1809.12C382.228 1807.34 382.732 1805.64 383.236 1803.79H383.332C383.836 1805.64 384.34 1807.34 384.892 1809.12L385.636 1811.54H380.932ZM394.05 1818H396.066V1812.96L398.802 1809.74L403.362 1818H405.594L400.05 1808.18L405.018 1802.16H402.762L396.138 1810.1H396.066V1802.16H394.05V1818ZM410.049 1818H420.009V1816.3H412.065V1810.54H418.569V1808.83H412.065V1803.84H419.769V1802.16H410.049V1818ZM157.646 1854H159.686L161.198 1849.15H166.91L168.398 1854H170.51L165.206 1838.16H162.95L157.646 1854ZM161.702 1847.54L162.446 1845.12C162.998 1843.34 163.502 1841.64 164.006 1839.79H164.102C164.606 1841.64 165.11 1843.34 165.662 1845.12L166.406 1847.54H161.702ZM179.693 1854.29C182.765 1854.29 184.973 1852.56 184.973 1848.02V1838.16H183.029V1848.05C183.029 1851.36 181.589 1852.54 179.693 1852.54C177.797 1852.54 176.381 1851.36 176.381 1848.05V1838.16H174.365V1848.02C174.365 1852.56 176.597 1854.29 179.693 1854.29ZM194.251 1854H196.267V1839.84H201.451V1838.16H189.067V1839.84H194.251V1854ZM205.546 1854H207.562V1846.54H214.138V1854H216.154V1838.16H214.138V1844.81H207.562V1838.16H205.546V1854ZM222 1854H231.96V1852.3H224.016V1846.54H230.52V1844.83H224.016V1839.84H231.72VLine truncated
|
||||
<circle cx="103.588" cy="1822.5" r="36" fill="url(#paint0_radial_26_19432)"/>
|
||||
<circle cx="103.588" cy="1822.5" r="20.5" fill="#3ECF8E"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
@@ -85,8 +85,7 @@ h6:not(.overwrite) {
|
||||
}
|
||||
|
||||
.toc-animate {
|
||||
transform: translate3d(3px, 0, 0) !important;
|
||||
color: hsla(153, 60%, 53%, 1) !important;
|
||||
@apply !translate-x-1 !text-brand-900;
|
||||
}
|
||||
|
||||
.prose-toc a {
|
||||
@@ -245,9 +244,34 @@ table {
|
||||
*
|
||||
*/
|
||||
.next-image--dynamic-fill {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.next-image--dynamic-fill.wide {
|
||||
@apply my-0 max-w-none -mx-8 w-[calc(100%_+_4rem)];
|
||||
}
|
||||
@media (min-width: 560px) {
|
||||
.next-image--dynamic-fill.wide {
|
||||
width: calc(100% + 6rem);
|
||||
margin: 0 -3rem;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px) {
|
||||
.next-image--dynamic-fill.wide {
|
||||
width: calc(100% + 10rem);
|
||||
margin: 0 -5rem;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1535px) {
|
||||
.next-image--dynamic-fill.wide {
|
||||
width: calc(100% + 14rem);
|
||||
margin: 0 -7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.next-image--dynamic-fill > span {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,12 @@ module.exports = ui({
|
||||
figcaption: {
|
||||
color: 'var(--colors-scale9)',
|
||||
},
|
||||
'figure.quote-figure p:first-child': {
|
||||
marginTop: '0 !important',
|
||||
},
|
||||
'figure.quote-figure p:last-child': {
|
||||
marginBottom: '0 !important',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import React from 'react'
|
||||
import type {
|
||||
ChatCompletionResponseMessage,
|
||||
CreateChatCompletionResponse,
|
||||
@@ -15,11 +16,12 @@ import {
|
||||
|
||||
import { SSE } from 'sse.js'
|
||||
|
||||
import { Button, IconAlertTriangle, IconCornerDownLeft, IconUser, Input } from 'ui'
|
||||
import { Alert, Button, IconAlertTriangle, IconCornerDownLeft, IconUser, Input } from 'ui'
|
||||
import { AiIcon, AiIconChat } from './Command.icons'
|
||||
import { CommandGroup, CommandItem } from './Command.utils'
|
||||
|
||||
import { useCommandMenu } from './CommandMenuProvider'
|
||||
import { AiWarning } from './Command.alerts'
|
||||
|
||||
import { cn } from './../../utils/cn'
|
||||
|
||||
@@ -364,7 +366,7 @@ const AiCommand = () => {
|
||||
|
||||
return (
|
||||
<div onClick={(e) => e.stopPropagation()}>
|
||||
<div className={cn('relative mb-[62px] py-4 max-h-[720px] overflow-auto')}>
|
||||
<div className={cn('relative mb-[145px] py-4 max-h-[720px] overflow-auto')}>
|
||||
{messages.map((message, index) => {
|
||||
switch (message.role) {
|
||||
case MessageRole.User:
|
||||
@@ -454,6 +456,7 @@ const AiCommand = () => {
|
||||
<div className="[overflow-anchor:auto] h-px w-full"></div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 w-full bg-scale-200 py-3">
|
||||
{messages.length > 0 && !hasError && <AiWarning className="mb-3 mx-3" />}
|
||||
<Input
|
||||
className="bg-scale-100 rounded mx-3"
|
||||
autoFocus
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Badge } from 'ui'
|
||||
import { Microscope } from 'lucide-react'
|
||||
|
||||
export const BadgeExperimental = () => {
|
||||
return (
|
||||
<Badge color="scale">
|
||||
<Microscope className="!mr-1.5 !w-3.5 !h-3.5" /> Experimental
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Alert } from 'ui'
|
||||
import { Microscope } from 'lucide-react'
|
||||
|
||||
export const AiWarning = ({ className }: { className?: string }) => (
|
||||
<Alert
|
||||
variant="info"
|
||||
title="Supabase AI is experimental and may produce incorrect answers."
|
||||
className={className}
|
||||
icon={<Microscope strokeWidth={1.5} size={18} className="text-scale-900" />}
|
||||
>
|
||||
<p>Always verify the output before executing.</p>
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const IncludeSchemaAlert = () => (
|
||||
<Alert
|
||||
variant={'warning'}
|
||||
title="Project metadata (tables, columns, and data types) is being shared with OpenAI"
|
||||
withIcon
|
||||
className="mx-3"
|
||||
>
|
||||
Start a new conversation to change this configuration
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const ExcludeSchemaAlert = () => (
|
||||
<Alert
|
||||
variant={'info'}
|
||||
title="Project metadata (tables, columns, and data types) is not being shared with OpenAI"
|
||||
withIcon
|
||||
className="mx-3"
|
||||
>
|
||||
Start a new conversation to change this configuration
|
||||
</Alert>
|
||||
)
|
||||
@@ -17,7 +17,7 @@ type SampleQueries = QueryCategory[]
|
||||
|
||||
export const SAMPLE_QUERIES: SampleQueries = [
|
||||
{
|
||||
category: 'Create tables',
|
||||
category: 'Tables',
|
||||
queries: [
|
||||
'Create a table that stores a list of cities, and insert 10 rows of sample data into it',
|
||||
'Create tables (with foreign key relationships) for blog posts and comments',
|
||||
@@ -25,7 +25,7 @@ export const SAMPLE_QUERIES: SampleQueries = [
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Create views',
|
||||
category: 'Views',
|
||||
queries: [
|
||||
'Create a view that shows the total revenue for each customer',
|
||||
'Create a view that shows all orders that were placed in the last week',
|
||||
@@ -34,7 +34,7 @@ export const SAMPLE_QUERIES: SampleQueries = [
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Create indexes',
|
||||
category: 'Indexes',
|
||||
queries: [
|
||||
'Create an index on the primary key column of my orders table',
|
||||
'Create a partial index on the orders table:',
|
||||
@@ -42,7 +42,7 @@ export const SAMPLE_QUERIES: SampleQueries = [
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Select data',
|
||||
category: 'Select',
|
||||
queries: [
|
||||
'Retrieve a list of employees from the employees table who have a salary greater than $50,000',
|
||||
'Retrieve a list of all employees with the title "Manager" from the employees table',
|
||||
@@ -51,7 +51,7 @@ export const SAMPLE_QUERIES: SampleQueries = [
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Create triggers',
|
||||
category: 'Triggers',
|
||||
queries: [
|
||||
'Create a trigger that updates the updated_at column on the orders table with the current time when the row of the orders table is updated',
|
||||
'Create a trigger to add a new user to the users table when someone new registers',
|
||||
@@ -60,7 +60,7 @@ export const SAMPLE_QUERIES: SampleQueries = [
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Row level security',
|
||||
category: 'Row Level Security',
|
||||
queries: [
|
||||
'Create an RLS policy that grants only authenticated access to the profiles table',
|
||||
'Create an RLS policy that grants SELECT access to the sales_rep role for the customers table, but denies access to all other roles',
|
||||
@@ -68,7 +68,7 @@ export const SAMPLE_QUERIES: SampleQueries = [
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Postgres functions',
|
||||
category: 'Functions',
|
||||
queries: [
|
||||
"Create a function to add a new entry to a user's table when a new user signs up",
|
||||
'Create an a function to calculate the average price of a product in a given category',
|
||||
|
||||
@@ -180,10 +180,11 @@ type CommandPrimitiveItemProps = React.ComponentPropsWithoutRef<typeof CommandPr
|
||||
|
||||
export interface CommandItemProps extends CommandPrimitiveItemProps {
|
||||
type: 'link' | 'block-link' | 'command'
|
||||
badge?: React.ReactNode
|
||||
}
|
||||
|
||||
export const CommandItem = React.forwardRef<CommandPrimitiveItemElement, CommandItemProps>(
|
||||
({ className, type, ...props }, ref) => (
|
||||
({ className, type, children, badge, ...props }, ref) => (
|
||||
<CommandPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
@@ -238,7 +239,12 @@ export const CommandItem = React.forwardRef<CommandPrimitiveItemElement, Command
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row items-center">{children}</div>
|
||||
{badge}
|
||||
</div>
|
||||
</CommandPrimitive.Item>
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import ThemeOptions from './ThemeOptions'
|
||||
import APIKeys from './APIKeys'
|
||||
import SearchableStudioItems from './SearchableStudioItems'
|
||||
import CommandMenuShortcuts from './CommandMenuShortcuts'
|
||||
import { BadgeExperimental } from './Command.Badges'
|
||||
|
||||
export const CHAT_ROUTES = [
|
||||
COMMAND_ROUTES.AI, // this one is temporary
|
||||
@@ -91,6 +92,7 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
<CommandGroup heading="Documentation" forceMount>
|
||||
<CommandItem
|
||||
type="command"
|
||||
badge={<BadgeExperimental />}
|
||||
onSelect={() => {
|
||||
setPages([...pages, COMMAND_ROUTES.AI])
|
||||
}}
|
||||
@@ -174,6 +176,7 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
<CommandItem
|
||||
forceMount
|
||||
type="command"
|
||||
badge={<BadgeExperimental />}
|
||||
onSelect={() => setPages([...pages, COMMAND_ROUTES.GENERATE_SQL])}
|
||||
>
|
||||
<AiIcon className="text-scale-1100" />
|
||||
@@ -203,7 +206,14 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
).split('https://app.supabase.com')[1]
|
||||
|
||||
return (
|
||||
<CommandItem key={item.url} type="link" onSelect={() => router.push(itemUrl)}>
|
||||
<CommandItem
|
||||
key={item.url}
|
||||
type="link"
|
||||
onSelect={() => {
|
||||
router.push(item.url)
|
||||
setIsOpen(false)
|
||||
}}
|
||||
>
|
||||
<IconArrowRight className="text-scale-900" />
|
||||
<CommandLabel>
|
||||
Go to <span className="font-bold"> {item.label}</span>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import { IconArrowLeft } from '../Icon/icons/IconArrowLeft'
|
||||
|
||||
import { BadgeExperimental } from './Command.Badges'
|
||||
import { COMMAND_ROUTES } from './Command.constants'
|
||||
import { CommandShortcut } from './Command.utils'
|
||||
import { useCommandMenu } from './CommandMenuProvider'
|
||||
|
||||
@@ -8,27 +9,45 @@ export default function CommandMenuShortcuts() {
|
||||
const { setPages, pages, currentPage } = useCommandMenu()
|
||||
|
||||
return (
|
||||
<div className="flex w-full gap-2 px-4 pt-4 justify-items-start flex-row items-center">
|
||||
<CommandShortcut onClick={() => setPages([])}>
|
||||
<div className="flex items-center gap-2">
|
||||
<IconArrowLeft width={15} height={15} />
|
||||
</div>
|
||||
</CommandShortcut>
|
||||
|
||||
{pages.map((page, index) => (
|
||||
<CommandShortcut
|
||||
type={page === currentPage ? 'breadcrumb' : 'default'}
|
||||
key={page}
|
||||
onClick={() => {
|
||||
if (index === pages.length - 1) {
|
||||
return
|
||||
}
|
||||
setPages(pages.slice(0, index - 1))
|
||||
}}
|
||||
>
|
||||
{page}
|
||||
<div className="flex w-full gap-2 px-4 pt-4 justify-items-start flex-row items-center justify-between">
|
||||
<div className="flex gap-2 flex-row items-center">
|
||||
<CommandShortcut onClick={() => setPages([])}>
|
||||
<div className="flex items-center gap-2">
|
||||
<IconArrowLeft width={15} height={15} />
|
||||
</div>
|
||||
</CommandShortcut>
|
||||
))}
|
||||
|
||||
{pages.map((page, index) => (
|
||||
<CommandShortcut
|
||||
type={page === currentPage ? 'breadcrumb' : 'default'}
|
||||
key={page}
|
||||
onClick={() => {
|
||||
if (index === pages.length - 1) {
|
||||
return
|
||||
}
|
||||
setPages(pages.slice(0, index - 1))
|
||||
}}
|
||||
>
|
||||
{page}
|
||||
</CommandShortcut>
|
||||
))}
|
||||
|
||||
{currentPage && isExperimental(currentPage) && <BadgeExperimental />}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: remove this function and store this info on each page
|
||||
* Temporary function to determine whether or not to show 'Experimental' badge
|
||||
*/
|
||||
function isExperimental(page: string) {
|
||||
switch (page) {
|
||||
case COMMAND_ROUTES.AI:
|
||||
case COMMAND_ROUTES.GENERATE_SQL:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import React from 'react'
|
||||
import { format } from 'sql-formatter'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import {
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
MessageRole,
|
||||
MessageStatus,
|
||||
useAiChat,
|
||||
Tabs,
|
||||
} from 'ui'
|
||||
|
||||
import { cn } from '../../../utils/cn'
|
||||
@@ -20,6 +22,7 @@ import { useCommandMenu } from '../CommandMenuProvider'
|
||||
import { SAMPLE_QUERIES } from '../Command.constants'
|
||||
import SQLOutputActions from './SQLOutputActions'
|
||||
import { generatePrompt } from './GenerateSQL.utils'
|
||||
import { ExcludeSchemaAlert, IncludeSchemaAlert, AiWarning } from '../Command.alerts'
|
||||
|
||||
const GenerateSQL = () => {
|
||||
// [Joshen] Temp hack to ensure that generatePrompt receives updated value
|
||||
@@ -83,8 +86,8 @@ const GenerateSQL = () => {
|
||||
<div onClick={(e) => e.stopPropagation()}>
|
||||
<div
|
||||
className={cn(
|
||||
'relative py-4 max-h-[550px] overflow-auto',
|
||||
allowSendingSchemaMetadata ? 'mb-[83px]' : 'mb-[42px]'
|
||||
'relative py-4 max-h-[420px] overflow-auto',
|
||||
allowSendingSchemaMetadata ? 'mb-[155px]' : 'mb-[64px]'
|
||||
)}
|
||||
>
|
||||
{messages.map((message, i) => {
|
||||
@@ -116,7 +119,8 @@ const GenerateSQL = () => {
|
||||
message.status === MessageStatus.Complete
|
||||
? formatAnswer(unformattedAnswer)
|
||||
: unformattedAnswer
|
||||
const cantHelp = answer === "Sorry, I don't know how to help with that."
|
||||
const cantHelp =
|
||||
answer.replace(/^-- /, '') === "Sorry, I don't know how to help with that."
|
||||
|
||||
return (
|
||||
<div className="px-4 [overflow-anchor:none] mb-6">
|
||||
@@ -143,13 +147,20 @@ const GenerateSQL = () => {
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2 flex-grow max-w-[93%]">
|
||||
<CodeBlock
|
||||
hideCopy
|
||||
language="sql"
|
||||
className="relative prose dark:prose-dark bg-scale-300 max-w-none"
|
||||
>
|
||||
{answer}
|
||||
</CodeBlock>
|
||||
<div className="-space-y-px">
|
||||
<CodeBlock
|
||||
hideCopy
|
||||
language="sql"
|
||||
className="
|
||||
relative prose dark:prose-dark bg-scale-300 max-w-none !mb-0
|
||||
!rounded-b-none
|
||||
|
||||
"
|
||||
>
|
||||
{answer}
|
||||
</CodeBlock>
|
||||
<AiWarning className="!rounded-t-none border-scale-400" />
|
||||
</div>
|
||||
{message.status === MessageStatus.Complete && (
|
||||
<SQLOutputActions answer={answer} messages={messages.slice(0, i + 1)} />
|
||||
)}
|
||||
@@ -164,57 +175,59 @@ const GenerateSQL = () => {
|
||||
|
||||
{messages.length === 0 && !hasError && (
|
||||
<div>
|
||||
<div className="px-10">
|
||||
<h3>
|
||||
<div className="px-4">
|
||||
<h3 className="text-base text-scale-1100">
|
||||
Describe what you need and Supabase AI will try to generate the relevant SQL
|
||||
statements
|
||||
</h3>
|
||||
<p className="text-sm mt-1 text-scale-1100">
|
||||
Here are some example prompts to try out.
|
||||
Here are some example prompts to try out:
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex mt-4 border-t pt-2">
|
||||
<div className="w-1/3 py-4 px-6">
|
||||
<ul className="space-y-2">
|
||||
{SAMPLE_QUERIES.map((item, index) => (
|
||||
<li
|
||||
key={index}
|
||||
onClick={() => setSelectedCategory(item.category)}
|
||||
className={cn(
|
||||
'px-4 py-1 cursor-pointer text-sm hover:bg-slate-300 rounded-md',
|
||||
selectedCategory === item.category && 'bg-slate-400 '
|
||||
)}
|
||||
>
|
||||
{item.category}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="w-2/3 py-4 px-6">
|
||||
<ul>
|
||||
{SAMPLE_QUERIES.find((item) => item.category === selectedCategory)?.queries.map(
|
||||
(query, index) => (
|
||||
<CommandItem
|
||||
type="command"
|
||||
onSelect={() => {
|
||||
if (!search) {
|
||||
handleSubmit(query)
|
||||
}
|
||||
}}
|
||||
forceMount
|
||||
key={query.replace(/\s+/g, '_')}
|
||||
>
|
||||
<div className="flex">
|
||||
<div>
|
||||
<AiIcon />
|
||||
<div className="mt-4 border-t pt-4 ml-4">
|
||||
<Tabs type="rounded-pills" size="small">
|
||||
{SAMPLE_QUERIES.map((sample) => (
|
||||
<Tabs.Panel
|
||||
key={sample.category}
|
||||
id={sample.category}
|
||||
label={sample.category}
|
||||
className="mt-4"
|
||||
>
|
||||
<div className="mr-8">
|
||||
{SAMPLE_QUERIES.find(
|
||||
(item) => item.category === sample.category
|
||||
)?.queries.map((query) => (
|
||||
<CommandItem
|
||||
type="command"
|
||||
onSelect={() => {
|
||||
if (!search) {
|
||||
handleSubmit(query)
|
||||
}
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
switch (e.key) {
|
||||
case 'Enter':
|
||||
if (!search || isLoading || isResponding) return
|
||||
return handleSubmit(query)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}}
|
||||
forceMount
|
||||
key={query.replace(/\s+/g, '_')}
|
||||
>
|
||||
<div className="flex">
|
||||
<div>
|
||||
<AiIcon />
|
||||
</div>
|
||||
<p>{query}</p>
|
||||
</div>
|
||||
<p>{query}</p>
|
||||
</div>
|
||||
</CommandItem>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
</div>
|
||||
</Tabs.Panel>
|
||||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -235,9 +248,10 @@ const GenerateSQL = () => {
|
||||
<div className="[overflow-anchor:auto] h-px w-full"></div>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-0 w-full bg-scale-200 py-3">
|
||||
<div className="absolute bottom-0 w-full bg-scale-200 pt-4">
|
||||
{/* {messages.length > 0 && !hasError && <AiWarning className="mb-4 mx-4" />} */}
|
||||
{allowSendingSchemaMetadata && (
|
||||
<>
|
||||
<div className="mb-4">
|
||||
{messages.length === 0 ? (
|
||||
<div className="flex items-center justify-between px-6 py-3">
|
||||
<div>
|
||||
@@ -261,25 +275,12 @@ const GenerateSQL = () => {
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
) : includeSchemaMetadata ? (
|
||||
<IncludeSchemaAlert />
|
||||
) : (
|
||||
<div className="flex items-center justify-between px-6 py-3">
|
||||
<div>
|
||||
<p className="text-sm">
|
||||
Table names, column names and their corresponding data types{' '}
|
||||
<span
|
||||
className={cn(includeSchemaMetadata ? 'text-brand-900' : 'text-amber-900')}
|
||||
>
|
||||
{includeSchemaMetadata ? 'are' : 'are not'} included
|
||||
</span>{' '}
|
||||
in this conversation
|
||||
</p>
|
||||
<p className="text-sm text-scale-1100">
|
||||
Start a new conversation to change this configuration
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<ExcludeSchemaAlert />
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
<Input
|
||||
inputRef={(inputElement) => {
|
||||
@@ -291,7 +292,7 @@ const GenerateSQL = () => {
|
||||
}, 0)
|
||||
}
|
||||
}}
|
||||
className="bg-scale-100 rounded mx-3"
|
||||
className="bg-scale-100 rounded mx-3 mb-4"
|
||||
autoFocus
|
||||
placeholder={
|
||||
isLoading || isResponding
|
||||
|
||||
@@ -98,7 +98,10 @@ export function Item({ icon, className, ...props }: ItemProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
return (
|
||||
<RadixDropdown.Item className={cn(__styles.item, className)} {...props}>
|
||||
<RadixDropdown.Item
|
||||
className={cn(__styles.item, className, props.disabled && __styles.disabled)}
|
||||
{...props}
|
||||
>
|
||||
{icon && icon}
|
||||
<span>{props.children}</span>
|
||||
</RadixDropdown.Item>
|
||||
|
||||
@@ -256,7 +256,7 @@ export default {
|
||||
|
||||
alert: {
|
||||
base: `
|
||||
relative rounded border py-4 px-6
|
||||
relative rounded-md border py-4 px-6
|
||||
flex space-x-4 items-start
|
||||
`,
|
||||
header: 'block text-sm font-normal mb-1',
|
||||
@@ -275,10 +275,10 @@ export default {
|
||||
description: `text-amber-1100`,
|
||||
},
|
||||
info: {
|
||||
base: `bg-blue-200 dark:bg-blue-100 border-blue-700`,
|
||||
icon: `text-blue-900`,
|
||||
header: `text-blue-1200`,
|
||||
description: `text-blue-1100`,
|
||||
base: `bg-scale-400 border-scale-500 dark:bg-scale-100 dark:border-scale-300`,
|
||||
icon: `text-scale-900`,
|
||||
header: `text-scale-1200`,
|
||||
description: `text-scale-1100`,
|
||||
},
|
||||
success: {
|
||||
base: `bg-brand-300 dark:bg-brand-100 border-brand-700`,
|
||||
@@ -1247,6 +1247,7 @@ export default {
|
||||
border-none
|
||||
focus:outline-none
|
||||
`,
|
||||
disabled: `opacity-50 cursor-default`,
|
||||
label: `
|
||||
text-scale-900
|
||||
px-4 flex items-center space-x-2 py-1.5
|
||||
|
||||
@@ -425,6 +425,13 @@
|
||||
"product": "auth",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"id": "sign-in-with-apple",
|
||||
"title": "Sign in with Apple",
|
||||
"slug": "sign-in-with-apple",
|
||||
"product": "auth",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"id": "sign-in-with-oauth",
|
||||
"title": "Sign in a user through OAuth",
|
||||
|
||||
@@ -165,6 +165,22 @@ functions:
|
||||
phone: '+13334445555',
|
||||
);
|
||||
```
|
||||
- id: sign-in-with-apple
|
||||
title: 'signInWithApple()'
|
||||
description: |
|
||||
Signs in a user using native Apple login.
|
||||
notes: |
|
||||
- You need to [register your bundle ID](https://developer.apple.com/help/account/manage-identifiers/register-an-app-id/) and add it to Supabase dashboard.
|
||||
- This method is only available in iOS and macOS
|
||||
- For other platforms, [signInWithOAuth()](https://supabase.com/docs/reference/dart/auth-signinwithoauth) should be used.
|
||||
examples:
|
||||
- id: sign-in-with-apple
|
||||
name: Sign in with Apple
|
||||
isSpotlight: true
|
||||
code: |
|
||||
```dart
|
||||
final AuthResponse = await supabase.auth.signInWithApple();
|
||||
```
|
||||
- id: sign-in-with-oauth
|
||||
title: 'signInWithOAuth()'
|
||||
description: |
|
||||
|
||||
@@ -142,7 +142,7 @@ const DefaultHeader = ({
|
||||
<div
|
||||
className={[
|
||||
'border border-scale-1100 w-[15px] h-[4px] translate-x-0.5',
|
||||
'transition duration-200 group-hover:border-brand-900 group-hover:translate-x-0',
|
||||
'transition duration-200 group-data-[highlighted]:border-brand-900 group-data-[highlighted]:translate-x-0',
|
||||
].join(' ')}
|
||||
/>
|
||||
</div>
|
||||
@@ -168,7 +168,7 @@ const DefaultHeader = ({
|
||||
<div
|
||||
className={[
|
||||
'border border-scale-1100 w-[4px] h-[15px] -translate-y-0.5',
|
||||
'transition duration-200 group-hover:border-brand-900 group-hover:translate-y-0',
|
||||
'transition duration-200 group-data-[highlighted]:border-brand-900 group-data-[highlighted]:translate-y-0',
|
||||
].join(' ')}
|
||||
/>
|
||||
</div>
|
||||
@@ -193,7 +193,7 @@ const DefaultHeader = ({
|
||||
<IconArrowUp
|
||||
className={clsx(
|
||||
'transition duration-200 absolute bottom-0 right-0 translate-y-1 opacity-0 bg-brand-700 rounded-full',
|
||||
'group-hover:translate-y-0 group-hover:text-brand-900 group-hover:opacity-100'
|
||||
'group-data-[highlighted]:translate-y-0 group-data-[highlighted]:text-brand-900 group-data-[highlighted]:opacity-100'
|
||||
)}
|
||||
strokeWidth={3}
|
||||
size={12}
|
||||
|
||||
@@ -2,7 +2,7 @@ import remarkGfm from 'remark-gfm'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import { PropsWithChildren, useMemo } from 'react'
|
||||
import { useParams } from 'common'
|
||||
import { CommandMenuProvider } from 'ui'
|
||||
import { CommandMenuProvider, markdownComponents } from 'ui'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
@@ -98,7 +98,9 @@ const CommandMenuWrapper = observer(({ children }: PropsWithChildren<{}>) => {
|
||||
site="studio"
|
||||
projectRef={ref}
|
||||
apiKeys={apiKeys}
|
||||
MarkdownHandler={(props) => <ReactMarkdown remarkPlugins={[remarkGfm]} {...props} />}
|
||||
MarkdownHandler={(props) => (
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]} components={markdownComponents} {...props} />
|
||||
)}
|
||||
metadata={cmdkMetadata}
|
||||
isOptedInToAI={allowCMDKDataOptIn && isOptedInToAI}
|
||||
saveGeneratedSQL={onSaveGeneratedSQL}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useEffect } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import Link from 'next/link'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Form, Input, Toggle } from 'ui'
|
||||
import { Collapsible, Form, IconChevronRight, IconHelpCircle, Input, Toggle } from 'ui'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useStore, checkPermissions, useFlag } from 'hooks'
|
||||
@@ -20,6 +22,7 @@ import {
|
||||
const GeneralSettings = () => {
|
||||
const { app, ui } = useStore()
|
||||
const { slug } = useParams()
|
||||
const [open, setOpen] = useState(false)
|
||||
const { name, opt_in_tags } = ui.selectedOrganization ?? {}
|
||||
|
||||
const formId = 'org-general-settings'
|
||||
@@ -100,7 +103,6 @@ const GeneralSettings = () => {
|
||||
label="Organization name"
|
||||
disabled={!canUpdateOrganization}
|
||||
/>
|
||||
|
||||
{showCMDK && allowCMDKDataOptIn && (
|
||||
<div className="mt-4">
|
||||
<Toggle
|
||||
@@ -109,8 +111,69 @@ const GeneralSettings = () => {
|
||||
disabled={!canUpdateOrganization}
|
||||
size="small"
|
||||
label="Opt-in to sending anonymous data to OpenAI"
|
||||
descriptionText="You can choose to share anonymous metadata with OpenAI to enhance your experience on Supabase anywhere we use AI. Only information such as table schemas with table names, column names, and data types will be shared. None of your actual table data will be sent to OpenAI."
|
||||
descriptionText="By opting into sending anonymous data, Supabase AI can improve the answers it shows you"
|
||||
/>
|
||||
<Collapsible open={open} onOpenChange={setOpen}>
|
||||
<Collapsible.Trigger asChild>
|
||||
<div className="flex items-center space-x-2 ml-16 cursor-pointer">
|
||||
<IconChevronRight
|
||||
strokeWidth={2}
|
||||
size={16}
|
||||
className={clsx('transition-all', open ? 'rotate-90' : '')}
|
||||
/>
|
||||
<p className="text-sm text-scale-1000 underline">
|
||||
Important information regarding opting in
|
||||
</p>
|
||||
</div>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Content>
|
||||
<div className="space-y-2 py-4 ml-16 text-sm text-scale-1100">
|
||||
<p>
|
||||
Supabase AI is a chatbot support tool powered by OpenAI. Supabase will
|
||||
share the query you submit and information about the databases you
|
||||
manage through Supabase with OpenAI, L.L.C. and its affiliates in
|
||||
order to provide the Supabase AI tool.
|
||||
</p>
|
||||
<p>
|
||||
OpenAI will only access information about the structure of your
|
||||
databases, such as table names, column and row headings. OpenAI will
|
||||
not access the contents of the database itself.
|
||||
</p>
|
||||
<p>
|
||||
OpenAI uses this information to generate responses to your query, and
|
||||
does not retain or use the information to train its algorithms or
|
||||
otherwise improve its products and services.
|
||||
</p>
|
||||
<p>
|
||||
If you have your own individual account on Supabase, we will use any
|
||||
personal information collected through [Supabase AI] to provide you
|
||||
with the [Supabase AI] tool. If you are in the UK, EEA or Switzerland,
|
||||
the processing of this personal information is necessary for the
|
||||
performance of a contract between you and us.
|
||||
</p>
|
||||
<p>
|
||||
Supabase collects information about the queries you submit through
|
||||
Supabase AI and the responses you receive to assess the performance of
|
||||
the Supabase AI tool and improve our services. If you are in the UK,
|
||||
EEA or Switzerland, the processing is necessary for our legitimate
|
||||
interests, namely informing our product development and improvement.
|
||||
</p>
|
||||
<p>
|
||||
For more information about how we use personal information, please see
|
||||
our{' '}
|
||||
<Link href="https://supabase.com/privacy">
|
||||
<a
|
||||
target="_blank"
|
||||
className="text-brand-900 border-b border-brand-900"
|
||||
>
|
||||
privacy policy
|
||||
</a>
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</Collapsible.Content>
|
||||
</Collapsible>
|
||||
</div>
|
||||
)}
|
||||
</FormSectionContent>
|
||||
|
||||
@@ -469,8 +469,6 @@ export default class MetaStore implements IMetaStore {
|
||||
category: 'error',
|
||||
message: `An error occurred while creating the column "${payload.name}"`,
|
||||
})
|
||||
const query = `alter table "${selectedTable.name}" drop column if exists "${payload.name}";`
|
||||
await this.rootStore.meta.query(query)
|
||||
return { error }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user