Continued work on point buy UI

This commit is contained in:
Stefan Zermatten
2022-08-23 14:44:35 +02:00
parent 59fc5ab851
commit e42ec4b862
11 changed files with 391 additions and 205 deletions

View File

@@ -1,187 +1,177 @@
<template lang="html">
<div class="point-buy-form">
<v-row dense>
<v-col
cols="12"
md="6"
>
<text-field
ref="focusFirst"
label="Table name"
:value="model.name"
:error-messages="errors.name"
@change="change('name', ...arguments)"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Min"
hint="The minimum value for each row"
:model="model.min"
:error-messages="errors.min"
@change="({path, value, ack}) =>
$emit('change', {path: ['min', ...path], value, ack})"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Max"
hint="The maximum value for each row"
:model="model.max"
:error-messages="errors.max"
@change="({path, value, ack}) =>
$emit('change', {path: ['max', ...path], value, ack})"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Cost"
hint="A function of `value` that determines the cost of each row"
hide-value
:model="model.cost"
:error-messages="errors.cost"
@change="({path, value, ack}) =>
$emit('change', {path: ['cost', ...path], value, ack})"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Total available points"
hint="The total allowed cost of all rows"
:model="model.total"
:error-messages="errors.total"
@change="({path, value, ack}) =>
$emit('change', {path: ['total', ...path], value, ack})"
/>
</v-col>
</v-row>
<v-subheader>
Rows
</v-subheader>
<v-slide-x-transition
group
leave-absolute
>
<v-row
v-for="(row, i) in model.values"
:key="row._id"
dense
>
<v-divider
v-if="i"
style="flex-basis: 100%;"
class="mb-6"
/>
<v-col cols="11">
<v-row dense>
<v-col
cols="12"
md="6"
>
<text-field
ref="focusFirst"
label="Row Name"
:value="row.name"
:error-messages="errors.values && errors.values[i] && errors.values[i].name"
@change="change(['values', i, 'name'], ...arguments)"
/>
<point-buy-spend-form
:model="model"
@change="e => $emit('change', e)"
@push="e => $emit('change', e)"
@pull="e => $emit('change', e)"
/>
<form-sections>
<form-section name="Settings">
<v-row dense>
<v-col
cols="12"
md="6"
>
<text-field
ref="focusFirst"
label="Table name"
:value="model.name"
:error-messages="errors.name"
@change="change('name', ...arguments)"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Min"
hint="The minimum value for each row"
:model="model.min"
:error-messages="errors.min"
@change="({path, value, ack}) =>
$emit('change', {path: ['min', ...path], value, ack})"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Max"
hint="The maximum value for each row"
:model="model.max"
:error-messages="errors.max"
@change="({path, value, ack}) =>
$emit('change', {path: ['max', ...path], value, ack})"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Cost"
hint="A function of `value` that determines the cost of each row"
hide-value
:model="model.cost"
:error-messages="errors.cost"
@change="({path, value, ack}) =>
$emit('change', {path: ['cost', ...path], value, ack})"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<computed-field
label="Total available points"
hint="The total allowed cost of all rows"
:model="model.total"
:error-messages="errors.total"
@change="({path, value, ack}) =>
$emit('change', {path: ['total', ...path], value, ack})"
/>
</v-col>
</v-row>
</form-section>
<form-section name="Rows">
<v-slide-x-transition
group
leave-absolute
>
<v-row
v-for="(row, i) in model.values"
:key="row._id"
dense
>
<v-divider
v-if="i"
style="flex-basis: 100%;"
class="mb-6"
/>
<v-col cols="11">
<v-row dense>
<v-col
cols="12"
md="6"
>
<text-field
ref="focusFirst"
label="Row Name"
:value="row.name"
:error-messages="errors.values && errors.values[i] && errors.values[i].name"
@change="change(['values', i, 'name'], ...arguments)"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<text-field
label="Variable name"
:value="row.variableName"
hint="Use this name in calculations to reference this row of the table"
:error-messages="errors.values && errors.values[i] && errors.values[i].variableName"
@change="change(['values', i, 'variableName'], ...arguments)"
/>
</v-col>
<v-col
v-if="row.errors && row.errors.length"
cols="12"
>
<calculation-error-list
:errors="row.errors"
/>
</v-col>
</v-row>
</v-col>
<v-col
cols="12"
md="6"
cols="1"
class="d-flex align-center justify-center"
>
<text-field
label="Variable name"
:value="row.variableName"
hint="Use this name in calculations to reference this row of the table"
:error-messages="errors.values && errors.values[i] && errors.values[i].variableName"
@change="change(['values', i, 'variableName'], ...arguments)"
/>
</v-col>
<v-col
cols="12"
md="6"
>
<text-field
label="Value"
type="number"
:min="row.hasOwnProperty('min') ? row.min && row.min.value : model.min && model.min.value"
:max="row.hasOwnProperty('max') ? row.max && row.max.value : model.max && model.max.value"
:value="row.value"
:error-messages="errors.values && errors.values[i] && errors.values[i].value"
@change="(value, ack) => $emit('change', {path: ['values', i, 'value'], value, ack})"
<v-btn
icon
large
@click="$emit('pull', {path: ['values', i]})"
>
<template v-if="row.spent">
Cost: {{ row.spent }}
</template>
</text-field>
</v-col>
<v-col
v-if="row.errors && row.errors.length"
cols="12"
>
<calculation-error-list
:errors="row.errors"
/>
<v-icon>mdi-delete</v-icon>
</v-btn>
</v-col>
</v-row>
</v-col>
<v-col
cols="1"
class="d-flex align-center justify-center"
>
<v-btn
icon
large
@click="$emit('pull', {path: ['values', i]})"
<v-row
key="addButton"
dense
justify="end"
class="mb-4"
>
<v-icon>mdi-delete</v-icon>
</v-btn>
</v-col>
</v-row>
<v-row
key="addButton"
dense
justify="end"
class="mb-4"
<v-col
cols="1"
class="d-flex justify-center"
>
<v-btn
icon
outlined
:loading="addRowLoading"
:disabled="rowsFull"
@click="addRow"
>
<v-icon>
mdi-plus
</v-icon>
</v-btn>
</v-col>
</v-row>
</v-slide-x-transition>
</form-section>
<form-section
v-if="$slots.children"
name="Children"
>
<v-col
cols="1"
class="d-flex justify-center"
>
<v-btn
icon
outlined
:loading="addRowLoading"
:disabled="rowsFull"
@click="addRow"
>
<v-icon>
mdi-plus
</v-icon>
</v-btn>
</v-col>
</v-row>
</v-slide-x-transition>
<form-section
v-if="$slots.children"
name="Children"
standalone
>
<slot name="children" />
</form-section>
<slot name="children" />
</form-section>
</form-sections>
</div>
</template>
@@ -190,10 +180,12 @@ import attributeListMixin from '/imports/ui/properties/forms/shared/lists/attrib
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
import { PointBuySchema } from '/imports/api/properties/PointBuys.js';
import CalculationErrorList from '/imports/ui/properties/forms/shared/CalculationErrorList.vue';
import PointBuySpendForm from '/imports/ui/properties/forms/PointBuySpendForm.vue';
export default {
components: {
CalculationErrorList,
PointBuySpendForm,
},
mixins: [propertyFormMixin, attributeListMixin],
data() {

View File

@@ -1,13 +1,101 @@
<template lang="html">
<div class="point-buy-spend-form">
<div />
<v-row dense>
<v-col
cols="10"
md="11"
/>
<v-col
cols="2"
md="1"
class="text-truncate d-flex justify-center"
>
Cost
</v-col>
</v-row>
<v-row
v-for="(row, i) in model.values"
:key="row._id"
dense
align="center"
>
<v-col
cols="12"
md="2"
class="d-flex justify-md-end"
>
{{ row.name }}
</v-col>
<v-col
cols="2"
md="1"
class="d-flex justify-md-center justify-end"
>
{{ row.value }}
</v-col>
<v-col
cols="8"
>
<smart-slider
thumb-label
dense
:ticks="max(row) - min(row) <= 20"
:min="min(row)"
:max="max(row)"
:value="row.value"
:error-messages="errors.values && errors.values[i] && errors.values[i].value"
@change="(value, ack) => $emit('change', {path: ['values', i, 'value'], value, ack})"
/>
</v-col>
<v-col
cols="2"
md="1"
class="text-truncate d-flex justify-center"
>
{{ row.spent }}
</v-col>
<v-col
v-if="row.errors && row.errors.length"
cols="12"
>
<calculation-error-list
:errors="row.errors"
/>
</v-col>
</v-row>
<v-row
dense
>
<v-col
cols="12"
class="text-h4 mb-4 pr-8 d-flex justify-end"
:class="{
'error--text': model.spent > (model.total && model.total.value),
'warning--text': model.spent < (model.total && model.total.value),
}"
>
{{ model.spent }} / {{ model.total && model.total.value }}
</v-col>
</v-row>
</div>
</template>
<script lang="js">
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
import CalculationErrorList from '/imports/ui/properties/forms/shared/CalculationErrorList.vue';
export default {
mixins: [propertyFormMixin],
};
export default {
components: {
CalculationErrorList,
},
methods: {
max(row) {
return row.max ? row.max && row.max.value : this.model.max && this.model.max.value;
},
min(row) {
return row.min ? row.min && row.min.value : this.model.min && this.model.min.value;
},
},
mixins: [propertyFormMixin],
};
</script>

View File

@@ -4,7 +4,7 @@
<v-expansion-panel-header>
{{ name }}
</v-expansion-panel-header>
<v-expansion-panel-content>
<v-expansion-panel-content class="pt-2">
<slot />
</v-expansion-panel-content>
</v-expansion-panel>
@@ -13,7 +13,7 @@
<v-expansion-panel-header>
{{ name }}
</v-expansion-panel-header>
<v-expansion-panel-content>
<v-expansion-panel-content class="pt-2">
<slot />
</v-expansion-panel-content>
</v-expansion-panel>