Made folders into groups in tabletop
This commit is contained in:
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -10,6 +10,7 @@
|
||||
"EJSON",
|
||||
"healthbar",
|
||||
"healthbars",
|
||||
"jank",
|
||||
"meteortesting",
|
||||
"nearley",
|
||||
"ngraph",
|
||||
@@ -19,6 +20,7 @@
|
||||
"Spellcasting",
|
||||
"uncomputed",
|
||||
"vuetify",
|
||||
"Vuex",
|
||||
"walkdown"
|
||||
]
|
||||
}
|
||||
@@ -35,12 +35,6 @@ export type Creature = Colored & Shared & {
|
||||
// Tabletop
|
||||
tabletopId?: string,
|
||||
initiativeRoll?: number,
|
||||
tabletopSettings?: {
|
||||
iconGroups: {
|
||||
name?: string,
|
||||
iconIds: string[],
|
||||
}[],
|
||||
},
|
||||
|
||||
settings: {
|
||||
useVariantEncumbrance?: true,
|
||||
@@ -131,17 +125,6 @@ const IconGroupSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
const CreatureTabletopSettingsSchema = new SimpleSchema({
|
||||
iconGroups: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
max: 10,
|
||||
},
|
||||
'iconGroups.$': {
|
||||
type: IconGroupSchema,
|
||||
},
|
||||
});
|
||||
|
||||
const CreatureSchema = new SimpleSchema({
|
||||
// Strings
|
||||
name: {
|
||||
@@ -252,10 +235,6 @@ const CreatureSchema = new SimpleSchema({
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
tabletopSettings: {
|
||||
type: CreatureTabletopSettingsSchema,
|
||||
optional: true,
|
||||
},
|
||||
|
||||
// Settings
|
||||
settings: {
|
||||
|
||||
@@ -59,6 +59,7 @@ export default async function doAction(
|
||||
task,
|
||||
},
|
||||
callback(action: EngineAction) {
|
||||
if (!action) return;
|
||||
resolve(callActionMethod(action, task));
|
||||
return elementId;
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
class="action-card overflow-y-auto"
|
||||
rounded
|
||||
:class="cardClasses"
|
||||
:data-id="model._id"
|
||||
>
|
||||
<div class="layout align-center px-3">
|
||||
<div
|
||||
@@ -34,6 +33,7 @@
|
||||
<div
|
||||
class="action-header flex layout column justify-center pl-1"
|
||||
style="height: 72px; cursor: pointer;"
|
||||
@click="$emit('open-details')"
|
||||
>
|
||||
<div class="action-title my-1">
|
||||
{{ model.name || propertyName }}
|
||||
@@ -230,13 +230,6 @@ export default {
|
||||
this.activated = undefined;
|
||||
}, 150);
|
||||
},
|
||||
openPropertyDetails() {
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-property-dialog',
|
||||
elementId: `${this.model._id}`,
|
||||
data: {_id: this.model._id},
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
:close-on-click="false"
|
||||
:content-class="`tabletop-prop-menu rows-${rows}`"
|
||||
:close-on-content-click="false"
|
||||
style="z-index: 2"
|
||||
>
|
||||
<tabletop-action-card
|
||||
v-if="selectedProp && selectedProp.type === 'action'"
|
||||
@@ -29,7 +30,10 @@
|
||||
transition: 'opacity 0.2s ease',
|
||||
}"
|
||||
:model="selectedProp"
|
||||
data-id="tabletop-action-card"
|
||||
@close-menu="menuOpen = false"
|
||||
@dialog-opened="menuOpen = false"
|
||||
@open-details="openPropertyDetails"
|
||||
/>
|
||||
<v-card
|
||||
v-else-if="activeIcon && activeIcon.tab"
|
||||
@@ -42,6 +46,17 @@
|
||||
{{ activeIcon.tabName }}
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-card
|
||||
v-else-if="activeIcon && activeIcon.actionName"
|
||||
style="width: 300px"
|
||||
>
|
||||
<v-card-title>
|
||||
<v-icon left>
|
||||
{{ activeIcon.icon }}
|
||||
</v-icon>
|
||||
{{ activeIcon.actionName }}
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
<v-card
|
||||
class="delete-card"
|
||||
@@ -178,6 +193,7 @@ export default {
|
||||
rows: 2,
|
||||
hoveredIcon: undefined,
|
||||
selectedIcon: undefined,
|
||||
lastIcon: undefined,
|
||||
menuOpen: false,
|
||||
menuX: 200,
|
||||
menuY: window.innerHeight - 216,
|
||||
@@ -227,6 +243,9 @@ export default {
|
||||
this.openCharacterSheet(icon.tab, icon.standardId);
|
||||
return;
|
||||
}
|
||||
if (icon.actionName) {
|
||||
this.openStandardAction(icon.standardId)
|
||||
}
|
||||
if (this.selectedIcon === icon) {
|
||||
this.selectedIcon = undefined;
|
||||
this.menuOpen = false;
|
||||
@@ -260,7 +279,23 @@ export default {
|
||||
data: {
|
||||
creatureId: this.creatureId,
|
||||
},
|
||||
});
|
||||
});
|
||||
this.menuOpen = false;
|
||||
},
|
||||
openStandardAction(standardId) {
|
||||
// TODO standard action dialogs
|
||||
this.menuOpen = false;
|
||||
},
|
||||
openPropertyDetails() {
|
||||
const propId = this.selectedProp._id;
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-property-dialog',
|
||||
elementId: 'tabletop-action-card',
|
||||
data: { _id: propId },
|
||||
callback: () => propId
|
||||
});
|
||||
// Close the menu while the dialog is open
|
||||
this.menuOpen = false;
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
@@ -279,9 +314,9 @@ export default {
|
||||
|
||||
// Get the standard icons
|
||||
const standardIconsById = {
|
||||
'cast-spell': {standardId: 'cast-spell', groupName: 'Standard Actions', icon: 'mdi-fire' },
|
||||
'make-check': {standardId: 'make-check', groupName: 'Standard Actions', icon: 'mdi-radiobox-marked' },
|
||||
'roll-dice': {standardId: 'roll-dice', groupName: 'Standard Actions', icon: 'mdi-dice-d20' },
|
||||
'cast-spell': {standardId: 'cast-spell', groupName: 'Standard Actions', icon: 'mdi-fire', actionName: 'Cast Spell' },
|
||||
'make-check': {standardId: 'make-check', groupName: 'Standard Actions', icon: 'mdi-radiobox-marked', actionName: 'Check' },
|
||||
'roll-dice': {standardId: 'roll-dice', groupName: 'Standard Actions', icon: 'mdi-dice-d20', actionName: 'Roll' },
|
||||
'tab-stats': {standardId: 'tab-stats', groupName: 'Tabs', icon: 'mdi-chart-box', tab: 'stats', tabName: 'Stats' },
|
||||
'tab-actions': {standardId: 'tab-actions', groupName: 'Tabs', icon: 'mdi-lightning-bolt', tab: 'actions', tabName: 'Actions' },
|
||||
'tab-spells': this.creature?.settings?.hideSpellsTab ? undefined : {standardId: 'tab-spells', groupName: 'Tabs', icon: 'mdi-fire', tab: 'spells', tabName: 'Spells' },
|
||||
@@ -292,28 +327,29 @@ export default {
|
||||
};
|
||||
|
||||
// Get the folders that could hide a property
|
||||
const folderIds = CreatureProperties.find({
|
||||
const folderGroupsById = {};
|
||||
CreatureProperties.find({
|
||||
'root.id': this.creatureId,
|
||||
type: 'folder',
|
||||
groupStats: true,
|
||||
hideStatsGroup: true,
|
||||
removed: { $ne: true },
|
||||
inactive: { $ne: true },
|
||||
}, { fields: { _id: 1 } }).map(folder => folder._id);
|
||||
}, { fields: { _id: 1 } }).forEach(folder => {
|
||||
const folderGroup = { name: folder._id, iconList: [] };
|
||||
iconGroups.push(folderGroup);
|
||||
folderGroupsById[folder._id] = folderGroup;
|
||||
});
|
||||
|
||||
// Get the properties that need to be shown as an icon
|
||||
const filter = {
|
||||
'root.id': this.creatureId,
|
||||
'parentId': {
|
||||
$nin: folderIds,
|
||||
},
|
||||
$and: [
|
||||
{
|
||||
$or: [
|
||||
{ type: 'action' },
|
||||
{ type: 'folder', groupStats: true },
|
||||
{ type: 'attribute' },
|
||||
{ type: 'toggle' },
|
||||
// { type: 'attribute' },
|
||||
// { type: 'toggle' },
|
||||
{ type: 'buff' }
|
||||
],
|
||||
},
|
||||
@@ -335,30 +371,15 @@ export default {
|
||||
const props = [];
|
||||
CreatureProperties.find(filter, {
|
||||
sort: { left: -1 },
|
||||
fields: { _id: 1, type: 1 },
|
||||
fields: { _id: 1, type: 1, parentId: 1 },
|
||||
}).forEach(prop => {
|
||||
props.push(prop);
|
||||
propsById[prop._id] = prop;
|
||||
});
|
||||
|
||||
// Using the creature's custom icon groups, collect the props into groups
|
||||
this.creature.tabletopSettings?.iconGroups.forEach(group => {
|
||||
const iconList = [];
|
||||
group.iconIds?.forEach(id => {
|
||||
if (propsById[id]) {
|
||||
const prop = propsById[id];
|
||||
prop._placedInGroup = true;
|
||||
iconList.push({ propId: prop._id });
|
||||
} else if (standardIconsById[id]) {
|
||||
const standardIcon = standardIconsById[id];
|
||||
standardIcon._placedInGroup = true;
|
||||
iconList.push(standardIcon);
|
||||
}
|
||||
});
|
||||
iconGroups.push({
|
||||
name: group.name,
|
||||
iconList,
|
||||
});
|
||||
// If they are in a folder, group them by that folder first
|
||||
if (folderGroupsById[prop.parentId]) {
|
||||
prop._placedInGroup = true;
|
||||
folderGroupsById[prop.parentId].iconList.push({ propId: prop._id });
|
||||
}
|
||||
});
|
||||
|
||||
// Default groups
|
||||
@@ -413,7 +434,9 @@ export default {
|
||||
iconGroups.buffs.rows = splitToNChunks(iconGroups.buffs.iconList, this.rows);
|
||||
}
|
||||
|
||||
return iconGroups;
|
||||
const filteredIconGroups = iconGroups.filter(group => group.iconList.length);
|
||||
filteredIconGroups.buffs = iconGroups.buffs;
|
||||
return filteredIconGroups;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user