mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-06-09 20:39:25 -03:00
feat(doctor): improve duplicate filename conflict UX with confirm modal, syntax-format nav, and i18n
- Remove [LoRAs] prefix noise from conflict detail display - Limit inline conflict groups to 5, show remainder count - Add 'Switch to Full Path Syntax' action in conflict card - Add confirmation modal before resolving conflicts (shows rename strategy) - Register resolveFilenameConflictsModal in ModalManager (fix no-op showModal) - Switch to Interface section and add highlight animation on syntax-format nav - Sync and translate conflictConfirm strings across all 10 locales
This commit is contained in:
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "Auflösung der Dateinamenskonflikte fehlgeschlagen: {message}"
|
"conflictsResolveFailed": "Auflösung der Dateinamenskonflikte fehlgeschlagen: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "Dateinamenskonflikte auflösen",
|
||||||
|
"message": "Umbenennen durch Anhängen eines 4-stelligen Hashs an jeden doppelten Dateinamen.",
|
||||||
|
"note": "Dieser Vorgang benennt Dateien auf der Festplatte um. Modellreferenzen in vorhandenen Workflows müssen möglicherweise aktualisiert werden, wenn Sie das A1111-Syntaxformat verwenden.",
|
||||||
|
"confirm": "Dateien umbenennen",
|
||||||
|
"cancel": "Abbrechen"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "Anwendungs-Update erkannt",
|
"title": "Anwendungs-Update erkannt",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "Failed to resolve filename conflicts: {message}"
|
"conflictsResolveFailed": "Failed to resolve filename conflicts: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "Resolve Filename Conflicts",
|
||||||
|
"message": "Renaming by appending a 4-character hash to each duplicate filename.",
|
||||||
|
"note": "This operation renames files on disk. Model references in existing workflows may need updating if you use the A1111 syntax format.",
|
||||||
|
"confirm": "Rename Files",
|
||||||
|
"cancel": "Cancel"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "Application Update Detected",
|
"title": "Application Update Detected",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "Error al resolver conflictos de nombre de archivo: {message}"
|
"conflictsResolveFailed": "Error al resolver conflictos de nombre de archivo: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "Resolver conflictos de nombres de archivo",
|
||||||
|
"message": "Renombrar añadiendo un hash de 4 caracteres a cada nombre de archivo duplicado.",
|
||||||
|
"note": "Esta operación renombra archivos en el disco. Es posible que las referencias a modelos en flujos de trabajo existentes deban actualizarse si usas el formato de sintaxis A1111.",
|
||||||
|
"confirm": "Renombrar archivos",
|
||||||
|
"cancel": "Cancelar"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "Actualización de la aplicación detectada",
|
"title": "Actualización de la aplicación detectada",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "Échec de la résolution des conflits de nom de fichier : {message}"
|
"conflictsResolveFailed": "Échec de la résolution des conflits de nom de fichier : {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "Résoudre les conflits de noms de fichiers",
|
||||||
|
"message": "Renommer en ajoutant un hachage de 4 caractères à chaque nom de fichier en double.",
|
||||||
|
"note": "Cette opération renomme les fichiers sur le disque. Les références de modèle dans les workflows existants peuvent nécessiter une mise à jour si vous utilisez le format de syntaxe A1111.",
|
||||||
|
"confirm": "Renommer les fichiers",
|
||||||
|
"cancel": "Annuler"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "Mise à jour de l'application détectée",
|
"title": "Mise à jour de l'application détectée",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "פתרון התנגשויות שמות קבצים נכשל: {message}"
|
"conflictsResolveFailed": "פתרון התנגשויות שמות קבצים נכשל: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "פתור התנגשויות בשמות קבצים",
|
||||||
|
"message": "שינוי שם על ידי הוספת האש באורך 4 תווים לכל שם קובץ כפול.",
|
||||||
|
"note": "פעולה זו משנה שמות של קבצים בדיסק. ייתכן שיהיה צורך לעדכן הפניות למודלים בזרימות עבודה קיימות אם אתה משתמש בפורמט התחביר A1111.",
|
||||||
|
"confirm": "שנה שמות קבצים",
|
||||||
|
"cancel": "ביטול"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "זוהה עדכון יישום",
|
"title": "זוהה עדכון יישום",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "ファイル名競合の解決に失敗しました: {message}"
|
"conflictsResolveFailed": "ファイル名競合の解決に失敗しました: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "ファイル名の競合を解決",
|
||||||
|
"message": "重複したファイル名に4文字のハッシュを追加してリネームします。",
|
||||||
|
"note": "この操作はディスク上のファイルをリネームします。A1111 構文形式を使用している場合、既存のワークフロー内のモデル参照を更新する必要があるかもしれません。",
|
||||||
|
"confirm": "ファイルをリネーム",
|
||||||
|
"cancel": "キャンセル"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "アプリケーション更新が検出されました",
|
"title": "アプリケーション更新が検出されました",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "파일명 충돌 해결 실패: {message}"
|
"conflictsResolveFailed": "파일명 충돌 해결 실패: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "파일명 충돌 해결",
|
||||||
|
"message": "중복 파일명에 4자리 해시를 추가하여 이름을 변경합니다.",
|
||||||
|
"note": "이 작업은 디스크에 있는 파일의 이름을 변경합니다. A1111 구문 형식을 사용하는 경우 기존 워크플로우의 모델 참조를 업데이트해야 할 수 있습니다.",
|
||||||
|
"confirm": "파일 이름 변경",
|
||||||
|
"cancel": "취소"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "애플리케이션 업데이트 감지",
|
"title": "애플리케이션 업데이트 감지",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "Не удалось разрешить конфликты имён файлов: {message}"
|
"conflictsResolveFailed": "Не удалось разрешить конфликты имён файлов: {message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "Разрешить конфликты имён файлов",
|
||||||
|
"message": "Переименование с добавлением 4-символьного хеша к каждому дублирующемуся имени файла.",
|
||||||
|
"note": "Эта операция переименовывает файлы на диске. Если вы используете синтаксис A1111, ссылки на модели в существующих рабочих процессах могут потребовать обновления.",
|
||||||
|
"confirm": "Переименовать файлы",
|
||||||
|
"cancel": "Отмена"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "Обнаружено обновление приложения",
|
"title": "Обнаружено обновление приложения",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "解决文件名冲突失败:{message}"
|
"conflictsResolveFailed": "解决文件名冲突失败:{message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "解决文件名冲突",
|
||||||
|
"message": "通过在每个重复文件名后附加 4 位哈希值来重命名文件。",
|
||||||
|
"note": "此操作会重命名磁盘上的文件。如果使用 A1111 语法格式,现有工作流中的模型引用可能需要更新。",
|
||||||
|
"confirm": "重命名文件",
|
||||||
|
"cancel": "取消"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "检测到应用更新",
|
"title": "检测到应用更新",
|
||||||
|
|||||||
@@ -1941,6 +1941,13 @@
|
|||||||
"conflictsResolveFailed": "解決檔案名稱衝突失敗:{message}"
|
"conflictsResolveFailed": "解決檔案名稱衝突失敗:{message}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conflictConfirm": {
|
||||||
|
"title": "解決檔案名稱衝突",
|
||||||
|
"message": "通過在每個重複檔案名稱後附加 4 位元哈希值來重新命名檔案。",
|
||||||
|
"note": "此操作會重新命名磁碟上的檔案。如果使用 A1111 語法格式,現有工作流程中的模型參考可能需要更新。",
|
||||||
|
"confirm": "重新命名檔案",
|
||||||
|
"cancel": "取消"
|
||||||
|
},
|
||||||
"banners": {
|
"banners": {
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"title": "偵測到應用程式更新",
|
"title": "偵測到應用程式更新",
|
||||||
|
|||||||
@@ -1063,12 +1063,22 @@ class DoctorHandler:
|
|||||||
"total_conflict_files": total_conflict_files,
|
"total_conflict_files": total_conflict_files,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
for conflict in all_conflicts:
|
|
||||||
|
# Show at most 5 conflict groups inline; note any remainder.
|
||||||
|
MAX_VISIBLE_CONFLICTS = 5
|
||||||
|
visible_conflicts = all_conflicts[:MAX_VISIBLE_CONFLICTS]
|
||||||
|
for conflict in visible_conflicts:
|
||||||
details.append(
|
details.append(
|
||||||
f"[{conflict['label']}] '{conflict['filename']}' "
|
f"'{conflict['filename']}' "
|
||||||
f"found in {len(conflict['paths'])} locations"
|
f"found in {len(conflict['paths'])} locations"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
hidden_count = len(all_conflicts) - MAX_VISIBLE_CONFLICTS
|
||||||
|
if hidden_count > 0:
|
||||||
|
details.append(
|
||||||
|
f"...and {hidden_count} more duplicate filename group(s)"
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": "filename_conflicts",
|
"id": "filename_conflicts",
|
||||||
"title": "Duplicate Filename Conflicts",
|
"title": "Duplicate Filename Conflicts",
|
||||||
@@ -1079,7 +1089,11 @@ class DoctorHandler:
|
|||||||
{
|
{
|
||||||
"id": "resolve-filename-conflicts",
|
"id": "resolve-filename-conflicts",
|
||||||
"label": "Resolve Conflicts",
|
"label": "Resolve Conflicts",
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"id": "open-settings-syntax-format",
|
||||||
|
"label": "Switch to Full Path Syntax",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,39 @@
|
|||||||
animation: modalFadeIn 0.2s ease-out;
|
animation: modalFadeIn 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#resolveFilenameConflictsModal .confirmation-message {
|
||||||
|
color: var(--text-color);
|
||||||
|
margin: var(--space-2) 0;
|
||||||
|
font-size: 1em;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#resolveFilenameConflictsModal .resolve-conflicts-detail {
|
||||||
|
color: var(--text-color);
|
||||||
|
margin: var(--space-2) 0;
|
||||||
|
font-size: 0.95em;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#resolveFilenameConflictsModal .resolve-conflicts-detail code {
|
||||||
|
background: var(--lora-surface);
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: monospace;
|
||||||
|
border: 1px solid var(--lora-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
#resolveFilenameConflictsModal .resolve-conflicts-impact {
|
||||||
|
background: var(--lora-surface);
|
||||||
|
border: 1px solid var(--lora-border);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
padding: var(--space-2);
|
||||||
|
margin: var(--space-2) 0;
|
||||||
|
color: var(--text-color);
|
||||||
|
text-align: left;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
.delete-model-info,
|
.delete-model-info,
|
||||||
.exclude-model-info {
|
.exclude-model-info {
|
||||||
/* Update info display styling */
|
/* Update info display styling */
|
||||||
|
|||||||
@@ -1369,3 +1369,14 @@ input:checked + .toggle-slider:before {
|
|||||||
background: var(--lora-error);
|
background: var(--lora-error);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Highlight animation for setting items targeted from Doctor actions */
|
||||||
|
@keyframes settings-highlight-pulse {
|
||||||
|
0%, 100% { box-shadow: 0 0 0 0 rgba(from var(--lora-accent) r g b / 0.4); }
|
||||||
|
50% { box-shadow: 0 0 0 4px rgba(from var(--lora-accent) r g b / 0.2); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-setting-highlight {
|
||||||
|
animation: settings-highlight-pulse 1.5s ease-in-out 3;
|
||||||
|
border-radius: var(--border-radius-xs);
|
||||||
|
}
|
||||||
|
|||||||
@@ -324,11 +324,42 @@ export class DoctorManager {
|
|||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
break;
|
break;
|
||||||
|
case 'open-settings-syntax-format':
|
||||||
|
modalManager.showModal('settingsModal');
|
||||||
|
window.setTimeout(() => {
|
||||||
|
// Switch to Interface section
|
||||||
|
document.querySelectorAll('.settings-section').forEach((s) => s.classList.remove('active'));
|
||||||
|
const interfaceSection = document.getElementById('section-interface');
|
||||||
|
if (interfaceSection) {
|
||||||
|
interfaceSection.classList.add('active');
|
||||||
|
}
|
||||||
|
document.querySelectorAll('.settings-nav-item').forEach((n) => n.classList.remove('active'));
|
||||||
|
const interfaceNav = document.querySelector('.settings-nav-item[data-section="interface"]');
|
||||||
|
if (interfaceNav) {
|
||||||
|
interfaceNav.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Focus and scroll to the LoRA Syntax Format dropdown
|
||||||
|
const select = document.getElementById('loraSyntaxFormat');
|
||||||
|
if (select) {
|
||||||
|
select.focus();
|
||||||
|
select.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
// Add temporary highlight animation
|
||||||
|
const settingItem = select.closest('.setting-item');
|
||||||
|
if (settingItem) {
|
||||||
|
settingItem.classList.add('settings-setting-highlight');
|
||||||
|
setTimeout(() => {
|
||||||
|
settingItem.classList.remove('settings-setting-highlight');
|
||||||
|
}, 4500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
break;
|
||||||
case 'repair-cache':
|
case 'repair-cache':
|
||||||
await this.repairCache();
|
await this.repairCache();
|
||||||
break;
|
break;
|
||||||
case 'resolve-filename-conflicts':
|
case 'resolve-filename-conflicts':
|
||||||
await this.resolveFilenameConflicts();
|
await this.promptResolveConflicts();
|
||||||
break;
|
break;
|
||||||
case 'reload-page':
|
case 'reload-page':
|
||||||
this.reloadUi();
|
this.reloadUi();
|
||||||
@@ -358,6 +389,62 @@ export class DoctorManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getConflictStats() {
|
||||||
|
const conflict = (this.lastDiagnostics?.diagnostics || []).find(
|
||||||
|
(d) => d.id === 'filename_conflicts'
|
||||||
|
);
|
||||||
|
if (!conflict || !Array.isArray(conflict.details)) {
|
||||||
|
return { groups: 0, files: 0 };
|
||||||
|
}
|
||||||
|
const summary = conflict.details.find(
|
||||||
|
(d) => d && typeof d === 'object' && d.conflict_groups !== undefined
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
groups: summary?.conflict_groups || 0,
|
||||||
|
files: summary?.total_conflict_files || 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async promptResolveConflicts() {
|
||||||
|
const stats = this._getConflictStats();
|
||||||
|
if (stats.groups === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailEl = document.getElementById('resolveConflictsDetail');
|
||||||
|
if (detailEl) {
|
||||||
|
detailEl.innerHTML = translate(
|
||||||
|
'conflictConfirm.detail',
|
||||||
|
{},
|
||||||
|
'Example: <code>Add_Details_v1.2</code> \u2192 <code>Add_Details_v1.2-a3f7</code>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const impactEl = document.getElementById('resolveConflictsImpact');
|
||||||
|
if (impactEl) {
|
||||||
|
impactEl.innerHTML = translate(
|
||||||
|
'conflictConfirm.impact',
|
||||||
|
{ count: stats.files, groups: stats.groups },
|
||||||
|
`Will rename <strong>${stats.files}</strong> file(s) across <strong>${stats.groups}</strong> duplicate group(s).`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._confirmResolveResolve = null;
|
||||||
|
modalManager.showModal('resolveFilenameConflictsModal');
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this._confirmResolveResolve = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async confirmResolveConflicts() {
|
||||||
|
modalManager.closeModal('resolveFilenameConflictsModal');
|
||||||
|
if (this._confirmResolveResolve) {
|
||||||
|
this._confirmResolveResolve(true);
|
||||||
|
this._confirmResolveResolve = null;
|
||||||
|
}
|
||||||
|
await this.resolveFilenameConflicts();
|
||||||
|
}
|
||||||
|
|
||||||
async resolveFilenameConflicts() {
|
async resolveFilenameConflicts() {
|
||||||
try {
|
try {
|
||||||
this.setLoading(true);
|
this.setLoading(true);
|
||||||
@@ -449,3 +536,8 @@ export class DoctorManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const doctorManager = new DoctorManager();
|
export const doctorManager = new DoctorManager();
|
||||||
|
|
||||||
|
// Make available globally for HTML onclick handlers
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
window.doctorManager = doctorManager;
|
||||||
|
}
|
||||||
|
|||||||
@@ -316,6 +316,19 @@ export class ModalManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register resolveFilenameConflictsModal
|
||||||
|
const resolveFilenameConflictsModal = document.getElementById('resolveFilenameConflictsModal');
|
||||||
|
if (resolveFilenameConflictsModal) {
|
||||||
|
this.registerModal('resolveFilenameConflictsModal', {
|
||||||
|
element: resolveFilenameConflictsModal,
|
||||||
|
onClose: () => {
|
||||||
|
this.getModal('resolveFilenameConflictsModal').element.classList.remove('show');
|
||||||
|
document.body.classList.remove('modal-open');
|
||||||
|
},
|
||||||
|
closeOnOutsideClick: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('keydown', this.boundHandleEscape);
|
document.addEventListener('keydown', this.boundHandleEscape);
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
@@ -396,7 +409,8 @@ export class ModalManager {
|
|||||||
id === "modelDuplicateDeleteModal" ||
|
id === "modelDuplicateDeleteModal" ||
|
||||||
id === "clearCacheModal" ||
|
id === "clearCacheModal" ||
|
||||||
id === "bulkDeleteModal" ||
|
id === "bulkDeleteModal" ||
|
||||||
id === "checkUpdatesConfirmModal"
|
id === "checkUpdatesConfirmModal" ||
|
||||||
|
id === "resolveFilenameConflictsModal"
|
||||||
) {
|
) {
|
||||||
modal.element.classList.add("show");
|
modal.element.classList.add("show");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -108,4 +108,21 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Resolve Filename Conflicts Confirmation Modal -->
|
||||||
|
<div id="resolveFilenameConflictsModal" class="modal delete-modal">
|
||||||
|
<div class="modal-content delete-modal-content">
|
||||||
|
<h2>{{ t('conflictConfirm.title') }}</h2>
|
||||||
|
<p class="confirmation-message">{{ t('conflictConfirm.message') }}</p>
|
||||||
|
<p class="resolve-conflicts-detail" id="resolveConflictsDetail"></p>
|
||||||
|
<div class="resolve-conflicts-impact" id="resolveConflictsImpact"></div>
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button class="cancel-btn" onclick="modalManager.closeModal('resolveFilenameConflictsModal')">{{ t('common.actions.cancel') }}</button>
|
||||||
|
<button class="primary-btn" id="resolveConflictsConfirmBtn" onclick="doctorManager.confirmResolveConflicts()">
|
||||||
|
<i class="fas fa-check"></i>
|
||||||
|
{{ t('conflictConfirm.confirm') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
Reference in New Issue
Block a user