Compare commits

..

4 Commits

Author SHA1 Message Date
Stefan Zermatten
0c24238069 Fixed not found page for Vuetify 2 2021-04-11 18:15:56 +02:00
Stefan Zermatten
66847430ad Fixed sign in and register pages not being built with Vuetify 2 components 2021-04-11 18:05:36 +02:00
Stefan Zermatten
bfb860605f Creature properties now duplicate with up to 50 children 2021-04-11 14:47:41 +02:00
Stefan Zermatten
d87524418a Fixed bug where character sheet fab could be permanently hidden by closing the insert from library dialog 2021-04-11 13:52:25 +02:00
12 changed files with 130 additions and 30 deletions

View File

@@ -65,7 +65,6 @@ let CreaturePropertySchema = new SimpleSchema({
}, },
'dependencies.$': { 'dependencies.$': {
type: String, type: String,
regEx: SimpleSchema.RegEx.Id,
}, },
}); });

View File

@@ -2,9 +2,24 @@ import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method'; import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
import { insertPropertyWork } from '/imports/api/creature/creatureProperties/methods/insertProperty.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js';
import {
setLineageOfDocs,
renewDocIds
} from '/imports/api/parenting/parenting.js';
import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js';
import { reorderDocs } from '/imports/api/parenting/order.js';
import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js';
import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js';
var snackbar;
if (Meteor.isClient){
snackbar = require(
'/imports/ui/components/snackbars/SnackbarQueue.js'
).snackbar
}
const DUPLICATE_CHILDREN_LIMIT = 50;
const duplicateProperty = new ValidatedMethod({ const duplicateProperty = new ValidatedMethod({
name: 'creatureProperties.duplicate', name: 'creatureProperties.duplicate',
@@ -20,13 +35,70 @@ const duplicateProperty = new ValidatedMethod({
timeInterval: 5000, timeInterval: 5000,
}, },
run({_id}) { run({_id}) {
let creatureProperty = CreatureProperties.findOne(_id); let property = CreatureProperties.findOne(_id);
let rootCreature = getRootCreatureAncestor(creatureProperty); let creature = getRootCreatureAncestor(property);
assertEditPermission(rootCreature, this.userId);
insertPropertyWork({ assertEditPermission(creature, this.userId);
property: creatureProperty,
creature: rootCreature, // Renew the doc ID
let randomSrc = DDP.randomStream('duplicateProperty');
let propertyId = randomSrc.id();
property._id = propertyId;
// Get all the descendants
let nodes = CreatureProperties.find({
'ancestors.id': _id,
removed: {$ne: true},
}, {
limit: DUPLICATE_CHILDREN_LIMIT + 1,
sort: {order: 1},
}).fetch();
// Alert the user if the limit was hit
if (nodes.length > DUPLICATE_CHILDREN_LIMIT){
nodes.pop();
if (Meteor.isClient){
snackbar({
text: `Only the first ${DUPLICATE_CHILDREN_LIMIT} children were duplicated`,
});
}
}
// re-map all the ancestors
setLineageOfDocs({
docArray: nodes,
newAncestry : [
...property.ancestors,
{id: propertyId, collection: 'creatureProperties'}
],
oldParent : {id: _id, collection: 'creatureProperties'},
});
// Give the docs new IDs without breaking internal references
renewDocIds({docArray: nodes});
// Order the root node
property.order += 0.5;
// Insert the properties
CreatureProperties.batchInsert([property, ...nodes]);
// Tree structure changed by inserts, reorder the tree
reorderDocs({
collection: CreatureProperties,
ancestorId: property.ancestors[0].id,
}); });
// Inserting the active status of the property needs to be denormalised
recomputeInactiveProperties(creature._id);
// Recompute the inventory
recomputeInventory(creature._id);
// Inserting a creature property invalidates dependencies: full recompute
recomputeCreatureByDoc(creature);
return propertyId;
}, },
}); });

View File

