big dialog overhaul + async nextticks

This commit is contained in:
Elvanos 2021-03-04 01:27:07 +01:00
parent d9a68cf0cf
commit 78ac7531d1
35 changed files with 1011 additions and 472 deletions

View file

@ -2,12 +2,20 @@
## 0.1.3
TODO
move doc buttons to the top bar
add delete document dialog to dialog system
### Bugfixes
- Fixed the "Name" field disappearing upon full deletion of text
- Fixed a bug with single/multi select fields working unintuitively for adding new values (eg: Character personality traits field or Sex field)
### New features
- Added a safeguard dialog for new project creation in case an opened project exists
- Added a safeguard dialog for project importing in case an opened project exists
- New control bar added for documents and project control
- A new logo added to the app (better visibility of the logo in small scales and icons)
- Massive overhaul of the search engine used by the Quick opening existing document and single/multi relationship fields (now supports tags, categories, document types, inteligent filtering and inteligent sorting via importance of the found values)
- Added color support to single/multi relationship fields
@ -18,14 +26,18 @@
### QoL adjustments
- Lightly modified the app color-scheme to offer better readability of contrast
- Changed icon for the button triggering quick-adding of new documents
- Changed the looks of tooltips to go well with the current app looks
- Modified selected and active indicators for already selected/active items in dropdown lists in order to not clash with the highlighting from the filter results
- Slightly modified the scrollbar visuals to be less intrusive
- Added a light golden tint to the background of the app to go easy on user's eyes before farkmode is added
- Added a light golden tint to the background of the app to go easy on user's eyes before dark mode is added
- Improved performance by reducing the amount of time the side-tree re-renders
- Visually alligned custom order badge for both nodes with and without children
- Added dark visuals to the single-select and multi-select fields to align with thge rest of the app
- Visually aligned custom order badge for both nodes with and without children
- Added dark visuals to the single-select and multi-select fields to align with the rest of the app
- All popup dialogs have been unified to dark-color mode
- Prettified a dialog popup for confirmation of closing a document with active edits
- Added a small filter over the big white areas to ease-up on the user's eyes before darkmode is added
- Added a small filter over the big white areas to ease-up on the user's eyes before dark mode is added
## 0.1.2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View file

@ -291,4 +291,8 @@ export default class BaseClass extends Vue {
// @ts-ignore
return (document.activeTypeSearch) ? colors.getBrand("primary") : document.color
}
sleep (ms:number) {
return new Promise(resolve => setTimeout(resolve, ms))
}
}

View file

@ -0,0 +1,205 @@
<template>
<div>
<!-- New document dialog -->
<newDocumentDialog
:dialog-trigger="newObjectDialogTrigger"
@trigger-dialog-close="newObjectDialogClose"
/>
<!-- Existing document dialog -->
<existingDocumentDialog
:dialog-trigger="existingObjectDialogTrigger"
@trigger-dialog-close="existingObjectDialogClose"
/>
<q-page-sticky position="top-right" class="documentControl">
<div class="documentControl__blocker"></div>
<div class="documentControl__wrapper">
<div class="documentControl__left">
<q-btn
icon="mdi-package-variant-closed"
color="primary"
outline
:disable="!projectExists"
@click="commenceExport"
>
<q-tooltip>
Export current project
</q-tooltip>
</q-btn>
<q-separator vertical inset color="accent" />
<q-btn
icon="mdi-database-search"
color="primary"
outline
@click="existingObjectAssignUID"
>
<q-tooltip>
Quick-search an existing document
</q-tooltip>
</q-btn>
<q-btn
icon="mdi-text-box-plus-outline"
color="primary"
outline
@click="newObjectAssignUID"
>
<q-tooltip>
Quick-add a new document
</q-tooltip>
</q-btn>
</div>
<div class="documentControl__right">
</div>
</div>
</q-page-sticky>
</div>
</template>
<script lang="ts">
import { Component, Watch } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import newDocumentDialog from "src/components/dialogs/NewDocument.vue"
import existingDocumentDialog from "src/components/dialogs/ExistingDocument.vue"
import { retrieveCurrentProjectName, exportProject } from "src/scripts/projectManagement/projectManagent"
@Component({
components: {
newDocumentDialog,
existingDocumentDialog
}
})
export default class DocumentControl extends BaseClass {
projectExists: undefined | string | boolean = false
projectName = ""
async created () {
this.projectName = await retrieveCurrentProjectName()
this.projectExists = !!(await retrieveCurrentProjectName())
}
/****************************************************************/
// Keybinds management
/****************************************************************/
/**
* Local keybinds
*/
@Watch("SGET_getCurrentKeyBindData", { deep: true })
processKeyPush () {
// Quick new document
if (this.determineKeyBind("quickNewDocument")) {
this.newObjectAssignUID()
}
// Quick open existing document
if (this.determineKeyBind("quickExistingDocument")) {
this.existingObjectAssignUID()
}
}
/****************************************************************/
// New document dialog
/****************************************************************/
newObjectDialogTrigger: string | false = false
newObjectDialogClose () {
this.newObjectDialogTrigger = false
}
newObjectAssignUID () {
this.newObjectDialogTrigger = this.generateUID()
}
/****************************************************************/
// Existing document dialog
/****************************************************************/
existingObjectDialogTrigger: string | false = false
existingObjectDialogClose () {
this.existingObjectDialogTrigger = false
}
existingObjectAssignUID () {
this.existingObjectDialogTrigger = this.generateUID()
}
/****************************************************************/
// Export project
/****************************************************************/
retrieveCurrentProjectName = retrieveCurrentProjectName
exportProject = exportProject
async commenceExport () {
const projectName = await retrieveCurrentProjectName()
this.exportProject(projectName)
}
}
</script>
<style lang="scss">
.documentControl {
z-index: 999;
background-color: $dark;
width: calc(100vw - 375px);
margin-top: 2.5px;
&__blocker {
position: absolute;
top: -7.5px;
left: 0;
right: 0;
background-color: darken($dark, 0.5);
z-index: 999;
height: 7.5px;
}
&__wrapper {
width: calc(100vw - 375px);
padding: 10px 15px;
display: flex;
justify-content: space-between;
}
&__left,
&__right {
display: flex;
}
&__left {
justify-content: flex-start;
.q-btn,
.q-separator {
margin-right: 10px;
}
}
&__right {
justify-content: flex-end;
.q-btn,
.q-separator {
margin-left: 10px;
}
}
}
</style>

View file

