refactor: use plain text for multi-line messages ni confirm dialog

This commit is contained in:
arabcoders 2026-04-18 20:18:41 +03:00
parent 9d1bde7355
commit 3f6149aaf7
9 changed files with 57 additions and 82 deletions

View file

@ -9,7 +9,7 @@
@after:enter="focusInput"
>
<template #body>
<p v-if="state.current?.opts.message">
<p v-if="state.current?.opts.message" class="whitespace-pre-line wrap-break-word">
{{ state.current?.opts.message }}
</p>
@ -23,14 +23,6 @@
/>
</UFormField>
<div
v-else-if="
'confirm' === state.current?.type && (state.current?.opts as ConfirmOptions)?.rawHTML
"
class="max-h-[40vh] overflow-auto text-sm text-default"
v-html="(state.current?.opts as ConfirmOptions)?.rawHTML"
/>
<div
v-if="
'confirm' === state.current?.type &&

View file

@ -52,10 +52,6 @@ export type ConfirmOptions = BaseOptions & {
* Text for the confirm button
*/
cancelText?: string;
/**
* Raw HTML content to include in the dialog message.
*/
rawHTML?: string;
/**
* Optional checkbox-style options to return with the confirmation result.
*/

View file

@ -934,15 +934,6 @@ const itemTypeLabel = (item: FileItem): string => {
return item.type === 'file' ? 'File' : ucFirst(item.type);
};
const escapeHtml = (value: string): string => {
return value
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;');
};
const toggleFilter = async (): Promise<void> => {
show_filter.value = !show_filter.value;
@ -1060,8 +1051,9 @@ const handleDeleteSelected = async (): Promise<void> => {
return;
}
const rawHTML =
'<ul>' +
const message =
'Delete the following items?' +
'\n\n' +
selectedElms.value
.map((selectedPath) => {
const item = items.value.find((entry) => entry.path === selectedPath);
@ -1069,15 +1061,14 @@ const handleDeleteSelected = async (): Promise<void> => {
return '';
}
return `<li><strong>${escapeHtml(itemTypeLabel(item))}:</strong> ${escapeHtml(item.name)}</li>`;
return `${itemTypeLabel(item)}: ${item.name}`;
})
.join('') +
'</ul>';
.filter(Boolean)
.join('\n');
const { status } = await dialog.confirmDialog({
title: 'Delete Confirmation',
message: 'Delete the following items?',
rawHTML,
message,
confirmText: 'Delete',
cancelText: 'Cancel',
confirmColor: 'error',

View file

@ -709,15 +709,16 @@ const deleteSelected = async (): Promise<void> => {
const { status } = await confirmDialog({
title: 'Delete Selected Conditions',
rawHTML:
`Delete <strong class="text-red-500">${selectedIds.value.length}</strong> condition/s?<ul>` +
message:
`Delete ${selectedIds.value.length} condition/s?` +
'\n\n' +
selectedIds.value
.map((id) => {
const item = filteredItems.value.find((cond) => cond.id === id);
return item ? `<li>${item.id}: ${item.name}</li>` : '';
return item ? `${item.id}: ${item.name}` : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
confirmText: 'Delete',
confirmColor: 'error',
});

View file

@ -618,15 +618,16 @@ const deleteSelected = async (): Promise<void> => {
const { status } = await confirmDialog({
title: 'Delete Selected Fields',
rawHTML:
`Delete <strong class="text-red-500">${selectedIds.value.length}</strong> field/s?<ul>` +
message:
`Delete ${selectedIds.value.length} field/s?` +
'\n\n' +
selectedIds.value
.map((id) => {
const item = filteredItems.value.find((field) => field.id === id);
return item ? `<li>${item.id}: ${item.name}</li>` : '';
return item ? `${item.id}: ${item.name}` : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
confirmText: 'Delete',
confirmColor: 'error',
});

View file

@ -767,15 +767,16 @@ const deleteSelected = async (): Promise<void> => {
const { status } = await confirmDialog({
title: 'Delete Selected Notifications',
rawHTML:
`Delete <strong class="text-red-500">${selectedIds.value.length}</strong> notification target/s?<ul>` +
message:
`Delete ${selectedIds.value.length} notification target/s?` +
'\n\n' +
selectedIds.value
.map((id) => {
const item = filteredTargets.value.find((target) => target.id === id);
return item ? `<li>${item.id}: ${item.name}</li>` : '';
return item ? `${item.id}: ${item.name}` : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
confirmText: 'Delete',
confirmColor: 'error',
});

View file

@ -585,15 +585,16 @@ const deleteSelected = async (): Promise<void> => {
const { status } = await confirmDialog({
title: 'Delete Selected Presets',
rawHTML:
`Delete <strong class="text-red-500">${selectedIds.value.length}</strong> preset/s?<ul>` +
message:
`Delete ${selectedIds.value.length} preset/s?` +
'\n\n' +
selectedIds.value
.map((id) => {
const item = filteredPresets.value.find((preset) => preset.id === id);
return item ? `<li>${item.id}: ${prettyName(item.name)}</li>` : '';
return item ? `${item.id}: ${prettyName(item.name)}` : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
confirmText: 'Delete',
confirmColor: 'error',
});

View file

@ -793,15 +793,16 @@ const deleteSelected = async (): Promise<void> => {
const { status } = await confirmDialog({
title: 'Delete Selected Task Definitions',
rawHTML:
`Delete <strong class="text-red-500">${selectedIds.value.length}</strong> task definition/s?<ul>` +
message:
`Delete ${selectedIds.value.length} task definition/s?` +
'\n\n' +
selectedIds.value
.map((id) => {
const item = filteredDefinitions.value.find((definition) => definition.id === id);
return item ? `<li>${item.id}: ${item.name || '(Unnamed definition)'}</li>` : '';
return item ? `${item.id}: ${item.name || '(Unnamed definition)'}` : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
confirmText: 'Delete',
confirmColor: 'error',
});

View file

@ -1000,15 +1000,16 @@ const deleteSelected = async () => {
const { status } = await confirmDialog({
title: 'Delete Selected Tasks',
rawHTML:
`Delete <strong class="text-red-500">${selectedElms.value.length}</strong> task/s?<ul>` +
message:
`Delete ${selectedElms.value.length} task/s?` +
'\n\n' +
selectedElms.value
.map((id) => {
const item = tasks.value.find((task) => task.id === id);
return item ? `<li>${item.id}: ${item.name}</li>` : '';
return item ? `${item.id}: ${item.name}` : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
confirmText: 'Delete',
confirmColor: 'error',
});
@ -1151,15 +1152,16 @@ const runSelected = async () => {
}
const { status } = await confirmDialog({
rawHTML:
'Run the following tasks?<ul>' +
message:
'Run the following tasks?' +
'\n\n' +
selectedElms.value
.map((id) => {
const item = tasks.value.find((task) => task.id === id);
return item ? `<li>${item.name}</li>` : '';
return item ? item.name : '';
})
.join('') +
'</ul>',
.filter(Boolean)
.join('\n'),
});
if (true !== status) {
@ -1346,24 +1348,13 @@ const generateMeta = async (item: Task) => {
try {
const { status } = await confirmDialog({
rawHTML: `
<p>
Generate '${item.name}' metadata? you will be notified when it is done.
</p>
<p>
<b>This action will generate:</b>
<ul>
<li><strong>tvshow.nfo</strong> - for media center compatibility</li>
<li><strong>title [id].info.json</strong> - yt-dlp metadata file</li>
<li>
<strong>Thumbnails</strong>: poster.jpg, fanart.jpg, thumb.jpg, banner.jpg, icon.jpg, landscape.jpg
<u>if they are available</u>.
</li>
</ul>
</p>
<p class="text-red-500">
<span>Warning</span>: This will overwrite existing metadata files if they exist.
</p>`,
message:
`Generate '${item.name}' metadata? You will be notified when it is done.` +
'\n\nThis action will generate:' +
'\n- tvshow.nfo - for media center compatibility' +
'\n- title [id].info.json - yt-dlp metadata file' +
'\n- Thumbnails: poster.jpg, fanart.jpg, thumb.jpg, banner.jpg, icon.jpg, landscape.jpg if they are available.' +
'\n\nWarning: This will overwrite existing metadata files if they exist.',
});
if (true !== status) {