feat: editable resource types + rt in deployments

This commit is contained in:
Ruben Fiszel
2023-06-22 00:19:25 +02:00
parent 7c8c93aef3
commit 605afca3b8
4 changed files with 151 additions and 18 deletions

View File

@@ -6338,8 +6338,7 @@ components:
EditResourceType:
type: object
properties:
schema:
type: string
schema: {}
description:
type: string

View File

@@ -23,7 +23,15 @@
const dispatch = createEventDispatcher()
type Kind = 'script' | 'resource' | 'schedule' | 'variable' | 'flow' | 'app' | 'raw_app'
type Kind =
| 'script'
| 'resource'
| 'schedule'
| 'variable'
| 'flow'
| 'app'
| 'raw_app'
| 'resource_type'
export let kind: Kind
export let initialPath: string = ''
@@ -60,7 +68,10 @@
dependencies = (await getDependencies(kind, path)).map((x) => ({
...x,
include:
kind == 'variable' || kind == 'resource' || (x.kind != 'variable' && x.kind != 'resource')
kind == 'variable' ||
kind == 'resource' ||
kind == 'resource_type' ||
(x.kind != 'variable' && x.kind != 'resource' && x.kind != 'resource_type')
}))
dependencies.forEach((x) => {
checkAlreadyExists(x.kind, x.path).then(
@@ -123,9 +134,8 @@
}
}
return recObj(res.value)
return [...recObj(res.value), { kind: 'resource_type', path: res.resource_type }]
}
return []
}
let toProcess = [{ kind, path }]
@@ -176,6 +186,11 @@
workspace: workspaceToDeployTo!,
path: path
})
} else if (kind == 'resource_type') {
return await ResourceService.existsResourceType({
workspace: workspaceToDeployTo!,
path: path
})
} else {
throw new Error(`Unknown kind ${kind}`)
}
@@ -313,6 +328,30 @@
}
})
}
} else if (kind == 'resource_type') {
const resource = await ResourceService.getResourceType({
workspace: $workspaceStore!,
path: path
})
if (alreadyExists) {
await ResourceService.updateResourceType({
workspace: workspaceToDeployTo!,
path: path,
requestBody: {
schema: resource.schema,
description: resource.description ?? ''
}
})
} else {
await ResourceService.createResourceType({
workspace: workspaceToDeployTo!,
requestBody: {
description: resource.description ?? '',
schema: resource.schema,
name: resource.name
}
})
}
} else if (kind == 'raw_app') {
throw new Error('Raw app deploy not implemented yet')
// const app = await RawAppService.getRawAppData({
@@ -393,6 +432,12 @@
path: path
})
return resource.value
} else if (kind == 'resource_type') {
const resource = await ResourceService.getResourceType({
workspace: workspace,
path: path
})
return resource.schema
} else if (kind == 'raw_app') {
throw new Error('Raw app deploy not implemented yet')
// const app = await RawAppService.getRawAppData({
@@ -473,8 +518,14 @@
<Badge color="red">
Missing
<Tooltip
>This {kind} doesn't exist and is not included in the deployment. Variable and Resources
are considered to be workspace specific and are never included by default.</Tooltip
>{#if kind == 'resource_type'}
Resource types are not re-deployed by default. We strongly recommend to add
shared resource types in 'admin' workspace, which will have them be shared to
every workspace.
{:else}
This {kind} doesn't exist and is not included in the deployment. Variables and Resources
are considered to be workspace specific and are never included by default.
{/if}</Tooltip
>
</Badge>
{/if}

View File

@@ -16,7 +16,7 @@
import { faHourglassHalf } from '@fortawesome/free-solid-svg-icons'
import { Badge } from '../common'
const POPUP_HEIGHT = 240 as const
const POPUP_HEIGHT = 320 as const
export let id: string
let job: Job | undefined = undefined

View File

@@ -34,6 +34,7 @@
faCircle,
faEdit,
faFileExport,
faPen,
faPlus,
faRefresh,
faSave,
@@ -63,11 +64,17 @@
}
let resourceTypeDrawer: Drawer
let editResourceTypeDrawer: Drawer
let newResourceType = {
name: '',
schema: emptySchema(),
description: ''
}
let editResourceType = {
name: '',
schema: emptySchema(),
description: ''
}
let resourceEditor: ResourceEditor | undefined
let shareModal: ShareModal
let appConnect: AppConnect
@@ -165,6 +172,20 @@
loadResourceTypes()
}
async function updateResourceType(): Promise<void> {
await ResourceService.updateResourceType({
workspace: $workspaceStore!,
path: editResourceType.name,
requestBody: {
schema: editResourceType.schema,
description: newResourceType.description
}
})
editResourceTypeDrawer.closeDrawer?.()
sendUserToast('Resource type updated')
loadResourceTypes()
}
async function handleDeleteResourceType(name: string) {
try {
await ResourceService.deleteResourceType({ workspace: $workspaceStore!, path: name })
@@ -190,6 +211,16 @@
resourceTypeDrawer.openDrawer?.()
}
async function startEditResourceType(name: string) {
const rt = await ResourceService.getResourceType({ workspace: $workspaceStore!, path: name })
editResourceType = {
name: rt.name,
schema: rt.schema,
description: rt.description ?? ''
}
editResourceTypeDrawer.openDrawer?.()
}
$: {
if ($workspaceStore && $userStore) {
loadResources()
@@ -268,6 +299,47 @@
</DrawerContent>
</Drawer>
<Drawer bind:this={editResourceTypeDrawer} size="800px">
<DrawerContent title="Edit resource type" on:close={editResourceTypeDrawer.closeDrawer}>
<svelte:fragment slot="actions">
<Button startIcon={{ icon: faSave }} on:click={updateResourceType}>Update</Button>
</svelte:fragment>
<div class="flex flex-col gap-6">
<label for="inp">
<div class="mb-1 font-semibold text-gray-700 gap-1 flex flex-row items-center"
>Name
<div class="flex flex-row items-center gap-x-4">
<div class="flex flex-row items-center">
<div class="inline-block">
<input
disabled
id="inp"
type="text"
bind:value={editResourceType.name}
class={classNames('!h-8 !border !border-gray-200')}
/>
</div>
</div>
</div>
</div></label
>
<label>
<div class="mb-1 font-semibold text-gray-700">Description</div>
<textarea
type="text"
use:autosize
autocomplete="off"
bind:value={editResourceType.description}
/></label
>
<div>
<div class="mb-1 font-semibold text-gray-700">Schema</div>
<SchemaEditor bind:schema={editResourceType.schema} />
</div>
</div>
</DrawerContent>
</Drawer>
<Drawer bind:this={resourceTypeDrawer} size="800px">
<DrawerContent title="Create resource type" on:close={resourceTypeDrawer.closeDrawer}>
<svelte:fragment slot="actions">
@@ -660,15 +732,26 @@
</Tooltip>
</Badge>
{:else if $userStore?.is_admin || $userStore?.is_super_admin}
<Button
size="sm"
color="red"
variant="border"
startIcon={{ icon: faTrash }}
on:click={() => handleDeleteResourceType(name)}
>
Delete
</Button>
<div class="flex flex-row-reverse gap-2">
<Button
size="sm"
color="red"
variant="border"
startIcon={{ icon: faTrash }}
on:click={() => handleDeleteResourceType(name)}
>
Delete
</Button>
<Button
size="sm"
variant="border"
color="dark"
startIcon={{ icon: faPen }}
on:click={() => startEditResourceType(name)}
>
Edit
</Button>
</div>
{:else}
<Badge>
Non Editable