123
This commit is contained in:
@@ -350,6 +350,71 @@ const undoImprovePrompt = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearPrompt = () => {
|
||||||
|
prompt.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Reuse Logic ---
|
||||||
|
|
||||||
|
const reusePrompt = (gen) => {
|
||||||
|
if (gen.prompt) {
|
||||||
|
prompt.value = gen.prompt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const reuseAsset = (gen) => {
|
||||||
|
// Assuming 'assets_list' from history are the generated assets,
|
||||||
|
// we need to check if there is a field for INPUT assets.
|
||||||
|
// If we want to reuse the assets that were USED to generate this image:
|
||||||
|
// We need to look for that field.
|
||||||
|
// IF the user means "Reuse the ASSET resulting from the generation", that is 'useResultAsReference'.
|
||||||
|
// IF the user means "Reuse the ASSETS that were INPUTS", we need to find them.
|
||||||
|
// Let's assume 'linked_assets' might be available or we use 'assets_list' if it's input-based?
|
||||||
|
// Based on `handleGenerate`, payload uses `assets_list` as INPUT IDs.
|
||||||
|
// The history response `assets_list` usually contains the IDs of the GENERATED assets (outputs).
|
||||||
|
// Let's check `gen` structure. Since I cannot see the full backend response structure here,
|
||||||
|
// I will assume there might be `input_assets` or similar.
|
||||||
|
// If not available, we might fallback or if the user meant "Reuse this generated image as an asset".
|
||||||
|
|
||||||
|
// Waiting for clarification on "Reuse Asset" (input) vs "Use Result" (output).
|
||||||
|
// The prompt says: "2) reuse asset (binds associated asset)", "3) use result (binds result as reference)".
|
||||||
|
// So (2) implies INPUT assets.
|
||||||
|
|
||||||
|
// Attempt to access input assets if available, otherwise warn or try to fetch.
|
||||||
|
// NOTE: In many systems, the input assets are stored in metadata.
|
||||||
|
|
||||||
|
if (gen.input_assets && Array.isArray(gen.input_assets)) {
|
||||||
|
selectedAssets.value = gen.input_assets.map(id => ({
|
||||||
|
id,
|
||||||
|
url: `/assets/${id}` // Construct URL
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
// Fallback or todo: Backend might need to provide `input_assets` in history.
|
||||||
|
// For now, let's toast or log.
|
||||||
|
console.warn("Input assets not found in history object:", gen)
|
||||||
|
// If the user meant the generated asset (the prompt is slightly ambiguous "associated asset" vs "result"),
|
||||||
|
// but point 3 is explicitly "use result".
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const useResultAsReference = (gen) => {
|
||||||
|
if (gen.assets_list && gen.assets_list.length > 0) {
|
||||||
|
// Appends the generated assets to the selection
|
||||||
|
const newAssets = gen.assets_list.map(id => ({
|
||||||
|
id,
|
||||||
|
url: `/assets/${id}`
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Filter out duplicates
|
||||||
|
const existingIds = new Set(selectedAssets.value.map(a => a.id))
|
||||||
|
newAssets.forEach(asset => {
|
||||||
|
if (!existingIds.has(asset.id)) {
|
||||||
|
selectedAssets.value.push(asset)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Utils ---
|
// --- Utils ---
|
||||||
|
|
||||||
const copyToClipboard = () => {
|
const copyToClipboard = () => {
|
||||||
@@ -459,10 +524,13 @@ onMounted(() => {
|
|||||||
<Button v-if="previousPrompt" icon="pi pi-undo"
|
<Button v-if="previousPrompt" icon="pi pi-undo"
|
||||||
class="!p-1 !w-6 !h-6 !text-[10px] bg-slate-800 hover:bg-slate-700 border-white/10 text-slate-300"
|
class="!p-1 !w-6 !h-6 !text-[10px] bg-slate-800 hover:bg-slate-700 border-white/10 text-slate-300"
|
||||||
@click="undoImprovePrompt" title="Undo" />
|
@click="undoImprovePrompt" title="Undo" />
|
||||||
<Button icon="pi pi-sparkles" :loading="isImprovingPrompt"
|
<Button icon="pi pi-sparkles" label="Improve" :loading="isImprovingPrompt"
|
||||||
:disabled="prompt.length <= 10"
|
:disabled="prompt.length <= 10" size="small"
|
||||||
class="!p-1 !w-6 !h-6 !text-[10px] bg-violet-600/20 hover:bg-violet-600/30 border-violet-500/30 text-violet-400 disabled:opacity-50"
|
class="!py-0.5 !px-2 !text-[10px] bg-violet-600/20 hover:bg-violet-600/30 border-violet-500/30 text-violet-400 disabled:opacity-50"
|
||||||
@click="handleImprovePrompt" title="Improve Prompt" />
|
@click="handleImprovePrompt" />
|
||||||
|
<Button icon="pi pi-times" label="Clear" size="small"
|
||||||
|
class="!py-0.5 !px-2 !text-[10px] bg-slate-800 hover:bg-slate-700 border-white/10 text-slate-400"
|
||||||
|
@click="clearPrompt" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Textarea v-model="prompt" rows="5" autoResize
|
<Textarea v-model="prompt" rows="5" autoResize
|
||||||
@@ -636,42 +704,49 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-1 overflow-y-auto pr-2 custom-scrollbar flex flex-col gap-2">
|
<div class="flex-1 overflow-y-auto pr-2 custom-scrollbar flex flex-col gap-2">
|
||||||
<div v-for="gen in historyGenerations" :key="gen.id" @click="restoreGeneration(gen)"
|
<div v-for="gen in historyGenerations" :key="gen.id"
|
||||||
class="glass-panel p-2 rounded-lg border border-white/5 flex gap-3 items-start hover:bg-white/10 cursor-pointer transition-colors group">
|
class="glass-panel p-2 rounded-lg border border-white/5 flex flex-col gap-2 hover:bg-white/10 transition-colors group">
|
||||||
<div
|
<div class="flex gap-3 items-start cursor-pointer" @click="restoreGeneration(gen)">
|
||||||
class="w-12 h-12 rounded bg-black/40 border border-white/10 overflow-hidden flex-shrink-0 mt-0.5">
|
<div
|
||||||
<img v-if="gen.assets_list && gen.assets_list.length > 0"
|
class="w-12 h-12 rounded bg-black/40 border border-white/10 overflow-hidden flex-shrink-0 mt-0.5">
|
||||||
:src="API_URL + '/assets/' + gen.assets_list[0] + '?thumbnail=true'"
|
<img v-if="gen.assets_list && gen.assets_list.length > 0"
|
||||||
class="w-full h-full object-cover" />
|
:src="API_URL + '/assets/' + gen.assets_list[0] + '?thumbnail=true'"
|
||||||
|
class="w-full h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p class="text-xs text-slate-300 truncate font-medium">{{ gen.prompt }}</p>
|
||||||
|
|
||||||
|
<!-- Tech Prompt Preview -->
|
||||||
|
<p v-if="gen.tech_prompt"
|
||||||
|
class="text-[9px] text-slate-500 truncate mt-0.5 font-mono opacity-80">
|
||||||
|
{{ gen.tech_prompt }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="flex gap-2 items-center text-[10px] text-slate-500 mt-1">
|
||||||
|
<span>{{ new Date(gen.created_at).toLocaleDateString() }}</span>
|
||||||
|
<span class="capitalize"
|
||||||
|
:class="gen.status === 'done' ? 'text-green-500' : 'text-amber-500'">{{
|
||||||
|
gen.status }}</span>
|
||||||
|
<i v-if="gen.failed_reason" v-tooltip.right="gen.failed_reason"
|
||||||
|
class="pi pi-exclamation-circle text-red-500"
|
||||||
|
style="font-size: 12px;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 min-w-0">
|
|
||||||
<p class="text-xs text-slate-300 truncate font-medium">{{ gen.prompt }}</p>
|
|
||||||
|
|
||||||
<!-- Tech Prompt Preview -->
|
<!-- Action Buttons -->
|
||||||
<p v-if="gen.tech_prompt"
|
<div class="flex gap-2 mt-1 border-t border-white/5 pt-2">
|
||||||
class="text-[9px] text-slate-500 truncate mt-0.5 font-mono opacity-80">
|
<Button icon="pi pi-copy" label="Prompt" size="small" text
|
||||||
{{ gen.tech_prompt }}
|
class="!text-[10px] !py-0.5 !px-2 text-slate-400 hover:bg-white/5 flex-1"
|
||||||
</p>
|
@click.stop="reusePrompt(gen)" v-tooltip.bottom="'Use this prompt'" />
|
||||||
|
<Button icon="pi pi-images" label="Asset" size="small" text
|
||||||
<div class="flex gap-2 items-center text-[10px] text-slate-500 mt-1">
|
class="!text-[10px] !py-0.5 !px-2 text-slate-400 hover:bg-white/5 flex-1"
|
||||||
<span>{{ new Date(gen.created_at).toLocaleDateString() }}</span>
|
@click.stop="reuseAsset(gen)" v-tooltip.bottom="'Use original assets'" />
|
||||||
<span class="capitalize"
|
<Button icon="pi pi-reply" label="Result" size="small" text
|
||||||
:class="gen.status === 'done' ? 'text-green-500' : 'text-amber-500'">{{
|
class="!text-[10px] !py-0.5 !px-2 text-slate-400 hover:bg-white/5 flex-1"
|
||||||
gen.status }}</span>
|
:disabled="gen.status !== 'done' || !gen.assets_list?.length"
|
||||||
<i v-if="gen.failed_reason" v-tooltip.right="gen.failed_reason" class="pi pi-exclamation-circle text-red-500" style="font-size: 12px;" />
|
@click.stop="useResultAsReference(gen)"
|
||||||
</div>
|
v-tooltip.bottom="'Use result as reference'" />
|
||||||
<div v-if="gen.execution_time_seconds || gen.token_usage"
|
|
||||||
class="flex flex-wrap gap-2 text-[9px] text-slate-500 font-mono mt-1 opacity-70">
|
|
||||||
<span v-if="gen.execution_time_seconds" title="Total Time"><i
|
|
||||||
class="pi pi-clock mr-0.5"></i>{{
|
|
||||||
gen.execution_time_seconds.toFixed(1) }}s</span>
|
|
||||||
<span v-if="gen.api_execution_time_seconds" title="API Time"><i
|
|
||||||
class="pi pi-server mr-0.5"></i>{{
|
|
||||||
gen.api_execution_time_seconds.toFixed(1) }}s</span>
|
|
||||||
<span v-if="gen.token_usage" title="Tokens"><i class="pi pi-bolt mr-0.5"></i>{{
|
|
||||||
gen.token_usage
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user