WIP: Deleting assets, UI only, also not wired up

This commit is contained in:
DrJKL
2025-11-26 18:13:55 -08:00
parent df82698f1e
commit ba43494d32
8 changed files with 139 additions and 13 deletions

View File

@@ -14,6 +14,7 @@
<component
:is="item.headerComponent"
v-if="item.headerComponent"
v-bind="item.headerProps"
:id="item.key"
/>
<h3 v-else :id="item.key">

View File

@@ -0,0 +1,14 @@
<template>
<div
class="flex flex-col px-4 py-2 text-sm text-muted-foreground border-t border-border-default"
>
<p v-if="confirmationText">
{{ confirmationText }}
</p>
</div>
</template>
<script setup lang="ts">
defineProps<{
confirmationText?: string
}>()
</script>

View File

@@ -0,0 +1,38 @@
<template>
<section class="w-full flex gap-2 justify-end px-2 pb-2">
<TextButton
:label="cancelTextX"
type="transparent"
autofocus
@click="$emit('cancel')"
/>
<TextButton
:label="confirmTextX"
type="transparent"
:class="confirmClass"
@click="$emit('confirm')"
/>
</section>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import TextButton from '@/components/button/TextButton.vue'
const { t } = useI18n()
const { cancelText, confirmText, confirmClass } = defineProps<{
cancelText?: string
confirmText?: string
confirmClass?: string
}>()
defineEmits<{
cancel: []
confirm: []
}>()
const confirmTextX = computed(() => confirmText || t('g.confirm'))
const cancelTextX = computed(() => cancelText || t('g.cancel'))
</script>

View File

@@ -0,0 +1,12 @@
<template>
<div
class="flex items-center gap-2 p-4 font-bold text-sm text-base-foreground font-inter"
>
<span v-if="title" class="flex-auto">{{ title }}</span>
</div>
</template>
<script setup lang="ts">
defineProps<{
title?: string
}>()
</script>

View File

@@ -0,0 +1,31 @@
import ConfirmBody from '@/components/dialog/confirm/ConfirmBody.vue'
import ConfirmFooter from '@/components/dialog/confirm/ConfirmFooter.vue'
import ConfirmHeader from '@/components/dialog/confirm/ConfirmHeader.vue'
import { useDialogStore } from '@/stores/dialogStore'
import type { ComponentAttrs } from 'vue-component-type-helpers'
interface ConfirmDialogOptions {
headerProps?: ComponentAttrs<typeof ConfirmHeader>
props?: ComponentAttrs<typeof ConfirmBody>
footerProps?: ComponentAttrs<typeof ConfirmFooter>
}
export function showConfirmDialog(options: ConfirmDialogOptions = {}) {
const dialogStore = useDialogStore()
const { headerProps, props, footerProps } = options
return dialogStore.showDialog({
headerComponent: ConfirmHeader,
component: ConfirmBody,
footerComponent: ConfirmFooter,
headerProps,
props,
footerProps,
dialogComponentProps: {
pt: {
header: 'py-0! px-0!',
content: 'p-0!',
footer: 'p-0!'
}
}
})
}

View File

@@ -54,7 +54,12 @@
<i class="icon-[lucide--pencil]" />
</template>
</IconTextButton>
<IconTextButton :label="$t('g.delete')" type="secondary" size="md">
<IconTextButton
:label="$t('g.delete')"
type="secondary"
size="md"
@click="confirmDeletion"
>
<template #icon>
<i class="icon-[lucide--trash-2]" />
</template>
@@ -120,9 +125,11 @@ import IconGroup from '@/components/button/IconGroup.vue'
import IconTextButton from '@/components/button/IconTextButton.vue'
import MoreButton from '@/components/button/MoreButton.vue'
import EditableText from '@/components/common/EditableText.vue'
import { showConfirmDialog } from '@/components/dialog/confirm/confirmDialog'
import AssetBadgeGroup from '@/platform/assets/components/AssetBadgeGroup.vue'
import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useDialogStore } from '@/stores/dialogStore'
import { cn } from '@/utils/tailwindUtil'
const { asset, interactive } = defineProps<{
@@ -135,6 +142,7 @@ defineEmits<{
}>()
const settingStore = useSettingStore()
const { closeDialog } = useDialogStore()
const dropdownMenuButton = useTemplateRef<InstanceType<typeof MoreButton>>(
'dropdown-menu-button'
@@ -155,6 +163,32 @@ const { isLoading, error } = useImage({
alt: asset.name
})
async function confirmDeletion() {
dropdownMenuButton.value?.hide()
const confirmDialog = showConfirmDialog({
headerProps: {
title: 'Delete this model?'
},
props: {
confirmationText:
'This model will be permanently removed from your library.'
},
footerProps: {
confirmText: 'Delete',
// TODO: These need to be put into the new Button Variants once we have them.
confirmClass: cn(
'bg-danger-200 text-base-foreground hover:bg-danger-200/80 focus:bg-danger-200/80 focus:ring ring-base-foreground'
),
onCancel: () => {
closeDialog(confirmDialog)
},
onConfirm: () => {
closeDialog(confirmDialog)
}
}
})
}
function startAssetRename() {
dropdownMenuButton.value?.hide()
isEditing.value = true

View File

@@ -1,6 +1,6 @@
<template>
<div
class="upload-model-dialog flex flex-col justify-between gap-6 p-4 pt-6 border-t-[1px] border-border-default"
class="upload-model-dialog flex flex-col justify-between gap-6 p-4 pt-6 border-t border-border-default"
>
<!-- Step 1: Enter URL -->
<UploadModelUrlInput

View File

@@ -46,6 +46,7 @@ interface DialogInstance<
visible: boolean
title?: string
headerComponent?: H
headerProps?: ComponentAttrs<H>
component: B
contentProps: ComponentAttrs<B>
footerComponent?: F
@@ -133,17 +134,11 @@ export const useDialogStore = defineStore('dialog', () => {
updateCloseOnEscapeStates()
}
function createDialog(options: {
key: string
title?: string
headerComponent?: Component
footerComponent?: Component
component: Component
props?: Record<string, any>
footerProps?: Record<string, any>
dialogComponentProps?: DialogComponentProps
priority?: number
}) {
function createDialog<
H extends Component = Component,
B extends Component = Component,
F extends Component = Component
>(options: ShowDialogOptions<H, B, F> & { key: string }) {
if (dialogStack.value.length >= 10) {
dialogStack.value.shift()
}
@@ -159,6 +154,7 @@ export const useDialogStore = defineStore('dialog', () => {
? markRaw(options.footerComponent)
: undefined,
component: markRaw(options.component),
headerProps: { ...options.headerProps },
contentProps: { ...options.props },
footerProps: { ...options.footerProps },
priority: options.priority ?? 1,