@ -1,7 +1,7 @@
<template>
<span>
<q-input ref="treeFilter" dark filled v-model="treeFilter" label="Search...">
<q-input ref="treeFilter" dark filled v-model="treeFilter" label="Filter document tree...">
<template v-slot:prepend>
<q-icon name="mdi-text-search" />
</template>
@ -170,11 +170,11 @@ export default class ObjectTree extends BaseClass {
await this.processBluePrints()
// Unfuck the rendering by giving the app some time to load first
setTimeout(() => {
this.buildCurrentObjectTree().catch((e) => {
console.log(e)
})
}, 500)
await this.$nextTick()
this.buildCurrentObjectTree().catch((e) => {
console.log(e)
})
}
/****************************************************************/

View file

@ -3,12 +3,31 @@
<div
:class="{'AppControl': isProject}"
>
<!-- Project close dialog -->
<projectCloseCheckDialog
:dialog-trigger="projectCloseCheckDialogTrigger"
:dialog-mode="'projectClose'"
@trigger-dialog-close="projectCloseCheckDialogClose"
/>
<!-- Keybind dialog -->
<keybindCheatsheetDialog
:dialog-trigger="keybindsDialogTrigger"
@trigger-dialog-close="keybindsDialogClose"
/>
<!-- Import project dialog -->
<importProjectCheckDialog
:dialog-trigger="importProjectDialogTrigger"
@trigger-dialog-close="importProjectDialogClose"
/>
<!-- New project dialog -->
<newProjectCheckDialog
:dialog-trigger="newProjectDialogTrigger"
@trigger-dialog-close="newProjectDialogClose"
/>
<q-btn-group
flat
class="AppControl__buttons"
@ -41,28 +60,19 @@
anchor="bottom left"
class="bg-gunmetal-light"
dark
square
>
<q-list class="bg-gunmetal-light" dark>
<q-item
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
@click="navigateToProjectPage"
:disable="!projectExists || isProjectPage"
>
<q-item-section>Go to project screen</q-item-section>
</q-item>
<q-item
<q-item
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
@click="exportProject(projectName)"
:disable="!projectExists"
class="noHigh"
@click="newProjectAssignUID"
>
<q-item-section>Export project</q-item-section>
<q-item-section>New project</q-item-section>
</q-item>
<q-separator dark />
@ -72,6 +82,44 @@
clickable
active
active-class="bg-gunmetal-light text-cultured"
class="noHigh"
@click="exportProject(projectName)"
:disable="!projectExists"
>
<q-item-section>Export current project</q-item-section>
</q-item>
<q-item
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
class="noHigh"
@click="importProjectAssignUID"
>
<q-item-section>Import existing project</q-item-section>
</q-item>
<q-separator dark />
<q-item
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
class="noHigh"
@click="navigateToProjectPage"
:disable="!projectExists || isProjectPage"
>
<q-item-section>Resume project</q-item-section>
</q-item>
<q-item
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
class="noHigh"
@click="projectCloseCheckDialogAssignUID"
:disable="!projectExists || isFrontpage"
>
@ -90,18 +138,37 @@
no-caps
>
Help
<q-menu anchor="bottom left" class="bg-gunmetal-light" dark>
<q-menu
anchor="bottom left"
class="bg-gunmetal-light"
dark
square
>
<q-list class="bg-gunmetal-light" dark>
<q-item
@click="toggleDevTools"
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
>
@click="keybindsDialogAssignUID"
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
class="noHigh"
>
<q-item-section>Show keybind cheatsheet</q-item-section>
</q-item>
<q-separator dark />
<q-item
@click="toggleDevTools"
v-close-popup
clickable
active
active-class="bg-gunmetal-light text-cultured"
class="noHigh"
>
<q-item-section>Toggle developer tools</q-item-section>
</q-item>
</q-list>
</q-menu>
@ -114,16 +181,24 @@
<script lang="ts">
import { Component, Prop } from "vue-property-decorator"
import { Component, Prop, Watch } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import projectCloseCheckDialog from "src/components/dialogs/ProjectCloseCheck.vue"
import keybindCheatsheetDialog from "src/components/dialogs/KeybindCheatsheet.vue"
import importProjectCheckDialog from "src/components/dialogs/ImportProjectCheck.vue"
import newProjectCheckDialog from "src/components/dialogs/NewProjectCheck.vue"
import { retrieveCurrentProjectName, exportProject } from "src/scripts/projectManagement/projectManagent"
import { toggleDevTools } from "src/scripts/utilities/devTools"
@Component({
components: { projectCloseCheckDialog }
components: {
projectCloseCheckDialog,
keybindCheatsheetDialog,
importProjectCheckDialog,
newProjectCheckDialog
}
})
export default class AppControl extends BaseClass {
@Prop() readonly isProject!: boolean
@ -163,6 +238,48 @@ export default class AppControl extends BaseClass {
}
})
}
importProjectDialogTrigger: string | false = false
importProjectDialogClose () {
this.importProjectDialogTrigger = false
}
importProjectAssignUID () {
this.importProjectDialogTrigger = this.generateUID()
}
newProjectDialogTrigger: string | false = false
newProjectDialogClose () {
this.newProjectDialogTrigger = false
}
newProjectAssignUID () {
this.newProjectDialogTrigger = this.generateUID()
}
/**
* Local keybinds
*/
@Watch("SGET_getCurrentKeyBindData", { deep: true })
processKeyPush () {
// Keybind cheatsheet
if (this.determineKeyBind("openKeybindsCheatsheet")) {
this.keybindsDialogAssignUID()
}
}
/****************************************************************/
// Keybings cheatsheet dialog
/****************************************************************/
keybindsDialogTrigger: string | false = false
keybindsDialogClose () {
this.keybindsDialogTrigger = false
}
keybindsDialogAssignUID () {
this.keybindsDialogTrigger = this.generateUID()
}
}
</script>

View file

@ -12,12 +12,12 @@
<q-btn
flat
label="Cancel"
color="primary"
color="accent"
v-close-popup />
<q-btn
flat
outline
label="Discard changes"
color="red"
color="secondary"
v-close-popup
@click="closeDocument(dialogDocument)" />
</q-card-actions>
@ -55,16 +55,15 @@ export default class CloseDocumentCheckDialog extends DialogBase {
this.dialogModel = true
}
else {
this.closeDocument(input)
this.closeDocument(input).catch(e => console.log(e))
}
}
closeDocument (input: I_OpenedDocument) {
async closeDocument (input: I_OpenedDocument) {
const dataPass = { doc: input, treeAction: false }
this.SSET_removeOpenedDocument(dataPass)
setTimeout(() => {
this.refreshRoute()
}, 100)
await this.$nextTick()
this.refreshRoute()
}
}
</script>

View file

