improve DbManagerButton + asset dropdown button
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
import Drawer from './common/drawer/Drawer.svelte'
|
||||
import DrawerContent from './common/drawer/DrawerContent.svelte'
|
||||
import { sendUserToast, sortArray } from '$lib/utils'
|
||||
import { ArrowLeft, Database, Expand, Loader2, Minimize, RefreshCcw } from 'lucide-svelte'
|
||||
import { ArrowLeft, Expand, Loader2, Minimize, RefreshCcw } from 'lucide-svelte'
|
||||
import {
|
||||
dbSupportsSchemas,
|
||||
getDbSchemas,
|
||||
@@ -15,7 +15,6 @@
|
||||
type TableMetadata
|
||||
} from './apps/components/display/dbtable/utils'
|
||||
import DbManager from './DBManager.svelte'
|
||||
import { Alert } from './common'
|
||||
import { dbDeleteTableActionWithPreviewScript, dbTableOpsWithPreviewScripts } from './dbOps'
|
||||
import { makeCreateTableQuery } from './apps/components/display/dbtable/queries/createTable'
|
||||
import { runScriptAndPollResult } from './jobs/utils'
|
||||
@@ -24,22 +23,24 @@
|
||||
import SimpleAgTable from './SimpleAgTable.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
|
||||
type Props = {
|
||||
resourceType: DbType
|
||||
resourcePath: string
|
||||
class?: string
|
||||
let resourceType: DbType | undefined = $state(undefined)
|
||||
let resourcePath: string | undefined = $state(undefined)
|
||||
let open = $derived(resourcePath && resourceType)
|
||||
|
||||
export function openDrawer(_resourceType: DbType, _resourcePath: string) {
|
||||
resourceType = _resourceType
|
||||
resourcePath = _resourcePath
|
||||
getSchema()
|
||||
}
|
||||
export function closeDrawer() {
|
||||
resourceType = undefined
|
||||
resourcePath = undefined
|
||||
refreshCount = 0
|
||||
refreshing = false
|
||||
}
|
||||
|
||||
let { resourceType, resourcePath }: Props = $props()
|
||||
|
||||
let dbSchema: DBSchema | undefined = $derived(
|
||||
resourcePath in $dbSchemas ? $dbSchemas[resourcePath] : undefined
|
||||
)
|
||||
|
||||
let isDrawerOpen: boolean = $state(false)
|
||||
|
||||
let shouldDisplayError = $derived(
|
||||
resourcePath && resourcePath in $dbSchemas && !$dbSchemas[resourcePath]
|
||||
resourcePath && resourcePath in $dbSchemas ? $dbSchemas[resourcePath] : undefined
|
||||
)
|
||||
|
||||
// `refreshCount` is a derived state. `refreshing` is the source of truth
|
||||
@@ -56,11 +57,11 @@
|
||||
|
||||
let expand = $state(false)
|
||||
$effect(() => {
|
||||
if (!isDrawerOpen) expand = false
|
||||
if (!open) expand = false
|
||||
})
|
||||
|
||||
async function getSchema() {
|
||||
if ($dbSchemas[resourcePath] && !refreshing) return
|
||||
if (!resourcePath || !resourceType || ($dbSchemas[resourcePath] && !refreshing)) return
|
||||
try {
|
||||
const oldDbSchema = $dbSchemas[resourcePath]
|
||||
await getDbSchemas(
|
||||
@@ -69,9 +70,7 @@
|
||||
$workspaceStore,
|
||||
$dbSchemas,
|
||||
(message: string) => {
|
||||
if (isDrawerOpen) {
|
||||
sendUserToast(message, true)
|
||||
}
|
||||
if (open) sendUserToast(message, true)
|
||||
}
|
||||
)
|
||||
// avoid infinite loop on error due to the way getDbSchemas is implemented
|
||||
@@ -95,6 +94,8 @@
|
||||
let cachedLastRefreshCount = 0
|
||||
|
||||
async function getColDefs(tableKey: string) {
|
||||
if (!resourcePath || !resourceType) return []
|
||||
|
||||
if (cachedLastRefreshCount !== refreshCount) cachedColDefs = {}
|
||||
cachedLastRefreshCount = refreshCount
|
||||
if (cachedColDefs[tableKey]) {
|
||||
@@ -130,37 +131,26 @@
|
||||
}}
|
||||
/>
|
||||
|
||||
{#if shouldDisplayError}
|
||||
<Alert type="error" size="xs" title="Schema not available" class="mt-2">
|
||||
Schema could not be loaded. Please check the permissions of the resource.
|
||||
</Alert>
|
||||
{:else}
|
||||
<Button
|
||||
size="xs"
|
||||
variant="border"
|
||||
spacingSize="xs2"
|
||||
btnClasses="mt-1 w-24"
|
||||
on:click={async () => {
|
||||
if (!dbSchema || !$workspaceStore) refreshing = true
|
||||
isDrawerOpen = true
|
||||
}}
|
||||
>
|
||||
<Database size={18} /> Manager
|
||||
</Button>
|
||||
<Drawer bind:open={isDrawerOpen} size={expand ? `${windowWidth}px` : '1200px'} preventEscape>
|
||||
<Drawer
|
||||
bind:open
|
||||
size={expand ? `${windowWidth}px` : '1200px'}
|
||||
preventEscape
|
||||
on:close={closeDrawer}
|
||||
>
|
||||
{#key [resourceType, resourcePath, dbSchema]}
|
||||
<DrawerContent
|
||||
title={replResultData ? 'Query Result' : 'Database Manager'}
|
||||
on:close={() => {
|
||||
if (replResultData) {
|
||||
replResultData = undefined
|
||||
} else {
|
||||
isDrawerOpen = false
|
||||
closeDrawer()
|
||||
}
|
||||
}}
|
||||
CloseIcon={replResultData ? ArrowLeft : undefined}
|
||||
noPadding
|
||||
>
|
||||
{#if dbSchema && $workspaceStore}
|
||||
{#if dbSchema && $workspaceStore && resourceType && resourcePath}
|
||||
<Splitpanes horizontal>
|
||||
<Pane class="relative">
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
@@ -191,8 +181,8 @@
|
||||
dbTableOpsWithPreviewScripts({
|
||||
colDefs,
|
||||
tableKey,
|
||||
resourcePath,
|
||||
resourceType,
|
||||
resourcePath: resourcePath!,
|
||||
resourceType: resourceType!,
|
||||
workspace: $workspaceStore
|
||||
})}
|
||||
dbTableActionsFactory={[
|
||||
@@ -204,16 +194,16 @@
|
||||
]}
|
||||
{refresh}
|
||||
dbTableEditorPropsFactory={({ selectedSchemaKey }) => ({
|
||||
resourceType,
|
||||
resourceType: resourceType!,
|
||||
previewSql: (values) =>
|
||||
makeCreateTableQuery(values, resourceType, selectedSchemaKey),
|
||||
makeCreateTableQuery(values, resourceType!, selectedSchemaKey),
|
||||
async onConfirm(values) {
|
||||
await runScriptAndPollResult({
|
||||
workspace: $workspaceStore,
|
||||
requestBody: {
|
||||
args: { database: '$res:' + resourcePath },
|
||||
content: makeCreateTableQuery(values, resourceType, selectedSchemaKey),
|
||||
language: getLanguageByResourceType(resourceType)
|
||||
content: makeCreateTableQuery(values, resourceType!, selectedSchemaKey),
|
||||
language: getLanguageByResourceType(resourceType!)
|
||||
}
|
||||
})
|
||||
refresh()
|
||||
@@ -268,5 +258,5 @@
|
||||
/>
|
||||
{/snippet}
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
{/if}
|
||||
{/key}
|
||||
</Drawer>
|
||||
@@ -6,12 +6,13 @@
|
||||
import ResourceEditorDrawer from './ResourceEditorDrawer.svelte'
|
||||
|
||||
import { Button } from './common'
|
||||
import DBManagerDrawerButton from './DBManagerDrawerButton.svelte'
|
||||
import { Pen, Plus, RotateCw } from 'lucide-svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { isDbType } from './apps/components/display/dbtable/utils'
|
||||
import Select from './select/Select.svelte'
|
||||
import { createDispatcherIfMounted } from '$lib/createDispatcherIfMounted'
|
||||
import DbManagerDrawer from './DBManagerDrawer.svelte'
|
||||
import ExploreAssetButton from '../../routes/(root)/(logged)/assets/ExploreAssetButton.svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const dispatchIfMounted = createDispatcherIfMounted(dispatch)
|
||||
@@ -146,6 +147,7 @@
|
||||
|
||||
let appConnect: AppConnect | undefined = $state()
|
||||
let resourceEditor: ResourceEditorDrawer | undefined = $state()
|
||||
let dbManagerDrawer: DbManagerDrawer | undefined = $state()
|
||||
</script>
|
||||
|
||||
<AppConnect
|
||||
@@ -253,6 +255,12 @@
|
||||
/>
|
||||
</div>
|
||||
{#if showSchemaExplorer && isDbType(resourceType) && value}
|
||||
<DBManagerDrawerButton {resourceType} resourcePath={value} />
|
||||
<ExploreAssetButton
|
||||
_resourceMetadata={{ resourceType }}
|
||||
asset={{ kind: 'resource', path: value }}
|
||||
{dbManagerDrawer}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<DbManagerDrawer bind:this={dbManagerDrawer} />
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
import type { ScriptOptions } from './copilot/chat/ContextManager.svelte'
|
||||
import { aiChatManager, AIMode } from './copilot/chat/AIChatManager.svelte'
|
||||
import { triggerableByAI } from '$lib/actions/triggerableByAI'
|
||||
import AssetsDetectedBadge from './assets/AssetsDetectedBadge.svelte'
|
||||
import AssetsDetectedBadge from './assets/AssetsDropdownButton.svelte'
|
||||
|
||||
interface Props {
|
||||
// Exported
|
||||
@@ -510,7 +510,9 @@
|
||||
<Pane bind:size={codePanelSize} minSize={10} class="!overflow-visible">
|
||||
<div class="h-full !overflow-visible bg-gray-50 dark:bg-[#272D38] relative">
|
||||
<div class="absolute top-2 right-4 z-10 flex flex-row gap-2">
|
||||
<AssetsDetectedBadge {assets} />
|
||||
{#if assets.length}
|
||||
<AssetsDetectedBadge {assets} />
|
||||
{/if}
|
||||
{#if testPanelSize === 0}
|
||||
<HideButton
|
||||
hidden={true}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { clone, pluralize } from '$lib/utils'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { Pyramid } from 'lucide-svelte'
|
||||
|
||||
const { assets }: { assets: string[] } = $props()
|
||||
|
||||
let prevAssets = $state<string[]>(assets ? clone(assets) : [])
|
||||
let blueBgDiv: HTMLDivElement | undefined = $state()
|
||||
|
||||
$effect(() => {
|
||||
if (!assets) return
|
||||
|
||||
if (!deepEqual(assets, prevAssets)) {
|
||||
prevAssets = clone(assets)
|
||||
// Replay animation
|
||||
if (blueBgDiv) {
|
||||
blueBgDiv.style.animation = 'none'
|
||||
blueBgDiv.offsetHeight /* trigger reflow */
|
||||
blueBgDiv.style.animation = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if assets.length > 0}
|
||||
<div
|
||||
class="text-xs z-50 flex text-tertiary items-center gap-2 px-2 py-1 bg-surface rounded-md border relative"
|
||||
>
|
||||
<div
|
||||
bind:this={blueBgDiv}
|
||||
class="absolute bg-blue-400/30 inset-0 rounded-md -z-50 opacity-0 animate-fade-out"
|
||||
></div>
|
||||
<Pyramid size={16} />
|
||||
{pluralize(assets.length, 'asset')}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,91 @@
|
||||
<script lang="ts">
|
||||
import { clone, pluralize, truncate } from '$lib/utils'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { Pyramid } from 'lucide-svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { Popover } from '../meltComponents'
|
||||
import S3FilePicker from '../S3FilePicker.svelte'
|
||||
import ExploreAssetButton, {
|
||||
assetCanBeExplored
|
||||
} from '../../../routes/(root)/(logged)/assets/ExploreAssetButton.svelte'
|
||||
import { formatAsset, parseAsset } from './lib'
|
||||
import DbManagerDrawer from '../DBManagerDrawer.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { ResourceService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
|
||||
let { assets: assetsUris }: { assets: string[] } = $props()
|
||||
const assets = $derived(assetsUris.map(parseAsset).filter((x) => !!x) ?? [])
|
||||
|
||||
let prevAssetsUris = $state<string[]>([])
|
||||
let blueBgDiv: HTMLDivElement | undefined = $state()
|
||||
|
||||
let s3FilePicker: S3FilePicker | undefined = $state()
|
||||
let dbManagerDrawer: DbManagerDrawer | undefined = $state()
|
||||
let isOpen = $state(false)
|
||||
|
||||
let resourceTypesCache: Record<string, string | undefined> = $state({})
|
||||
|
||||
$effect(() => {
|
||||
if (!assetsUris) return
|
||||
untrack(() => {
|
||||
if (deepEqual(assetsUris, prevAssetsUris)) return
|
||||
prevAssetsUris = clone(assetsUris)
|
||||
// Replay animation
|
||||
if (blueBgDiv) {
|
||||
blueBgDiv.style.animation = 'none'
|
||||
blueBgDiv.offsetHeight /* trigger reflow */
|
||||
blueBgDiv.style.animation = ''
|
||||
}
|
||||
for (const asset of assets) {
|
||||
if (asset.kind !== 'resource' || asset.path in resourceTypesCache) continue
|
||||
ResourceService.getResource({ path: asset.path, workspace: $workspaceStore! })
|
||||
.then((resource) => (resourceTypesCache[asset.path] = resource.resource_type))
|
||||
.catch((err) => (resourceTypesCache[asset.path] = undefined))
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }} bind:isOpen>
|
||||
<svelte:fragment slot="trigger">
|
||||
<div
|
||||
class={twMerge(
|
||||
'text-xs flex items-center gap-2 px-2 py-1.5 bg-surface rounded-md border relative',
|
||||
'transition-colors hover:bg-surface-hover hover:text-primary active:bg-surface/0 cursor-pointer'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
bind:this={blueBgDiv}
|
||||
class="absolute pointer-events-none bg-blue-300/60 inset-0 rounded-md opacity-0 animate-fade-out"
|
||||
></div>
|
||||
<Pyramid size={16} class="z-10" />
|
||||
<span class="z-10">
|
||||
{pluralize(assets.length, 'asset')}
|
||||
</span>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="content">
|
||||
<ul class="divide-y rounded-md">
|
||||
{#each assets as asset}
|
||||
{#if asset}
|
||||
<li class="text-sm px-4 h-12 flex gap-4 items-center select-none justify-between">
|
||||
{truncate(formatAsset(asset), 40)}
|
||||
{#if assetCanBeExplored(asset, { resourceType: resourceTypesCache[asset.path] })}
|
||||
<ExploreAssetButton
|
||||
{asset}
|
||||
{s3FilePicker}
|
||||
{dbManagerDrawer}
|
||||
onClick={() => (isOpen = false)}
|
||||
noText
|
||||
_resourceMetadata={{ resourceType: resourceTypesCache[asset.path] }}
|
||||
/>
|
||||
{/if}
|
||||
</li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
<S3FilePicker bind:this={s3FilePicker} readOnlyMode />
|
||||
<DbManagerDrawer bind:this={dbManagerDrawer} />
|
||||
@@ -1,9 +1,7 @@
|
||||
import type { AssetKind, ListAssetsResponse } from '$lib/gen'
|
||||
import type { AssetKind as _AssetKind, Asset as _Asset, ListAssetsResponse } from '$lib/gen'
|
||||
|
||||
export type Asset = {
|
||||
path: string
|
||||
kind: AssetKind
|
||||
}
|
||||
export type Asset = _Asset
|
||||
export type AssetKind = _AssetKind
|
||||
|
||||
export function parseAsset(asset: string): Asset | undefined {
|
||||
if (asset.startsWith('$res:')) return { path: asset.substring(5), kind: 'resource' }
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { formatAsset, getAssetUsagePageUri } from '$lib/components/assets/lib'
|
||||
import CenteredPage from '$lib/components/CenteredPage.svelte'
|
||||
import { Button, ClearableInput, DrawerContent } from '$lib/components/common'
|
||||
import { ClearableInput, DrawerContent } from '$lib/components/common'
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import RowIcon from '$lib/components/common/table/RowIcon.svelte'
|
||||
import DbManagerDrawer from '$lib/components/DBManagerDrawer.svelte'
|
||||
import PageHeader from '$lib/components/PageHeader.svelte'
|
||||
import S3FilePicker from '$lib/components/S3FilePicker.svelte'
|
||||
import { Cell, DataTable } from '$lib/components/table'
|
||||
import Head from '$lib/components/table/Head.svelte'
|
||||
import { AssetService, type ListAssetsResponse } from '$lib/gen'
|
||||
import { AssetService, ResourceService, type ListAssetsResponse } from '$lib/gen'
|
||||
import { userStore, workspaceStore, userWorkspaces } from '$lib/stores'
|
||||
import { usePromise } from '$lib/svelte5Utils.svelte'
|
||||
import { isS3Uri, pluralize, truncate } from '$lib/utils'
|
||||
import { File } from 'lucide-svelte'
|
||||
import { pluralize, truncate } from '$lib/utils'
|
||||
import { untrack } from 'svelte'
|
||||
import ExploreAssetButton from './ExploreAssetButton.svelte'
|
||||
|
||||
let assets = usePromise(() => AssetService.listAssets({ workspace: $workspaceStore ?? '' }))
|
||||
|
||||
@@ -23,8 +25,22 @@
|
||||
) ?? []
|
||||
)
|
||||
|
||||
let resourceTypesCache: Record<string, string | undefined> = $state({})
|
||||
$effect(() => {
|
||||
if (!assets.value) return
|
||||
untrack(() => {
|
||||
for (const asset of assets.value) {
|
||||
if (asset.kind !== 'resource' || asset.path in resourceTypesCache) continue
|
||||
ResourceService.getResource({ path: asset.path, workspace: $workspaceStore! })
|
||||
.then((resource) => (resourceTypesCache[asset.path] = resource.resource_type))
|
||||
.catch((err) => (resourceTypesCache[asset.path] = undefined))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let viewOccurences: ListAssetsResponse[number] | undefined = $state()
|
||||
let s3FilePicker: S3FilePicker | undefined = $state()
|
||||
let dbManagerDrawer: DbManagerDrawer | undefined = $state()
|
||||
</script>
|
||||
|
||||
{#if $userStore?.operator && $workspaceStore && !$userWorkspaces.find((_) => _.id === $workspaceStore)?.operator_settings?.resources}
|
||||
@@ -59,17 +75,13 @@
|
||||
</a>
|
||||
</Cell>
|
||||
<Cell>
|
||||
{#if asset.kind === 's3object'}
|
||||
<Button
|
||||
size="xs"
|
||||
variant="border"
|
||||
spacingSize="xs2"
|
||||
btnClasses="w-24"
|
||||
on:click={async () => isS3Uri(assetUri) && s3FilePicker?.open(assetUri)}
|
||||
>
|
||||
<File size={18} /> View
|
||||
</Button>
|
||||
{/if}
|
||||
<ExploreAssetButton
|
||||
{asset}
|
||||
{s3FilePicker}
|
||||
{dbManagerDrawer}
|
||||
_resourceMetadata={{ resourceType: resourceTypesCache[asset.path] }}
|
||||
class="w-24"
|
||||
/>
|
||||
</Cell>
|
||||
</tr>
|
||||
{/each}
|
||||
@@ -109,3 +121,4 @@
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
<S3FilePicker bind:this={s3FilePicker} readOnlyMode />
|
||||
<DbManagerDrawer bind:this={dbManagerDrawer} />
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<script module lang="ts">
|
||||
export function assetCanBeExplored(
|
||||
asset: Asset,
|
||||
_resourceMetadata?: { resourceType?: string }
|
||||
): boolean {
|
||||
return (
|
||||
asset.kind === 's3object' ||
|
||||
(asset.kind === 'resource' && isDbType(_resourceMetadata?.resourceType))
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { isDbType } from '$lib/components/apps/components/display/dbtable/utils'
|
||||
import { formatAsset, type Asset } from '$lib/components/assets/lib'
|
||||
import { Button } from '$lib/components/common'
|
||||
import DbManagerDrawer from '$lib/components/DBManagerDrawer.svelte'
|
||||
import S3FilePicker from '$lib/components/S3FilePicker.svelte'
|
||||
import { isS3Uri } from '$lib/utils'
|
||||
import { Database, File } from 'lucide-svelte'
|
||||
|
||||
const {
|
||||
asset,
|
||||
_resourceMetadata,
|
||||
s3FilePicker,
|
||||
dbManagerDrawer,
|
||||
onClick,
|
||||
class: className = '',
|
||||
noText = false
|
||||
}: {
|
||||
asset: Asset
|
||||
_resourceMetadata?: { resourceType?: string }
|
||||
s3FilePicker?: S3FilePicker
|
||||
dbManagerDrawer?: DbManagerDrawer
|
||||
onClick?: () => void
|
||||
class?: string
|
||||
noText?: boolean
|
||||
} = $props()
|
||||
const assetUri = $derived(formatAsset(asset))
|
||||
</script>
|
||||
|
||||
<Button
|
||||
size="xs"
|
||||
variant="border"
|
||||
spacingSize="xs2"
|
||||
wrapperClasses={className}
|
||||
on:click={async () => {
|
||||
if (asset.kind === 'resource' && isDbType(_resourceMetadata?.resourceType)) {
|
||||
dbManagerDrawer?.openDrawer(_resourceMetadata.resourceType, asset.path)
|
||||
} else if (asset.kind === 's3object' && isS3Uri(assetUri)) {
|
||||
s3FilePicker?.open(assetUri)
|
||||
}
|
||||
onClick?.()
|
||||
}}
|
||||
>
|
||||
{#if asset.kind === 's3object'}
|
||||
<span class:hidden={noText}>Explore</span> <File size={18} />
|
||||
{:else if asset.kind === 'resource'}
|
||||
<span class:hidden={noText}>Manage</span> <Database size={18} />
|
||||
{/if}
|
||||
</Button>
|
||||
@@ -60,8 +60,9 @@
|
||||
import EditableSchemaWrapper from '$lib/components/schema/EditableSchemaWrapper.svelte'
|
||||
import ResourceEditorDrawer from '$lib/components/ResourceEditorDrawer.svelte'
|
||||
import GfmMarkdown from '$lib/components/GfmMarkdown.svelte'
|
||||
import DbManagerDrawerButton from '$lib/components/DBManagerDrawerButton.svelte'
|
||||
import { isDbType } from '$lib/components/apps/components/display/dbtable/utils'
|
||||
import ExploreAssetButton from '../assets/ExploreAssetButton.svelte'
|
||||
import DbManagerDrawer from '$lib/components/DBManagerDrawer.svelte'
|
||||
|
||||
type ResourceW = ListableResource & { canWrite: boolean; marked?: string }
|
||||
type ResourceTypeW = ResourceType & { canWrite: boolean }
|
||||
@@ -414,6 +415,8 @@
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
let dbManagerDrawer: DbManagerDrawer | undefined = $state()
|
||||
</script>
|
||||
|
||||
<ConfirmationModal
|
||||
@@ -901,10 +904,11 @@
|
||||
</Cell>
|
||||
<Cell class="flex justify-end">
|
||||
{#if path && isDbType(resource_type)}
|
||||
<DbManagerDrawerButton
|
||||
resourcePath={path}
|
||||
resourceType={resource_type}
|
||||
class="mr-8"
|
||||
<ExploreAssetButton
|
||||
asset={{ kind: 'resource', path: path }}
|
||||
{dbManagerDrawer}
|
||||
_resourceMetadata={{ resourceType: resource_type }}
|
||||
class="w-24"
|
||||
/>
|
||||
{/if}
|
||||
<Dropdown
|
||||
@@ -1083,6 +1087,7 @@
|
||||
<SupabaseConnect bind:this={supabaseConnect} on:refresh={loadResources} />
|
||||
<AppConnect bind:this={appConnect} on:refresh={loadResources} />
|
||||
<ResourceEditorDrawer bind:this={resourceEditor} on:refresh={loadResources} />
|
||||
<DbManagerDrawer bind:this={dbManagerDrawer} />
|
||||
|
||||
<ShareModal
|
||||
bind:this={shareModal}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const plugin = require('tailwindcss/plugin')
|
||||
const { tailwindClasses } = require('./src/lib/components/apps/editor/componentsPanel/tailwindUtils')
|
||||
const {
|
||||
tailwindClasses
|
||||
} = require('./src/lib/components/apps/editor/componentsPanel/tailwindUtils')
|
||||
const { zIndexes } = require('./src/lib/zIndexes')
|
||||
|
||||
const lightTheme = {
|
||||
@@ -477,7 +479,8 @@ const config = {
|
||||
},
|
||||
animation: {
|
||||
'spin-counter-clockwise': 'spin-counter-clockwise 1s linear infinite',
|
||||
'zoom-in': 'zoom-in 0.25s ease-in-out'
|
||||
'zoom-in': 'zoom-in 0.25s ease-in-out',
|
||||
'fade-out': 'fade-out 1s ease-in-out'
|
||||
},
|
||||
keyframes: {
|
||||
'spin-counter-clockwise': {
|
||||
@@ -486,6 +489,10 @@ const config = {
|
||||
'zoom-in': {
|
||||
'0%': { transform: 'scale(0.95)' },
|
||||
'100%': { transform: 'scale(1)' }
|
||||
},
|
||||
'fade-out': {
|
||||
'0%': { opacity: '1' },
|
||||
'100%': { opacity: '0' }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user