mirror of
https://gitlab.com/bramw/baserow.git
synced 2024-11-25 00:46:46 +00:00
217 lines
5.6 KiB
Vue
217 lines
5.6 KiB
Vue
<template>
|
|
<div
|
|
ref="fieldContextAnchor"
|
|
class="grid-view-aggregation"
|
|
:class="{
|
|
'read-only': !userCanMakeAggregations,
|
|
}"
|
|
@click.prevent="
|
|
userCanMakeAggregations &&
|
|
$refs[`fieldContext`].toggle(
|
|
$refs.fieldContextAnchor,
|
|
'top',
|
|
'right',
|
|
10
|
|
)
|
|
"
|
|
>
|
|
<component
|
|
:is="viewAggregationType.getComponent()"
|
|
v-if="viewAggregationType"
|
|
:loading="loading"
|
|
:aggregation-type="viewAggregationType"
|
|
:value="value"
|
|
/>
|
|
<div
|
|
v-else-if="userCanMakeAggregations"
|
|
class="grid-view-aggregation__empty"
|
|
:class="{
|
|
'grid-view-aggregation__empty--active':
|
|
$refs.fieldContext && $refs.fieldContext.isOpen(),
|
|
}"
|
|
>
|
|
<i class="grid-view-aggregation__empty-icon iconoir-plus"></i>
|
|
{{ $t('common.summarize') }}
|
|
</div>
|
|
<Context ref="fieldContext">
|
|
<ul class="select__items">
|
|
<li
|
|
class="select__item select__item--no-options"
|
|
:class="{ active: !viewAggregationType }"
|
|
>
|
|
<a class="select__item-link" @click="selectAggregation('none')"
|
|
><div class="select__item-name">
|
|
<span class="select__item-name-text">{{
|
|
$t('common.none')
|
|
}}</span>
|
|
</div>
|
|
</a>
|
|
<i
|
|
v-if="!viewAggregationType"
|
|
class="select__item-active-icon iconoir-check"
|
|
></i>
|
|
</li>
|
|
<li
|
|
v-for="viewAggregation in viewAggregationTypes"
|
|
:key="viewAggregation.getType()"
|
|
class="select__item select__item--no-options"
|
|
:class="{
|
|
active: viewAggregation === viewAggregationType,
|
|
}"
|
|
>
|
|
<a
|
|
class="select__item-link"
|
|
@click="selectAggregation(viewAggregation.getType())"
|
|
><div class="select__item-name">
|
|
<span class="select__item-name-text">{{
|
|
viewAggregation.getName()
|
|
}}</span>
|
|
</div>
|
|
</a>
|
|
<i
|
|
v-if="viewAggregation === viewAggregationType"
|
|
class="select__item-active-icon iconoir-check"
|
|
></i>
|
|
</li>
|
|
</ul>
|
|
</Context>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters } from 'vuex'
|
|
|
|
export default {
|
|
name: 'GridViewFieldFooter',
|
|
props: {
|
|
database: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
field: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
view: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
storePrefix: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
},
|
|
data() {
|
|
return { pendingValueUpdate: false }
|
|
},
|
|
computed: {
|
|
userCanMakeAggregations() {
|
|
return this.$hasPermission(
|
|
'database.table.view.update_field_options',
|
|
this.view,
|
|
this.database.workspace.id
|
|
)
|
|
},
|
|
aggregationType() {
|
|
return this.fieldOptions[this.field.id]?.aggregation_type
|
|
},
|
|
aggregationRawType() {
|
|
return this.fieldOptions[this.field.id]?.aggregation_raw_type
|
|
},
|
|
value() {
|
|
if (this.fieldAggregationData[this.field.id] !== undefined) {
|
|
const { value } = this.fieldAggregationData[this.field.id]
|
|
|
|
return this.viewAggregationType.getValue(value, {
|
|
rowCount: this.rowCount,
|
|
field: this.field,
|
|
fieldType: this.fieldType,
|
|
})
|
|
} else {
|
|
return undefined
|
|
}
|
|
},
|
|
loading() {
|
|
return this.fieldAggregationData[this.field.id]?.loading
|
|
},
|
|
viewAggregationType() {
|
|
if (!this.aggregationType) {
|
|
return null
|
|
}
|
|
return this.$registry.get('viewAggregation', this.aggregationType)
|
|
},
|
|
viewAggregationTypes() {
|
|
return this.$registry
|
|
.getOrderedList('viewAggregation')
|
|
.filter((agg) => agg.fieldIsCompatible(this.field))
|
|
},
|
|
fieldType() {
|
|
return this.$registry.get('field', this.field.type)
|
|
},
|
|
},
|
|
watch: {
|
|
aggregationRawType(value) {
|
|
if (!value) {
|
|
return
|
|
}
|
|
// If an update is already pending, we don't need this one.
|
|
if (!this.pendingValueUpdate) {
|
|
this.$store.dispatch(
|
|
this.storePrefix + 'view/grid/fetchAllFieldAggregationData',
|
|
{
|
|
view: this.view,
|
|
}
|
|
)
|
|
}
|
|
},
|
|
},
|
|
beforeCreate() {
|
|
this.$options.computed = {
|
|
...(this.$options.computed || {}),
|
|
...mapGetters({
|
|
fieldAggregationData:
|
|
this.$options.propsData.storePrefix +
|
|
'view/grid/getAllFieldAggregationData',
|
|
fieldOptions:
|
|
this.$options.propsData.storePrefix + 'view/grid/getAllFieldOptions',
|
|
rowCount: this.$options.propsData.storePrefix + 'view/grid/getCount',
|
|
}),
|
|
}
|
|
},
|
|
methods: {
|
|
async selectAggregation(newType) {
|
|
this.$refs.fieldContext.hide()
|
|
|
|
const values = {
|
|
aggregation_type: '',
|
|
aggregation_raw_type: '',
|
|
}
|
|
|
|
if (newType !== 'none') {
|
|
const selectedAggregation = this.$registry.get(
|
|
'viewAggregation',
|
|
newType
|
|
)
|
|
values.aggregation_type = newType
|
|
values.aggregation_raw_type = selectedAggregation.getRawType()
|
|
}
|
|
|
|
// Prevent the watcher to trigger while value is not yet saved on server
|
|
this.pendingValueUpdate = true
|
|
try {
|
|
await this.$store.dispatch(
|
|
this.storePrefix + 'view/grid/updateFieldOptionsOfField',
|
|
{
|
|
field: this.field,
|
|
values,
|
|
readOnly: !this.userCanMakeAggregations,
|
|
}
|
|
)
|
|
} finally {
|
|
this.pendingValueUpdate = false
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|