mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
working sql editor upsert
This commit is contained in:
1 parent
10f5640837
commit
da6ff0f2b0
7 files changed
+405
-46
No files matched your search
@@ -75,12 +75,14 @@ const CommandMenuWrapper = ({ children }: PropsWithChildren<{}>) => {
|
||||
|
||||
try {
|
||||
const snippet = createSqlSnippetSkeleton({
|
||||
id: uuidv4(),
|
||||
name: title || 'Generated query',
|
||||
owner_id: profile?.id,
|
||||
project_id: selectedProject?.id,
|
||||
sql: formattedSql,
|
||||
})
|
||||
const data = { ...snippet, id: uuidv4() }
|
||||
snap.addSnippet(data as SqlSnippet, ref)
|
||||
|
||||
snap.addSnippet(snippet as SqlSnippet, ref)
|
||||
ui.setNotification({
|
||||
category: 'success',
|
||||
message: `Successfully saved snippet!`,
|
||||
|
||||
@@ -15,21 +15,27 @@ export const getResultsMarkdown = (results: any[]) => {
|
||||
}
|
||||
|
||||
export const createSqlSnippetSkeleton = ({
|
||||
id,
|
||||
name,
|
||||
sql,
|
||||
owner_id,
|
||||
project_id,
|
||||
}: {
|
||||
id?: string
|
||||
name?: string
|
||||
sql?: string
|
||||
owner_id?: number
|
||||
project_id?: number
|
||||
} = {}): UserContent<SqlSnippets.Content> => {
|
||||
return {
|
||||
...NEW_SQL_SNIPPET_SKELETON,
|
||||
id,
|
||||
...(name && { name }),
|
||||
...(owner_id && { owner_id }),
|
||||
...(project_id && { project_id }),
|
||||
content: {
|
||||
...NEW_SQL_SNIPPET_SKELETON.content,
|
||||
content_id: '',
|
||||
content_id: id ?? '',
|
||||
sql: sql ?? '',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { useParams, useTelemetryProps } from 'common'
|
||||
import { SQL_TEMPLATES } from 'components/interfaces/SQLEditor/SQLEditor.constants'
|
||||
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
|
||||
import { SqlSnippet } from 'data/content/sql-snippets-query'
|
||||
import { useCheckPermissions, useStore } from 'hooks'
|
||||
import { uuidv4 } from 'lib/helpers'
|
||||
@@ -19,6 +20,7 @@ const SQLTemplates = observer(() => {
|
||||
const { ref } = useParams()
|
||||
const router = useRouter()
|
||||
const { profile } = useProfile()
|
||||
const { project } = useProjectContext()
|
||||
const [sql, quickStart] = partition(SQL_TEMPLATES, { type: 'template' })
|
||||
|
||||
const telemetryProps = useTelemetryProps()
|
||||
@@ -28,10 +30,9 @@ const SQLTemplates = observer(() => {
|
||||
subject: { id: profile?.id },
|
||||
})
|
||||
|
||||
// [Joshen TODO] Removed optimistic query creation logic for now, need to figure out
|
||||
// how to do that after using ids as part of the URL
|
||||
const handleNewQuery = async (sql: string, name: string) => {
|
||||
if (!ref) return console.error('Project ref is required')
|
||||
if (!project) return console.error('Project is required')
|
||||
if (!profile) return console.error('Profile is required')
|
||||
if (!canCreateSQLSnippet) {
|
||||
return ui.setNotification({
|
||||
category: 'info',
|
||||
@@ -40,10 +41,16 @@ const SQLTemplates = observer(() => {
|
||||
}
|
||||
|
||||
try {
|
||||
const snippet = createSqlSnippetSkeleton({ name, sql, owner_id: profile?.id })
|
||||
const data = { ...snippet, id: uuidv4() }
|
||||
snap.addSnippet(data as SqlSnippet, ref)
|
||||
router.push(`/project/${ref}/sql/${data.id}`)
|
||||
const snippet = createSqlSnippetSkeleton({
|
||||
id: uuidv4(),
|
||||
name,
|
||||
sql,
|
||||
owner_id: profile.id,
|
||||
project_id: project.id,
|
||||
})
|
||||
|
||||
snap.addSnippet(snippet as SqlSnippet, project.ref)
|
||||
router.push(`/project/${project.ref}/sql/${snippet.id}`)
|
||||
} catch (error: any) {
|
||||
ui.setNotification({
|
||||
category: 'error',
|
||||
|
||||
@@ -16,6 +16,7 @@ import { useProfile } from 'lib/profile'
|
||||
import { useSnippets, useSqlEditorStateSnapshot } from 'state/sql-editor'
|
||||
import { Button, Dropdown, IconPlus, IconSearch, IconX, Input, Menu, useCommandMenu } from 'ui'
|
||||
import { COMMAND_ROUTES } from 'ui/src/components/Command/Command.constants'
|
||||
import { useProjectContext } from '../ProjectLayout/ProjectContext'
|
||||
import QueryItem from './QueryItem'
|
||||
|
||||
const SideBarContent = observer(() => {
|
||||
@@ -26,6 +27,7 @@ const SideBarContent = observer(() => {
|
||||
const [filterString, setFilterString] = useState('')
|
||||
const { setPages, setIsOpen } = useCommandMenu()
|
||||
const showCmdkHelper = useFlag('dashboardCmdk')
|
||||
const { project } = useProjectContext()
|
||||
|
||||
const snap = useSqlEditorStateSnapshot()
|
||||
const { isLoading, isSuccess } = useSqlSnippetsQuery(ref, {
|
||||
@@ -56,7 +58,8 @@ const SideBarContent = observer(() => {
|
||||
})
|
||||
|
||||
const handleNewQuery = async () => {
|
||||
if (!ref) return console.error('Project ref is required')
|
||||
if (!project) return console.error('Project is required')
|
||||
if (!profile) return console.error('Profile is required')
|
||||
if (!canCreateSQLSnippet) {
|
||||
return ui.setNotification({
|
||||
category: 'info',
|
||||
@@ -65,12 +68,16 @@ const SideBarContent = observer(() => {
|
||||
}
|
||||
|
||||
try {
|
||||
const snippet = createSqlSnippetSkeleton({ name: 'Untitled query', owner_id: profile?.id })
|
||||
const data = { ...snippet, id: uuidv4() }
|
||||
const snippet = createSqlSnippetSkeleton({
|
||||
id: uuidv4(),
|
||||
name: 'Untitled query',
|
||||
owner_id: profile.id,
|
||||
project_id: project.id,
|
||||
})
|
||||
|
||||
snap.addSnippet(data as SqlSnippet, ref)
|
||||
snap.addSnippet(snippet as SqlSnippet, project.ref)
|
||||
|
||||
router.push(`/project/${ref}/sql/${data.id}`)
|
||||
router.push(`/project/${project.ref}/sql/${snippet.id}`)
|
||||
} catch (error: any) {
|
||||
ui.setNotification({
|
||||
category: 'error',
|
||||
|
||||
Vendored
+327
-10
@@ -396,6 +396,8 @@ export interface paths {
|
||||
"/platform/projects/{ref}/content": {
|
||||
/** Gets project's content */
|
||||
get: operations["ContentController_getContent"];
|
||||
/** Updates project's content */
|
||||
put: operations["ContentController_updateWholeContent"];
|
||||
/** Creates project's content */
|
||||
post: operations["ContentController_createContent"];
|
||||
/** Deletes project's content */
|
||||
@@ -688,9 +690,13 @@ export interface paths {
|
||||
*/
|
||||
post: operations["VercelIntegrationController_createVercelIntegration"];
|
||||
};
|
||||
"/platform/integrations/vercel/{organization_integration_id}": {
|
||||
/** Removes Vercel organization integration with the given id */
|
||||
delete: operations["VercelIntegrationController_removeVercelIntegration"];
|
||||
};
|
||||
"/platform/integrations/vercel/projects/{organization_integration_id}": {
|
||||
/** Gets vercel projects for the given organization */
|
||||
get: operations["VercelProjectController_getProjects"];
|
||||
/** Gets vercel projects with the given organization integration id */
|
||||
get: operations["VercelProjectController_getVercelProjects"];
|
||||
};
|
||||
"/platform/integrations/vercel/connections/{organization_integration_id}": {
|
||||
/** Gets installed vercel project connections for the given organization integration */
|
||||
@@ -700,6 +706,10 @@ export interface paths {
|
||||
/** Connects a Vercel project to a supabase project */
|
||||
post: operations["VercelConnectionsController_createVercelConnection"];
|
||||
};
|
||||
"/platform/integrations/vercel/connections/{connection_id}/sync-envs": {
|
||||
/** Syncs supabase project envs with given connection id */
|
||||
post: operations["VercelConnectionsController_syncVercelConnectionEnvs"];
|
||||
};
|
||||
"/platform/integrations/vercel/connections/{connection_id}": {
|
||||
/** Deletes vercel project connection */
|
||||
delete: operations["VercelConnectionsController_deleteVercelConnection"];
|
||||
@@ -1044,6 +1054,8 @@ export interface paths {
|
||||
"/v0/projects/{ref}/content": {
|
||||
/** Gets project's content */
|
||||
get: operations["ContentController_getContent"];
|
||||
/** Updates project's content */
|
||||
put: operations["ContentController_updateWholeContent"];
|
||||
/** Creates project's content */
|
||||
post: operations["ContentController_createContent"];
|
||||
/** Deletes project's content */
|
||||
@@ -1235,6 +1247,23 @@ export interface paths {
|
||||
/** Deletes objects */
|
||||
delete: operations["StorageObjectsController_deleteObjects"];
|
||||
};
|
||||
"/v1/branch/{branch_id}": {
|
||||
/**
|
||||
* Get database branch config
|
||||
* @description Fetches configurations of the specified database branch
|
||||
*/
|
||||
get: operations["BranchController_getBranchDetails"];
|
||||
/**
|
||||
* Delete a database branch
|
||||
* @description Deletes the specified database branch
|
||||
*/
|
||||
delete: operations["BranchController_deleteBranch"];
|
||||
/**
|
||||
* Update database branch config
|
||||
* @description Updates the configuration of the specified database branch
|
||||
*/
|
||||
patch: operations["BranchController_updateBranch"];
|
||||
};
|
||||
"/v1/projects": {
|
||||
/**
|
||||
* List all projects
|
||||
@@ -1247,6 +1276,23 @@ export interface paths {
|
||||
"/v1/projects/{ref}/api-keys": {
|
||||
get: operations["ApiKeysController_getProjectApiKeys"];
|
||||
};
|
||||
"/v1/projects/{ref}/branches": {
|
||||
/**
|
||||
* List all database branches
|
||||
* @description Returns all database branches of the specified project.
|
||||
*/
|
||||
get: operations["BranchesController_getBranches"];
|
||||
/**
|
||||
* Create a database branch
|
||||
* @description Creates a database branch from the specified project.
|
||||
*/
|
||||
post: operations["BranchesController_createBranch"];
|
||||
/**
|
||||
* Disables preview branching
|
||||
* @description Disables preview branching for the specified project
|
||||
*/
|
||||
delete: operations["BranchesController_disableBranch"];
|
||||
};
|
||||
"/v1/projects/{ref}/custom-hostname": {
|
||||
/** Gets project's custom hostname config */
|
||||
get: operations["CustomHostnamesController_getCustomHostnameConfig"];
|
||||
@@ -2992,6 +3038,29 @@ export interface components {
|
||||
anon_key: string;
|
||||
service_key: string;
|
||||
};
|
||||
GetUserContentObject: {
|
||||
owner: {
|
||||
id?: number;
|
||||
username?: string;
|
||||
};
|
||||
updated_by: {
|
||||
id?: number;
|
||||
username?: string;
|
||||
};
|
||||
id: string;
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
type: Record<string, never>;
|
||||
visibility: Record<string, never>;
|
||||
name: string;
|
||||
description?: string;
|
||||
project_id: number;
|
||||
owner_id: number;
|
||||
last_updated_by: number;
|
||||
};
|
||||
GetUserContentResponse: {
|
||||
data: (components["schemas"]["GetUserContentObject"])[];
|
||||
};
|
||||
CreateContentParams: {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -3003,6 +3072,30 @@ export interface components {
|
||||
content?: Record<string, never>;
|
||||
owner_id?: number;
|
||||
};
|
||||
UserContentObject: {
|
||||
id: string;
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
type: Record<string, never>;
|
||||
visibility: Record<string, never>;
|
||||
name: string;
|
||||
description?: string;
|
||||
project_id: number;
|
||||
owner_id: number;
|
||||
last_updated_by: number;
|
||||
};
|
||||
UpsertContentParams: {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
/** @enum {string} */
|
||||
type: "sql" | "report" | "log_sql";
|
||||
/** @enum {string} */
|
||||
visibility: "user" | "project" | "org" | "public";
|
||||
content?: Record<string, never>;
|
||||
owner_id?: number;
|
||||
project_id: number;
|
||||
};
|
||||
UpdateContentParams: {
|
||||
id?: string;
|
||||
name?: string;
|
||||
@@ -3026,6 +3119,15 @@ export interface components {
|
||||
postgrest: string;
|
||||
"supabase-postgres": string;
|
||||
};
|
||||
BranchResponse: {
|
||||
id: string;
|
||||
name: string;
|
||||
project_ref: string;
|
||||
is_default: boolean;
|
||||
git_branch: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
ProjectDetailResponse: {
|
||||
cloud_provider: string;
|
||||
db_host: string;
|
||||
@@ -3046,6 +3148,7 @@ export interface components {
|
||||
volumeSizeGb?: number;
|
||||
maxDatabasePreprovisionGb?: number;
|
||||
lastDatabaseResizeAt?: string;
|
||||
preview_branches: (components["schemas"]["BranchResponse"])[];
|
||||
};
|
||||
ProjectRefResponse: {
|
||||
id: number;
|
||||
@@ -3704,6 +3807,14 @@ export interface components {
|
||||
framework?: string | null;
|
||||
link?: components["schemas"]["VercelProjectLink"];
|
||||
};
|
||||
GetVercelProjectsResponse: {
|
||||
projects: (components["schemas"]["IntegrationVercelProject"])[];
|
||||
pagination: {
|
||||
count?: number;
|
||||
next?: number | null;
|
||||
prev?: number | null;
|
||||
};
|
||||
};
|
||||
GetVercelConnections: {
|
||||
id: string;
|
||||
inserted_at: string;
|
||||
@@ -3798,6 +3909,21 @@ export interface components {
|
||||
GetMetricsResponse: {
|
||||
metrics: (components["schemas"]["ProjectMetric"])[];
|
||||
};
|
||||
BranchDetailResponse: {
|
||||
db_port: number;
|
||||
ref: string;
|
||||
postgres_version: string;
|
||||
/** @enum {string} */
|
||||
status: "ACTIVE_HEALTHY" | "ACTIVE_UNHEALTHY" | "COMING_UP" | "GOING_DOWN" | "INACTIVE" | "INIT_FAILED" | "REMOVED" | "RESTORING" | "UNKNOWN" | "UPGRADING" | "PAUSING";
|
||||
db_host: string;
|
||||
db_user?: string;
|
||||
db_pass?: string;
|
||||
jwt_secret?: string;
|
||||
};
|
||||
UpdateBranchBody: {
|
||||
branch_name?: string;
|
||||
git_branch?: string;
|
||||
};
|
||||
DatabaseResponse: {
|
||||
/** @description Database host */
|
||||
host: string;
|
||||
@@ -3808,6 +3934,11 @@ export interface components {
|
||||
name: string;
|
||||
api_key: string;
|
||||
};
|
||||
CreateBranchBody: {
|
||||
branch_name: string;
|
||||
git_branch?: string;
|
||||
region?: string;
|
||||
};
|
||||
UpdateCustomHostnameResponse: {
|
||||
/** @enum {string} */
|
||||
status: "1_not_started" | "2_initiated" | "3_challenge_verified" | "4_origin_setup_completed" | "5_services_reconfigured";
|
||||
@@ -6639,11 +6770,38 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: never;
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["GetUserContentResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to retrieve project's content */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Updates project's content */
|
||||
ContentController_updateWholeContent: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Project ref */
|
||||
ref: string;
|
||||
};
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["UpsertContentParams"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["UserContentObject"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to update project's content */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Creates project's content */
|
||||
ContentController_createContent: {
|
||||
parameters: {
|
||||
@@ -6660,7 +6818,7 @@ export interface operations {
|
||||
responses: {
|
||||
201: {
|
||||
content: {
|
||||
"application/json": (Record<string, never>)[];
|
||||
"application/json": (components["schemas"]["UserContentObject"])[];
|
||||
};
|
||||
};
|
||||
/** @description Failed to create project's content */
|
||||
@@ -6677,7 +6835,7 @@ export interface operations {
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": Record<string, never>;
|
||||
"application/json": components["schemas"]["UserContentObject"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to delete project's content */
|
||||
@@ -6699,7 +6857,7 @@ export interface operations {
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": (Record<string, never>)[];
|
||||
"application/json": (components["schemas"]["UserContentObject"])[];
|
||||
};
|
||||
};
|
||||
/** @description Failed to update project's content */
|
||||
@@ -8072,20 +8230,38 @@ export interface operations {
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Gets vercel projects for the given organization */
|
||||
VercelProjectController_getProjects: {
|
||||
/** Removes Vercel organization integration with the given id */
|
||||
VercelIntegrationController_removeVercelIntegration: {
|
||||
parameters: {
|
||||
path: {
|
||||
organization_integration_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: never;
|
||||
/** @description Failed to remove Vercel organization integration with the given id */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Gets vercel projects with the given organization integration id */
|
||||
VercelProjectController_getVercelProjects: {
|
||||
parameters: {
|
||||
query: {
|
||||
search?: string;
|
||||
from?: string;
|
||||
limit: string;
|
||||
};
|
||||
path: {
|
||||
organization_integration_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": (components["schemas"]["IntegrationVercelProject"])[];
|
||||
"application/json": components["schemas"]["GetVercelProjectsResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to get vercel projects for the given organization */
|
||||
/** @description Failed to get vercel projects with the given organization integration id */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
@@ -8119,6 +8295,19 @@ export interface operations {
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Syncs supabase project envs with given connection id */
|
||||
VercelConnectionsController_syncVercelConnectionEnvs: {
|
||||
parameters: {
|
||||
path: {
|
||||
connection_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
201: never;
|
||||
/** @description Failed to sync supabase project envs with given connection id */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Deletes vercel project connection */
|
||||
VercelConnectionsController_deleteVercelConnection: {
|
||||
parameters: {
|
||||
@@ -8517,6 +8706,70 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get database branch config
|
||||
* @description Fetches configurations of the specified database branch
|
||||
*/
|
||||
BranchController_getBranchDetails: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Branch ID */
|
||||
branch_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["BranchDetailResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to update database branch */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Delete a database branch
|
||||
* @description Deletes the specified database branch
|
||||
*/
|
||||
BranchController_deleteBranch: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Branch ID */
|
||||
branch_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: never;
|
||||
/** @description Failed to delete database branch */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Update database branch config
|
||||
* @description Updates the configuration of the specified database branch
|
||||
*/
|
||||
BranchController_updateBranch: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Branch ID */
|
||||
branch_id: string;
|
||||
};
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["UpdateBranchBody"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["BranchResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to update database branch */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
ApiKeysController_getProjectApiKeys: {
|
||||
parameters: {
|
||||
path: {
|
||||
@@ -8533,6 +8786,70 @@ export interface operations {
|
||||
403: never;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* List all database branches
|
||||
* @description Returns all database branches of the specified project.
|
||||
*/
|
||||
BranchesController_getBranches: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Project ref */
|
||||
ref: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": (components["schemas"]["BranchResponse"])[];
|
||||
};
|
||||
};
|
||||
/** @description Failed to retrieve database branches */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Create a database branch
|
||||
* @description Creates a database branch from the specified project.
|
||||
*/
|
||||
BranchesController_createBranch: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Project ref */
|
||||
ref: string;
|
||||
};
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["CreateBranchBody"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
201: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["BranchResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Failed to create database branch */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Disables preview branching
|
||||
* @description Disables preview branching for the specified project
|
||||
*/
|
||||
BranchesController_disableBranch: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Project ref */
|
||||
ref: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
200: never;
|
||||
/** @description Failed to disable preview branching */
|
||||
500: never;
|
||||
};
|
||||
};
|
||||
/** Gets project's custom hostname config */
|
||||
CustomHostnamesController_getCustomHostnameConfig: {
|
||||
parameters: {
|
||||
|
||||
@@ -1,28 +1,43 @@
|
||||
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
|
||||
import { put } from 'lib/common/fetch'
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { UserContent } from 'types'
|
||||
import { contentKeys } from './keys'
|
||||
|
||||
type UpsertContentVariables = {
|
||||
import { components } from 'data/api'
|
||||
import { put } from 'data/fetchers'
|
||||
import { contentKeys } from './keys'
|
||||
import { Content } from './content-query'
|
||||
|
||||
export type UpsertContentPayload = Omit<components['schemas']['UpsertContentParams'], 'content'> & {
|
||||
content: Content['content']
|
||||
}
|
||||
|
||||
export type UpsertContentVariables = {
|
||||
projectRef: string
|
||||
id: string
|
||||
payload: Partial<UserContent>
|
||||
payload: UpsertContentPayload
|
||||
}
|
||||
|
||||
export async function upsertContent(
|
||||
{ projectRef, payload }: UpsertContentVariables,
|
||||
signal?: AbortSignal
|
||||
) {
|
||||
const response = await put<UserContent[]>(`${API_URL}/projects/${projectRef}/content`, payload, {
|
||||
const { data, error } = await put('/platform/projects/{ref}/content', {
|
||||
params: { path: { ref: projectRef } },
|
||||
body: {
|
||||
id: payload.id,
|
||||
name: payload.name,
|
||||
description: payload.description,
|
||||
project_id: payload.project_id,
|
||||
owner_id: payload.owner_id,
|
||||
type: payload.type,
|
||||
visibility: payload.visibility,
|
||||
content: payload.content as any,
|
||||
},
|
||||
signal,
|
||||
})
|
||||
if (error) throw error
|
||||
|
||||
if (response.error) throw response.error
|
||||
return { content: response }
|
||||
return data
|
||||
}
|
||||
|
||||
type UpsertContentData = Awaited<ReturnType<typeof upsertContent>>
|
||||
export type UpsertContentData = Awaited<ReturnType<typeof upsertContent>>
|
||||
|
||||
export const useContentUpsertMutation = ({
|
||||
onSuccess,
|
||||
|
||||
+15
-10
@@ -1,8 +1,8 @@
|
||||
import { Content } from 'data/content/content-query'
|
||||
import { upsertContent } from 'data/content/content-upsert-mutation'
|
||||
import { UpsertContentPayload, upsertContent } from 'data/content/content-upsert-mutation'
|
||||
import { SqlSnippet } from 'data/content/sql-snippets-query'
|
||||
import { debounce, memoize } from 'lodash'
|
||||
import { useMemo } from 'react'
|
||||
import { SqlSnippets } from 'types'
|
||||
import { proxy, snapshot, subscribe, useSnapshot } from 'valtio'
|
||||
import { devtools, proxySet } from 'valtio/utils'
|
||||
|
||||
@@ -170,10 +170,13 @@ export const useSnippets = (projectRef: string | undefined) => {
|
||||
}, [projectRef, snapshot.orders, snapshot.snippets])
|
||||
}
|
||||
|
||||
async function upsert(id: string, projectRef: string, content: Partial<Content>) {
|
||||
async function upsert(id: string, projectRef: string, payload: UpsertContentPayload) {
|
||||
try {
|
||||
sqlEditorState.savingStates[id] = 'UPDATING'
|
||||
await upsertContent({ projectRef, id, payload: content })
|
||||
await upsertContent({
|
||||
projectRef,
|
||||
payload,
|
||||
})
|
||||
sqlEditorState.savingStates[id] = 'IDLE'
|
||||
} catch (error) {
|
||||
sqlEditorState.savingStates[id] = 'UPDATING_FAILED'
|
||||
@@ -181,8 +184,8 @@ async function upsert(id: string, projectRef: string, content: Partial<Content>)
|
||||
}
|
||||
|
||||
const memoizedUpdate = memoize((_id: string) => debounce(upsert, 1000))
|
||||
const debouncedUpdate = (id: string, projectRef: string, content: Partial<Content>) =>
|
||||
memoizedUpdate(id)(id, projectRef, content)
|
||||
const debouncedUpdate = (id: string, projectRef: string, payload: UpsertContentPayload) =>
|
||||
memoizedUpdate(id)(id, projectRef, payload)
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
devtools(sqlEditorState, { name: 'sqlEditorState', enabled: true })
|
||||
@@ -195,12 +198,14 @@ if (typeof window !== 'undefined') {
|
||||
|
||||
if (snippet) {
|
||||
debouncedUpdate(id, snippet.projectRef, {
|
||||
content: { ...snippet.snippet.content, content_id: id },
|
||||
...snippet.snippet,
|
||||
name: snippet.snippet.name ?? 'Untitled',
|
||||
description: snippet.snippet.description ?? '',
|
||||
visibility: 'user',
|
||||
project_id: snippet.snippet.project_id ?? 0,
|
||||
content: { ...snippet.snippet.content, content_id: id } as SqlSnippets.Content,
|
||||
type: 'sql',
|
||||
id,
|
||||
name: snippet.snippet.name,
|
||||
description: snippet.snippet.description,
|
||||
visibility: snippet.snippet.visibility ?? 'project',
|
||||
})
|
||||
|
||||
sqlEditorState.needsSaving.delete(id)
|
||||
|
||||
Reference in new issue
Block a user