1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-05-17 22:32:02 +00:00
bramw_baserow/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

334 lines
8.9 KiB
Vue
Raw Normal View History

2024-12-25 08:40:24 +00:00
<template>
<form @submit.prevent>
<FormSection
:title="$t('aggregateRowsDataSourceForm.data')"
class="margin-bottom-2"
>
<FormGroup
:label="$t('aggregateRowsDataSourceForm.sourceFieldLabel')"
class="margin-bottom-2"
small-label
required
horizontal
horizontal-narrow
>
<Dropdown
2025-04-23 08:50:10 +02:00
v-model="computedTableId"
2024-12-25 08:40:24 +00:00
:show-search="true"
fixed-items
:error="fieldHasErrors('table_id')"
>
<DropdownSection
v-for="database in databases"
:key="database.id"
:title="`${database.name} (${database.id})`"
>
<DropdownItem
v-for="table in database.tables"
:key="table.id"
:name="table.name"
:value="table.id"
:indented="true"
>
{{ table.name }}
</DropdownItem>
</DropdownSection>
</Dropdown>
</FormGroup>
<FormGroup
v-if="values.table_id && !fieldHasErrors('table_id')"
:label="$t('aggregateRowsDataSourceForm.viewFieldLabel')"
class="margin-bottom-2"
small-label
required
horizontal
horizontal-narrow
>
<Dropdown
2025-04-23 08:50:10 +02:00
v-model="v$.values.view_id.$model"
2024-12-25 08:40:24 +00:00
:show-search="false"
fixed-items
:disabled="fieldsLoading"
2024-12-25 08:40:24 +00:00
:error="fieldHasErrors('view_id')"
>
<DropdownItem
:name="$t('aggregateRowsDataSourceForm.notSelected')"
:value="null"
>{{ $t('aggregateRowsDataSourceForm.notSelected') }}</DropdownItem
>
<DropdownItem
v-for="view in tableViews"
:key="view.id"
:name="view.name"
:value="view.id"
>
{{ view.name }}
</DropdownItem>
</Dropdown>
</FormGroup>
<FormGroup
v-if="values.table_id && !fieldHasErrors('table_id')"
class="margin-bottom-2"
small-label
:label="$t('aggregateRowsDataSourceForm.aggregationFieldLabel')"
required
horizontal
horizontal-narrow
>
<Dropdown
2025-04-23 08:50:10 +02:00
v-model="v$.values.field_id.$model"
:disabled="tableFields.length === 0 || fieldsLoading"
2024-12-25 08:40:24 +00:00
:error="fieldHasErrors('field_id')"
>
<DropdownItem
v-for="field in tableFields"
:key="field.id"
:name="field.name"
:value="field.id"
:icon="fieldIconClass(field)"
>
</DropdownItem>
</Dropdown>
</FormGroup>
<FormGroup
v-if="!fieldHasErrors('field_id')"
small-label
:label="$t('aggregateRowsDataSourceForm.aggregationTypeLabel')"
required
horizontal
horizontal-narrow
>
<Dropdown
2025-04-23 08:50:10 +02:00
v-model="v$.values.aggregation_type.$model"
2024-12-25 08:40:24 +00:00
:error="fieldHasErrors('aggregation_type')"
:disabled="fieldsLoading"
2024-12-25 08:40:24 +00:00
>
<DropdownItem
v-for="viewAggregation in viewAggregationTypes"
:key="viewAggregation.getType()"
:name="viewAggregation.getName()"
:value="viewAggregation.getType()"
:disabled="
unsupportedAggregationTypes.includes(viewAggregation.getType())
"
2024-12-25 08:40:24 +00:00
>
</DropdownItem>
</Dropdown>
</FormGroup>
</FormSection>
</form>
</template>
<script>
2025-02-17 13:17:35 +00:00
import { useVuelidate } from '@vuelidate/core'
2024-12-25 08:40:24 +00:00
import form from '@baserow/modules/core/mixins/form'
2025-02-17 13:17:35 +00:00
import { required } from '@vuelidate/validators'
import tableFields from '@baserow/modules/database/mixins/tableFields'
2024-12-25 08:40:24 +00:00
const includes = (array) => (value) => {
return array.includes(value)
}
const includesIfSet = (array) => (value) => {
if (value === null || value === undefined) {
return true
}
return array.includes(value)
}
export default {
name: 'AggregateRowsDataSourceForm',
mixins: [form, tableFields],
2024-12-25 08:40:24 +00:00
props: {
dashboard: {
type: Object,
required: true,
},
widget: {
type: Object,
required: true,
},
dataSource: {
type: Object,
required: true,
},
storePrefix: {
type: String,
required: false,
default: '',
},
2024-12-25 08:40:24 +00:00
},
2025-02-17 13:17:35 +00:00
setup() {
return { v$: useVuelidate({ $lazy: true }) }
},
2024-12-25 08:40:24 +00:00
data() {
return {
allowedValues: ['table_id', 'view_id', 'field_id', 'aggregation_type'],
values: {
table_id: null,
view_id: null,
field_id: null,
aggregation_type: 'sum',
},
tableLoading: false,
skipFirstValuesEmit: true,
2025-04-23 08:50:10 +02:00
tableIdHasChanged: false,
2024-12-25 08:40:24 +00:00
}
},
computed: {
2025-04-23 08:50:10 +02:00
computedTableId: {
get() {
return this.v$.values.table_id.$model
},
set(tableId) {
if (tableId !== this.v$.values.table_id.$model) {
this.v$.values.table_id.$model = tableId
this.tableIdHasChanged = true
this.v$.values.view_id.$model = null
this.v$.values.field_id.$model = null
}
},
},
2024-12-25 08:40:24 +00:00
integration() {
return this.$store.getters[
`${this.storePrefix}dashboardApplication/getIntegrationById`
](this.dataSource.integration_id)
2024-12-25 08:40:24 +00:00
},
databases() {
return this.integration.context_data.databases
},
databaseSelected() {
2025-04-23 08:50:10 +02:00
return this.databases.find((database) =>
database.tables.some((table) => table.id === this.values.table_id)
2024-12-25 08:40:24 +00:00
)
},
tables() {
return this.databases.map((database) => database.tables).flat()
},
tableIds() {
return this.tables.map((table) => table.id)
},
tableSelected() {
return this.tables.find(({ id }) => id === this.values.table_id)
},
tableFieldIds() {
return this.tableFields.map((field) => field.id)
},
tableViews() {
return (
this.databaseSelected?.views.filter(
(view) => view.table_id === this.values.table_id
) || []
)
},
tableViewIds() {
return this.tableViews.map((view) => view.id)
},
viewAggregationTypes() {
const selectedField = this.tableFields.find(
(field) => field.id === this.values.field_id
)
if (!selectedField) return []
return this.$registry
.getOrderedList('viewAggregation')
.filter((agg) => agg.fieldIsCompatible(selectedField))
},
aggregationTypeNames() {
return this.viewAggregationTypes.map((aggType) => aggType.getType())
},
unsupportedAggregationTypes() {
return this.$registry.get('service', 'local_baserow_aggregate_rows')
.unsupportedAggregationTypes
},
2024-12-25 08:40:24 +00:00
},
watch: {
dataSource: {
async handler(values) {
this.setEmitValues(false)
2024-12-25 08:40:24 +00:00
// Reset the form to set default values
// again after a different widget is selected
await this.reset(true)
2024-12-25 08:40:24 +00:00
// Run form validation so that
// problems are highlighted immediately
this.v$.$touch()
await this.$nextTick()
this.setEmitValues(true)
2024-12-25 08:40:24 +00:00
},
2025-01-16 09:17:35 +00:00
deep: true,
2024-12-25 08:40:24 +00:00
},
2025-04-23 08:50:10 +02:00
fieldsLoading(loading) {
if (this.tableIdHasChanged && !loading) {
if (this.tableFields.length > 0) {
this.v$.values.field_id.$model = this.tableFields[0].id
2024-12-25 08:40:24 +00:00
}
2025-04-23 08:50:10 +02:00
this.tableIdHasChanged = false
}
2024-12-25 08:40:24 +00:00
},
'values.field_id': {
handler(fieldId) {
if (fieldId !== null) {
if (
!this.viewAggregationTypes.some(
2025-04-23 08:50:10 +02:00
(agg) => agg.getType() === this.v$.values.aggregation_type.$model
2024-12-25 08:40:24 +00:00
)
) {
if (this.viewAggregationTypes.length > 0) {
2025-04-23 08:50:10 +02:00
this.v$.values.aggregation_type.$model =
2024-12-25 08:40:24 +00:00
this.viewAggregationTypes[0].getType()
}
}
}
},
immediate: false,
},
},
2025-02-18 09:04:44 +01:00
mounted() {
this.v$.$validate()
},
2024-12-25 08:40:24 +00:00
validations() {
2025-02-17 13:17:35 +00:00
const self = this
2024-12-25 08:40:24 +00:00
return {
values: {
2025-02-17 13:17:35 +00:00
table_id: {
required,
isValidTableId: (value) => {
const ids = self.tableIds
return includes(ids)(value)
},
},
view_id: {
isValidViewId: (value) => {
const ids = self.tableViewIds
return includesIfSet(ids)(value)
},
},
field_id: {
required,
isValidFieldId: (value) => {
const ids = self.tableFieldIds
return includes(ids)(value)
},
},
2024-12-25 08:40:24 +00:00
aggregation_type: {
required,
2025-02-17 13:17:35 +00:00
isValidAggregationType: (value) => {
const types = self.aggregationTypeNames
return includes(types)(value)
},
2024-12-25 08:40:24 +00:00
},
},
}
},
methods: {
/* Overrides the method in the tableFields mixin */
getTableId() {
return this.values.table_id
},
2024-12-25 08:40:24 +00:00
fieldIconClass(field) {
const fieldType = this.$registry.get('field', field.type)
return fieldType.iconClass
},
},
}
</script>