mirror of
https://github.com/Elvanos/fantasia-archive.git
synced 2024-09-28 15:21:45 +12:00
0.1.5 - Added context menus and document actions, various fixes
This commit is contained in:
parent
51e8df56c1
commit
1cfd078a21
22 changed files with 911 additions and 63 deletions
|
@ -74,8 +74,11 @@ function createWindow () {
|
|||
})
|
||||
)
|
||||
}
|
||||
|
||||
console.log(params.dictionarySuggestions)
|
||||
console.log(params.misspelledWord)
|
||||
if((params.dictionarySuggestions && params.dictionarySuggestions.length) || params.misspelledWord){
|
||||
menu.popup()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -302,6 +302,11 @@ export default class BaseClass extends Vue {
|
|||
treeAction: boolean
|
||||
}) => void
|
||||
|
||||
@OpenedDocuments.Action("closeAllDocuments") SSET_closeAllDocuments!: () => void
|
||||
@OpenedDocuments.Action("forceCloseAllDocuments") SSET_forceCloseAllDocuments!: () => void
|
||||
@OpenedDocuments.Action("closeAllButCurrentDocuments") SSET_closeAllButCurrentDocuments!: (input: I_OpenedDocument) => void
|
||||
@OpenedDocuments.Action("forceCloseAllButCurrentDocuments") SSET_forceCloseAllButCurrentDocuments!: (input: I_OpenedDocument) => void
|
||||
|
||||
@OpenedDocuments.Action("triggerTreeAction") SSET_triggerTreeAction!: () => void
|
||||
@OpenedDocuments.Action("resetDocuments") SSET_resetDocuments!: () => void
|
||||
@OpenedDocuments.Action("resetRemoveIndex") SSET_resetRemoveIndex!: () => void
|
||||
|
|
|
@ -197,6 +197,23 @@
|
|||
</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-btn
|
||||
icon="mdi-content-copy"
|
||||
color="primary"
|
||||
outline
|
||||
@click="copyTargetDocument"
|
||||
v-if="!currentlyNew && SGET_allOpenedDocuments.docs.length > 0"
|
||||
>
|
||||
<q-tooltip
|
||||
:delay="500"
|
||||
max-width="500px"
|
||||
anchor="bottom left"
|
||||
self="top middle"
|
||||
>
|
||||
Copy current document
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-separator vertical inset color="accent"
|
||||
v-if="!currentlyNew && SGET_allOpenedDocuments.docs.length > 0"
|
||||
/>
|
||||
|
@ -240,6 +257,8 @@ import tipsTricksTriviaDialog from "src/components/dialogs/TipsTricksTrivia.vue"
|
|||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { extend, Loading, QSpinnerGears } from "quasar"
|
||||
import { saveDocument } from "src/scripts/databaseManager/documentManager"
|
||||
import { createNewWithParent } from "src/scripts/documentActions/createNewWithParent"
|
||||
import { copyDocument } from "src/scripts/documentActions/copyDocument"
|
||||
|
||||
import { retrieveCurrentProjectName, exportProject } from "src/scripts/projectManagement/projectManagent"
|
||||
|
||||
|
@ -311,6 +330,12 @@ export default class DocumentControl extends BaseClass {
|
|||
await this.sleep(100)
|
||||
this.addNewUnderParent()
|
||||
}
|
||||
|
||||
// Add new under parent - CTRL + ALT + C
|
||||
if (this.determineKeyBind("copyDocument") && !this.currentlyNew && this.SGET_allOpenedDocuments.docs.length > 0 && !this.SGET_getDialogsState) {
|
||||
await this.sleep(100)
|
||||
this.copyTargetDocument()
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
@ -414,15 +439,36 @@ export default class DocumentControl extends BaseClass {
|
|||
// Add new document under parent
|
||||
/****************************************************************/
|
||||
addNewUnderParent () {
|
||||
const currentDoc = this.findRequestedOrActiveDocument()
|
||||
if (currentDoc) {
|
||||
const routeObject = {
|
||||
_id: currentDoc.type,
|
||||
parent: currentDoc._id
|
||||
const currentDoc = this.findRequestedOrActiveDocument() as I_OpenedDocument
|
||||
createNewWithParent(currentDoc, this)
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Document copy
|
||||
/****************************************************************/
|
||||
documentPass = null as unknown as I_OpenedDocument
|
||||
|
||||
copyTargetDocument () {
|
||||
this.documentPass = extend(true, {}, this.findRequestedOrActiveDocument())
|
||||
|
||||
const newDocument = copyDocument(this.documentPass, this.generateUID())
|
||||
|
||||
const dataPass = {
|
||||
doc: newDocument,
|
||||
treeAction: false
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.addNewObjectRoute(routeObject)
|
||||
this.SSET_addOpenedDocument(dataPass)
|
||||
this.$router.push({
|
||||
path: newDocument.url
|
||||
}).catch((e: {name: string}) => {
|
||||
const errorName : string = e.name
|
||||
if (errorName === "NavigationDuplicated") {
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
<template>
|
||||
|
||||
<span>
|
||||
|
||||
<!-- Delele document dialog -->
|
||||
<deleteDocumentCheckDialog
|
||||
:dialog-trigger="deleteObjectDialogTrigger"
|
||||
:document-id="toDeleteID"
|
||||
:document-type="toDeleteType"
|
||||
@trigger-dialog-close="deleteObjectDialogClose"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="treeSearchWrapper"
|
||||
:class="{'fullWidth': disableDocumentControlBar}"
|
||||
|
@ -65,7 +74,7 @@
|
|||
:name="prop.node.icon"
|
||||
class="q-mr-sm self-center" />
|
||||
<span v-if="prop.node.isDead" class="documentLabel__isDeadMarker">†</span>
|
||||
<span class="documentLabel__content">
|
||||
<span :class="{'documentLabel__content': !hideDeadCrossThrough}">
|
||||
{{ prop.node.label }}
|
||||
</span>
|
||||
|
||||
|
@ -86,7 +95,7 @@
|
|||
<q-badge
|
||||
class="treeBadge"
|
||||
:class="{'noChilden': prop.node.children.length === 0}"
|
||||
v-if="prop.node.sticker"
|
||||
v-if="prop.node.sticker && !hideTreeOrderNumbers"
|
||||
color="primary"
|
||||
outline
|
||||
floating
|
||||
|
@ -125,7 +134,7 @@
|
|||
dense
|
||||
color="dark"
|
||||
class="z-1 q-ml-sm treeButton treeButton--add"
|
||||
icon="mdi-plus"
|
||||
icon="mdi-file-tree"
|
||||
size="10px"
|
||||
@click.stop.prevent="processNodeNewDocumentButton(prop.node)"
|
||||
>
|
||||
|
@ -136,6 +145,89 @@
|
|||
</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
<q-menu
|
||||
touch-position
|
||||
context-menu
|
||||
>
|
||||
|
||||
<q-list class="bg-gunmetal-light" v-if="!prop.node.isTag">
|
||||
|
||||
<template v-if="prop.node.isRoot || prop.node.children.length > 0">
|
||||
<q-item clickable v-close-popup @click="recursivelyExpandNodeDownwards(prop.node.key)">
|
||||
<q-item-section>Expand all</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-expand-all-outline" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="collapseAllNodesForce(prop.node)">
|
||||
<q-item-section>Collapse all</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-collapse-all-outline" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<template v-if="prop.node.isRoot">
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="addNewObjectRoute(prop.node)">
|
||||
<q-item-section>Add new document of type: {{prop.node.label}}</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-plus" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<template v-if="!prop.node.isRoot">
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="copyName(prop.node)">
|
||||
<q-item-section>Copy name</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-text-recognition" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="copyTextColor(prop.node)">
|
||||
<q-item-section>Copy text color</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-eyedropper" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="copyBackgroundColor(prop.node)">
|
||||
<q-item-section>Copy background color</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-format-color-fill" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="openExistingDocumentRoute(prop.node)">
|
||||
<q-item-section>Open document</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-pencil" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="addNewUnderParent(prop.node)">
|
||||
<q-item-section>Create new document with this document as parent</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-file-tree" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="copyTargetDocument(prop.node)">
|
||||
<q-item-section>Copy this document</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-content-copy" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="deleteTabDocument(prop.node)">
|
||||
<q-item-section class="text-secondary"><b>Delete this document</b></q-item-section>
|
||||
<q-item-section avatar class="text-secondary">
|
||||
<q-icon name="mdi-text-box-remove-outline" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
</q-list>
|
||||
|
||||
</q-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -175,15 +267,20 @@ import { Component, Watch } from "vue-property-decorator"
|
|||
import BaseClass from "src/BaseClass"
|
||||
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import PouchDB from "pouchdb"
|
||||
import deleteDocumentCheckDialog from "src/components/dialogs/DeleteDocumentCheck.vue"
|
||||
|
||||
import { engageBlueprints, retrieveAllBlueprints } from "src/scripts/databaseManager/blueprintManager"
|
||||
// import { cleanDatabases } from "src/scripts/databaseManager/cleaner"
|
||||
import { I_Blueprint } from "src/interfaces/I_Blueprint"
|
||||
import { extend, colors } from "quasar"
|
||||
import { tagListBuildFromBlueprints } from "src/scripts/utilities/tagListBuilder"
|
||||
import { retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
|
||||
import { createNewWithParent } from "src/scripts/documentActions/createNewWithParent"
|
||||
import { copyDocumentName, copyDocumentTextColor, copyDocumentBackgroundColor } from "src/scripts/documentActions/uniqueFieldCopy"
|
||||
import { copyDocument } from "src/scripts/documentActions/copyDocument"
|
||||
|
||||
@Component({
|
||||
components: { }
|
||||
components: { deleteDocumentCheckDialog }
|
||||
})
|
||||
export default class ObjectTree extends BaseClass {
|
||||
/****************************************************************/
|
||||
|
@ -234,6 +331,8 @@ export default class ObjectTree extends BaseClass {
|
|||
compactDocumentCount = false
|
||||
invertCategoryPosition = false
|
||||
doubleDashDocCount = false
|
||||
hideDeadCrossThrough = false
|
||||
hideTreeOrderNumbers = false
|
||||
|
||||
@Watch("SGET_options", { immediate: true, deep: true })
|
||||
onSettingsChange () {
|
||||
|
@ -250,6 +349,9 @@ export default class ObjectTree extends BaseClass {
|
|||
this.compactDocumentCount = options.compactDocumentCount
|
||||
this.invertCategoryPosition = options.invertCategoryPosition
|
||||
this.doubleDashDocCount = options.doubleDashDocCount
|
||||
this.hideDeadCrossThrough = options.hideDeadCrossThrough
|
||||
this.hideTreeOrderNumbers = options.hideTreeOrderNumbers
|
||||
|
||||
this.buildCurrentObjectTree().catch((e) => {
|
||||
console.log(e)
|
||||
})
|
||||
|
@ -696,11 +798,11 @@ export default class ObjectTree extends BaseClass {
|
|||
newDocsSnapshot = null
|
||||
|
||||
expandIDs.forEach(s => {
|
||||
this.recursivelyExpandNode(s)
|
||||
this.recursivelyExpandNodeUpwards(s)
|
||||
})
|
||||
}
|
||||
|
||||
recursivelyExpandNode (nodeID: string) {
|
||||
recursivelyExpandNodeUpwards (nodeID: string) {
|
||||
const treeDOM = this.$refs.tree as unknown as {
|
||||
setExpanded: (key:string, state: boolean)=> void
|
||||
getNodeByKey: (key:string)=> void
|
||||
|
@ -716,7 +818,37 @@ export default class ObjectTree extends BaseClass {
|
|||
|
||||
// Dig into the upper hierarchy
|
||||
if (currentTreeNode?.parentDoc) {
|
||||
this.recursivelyExpandNode(currentTreeNode.parentDoc)
|
||||
this.recursivelyExpandNodeUpwards(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
|
||||
])]
|
||||
}
|
||||
}
|
||||
|
||||
recursivelyExpandNodeDownwards (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 {children: any[], type: string}
|
||||
|
||||
// Dig into the upper hierarchy
|
||||
if (currentTreeNode?.children && currentTreeNode?.children.length > 0) {
|
||||
for (const child of currentTreeNode.children) {
|
||||
this.recursivelyExpandNodeDownwards(child.key)
|
||||
}
|
||||
}
|
||||
// If we are at the top of the tree, expand the top category
|
||||
else if (currentTreeNode?.type) {
|
||||
|
@ -805,6 +937,19 @@ export default class ObjectTree extends BaseClass {
|
|||
}
|
||||
}
|
||||
|
||||
collapseAllNodesForce (node: {key: string, children: []}) {
|
||||
if (node.children) {
|
||||
for (const child of node.children) {
|
||||
if (this.expandedTreeNodes.includes(node.key)) {
|
||||
this.collapseAllNodesForce(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.expandedTreeNodes.includes(node.key)) {
|
||||
this.expandedTreeNodes = this.expandedTreeNodes.filter(n => n !== node.key)
|
||||
}
|
||||
}
|
||||
|
||||
determineCatyegoryString (node: {
|
||||
documentCount: string
|
||||
categoryCount: string
|
||||
|
@ -824,6 +969,80 @@ export default class ObjectTree extends BaseClass {
|
|||
return `(<span class="docCount">${node.documentCount}</span> |${extraDivider} <span class="catCount">${node.categoryCount}</span>)`
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Document field copying
|
||||
/****************************************************************/
|
||||
|
||||
copyName (currentDoc: I_OpenedDocument) {
|
||||
copyDocumentName(currentDoc)
|
||||
}
|
||||
|
||||
copyTextColor (currentDoc: I_OpenedDocument) {
|
||||
copyDocumentTextColor(currentDoc)
|
||||
}
|
||||
|
||||
copyBackgroundColor (currentDoc: I_OpenedDocument) {
|
||||
copyDocumentBackgroundColor(currentDoc)
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Document copy
|
||||
/****************************************************************/
|
||||
|
||||
documentPass = null as unknown as I_OpenedDocument
|
||||
|
||||
copyTargetDocument (currentDoc: I_OpenedDocument) {
|
||||
this.documentPass = extend(true, {}, currentDoc)
|
||||
|
||||
const newDocument = copyDocument(this.documentPass, this.generateUID())
|
||||
|
||||
const dataPass = {
|
||||
doc: newDocument,
|
||||
treeAction: false
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.SSET_addOpenedDocument(dataPass)
|
||||
this.$router.push({
|
||||
path: newDocument.url
|
||||
}).catch((e: {name: string}) => {
|
||||
const errorName : string = e.name
|
||||
if (errorName === "NavigationDuplicated") {
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Add new document under parent
|
||||
/****************************************************************/
|
||||
addNewUnderParent (currentDoc: I_OpenedDocument) {
|
||||
createNewWithParent(currentDoc, this)
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Delete dialog
|
||||
/****************************************************************/
|
||||
|
||||
deleteObjectDialogTrigger: string | false = false
|
||||
deleteObjectDialogClose () {
|
||||
this.deleteObjectDialogTrigger = false
|
||||
}
|
||||
|
||||
deleteObjectAssignUID () {
|
||||
this.deleteObjectDialogTrigger = this.generateUID()
|
||||
}
|
||||
|
||||
toDeleteID = ""
|
||||
toDeleteType = ""
|
||||
|
||||
deleteTabDocument (targetDocument: I_OpenedDocument) {
|
||||
this.toDeleteID = targetDocument._id
|
||||
this.toDeleteType = targetDocument.type
|
||||
this.deleteObjectAssignUID()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -8,6 +8,14 @@
|
|||
@trigger-dialog-close="closeDocumentCheckDialogClose"
|
||||
/>
|
||||
|
||||
<!-- Delele document dialog -->
|
||||
<deleteDocumentCheckDialog
|
||||
:dialog-trigger="deleteObjectDialogTrigger"
|
||||
:document-id="toDeleteID"
|
||||
:document-type="toDeleteType"
|
||||
@trigger-dialog-close="deleteObjectDialogClose"
|
||||
/>
|
||||
|
||||
<q-tabs
|
||||
v-if="localDocuments.length > 0"
|
||||
:class="{'hasTextShadow': textShadow}"
|
||||
|
@ -33,7 +41,10 @@
|
|||
:to="`/project/display-content/${document.type}/${document._id}`"
|
||||
:key="document.type+document._id"
|
||||
:icon="(retrieveFieldValue(document,'categorySwitch') ? 'fas fa-folder-open' : document.icon)"
|
||||
:style="`color: ${retrieveFieldValue(document,'documentColor')}; background-color: ${retrieveFieldValue(document,'documentBackgroundColor')}; filter: ${(retrieveFieldValue(document,'minorSwitch') ? 'grayscale(100) brightness(0.7)' : '')}`"
|
||||
:style="`
|
||||
color: ${retrieveFieldValue(document,'documentColor')};
|
||||
background-color: ${retrieveFieldValue(document,'documentBackgroundColor')};
|
||||
filter: ${(retrieveFieldValue(document,'minorSwitch') ? 'grayscale(100) brightness(0.7)' : '')}`"
|
||||
:class="[
|
||||
{'isBold':
|
||||
(
|
||||
|
@ -51,7 +62,7 @@
|
|||
</span>
|
||||
<div
|
||||
class="q-tab__label"
|
||||
:class="{'isDead': retrieveFieldValue(document,'deadSwitch')}">
|
||||
:class="{'isDead': (retrieveFieldValue(document,'deadSwitch') && !hideDeadCrossThrough)}">
|
||||
{{retrieveFieldValue(document,'name')}}
|
||||
</div>
|
||||
<q-tooltip
|
||||
|
@ -75,6 +86,86 @@
|
|||
style="color: #fff;"
|
||||
@click.stop.prevent="tryCloseTab(document)"
|
||||
/>
|
||||
|
||||
<q-menu
|
||||
touch-position
|
||||
context-menu
|
||||
>
|
||||
|
||||
<q-list class="bg-gunmetal-light">
|
||||
<q-item clickable v-close-popup @click="copyName(document)">
|
||||
<q-item-section>Copy name</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-text-recognition" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="copyTextColor(document)">
|
||||
<q-item-section>Copy text color</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-eyedropper" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="copyBackgroundColor(document)">
|
||||
<q-item-section>Copy background color</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-format-color-fill" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item v-if="!document.isNew" clickable v-close-popup @click="addNewUnderParent(document)">
|
||||
<q-item-section>Create new document with this document as parent</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-file-tree" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-if="!document.isNew" v-close-popup @click="copyTargetDocument(document)">
|
||||
<q-item-section>Copy this document</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-content-copy" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator v-if="!document.isNew" />
|
||||
<q-item clickable v-close-popup @click="tryCloseTab(document)">
|
||||
<q-item-section>Close this tab</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-close" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="SSET_closeAllButCurrentDocuments(document)">
|
||||
<q-item-section>Close all tabs without changes except for this</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-close-box-outline" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="SSET_closeAllDocuments">
|
||||
<q-item-section>Close all tabs without changes</q-item-section>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="mdi-close-box-multiple-outline" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="SSET_forceCloseAllButCurrentDocuments(document)">
|
||||
<q-item-section>Force close all tabs except for this</q-item-section>
|
||||
<q-item-section avatar class="text-secondary">
|
||||
<q-icon name="mdi-close-box" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="SSET_forceCloseAllDocuments">
|
||||
<q-item-section>Force close all tabs</q-item-section>
|
||||
<q-item-section avatar class="text-secondary">
|
||||
<q-icon name="mdi-close-box-multiple" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="deleteTabDocument(document)">
|
||||
<q-item-section class="text-secondary"><b>Delete this document</b></q-item-section>
|
||||
<q-item-section avatar class="text-secondary">
|
||||
<q-icon name="mdi-text-box-remove-outline" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
|
||||
</q-menu>
|
||||
</q-route-tab>
|
||||
|
||||
</transition-group>
|
||||
|
@ -89,12 +180,20 @@
|
|||
import BaseClass from "src/BaseClass"
|
||||
|
||||
import { Component, Watch } from "vue-property-decorator"
|
||||
import deleteDocumentCheckDialog from "src/components/dialogs/DeleteDocumentCheck.vue"
|
||||
|
||||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import closeDocumentCheckDialog from "src/components/dialogs/CloseDocumentCheck.vue"
|
||||
import { createNewWithParent } from "src/scripts/documentActions/createNewWithParent"
|
||||
import { copyDocumentName, copyDocumentTextColor, copyDocumentBackgroundColor } from "src/scripts/documentActions/uniqueFieldCopy"
|
||||
import { copyDocument } from "src/scripts/documentActions/copyDocument"
|
||||
import { extend } from "quasar"
|
||||
|
||||
@Component({
|
||||
components: { closeDocumentCheckDialog }
|
||||
components: {
|
||||
closeDocumentCheckDialog,
|
||||
deleteDocumentCheckDialog
|
||||
}
|
||||
})
|
||||
export default class TopTabs extends BaseClass {
|
||||
/****************************************************************/
|
||||
|
@ -106,6 +205,11 @@ export default class TopTabs extends BaseClass {
|
|||
*/
|
||||
textShadow = false
|
||||
|
||||
/**
|
||||
* Determines if the "dead" document type should have a cross-text decoration or not
|
||||
*/
|
||||
hideDeadCrossThrough = false
|
||||
|
||||
/**
|
||||
* Watch changes on options
|
||||
*/
|
||||
|
@ -113,6 +217,7 @@ export default class TopTabs extends BaseClass {
|
|||
onSettingsChange () {
|
||||
const options = this.SGET_options
|
||||
this.textShadow = options.textShadow
|
||||
this.hideDeadCrossThrough = options.hideDeadCrossThrough
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
@ -138,6 +243,28 @@ export default class TopTabs extends BaseClass {
|
|||
if (this.determineKeyBind("previousTab") && this.localDocuments.length > 0 && !this.SGET_getDialogsState) {
|
||||
this.goToPreviousTab()
|
||||
}
|
||||
|
||||
// Close all tabs without changes except for this - CTRL + ALT + SHIFT + W
|
||||
if (this.determineKeyBind("closeAllTabsWithoutChangesButThis") && this.localDocuments.length > 0 && !this.SGET_getDialogsState) {
|
||||
const currentDoc = this.findRequestedOrActiveDocument() as I_OpenedDocument
|
||||
this.SSET_closeAllButCurrentDocuments(currentDoc)
|
||||
}
|
||||
|
||||
// Close all tabs without changes - CTRL + SHIFT + W
|
||||
if (this.determineKeyBind("closeAllTabsWithoutChanges") && this.localDocuments.length > 0 && !this.SGET_getDialogsState) {
|
||||
this.SSET_closeAllDocuments()
|
||||
}
|
||||
|
||||
// Force close all tabs except for this - NONE
|
||||
if (this.determineKeyBind("forceCloseAllTabsButThis") && this.localDocuments.length > 0 && !this.SGET_getDialogsState) {
|
||||
const currentDoc = this.findRequestedOrActiveDocument() as I_OpenedDocument
|
||||
this.SSET_forceCloseAllButCurrentDocuments(currentDoc)
|
||||
}
|
||||
|
||||
// Force close all tabs - NONE
|
||||
if (this.determineKeyBind("forceCloseAllTabs") && this.localDocuments.length > 0 && !this.SGET_getDialogsState) {
|
||||
this.SSET_forceCloseAllDocuments()
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
@ -231,6 +358,58 @@ export default class TopTabs extends BaseClass {
|
|||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Document field copying
|
||||
/****************************************************************/
|
||||
|
||||
copyName (currentDoc: I_OpenedDocument) {
|
||||
copyDocumentName(currentDoc)
|
||||
}
|
||||
|
||||
copyTextColor (currentDoc: I_OpenedDocument) {
|
||||
copyDocumentTextColor(currentDoc)
|
||||
}
|
||||
|
||||
copyBackgroundColor (currentDoc: I_OpenedDocument) {
|
||||
copyDocumentBackgroundColor(currentDoc)
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Document copy
|
||||
/****************************************************************/
|
||||
|
||||
documentPass = null as unknown as I_OpenedDocument
|
||||
|
||||
copyTargetDocument (currentDoc: I_OpenedDocument) {
|
||||
this.documentPass = extend(true, {}, currentDoc)
|
||||
|
||||
const newDocument = copyDocument(this.documentPass, this.generateUID())
|
||||
|
||||
const dataPass = {
|
||||
doc: newDocument,
|
||||
treeAction: false
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.SSET_addOpenedDocument(dataPass)
|
||||
this.$router.push({
|
||||
path: newDocument.url
|
||||
}).catch((e: {name: string}) => {
|
||||
const errorName : string = e.name
|
||||
if (errorName === "NavigationDuplicated") {
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Add new document under parent
|
||||
/****************************************************************/
|
||||
addNewUnderParent (currentDoc: I_OpenedDocument) {
|
||||
createNewWithParent(currentDoc, this)
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Close document dialog
|
||||
/****************************************************************/
|
||||
|
@ -243,6 +422,28 @@ export default class TopTabs extends BaseClass {
|
|||
closeDocumentCheckDialogAssignUID () {
|
||||
this.closeDocumentCheckDialogTrigger = this.generateUID()
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// Delete dialog
|
||||
/****************************************************************/
|
||||
|
||||
deleteObjectDialogTrigger: string | false = false
|
||||
deleteObjectDialogClose () {
|
||||
this.deleteObjectDialogTrigger = false
|
||||
}
|
||||
|
||||
deleteObjectAssignUID () {
|
||||
this.deleteObjectDialogTrigger = this.generateUID()
|
||||
}
|
||||
|
||||
toDeleteID = ""
|
||||
toDeleteType = ""
|
||||
|
||||
deleteTabDocument (targetDocument: I_OpenedDocument) {
|
||||
this.toDeleteID = targetDocument._id
|
||||
this.toDeleteType = targetDocument.type
|
||||
this.deleteObjectAssignUID()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
v-close-popup />
|
||||
<q-btn
|
||||
outline
|
||||
:disable="!retrieveFieldValue(currentDocument, 'name')"
|
||||
label="Delete document"
|
||||
color="secondary"
|
||||
@click="deleteDocument()" />
|
||||
|
@ -38,7 +39,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
|
||||
import { Component, Watch } from "vue-property-decorator"
|
||||
import { Component, Watch, Prop } from "vue-property-decorator"
|
||||
|
||||
import DialogBase from "src/components/dialogs/_DialogBase"
|
||||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
|
@ -53,18 +54,34 @@ export default class DeleteDocumentCheckDialog extends DialogBase {
|
|||
*/
|
||||
@Watch("dialogTrigger")
|
||||
async openDialog (val: string|false) {
|
||||
if (val && this.SGET_allOpenedDocuments.docs.length > 0) {
|
||||
if (val && (this.SGET_allOpenedDocuments.docs.length > 0 || (this.documentType.length > 0 && this.documentId.length > 0))) {
|
||||
if (this.SGET_getDialogsState) {
|
||||
return
|
||||
}
|
||||
this.SSET_setDialogState(true)
|
||||
this.dialogModel = true
|
||||
const CurrentObjectDB = new PouchDB(this.$route.params.type)
|
||||
this.currentDocument = await CurrentObjectDB.get(this.$route.params.id)
|
||||
|
||||
const documentType = (this.documentType.length > 0) ? this.documentType : this.$route.params.type
|
||||
const documentID = (this.documentId.length > 0) ? this.documentId : this.$route.params.id
|
||||
|
||||
const CurrentObjectDB = new PouchDB(documentType)
|
||||
this.currentDocument = await CurrentObjectDB.get(documentID)
|
||||
await CurrentObjectDB.close()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OPTIONAL
|
||||
* Type of the document to delete
|
||||
*/
|
||||
@Prop({ default: "" }) readonly documentType!: ""
|
||||
|
||||
/**
|
||||
* OPTIONAL
|
||||
* ID of the document to delete
|
||||
*/
|
||||
@Prop({ default: "" }) readonly documentId!: ""
|
||||
|
||||
/**
|
||||
* Current document for deletion
|
||||
*/
|
||||
|
@ -74,7 +91,8 @@ export default class DeleteDocumentCheckDialog extends DialogBase {
|
|||
* Delete the document
|
||||
*/
|
||||
async deleteDocument () {
|
||||
const CurrentObjectDB = new PouchDB(this.$route.params.type)
|
||||
const documentType = (this.documentType.length > 0) ? this.documentType : this.$route.params.type
|
||||
const CurrentObjectDB = new PouchDB(documentType)
|
||||
|
||||
// @ts-ignore
|
||||
await CurrentObjectDB.remove(this.currentDocument)
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<span class="isDeadIndicator" v-if="opt.isDead">
|
||||
†
|
||||
</span>
|
||||
<span :class="{'isDead': opt.isDead}" v-html="opt.label">
|
||||
<span :class="{'isDead': (opt.isDead && !hideDeadCrossThrough)}" v-html="opt.label">
|
||||
</span>
|
||||
</q-item-label>
|
||||
<q-item-label caption class="text-cultured" v-html="opt.hierarchicalPath"></q-item-label>
|
||||
|
@ -82,7 +82,7 @@
|
|||
dark
|
||||
color="primary"
|
||||
class="z-1 q-ml-md"
|
||||
icon="mdi-plus"
|
||||
icon="mdi-file-tree"
|
||||
size="md"
|
||||
@click.stop.prevent="addNewItemUnderSelected(opt)"
|
||||
>
|
||||
|
@ -92,6 +92,24 @@
|
|||
Add a new document belonging under {{ stripTags(opt.label) }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
tabindex="-1"
|
||||
round
|
||||
flat
|
||||
dense
|
||||
dark
|
||||
color="accent"
|
||||
class="z-1 q-ml-sm"
|
||||
icon="mdi-content-copy"
|
||||
size="md"
|
||||
@click.stop.prevent="copyTargetDocument(opt)"
|
||||
>
|
||||
<q-tooltip
|
||||
:delay="300"
|
||||
>
|
||||
Make a copy of {{ stripTags(opt.label) }}
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
|
@ -110,10 +128,11 @@
|
|||
<script lang="ts">
|
||||
|
||||
import { Component, Watch } from "vue-property-decorator"
|
||||
import { I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { advancedDocumentFilter } from "src/scripts/utilities/advancedDocumentFilter"
|
||||
import { extend } from "quasar"
|
||||
import PouchDB from "pouchdb"
|
||||
import { copyDocument } from "src/scripts/documentActions/copyDocument"
|
||||
|
||||
import DialogBase from "src/components/dialogs/_DialogBase"
|
||||
import { I_Blueprint } from "src/interfaces/I_Blueprint"
|
||||
|
@ -164,8 +183,14 @@ export default class ExistingDocumentDialog extends DialogBase {
|
|||
this.disableCloseAftertSelectQuickSearch = this.SGET_options.disableCloseAftertSelectQuickSearch
|
||||
this.includeCategories = !this.SGET_options.disableQuickSearchCategoryPrecheck
|
||||
this.textShadow = this.SGET_options.textShadow
|
||||
this.hideDeadCrossThrough = this.SGET_options.hideDeadCrossThrough
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the "dead" document type should have a cross-text decoration or not
|
||||
*/
|
||||
hideDeadCrossThrough = false
|
||||
|
||||
/**
|
||||
* Determines if the popup shouldnt close after a document is selected from the dropdown list
|
||||
*/
|
||||
|
@ -383,6 +408,31 @@ export default class ExistingDocumentDialog extends DialogBase {
|
|||
// @ts-ignore
|
||||
this.addNewObjectRoute(routeObject)
|
||||
}
|
||||
|
||||
documentPass = null as unknown as I_OpenedDocument
|
||||
|
||||
copyTargetDocument (currentDoc: I_OpenedDocument) {
|
||||
this.documentPass = extend(true, {}, currentDoc)
|
||||
|
||||
const newDocument = copyDocument(this.documentPass, this.generateUID())
|
||||
|
||||
const dataPass = {
|
||||
doc: newDocument,
|
||||
treeAction: false
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.SSET_addOpenedDocument(dataPass)
|
||||
this.$router.push({
|
||||
path: newDocument.url
|
||||
}).catch((e: {name: string}) => {
|
||||
const errorName : string = e.name
|
||||
if (errorName === "NavigationDuplicated") {
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -74,16 +74,17 @@ export default class KeybindCheatsheet extends DialogBase {
|
|||
|
||||
// Remap the cheetcheet based on available input settings
|
||||
this.localCheatSheet = this.SGET_getCurrentKeyBindData.defaults.map((bind, index) => {
|
||||
const userKb = this.SGET_getCurrentKeyBindData.userKeybinds.find(userKb => userKb.id === bind.id)
|
||||
const mappedKeybind = (
|
||||
this.SGET_getCurrentKeyBindData.userKeybinds[index] &&
|
||||
this.SGET_getCurrentKeyBindData.userKeybinds[index].which
|
||||
userKb &&
|
||||
userKb.which
|
||||
)
|
||||
// If user keybind
|
||||
? {
|
||||
altKey: this.SGET_getCurrentKeyBindData.userKeybinds[index].altKey,
|
||||
ctrlKey: this.SGET_getCurrentKeyBindData.userKeybinds[index].ctrlKey,
|
||||
shiftKey: this.SGET_getCurrentKeyBindData.userKeybinds[index].shiftKey,
|
||||
which: this.SGET_getCurrentKeyBindData.userKeybinds[index].which,
|
||||
altKey: userKb.altKey,
|
||||
ctrlKey: userKb.ctrlKey,
|
||||
shiftKey: userKb.shiftKey,
|
||||
which: userKb.which,
|
||||
id: bind.id,
|
||||
tooltip: bind.tooltip,
|
||||
note: bind.note
|
||||
|
|
|
@ -101,6 +101,21 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-4 optionWrapper">
|
||||
<div class="optionTitle">
|
||||
Accessibility - Hide strike-through
|
||||
<q-icon name="mdi-help-circle" size="16px" class="q-ml-md">
|
||||
<q-tooltip :delay="500">
|
||||
This setting hides the strike through effect on dead/gone/destroyed documents in order to increase visibility.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</div>
|
||||
|
||||
<q-toggle
|
||||
v-model="options.hideDeadCrossThrough"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-4 optionWrapper">
|
||||
<div class="optionTitle">
|
||||
Hide Welcome screen social links
|
||||
|
@ -414,6 +429,21 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-4 optionWrapper">
|
||||
<div class="optionTitle">
|
||||
Hide order numbers
|
||||
<q-icon name="mdi-help-circle" size="16px" class="q-ml-md">
|
||||
<q-tooltip :delay="500">
|
||||
This option disabled showing of the custom order numbers left of the names.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</div>
|
||||
|
||||
<q-toggle
|
||||
v-model="options.hideTreeOrderNumbers"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
</q-tab-panel>
|
||||
|
@ -655,6 +685,7 @@ export default class ProgramSettings extends DialogBase {
|
|||
darkMode: false,
|
||||
textShadow: false,
|
||||
doubleDashDocCount: false,
|
||||
hideDeadCrossThrough: false,
|
||||
tagsAtTop: false,
|
||||
noTags: false,
|
||||
compactTags: false,
|
||||
|
@ -674,6 +705,7 @@ export default class ProgramSettings extends DialogBase {
|
|||
hideWelcomeScreenSocials: false,
|
||||
hideTooltipsStart: false,
|
||||
hideTooltipsProject: false,
|
||||
hideTreeOrderNumbers: false,
|
||||
userKeybindList: []
|
||||
}
|
||||
|
||||
|
@ -895,7 +927,7 @@ export default class ProgramSettings extends DialogBase {
|
|||
id: keybind.id,
|
||||
editable: keybind.editable,
|
||||
defaultKeybind: keybind,
|
||||
userKeybind: (this.options.userKeybindList[index]) || ""
|
||||
userKeybind: (this.options.userKeybindList.find(userKb => userKb.id === keybind.id)) || ""
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<span class="isDeadIndicator" v-if="single.isDead">
|
||||
†
|
||||
</span>
|
||||
<span :class="{'isDead': single.isDead}">
|
||||
<span :class="{'isDead': (single.isDead && !hideDeadCrossThrough)}">
|
||||
{{stripTags(single.label)}}
|
||||
</span>
|
||||
</span>
|
||||
|
@ -147,7 +147,7 @@
|
|||
<span class="isDeadIndicator" v-if="opt.isDead">
|
||||
†
|
||||
</span>
|
||||
<span :class="{'isDead': opt.isDead}" v-html="opt.label">
|
||||
<span :class="{'isDead': (opt.isDead && !hideDeadCrossThrough)}" v-html="opt.label">
|
||||
</span>
|
||||
</q-item-label>
|
||||
<q-item-label caption class="text-cultured" v-html="opt.hierarchicalPath"></q-item-label>
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<span class="isDeadIndicator" v-if="localInput.isDead">
|
||||
†
|
||||
</span>
|
||||
<span :class="{'isDead': localInput.isDead}">
|
||||
<span :class="{'isDead': (localInput.isDead && !hideDeadCrossThrough)}">
|
||||
{{stripTags(localInput.label)}}
|
||||
</span>
|
||||
</span>
|
||||
|
@ -145,7 +145,7 @@
|
|||
<span class="isDeadIndicator" v-if="opt.isDead">
|
||||
†
|
||||
</span>
|
||||
<span :class="{'isDead': opt.isDead}" v-html="opt.label">
|
||||
<span :class="{'isDead': (opt.isDead && !hideDeadCrossThrough)}" v-html="opt.label">
|
||||
</span>
|
||||
</q-item-label>
|
||||
<q-item-label caption class="text-cultured" v-html="opt.hierarchicalPath"></q-item-label>
|
||||
|
|
|
@ -44,8 +44,14 @@ export default class FieldBase extends BaseClass {
|
|||
this.isDarkMode = this.SGET_options.darkMode
|
||||
this.disableDocumentToolTips = this.SGET_options.disableDocumentToolTips
|
||||
this.textShadow = this.SGET_options.textShadow
|
||||
this.hideDeadCrossThrough = this.SGET_options.hideDeadCrossThrough
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the "dead" document type should have a cross-text decoration or not
|
||||
*/
|
||||
hideDeadCrossThrough = false
|
||||
|
||||
/**
|
||||
* Determines if the text has shadows or not
|
||||
*/
|
||||
|
|
|
@ -16,22 +16,61 @@
|
|||
- Fixed a bug that was causing the relationship dropdowns sometimes not be clickable and instead caused dragging of the app window when shown over the top of the drag-bar at the top of the app
|
||||
- Updated advanced search guide with missing information about full-text search
|
||||
- Changes a small bug when the `New Object` dialog wasn't respecting option changes being done in the same session of the program being opened
|
||||
- Fixed a bug that was sometimes showing improper values inside the user defined keybinds both in the key settings and the cheatsheet
|
||||
- Fixed tag groups in hierarchical tree not respecting custom order and alphabetical order
|
||||
- Fixed a rather peculiar recuring bug that could cause the database to endlessly attempt to update a document while constantly throwing errors
|
||||
- Fixed a bug that was causing an "Empty" checkbox popping up at irrelevant places on right click
|
||||
- Managed to fix or at least mitigate multiple memory-leaks across the app
|
||||
- Optimized multiple parts of the code to run smoother
|
||||
- Fixed wrong icons in some fields in some document types
|
||||
- Fixed a bug that was allowing for an attempted deletion of a document while the document data was still being retrieved. This resulted in an error that both made a mess of a UI and didn't delete the desider document
|
||||
|
||||
### New features
|
||||
|
||||
- Added context menu support and multiple actions (right click) for top tabs and hierarchical tree
|
||||
- New action for **Top Tabs**
|
||||
- Copy name
|
||||
- Copy text color
|
||||
- Copy background color
|
||||
- Create new document with this document as parent
|
||||
- Copy this document
|
||||
- Close this tab
|
||||
- Close all tabs without changes except for this
|
||||
- Close all tabs without changes
|
||||
- Force close all tabs except for this
|
||||
- Force close all tabs
|
||||
- Delete document
|
||||
- New action for **Hiearachical Tree**
|
||||
- Add new document type: `DOCUMENT TYPE`
|
||||
- Only available in the root-categories
|
||||
- Expand all
|
||||
- Collapse all
|
||||
- Copy name
|
||||
- Copy text color
|
||||
- Copy background color
|
||||
- Open document
|
||||
- Create new document with this document as parent
|
||||
- Copy this document
|
||||
- Delete document
|
||||
- Added support for default empty keybinds
|
||||
- Added a dedicated button that opens the connected documents straight from the little chips in relationship fields while in edit mode
|
||||
- Added support for background color for documents
|
||||
- Added support for "Minor document" mode switch for better organization and visual representation of documents
|
||||
- Added support for "Dead/Gone/Destroyed" mode switch for better organization and visual representation of documents
|
||||
- Added option: Accessibility - Hide strike-through
|
||||
- Added option: Accessibility - Hide order numbers
|
||||
- Added functionality to copy existing documents along with all their contents
|
||||
- Added keybind: Close all tabs without changes except for this
|
||||
- Added keybind: Close all tabs without changes
|
||||
- Added keybind: Force close all tabs except for this
|
||||
- Added keybind: Force close all tabs
|
||||
- Added keybind: Copy active document
|
||||
|
||||
### QoL adjustments
|
||||
|
||||
- Changed focusing of the hierarchy tree search input from CTRL + SHIFT + W to CTRL + SHIFT +T
|
||||
- Updated fullscreen editor looks to work more like a proper document editor
|
||||
- Unified icons for same actions across the app
|
||||
- Reordered the basic document settings inside the app and separated them from the document content
|
||||
- Adjusted maximum width of switch fields to make them look like spaggeti
|
||||
- Updated the Advanced search guide with new additions and added one new Trivia popup text concerning it
|
||||
|
|
|
@ -73,6 +73,23 @@
|
|||
</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-content-copy"
|
||||
@click="copyTargetDocument"
|
||||
:outline="isDarkMode"
|
||||
class="q-mr-md"
|
||||
v-if="!currentData.isNew"
|
||||
>
|
||||
<q-tooltip
|
||||
:delay="500"
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
>
|
||||
Copy current document
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-btn
|
||||
color="secondary"
|
||||
icon="mdi-text-box-remove-outline"
|
||||
|
@ -234,6 +251,7 @@ import { I_Blueprint, I_ExtraFields } from "src/interfaces/I_Blueprint"
|
|||
import PouchDB from "pouchdb"
|
||||
import { extend } from "quasar"
|
||||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { copyDocument } from "src/scripts/documentActions/copyDocument"
|
||||
|
||||
import { saveDocument } from "src/scripts/databaseManager/documentManager"
|
||||
import deleteDocumentCheckDialog from "src/components/dialogs/DeleteDocumentCheck.vue"
|
||||
|
@ -766,6 +784,34 @@ export default class PageDocumentDisplay extends BaseClass {
|
|||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// `DOCUMENT COPY
|
||||
/****************************************************************/
|
||||
documentPass = null as unknown as I_OpenedDocument
|
||||
|
||||
copyTargetDocument () {
|
||||
this.documentPass = extend(true, {}, this.findRequestedOrActiveDocument())
|
||||
|
||||
const newDocument = copyDocument(this.documentPass, this.generateUID())
|
||||
|
||||
const dataPass = {
|
||||
doc: newDocument,
|
||||
treeAction: false
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.SSET_addOpenedDocument(dataPass)
|
||||
this.$router.push({
|
||||
path: newDocument.url
|
||||
}).catch((e: {name: string}) => {
|
||||
const errorName : string = e.name
|
||||
if (errorName === "NavigationDuplicated") {
|
||||
return
|
||||
}
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
// DOCUMENT ACTIONS
|
||||
/****************************************************************/
|
||||
|
|
|
@ -55,12 +55,12 @@ export const defaultKeybinds = [
|
|||
tooltip: "Focus search field in the left hierarchical tree"
|
||||
},
|
||||
|
||||
// Clear input in the left tree search - CTRL + SHIFT + W
|
||||
// Clear input in the left tree search - CTRL + SHIFT + T
|
||||
{
|
||||
altKey: false,
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
which: 87,
|
||||
which: 84,
|
||||
editable: true,
|
||||
id: "clearInputHierarchicalTree",
|
||||
tooltip: "Clear any input in the search field in the left hierarchical tree"
|
||||
|
@ -77,6 +77,50 @@ export const defaultKeybinds = [
|
|||
tooltip: "Close active document"
|
||||
},
|
||||
|
||||
// Close all tabs without changes except for this - CTRL + ALT + SHIFT + W
|
||||
{
|
||||
altKey: true,
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
which: 87,
|
||||
editable: true,
|
||||
id: "closeAllTabsWithoutChangesButThis",
|
||||
tooltip: "Close all tabs without changes except for this"
|
||||
},
|
||||
|
||||
// Close all tabs without changes - CTRL + SHIFT + W
|
||||
{
|
||||
altKey: false,
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
which: 87,
|
||||
editable: true,
|
||||
id: "closeAllTabsWithoutChanges",
|
||||
tooltip: "Close all tabs without changes"
|
||||
},
|
||||
|
||||
// Force close all tabs except for this - NONE
|
||||
{
|
||||
altKey: false,
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
which: false,
|
||||
editable: true,
|
||||
id: "forceCloseAllTabsButThis",
|
||||
tooltip: "Force close all tabs except for this"
|
||||
},
|
||||
|
||||
// Force close all tabs - NONE
|
||||
{
|
||||
altKey: false,
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
which: false,
|
||||
editable: true,
|
||||
id: "forceCloseAllTabs",
|
||||
tooltip: "Force close all tabs"
|
||||
},
|
||||
|
||||
// Next tab - ALT + RIGHT ARROW
|
||||
{
|
||||
altKey: true,
|
||||
|
@ -121,7 +165,7 @@ export const defaultKeybinds = [
|
|||
tooltip: "Edit active document"
|
||||
},
|
||||
|
||||
// Edit document - CTRL + SHIFT + N
|
||||
// Add a new document with current as parent - CTRL + SHIFT + N
|
||||
{
|
||||
altKey: false,
|
||||
ctrlKey: true,
|
||||
|
@ -132,6 +176,17 @@ export const defaultKeybinds = [
|
|||
tooltip: "Add a new document with the currently opened one as the parent"
|
||||
},
|
||||
|
||||
// Copy document - CTRL + ALT + C
|
||||
{
|
||||
altKey: true,
|
||||
ctrlKey: true,
|
||||
shiftKey: false,
|
||||
which: 67,
|
||||
editable: true,
|
||||
id: "copyDocument",
|
||||
tooltip: "Copy active document"
|
||||
},
|
||||
|
||||
// Delete document - CTRL + D
|
||||
{
|
||||
altKey: false,
|
||||
|
|
18
src/scripts/documentActions/copyDocument.ts
Normal file
18
src/scripts/documentActions/copyDocument.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
|
||||
export const copyDocument = (currentDoc: I_OpenedDocument, newDocumentID: string) : I_OpenedDocument => {
|
||||
currentDoc._id = newDocumentID
|
||||
currentDoc.isNew = true
|
||||
currentDoc.editMode = true
|
||||
currentDoc.hasEdits = false
|
||||
currentDoc.url = `/project/display-content/${currentDoc.type}/${newDocumentID}`
|
||||
|
||||
delete (currentDoc._rev)
|
||||
|
||||
const documentNameIndex = currentDoc.extraFields.findIndex(e => e.id === "name")
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
currentDoc.extraFields[documentNameIndex].value = `Copy of - ${currentDoc.extraFields[documentNameIndex].value}`
|
||||
|
||||
return currentDoc
|
||||
}
|
15
src/scripts/documentActions/createNewWithParent.ts
Normal file
15
src/scripts/documentActions/createNewWithParent.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
|
||||
/**
|
||||
* Toggles dev tools in the current window
|
||||
*/
|
||||
export const createNewWithParent = (currentDoc: I_OpenedDocument, callingComponent: any) => {
|
||||
if (currentDoc) {
|
||||
const routeObject = {
|
||||
_id: currentDoc.type,
|
||||
parent: currentDoc._id
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
callingComponent.addNewObjectRoute(routeObject)
|
||||
}
|
||||
}
|
34
src/scripts/documentActions/uniqueFieldCopy.ts
Normal file
34
src/scripts/documentActions/uniqueFieldCopy.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
|
||||
export const copyDocumentName = (targetDocument: I_OpenedDocument) => {
|
||||
const returnValue = targetDocument.extraFields.find(e => e.id === "name")?.value
|
||||
|
||||
const el = document.createElement("textarea")
|
||||
el.value = returnValue
|
||||
document.body.appendChild(el)
|
||||
el.select()
|
||||
document.execCommand("copy")
|
||||
document.body.removeChild(el)
|
||||
}
|
||||
|
||||
export const copyDocumentTextColor = (targetDocument: I_OpenedDocument) => {
|
||||
const returnValue = targetDocument.extraFields.find(e => e.id === "documentColor")?.value
|
||||
|
||||
const el = document.createElement("textarea")
|
||||
el.value = (returnValue) || ""
|
||||
document.body.appendChild(el)
|
||||
el.select()
|
||||
document.execCommand("copy")
|
||||
document.body.removeChild(el)
|
||||
}
|
||||
|
||||
export const copyDocumentBackgroundColor = (targetDocument: I_OpenedDocument) => {
|
||||
const returnValue = targetDocument.extraFields.find(e => e.id === "documentBackgroundColor")?.value
|
||||
|
||||
const el = document.createElement("textarea")
|
||||
el.value = (returnValue) || ""
|
||||
document.body.appendChild(el)
|
||||
el.select()
|
||||
document.execCommand("copy")
|
||||
document.body.removeChild(el)
|
||||
}
|
|
@ -36,6 +36,38 @@ const actions: ActionTree<OpenDocumentsStateInterface, StateInterface> = {
|
|||
}, 200)
|
||||
},
|
||||
|
||||
closeAllDocuments (state) {
|
||||
state.commit("closeAllDocuments")
|
||||
|
||||
setTimeout(() => {
|
||||
state.commit("resetTreeAction")
|
||||
}, 200)
|
||||
},
|
||||
|
||||
forceCloseAllDocuments (state) {
|
||||
state.commit("forceCloseAllDocuments")
|
||||
|
||||
setTimeout(() => {
|
||||
state.commit("resetTreeAction")
|
||||
}, 200)
|
||||
},
|
||||
|
||||
closeAllButCurrentDocuments (state, input) {
|
||||
state.commit("closeAllButCurrentDocuments", input)
|
||||
|
||||
setTimeout(() => {
|
||||
state.commit("resetTreeAction")
|
||||
}, 200)
|
||||
},
|
||||
|
||||
forceCloseAllButCurrentDocuments (state, input) {
|
||||
state.commit("forceCloseAllButCurrentDocuments", input)
|
||||
|
||||
setTimeout(() => {
|
||||
state.commit("resetTreeAction")
|
||||
}, 200)
|
||||
},
|
||||
|
||||
triggerTreeAction (state) {
|
||||
state.commit("triggerTreeAction")
|
||||
|
||||
|
|
|
@ -51,6 +51,30 @@ const mutation: MutationTree<OpenDocumentsStateInterface> = {
|
|||
state.documents.treeAction = true
|
||||
},
|
||||
|
||||
closeAllDocuments (state: OpenDocumentsStateInterface) {
|
||||
state.documents.docs = state.documents.docs.filter(doc => doc.hasEdits)
|
||||
state.documents.treeAction = true
|
||||
state.documents.timestamp = uid()
|
||||
},
|
||||
|
||||
forceCloseAllDocuments (state: OpenDocumentsStateInterface) {
|
||||
state.documents.docs = []
|
||||
state.documents.treeAction = true
|
||||
state.documents.timestamp = uid()
|
||||
},
|
||||
|
||||
closeAllButCurrentDocuments (state: OpenDocumentsStateInterface, input: I_OpenedDocument) {
|
||||
state.documents.docs = state.documents.docs.filter(doc => doc.hasEdits || doc._id === input._id)
|
||||
state.documents.treeAction = true
|
||||
state.documents.timestamp = uid()
|
||||
},
|
||||
|
||||
forceCloseAllButCurrentDocuments (state: OpenDocumentsStateInterface, input: I_OpenedDocument) {
|
||||
state.documents.docs = state.documents.docs.filter(doc => doc._id === input._id)
|
||||
state.documents.treeAction = true
|
||||
state.documents.timestamp = uid()
|
||||
},
|
||||
|
||||
resetDocuments (state: OpenDocumentsStateInterface) {
|
||||
state.documents.docs = []
|
||||
state.documents.treeAction = true
|
||||
|
|
|
@ -3,6 +3,7 @@ export interface OptionsStateInteface {
|
|||
_rev?: string,
|
||||
darkMode: boolean
|
||||
textShadow: boolean
|
||||
hideDeadCrossThrough: boolean
|
||||
doubleDashDocCount: boolean
|
||||
hideWelcomeScreenSocials: boolean
|
||||
noTags: boolean
|
||||
|
@ -23,6 +24,7 @@ export interface OptionsStateInteface {
|
|||
invertCategoryPosition: boolean
|
||||
hideTooltipsStart: boolean
|
||||
hideTooltipsProject: boolean
|
||||
hideTreeOrderNumbers: boolean
|
||||
|
||||
userKeybindList: any[]
|
||||
treeWidth?: number
|
||||
|
@ -33,6 +35,7 @@ function state (): OptionsStateInteface {
|
|||
_id: "settings",
|
||||
darkMode: false,
|
||||
textShadow: false,
|
||||
hideDeadCrossThrough: false,
|
||||
doubleDashDocCount: false,
|
||||
hideWelcomeScreenSocials: false,
|
||||
noTags: false,
|
||||
|
@ -53,6 +56,7 @@ function state (): OptionsStateInteface {
|
|||
invertCategoryPosition: false,
|
||||
hideTooltipsStart: false,
|
||||
hideTooltipsProject: false,
|
||||
hideTreeOrderNumbers: false,
|
||||
treeWidth: 374,
|
||||
userKeybindList: []
|
||||
}
|
||||
|
|
|
@ -1,37 +1,36 @@
|
|||
- Add "Related notes"
|
||||
- Add "Predecessors", "Successors", "Date of start", "Date of end" and "How long it lasted" fields to locations and all other groups
|
||||
- Switch field: Template (sigh... maybe???)
|
||||
|
||||
- Save scroll distance when switching tabs (consider some auto-scroll when opening edit mode)
|
||||
- Mass tag rename
|
||||
|
||||
- Add "Related notes"
|
||||
- Add "Predecessors", "Successors", "Date of start", "Date of end" and "How long it lasted" fields to locations and all other groups
|
||||
|
||||
- Add advanced search capabilities to the hierarchical tree
|
||||
|
||||
- "Save all" keybind and "Save all and exit" option on the exiting
|
||||
- Add support for dates in "custom order"... reee
|
||||
- Add safeguard to escape closing of settings only after something actually got modified
|
||||
|
||||
- Add hover/on-demand document preview to relationships
|
||||
- Floating notes corkboard
|
||||
- Export for MD/PDF
|
||||
|
||||
- Add intelligent responsive design to the left tree and document body (maybe button to pull the left bar in and out?)
|
||||
- Context menu: Expand all
|
||||
- Context menu: Collapse all
|
||||
- Context menu: Copy color (text and BG)
|
||||
- Context menu: Duplicate
|
||||
- Context menu: Copy name
|
||||
- Context menu: Delete
|
||||
- Context menu: Edit/Open
|
||||
- Context menu: Create new doc with parent of THIS
|
||||
- Context menu: Pin tab
|
||||
- Context menu: Unpin tab
|
||||
|
||||
- Pinned tabs (save through program closing)
|
||||
|
||||
- Add "Open all search matches" button in the Quick-search that opens a new page with a list of items
|
||||
- Custom order document types
|
||||
- Option: Retain opened tabs and their edited contents through sessions
|
||||
- Option: Single tab option coupled with pinned tabs
|
||||
- Option: Periodical backup (how many, how often, include files or not)
|
||||
|
||||
### Project settings
|
||||
|
||||
- Custom order document types
|
||||
- Pinned tabs (save through program closing)
|
||||
- Option: Periodical backup (how many, how often, include files or not)
|
||||
- Add Colors, Renaming and Hiding to default document types per project settings
|
||||
- Option: Retain opened tabs and their edited contents through sessions
|
||||
- Option: Single tab option coupled with pinned tabs
|
||||
- Add safeguard to escape closing of settings only after something actually got modified
|
||||
- Context menu: Pin tab
|
||||
- Context menu: Unpin tab
|
||||
|
||||
- Add support for dates in "custom order"... reee
|
||||
- Tag management (coloring)
|
||||
|
||||
- Simple data imports (maybe?)
|
||||
|
@ -40,7 +39,7 @@
|
|||
|
||||
- Add on-the-fly generation of non-existent 2-way relationships
|
||||
|
||||
- Automatic thumnail generation AND re-checking based on date
|
||||
- Automatic thumbnail generation AND re-checking based on date
|
||||
|
||||
- Option: Custom background for project
|
||||
- Check fonts offered in the WYSIWYG and add new
|
||||
|
@ -55,5 +54,6 @@
|
|||
- Allow/Disallow default document types
|
||||
- Timeline/Calendar support
|
||||
- AFMG support
|
||||
- Better color pasting to documents via context menu
|
||||
- Add printing support
|
||||
- Add % bar graphs in tree (pinned in #general, idea by popoto)
|
||||
|
|
Loading…
Reference in a new issue