Implement bulk operations for regex

This commit is contained in:
Cohee
2025-05-26 22:21:48 +03:00
parent 52c3b83f96
commit 523cc36b46
4 changed files with 101 additions and 18 deletions

View File

@@ -21,13 +21,28 @@
<small data-i18n="ext_regex_import_script">Import</small> <small data-i18n="ext_regex_import_script">Import</small>
</div> </div>
<input type="file" id="import_regex_file" hidden accept="*.json" multiple /> <input type="file" id="import_regex_file" hidden accept="*.json" multiple />
<div id="export_global_regex" class="menu_button menu_button_icon"> <label for="regex_bulk_edit" class="menu_button menu_button_icon">
<i class="fa-solid fa-file-export"></i> <input id="regex_bulk_edit" type="checkbox" class="displayNone" />
<small data-i18n="ext_regex_export_global">Export Global</small> <i class="fa-solid fa-edit"></i>
<small data-i18n="ext_regex_bulk_edit">Bulk Edit</small>
</label>
</div> </div>
<div id="export_scoped_regex" class="menu_button menu_button_icon"> <div class="regex_bulk_operations flex-container justifyCenter">
<div id="bulk_enable_regex" class="menu_button menu_button_icon">
<i class="fa-solid fa-toggle-on"></i>
<small data-i18n="Enable">Enable</small>
</div>
<div id="bulk_disable_regex" class="menu_button menu_button_icon">
<i class="fa-solid fa-toggle-off"></i>
<small data-i18n="Disable">Disable</small>
</div>
<div id="bulk_export_regex" class="menu_button menu_button_icon">
<i class="fa-solid fa-file-export"></i> <i class="fa-solid fa-file-export"></i>
<small data-i18n="ext_regex_export_scoped">Export Scoped</small> <small data-i18n="Export">Export</small>
</div>
<div id="bulk_delete_regex" class="menu_button menu_button_icon">
<i class="fa-solid fa-trash"></i>
<small data-i18n="Delete">Delete</small>
</div> </div>
</div> </div>
<hr /> <hr />

View File

@@ -607,22 +607,67 @@ jQuery(async () => {
$('#import_regex_file').trigger('click'); $('#import_regex_file').trigger('click');
}); });
$('#export_global_regex').on('click', async function () { function getSelectedScripts() {
const regexScripts = extension_settings?.regex ?? []; const scripts = getRegexScripts();
if (regexScripts.length) { const selector = '#regex_container .regex-script-label:has(.regex_bulk_checkbox:checked)';
const fileName = 'regex-global.json'; const selectedIds = Array.from(document.querySelectorAll(selector)).map(e => e.getAttribute('id')).filter(id => id);
const fileData = JSON.stringify(regexScripts, null, 4); return scripts.filter(script => selectedIds.includes(script.id));
download(fileData, fileName, 'application/json');
} }
$('#bulk_enable_regex').on('click', async function () {
const scripts = getSelectedScripts().filter(script => script.disabled);
if (scripts.length === 0) {
toastr.warning(t`No regex scripts selected for enabling.`);
return;
}
for (const script of scripts) {
script.disabled = false;
}
saveSettingsDebounced();
await loadRegexScripts();
}); });
$('#export_scoped_regex').on('click', async function () { $('#bulk_disable_regex').on('click', async function () {
const regexScripts = characters[this_chid]?.data?.extensions?.regex_scripts ?? []; const scripts = getSelectedScripts().filter(script => !script.disabled);
if (regexScripts.length) { if (scripts.length === 0) {
const fileName = `regex-${sanitizeFileName(characters[this_chid].name)}.json`; toastr.warning(t`No regex scripts selected for disabling.`);
const fileData = JSON.stringify(regexScripts, null, 4); return;
download(fileData, fileName, 'application/json');
} }
for (const script of scripts) {
script.disabled = true;
}
saveSettingsDebounced();
await loadRegexScripts();
});
$('#bulk_delete_regex').on('click', async function () {
const scripts = getSelectedScripts();
if (scripts.length === 0) {
toastr.warning(t`No regex scripts selected for deletion.`);
return;
}
const confirm = await callGenericPopup('Are you sure you want to delete the selected regex scripts?', POPUP_TYPE.CONFIRM);
if (!confirm) {
return;
}
for (const script of scripts) {
const isScoped = characters[this_chid]?.data?.extensions?.regex_scripts?.some(s => s.id === script.id);
await deleteRegexScript({ id: script.id, isScoped: isScoped });
}
await reloadCurrentChat();
saveSettingsDebounced();
});
$('#bulk_export_regex').on('click', async function () {
const scripts = getSelectedScripts();
if (scripts.length === 0) {
toastr.warning(t`No regex scripts selected for export.`);
return;
}
const fileName = `regex-${new Date().toISOString()}.json`;
const fileData = JSON.stringify(scripts, null, 4);
download(fileData, fileName, 'application/json');
await loadRegexScripts();
}); });
let sortableDatas = [ let sortableDatas = [

View File

@@ -1,4 +1,5 @@
<div class="regex-script-label flex-container flexnowrap"> <div class="regex-script-label flex-container flexnowrap">
<input type="checkbox" class="regex_bulk_checkbox" />
<span class="drag-handle menu-handle">&#9776;</span> <span class="drag-handle menu-handle">&#9776;</span>
<div class="regex_script_name flexGrow overflow-hidden"></div> <div class="regex_script_name flexGrow overflow-hidden"></div>
<div class="flex-container flexnowrap"> <div class="flex-container flexnowrap">

View File

@@ -56,7 +56,7 @@
} }
.regex-script-label { .regex-script-label {
align-items: center; align-items: baseline;
border: 1px solid var(--SmartThemeBorderColor); border: 1px solid var(--SmartThemeBorderColor);
border-radius: 10px; border-radius: 10px;
padding: 0 5px; padding: 0 5px;
@@ -126,3 +126,25 @@ input.enable_scoped {
right: 10px; right: 10px;
transform: translateY(-50%); transform: translateY(-50%);
} }
.regex_settings label[for="regex_bulk_edit"]:has(#regex_bulk_edit:checked) {
color: var(--golden);
}
.regex_settings .regex-script-container .regex-script-label .regex_bulk_checkbox {
margin-left: 5px;
margin-right: 5px;
}
.regex_settings .regex_bulk_operations,
.regex_settings .regex_bulk_checkbox {
display: none;
}
.regex_settings:has(#regex_bulk_edit:checked) .regex_bulk_operations {
display: flex;
}
.regex_settings:has(#regex_bulk_edit:checked) .regex_bulk_checkbox {
display: inline-grid;
}