mirror of
https://github.com/zadam/trilium.git
synced 2025-11-04 20:36:13 +01:00
sharing WIP
This commit is contained in:
@@ -136,7 +136,10 @@ class Note extends AbstractEntity {
|
||||
return this.parentBranches;
|
||||
}
|
||||
|
||||
/** @returns {Branch[]} */
|
||||
/**
|
||||
* @returns {Branch[]}
|
||||
* @deprecated use getParentBranches() instead
|
||||
*/
|
||||
getBranches() {
|
||||
return this.parentBranches;
|
||||
}
|
||||
|
||||
@@ -130,18 +130,38 @@ class NoteShort {
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {string[]} */
|
||||
getBranchIds() {
|
||||
/**
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getParentBranchIds() {
|
||||
return Object.values(this.parentToBranch);
|
||||
}
|
||||
|
||||
/** @returns {Branch[]} */
|
||||
getBranches() {
|
||||
/**
|
||||
* @returns {string[]}
|
||||
* @deprecated use getParentBranchIds() instead
|
||||
*/
|
||||
getBranchIds() {
|
||||
return this.getParentBranchIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Branch[]}
|
||||
*/
|
||||
getParentBranches() {
|
||||
const branchIds = Object.values(this.parentToBranch);
|
||||
|
||||
return this.froca.getBranches(branchIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Branch[]}
|
||||
* @deprecated use getParentBranches() instead
|
||||
*/
|
||||
getBranches() {
|
||||
return this.getParentBranches();
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
hasChildren() {
|
||||
return this.children.length > 0;
|
||||
@@ -620,8 +640,8 @@ class NoteShort {
|
||||
});
|
||||
}
|
||||
|
||||
hasAncestor(ancestorNote, visitedNoteIds = null) {
|
||||
if (this.noteId === ancestorNote.noteId) {
|
||||
hasAncestor(ancestorNoteId, visitedNoteIds = null) {
|
||||
if (this.noteId === ancestorNoteId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -635,13 +655,13 @@ class NoteShort {
|
||||
visitedNoteIds.add(this.noteId);
|
||||
|
||||
for (const templateNote of this.getTemplateNotes()) {
|
||||
if (templateNote.hasAncestor(ancestorNote, visitedNoteIds)) {
|
||||
if (templateNote.hasAncestor(ancestorNoteId, visitedNoteIds)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const parentNote of this.getParentNotes()) {
|
||||
if (parentNote.hasAncestor(ancestorNote, visitedNoteIds)) {
|
||||
if (parentNote.hasAncestor(ancestorNoteId, visitedNoteIds)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import MermaidWidget from "../widgets/mermaid.js";
|
||||
import BookmarkButtons from "../widgets/bookmark_buttons.js";
|
||||
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
||||
import BacklinksWidget from "../widgets/backlinks.js";
|
||||
import SharedInfoWidget from "../widgets/shared_info.js";
|
||||
|
||||
export default class DesktopLayout {
|
||||
constructor(customWidgets) {
|
||||
@@ -147,6 +148,7 @@ export default class DesktopLayout {
|
||||
.titlePlacement("bottom"))
|
||||
.button(new NoteActionsWidget())
|
||||
)
|
||||
.child(new SharedInfoWidget())
|
||||
.child(new NoteUpdateStatusWidget())
|
||||
.child(new BacklinksWidget())
|
||||
.child(new MermaidWidget())
|
||||
|
||||
@@ -50,7 +50,7 @@ function isAffecting(attrRow, affectedNote) {
|
||||
|
||||
if (this.isInheritable) {
|
||||
for (const owningNote of owningNotes) {
|
||||
if (owningNote.hasAncestor(attrNote)) {
|
||||
if (owningNote.hasAncestor(attrNote.noteId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ class Froca {
|
||||
froca.notes[note.noteId].childToBranch = {};
|
||||
}
|
||||
|
||||
const branches = [...note.getBranches(), ...note.getChildBranches()];
|
||||
const branches = [...note.getParentBranches(), ...note.getChildBranches()];
|
||||
|
||||
searchResultNoteIds.forEach((resultNoteId, index) => branches.push({
|
||||
// branchId should be repeatable since sometimes we reload some notes without rerendering the tree
|
||||
|
||||
@@ -340,10 +340,12 @@ function initHelpDropdown($el) {
|
||||
|
||||
const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/"
|
||||
|
||||
function openHelp(e) {
|
||||
window.open(wikiBaseUrl + $(e.target).attr("data-help-page"), '_blank');
|
||||
}
|
||||
|
||||
function initHelpButtons($el) {
|
||||
$el.on("click", "*[data-help-page]", e => {
|
||||
window.open(wikiBaseUrl + $(e.target).attr("data-help-page"), '_blank');
|
||||
});
|
||||
$el.on("click", "*[data-help-page]", e => openHelp(e));
|
||||
}
|
||||
|
||||
function filterAttributeName(name) {
|
||||
@@ -397,6 +399,7 @@ export default {
|
||||
timeLimit,
|
||||
initHelpDropdown,
|
||||
initHelpButtons,
|
||||
openHelp,
|
||||
filterAttributeName,
|
||||
isValidAttributeName
|
||||
};
|
||||
|
||||
@@ -33,11 +33,7 @@ const TPL = `
|
||||
.backlinks-close-ticker {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.backlinks-ticker:hover {
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
|
||||
.backlinks-items {
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
|
||||
@@ -1,96 +1,32 @@
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
import SwitchWidget from "./switch.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="bookmark-switch">
|
||||
<style>
|
||||
/* The switch - the box around the slider */
|
||||
.bookmark-switch .switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
.bookmark-switch .slider {
|
||||
border-radius: 24px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--more-accented-background-color);
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.bookmark-switch .slider:before {
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: var(--main-background-color);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.bookmark-switch .slider.checked {
|
||||
background-color: var(--main-text-color);
|
||||
}
|
||||
|
||||
.bookmark-switch .slider.checked:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="add-bookmark-button">
|
||||
Bookmark
|
||||
|
||||
|
||||
|
||||
<span title="Bookmark this note to the left side panel">
|
||||
<label class="switch">
|
||||
<span class="slider"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="remove-bookmark-button">
|
||||
Bookmark
|
||||
|
||||
|
||||
|
||||
<span title="Remove bookmark">
|
||||
<label class="switch">
|
||||
<span class="slider checked"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
export default class BookmarkSwitchWidget extends NoteContextAwareWidget {
|
||||
export default class BookmarkSwitchWidget extends SwitchWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
super.doRender();
|
||||
|
||||
this.$addBookmarkButton = this.$widget.find(".add-bookmark-button");
|
||||
this.$addBookmarkButton.on('click', () => attributeService.setLabel(this.noteId, 'bookmarked'));
|
||||
this.$switchOnName.text("Bookmark");
|
||||
this.$switchOnButton.attr("title", "Bookmark this note to the left side panel");
|
||||
|
||||
this.$removeBookmarkButton = this.$widget.find(".remove-bookmark-button");
|
||||
this.$removeBookmarkButton.on('click', async () => {
|
||||
for (const label of this.note.getLabels('bookmarked')) {
|
||||
await attributeService.removeAttributeById(this.noteId, label.attributeId);
|
||||
}
|
||||
});
|
||||
this.$switchOffName.text("Bookmark");
|
||||
this.$switchOffButton.attr("title", "Remove bookmark");
|
||||
}
|
||||
|
||||
async switchOff() {
|
||||
for (const label of this.note.getLabels('bookmarked')) {
|
||||
await attributeService.removeAttributeById(this.noteId, label.attributeId);
|
||||
}
|
||||
}
|
||||
|
||||
switchOn() {
|
||||
return attributeService.setLabel(this.noteId, 'bookmarked');
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
const isBookmarked = note.hasLabel('bookmarked');
|
||||
|
||||
this.$addBookmarkButton.toggle(!isBookmarked);
|
||||
this.$removeBookmarkButton.toggle(isBookmarked);
|
||||
this.$switchOn.toggle(!isBookmarked);
|
||||
this.$switchOff.toggle(isBookmarked);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
|
||||
@@ -1,89 +1,28 @@
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import SwitchWidget from "./switch.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="protected-note-switch">
|
||||
<style>
|
||||
/* The switch - the box around the slider */
|
||||
.protected-note-switch .switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
.protected-note-switch .slider {
|
||||
border-radius: 24px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--more-accented-background-color);
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.protected-note-switch .slider:before {
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: var(--main-background-color);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.protected-note-switch .slider.checked {
|
||||
background-color: var(--main-text-color);
|
||||
}
|
||||
|
||||
.protected-note-switch .slider.checked:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="protect-button">
|
||||
Protect the note
|
||||
|
||||
|
||||
|
||||
<span title="Note is not protected, click to make it protected">
|
||||
<label class="switch">
|
||||
<span class="slider"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="unprotect-button">
|
||||
Unprotect the note
|
||||
|
||||
|
||||
|
||||
<span title="Note is protected, click to make it unprotected">
|
||||
<label class="switch">
|
||||
<span class="slider checked"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
export default class ProtectedNoteSwitchWidget extends NoteContextAwareWidget {
|
||||
export default class ProtectedNoteSwitchWidget extends SwitchWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
super.doRender();
|
||||
|
||||
this.$protectButton = this.$widget.find(".protect-button");
|
||||
this.$protectButton.on('click', () => protectedSessionService.protectNote(this.noteId, true, false));
|
||||
this.$switchOnName.text("Protect the note");
|
||||
this.$switchOnButton.attr("title", "Note is not protected, click to make it protected");
|
||||
|
||||
this.$unprotectButton = this.$widget.find(".unprotect-button");
|
||||
this.$unprotectButton.on('click', () => protectedSessionService.protectNote(this.noteId, false, false));
|
||||
this.$switchOffName.text("Unprotect the note");
|
||||
this.$switchOffButton.attr("title", "Note is protected, click to make it unprotected");
|
||||
}
|
||||
|
||||
switchOn() {
|
||||
protectedSessionService.protectNote(this.noteId, true, false);
|
||||
}
|
||||
|
||||
switchOff() {
|
||||
protectedSessionService.protectNote(this.noteId, false, false)
|
||||
}
|
||||
|
||||
refreshWithNote(note) {
|
||||
this.$protectButton.toggle(!note.isProtected);
|
||||
this.$unprotectButton.toggle(!!note.isProtected);
|
||||
this.$switchOn.toggle(!note.isProtected);
|
||||
this.$switchOff.toggle(!!note.isProtected);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import NoteTypeWidget from "../note_type.js";
|
||||
import ProtectedNoteSwitchWidget from "../protected_note_switch.js";
|
||||
import EditabilitySelectWidget from "../editability_select.js";
|
||||
import BookmarkSwitchWidget from "../bookmark_switch.js";
|
||||
import SharedSwitchWidget from "../shared_switch.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="basic-properties-widget">
|
||||
@@ -36,6 +37,8 @@ const TPL = `
|
||||
</div>
|
||||
|
||||
<div class="bookmark-switch-container"></div>
|
||||
|
||||
<div class="shared-switch-container"></div>
|
||||
</div>`;
|
||||
|
||||
export default class BasicPropertiesWidget extends NoteContextAwareWidget {
|
||||
@@ -46,12 +49,14 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
|
||||
this.protectedNoteSwitchWidget = new ProtectedNoteSwitchWidget().contentSized();
|
||||
this.editabilitySelectWidget = new EditabilitySelectWidget().contentSized();
|
||||
this.bookmarkSwitchWidget = new BookmarkSwitchWidget().contentSized();
|
||||
this.sharedSwitchWidget = new SharedSwitchWidget().contentSized();
|
||||
|
||||
this.child(
|
||||
this.noteTypeWidget,
|
||||
this.protectedNoteSwitchWidget,
|
||||
this.editabilitySelectWidget,
|
||||
this.bookmarkSwitchWidget
|
||||
this.bookmarkSwitchWidget,
|
||||
this.sharedSwitchWidget
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,6 +88,7 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
|
||||
this.$widget.find(".protected-note-switch-container").append(this.protectedNoteSwitchWidget.render());
|
||||
this.$widget.find(".editability-select-container").append(this.editabilitySelectWidget.render());
|
||||
this.$widget.find(".bookmark-switch-container").append(this.bookmarkSwitchWidget.render());
|
||||
this.$widget.find(".shared-switch-container").append(this.sharedSwitchWidget.render());
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
|
||||
45
src/public/app/widgets/shared_info.js
Normal file
45
src/public/app/widgets/shared_info.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import options from "../services/options.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="shared-info-widget alert alert-warning">
|
||||
<style>
|
||||
.shared-info-widget {
|
||||
margin: 10px;
|
||||
contain: none;
|
||||
padding: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<span class="share-text"></span> <a class="share-link external"></a>. For help visit <a href="https://github.com/zadam/trilium/wiki/Sharing">wiki</a>.
|
||||
</div>`;
|
||||
|
||||
export default class SharedInfoWidget extends NoteContextAwareWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled() && this.note.hasAncestor('share');
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$shareLink = this.$widget.find(".share-link");
|
||||
this.$shareText = this.$widget.find(".share-text");
|
||||
this.contentSized();
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
const syncServerHost = options.get("syncServerHost");
|
||||
let link;
|
||||
|
||||
if (syncServerHost) {
|
||||
link = syncServerHost + "/share/" + note.noteId;
|
||||
this.$shareText.text("This note is shared publicly on");
|
||||
}
|
||||
else {
|
||||
link = location.protocol + '//' + location.host + location.pathname + "share/" + note.noteId;
|
||||
this.$shareText.text("This note is shared locally on");
|
||||
}
|
||||
|
||||
this.$shareLink.attr("href", link).text(link);
|
||||
}
|
||||
}
|
||||
68
src/public/app/widgets/shared_switch.js
Normal file
68
src/public/app/widgets/shared_switch.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import SwitchWidget from "./switch.js";
|
||||
import froca from "../services/froca.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import server from "../services/server.js";
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
export default class SharedSwitchWidget extends SwitchWidget {
|
||||
doRender() {
|
||||
super.doRender();
|
||||
|
||||
this.$switchOnName.text("Shared");
|
||||
this.$switchOnButton.attr("title", "Share the note");
|
||||
|
||||
this.$switchOffName.text("Shared");
|
||||
this.$switchOffButton.attr("title", "Unshare the note");
|
||||
|
||||
this.$helpButton.attr("data-help-page", "Sharing").show();
|
||||
this.$helpButton.on('click', e => utils.openHelp(e));
|
||||
}
|
||||
|
||||
switchOn() {
|
||||
branchService.cloneNoteTo(this.noteId, 'share');
|
||||
}
|
||||
|
||||
async switchOff() {
|
||||
const shareBranch = this.note.getParentBranches().find(b => b.parentNoteId === 'share');
|
||||
|
||||
if (!shareBranch) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.note.getParentBranches().length === 1) {
|
||||
const confirmDialog = await import('../dialogs/confirm.js');
|
||||
|
||||
const text = "This note exists only as a shared note, unsharing would delete it. Do you want to continue and thus delete this note?";
|
||||
|
||||
if (!await confirmDialog.confirm(text)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await server.remove(`branches/${shareBranch.branchId}`);
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
const isShared = note.hasAncestor('share');
|
||||
const canBeUnshared = isShared && note.getParentBranches().find(b => b.parentNoteId === 'share');
|
||||
const switchDisabled = isShared && !canBeUnshared;
|
||||
|
||||
this.$switchOn.toggle(!isShared);
|
||||
this.$switchOff.toggle(!!isShared);
|
||||
|
||||
if (switchDisabled) {
|
||||
this.$widget.attr("title", "Note cannot be unshared here because it is shared through inheritance from an ancestor.");
|
||||
this.$switchOff.addClass("switch-disabled");
|
||||
}
|
||||
else {
|
||||
this.$widget.removeAttr("title");
|
||||
this.$switchOff.removeClass("switch-disabled");
|
||||
}
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.getBranches().find(b => b.noteId === this.noteId)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
117
src/public/app/widgets/switch.js
Normal file
117
src/public/app/widgets/switch.js
Normal file
@@ -0,0 +1,117 @@
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
|
||||
const TPL = `
|
||||
<div class="switch-widget">
|
||||
<style>
|
||||
.switch-widget {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* The switch - the box around the slider */
|
||||
.switch-widget .switch {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.switch-on, .switch-off {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
.switch-widget .slider {
|
||||
border-radius: 24px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--more-accented-background-color);
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.switch-widget .slider:before {
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: var(--main-background-color);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.switch-widget .slider.checked {
|
||||
background-color: var(--main-text-color);
|
||||
}
|
||||
|
||||
.switch-widget .slider.checked:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
.switch-widget .switch-disabled {
|
||||
opacity: 70%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.switch-widget .switch-help-button {
|
||||
font-weight: 900;
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="switch-on">
|
||||
<span class="switch-on-name"></span>
|
||||
|
||||
|
||||
|
||||
<span class="switch-on-button">
|
||||
<label class="switch">
|
||||
<span class="slider"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="switch-off">
|
||||
<span class="switch-off-name"></span>
|
||||
|
||||
|
||||
|
||||
<span class="switch-off-button">
|
||||
<label class="switch">
|
||||
<span class="slider checked"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button class="switch-help-button" type="button" data-help-page="" title="Open help page" style="display: none;">?</button>
|
||||
</div>`;
|
||||
|
||||
export default class SwitchWidget extends NoteContextAwareWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
|
||||
this.$switchOn = this.$widget.find(".switch-on");
|
||||
this.$switchOnName = this.$widget.find(".switch-on-name");
|
||||
this.$switchOnButton = this.$widget.find(".switch-on-button");
|
||||
|
||||
this.$switchOnButton.on('click', () => this.switchOn());
|
||||
|
||||
this.$switchOff = this.$widget.find(".switch-off");
|
||||
this.$switchOffName = this.$widget.find(".switch-off-name");
|
||||
this.$switchOffButton = this.$widget.find(".switch-off-button");
|
||||
|
||||
this.$switchOffButton.on('click', () => this.switchOff());
|
||||
|
||||
this.$helpButton = this.$widget.find(".switch-help-button");
|
||||
|
||||
}
|
||||
|
||||
switchOff() {}
|
||||
switchOn() {}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ function deleteNote(req) {
|
||||
|
||||
const taskContext = TaskContext.getInstance(taskId, 'delete-notes');
|
||||
|
||||
for (const branch of note.getBranches()) {
|
||||
for (const branch of note.getParentBranches()) {
|
||||
noteService.deleteBranch(branch, deleteId, taskContext);
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ function getDeleteNotesPreview(req) {
|
||||
|
||||
const note = branch.getNote();
|
||||
|
||||
if (deleteAllClones || note.getBranches().length <= branchCountToDelete[branch.branchId]) {
|
||||
if (deleteAllClones || note.getParentBranches().length <= branchCountToDelete[branch.branchId]) {
|
||||
noteIdsToBeDeleted.add(note.noteId);
|
||||
|
||||
for (const childBranch of note.getChildBranches()) {
|
||||
|
||||
@@ -11,6 +11,12 @@ const becca = require("../becca/becca");
|
||||
const beccaService = require("../becca/becca_service");
|
||||
|
||||
function cloneNoteToParent(noteId, parentBranchId, prefix) {
|
||||
if (parentBranchId === 'share') {
|
||||
const specialNotesService = require('./special_notes');
|
||||
// share root note is created lazily
|
||||
specialNotesService.getShareRoot();
|
||||
}
|
||||
|
||||
const parentBranch = becca.getBranch(parentBranchId);
|
||||
|
||||
if (isNoteDeleted(noteId) || isNoteDeleted(parentBranch.noteId)) {
|
||||
|
||||
@@ -118,6 +118,7 @@ function createNewNote(params) {
|
||||
note.setContent(params.content);
|
||||
|
||||
const branch = new Branch({
|
||||
branchId: params.branchId,
|
||||
noteId: note.noteId,
|
||||
parentNoteId: params.parentNoteId,
|
||||
notePosition: params.notePosition !== undefined ? params.notePosition : getNewNotePosition(params.parentNoteId),
|
||||
@@ -540,7 +541,7 @@ function deleteBranch(branch, deleteId, taskContext) {
|
||||
branch.markAsDeleted(deleteId);
|
||||
|
||||
const note = branch.getNote();
|
||||
const notDeletedBranches = note.getBranches();
|
||||
const notDeletedBranches = note.getParentBranches();
|
||||
|
||||
if (notDeletedBranches.length === 0) {
|
||||
for (const childBranch of note.getChildBranches()) {
|
||||
@@ -785,7 +786,7 @@ function duplicateSubtree(origNoteId, newParentNoteId) {
|
||||
|
||||
const origNote = becca.notes[origNoteId];
|
||||
// might be null if orig note is not in the target newParentNoteId
|
||||
const origBranch = origNote.getBranches().find(branch => branch.parentNoteId === newParentNoteId);
|
||||
const origBranch = origNote.getParentBranches().find(branch => branch.parentNoteId === newParentNoteId);
|
||||
|
||||
const noteIdMapping = getNoteIdMapping(origNote);
|
||||
|
||||
|
||||
@@ -206,11 +206,12 @@ function getShareRoot() {
|
||||
|
||||
if (!shareRoot) {
|
||||
shareRoot = noteService.createNewNote({
|
||||
branchId: 'share',
|
||||
noteId: 'share',
|
||||
title: 'share',
|
||||
title: 'Shared notes',
|
||||
type: 'text',
|
||||
content: '',
|
||||
parentNoteId: getHiddenRoot().noteId
|
||||
parentNoteId: 'root'
|
||||
}).note;
|
||||
}
|
||||
|
||||
@@ -223,7 +224,7 @@ function createMissingSpecialNotes() {
|
||||
getSinglesNoteRoot();
|
||||
getSinglesNoteRoot();
|
||||
getGlobalNoteMap();
|
||||
getShareRoot();
|
||||
// share root is not automatically created since it's visible in the tree and many won't need it/use it
|
||||
|
||||
const hidden = getHiddenRoot();
|
||||
|
||||
@@ -238,5 +239,6 @@ module.exports = {
|
||||
saveSqlConsole,
|
||||
createSearchNote,
|
||||
saveSearchNote,
|
||||
createMissingSpecialNotes
|
||||
createMissingSpecialNotes,
|
||||
getShareRoot
|
||||
};
|
||||
|
||||
@@ -173,7 +173,7 @@ function sortNotes(parentNoteId, customSortBy = 'title', reverse = false, folder
|
||||
let position = 10;
|
||||
|
||||
for (const note of notes) {
|
||||
const branch = note.getBranches().find(b => b.parentNoteId === parentNoteId);
|
||||
const branch = note.getParentBranches().find(b => b.parentNoteId === parentNoteId);
|
||||
|
||||
sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?",
|
||||
[position, branch.branchId]);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
const AbstractEntity = require('./abstract_entity');
|
||||
const shareRoot = require("../../share_root");
|
||||
|
||||
class Branch extends AbstractEntity {
|
||||
constructor([branchId, noteId, parentNoteId, prefix, isExpanded]) {
|
||||
@@ -18,10 +17,6 @@ class Branch extends AbstractEntity {
|
||||
/** @param {boolean} */
|
||||
this.isExpanded = !!isExpanded;
|
||||
|
||||
if (this.noteId === shareRoot.SHARE_ROOT_NOTE_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
const childNote = this.childNote;
|
||||
const parentNote = this.parentNote;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ function load() {
|
||||
new Note(row);
|
||||
}
|
||||
|
||||
for (const row of sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0 AND noteId IN (${noteIdStr}) ORDER BY notePosition`)) {
|
||||
for (const row of sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0 AND parentNoteId IN (${noteIdStr}) ORDER BY notePosition`)) {
|
||||
new Branch(row);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user