Added second library tree for multi-track drifting

This commit is contained in:
Stefan Zermatten
2023-06-26 16:31:23 +02:00
parent 7562e29fac
commit 22d51eacab
8 changed files with 225 additions and 5 deletions

View File

@@ -3,6 +3,19 @@
class="layout"
style="height: 100%;"
>
<div
v-if="$slots['left-tree']"
class="layout column justify-start"
:style="computedTreeStyle"
>
<slot
name="left-tree"
/>
</div>
<v-divider
v-if="$slots['left-tree']"
vertical
/>
<div
class="layout column justify-start"
:style="computedTreeStyle"

View File

@@ -90,6 +90,20 @@
<v-icon>mdi-content-duplicate</v-icon>
</v-list-item-action>
</v-list-item>
<v-list-item
v-if="$listeners && $listeners['make-reference']"
:disabled="context.editPermission === false"
@click="$emit('make-reference')"
>
<v-list-item-content>
<v-list-item-title>
Create Reference
</v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-icon>mdi-link-plus</v-icon>
</v-list-item-action>
</v-list-item>
<v-list-item
v-if="$listeners && $listeners.move"
:disabled="context.editPermission === false"

View File

@@ -1,5 +1,12 @@
<template lang="html">
<tree-detail-layout>
<library-second-tree
v-if="showSecondTree"
slot="left-tree"
:selected-node="selectedNode"
@close="showSecondTree = false"
@selected="clickNode"
/>
<div
slot="tree"
class="layout column"
@@ -24,11 +31,33 @@
@extra-fields-changed="val => extraFields = val"
/>
<v-spacer />
<v-fade-transition>
<v-menu v-if="organize && $vuetify.breakpoint.mdAndUp">
<template #activator="{ on, attrs }">
<v-btn
icon
v-bind="attrs"
v-on="on"
>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</template>
<v-card>
<v-card-text>
<v-switch
v-model="showSecondTree"
label="Show second library tree"
/>
</v-card-text>
</v-card>
</v-menu>
</v-fade-transition>
<v-switch
v-if="!libraryId || canEditLibrary"
v-model="organize"
hide-details
label="Organize"
class="mx-3"
class="ml-1 mr-3 mt-2"
style="flex-grow: 0; height: 32px;"
/>
<insert-library-node-button
@@ -93,6 +122,7 @@ import isDarkColor from '/imports/client/ui/utility/isDarkColor.js';
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
import getThemeColor from '/imports/client/ui/utility/getThemeColor.js';
import TreeSearchInput from '/imports/client/ui/components/tree/TreeSearchInput.vue';
import LibrarySecondTree from '/imports/client/ui/library/LibrarySecondTree.vue';
export default {
components: {
@@ -102,6 +132,7 @@ export default {
LibraryContentsContainer,
InsertLibraryNodeButton,
TreeSearchInput,
LibrarySecondTree,
},
props: {
selection: Boolean,
@@ -115,6 +146,7 @@ export default {
selectedNodeId: undefined,
filter: undefined,
extraFields: [],
showSecondTree: false,
};},
computed: {
isToolbarDark(){

View File

@@ -5,7 +5,7 @@
:class="isSelected && !disabled && 'primary--text v-list-item--active'"
>
<v-list-item-action
v-if="selection"
v-if="selection && !singleSelect"
>
<v-checkbox
:disabled="disabled"
@@ -66,6 +66,7 @@ export default {
},
open: Boolean,
selection: Boolean,
singleSelect: Boolean,
dense: Boolean,
isSelected: Boolean,
disabled: Boolean,

View File

@@ -9,6 +9,7 @@
:model="library"
:to="{ name: 'singleLibrary', params: { id: library._id }}"
:selection="selection"
:single-select="singleSelect"
:is-selected="librariesSelected && librariesSelected.includes(library._id)"
:selected-by-collection="librariesSelectedByCollections && librariesSelectedByCollections.includes(library._id)"
:disabled="disabled"
@@ -26,6 +27,7 @@
:open="openCollections[libraryCollection._id]"
:model="libraryCollection"
:selection="selection"
:single-select="singleSelect"
:is-selected="libraryCollectionsSelected && libraryCollectionsSelected.includes(libraryCollection._id)"
:disabled="disabled"
@select="val => $emit('select-library-collection', libraryCollection._id, val)"
@@ -37,6 +39,7 @@
:model="library"
:to="{ name: 'singleLibrary', params: { id: library._id }}"
:selection="selection"
:single-select="singleSelect"
:is-selected="librariesSelected && librariesSelected.includes(library._id)"
:selected-by-collection="librariesSelectedByCollections && librariesSelectedByCollections.includes(library._id)"
:disabled="disabled"
@@ -44,6 +47,14 @@
@select="val => $emit('select-library', library._id, val)"
/>
</v-list-group>
<v-list-item v-if="!$subReady.libraries">
<v-spacer />
<v-progress-circular
indeterminate
color="primary"
/>
<v-spacer />
</v-list-item>
</v-list>
</template>
@@ -62,6 +73,7 @@ export default {
},
props: {
selection: Boolean,
singleSelect: Boolean,
disabled: Boolean,
librariesSelected: {
type: Array,
@@ -87,7 +99,7 @@ export default {
libraryCollections(){
const userId = Meteor.userId();
if (!userId) return;
const subCollections = Meteor.user().subscribedLibraryCollections || [];
const subCollections = Meteor.user()?.subscribedLibraryCollections || [];
return LibraryCollections.find({
$or: [
{ owner: userId },

View File

@@ -5,10 +5,11 @@
<v-list-item
v-bind="$attrs"
:class="(isSelected || selectedByCollection) && !disabled && 'primary--text v-list-item--active'"
:to="selection ? undefined : to"
:to="singleSelect ? undefined : to"
@click="singleSelect && $emit('select')"
>
<v-list-item-action
v-if="selection"
v-if="selection && !singleSelect"
>
<v-checkbox
:disabled="disabled"
@@ -42,6 +43,7 @@ export default {
required: true,
},
selection: Boolean,
singleSelect: Boolean,
isSelected: Boolean,
selectedByCollection: Boolean,
disabled: Boolean,

View File

@@ -10,6 +10,7 @@
@move="move"
@copy="copy"
@remove="remove"
@make-reference="makeReference"
@toggle-editing="editing = !editing"
@color-changed="value => change({path: ['color'], value})"
/>
@@ -206,6 +207,26 @@ export default {
}
});
},
makeReference() {
insertNode.call({
libraryNode: {
type: 'reference',
ref: {
collection: 'libraryNodes',
id: this.model._id,
},
order: (this.model.order || 0) + 0.5,
},
parentRef: this.model.parent,
}, (error, docId) => {
if (error) console.error(error);
if (this.embedded){
this.$emit('duplicated', docId);
} else {
this.$store.dispatch('popDialogStack');
}
});
},
selectSubProperty(_id) {
if (this.embedded) {
this.$emit('select-sub-property', _id);

View File

@@ -0,0 +1,125 @@
<template lang="html">
<div class="d-flex flex-column fill-height">
<v-fade-transition mode="out-in">
<v-toolbar
v-if="libraryId"
dark
flat
color="secondary"
>
<v-btn
icon
@click="libraryId = undefined"
>
<v-icon>mdi-close</v-icon>
</v-btn>
<v-toolbar-title
key="library-name"
class="d-flex"
>
<div class="flex-shrink-1">
{{ library && library.name }}
</div>
<v-spacer />
</v-toolbar-title>
<v-btn
v-if="library && ($route.params.id !== library._id)"
icon
@click="libraryId = undefined; $router.push({ name: 'singleLibrary', params: { id: library._id }})"
>
<v-icon>mdi-arrow-right-bold</v-icon>
</v-btn>
</v-toolbar>
<v-toolbar
v-else
dark
flat
color="secondary"
>
<v-toolbar-title
key="no-library"
>
<v-btn
icon
@click="$emit('close')"
>
<v-icon>mdi-close</v-icon>
</v-btn>
Select Library
</v-toolbar-title>
</v-toolbar>
</v-fade-transition>
<v-sheet
class="pa-3 flex-grow-1 flex-shrink-1"
style="overflow: auto;"
>
<v-fade-transition mode="out-in">
<library-list
v-if="!libraryId"
selection
single-select
@select-library="id => libraryId = id"
/>
<library-contents-container
v-else
:library-id="libraryId"
:organize-mode="canEditLibrary"
should-subscribe
:selected-node="selectedNode"
@selected="e => $emit('selected', e)"
/>
</v-fade-transition>
</v-sheet>
</div>
</template>
<script lang="js">
import LibraryList from '/imports/client/ui/library/LibraryList.vue';
import LibraryContentsContainer from '/imports/client/ui/library/LibraryContentsContainer.vue';
import Libraries from '/imports/api/library/Libraries.js';
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
export default {
components: {
LibraryList,
LibraryContentsContainer,
},
props: {
selectedNode: {
type: Object,
default: undefined,
},
},
data() {
return {
libraryId: undefined
};
},
meteor: {
$subscribe: {
'library'(){
if (this.libraryId){
return [this.libraryId]
} else {
return [];
}
},
},
library() {
return Libraries.findOne(this.libraryId);
},
canEditLibrary(){
if (!this.libraryId) return;
try {
assertEditPermission(this.library, Meteor.userId());
return true;
} catch (e){
return false;
}
},
},
}
</script>
<style lang="css" scoped>
</style>