Library nodes are now smarter about where in the tree they are inserted based on the currently selected node

This commit is contained in:
Stefan Zermatten
2021-04-09 12:36:14 +02:00
parent 838e2ed35f
commit 152677b023
6 changed files with 94 additions and 58 deletions

View File

@@ -100,7 +100,7 @@
}},
computed: {
hasChildren(){
return this.children && this.children.length || this.lazy && !this.expanded;
return this.children && !!this.children.length || this.lazy && !this.expanded;
},
showExpanded(){
return this.expanded && (this.organize || this.hasChildren)

View File

@@ -1,12 +1,14 @@
<template lang="html">
<v-btn
fab
:fab="fab"
:outlined="!fab"
small
color="primary"
data-id="insert-library-node-button"
@click="insertLibraryNode"
>
<v-icon>add</v-icon>
<slot />
</v-btn>
</template>
@@ -22,43 +24,73 @@ export default {
type: String,
required: true,
},
parentId: {
type: String,
default: undefined,
},
parentCollection: {
selectedNodeId: {
type: String,
default: undefined,
},
fab: Boolean,
},
methods: {
insertLibraryNode(){
let libraryId = this.libraryId;
let tier = getUserTier(Meteor.userId())
if (tier && tier.paidBenefits){
let parentRef = {
id: this.parentId || libraryId,
collection: this.parentCollection || 'libraries',
};
let {ancestors} = getAncestry({parentRef});
this.$store.commit('pushDialogStack', {
component: 'library-node-creation-dialog',
elementId: 'insert-library-node-button',
callback(libraryNode){
if (!libraryNode) return;
libraryNode.parent = parentRef;
libraryNode.ancestors = ancestors;
setDocToLastOrder({collection: LibraryNodes, doc: libraryNode});
let libraryNodeId = insertNode.call(libraryNode);
return `tree-node-${libraryNodeId}`;
}
});
} else {
// Check tier has paid benefits
let tier = getUserTier(Meteor.userId());
if (!(tier && tier.paidBenefits)){
this.$store.commit('pushDialogStack', {
component: 'tier-too-low-dialog',
elementId: 'insert-library-node-button',
});
return;
}
// Get ancestry reference
let order, parentRef;
let selectedComponent = document.querySelector(
`[data-id="tree-node-${this.selectedNodeId}"]`
);
if (selectedComponent){
let vueInstance = selectedComponent.__vue__.$parent;
if (vueInstance.showExpanded){
parentRef = {
id: this.selectedNodeId,
collection: 'libraryNodes',
};
} else {
parentRef = vueInstance.node.parent;
order = vueInstance.node.order + 0.5;
}
} else {
parentRef = {
id: libraryId,
collection: 'libraries',
};
}
let {ancestors} = getAncestry({parentRef});
// Insert form dialog
let that = this;
this.$store.commit('pushDialogStack', {
component: 'library-node-creation-dialog',
elementId: 'insert-library-node-button',
callback(libraryNode){
if (!libraryNode) return;
// Set ancestry and order
libraryNode.parent = parentRef;
libraryNode.ancestors = ancestors;
if (order){
libraryNode.order = order;
} else {
setDocToLastOrder({collection: LibraryNodes, doc: libraryNode});
}
// Insert doc
let libraryNodeId = insertNode.call(libraryNode);
that.$emit('selected', libraryNodeId);
return `tree-node-${libraryNodeId}`;
}
});
},
}
}

View File

@@ -28,7 +28,10 @@
<insert-library-node-button
v-if="libraryId"
style="bottom: -32px"
fab
:library-id="libraryId"
:selected-node-id="selected"
@selected="id => {if ($vuetify.breakpoint.mdAndUp) selected = id}"
/>
</v-toolbar>
<div
@@ -61,6 +64,7 @@
:_id="selected"
embedded
@removed="selected = undefined"
@duplicated="id => {if ($vuetify.breakpoint.mdAndUp) selected = id}"
/>
</div>
</tree-detail-layout>

View File

@@ -23,36 +23,32 @@
</div>
</v-expansion-panel-header>
<v-expansion-panel-content>
<v-layout
justify-space-around
class="ma-2"
>
<insert-library-node-button
:library-id="library._id"
:selected-node-id="selectedNodeId"
@selected="e => $emit('selected', e)"
/>
<v-btn
color="primary"
outlined
small
@click="$router.push(`/library/${library._id}`)"
>
<v-icon>arrow_forward</v-icon>
</v-btn>
</v-layout>
<library-contents-container
:library-id="library._id"
:organize-mode="organizeMode && editPermission(library)"
:edit-mode="editMode"
:selected-node-id="selectedNodeId"
should-subscribe
class="mb-4"
@selected="e => $emit('selected', e)"
/>
<v-layout>
<v-btn
text
small
style="background-color: inherit; margin-top: 0;"
:disabled="!editPermission(library)"
:data-id="`insert-node-${library._id}`"
@click="insertLibraryNode(library._id)"
>
<v-icon>add</v-icon>
New property
</v-btn>
<v-spacer />
<v-btn
small
icon
@click="$router.push(`/library/${library._id}`)"
>
<v-icon>arrow_forward</v-icon>
</v-btn>
</v-layout>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
@@ -76,10 +72,12 @@ import LibraryContentsContainer from '/imports/ui/library/LibraryContentsContain
import Libraries, { insertLibrary } from '/imports/api/library/Libraries.js';
import { getUserTier } from '/imports/api/users/patreon/tiers.js';
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
import InsertLibraryNodeButton from '/imports/ui/library/InsertLibraryNodeButton.vue';
export default {
components: {
LibraryContentsContainer,
InsertLibraryNodeButton,
},
props: {
organizeMode: Boolean,

View File

@@ -71,12 +71,12 @@
<script lang="js">
import LibraryNodes, {
duplicateNode,
updateLibraryNode,
pushToLibraryNode,
pullFromLibraryNode,
softRemoveLibraryNode,
} from '/imports/api/library/LibraryNodes.js';
import duplicateLibraryNode from '/imports/api/library/methods/duplicateLibraryNode.js';
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
import PropertyToolbar from '/imports/ui/components/propertyToolbar.vue';
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
@@ -147,10 +147,12 @@
methods: {
getPropertyName,
duplicate(){
duplicateNode.call({_id: this.currentId}, (error) => {
console.error(error);
duplicateLibraryNode.call({
_id: this.currentId
}, (error, duplicateId) => {
if (error) console.error(error);
if (this.embedded){
this.$emit('duplicated');
this.$emit('duplicated', duplicateId);
} else {
this.$store.dispatch('popDialogStack');
}

10
app/package-lock.json generated
View File

@@ -159,7 +159,7 @@
},
"ansi-regex": {
"version": "2.1.1",
"resolved": false,
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"ansi-styles": {
@@ -1322,7 +1322,7 @@
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": false,
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "^1.0.0"
@@ -2674,7 +2674,7 @@
},
"set-blocking": {
"version": "2.0.0",
"resolved": false,
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"setimmediate": {
@@ -2781,7 +2781,7 @@
},
"string-width": {
"version": "1.0.2",
"resolved": false,
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
@@ -2799,7 +2799,7 @@
},
"strip-ansi": {
"version": "3.0.1",
"resolved": false,
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"