<template> <form @submit.prevent> <LocalBaserowServiceForm :enable-row-id="enableRowId" :default-values="defaultValues" @table-changed="handleTableChange" @values-changed="emitServiceChange($event)" ></LocalBaserowServiceForm> <div v-if="tableLoading" class="loading margin-bottom-1"></div> <p v-if="values.integration_id && !values.table_id"> {{ $t('upsertRowWorkflowActionForm.noTableSelectedMessage') }} </p> <FieldMappingForm v-if="!tableLoading" v-model="values.field_mappings" :fields="getWritableSchemaFields" ></FieldMappingForm> </form> </template> <script> import _ from 'lodash' import FieldMappingForm from '@baserow/modules/integrations/localBaserow/components/services/FieldMappingForm' import form from '@baserow/modules/core/mixins/form' import LocalBaserowServiceForm from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowServiceForm' export default { name: 'LocalBaserowUpsertRowServiceForm', components: { LocalBaserowServiceForm, FieldMappingForm, }, mixins: [form], props: { workflowAction: { type: Object, required: false, default: null, }, enableRowId: { type: Boolean, required: false, default: false, }, }, data() { return { allowedValues: ['field_mappings'], values: { field_mappings: [], }, state: null, tableLoading: false, } }, computed: { /** * Returns the loading state of the workflow action. Used to * determine whether to show the loading spinner in the water. */ workflowActionLoading() { return this.$store.getters['workflowAction/getLoading']( this.workflowAction ) }, /** * Returns the writable fields in the schema, which the * `FieldMappingForm` can use to display the field mapping options. */ getWritableSchemaFields() { if ( this.workflowAction.service == null || this.workflowAction.service.schema == null // have service, no table ) { return [] } const schema = this.workflowAction.service.schema const schemaProperties = schema.type === 'array' ? schema.items.properties : schema.properties return Object.values(schemaProperties) .filter(({ metadata }) => metadata && !metadata.read_only) .map((prop) => prop.metadata) }, }, watch: { workflowActionLoading: { handler(value) { if (!value) { this.tableLoading = false } }, }, }, methods: { /** * When `LocalBaserowServiceForm` informs us that the table * has changed, we'll flag our `tableLoading` boolean as true. * We want to display a loading spinner between the `table_id` * changing, and the `field_mappings` being loaded. */ handleTableChange(newValue) { this.tableLoading = true }, /** * When `LocalBaserowServiceForm` informs us that service specific * values have changed, we want to determine what has changed and * emit the new values to the parent component. */ emitServiceChange(newValues) { if (this.isFormValid()) { const updated = { ...this.defaultValues, ...newValues } const differences = Object.fromEntries( Object.entries(updated).filter( ([key, value]) => !_.isEqual(value, this.defaultValues[key]) ) ) // If the `table_id` has changed, we'll reset the `field_mappings` // to an empty array. We update both the values and the differences // for different reasons: the former so that a subsequent change don't // stack up, and the latter so that the HTTP request which is triggered // due to the changes in `differences` don't include the old field mappings. if (differences.table_id) { this.values.field_mappings = [] differences.field_mappings = [] } this.$emit('values-changed', differences) } }, }, } </script>