@ -38,12 +38,12 @@
v-on="itemEvents"
:style="`color: ${opt.color}`"
>
<q-item-section avatar>
<q-icon
:style="`color: ${retrieveIconColor(opt)}`"
:name="(opt.isCategory) ? 'fas fa-folder-open' : opt.icon"
/>
</q-item-section>
<q-item-section avatar>
<q-icon
:style="`color: ${retrieveIconColor(opt)}`"
:name="(opt.isCategory) ? 'fas fa-folder-open' : opt.icon"
/>
</q-item-section>
<q-item-section>
<q-item-label v-html="opt.label" ></q-item-label>
<q-item-label caption class="text-cultured" v-html="opt.hierarchicalPath"></q-item-label>
@ -53,7 +53,7 @@
outline
style="opacity: 0.8;"
size="12px"
class="bg-dark text-cultured"
class="text-cultured"
v-html="`${input}`"
>
</q-chip>
@ -83,8 +83,8 @@
</q-card-section>
<q-card-section>
<q-card-actions align="center" class="q-mb-sm">
<q-btn flat label="Close window" color="primary" v-close-popup />
<q-card-actions align="around" class="q-mb-sm">
<q-btn flat label="Close" color="accent" v-close-popup />
</q-card-actions>
</q-card-section>
@ -151,35 +151,37 @@ export default class ExistingDocumentDialog extends DialogBase {
this.existingObjectsBackupList = allDocs
this.filterDocuments()
this.$nextTick(function () {
/*eslint-disable */
setTimeout( () =>{
if(this.$refs.ref_existingDocument){
// @ts-ignore
this.$refs.ref_existingDocument.focus()
}
}, 300)
/* eslint-enable */
})
await this.$nextTick()
await this.sleep(200)
if (this.$refs.ref_existingDocument) {
/*eslint-disable */
// @ts-ignore
this.$refs.ref_existingDocument.focus()
/* eslint-enable */
}
}
existingDocumentModel = null
filteredExistingInput = null as unknown as I_ShortenedDocument[]
async refocusSelect () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs.ref_existingDocument.setOptionIndex(-1)
// @ts-ignore
this.$refs.ref_existingDocument.moveOptionSelection(1, true)
/* eslint-enable */
}
filterExistingSelect (val: string, update: (e: () => void) => void) {
if (val === "") {
update(() => {
this.filteredExistingInput = this.existingObjectList
/*eslint-disable */
if(this.$refs.ref_existingDocument && this.filteredExistingInput.length > 0){
setTimeout(() => {
// @ts-ignore
this.$refs.ref_existingDocument.setOptionIndex(-1)
// @ts-ignore
this.$refs.ref_existingDocument.moveOptionSelection(1, true)
}, 300)
/* eslint-enable */
if (this.$refs.ref_existingDocument && this.filteredExistingInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
})
return
@ -188,19 +190,10 @@ export default class ExistingDocumentDialog extends DialogBase {
update(() => {
const needle = val.toLowerCase()
const listCopy : I_ShortenedDocument[] = extend(true, [], this.existingObjectList)
setTimeout(() => {
this.filteredExistingInput = advancedDocumentFilter(needle, listCopy)
}, 100)
this.filteredExistingInput = advancedDocumentFilter(needle, listCopy)
/*eslint-disable */
if(this.$refs.ref_existingDocument && this.filteredExistingInput.length > 0){
setTimeout(() => {
// @ts-ignore
this.$refs.ref_existingDocument.setOptionIndex(-1)
// @ts-ignore
this.$refs.ref_existingDocument.moveOptionSelection(1, true)
}, 100)
/* eslint-enable */
if (this.$refs.ref_existingDocument && this.filteredExistingInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
})
}

View file

@ -0,0 +1,91 @@
<template>
<q-dialog
v-model="dialogModel"
@hide="triggerDialogClose"
>
<q-card dark class="documentCloseDialog">
<q-card-section class="row justify-center">
<h6 class="text-center q-my-sm">Import existing project</h6>
</q-card-section>
<q-card-section class="row justify-center q-mx-xl">
<div>
Please note that the imported project will <span class="text-bold text-secondary">COMPLETELY OVERWRITE</span> the currently opened project.
<br>
If you haven't done so already, please export your current project first to prevent a <span class="text-bold text-secondary">FULL LOSS</span> of all your current project data!
</div>
</q-card-section>
<q-card-actions align="around" class="q-mx-xl q-mt-lg q-mb-md">
<q-btn
flat
label="Cancel"
color="accent"
v-close-popup />
<q-btn
flat
label="Export project"
color="primary"
@click="commenceExport"
/>
<q-btn
flat
label="Import project"
color="primary"
v-close-popup
@click="importProject()" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script lang="ts">
import { Component, Watch } from "vue-property-decorator"
import DialogBase from "src/components/dialogs/_DialogBase"
import { retrieveCurrentProjectName, exportProject, importExistingProject } from "src/scripts/projectManagement/projectManagent"
@Component({
components: { }
})
export default class ImportProjectCheckDialog extends DialogBase {
@Watch("dialogTrigger")
async openDialog (val: string|false) {
if (val) {
const projectName = await retrieveCurrentProjectName()
if (projectName) {
this.checkForCloseOpenedDocument()
}
else {
this.importProject()
}
}
}
checkForCloseOpenedDocument () {
if (this.SGET_getDialogsState) {
return
}
this.SSET_setDialogState(true)
this.dialogModel = true
}
importProject () {
importExistingProject(this.$router)
}
async commenceExport () {
const projectName = await retrieveCurrentProjectName()
exportProject(projectName)
}
}
</script>
<style lang="scss" scoped>
.documentCloseDialog {
min-width: 600px;
}
</style>

View file

@ -6,30 +6,34 @@
>
<q-card
class="keyBindsDialog"
dark
>
<q-card-section class="row items-center">
<h6 class="text-center q-my-sm">Keybind list</h6>
</q-card-section>
<q-card-section>
<q-markup-table>
<thead>
<tr>
<th class="text-left">Action</th>
<th class="text-left">Keybind</th>
</tr>
</thead>
<tbody>
<tr v-for="keybind in SGET_getCurrentKeyBindData.defaults" :key="keybind.id">
<td class="text-left" v-html="keybind.tooltip"/>
<td class="text-left" v-html="retrieveKeybindString(keybind)"/>
</tr>
</tbody>
</q-markup-table>
</q-card-section>
<q-markup-table
dark
flat
>
<thead>
<tr>
<th class="text-left">Action</th>
<th class="text-left">Keybind</th>
</tr>
</thead>
<tbody>
<tr v-for="keybind in SGET_getCurrentKeyBindData.defaults" :key="keybind.id">
<td class="text-left" v-html="keybind.tooltip"/>
<td class="text-left" v-html="retrieveKeybindString(keybind)"/>
</tr>
</tbody>
</q-markup-table>
</q-card-section>
<q-card-actions align="center" class="q-mb-lg q-mt-md">
<q-btn flat label="Close window" color="primary" v-close-popup />
<q-card-actions align="around" class="q-mb-lg q-mt-md">
<q-btn flat label="Close" color="accent" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
@ -58,5 +62,27 @@ export default class KeybindCheatsheet extends DialogBase {
}
</script>
<style lang="scss" scoped>
<style lang="scss">
.keyBindsDialog {
width: 100%;
max-width: 1000px !important;
h6 {
display: block;
text-align: center;
width: 100%;
}
table {
td {
max-width: 300px;
white-space: inherit;
}
}
.keybindNote {
opacity: 0.8;
font-size: 0.9em;
}
}
</style>

View file

@ -46,8 +46,8 @@
</q-card-section>
<q-card-section>
<q-card-actions align="center" class="q-mb-sm">
<q-btn flat label="Close window" color="primary" v-close-popup />
<q-card-actions align="around" class="q-mb-sm">
<q-btn flat label="Close" color="accent" v-close-popup />
</q-card-actions>
</q-card-section>
@ -78,7 +78,7 @@ export default class NewDocumentDialog extends DialogBase {
}
this.SSET_setDialogState(true)
this.dialogModel = true
this.populateNewObjectDialog()
this.populateNewObjectDialog().catch(e => console.log(e))
}
}
@ -86,7 +86,7 @@ export default class NewDocumentDialog extends DialogBase {
newDocumentModel = null
populateNewObjectDialog () {
async populateNewObjectDialog () {
// @ts-ignore
this.newObjectList = this.SGET_allBlueprints.map(blueprint => {
return {
@ -98,31 +98,32 @@ export default class NewDocumentDialog extends DialogBase {
}
})
this.$nextTick(function () {
/*eslint-disable */
setTimeout( () =>{
// @ts-ignore
this.$refs.ref_newDocument.focus()
}, 300)
/* eslint-enable */
})
await this.$nextTick()
await this.sleep(300)
/*eslint-disable */
// @ts-ignore
this.$refs.ref_newDocument.focus()
/* eslint-enable */
}
filteredNewInput = null as unknown as NewObjectDocument[]
async refocusSelect () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs.ref_newDocument.setOptionIndex(-1)
// @ts-ignore
this.$refs.ref_newDocument.moveOptionSelection(1, true)
/* eslint-enable */
}
filterNewSelect (val: string, update: (e: () => void) => void) {
if (val === "") {
update(() => {
this.filteredNewInput = this.newObjectList
/*eslint-disable */
if(this.$refs.ref_newDocument && this.filteredNewInput.length > 0){
setTimeout(() => {
// @ts-ignore
this.$refs.ref_newDocument.setOptionIndex(-1)
// @ts-ignore
this.$refs.ref_newDocument.moveOptionSelection(1, true)
}, 300)
/* eslint-enable */
if (this.$refs.ref_newDocument && this.filteredNewInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
})
return
@ -131,16 +132,9 @@ export default class NewDocumentDialog extends DialogBase {
update(() => {
const needle = val.toLowerCase()
this.filteredNewInput = this.newObjectList.filter(v => v.label.toLowerCase().indexOf(needle) > -1)
/*eslint-disable */
if(this.$refs.ref_newDocument && this.filteredNewInput.length > 0){
setTimeout(() => {
// @ts-ignore
this.$refs.ref_newDocument.setOptionIndex(-1)
// @ts-ignore
this.$refs.ref_newDocument.moveOptionSelection(1, true)
}, 300)
if (this.$refs.ref_newDocument && this.filteredNewInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
/* eslint-enable */
})
}

View file

@ -0,0 +1,107 @@
<template>
<q-dialog
v-model="dialogModel"
@hide="triggerDialogClose"
>
<q-card dark class="newProjectCheckDialog">
<q-card-section class="row justify-center">
<h6 class="text-center q-my-sm">New project</h6>
</q-card-section>
<q-card-section class="row justify-center q-mx-xl" v-if="projectExists">
<div>
Please note that the new project will <span class="text-bold text-secondary">COMPLETELY OVERWRITE</span> the currently opened project.
<br>
If you haven't done so already, please export your current project first to prevent a <span class="text-bold text-secondary">FULL LOSS</span> of all your current project data!
</div>
</q-card-section>
<q-card-section>
<div class="row justify-center">
<q-input
filled
dark
ref="newProjectInput"
style="width: 400px;"
label="New project name"
v-model="newProjectName"
/>
</div>
</q-card-section>
<q-card-actions align="around" class="q-mx-xl q-mt-lg q-mb-md">
<q-btn
flat
label="Cancel"
color="accent"
v-close-popup />
<q-btn
flat
v-if="projectExists"
label="Export project"
color="primary"
@click="commenceExport"
/>
<q-btn
flat
label="Create new project"
:disable="newProjectName.length === 0"
color="primary"
v-close-popup
@click="createNewProject" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script lang="ts">
import { Component, Watch } from "vue-property-decorator"
import DialogBase from "src/components/dialogs/_DialogBase"
import { retrieveCurrentProjectName, exportProject, createNewProject } from "src/scripts/projectManagement/projectManagent"
@Component({
components: { }
})
export default class ImportProjectCheckDialog extends DialogBase {
@Watch("dialogTrigger")
async openDialog (val: string|false) {
if (val) {
if (this.SGET_getDialogsState) {
return
}
this.SSET_setDialogState(true)
this.dialogModel = true
this.newProjectName = ""
this.projectExists = await retrieveCurrentProjectName()
/*eslint-disable */
// @ts-ignore
this.$refs.newProjectInput.focus()
/* eslint-enable */
}
}
projectExists: undefined | string | boolean = false
newProjectName = ""
createNewProject () {
createNewProject(this.newProjectName, this.$router).catch(e => console.log(e))
}
async commenceExport () {
const projectName = await retrieveCurrentProjectName()
exportProject(projectName)
}
}
</script>
<style lang="scss" scoped>
.newProjectCheckDialog {
min-width: 600px;
}
</style>

View file

@ -20,6 +20,7 @@
clickable
v-ripple
active
class="noHigh"
active-class="bg-primary-1 text-primary"
v-close-popup
:to="doc.url">
@ -34,11 +35,15 @@
</q-card-section>
<q-card-actions align="around" class="q-mx-xl q-mt-lg q-mb-md">
<q-btn flat label="Cancel" color="primary" v-close-popup />
<q-btn
flat
label="Cancel"
color="accent"
v-close-popup />
<q-btn
outline
:label="exitLabelText"
color="red"
color="secondary"
v-close-popup
@click="checkModeAction" />
</q-card-actions>

View file

@ -66,7 +66,7 @@
<div style="width: 115px;" class="justify-end flex">
<q-btn
v-if="editMode"
color="red"
color="secondary"
@click="removeFromList(index)"
label="Remove" />
</div>

View file

@ -48,6 +48,7 @@
dark
style="flex-grow: 1;"
dense
:ref="`multieRelationshipField${this.inputDataBluePrint.id}`"
:options="filteredInput"
use-input
outlined
@ -63,11 +64,28 @@
v-bind="itemProps"
v-on="itemEvents"
>
<q-item-section avatar>
<q-icon
:style="`color: ${retrieveIconColor(opt)}`"
:name="(opt.isCategory) ? 'fas fa-folder-open' : opt.icon"
/>
</q-item-section>
<q-item-section>
<q-item-label
:style="`color: ${opt.color}`"
v-html="opt.label" ></q-item-label>
<q-item-label caption class="text-cultured">{{opt.hierarchicalPath}}</q-item-label>
<q-item-label caption class="text-cultured" v-html="opt.hierarchicalPath"></q-item-label>
<q-item-label caption class="text-cultured" v-if="opt.tags">
<q-chip
v-for="(input,index) in opt.tags" :key="index"
outline
style="opacity: 0.8;"
size="12px"
class="text-cultured noBounce"
v-html="`${input}`"
>
</q-chip>
</q-item-label>
</q-item-section>
<q-tooltip v-if='opt.disable'>
This option is unavailable for selection as it is already paired to another.
@ -112,7 +130,8 @@ import { Component, Emit, Prop, Watch } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import PouchDB from "pouchdb"
import { advancedDocumentFilter } from "src/scripts/utilities/advancedDocumentFilter"
import { extend } from "quasar"
import { I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
import { I_ExtraFields } from "src/interfaces/I_Blueprint"
import { I_FieldRelationship, I_RelationshipPair } from "src/interfaces/I_FieldRelationship"
@ -163,17 +182,39 @@ export default class Field_SingleRelationship extends BaseClass {
inputNotes: { pairedId: string; value: string; }[] = []
async refocusSelect () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs[`multiRelationshipField${this.inputDataBluePrint.id}`].setOptionIndex(-1)
// @ts-ignore
this.$refs[`multiRelationshipField${this.inputDataBluePrint.id}`].moveOptionSelection(1, true)
/* eslint-enable */
}
filterSelect (val: string, update: (e: () => void) => void) {
if (val === "") {
update(() => {
this.filteredInput = this.extraInput
if (this.$refs[`multiRelationshipField${this.inputDataBluePrint.id}`] && this.filteredInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
})
return
}
update(() => {
const needle = val.toLowerCase()
this.filteredInput = this.extraInput.filter(v => v.label.toLowerCase().indexOf(needle) > -1)
const listCopy : I_ShortenedDocument[] = extend(true, [], this.extraInput)
// @ts-ignore
this.filteredInput = advancedDocumentFilter(needle, listCopy)
/*eslint-disable */
if(this.$refs[`multiRelationshipField${this.inputDataBluePrint.id}`] && this.filteredInput.length > 0){
this.refocusSelect().catch(e => console.log(e))
}
/* eslint-enable */
})
}
@ -219,6 +260,7 @@ export default class Field_SingleRelationship extends BaseClass {
return {
_id: objectDoc._id,
icon: objectDoc.icon,
value: objectDoc._id,
type: objectDoc.type,
disable: isDisabled,
@ -227,6 +269,7 @@ export default class Field_SingleRelationship extends BaseClass {
isCategory: objectDoc.extraFields.find(e => e.id === "categorySwitch")?.value,
color: objectDoc.extraFields.find(e => e.id === "documentColor")?.value,
pairedField: pairedField,
tags: objectDoc.extraFields.find(e => e.id === "tags")?.value,
// @ts-ignore
hierarchicalPath: this.getDocumentHieararchicalPath(objectDoc, allDbObjects)

View file

@ -28,7 +28,8 @@
style="width: 100%;"
dense
dark
menu-anchor="bottom middle"
:ref="`multiSelectField${this.inputDataBluePrint.id}`"
menu-anchor="bottom middle"
menu-self="top middle"
class="multiSelect"
:options="extraInput"
@ -94,6 +95,14 @@ export default class Field_MultiSelect extends BaseClass {
extraInput: string[] = []
async defocusSelectRef () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs[`multiSelectField${this.inputDataBluePrint.id}`].setOptionIndex(-1)
/* eslint-enable */
}
@Watch("inputDataBluePrint", { deep: true, immediate: true })
populateExtraInput () {
if (this.inputDataBluePrint?.predefinedSelectValues) {
@ -108,6 +117,7 @@ export default class Field_MultiSelect extends BaseClass {
this.extraInput = this.inputDataBluePrint.predefinedSelectValues
}
})
this.defocusSelectRef().catch(e => console.log(e))
return
}
@ -116,6 +126,7 @@ export default class Field_MultiSelect extends BaseClass {
const needle = val.toLowerCase()
this.extraInput = this.inputDataBluePrint.predefinedSelectValues.filter(v => v.toLowerCase().indexOf(needle) > -1)
}
this.defocusSelectRef().catch(e => console.log(e))
})
}

View file

@ -45,6 +45,7 @@
dark
style="flex-grow: 1;"
dense
:ref="`singleRelationshipField${this.inputDataBluePrint.id}`"
:options="filteredInput"
use-input
outlined
@ -58,11 +59,28 @@
v-bind="itemProps"
v-on="itemEvents"
>
<q-item-section avatar>
<q-icon
:style="`color: ${retrieveIconColor(opt)}`"
:name="(opt.isCategory) ? 'fas fa-folder-open' : opt.icon"
/>
</q-item-section>
<q-item-section>
<q-item-label
:style="`color: ${opt.color}`"
v-html="opt.label" ></q-item-label>
<q-item-label caption class="text-cultured">{{opt.hierarchicalPath}}</q-item-label>
<q-item-label caption class="text-cultured" v-html="opt.hierarchicalPath"></q-item-label>
<q-item-label caption class="text-cultured" v-if="opt.tags">
<q-chip
v-for="(input,index) in opt.tags" :key="index"
outline
style="opacity: 0.8;"
size="12px"
class="text-cultured noBounce"
v-html="`${input}`"
>
</q-chip>
</q-item-label>
</q-item-section>
<q-tooltip v-if='opt.disable'>
This option is unavailable for selection as it is already paired to another.
@ -105,6 +123,8 @@ import { Component, Emit, Prop, Watch } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import PouchDB from "pouchdb"
import { advancedDocumentFilter } from "src/scripts/utilities/advancedDocumentFilter"
import { extend } from "quasar"
import { I_ShortenedDocument } from "src/interfaces/I_OpenedDocument"
import { I_ExtraFields } from "src/interfaces/I_Blueprint"
@ -157,17 +177,37 @@ export default class Field_SingleRelationship extends BaseClass {
extraInput: I_FieldRelationship[] = []
filteredInput: I_FieldRelationship[] = []
async refocusSelect () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs[`singleRelationshipField${this.inputDataBluePrint.id}`].setOptionIndex(-1)
// @ts-ignore
this.$refs[`singleRelationshipField${this.inputDataBluePrint.id}`].moveOptionSelection(1, true)
/* eslint-enable */
}
filterSelect (val: string, update: (e: () => void) => void) {
if (val === "") {
update(() => {
this.filteredInput = this.extraInput
if (this.$refs[`singleRelationshipField${this.inputDataBluePrint.id}`] && this.filteredInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
})
return
}
update(() => {
const needle = val.toLowerCase()
this.filteredInput = this.extraInput.filter(v => v.label.toLowerCase().indexOf(needle) > -1)
const listCopy : I_ShortenedDocument[] = extend(true, [], this.extraInput)
// @ts-ignore
this.filteredInput = advancedDocumentFilter(needle, listCopy)
if (this.$refs[`singleRelationshipField${this.inputDataBluePrint.id}`] && this.filteredInput.length > 0) {
this.refocusSelect().catch(e => console.log(e))
}
})
}
@ -216,12 +256,14 @@ export default class Field_SingleRelationship extends BaseClass {
_id: objectDoc._id,
value: objectDoc._id,
type: objectDoc.type,
icon: objectDoc.icon,
disable: isDisabled,
url: `/project/display-content/${objectDoc.type}/${objectDoc._id}`,
label: objectDoc.extraFields.find(e => e.id === "name")?.value,
color: objectDoc.extraFields.find(e => e.id === "documentColor")?.value,
isCategory: objectDoc.extraFields.find(e => e.id === "categorySwitch")?.value,
pairedField: pairedField,
tags: objectDoc.extraFields.find(e => e.id === "tags")?.value,
// @ts-ignore
hierarchicalPath: this.getDocumentHieararchicalPath(objectDoc, allDbObjects)
}

View file

@ -25,7 +25,8 @@
style="width: 100%;"
dense
dark
menu-anchor="bottom middle"
:ref="`singleSelectField${this.inputDataBluePrint.id}`"
menu-anchor="bottom middle"
menu-self="top middle"
class="singleSelect"
:options="extraInput"
@ -85,6 +86,14 @@ export default class Field_SingleSelect extends BaseClass {
extraInput: string[] = []
async defocusSelectRef () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs[`singleSelectField${this.inputDataBluePrint.id}`].setOptionIndex(-1)
/* eslint-enable */
}
@Watch("inputDataBluePrint", { deep: true, immediate: true })
populateExtraInput () {
if (this.inputDataBluePrint?.predefinedSelectValues) {
@ -99,6 +108,7 @@ export default class Field_SingleSelect extends BaseClass {
this.extraInput = this.inputDataBluePrint.predefinedSelectValues
}
})
this.defocusSelectRef().catch(e => console.log(e))
return
}
@ -107,6 +117,7 @@ export default class Field_SingleSelect extends BaseClass {
const needle = val.toLowerCase()
this.extraInput = this.inputDataBluePrint.predefinedSelectValues.filter(v => v.toLowerCase().indexOf(needle) > -1)
}
this.defocusSelectRef().catch(e => console.log(e))
})
}

View file

@ -25,6 +25,7 @@
style="width: 100%;"
dense
dark
:ref="`tagField${this.inputDataBluePrint.id}`"
menu-anchor="bottom middle"
menu-self="top middle"
class="tagSelect"
@ -96,12 +97,21 @@ export default class Field_Tags extends BaseClass {
allTags: string[] = []
async defocusSelectRef () {
await this.$nextTick()
/*eslint-disable */
// @ts-ignore
this.$refs[`tagField${this.inputDataBluePrint.id}`].setOptionIndex(-1)
/* eslint-enable */
}
filterFn (val: string, update: (fn: any) => void) {
if (val === "") {
update(() => {
if (this.inputDataBluePrint?.predefinedSelectValues) {
this.allTags = this.inputDataBluePrint.predefinedSelectValues
}
this.defocusSelectRef().catch(e => console.log(e))
})
return
}
@ -111,6 +121,7 @@ export default class Field_Tags extends BaseClass {
const needle = val.toLowerCase()
this.allTags = this.inputDataBluePrint.predefinedSelectValues.filter(v => v.toLowerCase().indexOf(needle) > -1)
}
this.defocusSelectRef().catch(e => console.log(e))
})
}

View file

@ -32,6 +32,7 @@ html {
body {
background-color: rgba($primary, 0.025);
overflow-y: scroll;
/* WebKit/Blink Browsers */
::selection {
@ -50,10 +51,6 @@ body {
user-select: none !important;
}
.q-tooltip {
font-size: 11px;
}
.q-toggle__inner {
width: 100%;
}
@ -98,3 +95,52 @@ body {
.text-underline {
text-decoration: underline;
}
.q-chip--outline {
border-style: outset !important;
}
.q-focus-helper {
background-color: map-get($customColors, 'gunmetal-bright') !important;
}
.q-chip.noBounce {
padding-bottom: 6px;
padding-left: 11px;
padding-right: 11px;
padding-top: 6px;
}
body .q-item--active:not(.noHigh) {
color: inherit;
&::after {
content: "";
background-color: #d7ac47;
left: 5px;
width: 3px;
top: 10px;
border-radius: 3px;
position: absolute;
bottom: 10px;
}
&::before {
content: "";
background-color: #d7ac47;
right: 5px;
width: 3px;
top: 10px;
border-radius: 3px;
position: absolute;
bottom: 10px;
}
}
body .q-tooltip {
background-color: $accent;
color: $dark;
font-size: 13px;
font-weight: 600;
max-width: 800px;
}

View file

@ -12,11 +12,11 @@
// to match your app's branding.
// Tip: Use the "Theme Builder" on Quasar's documentation website.
$primary : #d2a334;
$secondary : #a4031f;
$primary : #d7ac47;
$secondary : #e3173a;
$accent : #dde4e4;
$dark : #19323c;
$dark : #18303a;
$positive : #21ba45;
$negative : #c10015;
@ -24,10 +24,12 @@ $info : #31ccec;
$warning : #f2c037;
$customColors: (
'gunmetal': #19323c,
'gunmetal-light': lighten(#19323c, 7.5),
'ruby-red': #a4031f,
'satin-sheen-gold': #d2a334,
'gunmetal': #18303a,
'gunmetal-light': lighten(#18303a, 7.5),
'gunmetal-bright': lighten(#18303a, 30),
'gunmetal-shine': lighten(#18303a, 60),
'ruby-red': #e3173a,
'satin-sheen-gold': #d7ac47,
'gainsboro': #dde4e4,
'cultured': #f5f5f5
);

View file

@ -0,0 +1,70 @@
<template>
<q-layout view="hHh LpR lfr">
<!-- Left drawer -->
<q-drawer
content-class="bg-dark text-cultured sideWrapper"
v-model="leftDrawerOpen"
side="left"
:width=375
show-if-above
>
<objectTree/>
</q-drawer>
<!-- Header -->
<appHeader
:is-project="true"
/>
<q-page-container>
<documentControl/>
<transition
enter-active-class="animated fadeIn"
leave-active-class="animated fadeOut"
appear
:duration="300"
>
<router-view :key="$route.path" />
</transition>
</q-page-container>
</q-layout>
</template>
<script lang="ts">
import { Component } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import objectTree from "src/components/ObjectTree.vue"
import appHeader from "src/components/AppHeader.vue"
import documentControl from "src/components/DocumentControl.vue"
@Component({
components: {
objectTree,
appHeader,
documentControl
}
})
export default class DocumentLayout extends BaseClass {
/****************************************************************/
// Local settings
/****************************************************************/
/**
* Model for the left drawer of the app containing the hierarchical tree
*/
leftDrawerOpen = true
}
</script>
<style lang="scss">
.q-layout {
outline: none !important;
}
</style>

View file

@ -1,233 +0,0 @@
<template>
<q-layout view="hHh LpR lfr">
<!-- Keybind dialog -->
<keybindCheatsheetDialog
:dialog-trigger="keybindsDialogTrigger"
@trigger-dialog-close="keybindsDialogClose"
/>
<!-- New document dialog -->
<newDocumentDialog
:dialog-trigger="newObjectDialogTrigger"
@trigger-dialog-close="newObjectDialogClose"
/>
<!-- Existing document dialog -->
<existingDocumentDialog
:dialog-trigger="existingObjectDialogTrigger"
@trigger-dialog-close="existingObjectDialogClose"
/>
<!-- Left drawer -->
<q-drawer
content-class="bg-dark text-cultured sideWrapper"
v-model="leftDrawerOpen"
side="left"
:width=375
show-if-above
>
<objectTree/>
<q-page-sticky position="bottom-right" class="controlButtons">
<q-btn
icon="mdi-note-plus-outline"
color="primary"
@click="newObjectAssignUID"
>
<q-tooltip>
Quick-add a new document.
</q-tooltip>
</q-btn>
<q-btn
icon="mdi-database-search"
color="primary"
@click="existingObjectAssignUID"
>
<q-tooltip>
Quick-search an existing document.
</q-tooltip>
</q-btn>
<q-btn
icon="mdi-keyboard-outline"
color="primary"
@click="keybindsDialogAssignUID"
>
<q-tooltip>
Show keybind cheatsheet.
</q-tooltip>
</q-btn>
</q-page-sticky>
</q-drawer>
<!-- Header -->
<appHeader
:is-project="true"
/>
<q-page-container>
<transition
enter-active-class="animated fadeIn"
leave-active-class="animated fadeOut"
appear
:duration="300"
>
<router-view :key="$route.path" />
</transition>
</q-page-container>
</q-layout>
</template>
<script lang="ts">
import { Component, Watch } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import objectTree from "src/components/ObjectTree.vue"
import appHeader from "src/components/AppHeader.vue"
import keybindCheatsheetDialog from "src/components/dialogs/KeybindCheatsheet.vue"
import newDocumentDialog from "src/components/dialogs/NewDocument.vue"
import existingDocumentDialog from "src/components/dialogs/ExistingDocument.vue"
@Component({
components: {
objectTree,
appHeader,
keybindCheatsheetDialog,
newDocumentDialog,
existingDocumentDialog
}
})
export default class MainLayout extends BaseClass {
/****************************************************************/
// Local settings
/****************************************************************/
/**
* Model for the left drawer of the app containing the hierarchical tree
*/
leftDrawerOpen = true
/****************************************************************/
// Keybinds management
/****************************************************************/
/**
* Local keybinds
*/
@Watch("SGET_getCurrentKeyBindData", { deep: true })
processKeyPush () {
// Keybind cheatsheet
if (this.determineKeyBind("openKeybindsCheatsheet")) {
this.keybindsDialogAssignUID()
}
// Quick new document
if (this.determineKeyBind("quickNewDocument")) {
this.newObjectAssignUID()
}
// Quick open existing document
if (this.determineKeyBind("quickExistingDocument")) {
this.existingObjectAssignUID()
}
}
/****************************************************************/
// Keybings cheatsheet dialog
/****************************************************************/
keybindsDialogTrigger: string | false = false
keybindsDialogClose () {
this.keybindsDialogTrigger = false
}
keybindsDialogAssignUID () {
this.keybindsDialogTrigger = this.generateUID()
}
/****************************************************************/
// New document dialog
/****************************************************************/
newObjectDialogTrigger: string | false = false
newObjectDialogClose () {
this.newObjectDialogTrigger = false
}
newObjectAssignUID () {
this.newObjectDialogTrigger = this.generateUID()
}
/****************************************************************/
// Existing document dialog
/****************************************************************/
existingObjectDialogTrigger: string | false = false
existingObjectDialogClose () {
this.existingObjectDialogTrigger = false
}
existingObjectAssignUID () {
this.existingObjectDialogTrigger = this.generateUID()
}
}
</script>
<style lang="scss">
.q-layout {
outline: none !important;
}
.keyBindsDialog {
width: 100%;
max-width: 1000px !important;
h6 {
display: block;
text-align: center;
width: 100%;
}
table {
td {
max-width: 300px;
white-space: inherit;
}
}
.keybindNote {
opacity: 0.8;
font-size: 0.9em;
}
}
.sideWrapper {
padding-bottom: 70px !important;
&::after {
content: '';
position: absolute;
background-color: $dark;
left: 0;
bottom: 0;
right: 5px;
height: 60px;
}
}
.controlButtons {
z-index: 3;
margin: 10px 15px 10px 10px;
button {
margin: 0 5px;
}
}
</style>

View file

@ -7,17 +7,19 @@
<q-dialog
v-model="deleteConfirmationDialog"
>
<q-card>
<q-card
dark
>
<q-card-section class="row items-center">
<span class="q-ml-sm">Are you sure want to delete <b>{{retrieveFieldValue(currentData,'name')}}</b>? <br> This action can not be reverted and the data will be lost <b>forever</b>.</span>
</q-card-section>
<q-card-actions align="right">
<q-btn flat label="Cancel" color="primary" v-close-popup />
<q-btn flat label="Cancel" color="accent" v-close-popup />
<q-btn
flat
outline
label="Delete"
color="red"
color="secondary"
v-close-popup
@click="deleteDocument()" />
</q-card-actions>
@ -48,7 +50,7 @@
/>
<q-btn
v-if="!currentData.isNew"
color="red"
color="secondary"
:label="`Delete ${bluePrintData.nameSingular}`"
@click="openDeleteDialog"
/>

View file

@ -5,15 +5,6 @@
<h3>Project screen for {{projectName}}</h3>
</div>
<div class="col-12 q-mb-lg">
<q-btn
color="primary"
size="md"
label="Export project"
class="q-px-xl q-py-xs"
@click="exportProject(projectName)"
/>
</div>
</q-page>
</template>
@ -22,7 +13,7 @@ import { Component } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import { retrieveCurrentProjectName, exportProject } from "src/scripts/projectManagement/projectManagent"
import { retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
@Component({
components: { }
@ -30,8 +21,6 @@ import { retrieveCurrentProjectName, exportProject } from "src/scripts/projectMa
export default class ProjectScreen extends BaseClass {
projectName = ""
exportProject = exportProject
async created () {
this.projectName = await retrieveCurrentProjectName()
}

View file

@ -1,38 +1,17 @@
<template>
<q-page class="column items-center justify-center">
<q-dialog
v-model="newProjectDialog"
persistent>
<q-card style="width: 500px;">
<q-card-section class="col items-center">
<div>
<h4>
New project
</h4>
</div>
<div>
<q-input
placeholder="Project name"
v-model="newProjectName"
outlined
dense
/>
</div>
<!-- Import project dialog -->
<importProjectCheckDialog
:dialog-trigger="importProjectDialogTrigger"
@trigger-dialog-close="importProjectDialogClose"
/>
</q-card-section>
<q-card-actions align="between">
<q-btn flat label="Cancel" color="red" v-close-popup />
<q-btn
label="Create"
color="primary"
v-close-popup
:disable="newProjectName.length === 0"
@click="createNewProject(newProjectName, $router)" />
</q-card-actions>
</q-card>
</q-dialog>
<!-- New project dialog -->
<newProjectCheckDialog
:dialog-trigger="newProjectDialogTrigger"
@trigger-dialog-close="newProjectDialogClose"
/>
<div class="col-12">
<h3>Welcome to Fantasia Archive</h3>
@ -48,7 +27,17 @@
>
<div>Resume project </div>
</q-btn>
</div>
<div class="col-12 q-mb-lg">
<q-btn
color="primary"
size="md"
class="q-px-xl q-py-xs"
@click="newProjectAssignUID"
>
New Project
</q-btn>
</div>
<div class="col-12 q-mb-lg">
@ -56,40 +45,9 @@
color="primary"
size="md"
class="q-px-xl q-py-xs"
@click="openExistingProject($router)"
@click="importProjectAssignUID()"
>
<div>Open existing project</div>
<q-icon
v-if="projectExists"
color="red"
right
size="30px"
name="mdi-alert-circle" >
<q-tooltip>
All data of the currently opened project will be lost unless it is exported first if an existing project is opened beforehand!
</q-tooltip>
</q-icon>
</q-btn>
</div>
<div class="col-12 q-mb-lg">
<q-btn
color="primary"
size="md"
class="q-px-xl q-py-xs"
@click="newProjectDialog = true"
>
<div>New Project</div>
<q-icon
v-if="projectExists"
color="red"
right
size="30px"
name="mdi-alert-circle" >
<q-tooltip>
All data of the currently opened project will be lost unless it is exported first if a new project is created beforehand!
</q-tooltip>
</q-icon>
Import existing project
</q-btn>
</div>
@ -100,19 +58,40 @@
import { Component } from "vue-property-decorator"
import BaseClass from "src/BaseClass"
import importProjectCheckDialog from "src/components/dialogs/ImportProjectCheck.vue"
import newProjectCheckDialog from "src/components/dialogs/NewProjectCheck.vue"
import { openExistingProject, createNewProject, retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
import { retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
@Component({
components: { }
components: {
importProjectCheckDialog,
newProjectCheckDialog
}
})
export default class WelcomeScreen extends BaseClass {
projectExists: undefined | string | boolean = false
newProjectName = ""
newProjectDialog = false
openExistingProject = openExistingProject
createNewProject = createNewProject
newProjectDialogTrigger: string | false = false
newProjectDialogClose () {
this.newProjectDialogTrigger = false
}
newProjectAssignUID () {
this.newProjectDialogTrigger = this.generateUID()
}
importProjectDialogTrigger: string | false = false
importProjectDialogClose () {
this.importProjectDialogTrigger = false
}
importProjectAssignUID () {
this.importProjectDialogTrigger = this.generateUID()
}
async created () {
this.projectExists = await retrieveCurrentProjectName()

View file

@ -1,5 +1,5 @@
import { RouteConfig } from "vue-router"
import MainLayout from "layouts/MainLayout.vue"
import DocumentLayout from "src/layouts/DocumentLayout.vue"
import ProjectManagentLayout from "layouts/ProjectManagentLayout.vue"
const routes: RouteConfig[] = [
@ -12,7 +12,7 @@ const routes: RouteConfig[] = [
},
{
path: "/project",
component: MainLayout,
component: DocumentLayout,
children: [
{ path: "/project", component: () => import("pages/ProjectScreen.vue") },
{ path: "/project/display-content/:type/:id", component: () => import("pages/DocumentDisplay.vue") }

View file

@ -93,7 +93,7 @@ export const removeCurrentProject = async () => {
* Opens a dialog to let user pick whatever project they wish to open and lets them select a directory
* @param vueRouter The vue router object
*/
export const openExistingProject = (vueRouter: any) => {
export const importExistingProject = (vueRouter: any) => {
/*eslint-disable */
remote.dialog.showOpenDialog({
properties: ["openDirectory"]
@ -122,6 +122,19 @@ export const openExistingProject = (vueRouter: any) => {
await CurrentDB.loadIt(fileContents)
}
/*eslint-disable */
// @ts-ignore
vueRouter.push({ path: "/" }).catch((e: {name: string}) => {
const errorName : string = e.name
if (errorName === "NavigationDuplicated") {
return
}
console.log(e)
})
/* eslint-enable */
await new Promise(resolve => setTimeout(resolve, 1000))
/*eslint-disable */
// @ts-ignore
vueRouter.push({ path: "/project" }).catch((e: {name: string}) => {