Implement document linking feature for @ keypress.

This commit is contained in:
Gáspár József Dániel 2023-05-13 13:21:11 +02:00
parent d77daf8d65
commit 545ab74066
4 changed files with 119 additions and 21 deletions

View file

@ -102,7 +102,6 @@ import PouchDB from "pouchdb"
import { OptionsStateInteface } from "./store/module-options/state"
import { colors } from "quasar"
import { tipsTricks } from "src/scripts/utilities/tipsTricks"
import { shell } from "electron"
import { summonAllPlusheForms } from "src/scripts/utilities/plusheMascot"
import { saveCorkboard, retrieveCorkboard, retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
import documentPreview from "src/components/DocumentPreview.vue"
@ -287,24 +286,9 @@ export default class App extends BaseClass {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if (event.target && event.target.tagName.toLowerCase() === "a" && event.target.closest(".fieldWysiwyg")) {
try {
// @ts-ignore
const url = new URL(event.target.href as string)
// @ts-ignore
console.log(url)
if (url.protocol === "http:" || url.protocol === "https:") {
shell.openExternal(url.href).catch(e => console.log(e))
}
else if (url.protocol === "document:") {
const doc = this.SGET_document(url.pathname)
/* eslint-disable */
this.openExistingDocumentRoute(doc)
/* eslint-enable */
}
}
catch (_) {
}
// @ts-ignore
this.openLink(event.target.href as string)
// @ts-ignore
}
}

View file

@ -9,6 +9,7 @@ import { uid, colors, extend } from "quasar"
import { I_FieldRelationship } from "src/interfaces/I_FieldRelationship"
import { I_KeyPressObject } from "src/interfaces/I_KeypressObject"
import { ProjectInterface } from "./store/module-project/state"
import { shell } from "electron"
const Blueprints = namespace("blueprintsModule")
const AllDocuments = namespace("allDocumentsModule")
@ -678,4 +679,25 @@ export default class BaseClass extends Vue {
return hasLegacyValue
})
}
openLink (link: string) {
try {
// @ts-ignore
const url = new URL(link)
// @ts-ignore
console.log(url)
if (url.protocol === "http:" || url.protocol === "https:") {
shell.openExternal(url.href).catch(e => console.log(e))
}
else if (url.protocol === "document:") {
const doc = this.SGET_document(url.pathname)
/* eslint-disable */
this.openExistingDocumentRoute(doc)
/* eslint-enable */
}
}
catch (_) {
}
}
}

View file

@ -241,7 +241,7 @@
<script lang="ts">
import { Component, Watch } from "vue-property-decorator"
import { Component, Emit, Prop, Watch } from "vue-property-decorator"
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
import { advancedDocumentFilter } from "src/scripts/utilities/advancedDocumentFilter"
import { extend, uid } from "quasar"
@ -260,6 +260,10 @@ import documentPreview from "src/components/DocumentPreview.vue"
}
})
export default class ExistingDocumentDialog extends DialogBase {
@Prop({
default: false
}) readonly preventOpen!: boolean
/****************************************************************/
// DIALOG CONTROL
/****************************************************************/
@ -490,6 +494,17 @@ export default class ExistingDocumentDialog extends DialogBase {
openExistingInput (e: I_ShortenedDocument) {
// @ts-ignore
e = (Array.isArray(e)) ? e[0] : e
// Signal to any listeners that care about this document being opened
this.signalDocumentSelected(e._id)
// If the caller doesn't want to open the document, don't actually open the document
if (this.preventOpen) {
this.dialogModel = false
this.existingDocumentModel = []
return
}
// Open document and close dialog
if (!this.disableCloseAftertSelectQuickSearch) {
this.dialogModel = false
@ -618,6 +633,12 @@ export default class ExistingDocumentDialog extends DialogBase {
this.SSET_setExportDialogState([node._id])
}
// Runs when a document would be opened by this dialog
@Emit()
signalDocumentSelected (document: string) {
return document
}
}
</script>

View file

@ -1,5 +1,14 @@
<template>
<div>
<template v-if="editMode">
<existingDocumentDialog
preventOpen="true"
:dialog-trigger="existingObjectDialogTrigger"
@trigger-dialog-close="existingObjectDialogClose"
@signal-document-selected="handleDocumentSelected"
/>
</template>
<div class="flex justify-center items-center text-weight-bolder q-mb-sm q-mt-md fieldWysiwygTitle">
<span>
<q-icon v-if="inputIcon" :name="inputIcon" :size="(inputIcon.includes('fas') || inputIcon.includes('fab'))? '15px': '20px'" class="q-mr-md"/>
@ -29,6 +38,8 @@
v-if="editMode"
:definitions="definitions"
min-height="350px"
@keypress.native="handleEditorKeypress"
@click.native="handleEditorClick"
/>
<div class="separatorWrapper">
@ -43,9 +54,12 @@
import { Component, Emit, Prop, Watch } from "vue-property-decorator"
import FieldBase from "src/components/fields/_FieldBase"
import { QEditor } from "quasar"
@Component({
components: { }
components: {
existingDocumentDialog: () => import("src/components/dialogs/ExistingDocument.vue")
}
})
export default class Field_Wysiwyg extends FieldBase {
/****************************************************************/
@ -145,6 +159,63 @@ export default class Field_Wysiwyg extends FieldBase {
/* eslint-enable */
}
existingObjectDialogTrigger: string | false = false
handleDocumentSelected (id: string) {
/*eslint-disable */
const editor = this.$refs[`wysiwygField${this.inputDataBluePrint.id}`] as any
editor.focus()
const doc = this.SGET_document(id)
// We need to timeout here to give time to the runtime to focus the editor.
// when focused the caret will return to it's previous position and we can insert the document link
setTimeout(() => {
editor.runCmd("insertHtml", `<a href="document:${id}">${doc.label}<a/>`)
}, 1)
/* eslint-enable */
}
existingObjectDialogClose () {
this.existingObjectDialogTrigger = false
}
existingObjectAssignUID () {
this.existingObjectDialogTrigger = this.generateUID()
}
handleEditorKeypress (evt: any) {
/*eslint-disable */
if (evt.key === '@' && this.editMode) {
const editor = this.$refs[`wysiwygField${this.inputDataBluePrint.id}`] as QEditor
// We don't want to paste anything special in the source mode editor, let the user do their thing
if ((editor as any).isViewingSource)
return;
// Prevent showing up `@` character
evt.preventDefault()
// Open the selector dialog
this.existingObjectAssignUID()
}
/* eslint-enable */
}
handleEditorClick (evt: any) {
/*eslint-disable */
if (evt.target.tagName.toLowerCase() === 'a') {
// Only follow links when ctrl is pressed
if (evt.ctrlKey) {
const link = evt.target.href
console.log(link)
console.log(evt.target.tagName)
evt.stopPropagation()
this.openLink(link)
}
}
/* eslint-enable */
}
/**
* Subsitution strings for toolbar
*/