Merge pull request #2955 from Yokayo/staging Add rename buttons for advanced formatting presets
Signed| @@ -3178,9 +3178,10 @@ | ||
| 3178 | 3178 | </h4> |
| 3179 | 3179 | <div class="flex-container" title="Select your current Context Template" data-i18n="[title]Select your current Context Template"> |
| 3180 | 3180 | <select id="context_presets" data-preset-manager-for="context" class="flex1 text_pole"></select> |
| 3181 | 3181 | <div class="flex-container justifyCenter gap3px"> |
| 3182 | 3182 | <input type="file" hidden data-preset-manager-file="context" accept=".json, .settings"> |
| 3183 | 3183 | <i data-preset-manager-update="context" class="menu_button fa-solid fa-save" title="Update current template" data-i18n="[title]Update current template"></i> |
| 3184 | + <i data-preset-manager-rename="context" class="menu_button fa-pencil fa-solid" title="Rename current template" data-i18n="[title]Rename current template"></i> | |
| 3184 | 3185 | <i data-preset-manager-new="context" class="menu_button fa-solid fa-file-circle-plus" title="Save template as" data-i18n="[title]Save template as"></i> |
| 3185 | 3186 | <i data-preset-manager-import="context" class="displayNone menu_button fa-solid fa-file-import" title="Import template" data-i18n="[title]Import template"></i> |
| 3186 | 3187 | <i data-preset-manager-export="context" class="displayNone menu_button fa-solid fa-file-export" title="Export template" data-i18n="[title]Export template"></i> |
| @@ -3289,9 +3290,10 @@ | ||
| 3289 | 3290 | |
| 3290 | 3291 | <div class="flex-container" title="Select your current Instruct Template" data-i18n="[title]Select your current Instruct Template"> |
| 3291 | 3292 | <select id="instruct_presets" data-preset-manager-for="instruct" class="flex1 text_pole"></select> |
| 3292 | 3293 | <div class="flex-container margin0 justifyCenter gap3px"> |
| 3293 | 3294 | <input type="file" hidden data-preset-manager-file="instruct" accept=".json, .settings"> |
| 3294 | 3295 | <i data-preset-manager-update="instruct" class="menu_button fa-solid fa-save" title="Update current template" data-i18n="[title]Update current template"></i> |
| 3296 | + <i data-preset-manager-rename="instruct" class="menu_button fa-pencil fa-solid" title="Rename current template" data-i18n="[title]Rename current template"></i> | |
| 3295 | 3297 | <i data-preset-manager-new="instruct" class="menu_button fa-solid fa-file-circle-plus" title="Save template as" data-i18n="[title]Save template as"></i> |
| 3296 | 3298 | <i data-preset-manager-import="instruct" class="displayNone menu_button fa-solid fa-file-import" title="Import template" data-i18n="[title]Import template"></i> |
| 3297 | 3299 | <i data-preset-manager-export="instruct" class="displayNone menu_button fa-solid fa-file-export" title="Export template" data-i18n="[title]Export template"></i> |
| @@ -3469,9 +3471,10 @@ | ||
| 3469 | 3471 | |
| 3470 | 3472 | <div class="flex-container" title="Select your current System Prompt" data-i18n="[title]Select your current System Prompt"> |
| 3471 | 3473 | <select id="sysprompt_select" data-preset-manager-for="sysprompt" class="flex1 text_pole"></select> |
| 3472 | 3474 | <div class="flex-container margin0 justifyCenter gap3px"> |
| 3473 | 3475 | <input type="file" hidden data-preset-manager-file="sysprompt" accept=".json, .settings"> |
| 3474 | 3476 | <i data-preset-manager-update="sysprompt" class="menu_button fa-solid fa-save" title="Update current prompt" data-i18n="[title]Update current prompt"></i> |
| 3477 | + <i data-preset-manager-rename="sysprompt" class="menu_button fa-pencil fa-solid" title="Rename current prompt" data-i18n="[title]Rename current prompt"></i> | |
| 3475 | 3478 | <i data-preset-manager-new="sysprompt" class="menu_button fa-solid fa-file-circle-plus" title="Save prompt as" data-i18n="[title]Save prompt as"></i> |
| 3476 | 3479 | <i data-preset-manager-import="sysprompt" class="displayNone menu_button fa-solid fa-file-import" title="Import template" data-i18n="[title]Import template"></i> |
| 3477 | 3480 | <i data-preset-manager-export="sysprompt" class="displayNone menu_button fa-solid fa-file-export" title="Export template" data-i18n="[title]Export template"></i> |
| @@ -1720,7 +1720,7 @@ | ||
| 1720 | 1720 | "Proxy Preset": "Пресет для прокси", |
| 1721 | 1721 | "Enter a name:": "Введите название:", |
| 1722 | 1722 | "Are you sure you want to delete the selected profile?": "Вы точно хотите удалить выбранный профиль?", |
| 1723 | 1723 | "instruct_enabled": "ВключитьВкл/выкл Instruct-режим", |
| 1724 | 1724 | "Instruct Template": "Шаблон Instruct-режима", |
| 1725 | 1725 | "instruct_template_activation_regex_desc": "Автоматически активировать этот шаблон в момент подключения к API или выбора модели, если название модели соответствует этому рег. выражению.", |
| 1726 | 1726 | "instruct_bind_to_context": "При включении этой опции Шаблон контекста будет выбираться, исходя из выбранного в текущий момент Шаблона Instruct-режима, либо по вашему желанию.", |
| @@ -1730,11 +1730,11 @@ | ||
| 1730 | 1730 | "Export Advanced Formatting settings": "Экспорт настроек Расширенного форматирования", |
| 1731 | 1731 | "Select your current System Prompt": "Выберите текущий системный промпт", |
| 1732 | 1732 | "Prompt Content": "Текст промпта", |
| 1733 | 1733 | "Update current prompt": "Обновить текущийСохранить промпт", |
| 1734 | 1734 | "Save prompt as": "Сохранить как...", |
| 1735 | 1735 | "Import template": "Импорт шаблона", |
| 1736 | 1736 | "Export template": "Экспорт шаблона", |
| 1737 | 1737 | "Restore current prompt": "Восстановить текущий промпт", |
| 1738 | 1738 | "comma delimited,no spaces between": "через запятую,без пробелов в промежутках", |
| 1739 | 1739 | "User Message Sequences": "Строки для сообщений пользователя", |
| 1740 | 1740 | "Assistant Message Sequences": "Строки для сообщений ассистента", |
| @@ -1757,7 +1757,7 @@ | ||
| 1757 | 1757 | "Preset was not deleted from server": "Пресет не удалён с сервера", |
| 1758 | 1758 | "Preset deleted": "Пресет удалён", |
| 1759 | 1759 | "Delete the preset?": "Удалить пресет?", |
| 1760 | 1760 | "Preset updated": "Пресет обновлёнсохранён", |
| 1761 | 1761 | "Entered reverse proxy address is not a valid URL": "Введённый адрес прокси невалиден", |
| 1762 | 1762 | "An error occurred while counting tokens: Token budget exceeded.": "Ошибка при подсчёте токенов: Превышен бюджет токенов", |
| 1763 | 1763 | "An error occurred while counting tokens: Invalid character name": "Ошибка при подсчёте токенов: Невалидное имя персонажа", |
| @@ -1893,5 +1893,71 @@ | ||
| 1893 | 1893 | "Base": "Основание", |
| 1894 | 1894 | "DRY_Base_desc": "Определяет, насколько быстро возрастает штраф с увеличением длины строки.", |
| 1895 | 1895 | "Allowed Length": "Допустимая длина", |
| 1896 | 1896 | "DRY_Allowed_Length_desc": "Длина повторяющейся строки, при превышении которой DRY начинает налагать штраф.", |
| 1897 | + "Invalid data provided for master import": "Глоб. импорт не может быть выполнен по причине невалидности данных", | |
| 1898 | + "Importing instruct template...": "Импортируем...", | |
| 1899 | + "Instruct template detected": "Обнаружен шаблон Instruct-режима", | |
| 1900 | + "Importing as context template...": "Импортируем...", | |
| 1901 | + "Context template detected": "Обнаружен шаблон контекста", | |
| 1902 | + "Importing as system prompt...": "Импортируем...", | |
| 1903 | + "System prompt detected": "Обнаружен системный промпт", | |
| 1904 | + "Importing as settings preset...": "Импортируем...", | |
| 1905 | + "Text Completion settings detected": "Обнаружены настройки Text Completion", | |
| 1906 | + "No valid sections found in imported data": "Не найдено ни одной валидной секции данных", | |
| 1907 | + "No sections selected for import": "Не выбрано ни одной секции для импорта", | |
| 1908 | + "Import": "Импортировать", | |
| 1909 | + "Imported ${0} settings: ${1}": "Импортировано ${0} настроек: ${1}", | |
| 1910 | + "Export": "Экспортировать", | |
| 1911 | + "No sections selected for export": "Не выбрано ни одной секции для экспорта", | |
| 1912 | + "Cannot update GUI preset": "Пресет для GUI обновить невозможно", | |
| 1913 | + "Template updated": "Шаблон сохранён", | |
| 1914 | + "Hint: Use a character/group name to bind preset to a specific chat.": "Совет: введите имя персонажа/группы, чтобы привязать пресет к определённому чату.", | |
| 1915 | + "Preset name:": "Название пресета:", | |
| 1916 | + "Template name:": "Название шаблона:", | |
| 1917 | + "Preset saved": "Пресет сохранён", | |
| 1918 | + "Template saved": "Шаблон сохранён", | |
| 1919 | + "Preset could not be saved": "Не удалось сохранить пресет", | |
| 1920 | + "Preset could not be renamed": "Не удалось обновить пресет", | |
| 1921 | + "Preset renamed": "Пресет переименован", | |
| 1922 | + "Template renamed": "Шаблон переименован", | |
| 1923 | + "Cannot delete GUI preset": "Пресет для GUI удалить невозможно", | |
| 1924 | + "Failed to restore default preset": "Не удалось восстановить пресет по умолчанию", | |
| 1925 | + "Failed to restore default template": "Не удалось восстановить шаблон по умолчанию", | |
| 1926 | + "Rename preset": "Переименовать пресет", | |
| 1927 | + "Rename template": "Переименовать шаблон", | |
| 1928 | + "Enter a new name:": "Введите новое название:", | |
| 1929 | + "Preset imported": "Пресет импортирован", | |
| 1930 | + "Template imported": "Шаблон импортирован", | |
| 1931 | + "Delete this preset?": "Удалить этот пресет?", | |
| 1932 | + "Delete this template?": "Удалить этот шаблон?", | |
| 1933 | + "This action is irreversible and your current settings will be overwritten.": "Отменить это действие невозможно. Ваши текущие настройки будут перезаписаны.", | |
| 1934 | + "Preset deleted": "Пресет удалён", | |
| 1935 | + "Template deleted": "Шаблон удалён", | |
| 1936 | + "Template was not deleted from server": "Шаблон не удалён с сервера", | |
| 1937 | + "Cannot restore GUI preset": "Пресет для Gui восстановить нельзя", | |
| 1938 | + "Default preset cannot be restored": "Невозможно восстановить пресет по умолчанию", | |
| 1939 | + "Default template cannot be restored": "Невозможно восстановить шаблон по умолчанию", | |
| 1940 | + "Resetting a <b>default preset</b> will restore the default settings": "Сброс <b>стандартного пресета</b> восстановит настройки по умолчанию.", | |
| 1941 | + "Resetting a <b>default template</b> will restore the default settings.": "Сброс <b>стандартного шаблона</b> восстановит настройки по умолчанию.", | |
| 1942 | + "Are you sure?": "Вы уверены?", | |
| 1943 | + "Default preset restored": "Стандартный пресет восстановлен", | |
| 1944 | + "Default template restored": "Стандартный шаблон восстановлен", | |
| 1945 | + "Resetting a <b>custom preset</b> will restore to the last saved state.": "Сброс <b>пользовательского пресета</b> откатит его к последнему сохранённому состоянию.", | |
| 1946 | + "Resetting a <b>custom template</b> will restore to the last saved state.": "Сброс <b>пользовательского шаблона</b> откатит его к последнему сохранённому состоянию.", | |
| 1947 | + "Preset restored": "Пресет восстановлен", | |
| 1948 | + "Template restored": "Шаблон восстановлен", | |
| 1949 | + "Update current template": "Сохранить шаблон", | |
| 1950 | + "Rename current template": "Переименовать шаблон", | |
| 1951 | + "Save template as": "Сохранить как...", | |
| 1952 | + "Restore current template": "Восстановить шаблон", | |
| 1953 | + "Delete the template": "Удалить шаблон", | |
| 1954 | + "Rename current prompt": "Переименовать промпт", | |
| 1955 | + "Select your current Context Template": "Выберите активный шаблон контекста", | |
| 1956 | + "Select your current Instruct Template": "Выберите активный шаблон Instruct-режима", | |
| 1957 | + "and connect to an": "и подключитесь к", | |
| 1958 | + "You can add more": "Можете добавить больше", | |
| 1959 | + "from other websites": "с других сайтов.", | |
| 1960 | + "Go to the": "Загляните в", | |
| 1961 | + "to install additional features.": ", чтобы установить разные дополнительные ресурсы.", | |
| 1962 | + "or_welcome": "; также доступен" | |
| 1897 | 1963 | } |
| @@ -6755,7 +6755,7 @@ export async function saveSettings(type) { | ||
| 6755 | 6755 | eventSource.emit(event_types.SETTINGS_UPDATED); |
| 6756 | 6756 | }, |
| 6757 | 6757 | error: function (jqXHR, exception) { |
| 6758 | 6758 | toastr.error(t`Check the server connection and reload the page to prevent data loss.t`, t`Settings could not be saved`); |
| 6759 | 6759 | console.log(exception); |
| 6760 | 6760 | console.log(jqXHR); |
| 6761 | 6761 | }, |
| @@ -34,6 +34,7 @@ import { | ||
| 34 | 34 | textgenerationwebui_settings as textgen_settings, |
| 35 | 35 | } from './textgen-settings.js'; |
| 36 | 36 | import { download, parseJsonFile, waitUntilCondition } from './utils.js'; |
| 37 | +import { t } from './i18n.js'; | |
| 37 | 38 | |
| 38 | 39 | const presetManagers = {}; |
| 39 | 40 | |
| @@ -194,32 +195,32 @@ class PresetManager { | ||
| 194 | 195 | */ |
| 195 | 196 | static async performMasterImport(data, fileName) { |
| 196 | 197 | if (!data || typeof data !== 'object') { |
| 197 | 198 | toastr.error('t`Invalid data provided for master import'`); |
| 198 | 199 | return; |
| 199 | 200 | } |
| 200 | 201 | |
| 201 | 202 | // Check for legacy file imports |
| 202 | 203 | // 1. Instruct Template |
| 203 | 204 | if (this.isPossiblyInstructData(data)) { |
| 204 | 205 | toastr.info('t`Importing instruct template...'`, 't`Instruct template detected'`); |
| 205 | 206 | return await getPresetManager('instruct').savePreset(data.name, data); |
| 206 | 207 | } |
| 207 | 208 | |
| 208 | 209 | // 2. Context Template |
| 209 | 210 | if (this.isPossiblyContextData(data)) { |
| 210 | 211 | toastr.info('t`Importing as context template...'`, 't`Context template detected'`); |
| 211 | 212 | return await getPresetManager('context').savePreset(data.name, data); |
| 212 | 213 | } |
| 213 | 214 | |
| 214 | 215 | // 3. System Prompt |
| 215 | 216 | if (this.isPossiblySystemPromptData(data)) { |
| 216 | 217 | toastr.info('t`Importing as system prompt...'`, 't`System prompt detected'`); |
| 217 | 218 | return await getPresetManager('sysprompt').savePreset(data.name, data); |
| 218 | 219 | } |
| 219 | 220 | |
| 220 | 221 | // 4. Text Completion settings |
| 221 | 222 | if (this.isPossiblyTextCompletionData(data)) { |
| 222 | 223 | toastr.info('t`Importing as settings preset...'`, 't`Text Completion settings detected'`); |
| 223 | 224 | return await getPresetManager('textgenerationwebui').savePreset(fileName, data); |
| 224 | 225 | } |
| 225 | 226 | |
| @@ -231,7 +232,7 @@ class PresetManager { | ||
| 231 | 232 | } |
| 232 | 233 | |
| 233 | 234 | if (validSections.length === 0) { |
| 234 | 235 | toastr.error('t`No valid sections found in imported data'`); |
| 235 | 236 | return; |
| 236 | 237 | } |
| 237 | 238 | |
| @@ -242,8 +243,8 @@ class PresetManager { | ||
| 242 | 243 | |
| 243 | 244 | const html = $(await renderTemplateAsync('masterImport', { sections: sectionNames })); |
| 244 | 245 | const popup = new Popup(html, POPUP_TYPE.CONFIRM, '', { |
| 245 | 246 | okButton: 't`Import'`, |
| 246 | 247 | cancelButton: 't`Cancel'`, |
| 247 | 248 | }); |
| 248 | 249 | |
| 249 | 250 | const result = await popup.show(); |
| @@ -257,7 +258,7 @@ class PresetManager { | ||
| 257 | 258 | const confirmedSections = html.find('input:checked').map((_, el) => el instanceof HTMLInputElement && el.value).get(); |
| 258 | 259 | |
| 259 | 260 | if (confirmedSections.length === 0) { |
| 260 | 261 | toastr.info('t`No sections selected for import'`); |
| 261 | 262 | return; |
| 262 | 263 | } |
| 263 | 264 | |
| @@ -270,7 +271,7 @@ class PresetManager { | ||
| 270 | 271 | } |
| 271 | 272 | } |
| 272 | 273 | |
| 273 | 274 | toastr.success(t`Imported ${importedSections.length} settings: ${importedSections.join(', ')}`); |
| 274 | 275 | } |
| 275 | 276 | |
| 276 | 277 | /** |
| @@ -285,8 +286,8 @@ class PresetManager { | ||
| 285 | 286 | const html = $(await renderTemplateAsync('masterExport', { sections: sectionNames })); |
| 286 | 287 | |
| 287 | 288 | const popup = new Popup(html, POPUP_TYPE.CONFIRM, '', { |
| 288 | 289 | okButton: 't`Export'`, |
| 289 | 290 | cancelButton: 't`Cancel'`, |
| 290 | 291 | }); |
| 291 | 292 | |
| 292 | 293 | const result = await popup.show(); |
| @@ -300,7 +301,7 @@ class PresetManager { | ||
| 300 | 301 | const data = {}; |
| 301 | 302 | |
| 302 | 303 | if (confirmedSections.length === 0) { |
| 303 | 304 | toastr.info('t`No sections selected for export'`); |
| 304 | 305 | return; |
| 305 | 306 | } |
| 306 | 307 | |
| @@ -366,21 +367,21 @@ class PresetManager { | ||
| 366 | 367 | console.log(selected); |
| 367 | 368 | |
| 368 | 369 | if (selected.val() == 'gui') { |
| 369 | 370 | toastr.info('t`Cannot update GUI preset'`); |
| 370 | 371 | return; |
| 371 | 372 | } |
| 372 | 373 | |
| 373 | 374 | const name = selected.text(); |
| 374 | 375 | await this.savePreset(name); |
| 375 | 376 | |
| 376 | 377 | const successToast = !this.isAdvancedFormatting() ? 't`Preset updated'` : 't`Template updated'`; |
| 377 | 378 | toastr.success(successToast); |
| 378 | 379 | } |
| 379 | 380 | |
| 380 | 381 | async savePresetAs() { |
| 381 | 382 | const inputValue = this.getSelectedPresetName(); |
| 382 | 383 | const popupText = !this.isAdvancedFormatting() ? '<h4>' + t`Hint: Use a character/group name to bind preset to a specific chat.` + '</h4>' : ''; |
| 383 | 384 | const headerText = !this.isAdvancedFormatting() ? 't`Preset name:'` : 't`Template name:'`; |
| 384 | 385 | const name = await Popup.show.input(headerText, popupText, inputValue); |
| 385 | 386 | if (!name) { |
| 386 | 387 | console.log('Preset name not provided'); |
| @@ -389,7 +390,7 @@ class PresetManager { | ||
| 389 | 390 | |
| 390 | 391 | await this.savePreset(name); |
| 391 | 392 | |
| 392 | 393 | const successToast = !this.isAdvancedFormatting() ? 't`Preset saved'` : 't`Template saved'`; |
| 393 | 394 | toastr.success(successToast); |
| 394 | 395 | } |
| 395 | 396 | |
| @@ -411,7 +412,7 @@ class PresetManager { | ||
| 411 | 412 | }); |
| 412 | 413 | |
| 413 | 414 | if (!response.ok) { |
| 414 | 415 | toastr.error('t`Check the server connection and reload the page to prevent data loss.'`, 't`Preset could not be saved'`); |
| 415 | 416 | console.error('Preset could not be saved', response); |
| 416 | 417 | throw new Error('Preset could not be saved'); |
| 417 | 418 | } |
| @@ -422,6 +423,19 @@ class PresetManager { | ||
| 422 | 423 | this.updateList(name, preset); |
| 423 | 424 | } |
| 424 | 425 | |
| 426 | + async renamePreset(newName) { | |
| 427 | + const oldName = this.getSelectedPresetName(); | |
| 428 | + try { | |
| 429 | + await this.savePreset(newName); | |
| 430 | + await this.deletePreset(oldName); | |
| 431 | + } catch (error) { | |
| 432 | + toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Preset could not be renamed`); | |
| 433 | + console.error('Preset could not be renamed', error); | |
| 434 | + throw new Error('Preset could not be renamed'); | |
| 435 | + } | |
| 436 | + | |
| 437 | + } | |
| 438 | + | |
| 425 | 439 | getPresetList() { |
| 426 | 440 | let presets = []; |
| 427 | 441 | let preset_names = {}; |
| @@ -585,13 +599,14 @@ class PresetManager { | ||
| 585 | 599 | return settings; |
| 586 | 600 | } |
| 587 | 601 | |
| 588 | - async deleteCurrentPreset() { | |
| 602 | + // pass no arguments to delete current preset | |
| 603 | + async deletePreset(name) { | |
| 589 | 604 | const { preset_names, presets } = this.getPresetList(); |
| 590 | - const value = this.getSelectedPreset(); | |
| 605 | + const value = name ? (this.isKeyedApi() ? this.findPreset(name) : name) : this.getSelectedPreset(); | |
| 591 | 606 | const nameToDelete = name || this.getSelectedPresetName(); |
| 592 | 607 | |
| 593 | 608 | if (value == 'gui') { |
| 594 | 609 | toastr.info('t`Cannot delete GUI preset'`); |
| 595 | 610 | return; |
| 596 | 611 | } |
| 597 | 612 | |
| @@ -605,7 +620,10 @@ class PresetManager { | ||
| 605 | 620 | delete preset_names[nameToDelete]; |
| 606 | 621 | } |
| 607 | 622 | |
| 608 | - if (Object.keys(preset_names).length) { | |
| 623 | + // switch in UI only when deleting currently selected preset | |
| 624 | + const switchPresets = !name || this.getSelectedPresetName() == name; | |
| 625 | + | |
| 626 | + if (Object.keys(preset_names).length && switchPresets) { | |
| 609 | 627 | const nextPresetName = Object.keys(preset_names)[0]; |
| 610 | 628 | const newValue = preset_names[nextPresetName]; |
| 611 | 629 | $(this.select).find(`option[value="${newValue}"]`).attr('selected', 'true'); |
| @@ -629,7 +647,7 @@ class PresetManager { | ||
| 629 | 647 | }); |
| 630 | 648 | |
| 631 | 649 | if (!response.ok) { |
| 632 | 650 | const errorToast = !this.isAdvancedFormatting() ? 't`Failed to restore default preset'` : 't`Failed to restore default template'`; |
| 633 | 651 | toastr.error(errorToast); |
| 634 | 652 | return; |
| 635 | 653 | } |
| @@ -721,7 +739,8 @@ async function waitForConnection() { | ||
| 721 | 739 | export async function initPresetManager() { |
| 722 | 740 | eventSource.on(event_types.CHAT_CHANGED, autoSelectPreset); |
| 723 | 741 | registerPresetManagers(); |
| 724 | 742 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'preset', |
| 743 | + name: 'preset', | |
| 725 | 744 | callback: presetCommandCallback, |
| 726 | 745 | returns: 'current preset', |
| 727 | 746 | unnamedArgumentList: [ |
| @@ -774,6 +793,29 @@ export async function initPresetManager() { | ||
| 774 | 793 | await presetManager.savePresetAs(); |
| 775 | 794 | }); |
| 776 | 795 | |
| 796 | + $(document).on('click', '[data-preset-manager-rename]', async function () { | |
| 797 | + const apiId = $(this).data('preset-manager-rename'); | |
| 798 | + const presetManager = getPresetManager(apiId); | |
| 799 | + | |
| 800 | + if (!presetManager) { | |
| 801 | + console.warn(`Preset Manager not found for API: ${apiId}`); | |
| 802 | + return; | |
| 803 | + } | |
| 804 | + | |
| 805 | + const popupHeader = !presetManager.isAdvancedFormatting() ? t`Rename preset` : t`Rename template`; | |
| 806 | + const oldName = presetManager.getSelectedPresetName(); | |
| 807 | + const newName = await Popup.show.input(popupHeader, t`Enter a new name:`, oldName); | |
| 808 | + if (!newName || oldName === newName) { | |
| 809 | + console.debug(!presetManager.isAdvancedFormatting() ? 'Preset rename cancelled' : 'Template rename cancelled'); | |
| 810 | + return; | |
| 811 | + } | |
| 812 | + | |
| 813 | + await presetManager.renamePreset(newName); | |
| 814 | + | |
| 815 | + const successToast = !presetManager.isAdvancedFormatting() ? t`Preset renamed` : t`Template renamed`; | |
| 816 | + toastr.success(successToast); | |
| 817 | + }); | |
| 818 | + | |
| 777 | 819 | $(document).on('click', '[data-preset-manager-export]', async function () { |
| 778 | 820 | const apiId = $(this).data('preset-manager-export'); |
| 779 | 821 | const presetManager = getPresetManager(apiId); |
| @@ -816,7 +858,7 @@ export async function initPresetManager() { | ||
| 816 | 858 | data['name'] = name; |
| 817 | 859 | |
| 818 | 860 | await presetManager.savePreset(name, data); |
| 819 | 861 | const successToast = !presetManager.isAdvancedFormatting() ? 't`Preset imported'` : 't`Template imported'`; |
| 820 | 862 | toastr.success(successToast); |
| 821 | 863 | e.target.value = null; |
| 822 | 864 | }); |
| @@ -830,19 +872,19 @@ export async function initPresetManager() { | ||
| 830 | 872 | return; |
| 831 | 873 | } |
| 832 | 874 | |
| 833 | 875 | const headerText = !presetManager.isAdvancedFormatting() ? 't`Delete this preset?'` : 't`Delete this template?'`; |
| 834 | 876 | const confirm = await Popup.show.confirm(headerText, 't`This action is irreversible and your current settings will be overwritten.'`); |
| 835 | 877 | if (!confirm) { |
| 836 | 878 | return; |
| 837 | 879 | } |
| 838 | 880 | |
| 839 | 881 | const result = await presetManager.deleteCurrentPresetdeletePreset(); |
| 840 | 882 | |
| 841 | 883 | if (result) { |
| 842 | 884 | const successToast = !presetManager.isAdvancedFormatting() ? 't`Preset deleted'` : 't`Template deleted'`; |
| 843 | 885 | toastr.success(successToast); |
| 844 | 886 | } else { |
| 845 | 887 | const warningToast = !presetManager.isAdvancedFormatting() ? 't`Preset was not deleted from server'` : 't`Template was not deleted from server'`; |
| 846 | 888 | toastr.warning(warningToast); |
| 847 | 889 | } |
| 848 | 890 | |
| @@ -862,7 +904,7 @@ export async function initPresetManager() { | ||
| 862 | 904 | const data = await presetManager.getDefaultPreset(name); |
| 863 | 905 | |
| 864 | 906 | if (name == 'gui') { |
| 865 | 907 | toastr.info('t`Cannot restore GUI preset'`); |
| 866 | 908 | return; |
| 867 | 909 | } |
| 868 | 910 | |
| @@ -872,37 +914,37 @@ export async function initPresetManager() { | ||
| 872 | 914 | |
| 873 | 915 | if (data.isDefault) { |
| 874 | 916 | if (Object.keys(data.preset).length === 0) { |
| 875 | 917 | const errorToast = !presetManager.isAdvancedFormatting() ? 't`Default preset cannot be restored'` : 't`Default template cannot be restored'`; |
| 876 | 918 | toastr.error(errorToast); |
| 877 | 919 | return; |
| 878 | 920 | } |
| 879 | 921 | |
| 880 | 922 | const confirmText = !presetManager.isAdvancedFormatting() |
| 881 | 923 | ? 't`Resetting a <b>default preset</b> will restore the default settings.'` |
| 882 | 924 | : 't`Resetting a <b>default template</b> will restore the default settings.'`; |
| 883 | 925 | const confirm = await Popup.show.confirm('t`Are you sure?'`, confirmText); |
| 884 | 926 | if (!confirm) { |
| 885 | 927 | return; |
| 886 | 928 | } |
| 887 | 929 | |
| 888 | 930 | await presetManager.deleteCurrentPresetdeletePreset(); |
| 889 | 931 | await presetManager.savePreset(name, data.preset); |
| 890 | 932 | const option = presetManager.findPreset(name); |
| 891 | 933 | presetManager.selectPreset(option); |
| 892 | 934 | const successToast = !presetManager.isAdvancedFormatting() ? 't`Default preset restored'` : 't`Default template restored'`; |
| 893 | 935 | toastr.success(successToast); |
| 894 | 936 | } else { |
| 895 | 937 | const confirmText = !presetManager.isAdvancedFormatting() |
| 896 | 938 | ? 't`Resetting a <b>custom preset</b> will restore to the last saved state.'` |
| 897 | 939 | : 't`Resetting a <b>custom template</b> will restore to the last saved state.'`; |
| 898 | 940 | const confirm = await Popup.show.confirm('t`Are you sure?'`, confirmText); |
| 899 | 941 | if (!confirm) { |
| 900 | 942 | return; |
| 901 | 943 | } |
| 902 | 944 | |
| 903 | 945 | const option = presetManager.findPreset(name); |
| 904 | 946 | presetManager.selectPreset(option); |
| 905 | 947 | const successToast = !presetManager.isAdvancedFormatting() ? 't`Preset restored'` : 't`Template restored'`; |
| 906 | 948 | toastr.success(successToast); |
| 907 | 949 | } |
| 908 | 950 | }); |
| @@ -10,7 +10,7 @@ | ||
| 10 | 10 | <span data-i18n="Click _space">Click </span> |
| 11 | 11 | <button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="sys-settings-button"> |
| 12 | 12 | <i class="fa-solid fa-plug"></i> |
| 13 | 13 | <span data-i18n="[title]API Connections">API Connections</span> |
| 14 | 14 | </button> |
| 15 | 15 | <span data-i18n="and connect to an">and connect to an</span> |
| 16 | 16 | <a href="https://docs.sillytavern.app/usage/api-connections/" target="_blank"> |
| @@ -21,7 +21,7 @@ | ||
| 21 | 21 | <span data-i18n="Click _space">Click </span> |
| 22 | 22 | <button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="rightNavHolder"> |
| 23 | 23 | <i class="fa-solid fa-address-card"></i> |
| 24 | 24 | <span data-i18n="[title]Character Management">Character Management</span> |
| 25 | 25 | </button> |
| 26 | 26 | <span data-i18n="and pick a character."> and pick a character.</span> |
| 27 | 27 | </li> |
| @@ -33,7 +33,7 @@ | ||
| 33 | 33 | <i class="fa-solid fa-image-portrait"></i> |
| 34 | 34 | <span data-i18n="Sample characters">Sample characters</span> |
| 35 | 35 | </button> |
| 36 | 36 | <span data-i18n="oror_welcome">or</span> |
| 37 | 37 | <button class="external_import_button menu_button menu_button_icon inline-flex"> |
| 38 | 38 | <i class="fa-solid fa-cloud-arrow-down"></i> |
| 39 | 39 | <span data-i18n="Import Characters">Import characters</span> |
| @@ -48,7 +48,7 @@ | ||
| 48 | 48 | |
| 49 | 49 | <button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="extensions-settings-button"> |
| 50 | 50 | <i class="fa-solid fa-cubes"></i> |
| 51 | 51 | <span data-i18n="[title]Extensions">Extensions</span> |
| 52 | 52 | </button> |
| 53 | 53 | |
| 54 | 54 | <span data-i18n="to install additional features.">to install additional features.</span> |