@@ -34,7 +34,9 @@ const duplicateLibraryNode = new ValidatedMethod({
run({_id}) { run({_id}) {
let libraryNode = LibraryNodes.findOne(_id); let libraryNode = LibraryNodes.findOne(_id);
assertDocEditPermission(libraryNode, this.userId); assertDocEditPermission(libraryNode, this.userId);
let libraryNodeId = Random.id();
let randomSrc = DDP.randomStream('duplicateLibraryNode');
let libraryNodeId = randomSrc.id();
libraryNode._id = libraryNodeId; libraryNode._id = libraryNodeId;
let nodes = LibraryNodes.find({ let nodes = LibraryNodes.find({

View File

@@ -33,7 +33,7 @@ const AdjustmentSchema = new SimpleSchema({
const ComputedOnlyAdjustmentSchema = new SimpleSchema({ const ComputedOnlyAdjustmentSchema = new SimpleSchema({
amountResult: { amountResult: {
type: SimpleSchema.Integer, type: SimpleSchema.oneOf(String, Number),
optional: true, optional: true,
}, },
amountErrors: { amountErrors: {

View File

@@ -29,7 +29,7 @@ const DamageSchema = new SimpleSchema({
const ComputedOnlyDamageSchema = new SimpleSchema({ const ComputedOnlyDamageSchema = new SimpleSchema({
amountResult: { amountResult: {
type: SimpleSchema.oneOf(String, SimpleSchema.Integer), type: SimpleSchema.oneOf(String, Number),
optional: true, optional: true,
}, },
amountErrors: { amountErrors: {

View File

@@ -10,7 +10,11 @@ const InlineComputationSchema = new SimpleSchema({
type: String, type: String,
optional: true, optional: true,
}, },
errors: ErrorSchema, errors: {
type: Array,
optional: true,
},
'errors.$': ErrorSchema,
}); });
export default InlineComputationSchema; export default InlineComputationSchema;

View File

@@ -213,7 +213,7 @@
component: 'creature-property-from-library-dialog', component: 'creature-property-from-library-dialog',
elementId: 'insert-creature-property-from-library-btn', elementId: 'insert-creature-property-from-library-btn',
callback(libraryNode){ callback(libraryNode){
if (!libraryNode) return; if (!libraryNode) return 'insert-creature-property-fab';
revealFab(fab); revealFab(fab);
let nodeId = libraryNode._id; let nodeId = libraryNode._id;

View File

@@ -53,6 +53,7 @@
embedded embedded
:_id="selected" :_id="selected"
@removed="selected = undefined" @removed="selected = undefined"
@duplicated="id => selected = id"
/> />
</template> </template>
</tree-detail-layout> </tree-detail-layout>

View File

@@ -158,12 +158,12 @@ export default {
methods: { methods: {
getPropertyName, getPropertyName,
duplicate(){ duplicate(){
duplicateProperty.call({_id: this.currentId}, (error) => { duplicateProperty.call({_id: this.currentId}, (error, id) => {
if (error) { if (error) {
console.error(error); console.error(error);
} }
if (this.embedded){ if (this.embedded){
this.$emit('duplicated'); this.$emit('duplicated', id);
} else { } else {
this.$store.dispatch('popDialogStack'); this.$store.dispatch('popDialogStack');
} }

View File

@@ -1,12 +1,19 @@
<template> <template>
<div> <v-layout
<v-layout style="height: 100%;"
align-center column
justify-center align-center
> justify-center
<h1> >
No page was found for this address <h1 class="text-h1">
</h1> 404
</v-layout> </h1>
</div> <h1 class="ma-4 text-h3">
No page was found for this address
</h1>
</v-layout>
</template> </template>
<script lang="js">
export default {}
</script>

View File

@@ -18,6 +18,8 @@
type="text" type="text"
label="Email" label="Email"
:rules="emailRules" :rules="emailRules"
class="ma-2"
outlined
required required
@keyup.enter="submit" @keyup.enter="submit"
/> />
@@ -26,6 +28,8 @@
type="text" type="text"
label="Username" label="Username"
:rules="usernameRules" :rules="usernameRules"
class="ma-2"
outlined
required required
@keyup.enter="submit" @keyup.enter="submit"
/> />
@@ -34,6 +38,8 @@
type="password" type="password"
label="Password" label="Password"
:rules="passwordRules" :rules="passwordRules"
class="ma-2"
outlined
required required
@keyup.enter="submit" @keyup.enter="submit"
/> />
@@ -42,6 +48,8 @@
type="password" type="password"
label="Password Again" label="Password Again"
:rules="password2Rules" :rules="password2Rules"
class="ma-2"
outlined
required required
@keyup.enter="submit" @keyup.enter="submit"
/> />
@@ -78,7 +86,7 @@
</template> </template>
<script lang="js"> <script lang="js">
export default{ export default {
data() { data() {
return { return {
valid: true, valid: true,
@@ -88,7 +96,7 @@
], ],
email: '', email: '',
emailRules: [ emailRules: [
v => !!v || 'Name is required', v => !!v || 'E-mail is required',
v => /.+@.+/.test(v) || 'E-mail must be valid', v => /.+@.+/.test(v) || 'E-mail must be valid',
], ],
password: '', password: '',

View File

@@ -18,6 +18,8 @@
type="text" type="text"
label="Username or email" label="Username or email"
:rules="nameRules" :rules="nameRules"
class="ma-2"
outlined
required required
@keyup.enter="submit" @keyup.enter="submit"
/> />
@@ -26,6 +28,8 @@
type="password" type="password"
label="Password" label="Password"
:rules="passwordRules" :rules="passwordRules"
class="ma-2"
outlined
required required
@keyup.enter="submit" @keyup.enter="submit"
/> />
@@ -39,6 +43,7 @@
<v-btn <v-btn
:disabled="!valid" :disabled="!valid"
color="accent" color="accent"
class="ma-2"
@click="submit" @click="submit"
> >
Sign In Sign In
@@ -46,6 +51,7 @@
<v-btn <v-btn
color="accent" color="accent"
:to="{ name: 'register', query: { redirect: this.$route.query.redirect} }" :to="{ name: 'register', query: { redirect: this.$route.query.redirect} }"
class="ma-2"
> >
Register Register
</v-btn> </v-btn>
@@ -62,6 +68,7 @@
</div> </div>
<v-btn <v-btn
color="accent" color="accent"
class="ma-2"
@click="googleLogin" @click="googleLogin"
> >
Sign in with Google Sign in with Google
@@ -71,6 +78,7 @@
</div> </div>
<v-btn <v-btn
color="accent" color="accent"
class="ma-2"
@click="patreonLogin" @click="patreonLogin"
> >
Sign in with Patreon Sign in with Patreon
@@ -80,8 +88,7 @@
</template> </template>
<script lang="js"> <script lang="js">
import { Meteor } from 'meteor/meteor' export default {
export default{
data: () => ({ data: () => ({
valid: true, valid: true,
name: '', name: '',