mirror of
https://github.com/Elvanos/fantasia-archive.git
synced 2024-06-02 02:14:47 +12:00
0.1.7-DEV-1: added on-the-fly relationship documents generation
This commit is contained in:
parent
8345634a93
commit
88bff4a5ba
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "fantasiaarchive",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"description": "A database manager for world building",
|
||||
"productName": "Fantasia Archive",
|
||||
"author": "Elvanos <elvanos66@gmail.com>",
|
||||
|
|
44
src/App.vue
44
src/App.vue
|
@ -7,8 +7,8 @@
|
|||
no-resize
|
||||
dark
|
||||
title="Advanced Search Cheatsheet"
|
||||
:height="510"
|
||||
:width="425"
|
||||
:height="535"
|
||||
:width="500"
|
||||
:start-x="50"
|
||||
:start-y="150"
|
||||
:actions="['pin', 'close']"
|
||||
|
@ -77,7 +77,7 @@ export default class App extends BaseClass {
|
|||
// APP START & END SETUP
|
||||
/****************************************************************/
|
||||
|
||||
created () {
|
||||
async created () {
|
||||
// Catch middle clicks
|
||||
window.addEventListener("auxclick", this.reactToMiddleClick)
|
||||
|
||||
|
@ -89,19 +89,19 @@ export default class App extends BaseClass {
|
|||
}
|
||||
}
|
||||
|
||||
// Catch normal clicks inside wysiwyg
|
||||
window.addEventListener("click", this.openWysiwygLink)
|
||||
|
||||
// Load settings
|
||||
this.loadSettings().catch(e => console.log(e))
|
||||
await this.loadSettings()
|
||||
|
||||
// React to keybind presses
|
||||
window.addEventListener("keydown", this.triggerKeyPush)
|
||||
await this.loadCorkboardCotent()
|
||||
|
||||
// Load the popup hint on start
|
||||
this.loadHintPopup()
|
||||
|
||||
this.loadCorkboardCotent().catch(e => console.log(e))
|
||||
// React to keybind presses
|
||||
window.addEventListener("keydown", this.triggerKeyPush)
|
||||
|
||||
// Catch normal clicks inside wysiwyg
|
||||
window.addEventListener("click", this.openWysiwygLink)
|
||||
}
|
||||
|
||||
destroyed () {
|
||||
|
@ -344,9 +344,31 @@ export default class App extends BaseClass {
|
|||
}, 1000)
|
||||
}
|
||||
|
||||
/**
|
||||
* Corkboard checker
|
||||
* Can go up to 3
|
||||
*/
|
||||
corkboardCheck = 0
|
||||
|
||||
async loadCorkboardCotent () {
|
||||
const options = this.SGET_options
|
||||
|
||||
this.corkboardContent = await retrieveCorkboard()
|
||||
if (this.corkboardContent.length > 0) {
|
||||
|
||||
// Considering there is a bit of a delay between the initial load of the store DB content, we give the program 3 attempts to load the data over 3 seconds. If no is loaded in that time, we assume that the settings are not set at all and display the hint as normal.
|
||||
if ((!options._id || !options._rev) && this.corkboardCheck < 3) {
|
||||
setTimeout(() => {
|
||||
this.corkboardCheck++
|
||||
this.loadCorkboardCotent().catch(e => console.log(e))
|
||||
}, 1000)
|
||||
return
|
||||
}
|
||||
|
||||
if (options.preventFilledNoteBoardPopup) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.corkboardContent.length) {
|
||||
this.corkboardWindowVisible = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -582,7 +582,7 @@ export default class DocumentControl extends BaseClass {
|
|||
const savedDocument: {
|
||||
documentCopy: I_OpenedDocument,
|
||||
allOpenedDocuments: I_OpenedDocument[]
|
||||
} = await saveDocument(currentDoc, this.documentsCopy, this.SGET_allDocuments.docs, editMode).catch(err => console.log(err))
|
||||
} = await saveDocument(currentDoc, this.documentsCopy, this.SGET_allDocuments.docs, editMode, this).catch(err => console.log(err))
|
||||
|
||||
// Update the opened document
|
||||
const dataPass = { doc: savedDocument.documentCopy, treeAction: true }
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
>
|
||||
<q-tab name="uiSettings" label="Visuals & Accessibility" />
|
||||
<q-tab name="docSettings" label="Document view/edit" />
|
||||
<q-tab name="popupSettings" label="Popup dialogs" />
|
||||
<q-tab name="popupSettings" label="Popups & Floating Windows" />
|
||||
<q-tab name="treeSettings" label="Hierarchical tree" />
|
||||
|
||||
<q-separator dark />
|
||||
|
@ -338,7 +338,7 @@
|
|||
<div class="row justify-start">
|
||||
<div class="col-12">
|
||||
<div class="text-h6">
|
||||
Popup dialogs
|
||||
Popups & Floating Windows
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -403,6 +403,31 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="text-bold q-mt-xl">
|
||||
Floating windows
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6 col-lg-4 optionWrapper">
|
||||
<div class="optionTitle">
|
||||
Prevent filled note board showing
|
||||
<q-icon name="mdi-help-circle" size="16px" class="q-ml-md">
|
||||
<q-tooltip :delay="500">
|
||||
Turning this on prevents the note board showing automatically
|
||||
<br>
|
||||
at the start of the app in case in contains any notes persisting
|
||||
<br>
|
||||
from previous sessions of FA that the user filed previously.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</div>
|
||||
|
||||
<q-toggle
|
||||
v-model="options.preventFilledNoteBoardPopup"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
</q-tab-panel>
|
||||
|
@ -917,6 +942,7 @@ export default class ProgramSettings extends DialogBase {
|
|||
options: OptionsStateInteface = {
|
||||
_id: "settings",
|
||||
darkMode: false,
|
||||
preventFilledNoteBoardPopup: false,
|
||||
preventAutoScroll: false,
|
||||
textShadow: false,
|
||||
hideAdvSearchCheatsheetButton: false,
|
||||
|
|
|
@ -148,6 +148,8 @@
|
|||
:option-disable="opt => Object(opt) === opt ? disabledIDList.includes(opt._id) : true"
|
||||
:outlined="!isDarkMode"
|
||||
:filled="isDarkMode"
|
||||
new-value-mode="add-unique"
|
||||
@new-value="addNewRelationshipObject"
|
||||
use-chips
|
||||
multiple
|
||||
option-value="_id"
|
||||
|
@ -170,10 +172,16 @@
|
|||
dense
|
||||
@remove="scope.removeAtIndex(scope.index)"
|
||||
:tabindex="scope.tabindex"
|
||||
color="accent"
|
||||
:color="(scope.opt.isAutoGenerated) ? 'teal-3' : 'accent'"
|
||||
text-color="dark"
|
||||
class="text-bold"
|
||||
>
|
||||
|
||||
<q-tooltip
|
||||
v-if="scope.opt.isAutoGenerated"
|
||||
:delay="500">
|
||||
This document doesn't exist yet. It will be auto-generated on save.
|
||||
</q-tooltip>
|
||||
<template v-if="scope.opt.isDead">
|
||||
†
|
||||
</template>
|
||||
|
@ -187,6 +195,7 @@
|
|||
size="sm"
|
||||
icon="mdi-open-in-new"
|
||||
@click.stop.prevent="openNewTab(scope.opt)"
|
||||
v-if="!scope.opt.isAutoGenerated"
|
||||
>
|
||||
<q-tooltip :delay="500">
|
||||
Open in new tab without leaving this one
|
||||
|
@ -433,7 +442,7 @@ import { Component, Emit, Prop, Watch } from "vue-property-decorator"
|
|||
|
||||
import FieldBase from "src/components/fields/_FieldBase"
|
||||
import { advancedDocumentFilter } from "src/scripts/utilities/advancedDocumentFilter"
|
||||
import { extend } from "quasar"
|
||||
import { extend, uid } from "quasar"
|
||||
import { I_ShortenedDocument, I_OpenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { I_FieldRelationship, I_RelationshipPair } from "src/interfaces/I_FieldRelationship"
|
||||
import { createNewWithParent } from "src/scripts/documentActions/createNewWithParent"
|
||||
|
@ -625,22 +634,28 @@ export default class Field_MultiRelationship extends FieldBase {
|
|||
this.localInput = (Array.isArray(this.localInput)) ? this.localInput : []
|
||||
|
||||
const toRemoveIndexList: string[] = []
|
||||
let autoGenerateCleanup = false
|
||||
|
||||
for (const [index] of this.localInput.entries()) {
|
||||
// Proceed only if the local input is properly set up
|
||||
if (this.localInput[index]._id) {
|
||||
// If the matched object doesn't exist in the object, assume it has been deleted or newer existed and silently emit a signal input which auto-updates the document
|
||||
|
||||
if (!allDbObjects.docs.find(e => e._id === this.localInput[index]._id)) {
|
||||
if (!allDbObjects.docs.find(e => e._id === this.localInput[index]._id) && !this.localInput[index]?.isAutoGenerated) {
|
||||
toRemoveIndexList.push(this.localInput[index]._id)
|
||||
}
|
||||
|
||||
// If the object does exist, make sure we have the newest available name by reasigning the label if it is different. Then trigger a silent update
|
||||
else {
|
||||
if (allDbObjects.docs.find(e => e._id === this.localInput[index]._id)) {
|
||||
const matchedFieldContent = allDbObjects.docs.find(e => e._id === this.localInput[index]._id)
|
||||
if (matchedFieldContent) {
|
||||
this.localInput[index].label = matchedFieldContent.label
|
||||
this.localInput[index].isDead = matchedFieldContent.extraFields.find(e => e.id === "deadSwitch")?.value
|
||||
}
|
||||
if (this.localInput[index].isAutoGenerated) {
|
||||
this.localInput[index].isAutoGenerated = false
|
||||
autoGenerateCleanup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -648,7 +663,7 @@ export default class Field_MultiRelationship extends FieldBase {
|
|||
this.allTypeDocuments = allDbObjects.docs
|
||||
|
||||
// Remove delete documents paired to this
|
||||
if (toRemoveIndexList.length > 0) {
|
||||
if (toRemoveIndexList.length > 0 || autoGenerateCleanup) {
|
||||
toRemoveIndexList.forEach((id) => {
|
||||
const indexToRemove = this.localInput.findIndex(doc => doc._id === id)
|
||||
if (indexToRemove > -1) {
|
||||
|
@ -721,6 +736,8 @@ export default class Field_MultiRelationship extends FieldBase {
|
|||
id: e._id,
|
||||
type: e.type,
|
||||
url: e.url,
|
||||
label: (e?.label) || "",
|
||||
isAutoGenerated: (e.isAutoGenerated),
|
||||
pairedField: (this.inputDataBluePrint?.relationshipSettings?.connectedField) || ""
|
||||
}
|
||||
}),
|
||||
|
@ -819,6 +836,83 @@ export default class Field_MultiRelationship extends FieldBase {
|
|||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
addNewRelationshipObject (input: string) {
|
||||
const newObjectType = this.inputDataBluePrint?.relationshipSettings?.connectedObjectType as unknown as string
|
||||
|
||||
const pairedBlueprint = this.SGET_blueprint(newObjectType)
|
||||
|
||||
const newObjectID = uid()
|
||||
|
||||
const newDocument = {
|
||||
bgColor: undefined,
|
||||
color: undefined,
|
||||
extraFields: [
|
||||
|
||||
{
|
||||
id: "name",
|
||||
value: input
|
||||
},
|
||||
{
|
||||
id: "parentDoc",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentBackgroundColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "finishedSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "minorSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "deadSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "categorySwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "order",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "tags",
|
||||
value: []
|
||||
},
|
||||
{
|
||||
id: "categoryDescription",
|
||||
value: ""
|
||||
}
|
||||
],
|
||||
hierarchicalPath: pairedBlueprint.namePlural,
|
||||
icon: pairedBlueprint.icon,
|
||||
id: newObjectID,
|
||||
isCategory: "",
|
||||
isDead: undefined,
|
||||
isMinor: undefined,
|
||||
isAutoGenerated: true,
|
||||
label: input,
|
||||
tags: [],
|
||||
type: newObjectType,
|
||||
url: `/project/display-content/${newObjectType}/${newObjectID}`,
|
||||
_id: newObjectID
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.localInput.push(newDocument)
|
||||
|
||||
this.processInput()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -143,6 +143,8 @@
|
|||
:options="filterList"
|
||||
:option-disable="opt => Object(opt) === opt ? disabledIDList.includes(opt._id) : true"
|
||||
use-input
|
||||
new-value-mode="add-unique"
|
||||
@new-value="addNewRelationshipObject"
|
||||
:outlined="!isDarkMode"
|
||||
:filled="isDarkMode"
|
||||
input-debounce="500"
|
||||
|
@ -167,10 +169,16 @@
|
|||
@click="openNewTab(scope.opt)"
|
||||
@remove="scope.removeAtIndex(scope.index)"
|
||||
:tabindex="scope.tabindex"
|
||||
color="accent"
|
||||
:color="(scope.opt.isAutoGenerated) ? 'teal-3' : 'accent'"
|
||||
text-color="dark"
|
||||
class="text-bold"
|
||||
>
|
||||
<q-tooltip
|
||||
v-if="scope.opt.isAutoGenerated"
|
||||
:delay="500">
|
||||
This document doesn't exist yet. It will be auto-generated on save.
|
||||
</q-tooltip>
|
||||
|
||||
<template v-if="scope.opt.isDead">
|
||||
†
|
||||
</template>
|
||||
|
@ -183,6 +191,7 @@
|
|||
style="color: #000 !important;"
|
||||
size="sm"
|
||||
icon="mdi-open-in-new"
|
||||
v-if="!scope.opt.isAutoGenerated"
|
||||
@click.stop.prevent="openNewTab(scope.opt)"
|
||||
>
|
||||
<q-tooltip :delay="500">
|
||||
|
@ -386,7 +395,7 @@ import { Component, Emit, Prop, Watch } from "vue-property-decorator"
|
|||
import FieldBase from "src/components/fields/_FieldBase"
|
||||
|
||||
import { advancedDocumentFilter } from "src/scripts/utilities/advancedDocumentFilter"
|
||||
import { extend } from "quasar"
|
||||
import { extend, uid } from "quasar"
|
||||
|
||||
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { I_FieldRelationship, I_RelationshipPairSingle } from "src/interfaces/I_FieldRelationship"
|
||||
|
@ -580,12 +589,14 @@ export default class Field_SingleRelationship extends FieldBase {
|
|||
// Proceed only if the local input is properly set up
|
||||
if (this.localInput._id) {
|
||||
// If the matched object doesn't exist in the object, assume it has been deleted or never existed
|
||||
if (!allDbObjects.docs.find(e => e._id === this.localInput._id)) {
|
||||
if (!allDbObjects.docs.find(e => e._id === this.localInput._id) && !this.localInput?.isAutoGenerated) {
|
||||
// @ts-ignore
|
||||
|
||||
this.localInput = ""
|
||||
}
|
||||
|
||||
// If the object does exist, make sure we have the newest available name by reasigning the label if it is different
|
||||
else {
|
||||
if (allDbObjects.docs.find(e => e._id === this.localInput._id)) {
|
||||
const matchedFieldContent = allDbObjects.docs.find(e => e._id === this.localInput._id)
|
||||
|
||||
if (matchedFieldContent && (
|
||||
|
@ -595,6 +606,10 @@ export default class Field_SingleRelationship extends FieldBase {
|
|||
this.localInput.label = matchedFieldContent.label
|
||||
this.localInput.isDead = matchedFieldContent.extraFields.find(e => e.id === "deadSwitch")?.value
|
||||
}
|
||||
|
||||
if (this.localInput.isAutoGenerated) {
|
||||
this.localInput.isAutoGenerated = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,6 +679,8 @@ export default class Field_SingleRelationship extends FieldBase {
|
|||
id: this.localInput._id,
|
||||
type: this.localInput.type,
|
||||
url: this.localInput.url,
|
||||
label: (this.localInput?.label) || "",
|
||||
isAutoGenerated: (this.localInput.isAutoGenerated),
|
||||
pairedField: (this.inputDataBluePrint?.relationshipSettings?.connectedField) || ""
|
||||
}
|
||||
: null
|
||||
|
@ -753,6 +770,83 @@ export default class Field_SingleRelationship extends FieldBase {
|
|||
console.log(e)
|
||||
})
|
||||
}
|
||||
|
||||
addNewRelationshipObject (input: string) {
|
||||
const newObjectType = this.inputDataBluePrint?.relationshipSettings?.connectedObjectType as unknown as string
|
||||
|
||||
const pairedBlueprint = this.SGET_blueprint(newObjectType)
|
||||
|
||||
const newObjectID = uid()
|
||||
|
||||
const newDocument = {
|
||||
bgColor: undefined,
|
||||
color: undefined,
|
||||
extraFields: [
|
||||
|
||||
{
|
||||
id: "name",
|
||||
value: input
|
||||
},
|
||||
{
|
||||
id: "parentDoc",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentBackgroundColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "finishedSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "minorSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "deadSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "categorySwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "order",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "tags",
|
||||
value: []
|
||||
},
|
||||
{
|
||||
id: "categoryDescription",
|
||||
value: ""
|
||||
}
|
||||
],
|
||||
hierarchicalPath: pairedBlueprint.namePlural,
|
||||
icon: pairedBlueprint.icon,
|
||||
id: newObjectID,
|
||||
isCategory: "",
|
||||
isDead: undefined,
|
||||
isMinor: undefined,
|
||||
isAutoGenerated: true,
|
||||
label: input,
|
||||
tags: [],
|
||||
type: newObjectType,
|
||||
url: `/project/display-content/${newObjectType}/${newObjectID}`,
|
||||
_id: newObjectID
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.localInput = newDocument
|
||||
|
||||
this.processInput()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
use-chips
|
||||
@filter="filterFn"
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
new-value-mode="add-unique"
|
||||
multiple
|
||||
v-model="localInput"
|
||||
@new-value="addNewValue"
|
||||
|
|
|
@ -612,11 +612,11 @@ body .q-tooltip {
|
|||
min-height: 186px !important;
|
||||
min-width: 250px !important;
|
||||
|
||||
.q-window__body{
|
||||
.q-window__body {
|
||||
min-height: 146px !important;
|
||||
min-width: 250px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.corkboardInput {
|
||||
height: 100%;
|
||||
|
@ -627,7 +627,7 @@ body .q-tooltip {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.q-validation-component{
|
||||
.q-validation-component {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
@ -651,3 +651,8 @@ body .q-tooltip {
|
|||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
#q-app {
|
||||
position: relative;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
|
|
@ -13,4 +13,5 @@
|
|||
- Full search
|
||||
- `%` - Beginning of the full-search
|
||||
- `:` - Division between the field-name and field value
|
||||
- `%:something` - Search through all fields for value
|
||||
- `%some-field:some-value` - Search through all fields for value
|
||||
- This can also be used to search for colors: `%color:blue`
|
||||
|
|
|
@ -3,6 +3,28 @@
|
|||
|
||||
---
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Known issues
|
||||
|
||||
- Creating a brand new project can sometimes get stuck. Restarting the app fixes this.
|
||||
- Importing existing project can sometimes get stuck. Restarting the app fixes this.
|
||||
|
||||
### Bugfixes & Optimizations
|
||||
|
||||
- Fixed infinite vertical scroll of the app caused by buggy behavior of the floating windows being pulled on the bottom of the visible window
|
||||
- Fixed a limiter for advanced search that was throwing errors in rare cases
|
||||
- Fixed a bug that was causing single-to-single relationship notes not properly saving
|
||||
|
||||
### New features
|
||||
|
||||
- **Added on-the-fly relationship documents generation**
|
||||
- Added option: Prevent filled note board showing
|
||||
|
||||
### QoL adjustments
|
||||
|
||||
- Added a note about possible color searching in the advanced search cheatsheet popup window
|
||||
|
||||
## 0.1.6a
|
||||
|
||||
### Known issues
|
||||
|
|
2
src/env.d.ts
vendored
2
src/env.d.ts
vendored
|
@ -1,5 +1,5 @@
|
|||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
interface ProcessEnv {
|
||||
NODE_ENV: string;
|
||||
VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined;
|
||||
VUE_ROUTER_BASE: string | undefined;
|
||||
|
|
|
@ -7,6 +7,7 @@ export interface I_FieldRelationship{
|
|||
pairedField: string
|
||||
isCategory: boolean
|
||||
isDead: boolean
|
||||
isAutoGenerated?: boolean
|
||||
}
|
||||
|
||||
export interface I_RelationshipPair {
|
||||
|
|
|
@ -932,7 +932,7 @@ export default class PageDocumentDisplay extends BaseClass {
|
|||
const savedDocument: {
|
||||
documentCopy: I_OpenedDocument,
|
||||
allOpenedDocuments: I_OpenedDocument[]
|
||||
} = await saveDocument(currentDoc, openedDocumentsCopy, this.SGET_allDocuments.docs, keepEditMode)
|
||||
} = await saveDocument(currentDoc, openedDocumentsCopy, this.SGET_allDocuments.docs, keepEditMode, this)
|
||||
|
||||
// Update the opened document
|
||||
const dataPass = { doc: savedDocument.documentCopy, treeAction: true }
|
||||
|
|
|
@ -564,7 +564,7 @@ export const charactersBlueprint: I_Blueprint = {
|
|||
"Focused",
|
||||
"Folksy",
|
||||
"Foolish",
|
||||
"Forecful",
|
||||
"Forceful",
|
||||
"Forgetful",
|
||||
"Forgiving",
|
||||
"Formal",
|
||||
|
|
|
@ -346,7 +346,7 @@ export const guildsBlueprint: I_Blueprint = {
|
|||
id: "pairedEnemyPolGroups",
|
||||
name: "Enemy Ideologies/Political groups",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-account-group",
|
||||
icon: "mdi-bank-outline",
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "politicalGroups",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { single_changeRelationshipToAnotherObject, many_changeRelationshipToAnotherObject } from "src/scripts/databaseManager/relationshipManager"
|
||||
import { I_OpenedDocument, I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
|
||||
import { I_ExtraFields } from "src/interfaces/I_Blueprint"
|
||||
import { extend } from "quasar"
|
||||
import { I_Blueprint, I_ExtraFields } from "src/interfaces/I_Blueprint"
|
||||
import PouchDB from "pouchdb"
|
||||
import { Loading, QSpinnerGears, extend } from "quasar"
|
||||
|
||||
/**
|
||||
* Saves the given project and handles all the needed procedures
|
||||
|
@ -11,10 +11,27 @@ export const saveDocument = async (
|
|||
document: I_OpenedDocument,
|
||||
allOpenedDocuments: I_OpenedDocument[],
|
||||
allDocuments: I_ShortenedDocument[],
|
||||
editModeAfterSave: boolean
|
||||
editModeAfterSave: boolean,
|
||||
vueInstance: any
|
||||
) => {
|
||||
const BlueprintsDB = new PouchDB("blueprints")
|
||||
const currentBlueprint: {extraFields: I_ExtraFields[]} = await BlueprintsDB.get(document.type)
|
||||
const loadingSetup = {
|
||||
message: "<h4>Saving document...</h4>",
|
||||
spinnerColor: "primary",
|
||||
messageColor: "cultured",
|
||||
spinnerSize: 120,
|
||||
backgroundColor: "dark",
|
||||
// @ts-ignore
|
||||
spinner: QSpinnerGears
|
||||
}
|
||||
|
||||
// Time for cases when people want to auto-generate A LOT of documents
|
||||
const saveTimeout = setTimeout(() => {
|
||||
// @ts-ignore
|
||||
Loading.show(loadingSetup)
|
||||
}, 750)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
const currentBlueprint: {extraFields: I_ExtraFields[]} = vueInstance.SGET_blueprint(document.type)
|
||||
window.FA_dbs[document.type] = new PouchDB(document.type)
|
||||
const CurrentObjectDB = window.FA_dbs[document.type]
|
||||
|
||||
|
@ -38,17 +55,100 @@ export const saveDocument = async (
|
|||
|
||||
allOpenedDocuments = allOpenedDocuments.filter(doc => doc._id !== document._id)
|
||||
|
||||
// Handle relationship fields
|
||||
// Handle single document autogeneration
|
||||
const single_relationshipTypesAutoGeneration = ["singleToNoneRelationship", "singleToSingleRelationship", "singleToManyRelationship"]
|
||||
const single_allRelationshipFieldsAutoGeneration = documentCopy.extraFields.filter(field => {
|
||||
const currentField = currentBlueprint.extraFields.find(e => e.id === field.id) as unknown as I_ExtraFields
|
||||
return (currentField && single_relationshipTypesAutoGeneration.includes(currentField.type))
|
||||
})
|
||||
|
||||
// Update single fields autogeneration
|
||||
for (const field of single_allRelationshipFieldsAutoGeneration) {
|
||||
const fieldValue = field.value?.value
|
||||
|
||||
if (fieldValue?.isAutoGenerated) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
const pairedBlueprint: I_Blueprint = vueInstance.SGET_blueprint(fieldValue.type)
|
||||
|
||||
const newDocument = {
|
||||
bgColor: undefined,
|
||||
color: undefined,
|
||||
extraFields: [
|
||||
|
||||
{
|
||||
id: "name",
|
||||
value: fieldValue.label
|
||||
},
|
||||
{
|
||||
id: "parentDoc",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentBackgroundColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "finishedSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "minorSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "deadSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "categorySwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "order",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "tags",
|
||||
value: []
|
||||
},
|
||||
{
|
||||
id: "categoryDescription",
|
||||
value: ""
|
||||
}
|
||||
],
|
||||
hierarchicalPath: pairedBlueprint.namePlural,
|
||||
icon: pairedBlueprint.icon,
|
||||
id: fieldValue.id,
|
||||
type: fieldValue.type,
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
url: `/project/display-content/${fieldValue.type}/${fieldValue.id}`,
|
||||
_id: fieldValue.id
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
window.FA_dbs[newDocument.type] = new PouchDB(newDocument.type)
|
||||
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
await window.FA_dbs[newDocument.type].put(newDocument)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
vueInstance.SSET_addDocument({ doc: vueInstance.mapShortDocument(newDocument, vueInstance.SGET_allDocumentsByType(newDocument.type).docs) })
|
||||
|
||||
delete (fieldValue.isAutoGenerated)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle relationship single fields
|
||||
const single_relationshipTypes = ["singleToSingleRelationship", "singleToManyRelationship"]
|
||||
const single_allRelationshipFields = documentCopy.extraFields.filter(field => {
|
||||
const currentField = currentBlueprint.extraFields.find(e => e.id === field.id) as unknown as I_ExtraFields
|
||||
return (currentField && single_relationshipTypes.includes(currentField.type))
|
||||
})
|
||||
const many_relationshipTypes = ["manyToSingleRelationship", "manyToManyRelationship"]
|
||||
const many_allRelationshipFields = documentCopy.extraFields.filter(field => {
|
||||
const currentField = currentBlueprint.extraFields.find(e => e.id === field.id) as unknown as I_ExtraFields
|
||||
return (currentField && many_relationshipTypes.includes(currentField.type))
|
||||
})
|
||||
|
||||
// Update single fields
|
||||
for (const field of single_allRelationshipFields) {
|
||||
|
@ -93,6 +193,105 @@ export const saveDocument = async (
|
|||
})
|
||||
}
|
||||
|
||||
// Handle relationship many fields
|
||||
const many_relationshipTypes = ["manyToSingleRelationship", "manyToManyRelationship"]
|
||||
const many_allRelationshipFields = documentCopy.extraFields.filter(field => {
|
||||
const currentField = currentBlueprint.extraFields.find(e => e.id === field.id) as unknown as I_ExtraFields
|
||||
return (currentField && many_relationshipTypes.includes(currentField.type))
|
||||
})
|
||||
|
||||
// Handle many document autogeneration
|
||||
const many_relationshipTypesAutoGeneration = ["manyToNoneRelationship", "manyToSingleRelationship", "manyToManyRelationship"]
|
||||
const many_allRelationshipFieldsAutoGeneration = documentCopy.extraFields.filter(field => {
|
||||
const currentField = currentBlueprint.extraFields.find(e => e.id === field.id) as unknown as I_ExtraFields
|
||||
return (currentField && many_relationshipTypesAutoGeneration.includes(currentField.type))
|
||||
})
|
||||
|
||||
// Update many fields autogeneration
|
||||
for (const field of many_allRelationshipFieldsAutoGeneration) {
|
||||
const fieldArray = field.value?.value
|
||||
|
||||
if (Array.isArray(fieldArray)) {
|
||||
for (const fieldValue of fieldArray) {
|
||||
if (fieldValue?.isAutoGenerated) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
const pairedBlueprint: I_Blueprint = vueInstance.SGET_blueprint(fieldValue.type)
|
||||
|
||||
const newDocument = {
|
||||
bgColor: undefined,
|
||||
color: undefined,
|
||||
extraFields: [
|
||||
|
||||
{
|
||||
id: "name",
|
||||
value: fieldValue.label
|
||||
},
|
||||
{
|
||||
id: "parentDoc",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "documentBackgroundColor",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "finishedSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "minorSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "deadSwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "categorySwitch",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "order",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
id: "tags",
|
||||
value: []
|
||||
},
|
||||
{
|
||||
id: "categoryDescription",
|
||||
value: ""
|
||||
}
|
||||
],
|
||||
hierarchicalPath: pairedBlueprint.namePlural,
|
||||
icon: pairedBlueprint.icon,
|
||||
id: fieldValue.id,
|
||||
type: fieldValue.type,
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
url: `/project/display-content/${fieldValue.type}/${fieldValue.id}`,
|
||||
_id: fieldValue.id
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
window.FA_dbs[newDocument.type] = new PouchDB(newDocument.type)
|
||||
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
await window.FA_dbs[newDocument.type].put(newDocument)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
vueInstance.SSET_addDocument({ doc: vueInstance.mapShortDocument(newDocument, vueInstance.SGET_allDocumentsByType(newDocument.type).docs) })
|
||||
|
||||
delete (fieldValue.isAutoGenerated)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update many fields
|
||||
for (const field of many_allRelationshipFields) {
|
||||
const many_updatedDocuments: I_OpenedDocument[] = await many_changeRelationshipToAnotherObject(field, documentCopy, currentDocument)
|
||||
|
@ -151,6 +350,9 @@ export const saveDocument = async (
|
|||
// Set edit mode for frontend
|
||||
documentCopy.editMode = editModeAfterSave
|
||||
|
||||
clearTimeout(saveTimeout)
|
||||
Loading.hide()
|
||||
|
||||
return { documentCopy, allOpenedDocuments }
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ export const single_changeRelationshipToAnotherObject = async (
|
|||
|
||||
if (previousValue && typeof currentValue !== "string" && currentValue) {
|
||||
if (fieldType === "singleToSingleRelationship") {
|
||||
updatedDocuments.push(await single_removeRelationshipFromAnotherObject(previousValue))
|
||||
updatedDocuments.push(await single_removeRelationshipFromAnotherObject(currentValue, previousValue))
|
||||
updatedDocuments.push(await single_addRelationshipToAnotherObject(field, currentValue, currentDocument))
|
||||
}
|
||||
if (fieldType === "singleToManyRelationship") {
|
||||
|
@ -43,7 +43,7 @@ export const single_changeRelationshipToAnotherObject = async (
|
|||
|
||||
if ((previousValue && typeof currentValue === "string") || (previousValue && !currentValue)) {
|
||||
if (fieldType === "singleToSingleRelationship") {
|
||||
updatedDocuments.push(await single_removeRelationshipFromAnotherObject(previousValue))
|
||||
updatedDocuments.push(await single_removeRelationshipFromAnotherObject(currentValue, previousValue))
|
||||
}
|
||||
if (fieldType === "singleToManyRelationship") {
|
||||
const removedValued = await many_removeRelationshipFromAnotherObject(previousValue, currentDocument)
|
||||
|
@ -102,6 +102,7 @@ export const single_addRelationshipToAnotherObject = async (
|
|||
}
|
||||
|
||||
export const single_removeRelationshipFromAnotherObject = async (
|
||||
currentValue: I_FieldRelationship,
|
||||
previousValue: I_FieldRelationship
|
||||
) => {
|
||||
const typeToFind = previousValue.type
|
||||
|
@ -113,7 +114,9 @@ export const single_removeRelationshipFromAnotherObject = async (
|
|||
const pairedField = previousValue.pairedField
|
||||
const pairedFieldIndex = pairedDocument.extraFields.findIndex(e => e.id === pairedField)
|
||||
|
||||
pairedDocument.extraFields[pairedFieldIndex].value = { value: "", addedValues: "" }
|
||||
if (currentValue?._id !== previousValue?._id) {
|
||||
pairedDocument.extraFields[pairedFieldIndex].value = { value: "", addedValues: "" }
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
await window.FA_dbs[typeToFind].put(pairedDocument)
|
||||
|
@ -157,7 +160,8 @@ export const many_changeRelationshipToAnotherObject = async (
|
|||
}
|
||||
|
||||
if (fieldType === "manyToSingleRelationship") {
|
||||
const removedValued = await single_removeRelationshipFromAnotherObject(removedValue)
|
||||
// @ts-ignore
|
||||
const removedValued = await single_removeRelationshipFromAnotherObject(removedValue, {})
|
||||
if (removedValued) {
|
||||
updatedDocuments.push(removedValued)
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@ export const advancedDocumentFilter = (inputString: string, currentDocumentList:
|
|||
|
||||
// @ts-ignore
|
||||
const matchingDocument = allDocuments.find(doc => doc.id === valueToMap._id)
|
||||
|
||||
if (matchingDocument) {
|
||||
// @ts-ignore
|
||||
returnValue = matchingDocument.extraFields.find(e => e.id === "name")?.value as string
|
||||
|
@ -162,7 +163,7 @@ export const advancedDocumentFilter = (inputString: string, currentDocumentList:
|
|||
}
|
||||
|
||||
// Fix all missing values that slipped through
|
||||
if (!returnValue || returnValue.value === null) {
|
||||
if (typeof returnValue !== "string") {
|
||||
returnValue = ""
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ export interface OptionsStateInteface {
|
|||
_id: string,
|
||||
_rev?: string,
|
||||
darkMode: boolean
|
||||
preventFilledNoteBoardPopup: boolean
|
||||
preventAutoScroll: boolean
|
||||
hideAdvSearchCheatsheetButton: boolean
|
||||
textShadow: boolean
|
||||
|
@ -43,6 +44,7 @@ function state (): OptionsStateInteface {
|
|||
return {
|
||||
_id: "settings",
|
||||
darkMode: false,
|
||||
preventFilledNoteBoardPopup: false,
|
||||
preventAutoScroll: false,
|
||||
hideAdvSearchCheatsheetButton: false,
|
||||
textShadow: false,
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
|
||||
- **Add isAutoGenerated setter for document saving to prvent future conflicts**
|
||||
|
||||
- **Fix notes not saving in single-to-single relationships**
|
||||
|
||||
## THE GM BATCH
|
||||
|
||||
- Add on-the-fly generation of non-existent 2-way relationships
|
||||
- Add hover/on-demand document preview to relationships
|
||||
|
||||
- Export for MD/PDF/ODT/DOCX
|
||||
|
@ -15,8 +18,8 @@
|
|||
- Add option for project graph to filter out categories or show them separately
|
||||
- Add HTML webcolor cheatsheet in floating window (look for JSON of them somewhere?)
|
||||
- Word count for editor fields
|
||||
- Add "Open app folder" to help menu
|
||||
- Try to get field titles to show in full-screen edit of text editor fields
|
||||
- List of last saved documents on project overview
|
||||
|
||||
- Consider adding some kind of "Follower name" to different group types
|
||||
- Consider reworking the save document mechanic (save doesnt close, open/exit edit mode instead)
|
||||
|
|
Loading…
Reference in a new issue