2022-06-16 19:41:29 +02:00
|
|
|
import server from "../../services/server.js";
|
|
|
|
import froca from "../../services/froca.js";
|
|
|
|
import linkService from "../../services/link.js";
|
|
|
|
import utils from "../../services/utils.js";
|
|
|
|
import BasicWidget from "../basic_widget.js";
|
2024-07-23 17:38:22 +08:00
|
|
|
import { t } from "../../services/i18n.js";
|
2025-01-09 18:36:24 +02:00
|
|
|
import type { FAttributeRow } from "../../entities/fattribute.js";
|
2024-12-21 15:30:11 +02:00
|
|
|
|
|
|
|
// TODO: Use common with server.
|
|
|
|
interface Response {
|
|
|
|
noteIdsToBeDeleted: string[];
|
|
|
|
brokenRelations: FAttributeRow[];
|
|
|
|
}
|
|
|
|
|
2024-12-21 15:34:07 +02:00
|
|
|
export interface ResolveOptions {
|
2024-12-21 15:30:11 +02:00
|
|
|
proceed: boolean;
|
2025-01-09 18:07:02 +02:00
|
|
|
deleteAllClones?: boolean;
|
2024-12-21 15:30:11 +02:00
|
|
|
eraseNotes?: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface ShowDeleteNotesDialogOpts {
|
|
|
|
branchIdsToDelete: string[];
|
|
|
|
callback: (opts: ResolveOptions) => void;
|
|
|
|
forceDeleteAllClones: boolean;
|
|
|
|
}
|
2022-06-16 19:41:29 +02:00
|
|
|
|
|
|
|
const TPL = `
|
|
|
|
<div class="delete-notes-dialog modal mx-auto" tabindex="-1" role="dialog">
|
|
|
|
<div class="modal-dialog modal-dialog-scrollable modal-xl" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
2025-01-09 18:07:02 +02:00
|
|
|
<h4 class="modal-title">${t("delete_notes.delete_notes_preview")}</h4>
|
|
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="${t("delete_notes.close")}"></button>
|
2022-06-16 19:41:29 +02:00
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
2024-09-03 18:15:10 +02:00
|
|
|
<div class="form-checkbox">
|
2025-01-24 22:35:45 +02:00
|
|
|
<label for="delete-all-clones" class="form-check-label tn-checkbox">
|
|
|
|
<input id="delete-all-clones" class="delete-all-clones form-check-input" value="1" type="checkbox">
|
|
|
|
${t("delete_notes.delete_all_clones_description")}
|
|
|
|
</label>
|
2022-06-16 19:41:29 +02:00
|
|
|
</div>
|
|
|
|
|
2024-09-03 18:15:10 +02:00
|
|
|
<div class="form-checkbox" style="margin-bottom: 1rem">
|
2025-01-24 22:35:45 +02:00
|
|
|
<label for="erase-notes" class="form-check-label tn-checkbox">
|
|
|
|
<input id="erase-notes" class="erase-notes form-check-input" value="1" type="checkbox">
|
|
|
|
${t("delete_notes.erase_notes_warning")}
|
|
|
|
</label>
|
2022-06-16 19:41:29 +02:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="delete-notes-list-wrapper">
|
2025-01-09 18:07:02 +02:00
|
|
|
<h4>${t("delete_notes.notes_to_be_deleted", { noteCount: '<span class="deleted-notes-count"></span>' })}</h4>
|
2022-06-16 19:41:29 +02:00
|
|
|
|
|
|
|
<ul class="delete-notes-list" style="max-height: 200px; overflow: auto;"></ul>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="no-note-to-delete-wrapper alert alert-info">
|
2025-01-09 18:07:02 +02:00
|
|
|
${t("delete_notes.no_note_to_delete")}
|
2022-06-16 19:41:29 +02:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="broken-relations-wrapper">
|
|
|
|
<div class="alert alert-danger">
|
2025-01-09 18:07:02 +02:00
|
|
|
<h4>${t("delete_notes.broken_relations_to_be_deleted", { relationCount: '<span class="broke-relations-count"></span>' })}</h4>
|
2022-06-16 19:41:29 +02:00
|
|
|
|
|
|
|
<ul class="broken-relations-list" style="max-height: 200px; overflow: auto;"></ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
2025-01-09 18:07:02 +02:00
|
|
|
<button class="delete-notes-dialog-cancel-button btn btn-sm">${t("delete_notes.cancel")}</button>
|
2022-06-16 19:41:29 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
<button class="delete-notes-dialog-ok-button btn btn-primary btn-sm">${t("delete_notes.ok")}</button>
|
2022-06-16 19:41:29 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>`;
|
|
|
|
|
|
|
|
export default class DeleteNotesDialog extends BasicWidget {
|
2024-12-21 15:30:11 +02:00
|
|
|
private branchIds: string[] | null;
|
|
|
|
private resolve!: (options: ResolveOptions) => void;
|
|
|
|
|
|
|
|
private $content!: JQuery<HTMLElement>;
|
|
|
|
private $okButton!: JQuery<HTMLElement>;
|
|
|
|
private $cancelButton!: JQuery<HTMLElement>;
|
|
|
|
private $deleteNotesList!: JQuery<HTMLElement>;
|
|
|
|
private $brokenRelationsList!: JQuery<HTMLElement>;
|
|
|
|
private $deletedNotesCount!: JQuery<HTMLElement>;
|
|
|
|
private $noNoteToDeleteWrapper!: JQuery<HTMLElement>;
|
|
|
|
private $deleteNotesListWrapper!: JQuery<HTMLElement>;
|
|
|
|
private $brokenRelationsListWrapper!: JQuery<HTMLElement>;
|
|
|
|
private $brokenRelationsCount!: JQuery<HTMLElement>;
|
|
|
|
private $deleteAllClones!: JQuery<HTMLElement>;
|
|
|
|
private $eraseNotes!: JQuery<HTMLElement>;
|
|
|
|
|
|
|
|
private forceDeleteAllClones?: boolean;
|
|
|
|
|
2022-06-16 19:41:29 +02:00
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.branchIds = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
doRender() {
|
|
|
|
this.$widget = $(TPL);
|
|
|
|
this.$content = this.$widget.find(".recent-changes-content");
|
|
|
|
this.$okButton = this.$widget.find(".delete-notes-dialog-ok-button");
|
|
|
|
this.$cancelButton = this.$widget.find(".delete-notes-dialog-cancel-button");
|
|
|
|
this.$deleteNotesList = this.$widget.find(".delete-notes-list");
|
|
|
|
this.$brokenRelationsList = this.$widget.find(".broken-relations-list");
|
|
|
|
this.$deletedNotesCount = this.$widget.find(".deleted-notes-count");
|
|
|
|
this.$noNoteToDeleteWrapper = this.$widget.find(".no-note-to-delete-wrapper");
|
|
|
|
this.$deleteNotesListWrapper = this.$widget.find(".delete-notes-list-wrapper");
|
|
|
|
this.$brokenRelationsListWrapper = this.$widget.find(".broken-relations-wrapper");
|
|
|
|
this.$brokenRelationsCount = this.$widget.find(".broke-relations-count");
|
|
|
|
this.$deleteAllClones = this.$widget.find(".delete-all-clones");
|
|
|
|
this.$eraseNotes = this.$widget.find(".erase-notes");
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
this.$widget.on("shown.bs.modal", () => this.$okButton.trigger("focus"));
|
2022-06-16 19:41:29 +02:00
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
this.$cancelButton.on("click", () => {
|
2022-06-16 19:41:29 +02:00
|
|
|
utils.closeActiveDialog();
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
this.resolve({ proceed: false });
|
2022-06-16 19:41:29 +02:00
|
|
|
});
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
this.$okButton.on("click", () => {
|
2022-06-16 19:41:29 +02:00
|
|
|
utils.closeActiveDialog();
|
|
|
|
|
|
|
|
this.resolve({
|
|
|
|
proceed: true,
|
2022-09-15 23:09:24 +02:00
|
|
|
deleteAllClones: this.forceDeleteAllClones || this.isDeleteAllClonesChecked(),
|
2022-06-16 19:41:29 +02:00
|
|
|
eraseNotes: this.isEraseNotesChecked()
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
this.$deleteAllClones.on("click", () => this.renderDeletePreview());
|
2022-06-16 19:41:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async renderDeletePreview() {
|
2025-01-09 18:07:02 +02:00
|
|
|
const response = await server.post<Response>("delete-notes-preview", {
|
2022-06-16 19:41:29 +02:00
|
|
|
branchIdsToDelete: this.branchIds,
|
2022-09-15 23:09:24 +02:00
|
|
|
deleteAllClones: this.forceDeleteAllClones || this.isDeleteAllClonesChecked()
|
2022-06-16 19:41:29 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
this.$deleteNotesList.empty();
|
|
|
|
this.$brokenRelationsList.empty();
|
|
|
|
|
|
|
|
this.$deleteNotesListWrapper.toggle(response.noteIdsToBeDeleted.length > 0);
|
|
|
|
this.$noNoteToDeleteWrapper.toggle(response.noteIdsToBeDeleted.length === 0);
|
|
|
|
|
|
|
|
for (const note of await froca.getNotes(response.noteIdsToBeDeleted)) {
|
2025-01-09 18:07:02 +02:00
|
|
|
this.$deleteNotesList.append($("<li>").append(await linkService.createLink(note.noteId, { showNotePath: true })));
|
2022-06-16 19:41:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.$deletedNotesCount.text(response.noteIdsToBeDeleted.length);
|
|
|
|
|
|
|
|
this.$brokenRelationsListWrapper.toggle(response.brokenRelations.length > 0);
|
|
|
|
this.$brokenRelationsCount.text(response.brokenRelations.length);
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
await froca.getNotes(response.brokenRelations.map((br) => br.noteId));
|
2022-06-16 19:41:29 +02:00
|
|
|
|
|
|
|
for (const attr of response.brokenRelations) {
|
|
|
|
this.$brokenRelationsList.append(
|
2025-01-09 18:07:02 +02:00
|
|
|
$("<li>").html(
|
|
|
|
t("delete_notes.deleted_relation_text", {
|
|
|
|
note: (await linkService.createLink(attr.value)).html(),
|
|
|
|
relation: `<code>${attr.name}</code>`,
|
|
|
|
source: (await linkService.createLink(attr.noteId)).html()
|
|
|
|
})
|
|
|
|
)
|
2022-06-16 19:41:29 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
async showDeleteNotesDialogEvent({ branchIdsToDelete, callback, forceDeleteAllClones }: ShowDeleteNotesDialogOpts) {
|
2022-06-16 19:41:29 +02:00
|
|
|
this.branchIds = branchIdsToDelete;
|
2022-09-15 23:09:24 +02:00
|
|
|
this.forceDeleteAllClones = forceDeleteAllClones;
|
2022-06-16 19:41:29 +02:00
|
|
|
|
|
|
|
await this.renderDeletePreview();
|
|
|
|
|
|
|
|
utils.openDialog(this.$widget);
|
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
this.$deleteAllClones.prop("checked", !!forceDeleteAllClones).prop("disabled", !!forceDeleteAllClones);
|
2022-09-15 23:09:24 +02:00
|
|
|
|
2022-06-16 19:41:29 +02:00
|
|
|
this.$eraseNotes.prop("checked", false);
|
|
|
|
|
|
|
|
this.resolve = callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
isDeleteAllClonesChecked() {
|
|
|
|
return this.$deleteAllClones.is(":checked");
|
|
|
|
}
|
|
|
|
|
|
|
|
isEraseNotesChecked() {
|
|
|
|
return this.$eraseNotes.is(":checked");
|
|
|
|
}
|
|
|
|
}
|