Added simple feature UI components and insertion dialog
This commit is contained in:
@@ -9,16 +9,15 @@
|
||||
@change="change"
|
||||
:debounce-time="0"
|
||||
/>
|
||||
<div slot="actions">
|
||||
<v-spacer/>
|
||||
<v-btn
|
||||
flat
|
||||
:disabled="!valid"
|
||||
@click="$store.dispatch('popDialogStack', attribute)"
|
||||
>
|
||||
Insert Attribute
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-spacer slot="actions"/>
|
||||
<v-btn
|
||||
flat
|
||||
slot="actions"
|
||||
:disabled="!valid"
|
||||
@click="$store.dispatch('popDialogStack', attribute)"
|
||||
>
|
||||
Insert Attribute
|
||||
</v-btn>
|
||||
</dialog-base>
|
||||
</template>
|
||||
|
||||
@@ -26,7 +25,6 @@
|
||||
import AttributeEdit from '/imports/ui/components/AttributeEdit.vue';
|
||||
import Attributes from '/imports/api/creature/properties/Attributes.js';
|
||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||
import { Tracker } from 'meteor/tracker';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
/>
|
||||
<smart-select
|
||||
label="Reset"
|
||||
append-icon="arrow_drop_down"
|
||||
clearable
|
||||
:items="resetOptions"
|
||||
:value="attribute.reset"
|
||||
|
||||
51
app/imports/ui/components/FeatureCard.Story.vue
Normal file
51
app/imports/ui/components/FeatureCard.Story.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template lang="html">
|
||||
<column-layout>
|
||||
<div
|
||||
v-for="(feature, index) in features"
|
||||
:key="index"
|
||||
>
|
||||
<feature-card
|
||||
v-bind="feature"
|
||||
/>
|
||||
</div>
|
||||
</column-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||
import FeatureCard from '/imports/ui/components/FeatureCard.vue';
|
||||
|
||||
export default {
|
||||
dontWrap: true,
|
||||
components: {
|
||||
ColumnLayout,
|
||||
FeatureCard,
|
||||
},
|
||||
data(){return {
|
||||
features: [
|
||||
{
|
||||
name: 'Feature 1',
|
||||
enabled: true,
|
||||
alwaysEnabled: true,
|
||||
description: `
|
||||
|
||||
blah blah, with
|
||||
|
||||
spacing
|
||||
`,
|
||||
color: '#f44336',
|
||||
}, {
|
||||
name: 'Feature 2',
|
||||
enabled: false,
|
||||
alwaysEnabled: false,
|
||||
description: `Short Description`,
|
||||
uses: 5,
|
||||
used: 2,
|
||||
},
|
||||
],
|
||||
}},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css' scoped>
|
||||
</style>
|
||||
60
app/imports/ui/components/FeatureCard.vue
Normal file
60
app/imports/ui/components/FeatureCard.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template lang="html">
|
||||
<toolbar-card :color="color" @click="$emit('click')">
|
||||
<span slot="toolbar">
|
||||
{{name}}
|
||||
</span>
|
||||
<v-spacer slot="toolbar"/>
|
||||
<v-checkbox
|
||||
hide-details
|
||||
class="shrink"
|
||||
v-if="!alwaysEnabled"
|
||||
:value="enabled"
|
||||
@change="enabled => $emit('change', {enabled})"
|
||||
slot="toolbar"
|
||||
/>
|
||||
<v-card-text>
|
||||
{{description}}
|
||||
</v-card-text>
|
||||
<v-card-actions v-if="uses">
|
||||
<v-spacer/>
|
||||
<v-btn
|
||||
flat
|
||||
:disabled="uses - used <= 0"
|
||||
@click="$emit('used')"
|
||||
>
|
||||
Use
|
||||
</v-btn>
|
||||
<v-btn
|
||||
flat
|
||||
:disabled="!used"
|
||||
@click="$emit('reset')"
|
||||
>
|
||||
Reset
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</toolbar-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarCard from '/imports/ui/components/ToolbarCard.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
charId: String,
|
||||
name: String,
|
||||
description: String,
|
||||
uses: Number,
|
||||
used: Number,
|
||||
reset: String,
|
||||
color: String,
|
||||
enabled: Boolean,
|
||||
alwaysEnabled: Boolean,
|
||||
},
|
||||
components: {
|
||||
ToolbarCard,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
78
app/imports/ui/components/FeatureCreationDialog.vue
Normal file
78
app/imports/ui/components/FeatureCreationDialog.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template lang="html">
|
||||
<dialog-base>
|
||||
<div slot="toolbar">
|
||||
New Feature
|
||||
</div>
|
||||
<feature-edit
|
||||
:feature="feature"
|
||||
:errors="errors"
|
||||
@change="change"
|
||||
:debounce-time="0"
|
||||
/>
|
||||
<v-spacer slot="actions"/>
|
||||
<v-btn
|
||||
flat
|
||||
slot="actions"
|
||||
:disabled="!valid"
|
||||
@click="$store.dispatch('popDialogStack', feature)"
|
||||
>
|
||||
Insert Feature
|
||||
</v-btn>
|
||||
</dialog-base>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FeatureEdit from '/imports/ui/components/FeatureEdit.vue';
|
||||
import Features from '/imports/api/creature/properties/Features.js';
|
||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FeatureEdit,
|
||||
DialogBase,
|
||||
},
|
||||
data(){ return {
|
||||
feature: {
|
||||
name: 'New Feature',
|
||||
description: null,
|
||||
uses: null,
|
||||
used: 0,
|
||||
reset: null,
|
||||
enabled: true,
|
||||
alwaysEnabled: true,
|
||||
color: '#9E9E9E',
|
||||
},
|
||||
valid: true,
|
||||
}},
|
||||
methods: {
|
||||
change(update, ack){
|
||||
for (key in update){
|
||||
this.feature[key] = update[key];
|
||||
}
|
||||
if (ack) ack();
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.validationContext = Features.simpleSchema().newContext();
|
||||
},
|
||||
computed: {
|
||||
errors(){
|
||||
this.valid = true;
|
||||
let cleanAtt = this.validationContext.clean(this.feature)
|
||||
this.validationContext.validate(cleanAtt, {keys: [
|
||||
'name', 'description', 'uses', 'used', 'reset', 'enabled',
|
||||
'alwaysEnabled', 'color',
|
||||
]});
|
||||
let errors = {};
|
||||
this.validationContext.validationErrors().forEach(error => {
|
||||
if (this.valid) this.valid = false;
|
||||
errors[error.name] = Features.simpleSchema().messageForError(error);
|
||||
});
|
||||
return errors;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
113
app/imports/ui/components/FeatureEdit.vue
Normal file
113
app/imports/ui/components/FeatureEdit.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template lang="html">
|
||||
<div>
|
||||
<text-field
|
||||
label="Name"
|
||||
:value="feature.name"
|
||||
@change="(name, ack) => $emit('change', {name}, ack)"
|
||||
:error-messages="errors.name"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Used"
|
||||
type="number"
|
||||
:value="feature.used"
|
||||
@change="(used, ack) => $emit('change', {used}, ack)"
|
||||
:error-messages="errors.used"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Uses"
|
||||
:value="feature.uses"
|
||||
@change="(uses, ack) => $emit('change', {uses}, ack)"
|
||||
:error-messages="errors.uses"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<smart-select
|
||||
label="Reset"
|
||||
clearable
|
||||
:items="resetOptions"
|
||||
:value="feature.reset"
|
||||
:error-messages="errors.reset"
|
||||
:menu-props="{auto: true, lazy: true}"
|
||||
@change="(reset, ack) => $emit('change', {reset}, ack)"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<smart-select
|
||||
label="Enabled"
|
||||
:items="enabledOptions"
|
||||
:value="enabledStatus"
|
||||
:error-messages="errors.enabled || errors.alwaysEnabled"
|
||||
:menu-props="{auto: true, lazy: true}"
|
||||
@change="changeEnabled"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-area
|
||||
label="Description"
|
||||
:value="feature.description"
|
||||
:error-messages="errors.description"
|
||||
@change="(description, ack) => $emit('change', {description}, ack)"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
feature: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
errors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
debounceTime: Number,
|
||||
},
|
||||
data(){ return{
|
||||
resetOptions: [
|
||||
{
|
||||
text: 'Short rest',
|
||||
value: 'shortRest',
|
||||
}, {
|
||||
text: 'Long rest',
|
||||
value: 'longRest',
|
||||
}
|
||||
],
|
||||
enabledOptions: [
|
||||
{
|
||||
text: 'Always enabled',
|
||||
value: 'always',
|
||||
}, {
|
||||
text: 'Enabled',
|
||||
value: 'enabled',
|
||||
}, {
|
||||
text: 'Disabled',
|
||||
value: 'disabled',
|
||||
}
|
||||
],
|
||||
}},
|
||||
computed: {
|
||||
enabledStatus(){
|
||||
if (!this.feature) return;
|
||||
if (this.feature.alwaysEnabled) return 'always';
|
||||
if (this.feature.enabled) return 'enabled';
|
||||
return 'disabled';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
changeEnabled(value, ack){
|
||||
if (value === 'always'){
|
||||
this.$emit('change', {enabled: true, alwaysEnabled: true}, ack);
|
||||
} else if (value === 'enabled'){
|
||||
this.$emit('change', {enabled: true, alwaysEnabled: false}, ack);
|
||||
} else if (value === 'disabled'){
|
||||
this.$emit('change', {enabled: false, alwaysEnabled: false}, ack);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
38
app/imports/ui/components/ToolbarCard.vue
Normal file
38
app/imports/ui/components/ToolbarCard.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template lang="html">
|
||||
<v-card>
|
||||
<v-toolbar
|
||||
flat
|
||||
style="transform: none;"
|
||||
@click="$emit('click')"
|
||||
:color="color"
|
||||
:dark="isDark"
|
||||
>
|
||||
<slot name="toolbar"/>
|
||||
</v-toolbar>
|
||||
<div>
|
||||
<slot/>
|
||||
</div>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
||||
export default {
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default(){
|
||||
return this.$vuetify.theme.secondary;
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isDark(){
|
||||
return isDarkColor(this.color);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
:loading="loading"
|
||||
:error-messages="errors"
|
||||
:value="safeValue"
|
||||
:auto-grow="autoGrow"
|
||||
@input="input"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@@ -15,5 +16,11 @@
|
||||
|
||||
export default {
|
||||
mixins: [SmartInput],
|
||||
props: {
|
||||
autoGrow: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user