mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
converted delete notes dialog to new pattern
This commit is contained in:
parent
eb8e5eafb6
commit
9707094686
@ -1,99 +0,0 @@
|
|||||||
import server from "../services/server.js";
|
|
||||||
import froca from "../services/froca.js";
|
|
||||||
import linkService from "../services/link.js";
|
|
||||||
import utils from "../services/utils.js";
|
|
||||||
|
|
||||||
const $dialog = $("#delete-notes-dialog");
|
|
||||||
const $okButton = $("#delete-notes-dialog-ok-button");
|
|
||||||
const $cancelButton = $("#delete-notes-dialog-cancel-button");
|
|
||||||
const $deleteNotesList = $("#delete-notes-list");
|
|
||||||
const $brokenRelationsList = $("#broken-relations-list");
|
|
||||||
const $deletedNotesCount = $("#deleted-notes-count");
|
|
||||||
const $noNoteToDeleteWrapper = $("#no-note-to-delete-wrapper");
|
|
||||||
const $deleteNotesListWrapper = $("#delete-notes-list-wrapper");
|
|
||||||
const $brokenRelationsListWrapper = $("#broken-relations-wrapper");
|
|
||||||
const $brokenRelationsCount = $("#broke-relations-count");
|
|
||||||
const $deleteAllClones = $("#delete-all-clones");
|
|
||||||
const $eraseNotes = $("#erase-notes");
|
|
||||||
|
|
||||||
let branchIds = null;
|
|
||||||
let resolve = null;
|
|
||||||
|
|
||||||
async function renderDeletePreview() {
|
|
||||||
const response = await server.post('delete-notes-preview', {
|
|
||||||
branchIdsToDelete: branchIds,
|
|
||||||
deleteAllClones: isDeleteAllClonesChecked()
|
|
||||||
});
|
|
||||||
|
|
||||||
$deleteNotesList.empty();
|
|
||||||
$brokenRelationsList.empty();
|
|
||||||
|
|
||||||
$deleteNotesListWrapper.toggle(response.noteIdsToBeDeleted.length > 0);
|
|
||||||
$noNoteToDeleteWrapper.toggle(response.noteIdsToBeDeleted.length === 0);
|
|
||||||
|
|
||||||
for (const note of await froca.getNotes(response.noteIdsToBeDeleted)) {
|
|
||||||
$deleteNotesList.append(
|
|
||||||
$("<li>").append(
|
|
||||||
await linkService.createNoteLink(note.noteId, {showNotePath: true})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$deletedNotesCount.text(response.noteIdsToBeDeleted.length);
|
|
||||||
|
|
||||||
$brokenRelationsListWrapper.toggle(response.brokenRelations.length > 0);
|
|
||||||
$brokenRelationsCount.text(response.brokenRelations.length);
|
|
||||||
|
|
||||||
await froca.getNotes(response.brokenRelations.map(br => br.noteId));
|
|
||||||
|
|
||||||
for (const attr of response.brokenRelations) {
|
|
||||||
$brokenRelationsList.append(
|
|
||||||
$("<li>")
|
|
||||||
.append(`Note `)
|
|
||||||
.append(await linkService.createNoteLink(attr.value))
|
|
||||||
.append(` (to be deleted) is referenced by relation <code>${attr.name}</code> originating from `)
|
|
||||||
.append(await linkService.createNoteLink(attr.noteId))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function showDialog(branchIdsToDelete) {
|
|
||||||
branchIds = branchIdsToDelete;
|
|
||||||
|
|
||||||
await renderDeletePreview();
|
|
||||||
|
|
||||||
utils.openDialog($dialog);
|
|
||||||
|
|
||||||
$deleteAllClones.prop("checked", false);
|
|
||||||
$eraseNotes.prop("checked", false);
|
|
||||||
|
|
||||||
return new Promise((res, rej) => resolve = res);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isDeleteAllClonesChecked() {
|
|
||||||
return $deleteAllClones.is(":checked");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isEraseNotesChecked() {
|
|
||||||
return $eraseNotes.is(":checked");
|
|
||||||
}
|
|
||||||
|
|
||||||
$dialog.on('shown.bs.modal', () => $okButton.trigger("focus"));
|
|
||||||
|
|
||||||
$cancelButton.on('click', () => {
|
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
resolve({proceed: false});
|
|
||||||
});
|
|
||||||
|
|
||||||
$okButton.on('click', () => {
|
|
||||||
utils.closeActiveDialog();
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
proceed: true,
|
|
||||||
deleteAllClones: isDeleteAllClonesChecked(),
|
|
||||||
eraseNotes: isEraseNotesChecked()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$deleteAllClones.on('click', () => renderDeletePreview());
|
|
@ -1,29 +0,0 @@
|
|||||||
import protectedSessionService from "../services/protected_session.js";
|
|
||||||
import utils from "../services/utils.js";
|
|
||||||
|
|
||||||
const $dialog = $("#protected-session-password-dialog");
|
|
||||||
const $passwordForm = $dialog.find(".protected-session-password-form");
|
|
||||||
const $passwordInput = $dialog.find(".protected-session-password");
|
|
||||||
|
|
||||||
export function show() {
|
|
||||||
utils.openDialog($dialog);
|
|
||||||
|
|
||||||
$passwordInput.trigger('focus');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function close() {
|
|
||||||
// this may fail if the dialog has not been previously opened (not sure if still true with Bootstrap modal)
|
|
||||||
try {
|
|
||||||
$dialog.modal('hide');
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
$passwordForm.on('submit', () => {
|
|
||||||
const password = $passwordInput.val();
|
|
||||||
$passwordInput.val("");
|
|
||||||
|
|
||||||
protectedSessionService.setupProtectedSession(password);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
@ -70,6 +70,7 @@ import ExportDialog from "../widgets/dialogs/export.js";
|
|||||||
import MarkdownImportDialog from "../widgets/dialogs/markdown_import.js";
|
import MarkdownImportDialog from "../widgets/dialogs/markdown_import.js";
|
||||||
import ProtectedSessionPasswordDialog from "../widgets/dialogs/protected_session_password.js";
|
import ProtectedSessionPasswordDialog from "../widgets/dialogs/protected_session_password.js";
|
||||||
import NoteRevisionsDialog from "../widgets/dialogs/note_revisions.js";
|
import NoteRevisionsDialog from "../widgets/dialogs/note_revisions.js";
|
||||||
|
import DeleteNotesDialog from "../widgets/dialogs/delete_notes.js";
|
||||||
|
|
||||||
export default class DesktopLayout {
|
export default class DesktopLayout {
|
||||||
constructor(customWidgets) {
|
constructor(customWidgets) {
|
||||||
@ -214,6 +215,7 @@ export default class DesktopLayout {
|
|||||||
.child(new ExportDialog())
|
.child(new ExportDialog())
|
||||||
.child(new MarkdownImportDialog())
|
.child(new MarkdownImportDialog())
|
||||||
.child(new ProtectedSessionPasswordDialog())
|
.child(new ProtectedSessionPasswordDialog())
|
||||||
.child(new NoteRevisionsDialog());
|
.child(new NoteRevisionsDialog())
|
||||||
|
.child(new DeleteNotesDialog());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import toastService from "./toast.js";
|
|||||||
import froca from "./froca.js";
|
import froca from "./froca.js";
|
||||||
import hoistedNoteService from "./hoisted_note.js";
|
import hoistedNoteService from "./hoisted_note.js";
|
||||||
import ws from "./ws.js";
|
import ws from "./ws.js";
|
||||||
|
import appContext from "./app_context.js";
|
||||||
|
|
||||||
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
|
||||||
branchIdsToMove = filterRootNote(branchIdsToMove);
|
branchIdsToMove = filterRootNote(branchIdsToMove);
|
||||||
@ -81,8 +82,8 @@ async function deleteNotes(branchIdsToDelete) {
|
|||||||
deleteAllClones = false;
|
deleteAllClones = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const deleteNotesDialog = await import("../dialogs/delete_notes.js");
|
({proceed, deleteAllClones, eraseNotes} = await new Promise(res =>
|
||||||
({proceed, deleteAllClones, eraseNotes} = await deleteNotesDialog.showDialog(branchIdsToDelete));
|
appContext.triggerCommand('showDeleteNotesDialog', {branchIdsToDelete, callback: res})));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proceed) {
|
if (!proceed) {
|
||||||
|
167
src/public/app/widgets/dialogs/delete_notes.js
Normal file
167
src/public/app/widgets/dialogs/delete_notes.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
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";
|
||||||
|
|
||||||
|
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">
|
||||||
|
<h4 class="modal-title mr-auto">Delete notes preview</h4>
|
||||||
|
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input class="delete-all-clones" value="1" type="checkbox">
|
||||||
|
|
||||||
|
delete also all clones
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label title="Normal (soft) deletion only marks the notes as deleted and they can be undeleted (in recent changes dialog) within a period of time. Checking this option will erase the notes immediatelly and it won't be possible to undelete the notes.">
|
||||||
|
<input class="erase-notes" value="1" type="checkbox">
|
||||||
|
|
||||||
|
erase notes permanently (can't be undone). This will force application reload.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="delete-notes-list-wrapper">
|
||||||
|
<h4>Following notes will be deleted (<span class="deleted-notes-count"></span>)</h4>
|
||||||
|
|
||||||
|
<ul class="delete-notes-list" style="max-height: 200px; overflow: auto;"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="no-note-to-delete-wrapper alert alert-info">
|
||||||
|
No note will be deleted (only clones).
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="broken-relations-wrapper">
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<h4>Following relations will be broken and deleted (<span class="broke-relations-count"></span>)</h4>
|
||||||
|
|
||||||
|
<ul class="broken-relations-list" style="max-height: 200px; overflow: auto;"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="delete-notes-dialog-cancel-button btn btn-sm">Cancel</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<button class="delete-notes-dialog-ok-button btn btn-primary btn-sm">OK</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
export default class DeleteNotesDialog extends BasicWidget {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.branchIds = null;
|
||||||
|
this.resolve = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
doRender() {
|
||||||
|
this.$widget = $(TPL);
|
||||||
|
this.$content = this.$widget.find(".recent-changes-content");
|
||||||
|
this.$dialog = this.$widget.find(".delete-notes-dialog");
|
||||||
|
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");
|
||||||
|
|
||||||
|
this.$dialog.on('shown.bs.modal', () => this.$okButton.trigger("focus"));
|
||||||
|
|
||||||
|
this.$cancelButton.on('click', () => {
|
||||||
|
utils.closeActiveDialog();
|
||||||
|
|
||||||
|
this.resolve({proceed: false});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$okButton.on('click', () => {
|
||||||
|
utils.closeActiveDialog();
|
||||||
|
|
||||||
|
this.resolve({
|
||||||
|
proceed: true,
|
||||||
|
deleteAllClones: this.isDeleteAllClonesChecked(),
|
||||||
|
eraseNotes: this.isEraseNotesChecked()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$deleteAllClones.on('click', () => this.renderDeletePreview());
|
||||||
|
}
|
||||||
|
|
||||||
|
async renderDeletePreview() {
|
||||||
|
const response = await server.post('delete-notes-preview', {
|
||||||
|
branchIdsToDelete: this.branchIds,
|
||||||
|
deleteAllClones: this.isDeleteAllClonesChecked()
|
||||||
|
});
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
this.$deleteNotesList.append(
|
||||||
|
$("<li>").append(
|
||||||
|
await linkService.createNoteLink(note.noteId, {showNotePath: true})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$deletedNotesCount.text(response.noteIdsToBeDeleted.length);
|
||||||
|
|
||||||
|
this.$brokenRelationsListWrapper.toggle(response.brokenRelations.length > 0);
|
||||||
|
this.$brokenRelationsCount.text(response.brokenRelations.length);
|
||||||
|
|
||||||
|
await froca.getNotes(response.brokenRelations.map(br => br.noteId));
|
||||||
|
|
||||||
|
for (const attr of response.brokenRelations) {
|
||||||
|
this.$brokenRelationsList.append(
|
||||||
|
$("<li>")
|
||||||
|
.append(`Note `)
|
||||||
|
.append(await linkService.createNoteLink(attr.value))
|
||||||
|
.append(` (to be deleted) is referenced by relation <code>${attr.name}</code> originating from `)
|
||||||
|
.append(await linkService.createNoteLink(attr.noteId))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async showDeleteNotesDialogEvent({branchIdsToDelete, callback}) {
|
||||||
|
this.branchIds = branchIdsToDelete;
|
||||||
|
|
||||||
|
await this.renderDeletePreview();
|
||||||
|
|
||||||
|
utils.openDialog(this.$widget);
|
||||||
|
|
||||||
|
this.$deleteAllClones.prop("checked", false);
|
||||||
|
this.$eraseNotes.prop("checked", false);
|
||||||
|
|
||||||
|
this.resolve = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDeleteAllClonesChecked() {
|
||||||
|
return this.$deleteAllClones.is(":checked");
|
||||||
|
}
|
||||||
|
|
||||||
|
isEraseNotesChecked() {
|
||||||
|
return this.$eraseNotes.is(":checked");
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,6 @@
|
|||||||
<%- include('dialogs/info.ejs') %>
|
<%- include('dialogs/info.ejs') %>
|
||||||
<%- include('dialogs/prompt.ejs') %>
|
<%- include('dialogs/prompt.ejs') %>
|
||||||
<%- include('dialogs/confirm.ejs') %>
|
<%- include('dialogs/confirm.ejs') %>
|
||||||
<%- include('dialogs/delete_notes.ejs') %>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */
|
global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
<div id="delete-notes-dialog" class="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">
|
|
||||||
<h4 class="modal-title mr-auto">Delete notes preview</h4>
|
|
||||||
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<input id="delete-all-clones" value="1" type="checkbox">
|
|
||||||
|
|
||||||
delete also all clones
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label title="Normal (soft) deletion only marks the notes as deleted and they can be undeleted (in recent changes dialog) within a period of time. Checking this option will erase the notes immediatelly and it won't be possible to undelete the notes.">
|
|
||||||
<input id="erase-notes" value="1" type="checkbox">
|
|
||||||
|
|
||||||
erase notes permanently (can't be undone). This will force application reload.
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="delete-notes-list-wrapper">
|
|
||||||
<h4>Following notes will be deleted (<span id="deleted-notes-count"></span>)</h4>
|
|
||||||
|
|
||||||
<ul id="delete-notes-list" style="max-height: 200px; overflow: auto;"></ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="no-note-to-delete-wrapper" class="alert alert-info">
|
|
||||||
No note will be deleted (only clones).
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="broken-relations-wrapper">
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<h4>Following relations will be broken and deleted (<span id="broke-relations-count"></span>)</h4>
|
|
||||||
|
|
||||||
<ul id="broken-relations-list" style="max-height: 200px; overflow: auto;"></ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button class="btn btn-sm" id="delete-notes-dialog-cancel-button">Cancel</button>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button class="btn btn-primary btn-sm" id="delete-notes-dialog-ok-button">OK</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
Loading…
x
Reference in New Issue
Block a user