1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-24 16:36:46 +00:00
bramw_baserow/web-frontend/modules/builder/mixins/collectionElementForm.js
2024-11-07 11:09:56 +00:00

176 lines
6.6 KiB
JavaScript

import { mapGetters } from 'vuex'
import applicationContextMixin from '@baserow/modules/builder/mixins/applicationContext'
import { CurrentRecordDataProviderType } from '@baserow/modules/builder/dataProviderTypes'
export default {
mixins: [applicationContextMixin],
computed: {
/**
* Returns the schema which the service schema property selector
* will use when listing the available properties. If the collection
* element is not nested, we'll use the selected data source's schema,
* otherwise if it's nested, we use the current record's data schema.
* @returns {Object} - The schema to use.
*/
propertySelectorSchema() {
return this.$registry
.get('builderDataProvider', CurrentRecordDataProviderType.getType())
.getDataSchema({
...this.applicationContext,
/**
* We want to use the data_source_id of this element...
*/
allowSameElement: true,
/**
* but, we don't want to use the schema property of this element as we are
* defining it.
*/
followSameElementSchemaProperties: false,
})
},
/**
* A convenience computed method which returns if this element has
* a collection ancestor. This influences a few things, such as whether
* the schema property selector is available, or whether the data source
* dropdown is available.
* @returns {boolean} - Whether the element has a collection ancestor.
*/
hasCollectionAncestor() {
const { element } = this.applicationContext
const elementType = this.$registry.get('element', element.type)
return elementType.hasCollectionAncestor(this.page, element)
},
/**
* In collection element forms, the ability to configure property options
* (e.g. allowing properties to be filterable, sortable and/or searchable)
* is dependent on whether the selected data source returns a list, and if
* the feature flag is enabled.
* @returns {boolean} - Whether the property options are available.
*/
propertyOptionsAvailable() {
return this.selectedDataSource && this.selectedDataSourceReturnsList
},
/**
* In collection element forms, the ability to view paging options
* (e.g. items per page, or styling the load more button) is dependent
* on whether the selected data source returns a list. When a single row
* data source is used, we use all of its records to iterate with, so no
* paging options are available.
* @returns {boolean} - Whether the paging options are available.
*/
pagingOptionsAvailable() {
return this.selectedDataSourceReturnsList
},
/**
* In collection element forms, the ability to choose a data source
* is dependent on whether the element has a collection ancestor. If
* it's a root-level collection element, designers can choose one,
* otherwise only schema properties can be chosen.
* @returns {boolean} - Whether the data source dropdown is available.
*/
dataSourceDropdownAvailable() {
return !this.hasCollectionAncestor
},
/**
* - If the collection element is a root element:
* - If a non-list-type data source is selected:
* - Designer MUST then choose a SchemaPropertySelector to use
* - If a list-type data source is selected:
* - The SchemaPropertySelector is hidden and no longer usable.
* - If the collection element is nested:
* - The data source Dropdown component is hidden and no longer usable.
* - The SchemaPropertySelector can choose a single property from the current_record schema.
* @returns {boolean}
*/
propertySelectorAvailable() {
if (!this.hasCollectionAncestor) {
// If we don't have a data source, or
// We do, and it returns a list, then the schema selector isn't available.
if (!this.selectedDataSource || this.selectedDataSourceReturnsList) {
return false
}
}
return true
},
sharedPage() {
return this.$store.getters['page/getSharedPage'](this.builder)
},
/**
* Returns all data sources that are available to the current page.
* The data source will need a `type` and a valid schema.
* @returns {Array} - The data sources the page designer can choose from.
*/
dataSources() {
const pages = [this.sharedPage, this.page]
return this.$store.getters['dataSource/getPagesDataSources'](
pages
).filter((dataSource) => {
const serviceType =
dataSource.type && this.$registry.get('service', dataSource.type)
return serviceType?.getDataSchema(dataSource)
})
},
selectedDataSource() {
if (!this.values.data_source_id) {
return null
}
const pages = [this.sharedPage, this.page]
return this.$store.getters['dataSource/getPagesDataSourceById'](
pages,
this.values.data_source_id
)
},
selectedDataSourceType() {
if (!this.selectedDataSource || !this.selectedDataSource.type) {
return null
}
return this.$registry.get('service', this.selectedDataSource.type)
},
selectedDataSourceReturnsList() {
return this.selectedDataSourceType?.returnsList
},
maxItemPerPage() {
if (!this.selectedDataSourceType) {
return 20
}
return this.selectedDataSourceType.maxResultLimit
},
elementHasContent() {
const { element } = this.applicationContext
return this.$store.getters['elementContent/getElementContent'](element)
},
...mapGetters({
element: 'element/getSelected',
}),
},
watch: {
/**
* When the data source is changed, we need to reset the schema property
*/
'values.data_source_id'(newValue, oldValue) {
if (oldValue && newValue !== oldValue) {
this.values.schema_property = null
}
},
/**
* When the array of data sources available to this page changes, ensure
* that the selected data source is still available. If it's not, reset
* the `data_source_id` to null`.
*/
'dataSources.length'(newValue, oldValue) {
if (this.values.data_source_id && oldValue > newValue) {
if (
!this.dataSources.some(({ id }) => id === this.values.data_source_id)
) {
// Remove the data_source_id if the related dataSource has been deleted.
this.values.data_source_id = null
// And delete element content (not handled by the element event)
this.$store.dispatch('elementContent/clearElementContent', {
element: this.element,
})
}
}
},
},
}