fantasia-archive/src/pages/DocumentDisplay.vue

1361 lines
40 KiB
Vue
Raw Normal View History

2021-01-31 02:43:13 +13:00
<template>
2021-03-18 10:26:08 +13:00
<q-page
class="documentDisplay"
:class="{
'q-pb-xl q-pl-xl q-pr-xl': disableDocumentControlBar,
'q-pa-xl': !disableDocumentControlBar,
'hiddenFields': (hideEmptyFields || retrieveFieldValue(currentData, 'finishedSwitch'))
2021-03-18 10:26:08 +13:00
}"
2021-02-21 01:06:21 +13:00
v-if="bluePrintData"
>
2021-03-18 10:26:08 +13:00
<!-- Delele document dialog -->
<deleteDocumentCheckDialog
:dialog-trigger="deleteObjectDialogTrigger"
@trigger-dialog-close="deleteObjectDialogClose"
/>
2021-01-31 02:43:13 +13:00
<div class="row justify-start q-col-gutter-x-xl">
2021-03-18 10:26:08 +13:00
<div
class="flex justify-end localControlRow"
v-if="disableDocumentControlBar"
>
2021-04-17 00:46:34 +12:00
<q-btn
icon="mdi-content-save-edit"
:color="(hasEdits) ? 'teal-14' : 'primary'"
:outline="isDarkMode"
class="q-mr-md"
@click="saveCurrentDocument(true)"
v-if="editMode"
>
<q-tooltip
:delay="500"
anchor="bottom left"
self="top middle"
>
Save document without exiting edit mode
</q-tooltip>
</q-btn>
2021-03-18 10:26:08 +13:00
<q-btn
:color="(hasEdits) ? 'teal-14' : 'primary'"
icon="mdi-content-save"
2021-04-17 00:46:34 +12:00
@click="saveCurrentDocument(false)"
2021-03-18 10:26:08 +13:00
:outline="isDarkMode"
class="q-mr-md"
v-if="editMode"
>
<q-tooltip
:delay="500"
anchor="bottom middle"
self="top middle"
>
Save current document
</q-tooltip>
</q-btn>
<q-btn
color="primary"
icon="mdi-file-document-edit"
@click="toggleEditMode"
:outline="isDarkMode"
class="q-mr-md"
v-if="!editMode"
>
<q-tooltip
:delay="500"
anchor="bottom middle"
self="top middle"
>
Edit current document
</q-tooltip>
</q-btn>
2021-06-07 12:57:36 +12:00
<q-btn
icon="mdi-file-search-outline"
color="primary"
class="q-mr-md"
:outline="isDarkMode"
@click="openThisDocumentInSidebar"
v-if="!currentData.isNew"
>
<q-tooltip
:delay="500"
max-width="500px"
anchor="bottom middle"
self="top middle"
>
Preview document in split-view mode
</q-tooltip>
</q-btn>
2021-03-18 10:26:08 +13:00
<q-btn
color="primary"
icon="mdi-file-tree"
@click="addNewUnderParent"
:outline="isDarkMode"
class="q-mr-md"
v-if="!currentData.isNew"
>
<q-tooltip
:delay="500"
anchor="bottom middle"
self="top middle"
>
Add a new document with the currently opened one as the parent
2021-03-18 10:26:08 +13:00
</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-separator
vertical
inset
:color="(isDarkMode) ? 'accent' : 'black'"
class="q-mr-md"
/>
<q-btn
:color="(hasEdits) ? 'secondary' : 'primary'"
icon="mdi-database-export-outline"
2021-06-07 12:57:36 +12:00
@click="triggerExport"
:outline="isDarkMode"
class="q-mr-md"
v-if="!currentData.isNew"
>
<q-tooltip
:delay="500"
anchor="bottom middle"
self="top middle"
>
Export current project
<span class="text-secondary" v-if="hasEdits">
<br>
<br>
Document has active edits.
<br>
These will not be exported.
<br>
Please save first.
</span>
</q-tooltip>
</q-btn>
<q-separator
vertical
inset
:color="(isDarkMode) ? 'accent' : 'black'"
class="q-mr-md"
/>
2021-03-18 10:26:08 +13:00
<q-btn
color="secondary"
icon="mdi-text-box-remove-outline"
:outline="isDarkMode"
@click="deleteObjectAssignUID"
v-if="!currentData.isNew"
>
<q-tooltip
:delay="500"
anchor="bottom left"
self="top middle"
>
Delete current document
</q-tooltip>
</q-btn>
</div>
<div class="col-12 q-mt-xl justify-end" v-if="showDocumentID">
<q-input style="width: 375px;" readonly outlined label="Document ID" stack-label @click="copyID" ref="idCopy" v-model="currentData._id">
</q-input>
</div>
<div
v-for="field in bluePrintData.extraFields"
2021-04-06 01:28:33 +12:00
:key="`${field.id}`"
2021-05-15 11:35:18 +12:00
v-show="
(retrieveFieldType(currentData, field.id) !== 'break' || !hideDocumentTitles) &&
(
(hasValueFieldFilter(field) || editMode)
2021-06-11 13:01:18 +12:00
&& (checkBreakSectionValues(field) || editMode)
2021-05-15 11:35:18 +12:00
&& checkForLegacyFieldValue(currentData, field)
&& checkDocumentTemplate(field.id)
2021-05-15 11:35:18 +12:00
)
"
:class="`
col-12
col-md-${determineSize_MD(field)}
col-lg-${determineSize_LG(field)}
col-xl-${determineSize_XL(field)}
q-mb-md
documentColumnWrapper
2021-05-14 06:51:31 +12:00
${(determineLegacyField(currentData, field.id)) ? 'isLegacy' : ''}
`">
<Field_Break
class="inputWrapper break"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'break' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
/>
<Field_Text
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'text' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_Number
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'number' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_Switch
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'switch' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_ColorPicker
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'colorPicker' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_List
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'list' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_SingleSelect
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'singleSelect' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_MultiSelect
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'multiSelect' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_SingleRelationship
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="(field.type === 'singleToNoneRelationship' || field.type === 'singleToSingleRelationship' || field.type === 'singleToManyRelationship') && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
:current-id="currentData._id"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_MultiRelationship
class="inputWrapper"
v-if="(field.type === 'manyToNoneRelationship' || field.type ===
2021-04-06 01:28:33 +12:00
'manyToSingleRelationship' || field.type === 'manyToManyRelationship') && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
:current-id="currentData._id"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_Wysiwyg
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'wysiwyg' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="(retrieveFieldValue(currentData, field.id)) ? retrieveFieldValue(currentData, field.id) : ''"
:isNew="currentData.isNew"
:editMode="editMode"
:current-id="currentData._id"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_Tags
class="inputWrapper"
2021-04-06 01:28:33 +12:00
v-if="field.type === 'tags' && categoryFieldFilter(field.id)"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
<Field_DocumentTemplate
class="inputWrapper"
v-if="field.type === 'documentTemplate'"
:inputDataBluePrint="field"
:inputDataValue="retrieveFieldValue(currentData, field.id)"
:isNew="currentData.isNew"
:editMode="editMode"
@signal-input="reactToFieldUpdate($event, field)"
/>
</div>
2021-02-21 01:06:21 +13:00
2021-01-31 02:43:13 +13:00
</div>
</q-page>
</template>
<script lang="ts">
import { Component, Watch } from "vue-property-decorator"
2021-01-31 02:43:13 +13:00
import BaseClass from "src/BaseClass"
import { I_Blueprint, I_ExtraFields } from "src/interfaces/I_Blueprint"
import { extend } from "quasar"
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
import { copyDocument } from "src/scripts/documentActions/copyDocument"
2021-01-31 02:43:13 +13:00
import { saveDocument } from "src/scripts/databaseManager/documentManager"
2021-03-18 10:26:08 +13:00
import deleteDocumentCheckDialog from "src/components/dialogs/DeleteDocumentCheck.vue"
import { retrieveAllDocumentTemplatesFromDB } from "src/scripts/projectManagement/documentTemplates"
import Field_Break from "src/components/fields/Field_Break.vue"
import Field_Text from "src/components/fields/Field_Text.vue"
import Field_Number from "src/components/fields/Field_Number.vue"
import Field_Switch from "src/components/fields/Field_Switch.vue"
import Field_ColorPicker from "src/components/fields/Field_ColorPicker.vue"
import Field_List from "src/components/fields/Field_List.vue"
import Field_SingleSelect from "src/components/fields/Field_SingleSelect.vue"
import Field_MultiSelect from "src/components/fields/Field_MultiSelect.vue"
import Field_SingleRelationship from "src/components/fields/Field_SingleRelationship.vue"
import Field_MultiRelationship from "src/components/fields/Field_MultiRelationship.vue"
import Field_Wysiwyg from "src/components/fields/Field_Wysiwyg.vue"
import Field_Tags from "src/components/fields/Field_Tags.vue"
import Field_DocumentTemplate from "src/components/fields/Field_DocumentTemplate.vue"
import { updateLastOpenedDocuments } from "src/scripts/projectManagement/projectManagent"
import { I_DocumentTemplate } from "src/interfaces/I_DocumentTemplate"
2021-01-31 02:43:13 +13:00
@Component({
components: {
2021-02-09 15:21:48 +13:00
Field_Break,
2021-01-31 02:43:13 +13:00
Field_Text,
Field_Number,
2021-02-21 01:06:21 +13:00
Field_Switch,
Field_ColorPicker,
2021-01-31 02:43:13 +13:00
Field_List,
Field_SingleSelect,
Field_MultiSelect,
Field_SingleRelationship,
Field_MultiRelationship,
Field_Wysiwyg,
2021-03-18 10:26:08 +13:00
Field_Tags,
Field_DocumentTemplate,
2021-03-18 10:26:08 +13:00
deleteDocumentCheckDialog
2021-01-31 02:43:13 +13:00
}
})
export default class PageDocumentDisplay extends BaseClass {
2021-04-06 01:28:33 +12:00
/****************************************************************/
// LOCAL SETTINGS
/****************************************************************/
/**
* React to changes on the options store
*/
@Watch("SGET_options", { immediate: true, deep: true })
onSettingsChange () {
const options = this.SGET_options
this.disableDocumentControlBar = options.disableDocumentControlBar
this.isDarkMode = options.darkMode
this.hideEmptyFields = options.hideEmptyFields
2021-05-15 11:35:18 +12:00
this.hideDocumentTitles = options.hideDocumentTitles
this.preventAutoScroll = options.preventAutoScroll
this.showDocumentID = options.showDocumentID
2021-04-06 01:28:33 +12:00
}
2021-05-15 11:35:18 +12:00
hideDocumentTitles = false
showDocumentID = false
/**
* Determines if the documents will recall their scroll distances and auto-scroll on switching ot not.
*/
preventAutoScroll = false
2021-04-06 01:28:33 +12:00
/**
* Determines if the document control bar is show or hidden
*/
disableDocumentControlBar = false
/**
* Determines if this should be showing in dark or light mode
*/
isDarkMode = false
/**
* Determines if empty fields should be hidden
*/
hideEmptyFields = false
/****************************************************************/
// BASIC DATA
/****************************************************************/
/**
* The current object type blueprint data
*/
bluePrintData = false as unknown as I_Blueprint
/**
* Determines if the current document has active edits or not
*/
hasEdits = false
/**
* Determines if the current document is in edit mode or not
*/
editMode = false
/**
* Current raw data of the document
*/
currentData = false as unknown as I_OpenedDocument
/**
* A direct dopy of "currentData" for the purposes of VUEX so they won't overlap via reference
*/
localDataCopy = false as unknown as I_OpenedDocument
/****************************************************************/
// DOCUMENT FUNCTIONALITY
/****************************************************************/
2021-01-31 02:43:13 +13:00
/**
* Watches on changes of the route in order to load proper blueprint and object data
*/
@Watch("$route", { immediate: true, deep: true })
2021-03-18 10:26:08 +13:00
async onUrlChange () {
// window.removeEventListener("scroll", this.watchPageScroll)
// window.removeEventListener("scroll", this.watchPageScroll)
// window.removeEventListener("scroll", this.watchPageScroll)
this.documentTemplateList = await retrieveAllDocumentTemplatesFromDB()
2021-03-18 10:26:08 +13:00
await this.sleep(50)
const doc = this.findRequestedOrActiveDocument() as I_OpenedDocument
2021-03-18 10:26:08 +13:00
window.scrollTo({ top: 0, behavior: "auto" })
this.reloadLocalContent()
2021-03-18 10:26:08 +13:00
const scrollTop = (doc.scrollDistance && !this.preventAutoScroll) ? doc.scrollDistance : 0
window.scrollTo({ top: scrollTop, behavior: "auto" })
// window.removeEventListener("scroll", this.watchPageScroll)
// window.removeEventListener("scroll", this.watchPageScroll)
// window.removeEventListener("scroll", this.watchPageScroll)
// window.addEventListener("scroll", this.watchPageScroll)
}
documentTemplateList: I_DocumentTemplate[] = []
decounceScrollTimer = false as any
watchPageScroll () {
if (this.preventAutoScroll) {
return
}
if (this.decounceScrollTimer) {
window.clearTimeout(this.decounceScrollTimer)
}
this.decounceScrollTimer = window.setTimeout(() => {
const currentScroll = window.scrollY
const dataCopy: I_OpenedDocument = extend(true, {}, this.findRequestedOrActiveDocument())
dataCopy.scrollDistance = currentScroll
// Attempts to add current document to list
const dataPass = { doc: dataCopy, treeAction: false }
this.SSET_updateOpenedDocument(dataPass)
}, 200)
2021-03-18 10:26:08 +13:00
}
2021-04-06 01:28:33 +12:00
/**
* Check if the current document has edits or not
*/
2021-03-18 10:26:08 +13:00
checkHasEdits () {
const currentDocument = this.findRequestedOrActiveDocument()
if (currentDocument && currentDocument.hasEdits) {
this.hasEdits = true
}
else {
this.hasEdits = false
}
}
/**
* Watches on changes of the opened documents in order to load proper blueprint and object data
*/
@Watch("SGET_allOpenedDocuments", { deep: true })
async onDocChange () {
2021-03-18 10:26:08 +13:00
this.checkHasEdits()
2021-04-03 12:33:49 +13:00
await this.sleep(100)
const matchingDoc = this.findRequestedOrActiveDocument()
if (matchingDoc && matchingDoc._id === this.currentData._id && !matchingDoc.hasEdits) {
this.reloadLocalContent()
}
}
2021-04-06 01:28:33 +12:00
/**
* Attemp to reload the current local content. If it doesn't exist, create a new one.
*/
reloadLocalContent () {
2021-01-31 02:43:13 +13:00
// Determine the type and retrieve the right blueprint
this.bluePrintData = this.retrieveDocumentBlueprint()
// Check if the objects exists in a database
let retrievedObject = false as unknown as I_OpenedDocument | I_ShortenedDocument
if (this.SGET_document(this.$route.params.id)) {
retrievedObject = this.SGET_document(this.$route.params.id)
}
if (this.SGET_openedDocument(this.$route.params.id)) {
retrievedObject = this.SGET_openedDocument(this.$route.params.id)
2021-01-31 02:43:13 +13:00
}
// Either create a new document or load existing one
this.currentData = (retrievedObject) ? extend(true, [], retrievedObject) : this.createNewDocumentObject()
if (!this.currentData) {
this.$router.push({ path: "/project" }).catch((e: {name: string}) => {
if (e && e.name !== "NavigationDuplicated") {
console.log(e)
}
})
return
}
const objectFields = this.mapNewObjectFields()
2021-01-31 02:43:13 +13:00
if (!objectFields) {
return
}
2021-01-31 02:43:13 +13:00
this.currentData.extraFields = objectFields
if (this.currentData.editMode) {
this.editMode = true
}
else {
this.editMode = false
}
if (this.$route.query?.editMode) {
this.editMode = true
this.currentData.editMode = true
const query = Object.assign({}, this.$route.query)
delete query.editMode
this.$router.replace({ query }).catch(e => console.log(e))
}
2021-01-31 02:43:13 +13:00
const dataCopy: I_OpenedDocument = extend(true, {}, this.currentData)
// Attempts to add current document to list
2021-02-28 06:00:57 +13:00
const dataPass = { doc: dataCopy, treeAction: false }
this.SSET_addOpenedDocument(dataPass)
if (!this.currentData.isNew) {
updateLastOpenedDocuments(this.currentData._id).catch(e => console.log(e))
}
2021-01-31 02:43:13 +13:00
}
2021-04-06 01:28:33 +12:00
/**
* React to a local field getting updated by updating it iun the store accordingly
*/
2021-04-04 09:25:27 +12:00
reactToFieldUpdate (inputData: string, field: I_ExtraFields) {
2021-01-31 02:43:13 +13:00
// FIELD - Text
if (field.type === "text") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-01-31 02:43:13 +13:00
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
2021-02-21 01:06:21 +13:00
// FIELD - Number
2021-01-31 02:43:13 +13:00
if (field.type === "number") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
2021-02-21 01:06:21 +13:00
// FIELD - Switch
if (field.type === "switch") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-02-21 01:06:21 +13:00
if (field.id === "categorySwitch") {
const localCopy: I_Blueprint = (extend(true, {}, this.bluePrintData))
const blueprintUpdateCopy: I_Blueprint = (extend(true, {}, this.bluePrintData))
blueprintUpdateCopy.extraFields = []
// Reset fields so they re-render
this.SSET_blueprint(blueprintUpdateCopy)
this.retrieveDocumentBlueprint()
this.SSET_blueprint(localCopy)
this.retrieveDocumentBlueprint()
}
}
// FIELD - Color Picker
if (field.type === "colorPicker") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-02-21 01:06:21 +13:00
}
2021-01-31 02:43:13 +13:00
// FIELD - List
if (field.type === "list") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
// FIELD - Simple select
if (field.type === "singleSelect") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
// FIELD - Multi select
if (field.type === "multiSelect") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
// FIELD - Single relationship
if (field.type === "singleToNoneRelationship" || field.type === "singleToManyRelationship" || field.type === "singleToSingleRelationship") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
// FIELD - Multi relationship
if (field.type === "manyToNoneRelationship" || field.type === "manyToSingleRelationship" || field.type === "manyToManyRelationship") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
// @ts-ignore
2021-04-28 03:13:46 +12:00
if (inputData.isSilent) {
2021-04-04 09:25:27 +12:00
dataPass.doc.hasEdits = false
}
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
// FIELD - Wysiwyg
if (field.type === "wysiwyg") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
2021-02-28 06:00:57 +13:00
this.SSET_updateOpenedDocument(dataPass)
2021-01-31 02:43:13 +13:00
}
// FIELD - Tags
if (field.type === "tags") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
2021-03-11 13:10:22 +13:00
this.currentData.extraFields[indexToUpdate].value = inputData
2021-04-06 01:28:33 +12:00
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: false }
this.SSET_updateOpenedDocument(dataPass)
}
// FIELD - Document template
if (field.type === "documentTemplate") {
this.currentData.hasEdits = true
const indexToUpdate = this.currentData.extraFields.findIndex(s => s.id === field.id)
this.currentData.extraFields[indexToUpdate].value = inputData
this.localDataCopy = extend(true, {}, this.currentData)
const dataPass = { doc: this.localDataCopy, treeAction: true }
this.SSET_updateOpenedDocument(dataPass)
}
2021-01-31 02:43:13 +13:00
}
/**
* Retrieves the current document type blueprint
*/
retrieveDocumentBlueprint () : I_Blueprint {
this.bluePrintData = this.SGET_blueprint(this.$route.params.type)
return this.SGET_blueprint(this.$route.params.type)
}
2021-04-06 01:28:33 +12:00
/**
* Map new object "name" and "parentDoc" fields if pre-filled
*/
mapNewObjectFields () {
2021-01-31 02:43:13 +13:00
const currentExtraFields = (this.currentData && this.currentData.extraFields) ? this.currentData.extraFields : []
const blueprint = this.retrieveDocumentBlueprint()
if (!blueprint) {
return false
}
2021-01-31 02:43:13 +13:00
for (const field of blueprint.extraFields) {
const exists = currentExtraFields.find(f => {
return f.id === field.id
})
2021-01-31 02:43:13 +13:00
if (!exists) {
if (field.id === "name") {
currentExtraFields.push(
{
id: "name",
value: `New ${this.bluePrintData.nameSingular.toLowerCase()}`
}
)
}
else if (field.id === "parentDoc") {
if (this.$route.query?.parent) {
// Check if the objects exists in a database
const parentID = this.$route.query.parent as string
let retrievedObject = false as unknown as I_ShortenedDocument
try {
retrievedObject = this.SGET_document(parentID)
}
catch (error) {}
currentExtraFields.push(
{
id: "parentDoc",
value: {
value: {
_id: retrievedObject._id,
value: retrievedObject._id,
type: this.bluePrintData._id,
disable: false,
url: retrievedObject.url,
label: this.retrieveFieldValue(retrievedObject, "name"),
pairedField: ""
},
addedValues: {
pairedId: "",
value: ""
}
}
}
)
}
else {
currentExtraFields.push({ id: field.id, value: "" })
}
}
2021-06-07 12:57:36 +12:00
else if (field.id === "tags") {
if (this.$route.query?.tag) {
// Check if the objects exists in a database
const tag = this.$route.query.tag as string
currentExtraFields.push(
{
id: "tags",
value: [tag]
}
)
}
else {
currentExtraFields.push({ id: field.id, value: "" })
}
}
else {
2021-01-31 02:43:13 +13:00
currentExtraFields.push({ id: field.id, value: "" })
}
}
}
2021-01-31 02:43:13 +13:00
return currentExtraFields
}
/**
* Creates a new document object
*/
createNewDocumentObject () : I_OpenedDocument {
this.editMode = true
if (!this.$route.params.id || !this.bluePrintData) {
// @ts-ignore
return false
}
2021-01-31 02:43:13 +13:00
const uniqueID = this.$route.params.id
return {
_id: uniqueID,
type: this.bluePrintData._id,
icon: this.bluePrintData.icon,
editMode: true,
isNew: true,
isFinished: false,
2021-01-31 02:43:13 +13:00
hasEdits: false,
url: `/project/display-content/${this.bluePrintData._id}/${uniqueID}`,
extraFields: []
}
}
2021-02-21 01:06:21 +13:00
2021-04-06 01:28:33 +12:00
/**
* Check if field should be showing if the category setting is turned on
*/
categoryFieldFilter (currentFieldID: string) {
2021-02-21 01:06:21 +13:00
const isCategory = this.retrieveFieldValue(this.currentData, "categorySwitch")
const ignoredList = ["breakDocumentSettings", "name", "documentColor", "documentBackgroundColor", "parentDoc", "order", "categorySwitch", "minorSwitch", "deadSwitch", "finishedSwitch", "tags", "otherNames", "docTemplate"]
return (
(
(!isCategory && currentFieldID !== "categoryDescription") ||
ignoredList.includes(currentFieldID)
) || (isCategory && currentFieldID === "categoryDescription")
)
2021-02-21 01:06:21 +13:00
}
2021-03-18 10:26:08 +13:00
2021-06-11 13:01:18 +12:00
checkBreakSectionValues (field: any) {
// If this isnt break, let it through
if (field.type !== "break") {
return true
}
// If this is a break, keep checking following field either until a filled value if found (in which case, elt it through) or until anothe break OR end of the list is found - in which case, deny it
const fullFieldLength = this.bluePrintData.extraFields.length
let matchedIndex = this.bluePrintData.extraFields.findIndex(f => f.id === field.id)
let matchedField = this.bluePrintData.extraFields[matchedIndex + 1]
while (matchedField.type !== "break" || matchedIndex + 1 === fullFieldLength) {
matchedField = this.bluePrintData.extraFields[matchedIndex + 1]
2021-06-11 13:01:18 +12:00
if (!matchedField || matchedField.type === "break") {
return false
}
2021-06-11 13:01:18 +12:00
const hasValue = this.hasValueFieldFilter(matchedField)
if (hasValue) {
return true
}
matchedIndex++
}
return false
}
2021-05-14 06:51:31 +12:00
checkForLegacyFieldValue (document: I_OpenedDocument| I_ShortenedDocument, field: {id: string}) {
const isLegacyField = this.determineLegacyField(document, field.id)
if (!isLegacyField) {
return true
}
const value = this.retrieveFieldValue(this.currentData, field.id)
let hasValue = true
if (!value ||
2021-07-05 11:29:21 +12:00
(typeof value === "string" && value.length === 0) ||
// @ts-ignore
(typeof value.value === "string" && value.value.length === 0) ||
// @ts-ignore
2021-05-14 06:51:31 +12:00
(Array.isArray(value) && value.length === 0) ||
// @ts-ignore
2021-07-05 11:29:21 +12:00
(value.value && value.value.length === 0) ||
2021-05-14 06:51:31 +12:00
// @ts-ignore
(value.value === null)) {
hasValue = false
}
if (isLegacyField && hasValue) {
return true
}
return false
}
2021-04-06 01:28:33 +12:00
/**
* Checks if the field in question
*/
hasValueFieldFilter (field: any) {
if (this.retrieveFieldType(this.currentData, field.id) === "break") {
return true
}
if (!this.hideEmptyFields && !this.retrieveFieldValue(this.currentData, "finishedSwitch")) {
2021-04-06 01:28:33 +12:00
return true
}
const value = this.retrieveFieldValue(this.currentData, field.id)
if (!value ||
(Array.isArray(value) && value.length === 0) ||
// @ts-ignore
(value?.value?.length === 0) ||
2021-04-06 01:28:33 +12:00
// @ts-ignore
(value.value === null)) {
return false
}
2021-04-06 01:28:33 +12:00
return true
}
/****************************************************************/
// RESPONSIVE COLLUMN STYLES
/****************************************************************/
determineSize_MD (field: I_ExtraFields) {
if (field.type === "break") {
return 12
}
if (field.sizing <= 6) {
return 6
}
return field.sizing
}
determineSize_LG (field: I_ExtraFields) {
if (field.type === "break") {
return 12
}
if (field.sizing <= 4) {
return 4
}
return field.sizing
}
determineSize_XL (field: I_ExtraFields) {
if (field.type === "break") {
return 12
}
return field.sizing
}
2021-03-18 10:26:08 +13:00
/****************************************************************/
2021-04-06 01:28:33 +12:00
// DELETE DIALOG
2021-03-18 10:26:08 +13:00
/****************************************************************/
deleteObjectDialogTrigger: string | false = false
deleteObjectDialogClose () {
this.deleteObjectDialogTrigger = false
}
deleteObjectAssignUID () {
this.deleteObjectDialogTrigger = this.generateUID()
}
/****************************************************************/
2021-04-06 01:28:33 +12:00
// ADD NEW DOCUMENT UNDER PARENT
2021-03-18 10:26:08 +13:00
/****************************************************************/
addNewUnderParent () {
const currentDoc = this.findRequestedOrActiveDocument()
if (currentDoc) {
const routeObject = {
_id: currentDoc.type,
parent: currentDoc._id
}
// @ts-ignore
this.addNewObjectRoute(routeObject)
}
}
/****************************************************************/
// DOCUMENT COPY
/****************************************************************/
documentPass = null as unknown as I_OpenedDocument
copyTargetDocument () {
this.documentPass = extend(true, {}, this.findRequestedOrActiveDocument())
2021-05-02 02:31:33 +12:00
const blueprint = this.SGET_blueprint(this.documentPass.type)
const newDocument = copyDocument(this.documentPass, this.generateUID(), blueprint)
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)
})
}
2021-03-18 10:26:08 +13:00
/****************************************************************/
2021-04-06 01:28:33 +12:00
// DOCUMENT ACTIONS
2021-03-18 10:26:08 +13:00
/****************************************************************/
2021-04-06 01:28:33 +12:00
/**
* Turns onthe edit mode
*/
2021-03-18 10:26:08 +13:00
toggleEditMode () {
const currentDoc = this.findRequestedOrActiveDocument()
if (currentDoc && !currentDoc.editMode) {
const dataCopy: I_OpenedDocument = extend(true, {}, currentDoc)
dataCopy.editMode = true
const dataPass = { doc: dataCopy, treeAction: false }
this.SSET_updateOpenedDocument(dataPass)
}
}
2021-04-06 01:28:33 +12:00
/**
* Saves the current document
*/
2021-04-17 00:46:34 +12:00
async saveCurrentDocument (keepEditMode: boolean) {
if (document.activeElement && keepEditMode === false) {
2021-03-18 10:26:08 +13:00
(document.activeElement as HTMLElement).blur()
}
const currentDoc = this.findRequestedOrActiveDocument()
2021-04-27 01:01:51 +12:00
// @ts-ignore
const isNew = currentDoc.isNew
2021-03-18 10:26:08 +13:00
const allDocuments = this.SGET_allOpenedDocuments
const openedDocumentsCopy: I_OpenedDocument[] = extend(true, [], allDocuments.docs)
2021-03-18 10:26:08 +13:00
if (currentDoc) {
2021-05-15 11:35:18 +12:00
const docCopy:I_OpenedDocument = extend(true, [], currentDoc)
2021-03-18 10:26:08 +13:00
// @ts-ignore
const savedDocument: {
documentCopy: I_OpenedDocument,
allOpenedDocuments: I_OpenedDocument[]
2021-05-15 11:35:18 +12:00
} = await saveDocument(docCopy, openedDocumentsCopy, this.SGET_allDocuments.docs, keepEditMode, this)
2021-03-18 10:26:08 +13:00
// Update the opened document
const dataPass = { doc: savedDocument.documentCopy, treeAction: true }
this.SSET_updateOpenedDocument(dataPass)
2021-04-27 01:01:51 +12:00
// Update document
if (!isNew) {
// @ts-ignore
this.SSET_updateDocument({ doc: this.mapShortDocument(savedDocument.documentCopy, this.SGET_allDocumentsByType(savedDocument.documentCopy.type).docs) })
}
// Add new document
else {
// @ts-ignore
this.SSET_addDocument({ doc: this.mapShortDocument(savedDocument.documentCopy, this.SGET_allDocumentsByType(savedDocument.documentCopy.type).docs) })
}
2021-03-18 10:26:08 +13:00
// Update all others
for (const doc of savedDocument.allOpenedDocuments) {
// Update the opened document
const dataPass = { doc: doc, treeAction: true }
this.SSET_updateOpenedDocument(dataPass)
// @ts-ignored
this.SSET_updateDocument({ doc: this.mapShortDocument(doc, this.SGET_allDocumentsByType(doc.type).docs) })
2021-03-18 10:26:08 +13:00
}
2021-04-17 00:46:34 +12:00
this.$q.notify({
group: false,
type: "positive",
message: "Document successfully saved"
})
2021-03-18 10:26:08 +13:00
}
}
2021-06-07 12:57:36 +12:00
/****************************************************************/
// Open current document in sidebar
/****************************************************************/
openThisDocumentInSidebar () {
const currentDoc = this.findRequestedOrActiveDocument() as I_OpenedDocument
this.openDocumentPreviewPanel(currentDoc._id)
}
copyID () {
const copyText = this.$refs.idCopy
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
copyText.select()
document.execCommand("copy")
this.$q.notify({
group: false,
type: "positive",
message: "Document ID Copied"
})
}
2021-06-07 12:57:36 +12:00
triggerExport () {
const localId = this.currentData._id
this.SSET_setExportDialogState([localId])
}
checkDocumentTemplate (id: string) {
const ignoredList = ["breakDocumentSettings", "name", "documentColor", "documentBackgroundColor", "parentDoc", "order", "categorySwitch", "minorSwitch", "deadSwitch", "finishedSwitch", "tags", "docTemplate"]
if (ignoredList.includes(id)) {
return true
}
const selectedTemplate = this.retrieveFieldValue(this.currentData, "docTemplate")
if (!selectedTemplate) {
return true
}
const matchedDocumentTemplate = this.documentTemplateList.find(e => e.id === selectedTemplate)
if (!matchedDocumentTemplate) {
return true
}
const matchedDocumentType = matchedDocumentTemplate.documentTypeList.find(e => e.documentTypeID === this.bluePrintData._id)
if (!matchedDocumentType) {
return true
}
if (matchedDocumentType.excludedFieldIDList.includes(id)) {
return false
}
return true
}
2021-01-31 02:43:13 +13:00
}
</script>
<style lang="scss" scoped>
.inputWrapper {
2021-03-08 11:07:40 +13:00
min-height: 95px;
2021-01-31 02:43:13 +13:00
display: flex;
flex-direction: column;
2021-02-09 15:21:48 +13:00
justify-content: flex-start;
height: 100%;
&.break {
min-height: inherit;
}
}
</style>
<style lang="scss">
.documentColumnWrapper {
flex-grow: 1;
2021-05-14 06:51:31 +12:00
&.isLegacy {
border: 1px dashed $primary;
padding: 30px;
margin-left: 20px;
max-width: 98%;
margin-top: 20px;
background-color: rgba($secondary, 0.15);
}
}
2021-02-09 15:21:48 +13:00
.separatorWrapper {
margin-top: auto;
}
.q-field {
max-width: 100%;
2021-01-31 02:43:13 +13:00
}
2021-03-18 10:26:08 +13:00
.documentDisplay {
&.hiddenFields {
padding-top: 105px;
}
.localControlRow {
position: absolute;
right: 48px;
top: 50px;
}
/* WebKit/Blink Browsers */
::selection {
background: lighten($dark, 30);
color: white;
}
/* Gecko Browsers */
::-moz-selection {
background: lighten($dark, 30);
color: white;
}
}
2021-04-18 02:43:13 +12:00
body:not(.body--dark) {
.documentDisplay {
.isDead {
text-decoration-color: #000;
}
}
}
2021-03-18 10:26:08 +13:00
body.body--dark {
.documentDisplay {
/* WebKit/Blink Browsers */
::selection {
color: lighten($primary, 25);
background: lighten($secondary, 7);
}
/* Gecko Browsers */
::-moz-selection {
color: lighten($primary, 25);
background: lighten($secondary, 7);
}
$darkModeText: #dcdcdc;
color: $darkModeText;
.connectionList .connectionNote,
.listNote {
color: $darkModeText;
opacity: 0.9;
}
.q-list--dark,
.q-item--dark,
.q-field--dark .q-field__native,
.q-field--dark .q-field__prefix,
.q-field--dark .q-field__suffix,
.q-field--dark .q-field__input {
color: $darkModeText;
}
.q-separator {
opacity: 0.85;
background-color: $primary !important;
}
.q-field--dark .q-field__control::before {
background-color: rgba(255, 255, 255, 0.1);
opacity: 0.6;
border: none;
}
.tagSelect,
.singleSelect,
.multiSelect,
.singleRelashionshipSelect,
.multiRelashionshipSelect,
.existingDocumentSelect,
.newDocumentSelect {
&.q-field--dark .q-field__control::before {
border: none;
}
.relationshipChipNewTab,
2021-03-18 10:26:08 +13:00
.q-field__input,
.q-icon,
.q-field__native span {
color: $darkModeText !important;
.q-icon,
2021-03-18 10:26:08 +13:00
&.q-chip__icon--remove {
color: #000 !important;
}
}
}
}
}
2021-01-31 02:43:13 +13:00
</style>