mirror of
https://github.com/Elvanos/fantasia-archive.git
synced 2024-06-02 02:14:47 +12:00
0.1.7-DEV-6.2: added legacy document tool, fixed some bugs
This commit is contained in:
parent
922f15cde5
commit
b13d7b0c94
|
@ -622,4 +622,30 @@ export default class BaseClass extends Vue {
|
|||
|
||||
return Object.freeze(object)
|
||||
}
|
||||
|
||||
checkForLegacyDocuments () {
|
||||
return this.SGET_allDocuments.docs.filter(doc => {
|
||||
const localBlueprint = this.SGET_blueprint(doc.type)
|
||||
let hasLegacyValue = false
|
||||
for (const field of doc.extraFields) {
|
||||
const pairedBlueprintField = localBlueprint.extraFields.find(e => e.id === field.id)
|
||||
if (pairedBlueprintField && pairedBlueprintField.isLegacy) {
|
||||
const value = field.value
|
||||
|
||||
if (!value ||
|
||||
(Array.isArray(value) && value.length === 0) ||
|
||||
// @ts-ignore
|
||||
(value?.value?.length === 0) ||
|
||||
// @ts-ignore
|
||||
(value.value === null)) {
|
||||
return false
|
||||
}
|
||||
hasLegacyValue = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return hasLegacyValue
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ export default class DocumentPreview extends BaseClass {
|
|||
if (!value ||
|
||||
(Array.isArray(value) && value.length === 0) ||
|
||||
// @ts-ignore
|
||||
(value?.value && value.value.length === 0) ||
|
||||
(value?.value?.length === 0) ||
|
||||
// @ts-ignore
|
||||
(value.value === null)) {
|
||||
return false
|
||||
|
|
|
@ -583,6 +583,11 @@ export default class AppControl extends BaseClass {
|
|||
if (this.determineKeyBind("navigateToProjectOverview") && this.projectExists && !this.isProjectPage) {
|
||||
this.navigateToProjectPage()
|
||||
}
|
||||
|
||||
// App options
|
||||
if (this.determineKeyBind("toggleDeveloperTools")) {
|
||||
this.toggleDevTools()
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
|
|
@ -65,7 +65,7 @@ import { Component, Watch } from "vue-property-decorator"
|
|||
import DialogBase from "src/components/dialogs/_DialogBase"
|
||||
import { retrieveCurrentProjectName, exportProject, createNewProject } from "src/scripts/projectManagement/projectManagent"
|
||||
|
||||
import { Loading, QSpinnerGears } from "quasar"
|
||||
import { Loading, QSpinnerGears, extend } from "quasar"
|
||||
|
||||
@Component({
|
||||
components: { }
|
||||
|
@ -150,6 +150,12 @@ export default class ImportProjectCheckDialog extends DialogBase {
|
|||
spinner: QSpinnerGears
|
||||
})
|
||||
|
||||
const optionsSnapShot = extend(true, {}, this.SGET_options)
|
||||
// @ts-ignore
|
||||
optionsSnapShot.legacyFieldsCheck = false
|
||||
// @ts-ignore
|
||||
this.SSET_options(optionsSnapShot)
|
||||
|
||||
createNewProject(this.newProjectName, this.$router, this.$q, this).catch(e => console.log(e))
|
||||
}
|
||||
|
||||
|
|
|
@ -181,6 +181,9 @@ export default class RepairProjectDialog extends DialogBase {
|
|||
}
|
||||
|
||||
async remapDocument (document: I_ShortenedDocument, blueprint: I_Blueprint) {
|
||||
// Fix any old, hanging icons
|
||||
document.icon = blueprint.icon
|
||||
|
||||
const statFieldIDS = [
|
||||
"strength",
|
||||
"constitution",
|
||||
|
@ -283,9 +286,6 @@ export default class RepairProjectDialog extends DialogBase {
|
|||
document.extraFields.splice(fieldIndex, 1)
|
||||
})
|
||||
|
||||
if (document._id === "e1e24951-e2af-4513-8e4c-50fb93fd94d9") {
|
||||
console.log(document.extraFields)
|
||||
}
|
||||
this.processedDocument++
|
||||
|
||||
await this.sleep(25)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<span v-html="toolTip"/>
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-if="isOneWayRelationship" name="mdi-arrow-right-bold" size="16px" class="documentLabelExtra">
|
||||
<q-icon v-if="isOneWayRelationship" name="mdi-arrow-right-bold" size="16px" class="documentLabelExtra" color="amber-14">
|
||||
<q-tooltip :delay="500" v-if="!disableDocumentToolTips">
|
||||
This is a one-way relationship. <br> Editing this value <span class="text-secondary">WILL NOT</span> have any effect on the connected document/s.
|
||||
<br>
|
||||
|
@ -20,7 +20,7 @@
|
|||
Middle-clicking the linked document in non-edit mode will open it in new tab and not focus on it.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-if="!isOneWayRelationship" name="mdi-arrow-left-right-bold" size="16px" class="documentLabelExtra">
|
||||
<q-icon v-if="!isOneWayRelationship" name="mdi-arrow-left-right-bold" size="16px" class="documentLabelExtra" color="teal-14">
|
||||
<q-tooltip :delay="500" v-if="!disableDocumentToolTips">
|
||||
This is a two-way relationship. <br> Editing this value <span class="text-secondary">WILL</span> also affect the connected document/s.
|
||||
<br>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<span v-html="toolTip"/>
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-if="isOneWayRelationship" name="mdi-arrow-right-bold" size="16px" class="documentLabelExtra">
|
||||
<q-icon v-if="isOneWayRelationship" name="mdi-arrow-right-bold" size="16px" class="documentLabelExtra" color="amber-14">
|
||||
<q-tooltip :delay="500" v-if="!disableDocumentToolTips">
|
||||
This is a one-way relationship. <br> Editing this value <span class="text-secondary">WILL NOT</span> have any effect on the connected document/s.
|
||||
<br>
|
||||
|
@ -20,7 +20,7 @@
|
|||
Middle-clicking the linked document in non-edit mode will open it in new tab and not focus on it.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-if="!isOneWayRelationship" name="mdi-arrow-left-right-bold" size="16px" class="documentLabelExtra">
|
||||
<q-icon v-if="!isOneWayRelationship" name="mdi-arrow-left-right-bold" size="16px" class="documentLabelExtra" color="teal-14">
|
||||
<q-tooltip :delay="500" v-if="!disableDocumentToolTips">
|
||||
This is a two-way relationship. <br> Editing this value <span class="text-secondary">WILL</span> also affect the connected document/s.
|
||||
<br>
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
- Added `Follower/Subject count` field to all types of groups document types
|
||||
- Added dev option to the menu for quick document ID copying
|
||||
- Updated the legacy project repair tool to also transfer old stat fields into the new setup
|
||||
- Added keybind for toggling Developer tools
|
||||
- Added an checker tool for removal of legacy fields for the user
|
||||
|
||||
### QoL adjustments
|
||||
|
||||
|
@ -48,6 +50,7 @@
|
|||
- Updated selects to act as text input fields in case there are no prdefixed values in the list
|
||||
- Field labels received a facelift to look more appealing to look at when showing on smaller screens
|
||||
- Attempteds to "prettify" the display mode of the document fields in case the "Hide empty fields" option is ticked on
|
||||
- Added a tiny bit of color to help discern which relationship is one-way and which is two-way
|
||||
|
||||
## 0.1.6a
|
||||
|
||||
|
|
|
@ -60,6 +60,25 @@
|
|||
>
|
||||
<router-view :key="$route.path" />
|
||||
</transition>
|
||||
|
||||
<q-page-sticky position="top-right" :offset="[18, 75]">
|
||||
<q-btn
|
||||
icon="mdi-book-search-outline"
|
||||
color="red-13"
|
||||
fab
|
||||
v-if="legacyFieldsCheck"
|
||||
@click="openLegacyDocuments"
|
||||
>
|
||||
<q-tooltip
|
||||
:delay="500"
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
>
|
||||
Check for documents with legacy values
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-page-sticky>
|
||||
|
||||
</q-page-container>
|
||||
</template>
|
||||
</q-splitter>
|
||||
|
@ -214,6 +233,8 @@ export default class DocumentLayout extends BaseClass {
|
|||
const options = this.SGET_options
|
||||
this.hideHierarchyTree = options.hideHierarchyTree
|
||||
|
||||
this.legacyFieldsCheck = options.legacyFieldsCheck
|
||||
|
||||
// @ts-ignore
|
||||
this.pre017check = options.pre017check
|
||||
|
||||
|
@ -225,6 +246,8 @@ export default class DocumentLayout extends BaseClass {
|
|||
}
|
||||
}
|
||||
|
||||
legacyFieldsCheck: boolean|undefined = true
|
||||
|
||||
get limiterWidth () {
|
||||
return (!this.hideHierarchyTree) ? 374 : 0
|
||||
}
|
||||
|
@ -251,6 +274,51 @@ export default class DocumentLayout extends BaseClass {
|
|||
this.SSET_options(this.optionsSnapShot)
|
||||
}
|
||||
|
||||
openLegacyDocuments () {
|
||||
const legacyDocs = this.checkForLegacyDocuments()
|
||||
legacyDocs.forEach(doc => {
|
||||
const dataPass = {
|
||||
doc: doc,
|
||||
treeAction: false
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.SSET_addOpenedDocument(dataPass)
|
||||
})
|
||||
|
||||
if (legacyDocs.length > 0) {
|
||||
this.$q.notify({
|
||||
group: false,
|
||||
type: "warning",
|
||||
timeout: 0,
|
||||
html: true,
|
||||
actions: [{ icon: "mdi-close", color: "black" }],
|
||||
message: `
|
||||
${legacyDocs.length} documents with legacy field values found.
|
||||
<br>
|
||||
Please remap the legacy fields manually to ensure proper functioning of FA.
|
||||
<br>
|
||||
After the remapping is done, rerun the tool to re-check.
|
||||
`
|
||||
})
|
||||
}
|
||||
|
||||
if (legacyDocs.length === 0) {
|
||||
const optionsSnapShot = extend(true, {}, this.SGET_options)
|
||||
// @ts-ignore
|
||||
optionsSnapShot.legacyFieldsCheck = false
|
||||
// @ts-ignore
|
||||
this.SSET_options(optionsSnapShot)
|
||||
|
||||
this.$q.notify({
|
||||
group: false,
|
||||
type: "positive",
|
||||
timeout: 3000,
|
||||
message: "No legacy fields with active values found!"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* React to dragging of the splitter
|
||||
*/
|
||||
|
|
|
@ -834,11 +834,12 @@ export default class PageDocumentDisplay extends BaseClass {
|
|||
if (!value ||
|
||||
(Array.isArray(value) && value.length === 0) ||
|
||||
// @ts-ignore
|
||||
(value?.value && value.value.length === 0) ||
|
||||
(value?.value?.length === 0) ||
|
||||
// @ts-ignore
|
||||
(value.value === null)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -299,5 +299,16 @@ export const defaultKeybinds = [
|
|||
id: "collapseExpandeTreeNode",
|
||||
tooltip: "Collapse or open the focused category in the left hierarchical tree",
|
||||
note: "(while the hierarchical tree item is focused)"
|
||||
},
|
||||
|
||||
// Toggle developer tools - CTRL + SHIFT + ALT + I
|
||||
{
|
||||
altKey: true,
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
which: 73,
|
||||
editable: true,
|
||||
id: "toggleDeveloperTools",
|
||||
tooltip: "Toggles the developer tools on/off"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -209,29 +209,19 @@ export const itemsBlueprint: I_Blueprint = {
|
|||
name: "Related to other Items",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-sword",
|
||||
sizing: 4,
|
||||
sizing: 6,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "items",
|
||||
connectedField: "pairedItems"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "pairedConnectedProfessions",
|
||||
name: "Commonly used by Occupations/Classes",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fab fa-pied-piper-hat",
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "professions",
|
||||
connectedField: "pairedConnectedItems"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
id: "relatedCultures",
|
||||
name: "Connected to Cultures/Art",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fas fa-archway",
|
||||
sizing: 4,
|
||||
sizing: 6,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "culture",
|
||||
connectedField: "pairedItems"
|
||||
|
@ -426,7 +416,7 @@ export const itemsBlueprint: I_Blueprint = {
|
|||
},
|
||||
{
|
||||
id: "breakNotes",
|
||||
name: "Connections - Story/Lore & World",
|
||||
name: "Connections - Story/Lore, World & Details",
|
||||
type: "break",
|
||||
sizing: 12
|
||||
},
|
||||
|
@ -435,7 +425,7 @@ export const itemsBlueprint: I_Blueprint = {
|
|||
name: "Connected to Lore notes/Other notes",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-script-text-outline",
|
||||
sizing: 6,
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "loreNotes",
|
||||
connectedField: "pairedConnectedItems"
|
||||
|
@ -446,7 +436,7 @@ export const itemsBlueprint: I_Blueprint = {
|
|||
name: "Connected to Characters",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-account",
|
||||
sizing: 6,
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "characters",
|
||||
connectedField: "pairedConnectedItems"
|
||||
|
@ -457,7 +447,7 @@ export const itemsBlueprint: I_Blueprint = {
|
|||
name: "Connected to Locations",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-map-marker-radius",
|
||||
sizing: 6,
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "locations",
|
||||
connectedField: "pairedConnectedItems"
|
||||
|
@ -468,16 +458,27 @@ export const itemsBlueprint: I_Blueprint = {
|
|||
name: "Connected to Species/Races/Flora/Fauna",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fas fa-dragon",
|
||||
sizing: 6,
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "races",
|
||||
connectedField: "pairedConnectedItems"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "pairedConnectedProfessions",
|
||||
name: "Connected to by Occupations/Classes",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fab fa-pied-piper-hat",
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "professions",
|
||||
connectedField: "pairedConnectedItems"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
id: "breakWorld",
|
||||
name: "Connections - World",
|
||||
id: "breakPolitics",
|
||||
name: "Connections - Groups/Teachings",
|
||||
type: "break",
|
||||
sizing: 12
|
||||
},
|
||||
|
|
|
@ -242,7 +242,7 @@ export const languagesBlueprint: I_Blueprint = {
|
|||
},
|
||||
{
|
||||
id: "pairedCharacter",
|
||||
name: "Prominent Speakers",
|
||||
name: "Connected to Characters",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-account",
|
||||
sizing: 4,
|
||||
|
@ -253,7 +253,7 @@ export const languagesBlueprint: I_Blueprint = {
|
|||
},
|
||||
{
|
||||
id: "pairedLocations",
|
||||
name: "Spoken in Locations",
|
||||
name: "Connected to Locations",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "mdi-map-marker-radius",
|
||||
sizing: 4,
|
||||
|
@ -264,7 +264,7 @@ export const languagesBlueprint: I_Blueprint = {
|
|||
},
|
||||
{
|
||||
id: "usedByRaces",
|
||||
name: "Spoken by Species/Races/Flora/Fauna",
|
||||
name: "Connected to Species/Races/Flora/Fauna",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fas fa-dragon",
|
||||
sizing: 4,
|
||||
|
|
|
@ -249,7 +249,7 @@ export const professionsBlueprint: I_Blueprint = {
|
|||
name: "Commonly used Skills/Spells/Other",
|
||||
type: "manyToNoneRelationship",
|
||||
icon: "mdi-sword-cross",
|
||||
sizing: 6,
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "skills"
|
||||
}
|
||||
|
@ -259,11 +259,22 @@ export const professionsBlueprint: I_Blueprint = {
|
|||
name: "Commonly used Items",
|
||||
type: "manyToNoneRelationship",
|
||||
icon: "mdi-sword",
|
||||
sizing: 6,
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "items"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "commonRaces",
|
||||
name: "Common Species/Races/Flora/Fauna",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fas fa-dragon",
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "races",
|
||||
connectedField: "commonProfessions"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "usedResources",
|
||||
name: "Used Resources/Materials",
|
||||
|
@ -335,7 +346,7 @@ export const professionsBlueprint: I_Blueprint = {
|
|||
icon: "fas fa-journal-whills",
|
||||
sizing: 6,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "professions",
|
||||
connectedObjectType: "myths",
|
||||
connectedField: "pairedProfessions"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -337,6 +337,17 @@ export const racesBlueprint: I_Blueprint = {
|
|||
connectedField: "pairedRacesSkills"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "commonProfessions",
|
||||
name: "Common Occupations/Classes",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fab fa-pied-piper-hat",
|
||||
sizing: 4,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "professions",
|
||||
connectedField: "commonRaces"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "pairedProducedFromResources",
|
||||
name: "Resources/Materials produced from the Species/Race/Flora/Fauna",
|
||||
|
|
|
@ -344,25 +344,25 @@ export const resourcesBlueprint: I_Blueprint = {
|
|||
}
|
||||
},
|
||||
{
|
||||
id: "usedResources",
|
||||
id: "usedProfessions",
|
||||
name: "Used by Occupations/Classes",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fab fa-pied-piper-hat",
|
||||
sizing: 6,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "professions",
|
||||
connectedField: "usedProfessions"
|
||||
connectedField: "usedResources"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "producedResources",
|
||||
id: "producedProfessions",
|
||||
name: "Produced by Occupations/Classes",
|
||||
type: "manyToManyRelationship",
|
||||
icon: "fab fa-pied-piper-hat",
|
||||
sizing: 6,
|
||||
relationshipSettings: {
|
||||
connectedObjectType: "professions",
|
||||
connectedField: "producedProfessions"
|
||||
connectedField: "producedResources"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ import load from "pouchdb-load"
|
|||
import PouchDB from "pouchdb"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { extend } from "quasar"
|
||||
|
||||
/**
|
||||
* Creates a brand new project and deleted any present data avaiable right now
|
||||
|
@ -174,6 +175,12 @@ export const importExistingProject = (vueRouter: any, Loading: any, loadingSetup
|
|||
|
||||
}
|
||||
|
||||
const optionsSnapShot = extend(true, {}, vueInstance.SGET_options)
|
||||
// @ts-ignore
|
||||
optionsSnapShot.legacyFieldsCheck = true
|
||||
// @ts-ignore
|
||||
vueInstance.SSET_options(optionsSnapShot)
|
||||
|
||||
/*eslint-disable */
|
||||
// @ts-ignore
|
||||
vueRouter.push({ path: "/" }).catch((e: {name: string}) => {
|
||||
|
@ -243,9 +250,15 @@ export const mergeExistingProject = (vueRouter: any, Loading: any, loadingSetup:
|
|||
const fileContents = fs.readFileSync(`${folderPath}/${file}`, { encoding: "utf8" })
|
||||
// @ts-ignore
|
||||
await window.FA_dbs[currentDBName].loadIt(fileContents)
|
||||
|
||||
}
|
||||
|
||||
|
||||
const optionsSnapShot = extend(true, {}, vueInstance.SGET_options)
|
||||
// @ts-ignore
|
||||
optionsSnapShot.legacyFieldsCheck = true
|
||||
// @ts-ignore
|
||||
vueInstance.SSET_options(optionsSnapShot)
|
||||
|
||||
/*eslint-disable */
|
||||
// @ts-ignore
|
||||
vueRouter.push({ path: "/" }).catch((e: {name: string}) => {
|
||||
|
|
|
@ -43,7 +43,8 @@ export interface OptionsStateInteface {
|
|||
|
||||
userKeybindList: any[]
|
||||
treeWidth?: number
|
||||
pre017check?: boolean
|
||||
pre017check?: boolean,
|
||||
legacyFieldsCheck?: boolean
|
||||
}
|
||||
|
||||
function state (): OptionsStateInteface {
|
||||
|
@ -89,7 +90,8 @@ function state (): OptionsStateInteface {
|
|||
preventPreviewsDocuments: false,
|
||||
treeWidth: 374,
|
||||
userKeybindList: [],
|
||||
pre017check: true
|
||||
pre017check: true,
|
||||
legacyFieldsCheck: true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
## THE GM BATCH START - 0.1.7
|
||||
|
||||
- Add "Predecessors", "Successors", "Date of start", "Date of end" and "How long it lasted" fields to locations and all other groups
|
||||
|
||||
- Add setting to hide labels in document preview/view
|
||||
- Add legacy field support & options
|
||||
|
||||
- Add toggle for "Simple/Complex conditions" to show only one field for conditions
|
||||
|
||||
- "Toggle dev tools" keybind
|
||||
- "Save all" keybind and "Save all and exit" option on the exiting
|
||||
- "Save and tick as finished" keybind
|
||||
|
||||
|
|
Loading…
Reference in a new issue