2021-01-31 02:43:13 +13:00
|
|
|
<template>
|
|
|
|
|
|
|
|
<span>
|
2021-03-18 10:26:08 +13:00
|
|
|
<div
|
|
|
|
class="treeSearchWrapper"
|
|
|
|
:class="{'fullWidth': disableDocumentControlBar}"
|
|
|
|
>
|
|
|
|
<q-input
|
|
|
|
ref="treeFilter"
|
|
|
|
filled
|
|
|
|
dark
|
|
|
|
debounce="200"
|
|
|
|
v-model="treeFilter"
|
|
|
|
label="Filter document tree..."
|
|
|
|
>
|
|
|
|
<template v-slot:append>
|
|
|
|
<q-icon name="mdi-text-search" />
|
|
|
|
</template>
|
|
|
|
<template v-slot:prepend>
|
|
|
|
<q-icon v-if="treeFilter !== ''" name="clear" class="cursor-pointer text-secondary" @click="resetTreeFilter" />
|
|
|
|
</template>
|
|
|
|
</q-input>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<h6 class="projectTitle text-cultured" v-if="!noProjectName">
|
2021-03-08 11:07:40 +13:00
|
|
|
<span>
|
|
|
|
{{projectName}}
|
|
|
|
<q-tooltip
|
|
|
|
:delay="1000"
|
|
|
|
>
|
|
|
|
This is your currently opened project's name.
|
|
|
|
</q-tooltip>
|
|
|
|
</span>
|
|
|
|
</h6>
|
|
|
|
|
2021-01-31 02:43:13 +13:00
|
|
|
<q-tree
|
2021-02-09 15:21:48 +13:00
|
|
|
class="objectTree q-pa-sm"
|
2021-03-18 10:26:08 +13:00
|
|
|
:class="{'hasTextShadow': textShadow}"
|
2021-02-23 11:30:18 +13:00
|
|
|
:nodes="hierarchicalTree"
|
2021-02-21 03:13:37 +13:00
|
|
|
node-key="key"
|
2021-01-31 02:43:13 +13:00
|
|
|
no-connectors
|
|
|
|
ref="tree"
|
|
|
|
dark
|
2021-03-08 11:07:40 +13:00
|
|
|
:duration="200"
|
2021-01-31 02:43:13 +13:00
|
|
|
:filter="treeFilter"
|
|
|
|
:selected.sync="selectedTreeNode"
|
2021-02-26 14:50:46 +13:00
|
|
|
:expanded.sync="expandedTreeNodes"
|
2021-03-08 11:07:40 +13:00
|
|
|
no-nodes-label="Loading your project..."
|
|
|
|
no-results-label="Nothing matches your request"
|
2021-01-31 02:43:13 +13:00
|
|
|
>
|
|
|
|
<template v-slot:default-header="prop">
|
2021-03-08 11:07:40 +13:00
|
|
|
<div class="row items-center col-grow"
|
|
|
|
@click.stop.prevent="processNodeClick(prop.node)"
|
|
|
|
@click.stop.prevent.middle="processNodeLabelMiddleClick(prop.node)"
|
|
|
|
>
|
2021-02-23 11:30:18 +13:00
|
|
|
<div class="documentLabel"
|
|
|
|
:style="`color: ${prop.node.color}`"
|
|
|
|
>
|
2021-02-26 14:50:46 +13:00
|
|
|
<q-icon
|
2021-03-03 14:10:05 +13:00
|
|
|
:style="`color: ${determineNodeColor(prop.node)}; width: 22px !important;`"
|
2021-02-26 14:50:46 +13:00
|
|
|
:size="(prop.node.icon.includes('fas')? '16px': '21px')"
|
|
|
|
:name="prop.node.icon"
|
|
|
|
class="q-mr-sm self-center" />
|
2021-01-31 14:46:23 +13:00
|
|
|
{{ prop.node.label }}
|
|
|
|
<span
|
2021-03-19 14:54:44 +13:00
|
|
|
class="text-grey-5 text-weight-medium q-ml-xs"
|
|
|
|
v-if="(prop.node.isRoot || prop.node.isTag) && !disableDocumentCounts">
|
|
|
|
<span v-html="determineCatyegoryString(prop.node)"/>
|
2021-03-05 12:51:41 +13:00
|
|
|
<q-tooltip
|
2021-03-19 14:54:44 +13:00
|
|
|
:delay="500"
|
2021-03-05 12:51:41 +13:00
|
|
|
>
|
2021-03-19 14:54:44 +13:00
|
|
|
Document & Categories count: <span class="text-bold text-satin-sheen-gold-dark">{{prop.node.allCount}}</span>
|
|
|
|
<br>
|
2021-03-08 11:07:40 +13:00
|
|
|
Document count: <span class="text-bold text-satin-sheen-gold-dark">{{prop.node.documentCount}}</span>
|
2021-03-05 12:51:41 +13:00
|
|
|
<br>
|
2021-03-08 11:07:40 +13:00
|
|
|
Category count: <span class="text-bold text-satin-sheen-gold-dark">{{prop.node.categoryCount}}</span>
|
2021-03-05 12:51:41 +13:00
|
|
|
</q-tooltip>
|
2021-01-31 14:46:23 +13:00
|
|
|
</span>
|
2021-01-31 02:43:13 +13:00
|
|
|
<q-badge
|
2021-02-26 14:50:46 +13:00
|
|
|
class="treeBadge"
|
2021-03-03 08:59:56 +13:00
|
|
|
:class="{'noChilden': prop.node.children.length === 0}"
|
2021-02-26 14:50:46 +13:00
|
|
|
v-if="prop.node.sticker"
|
|
|
|
color="primary"
|
|
|
|
outline
|
|
|
|
floating
|
|
|
|
>
|
|
|
|
{{prop.node.sticker}}
|
|
|
|
<q-tooltip
|
|
|
|
:delay="500"
|
|
|
|
>
|
2021-01-31 02:43:13 +13:00
|
|
|
Order priority of the document
|
|
|
|
</q-tooltip>
|
|
|
|
</q-badge>
|
2021-02-23 11:30:18 +13:00
|
|
|
<div class="treeButtonGroup">
|
|
|
|
<q-btn
|
|
|
|
tabindex="-1"
|
2021-03-03 14:10:05 +13:00
|
|
|
v-if="prop.node.children && prop.node.children.length > 0 && !prop.node.isRoot && !prop.node.isTag"
|
2021-02-23 11:30:18 +13:00
|
|
|
round
|
2021-02-26 14:50:46 +13:00
|
|
|
flat
|
2021-02-23 11:30:18 +13:00
|
|
|
dense
|
2021-02-26 14:50:46 +13:00
|
|
|
color="dark"
|
|
|
|
class="z-1 q-ml-sm treeButton treeButton--edit"
|
|
|
|
icon="mdi-pencil"
|
2021-03-05 12:51:41 +13:00
|
|
|
size="10px"
|
2021-02-26 14:50:46 +13:00
|
|
|
@click.stop.prevent="openExistingDocumentRoute(prop.node)"
|
|
|
|
>
|
|
|
|
<q-tooltip
|
|
|
|
:delay="300"
|
2021-02-23 11:30:18 +13:00
|
|
|
>
|
2021-02-26 14:50:46 +13:00
|
|
|
Open/Edit {{ prop.node.label }}
|
2021-02-23 11:30:18 +13:00
|
|
|
</q-tooltip>
|
|
|
|
</q-btn>
|
|
|
|
<q-btn
|
|
|
|
tabindex="-1"
|
2021-03-18 10:26:08 +13:00
|
|
|
v-if="(!prop.node.specialLabel && !prop.node.isRoot) && !prop.node.isTag"
|
2021-02-23 11:30:18 +13:00
|
|
|
round
|
2021-02-26 14:50:46 +13:00
|
|
|
flat
|
2021-02-23 11:30:18 +13:00
|
|
|
dense
|
2021-02-26 14:50:46 +13:00
|
|
|
color="dark"
|
|
|
|
class="z-1 q-ml-sm treeButton treeButton--add"
|
|
|
|
icon="mdi-plus"
|
2021-03-05 12:51:41 +13:00
|
|
|
size="10px"
|
2021-02-26 14:50:46 +13:00
|
|
|
@click.stop.prevent="processNodeNewDocumentButton(prop.node)"
|
|
|
|
>
|
|
|
|
<q-tooltip
|
|
|
|
:delay="300"
|
|
|
|
>
|
|
|
|
Add a new document belonging under {{ prop.node.label }}
|
2021-02-23 11:30:18 +13:00
|
|
|
</q-tooltip>
|
|
|
|
</q-btn>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-01-31 02:43:13 +13:00
|
|
|
</div>
|
2021-02-23 11:30:18 +13:00
|
|
|
|
2021-01-31 02:43:13 +13:00
|
|
|
</template>
|
|
|
|
</q-tree>
|
|
|
|
|
|
|
|
<!--
|
|
|
|
<q-list>
|
|
|
|
<q-separator
|
|
|
|
color="white"
|
|
|
|
inset
|
|
|
|
class="q-mt-md"
|
|
|
|
/>
|
|
|
|
<q-item
|
|
|
|
v-ripple
|
|
|
|
clickable
|
|
|
|
class="q-mt-md"
|
|
|
|
>
|
|
|
|
<q-item-section avatar>
|
|
|
|
<q-icon :name="menuAddNewItem.icon" />
|
|
|
|
</q-item-section>
|
|
|
|
<q-item-section>
|
|
|
|
{{ menuAddNewItem.label }}
|
|
|
|
</q-item-section>
|
|
|
|
</q-item>
|
|
|
|
|
|
|
|
</q-list>
|
|
|
|
|
|
|
|
-->
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
2021-02-23 11:30:18 +13:00
|
|
|
import { Component, Watch } from "vue-property-decorator"
|
2021-01-31 02:43:13 +13:00
|
|
|
|
|
|
|
import BaseClass from "src/BaseClass"
|
2021-02-28 06:00:57 +13:00
|
|
|
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
|
2021-01-31 02:43:13 +13:00
|
|
|
import PouchDB from "pouchdb"
|
2021-02-26 14:50:46 +13:00
|
|
|
import { engageBlueprints, retrieveAllBlueprints } from "src/scripts/databaseManager/blueprintManager"
|
|
|
|
// import { cleanDatabases } from "src/scripts/databaseManager/cleaner"
|
2021-01-31 02:43:13 +13:00
|
|
|
import { I_Blueprint } from "src/interfaces/I_Blueprint"
|
2021-03-03 14:10:05 +13:00
|
|
|
import { extend, colors } from "quasar"
|
|
|
|
import { tagListBuildFromBlueprints } from "src/scripts/utilities/tagListBuilder"
|
2021-03-08 11:07:40 +13:00
|
|
|
import { retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
|
2021-01-31 02:43:13 +13:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
components: { }
|
|
|
|
})
|
|
|
|
export default class ObjectTree extends BaseClass {
|
2021-02-23 11:30:18 +13:00
|
|
|
/****************************************************************/
|
|
|
|
// KEYBINDS MANAGEMENT
|
|
|
|
/****************************************************************/
|
|
|
|
@Watch("SGET_getCurrentKeyBindData", { deep: true })
|
|
|
|
processKeyPush () {
|
|
|
|
// Focus left tree search
|
2021-03-18 10:26:08 +13:00
|
|
|
if (this.determineKeyBind("focusHierarchicalTree") && !this.SGET_getDialogsState) {
|
2021-02-21 01:06:21 +13:00
|
|
|
const treeFilterDOM = this.$refs.treeFilter as unknown as HTMLInputElement
|
|
|
|
treeFilterDOM.focus()
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
// Clear input in the left tree search
|
2021-03-18 10:26:08 +13:00
|
|
|
if (this.determineKeyBind("clearInputHierarchicalTree") && !this.SGET_getDialogsState) {
|
2021-02-21 01:06:21 +13:00
|
|
|
this.resetTreeFilter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/****************************************************************/
|
|
|
|
// GENERIC FUNCTIONALITY
|
|
|
|
/****************************************************************/
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-03-08 11:07:40 +13:00
|
|
|
projectName = ""
|
|
|
|
|
2021-01-31 02:43:13 +13:00
|
|
|
/**
|
2021-02-23 11:30:18 +13:00
|
|
|
* Load all blueprints and build the tree out of them
|
2021-01-31 02:43:13 +13:00
|
|
|
*/
|
2021-02-23 11:30:18 +13:00
|
|
|
async created () {
|
2021-03-08 11:07:40 +13:00
|
|
|
this.projectName = await retrieveCurrentProjectName()
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
// await cleanDatabases()
|
|
|
|
await this.processBluePrints()
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
// Unfuck the rendering by giving the app some time to load first
|
2021-03-04 13:27:07 +13:00
|
|
|
await this.$nextTick()
|
2021-03-18 10:26:08 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
tagsAtTop = false
|
|
|
|
compactTags = false
|
|
|
|
noTags = false
|
|
|
|
noProjectName = false
|
|
|
|
invertTreeSorting = false
|
|
|
|
doNotcollaseTreeOptions = false
|
|
|
|
disableDocumentControlBar = false
|
|
|
|
textShadow = false
|
2021-03-19 14:54:44 +13:00
|
|
|
disableDocumentCounts = false
|
|
|
|
compactDocumentCount = false
|
|
|
|
invertCategoryPosition = false
|
|
|
|
doubleDashDocCount = false
|
2021-03-18 10:26:08 +13:00
|
|
|
|
|
|
|
@Watch("SGET_options", { immediate: true, deep: true })
|
|
|
|
onSettingsChange () {
|
|
|
|
const options = this.SGET_options
|
|
|
|
this.tagsAtTop = options.tagsAtTop
|
|
|
|
this.compactTags = options.compactTags
|
|
|
|
this.noTags = options.noTags
|
|
|
|
this.noProjectName = options.noProjectName
|
|
|
|
this.invertTreeSorting = options.invertTreeSorting
|
|
|
|
this.doNotcollaseTreeOptions = options.doNotcollaseTreeOptions
|
|
|
|
this.disableDocumentControlBar = options.disableDocumentControlBar
|
|
|
|
this.textShadow = options.textShadow
|
2021-03-19 14:54:44 +13:00
|
|
|
this.disableDocumentCounts = options.disableDocumentCounts
|
|
|
|
this.compactDocumentCount = options.compactDocumentCount
|
|
|
|
this.invertCategoryPosition = options.invertCategoryPosition
|
|
|
|
this.doubleDashDocCount = options.doubleDashDocCount
|
2021-03-04 13:27:07 +13:00
|
|
|
this.buildCurrentObjectTree().catch((e) => {
|
|
|
|
console.log(e)
|
|
|
|
})
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
|
|
// BLUEPRINT MANAGEMENT
|
|
|
|
/****************************************************************/
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
* In case any of the blueprints change, reload the whole tree
|
|
|
|
*/
|
2021-01-31 02:43:13 +13:00
|
|
|
@Watch("SGET_allBlueprints", { deep: true })
|
|
|
|
reactToBluePrintRefresh () {
|
2021-02-23 11:30:18 +13:00
|
|
|
this.buildCurrentObjectTree().catch((e) => {
|
|
|
|
console.log(e)
|
|
|
|
})
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
* Processes all blueprints and redies the store for population of the app
|
|
|
|
*/
|
|
|
|
async processBluePrints (): Promise<void> {
|
|
|
|
await engageBlueprints()
|
|
|
|
|
|
|
|
const allObjectBlueprints = (await retrieveAllBlueprints()).rows.map((blueprint) => {
|
|
|
|
return blueprint.doc
|
|
|
|
}) as I_Blueprint[]
|
|
|
|
|
|
|
|
this.SSET_allBlueprints(allObjectBlueprints)
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/****************************************************************/
|
|
|
|
// HIERARCHICAL TREE - HELPERS AND MODELS
|
|
|
|
/****************************************************************/
|
|
|
|
|
2021-03-08 11:07:40 +13:00
|
|
|
@Watch("$route", { deep: true })
|
|
|
|
async reactToRouteChange () {
|
|
|
|
// Wait for animations
|
|
|
|
await this.sleep(200)
|
|
|
|
if (this.SGET_allOpenedDocuments.docs.length > 0) {
|
|
|
|
const currentDoc = this.findRequestedOrActiveDocument() as unknown as I_OpenedDocument
|
|
|
|
this.selectedTreeNode = currentDoc._id
|
|
|
|
}
|
|
|
|
else {
|
2021-01-31 02:43:13 +13:00
|
|
|
this.selectedTreeNode = null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2021-01-31 02:43:13 +13:00
|
|
|
@Watch("SGET_allOpenedDocuments", { deep: true })
|
2021-02-28 06:00:57 +13:00
|
|
|
async reactToDocumentListChange (val: { treeAction: boolean, docs: I_OpenedDocument[]}) {
|
|
|
|
if (val.treeAction) {
|
|
|
|
await this.buildCurrentObjectTree()
|
|
|
|
this.buildTreeExpands(val?.docs)
|
|
|
|
this.lastDocsSnapShot = extend(true, [], val.docs)
|
|
|
|
}
|
|
|
|
else if (val.docs.length !== this.lastDocsSnapShot.length) {
|
|
|
|
this.lastDocsSnapShot = extend(true, [], val.docs)
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
2021-02-28 06:00:57 +13:00
|
|
|
lastDocsSnapShot:I_OpenedDocument[] = []
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
* Generic wrapper for adding of new object types to the tree
|
|
|
|
*/
|
|
|
|
menuAddNewItem = {
|
|
|
|
icon: "mdi-plus",
|
|
|
|
label: "Add new object type"
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Contains all the data for the render in tree
|
|
|
|
*/
|
|
|
|
hierarchicalTree: {children: I_ShortenedDocument[], icon: string, label: string}[] = []
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A resetter for the currently selected node
|
|
|
|
*/
|
2021-03-08 11:07:40 +13:00
|
|
|
selectedTreeNode = null as null | string
|
2021-02-23 11:30:18 +13:00
|
|
|
|
2021-02-26 14:50:46 +13:00
|
|
|
/**
|
|
|
|
* Holds all currently expanded notes
|
|
|
|
*/
|
2021-03-18 10:26:08 +13:00
|
|
|
expandedTreeNodes: string[] = []
|
2021-02-26 14:50:46 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
* Filter model for the tree
|
|
|
|
*/
|
|
|
|
treeFilter = ""
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets the tree filter and refocuses the search box
|
|
|
|
*/
|
|
|
|
resetTreeFilter () {
|
|
|
|
this.treeFilter = ""
|
|
|
|
const treeFilterDOM = this.$refs.treeFilter as unknown as HTMLInputElement
|
2021-03-03 14:10:05 +13:00
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
2021-02-23 11:30:18 +13:00
|
|
|
treeFilterDOM.focus()
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
|
|
// HIERARCHICAL TREE - CONTENT CONSTRUCTION
|
|
|
|
/****************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sort the whole tree via alphabetical and custom numeric order
|
|
|
|
* @param input Hierartchical tree object to sort
|
|
|
|
*/
|
2021-01-31 02:43:13 +13:00
|
|
|
sortDocuments (input: I_ShortenedDocument[]) {
|
|
|
|
input
|
2021-02-23 11:30:18 +13:00
|
|
|
|
|
|
|
// Sort by name
|
2021-01-31 02:43:13 +13:00
|
|
|
.sort((a, b) => a.label.localeCompare(b.label))
|
2021-02-23 11:30:18 +13:00
|
|
|
|
|
|
|
// Sort by custom order
|
2021-01-31 02:43:13 +13:00
|
|
|
.sort((a, b) => {
|
2021-03-18 10:26:08 +13:00
|
|
|
let order1 = 0
|
|
|
|
let order2 = 0
|
|
|
|
|
|
|
|
if (!this.invertTreeSorting) {
|
|
|
|
order1 = a.extraFields.find(e => e.id === "order")?.value
|
|
|
|
order2 = b.extraFields.find(e => e.id === "order")?.value
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
order2 = a.extraFields.find(e => e.id === "order")?.value
|
|
|
|
order1 = b.extraFields.find(e => e.id === "order")?.value
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
if (order1 > order2) {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
if (order1 < order2) {
|
|
|
|
return -1
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
|
2021-02-28 06:00:57 +13:00
|
|
|
// Put the number value on top of the list and alphabetical below them
|
|
|
|
input = [
|
|
|
|
...input.filter(e => e.extraFields.find(e => e.id === "order")?.value),
|
|
|
|
...input.filter(e => !e.extraFields.find(e => e.id === "order")?.value)
|
|
|
|
]
|
|
|
|
|
2021-01-31 02:43:13 +13:00
|
|
|
input.forEach((e, i) => {
|
2021-02-23 11:30:18 +13:00
|
|
|
// Run recursive if the node has any children
|
|
|
|
if (e.children.length > 0) {
|
|
|
|
input[i].children = this.sortDocuments(input[i].children)
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
})
|
|
|
|
|
|
|
|
return input
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
* Builds proper hiearachy for flat array of documents
|
|
|
|
* @param input Non-hierarchical tree to build the hiearachy out of
|
|
|
|
*/
|
2021-01-31 02:43:13 +13:00
|
|
|
buildTreeHierarchy (input: I_ShortenedDocument[]) {
|
|
|
|
const map: number[] = []
|
|
|
|
let node
|
|
|
|
const roots = []
|
|
|
|
let i
|
|
|
|
|
|
|
|
for (i = 0; i < input.length; i += 1) {
|
2021-02-23 11:30:18 +13:00
|
|
|
// Initialize the map
|
|
|
|
map[input[i]._id] = i
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < input.length; i += 1) {
|
|
|
|
node = input[i]
|
|
|
|
if (node.parentDoc !== false) {
|
2021-02-23 11:30:18 +13:00
|
|
|
// If there are any dangling branches check that map[node.parentDoc] exists
|
2021-01-31 02:43:13 +13:00
|
|
|
if (input[map[node.parentDoc]]) {
|
|
|
|
input[map[node.parentDoc]].children.push(node)
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
else {
|
2021-01-31 02:43:13 +13:00
|
|
|
roots.push(node)
|
|
|
|
}
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
else {
|
2021-01-31 02:43:13 +13:00
|
|
|
roots.push(node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const sortedRoots = this.sortDocuments(roots)
|
|
|
|
|
|
|
|
return sortedRoots
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
/**
|
|
|
|
* Builds a brand new sparkling hearchy tree out of available data
|
|
|
|
*/
|
2021-01-31 02:43:13 +13:00
|
|
|
async buildCurrentObjectTree () {
|
|
|
|
const allBlueprings = this.SGET_allBlueprints
|
2021-03-18 10:26:08 +13:00
|
|
|
let treeObject: any[] = []
|
2021-03-03 14:10:05 +13:00
|
|
|
let allTreeDocuments: I_ShortenedDocument[] = []
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
// Process all documents, build hieararchy out of the and sort them via name and custom order
|
2021-01-31 02:43:13 +13:00
|
|
|
for (const blueprint of allBlueprings) {
|
|
|
|
const CurrentObjectDB = new PouchDB(blueprint._id)
|
|
|
|
|
|
|
|
const allDocuments = await CurrentObjectDB.allDocs({ include_docs: true })
|
|
|
|
|
|
|
|
const allDocumentsRows = allDocuments.rows
|
|
|
|
.map((singleDocument) => {
|
|
|
|
const doc = singleDocument.doc as unknown as I_ShortenedDocument
|
|
|
|
|
2021-02-09 15:21:48 +13:00
|
|
|
const parentDocID = doc.extraFields.find(e => e.id === "parentDoc")?.value.value as unknown as {_id: string}
|
2021-02-21 01:06:21 +13:00
|
|
|
const color = doc.extraFields.find(e => e.id === "documentColor")?.value as unknown as string
|
|
|
|
const isCategory = doc.extraFields.find(e => e.id === "categorySwitch")?.value as unknown as string
|
2021-01-31 02:43:13 +13:00
|
|
|
|
|
|
|
return {
|
|
|
|
label: doc.extraFields.find(e => e.id === "name")?.value,
|
2021-02-21 01:06:21 +13:00
|
|
|
icon: (isCategory) ? "fas fa-folder-open" : doc.icon,
|
2021-03-05 12:51:41 +13:00
|
|
|
isCategory: !!(isCategory),
|
2021-01-31 02:43:13 +13:00
|
|
|
sticker: doc.extraFields.find(e => e.id === "order")?.value,
|
|
|
|
parentDoc: (parentDocID) ? parentDocID._id : false,
|
2021-02-23 11:30:18 +13:00
|
|
|
handler: this.openExistingDocumentRoute,
|
2021-01-31 02:43:13 +13:00
|
|
|
expandable: true,
|
2021-02-21 01:06:21 +13:00
|
|
|
color: color,
|
2021-01-31 02:43:13 +13:00
|
|
|
type: doc.type,
|
|
|
|
children: [],
|
|
|
|
hasEdits: false,
|
|
|
|
isNew: false,
|
|
|
|
url: doc.url,
|
|
|
|
extraFields: (doc?.extraFields) || [],
|
2021-02-21 03:13:37 +13:00
|
|
|
_id: singleDocument.id,
|
|
|
|
key: singleDocument.id
|
2021-01-31 02:43:13 +13:00
|
|
|
} as I_ShortenedDocument
|
|
|
|
})
|
|
|
|
|
2021-03-05 12:51:41 +13:00
|
|
|
const documentCount = allDocumentsRows.filter(e => !e.isCategory).length
|
|
|
|
const categoryCount = allDocumentsRows.filter(e => e.isCategory).length
|
|
|
|
const allCount = allDocumentsRows.length
|
|
|
|
|
2021-04-06 01:28:33 +12:00
|
|
|
// @ts-ignore
|
|
|
|
allTreeDocuments = [...allTreeDocuments, ...extend(true, [], allDocumentsRows)]
|
2021-01-31 14:46:23 +13:00
|
|
|
|
2021-01-31 02:43:13 +13:00
|
|
|
const hierarchicalTreeContent = this.buildTreeHierarchy(allDocumentsRows)
|
|
|
|
|
|
|
|
const treeRow = {
|
|
|
|
label: blueprint.namePlural,
|
|
|
|
icon: blueprint.icon,
|
2021-01-31 14:46:23 +13:00
|
|
|
order: blueprint.order,
|
2021-01-31 02:43:13 +13:00
|
|
|
_id: blueprint._id,
|
2021-02-21 03:13:37 +13:00
|
|
|
key: blueprint._id,
|
2021-02-23 11:30:18 +13:00
|
|
|
handler: this.addNewObjectRoute,
|
2021-01-31 02:43:13 +13:00
|
|
|
specialLabel: blueprint.nameSingular.toLowerCase(),
|
2021-01-31 14:46:23 +13:00
|
|
|
isRoot: true,
|
2021-03-05 12:51:41 +13:00
|
|
|
allCount: allCount,
|
2021-01-31 14:46:23 +13:00
|
|
|
documentCount: documentCount,
|
2021-03-05 12:51:41 +13:00
|
|
|
categoryCount: categoryCount,
|
2021-01-31 02:43:13 +13:00
|
|
|
children: [
|
|
|
|
...hierarchicalTreeContent,
|
|
|
|
{
|
|
|
|
label: `Add new ${blueprint.nameSingular.toLowerCase()}`,
|
|
|
|
icon: "mdi-plus",
|
2021-02-23 11:30:18 +13:00
|
|
|
handler: this.addNewObjectRoute,
|
|
|
|
children: false,
|
|
|
|
key: `${blueprint._id}_add`,
|
|
|
|
_id: blueprint._id,
|
|
|
|
specialLabel: blueprint.nameSingular.toLowerCase()
|
|
|
|
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
treeObject.push(treeRow)
|
2021-04-06 01:28:33 +12:00
|
|
|
|
|
|
|
await CurrentObjectDB.close()
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
// Sort the top level of the blueprints
|
2021-01-31 14:46:23 +13:00
|
|
|
treeObject.sort((a, b) => {
|
|
|
|
if (a.order < b.order) {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if (a.order > b.order) {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
if (!this.noTags) {
|
|
|
|
const tagList = await tagListBuildFromBlueprints(this.SGET_allBlueprints)
|
2021-03-03 14:10:05 +13:00
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
let allTags = 0
|
|
|
|
let allTagsCategories = 0
|
|
|
|
let allTagsDocuments = 0
|
|
|
|
|
|
|
|
let tagNodeList = tagList.map((tag: string) => {
|
|
|
|
const tagDocs = allTreeDocuments
|
|
|
|
.filter(doc => {
|
|
|
|
const docTags = doc.extraFields.find(e => e.id === "tags")?.value as unknown as string[]
|
|
|
|
return (docTags && docTags.includes(tag))
|
|
|
|
})
|
|
|
|
.map((doc:I_ShortenedDocument) => {
|
2021-03-03 14:10:05 +13:00
|
|
|
// @ts-ignore
|
2021-03-18 10:26:08 +13:00
|
|
|
doc.key = `${tag}${doc._id}`
|
|
|
|
// @ts-ignore
|
|
|
|
// doc.isTag = true
|
|
|
|
return doc
|
|
|
|
})
|
|
|
|
.sort((a, b) => a.label.localeCompare(b.label))
|
|
|
|
|
|
|
|
const documentCount = tagDocs.filter(e => !e.isCategory).length
|
|
|
|
const categoryCount = tagDocs.filter(e => e.isCategory).length
|
|
|
|
const allCount = tagDocs.length
|
|
|
|
|
|
|
|
allTags += allCount
|
|
|
|
allTagsCategories += categoryCount
|
|
|
|
allTagsDocuments += documentCount
|
|
|
|
|
|
|
|
return {
|
|
|
|
label: `${tag}`,
|
|
|
|
icon: "mdi-tag",
|
|
|
|
_id: `tag-${tag}`,
|
|
|
|
key: `tag-${tag}`,
|
|
|
|
allCount: allCount,
|
|
|
|
documentCount: documentCount,
|
|
|
|
categoryCount: categoryCount,
|
|
|
|
isRoot: true,
|
|
|
|
isTag: true,
|
|
|
|
children: tagDocs
|
|
|
|
}
|
|
|
|
})
|
2021-03-03 14:10:05 +13:00
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
if (this.compactTags && tagNodeList.length > 0) {
|
|
|
|
tagNodeList = [
|
|
|
|
{
|
|
|
|
label: "Tags",
|
|
|
|
icon: "mdi-tag",
|
|
|
|
_id: "tagsList",
|
|
|
|
key: "tagList",
|
|
|
|
isRoot: true,
|
|
|
|
allCount: allTags,
|
|
|
|
documentCount: allTagsDocuments,
|
|
|
|
categoryCount: allTagsCategories,
|
|
|
|
isTag: true,
|
|
|
|
// @ts-ignore
|
|
|
|
children: tagNodeList.map(e => {
|
|
|
|
e.isRoot = false
|
|
|
|
return e
|
|
|
|
})
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2021-03-05 12:51:41 +13:00
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
if (this.tagsAtTop) {
|
|
|
|
treeObject = [...tagNodeList, ...treeObject]
|
2021-03-03 14:10:05 +13:00
|
|
|
}
|
2021-03-18 10:26:08 +13:00
|
|
|
else {
|
|
|
|
treeObject = [...treeObject, ...tagNodeList]
|
|
|
|
}
|
|
|
|
}
|
2021-03-03 14:10:05 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
// Assign the finished object to the render model
|
|
|
|
this.hierarchicalTree = treeObject
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
processNodeNewDocumentButton (node: {
|
|
|
|
key: string
|
|
|
|
_id: string
|
|
|
|
children: []
|
|
|
|
type: string
|
|
|
|
isRoot: boolean
|
|
|
|
specialLabel: string|boolean
|
|
|
|
}) {
|
|
|
|
// If this is top level blueprint
|
|
|
|
if (node.isRoot) {
|
|
|
|
// @ts-ignore
|
|
|
|
this.addNewObjectRoute(node)
|
|
|
|
}
|
|
|
|
// If this is a custom document
|
|
|
|
else {
|
|
|
|
const routeObject = {
|
|
|
|
_id: node.type,
|
|
|
|
parent: node._id
|
|
|
|
}
|
|
|
|
// @ts-ignore
|
|
|
|
this.addNewObjectRoute(routeObject)
|
|
|
|
}
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-02-28 06:00:57 +13:00
|
|
|
buildTreeExpands (newDocs: I_OpenedDocument[]) {
|
|
|
|
const expandIDs: string[] = []
|
|
|
|
|
2021-04-06 01:28:33 +12:00
|
|
|
let newDocsSnapshot: I_OpenedDocument[] = extend(true, [], newDocs)
|
2021-03-18 10:26:08 +13:00
|
|
|
|
2021-02-28 06:00:57 +13:00
|
|
|
// Check for parent changes
|
2021-03-18 10:26:08 +13:00
|
|
|
newDocsSnapshot.forEach((s, index) => {
|
2021-02-28 06:00:57 +13:00
|
|
|
const oldParentDoc = this.lastDocsSnapShot.find(doc => doc._id === s._id)
|
|
|
|
// Fizzle if the parent doesn't exist in the old version
|
|
|
|
if (!oldParentDoc) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
const oldParentDocField = this.retrieveFieldValue(oldParentDoc, "parentDoc")
|
|
|
|
// @ts-ignore
|
|
|
|
const oldParentDocID = (oldParentDocField?.value) ? oldParentDocField.value.value : ""
|
|
|
|
|
|
|
|
const newParentDocField = this.retrieveFieldValue(s, "parentDoc")
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
const newParentDocID = (newParentDocField?.value) ? newParentDocField.value.value : ""
|
|
|
|
if ((newParentDocID !== oldParentDocID) || (newParentDocID && oldParentDoc.isNew)) {
|
|
|
|
expandIDs.push(newParentDocID)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// Process top level documents
|
2021-03-18 10:26:08 +13:00
|
|
|
newDocsSnapshot.forEach(s => {
|
2021-02-28 06:00:57 +13:00
|
|
|
const newParentDocField = this.retrieveFieldValue(s, "parentDoc")
|
2021-03-18 10:26:08 +13:00
|
|
|
const oldParentDoc = this.lastDocsSnapShot.find(doc => doc._id === s._id)
|
|
|
|
// @ts-ignore
|
|
|
|
const oldParentDocField = this.retrieveFieldValue(oldParentDoc, "parentDoc")
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
const oldParentDocID = (oldParentDocField?.value) ? oldParentDocField.value.value : false
|
2021-02-28 06:00:57 +13:00
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
const newParentDocID = (newParentDocField?.value) ? newParentDocField.value.value : false
|
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
if (!newParentDocID && oldParentDocID !== newParentDocID) {
|
2021-02-28 06:00:57 +13:00
|
|
|
expandIDs.push(s.type)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-04-06 01:28:33 +12:00
|
|
|
// @ts-ignore
|
|
|
|
newDocsSnapshot = null
|
|
|
|
|
2021-03-03 08:59:56 +13:00
|
|
|
expandIDs.forEach(s => {
|
2021-02-28 06:00:57 +13:00
|
|
|
this.recursivelyExpandNode(s)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
recursivelyExpandNode (nodeID: string) {
|
|
|
|
const treeDOM = this.$refs.tree as unknown as {
|
|
|
|
setExpanded: (key:string, state: boolean)=> void
|
|
|
|
getNodeByKey: (key:string)=> void
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
this.expandedTreeNodes = [...new Set([
|
|
|
|
...this.expandedTreeNodes,
|
|
|
|
nodeID
|
|
|
|
])]
|
|
|
|
|
|
|
|
const currentTreeNode = (treeDOM.getNodeByKey(nodeID)) as unknown as {parentDoc: string, type: string}
|
|
|
|
|
|
|
|
// Dig into the upper hierarchy
|
|
|
|
if (currentTreeNode?.parentDoc) {
|
|
|
|
this.recursivelyExpandNode(currentTreeNode.parentDoc)
|
|
|
|
}
|
|
|
|
// If we are at the top of the tree, expand the top category
|
|
|
|
else if (currentTreeNode?.type) {
|
|
|
|
// @ts-ignore
|
|
|
|
this.expandedTreeNodes = [...new Set([
|
|
|
|
...this.expandedTreeNodes,
|
|
|
|
currentTreeNode.type
|
|
|
|
])]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
processNodeLabelMiddleClick (node: {
|
|
|
|
key: string
|
|
|
|
_id: string
|
|
|
|
children: []
|
|
|
|
type: string
|
|
|
|
isRoot: boolean
|
2021-03-03 14:10:05 +13:00
|
|
|
isTag: boolean
|
2021-02-23 11:30:18 +13:00
|
|
|
specialLabel: string|boolean
|
|
|
|
}) {
|
2021-03-03 14:10:05 +13:00
|
|
|
if (node.isRoot && node.isTag) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
if (!node.specialLabel && !node.isRoot) {
|
|
|
|
// @ts-ignore
|
|
|
|
this.openExistingDocumentRoute(node)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.addNewObjectRoute(node)
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
processNodeClick (node: {
|
|
|
|
key: string
|
|
|
|
children: []
|
|
|
|
specialLabel: string|boolean
|
|
|
|
}) {
|
|
|
|
// If this is a category or has children
|
|
|
|
if (node.children.length > 0) {
|
|
|
|
this.expandeCollapseNode(node)
|
|
|
|
}
|
|
|
|
// If this lacks a "special label" - AKA anything that isn't the "Add new XY" node
|
|
|
|
else if (!node.specialLabel) {
|
|
|
|
// @ts-ignore
|
|
|
|
this.openExistingDocumentRoute(node)
|
|
|
|
}
|
|
|
|
// If this lacks a "special label" - AKA if this is the "Add new XY" node
|
|
|
|
else {
|
|
|
|
// @ts-ignore
|
|
|
|
this.addNewObjectRoute(node)
|
|
|
|
}
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
expandeCollapseNode (node: {key: string, children: []}) {
|
2021-02-23 11:30:18 +13:00
|
|
|
const treeDOM = this.$refs.tree as unknown as {
|
|
|
|
setExpanded: (key:string, state: boolean)=> void,
|
|
|
|
isExpanded: (key:string)=> boolean
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
const isExpanded = treeDOM.isExpanded(node.key)
|
2021-03-18 10:26:08 +13:00
|
|
|
|
|
|
|
if (isExpanded) {
|
|
|
|
this.collapseAllNodes(node)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
treeDOM.setExpanded(node.key, true)
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
2021-03-03 14:10:05 +13:00
|
|
|
|
|
|
|
determineNodeColor (node: {color: string, isTag: boolean, isRoot: boolean}) {
|
|
|
|
// @ts-ignore
|
2021-03-18 10:26:08 +13:00
|
|
|
return (node?.isTag) ? colors.getBrand("primary") : node.color
|
|
|
|
}
|
|
|
|
|
|
|
|
collapseAllNodes (node: {key: string, children: []}) {
|
|
|
|
if (node.children && !this.doNotcollaseTreeOptions) {
|
|
|
|
for (const child of node.children) {
|
|
|
|
if (this.expandedTreeNodes.includes(node.key)) {
|
|
|
|
this.collapseAllNodes(child)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.expandedTreeNodes.includes(node.key)) {
|
|
|
|
this.expandedTreeNodes = this.expandedTreeNodes.filter(n => n !== node.key)
|
|
|
|
}
|
2021-03-03 14:10:05 +13:00
|
|
|
}
|
2021-03-19 14:54:44 +13:00
|
|
|
|
|
|
|
determineCatyegoryString (node: {
|
|
|
|
documentCount: string
|
|
|
|
categoryCount: string
|
|
|
|
}) {
|
|
|
|
let extraDivider = ""
|
|
|
|
if (this.doubleDashDocCount) {
|
|
|
|
extraDivider = "|"
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.compactDocumentCount) {
|
|
|
|
return `(<span class="docCount">${node.documentCount}</span>)`
|
|
|
|
}
|
|
|
|
if (this.invertCategoryPosition) {
|
|
|
|
return `(<span class="catCount">${node.categoryCount}</span> |${extraDivider} <span class="docCount">${node.documentCount}</span>)`
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return `(<span class="docCount">${node.documentCount}</span> |${extraDivider} <span class="catCount">${node.categoryCount}</span>)`
|
|
|
|
}
|
|
|
|
}
|
2021-01-31 02:43:13 +13:00
|
|
|
}
|
|
|
|
</script>
|
2021-02-09 15:21:48 +13:00
|
|
|
|
|
|
|
<style lang="scss">
|
2021-03-05 12:51:41 +13:00
|
|
|
|
2021-03-08 11:07:40 +13:00
|
|
|
.projectTitle {
|
|
|
|
margin: 0 0 -5px 0;
|
2021-03-18 10:26:08 +13:00
|
|
|
padding: 10px 10px 0;
|
2021-03-08 11:07:40 +13:00
|
|
|
}
|
|
|
|
|
2021-02-09 15:21:48 +13:00
|
|
|
.objectTree {
|
2021-03-18 10:26:08 +13:00
|
|
|
&.hasTextShadow {
|
|
|
|
.documentLabel {
|
|
|
|
font-weight: 500;
|
|
|
|
$shadowColorOutline: #000;
|
|
|
|
$shadowColorSurround: #000;
|
|
|
|
|
|
|
|
filter: drop-shadow(0 0 4px #000);
|
|
|
|
text-shadow:
|
|
|
|
-2px -2px 0 $shadowColorSurround,
|
|
|
|
2px -2px 0 $shadowColorSurround,
|
|
|
|
-2px 2px 0 $shadowColorSurround,
|
|
|
|
2px 2px 0 $shadowColorSurround,
|
|
|
|
-1px -1px 0 $shadowColorOutline,
|
|
|
|
1px -1px 0 $shadowColorOutline,
|
|
|
|
-1px 1px 0 $shadowColorOutline,
|
|
|
|
1px 1px 0 $shadowColorOutline;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 14:54:44 +13:00
|
|
|
.catCount {
|
|
|
|
color: var(--q-color-accent);
|
|
|
|
}
|
|
|
|
|
|
|
|
.docCount {
|
|
|
|
color: var(--q-color-primary);
|
|
|
|
}
|
|
|
|
|
2021-03-08 11:07:40 +13:00
|
|
|
> .q-tree__node {
|
|
|
|
padding-left: 0 !important;
|
|
|
|
}
|
|
|
|
|
|
|
|
.q-tree__children {
|
|
|
|
padding-left: 5px;
|
|
|
|
}
|
2021-03-05 12:51:41 +13:00
|
|
|
|
2021-02-09 15:21:48 +13:00
|
|
|
.q-tree__arrow {
|
2021-02-23 11:30:18 +13:00
|
|
|
margin-right: 0;
|
2021-02-26 14:50:46 +13:00
|
|
|
padding: 4px 4px 4px 0;
|
2021-03-08 11:07:40 +13:00
|
|
|
position: absolute;
|
|
|
|
pointer-events: none;
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
|
2021-03-05 12:51:41 +13:00
|
|
|
.q-tree__node {
|
|
|
|
padding: 0 0 0 22px;
|
|
|
|
}
|
|
|
|
|
2021-02-23 11:30:18 +13:00
|
|
|
.q-tree__node-header {
|
|
|
|
padding: 0;
|
2021-03-08 11:07:40 +13:00
|
|
|
|
|
|
|
&:focus {
|
|
|
|
> .q-focus-helper {
|
|
|
|
opacity: 0 !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
> .q-focus-helper {
|
|
|
|
opacity: 0.15 !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&.q-tree__node--selected {
|
|
|
|
> .q-focus-helper {
|
|
|
|
opacity: 0.22 !important;
|
|
|
|
}
|
|
|
|
}
|
2021-02-09 15:21:48 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
.documentLabel {
|
2021-02-23 11:30:18 +13:00
|
|
|
width: 100%;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
2021-03-08 11:07:40 +13:00
|
|
|
padding: 4px 4px 4px 25px;
|
|
|
|
align-items: center;
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
.treeButtonGroup {
|
|
|
|
flex-grow: 0;
|
|
|
|
flex-shrink: 0;
|
|
|
|
display: flex;
|
|
|
|
height: fit-content;
|
|
|
|
margin-left: auto;
|
|
|
|
align-self: center;
|
2021-02-09 15:21:48 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-26 14:50:46 +13:00
|
|
|
.treeBadge {
|
|
|
|
left: inherit;
|
|
|
|
right: calc(100% + 3px);
|
|
|
|
padding: 3px 2px;
|
|
|
|
border: none;
|
|
|
|
background: rgba($primary, 0.15);
|
|
|
|
top: 50%;
|
|
|
|
transform: translateY(-50%);
|
|
|
|
min-width: 24px;
|
|
|
|
justify-content: center;
|
2021-03-03 08:59:56 +13:00
|
|
|
|
|
|
|
&.noChilden {
|
2021-03-08 11:07:40 +13:00
|
|
|
right: calc(100% + 3px);
|
2021-03-03 08:59:56 +13:00
|
|
|
}
|
2021-02-26 14:50:46 +13:00
|
|
|
}
|
2021-02-23 11:30:18 +13:00
|
|
|
|
2021-03-05 12:51:41 +13:00
|
|
|
.treeSearchWrapper {
|
2021-03-18 10:26:08 +13:00
|
|
|
top: -55px;
|
|
|
|
left: 0;
|
|
|
|
position: fixed;
|
2021-03-05 12:51:41 +13:00
|
|
|
width: 375px;
|
|
|
|
z-index: 555;
|
|
|
|
background-color: $dark;
|
|
|
|
|
2021-03-18 10:26:08 +13:00
|
|
|
&.fullWidth {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
2021-03-05 12:51:41 +13:00
|
|
|
> div {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
label {
|
|
|
|
background-color: $dark;
|
|
|
|
|
|
|
|
&.q-field--focused {
|
|
|
|
width: 100vw;
|
|
|
|
max-width: inherit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-26 14:50:46 +13:00
|
|
|
.treeButton {
|
2021-02-23 11:30:18 +13:00
|
|
|
&--add {
|
|
|
|
.q-icon {
|
|
|
|
font-size: 20px;
|
2021-02-26 14:50:46 +13:00
|
|
|
color: $primary;
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&--edit {
|
|
|
|
.q-icon {
|
|
|
|
font-size: 14px;
|
2021-02-26 14:50:46 +13:00
|
|
|
color: #fff;
|
2021-02-23 11:30:18 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-18 10:26:08 +13:00
|
|
|
|
|
|
|
body.body--dark {
|
|
|
|
.objectTree {
|
|
|
|
.documentLabel {
|
|
|
|
color: #dcdcdc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.projectTitle {
|
|
|
|
color: #dcdcdc;
|
|
|
|
}
|
|
|
|
}
|
2021-02-09 15:21:48 +13:00
|
|
|
</style>
|