1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-11 07:51:20 +00:00

Merge branch '2822-implement-the-frontend-for-a-local-baserow-delete-row-action' into 'develop'

Resolve "Implement the frontend for a local Baserow delete row action"

Closes 

See merge request 
This commit is contained in:
Peter Evans 2024-07-24 16:24:30 +00:00
commit 6672298f1c
9 changed files with 249 additions and 112 deletions

View file

@ -0,0 +1,7 @@
{
"type": "feature",
"message": "[Builder] Introduce the 'delete row' workflow action",
"issue_number": 2822,
"bullet_points": [],
"created_at": "2024-07-19"
}

View file

@ -2,8 +2,7 @@
<UpsertRowWorkflowActionForm
:workflow-action="workflowAction"
:default-values="defaultValues.service"
:application="builder"
@values-changed="mutateService($event)"
@values-changed="values.service = { ...workflowAction.service, ...$event }"
>
</UpsertRowWorkflowActionForm>
</template>
@ -11,13 +10,11 @@
<script>
import UpsertRowWorkflowActionForm from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowUpsertRowServiceForm'
import form from '@baserow/modules/core/mixins/form'
import _ from 'lodash'
export default {
name: 'CreateRowWorkflowAction',
components: { UpsertRowWorkflowActionForm },
mixins: [form],
inject: ['builder'],
props: {
workflowAction: {
type: Object,
@ -33,12 +30,5 @@ export default {
},
}
},
methods: {
mutateService(newValues) {
if (!_.isMatch(this.workflowAction.service, newValues)) {
this.values.service = { ...this.workflowAction.service, ...newValues }
}
},
},
}
</script>

View file

@ -0,0 +1,40 @@
<template>
<form @submit.prevent>
<LocalBaserowServiceForm
enable-row-id
:default-values="defaultValues.service"
@values-changed="
values.service = { ...workflowAction.service, ...$event }
"
></LocalBaserowServiceForm>
</form>
</template>
<script>
import form from '@baserow/modules/core/mixins/form'
import LocalBaserowServiceForm from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowServiceForm'
export default {
name: 'DeleteRowWorkflowActionForm',
components: {
LocalBaserowServiceForm,
},
mixins: [form],
inject: ['builder'],
props: {
workflowAction: {
type: Object,
required: false,
default: null,
},
},
data() {
return {
allowedValues: ['service'],
values: {
service: {},
},
}
},
}
</script>

View file

@ -3,8 +3,7 @@
enable-row-id
:workflow-action="workflowAction"
:default-values="defaultValues.service"
:application="builder"
@values-changed="mutateService($event)"
@values-changed="values.service = { ...workflowAction.service, ...$event }"
>
</UpsertRowWorkflowActionForm>
</template>
@ -12,13 +11,11 @@
<script>
import UpsertRowWorkflowActionForm from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowUpsertRowServiceForm.vue'
import form from '@baserow/modules/core/mixins/form'
import _ from 'lodash'
export default {
name: 'UpdateRowWorkflowAction',
components: { UpsertRowWorkflowActionForm },
mixins: [form],
inject: ['builder'],
props: {
workflowAction: {
type: Object,
@ -34,12 +31,5 @@ export default {
},
}
},
methods: {
mutateService(newValues) {
if (!_.isMatch(this.workflowAction.service, newValues)) {
this.values.service = { ...this.workflowAction.service, ...newValues }
}
},
},
}
</script>

View file

@ -534,6 +534,7 @@
"openPageLabel": "Open Page",
"createRowLabel": "Create Row",
"updateRowLabel": "Update Row",
"deleteRowLabel": "Delete Row",
"logoutLabel": "Logout",
"refreshDataSourceLabel": "Refresh data source"
},
@ -615,10 +616,12 @@
"defaultTitle": "Data loading error",
"defaultMessage": "An error occurred while loading data for the page."
},
"upsertRowWorkflowActionForm": {
"localBaserowServiceForm": {
"integrationDropdownLabel": "Integration",
"rowIdLabel": "Row ID",
"rowIdPlaceholder": "Select a row ID",
"rowIdPlaceholder": "Select a row ID"
},
"upsertRowWorkflowActionForm": {
"fieldMappingPlaceholder": "Choose a field value",
"noTableSelectedMessage": "Choose a table to begin configuring your fields."
},

View file

@ -101,6 +101,7 @@ import {
UpdateRowWorkflowActionType,
LogoutWorkflowActionType,
RefreshDataSourceWorkflowActionType,
DeleteRowWorkflowActionType,
} from '@baserow/modules/builder/workflowActionTypes'
import {
@ -321,6 +322,10 @@ export default (context) => {
'workflowAction',
new UpdateRowWorkflowActionType(context)
)
app.$registry.register(
'workflowAction',
new DeleteRowWorkflowActionType(context)
)
app.$registry.register(
'collectionField',

View file

@ -8,6 +8,7 @@ import UpdateRowWorkflowActionForm from '@baserow/modules/builder/components/wor
import { DataProviderType } from '@baserow/modules/core/dataProviderTypes'
import resolveElementUrl from '@baserow/modules/builder/utils/urlResolution'
import { ensureString } from '@baserow/modules/core/utils/validator'
import DeleteRowWorkflowActionForm from '@baserow/modules/builder/components/workflowAction/DeleteRowWorkflowActionForm.vue'
export class NotificationWorkflowActionType extends WorkflowActionType {
static getType() {
@ -198,3 +199,17 @@ export class UpdateRowWorkflowActionType extends WorkflowActionServiceType {
return this.app.i18n.t('workflowActionTypes.updateRowLabel')
}
}
export class DeleteRowWorkflowActionType extends WorkflowActionServiceType {
static getType() {
return 'delete_row'
}
get form() {
return DeleteRowWorkflowActionForm
}
get label() {
return this.app.i18n.t('workflowActionTypes.deleteRowLabel')
}
}

View file

@ -0,0 +1,119 @@
<template>
<form @submit.prevent>
<FormGroup
:label="$t('localBaserowServiceForm.integrationDropdownLabel')"
small-label
required
class="margin-bottom-2"
>
<IntegrationDropdown
v-model="values.integration_id"
:application="builder"
:integrations="integrations"
:integration-type="integrationType"
/>
</FormGroup>
<LocalBaserowTableSelector
v-if="selectedIntegration"
v-model="fakeTableId"
:databases="databases"
:display-view-dropdown="false"
/>
<FormGroup
v-if="enableRowId && values.integration_id"
small-label
:label="$t('localBaserowServiceForm.rowIdLabel')"
class="margin-bottom-2"
required
>
<InjectedFormulaInput
v-model="values.row_id"
:disabled="values.table_id === null"
:placeholder="$t('localBaserowServiceForm.rowIdPlaceholder')"
/>
</FormGroup>
</form>
</template>
<script>
import LocalBaserowTableSelector from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowTableSelector'
import { LocalBaserowIntegrationType } from '@baserow/modules/integrations/integrationTypes'
import InjectedFormulaInput from '@baserow/modules/core/components/formula/InjectedFormulaInput'
import IntegrationDropdown from '@baserow/modules/core/components/integrations/IntegrationDropdown'
import form from '@baserow/modules/core/mixins/form'
/**
* The purpose of this component is to reuse the concept of a "Local Baserow service form"
* across our Local Baserow workflow action forms. Upsert (used by Create and Update)
* and Delete need to be able to manage the integration, table, and optional row ID.
* Rather than duplicate the form a few times, this component keeps things tidier.
*/
export default {
name: 'LocalBaserowServiceForm',
components: {
IntegrationDropdown,
LocalBaserowTableSelector,
InjectedFormulaInput,
},
mixins: [form],
inject: ['builder'],
props: {
enableRowId: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
allowedValues: ['row_id', 'table_id', 'integration_id'],
values: {
row_id: '',
table_id: null,
integration_id: null,
},
}
},
computed: {
integrations() {
return this.$store.getters['integration/getIntegrations'](this.builder)
},
fakeTableId: {
get() {
return this.values.table_id
},
set(newValue) {
this.values.table_id = newValue
// Emit that the table changed so that the parent
// component can optionally do something with it,
// e.g. showing a loading spinner.
this.$emit('table-changed', newValue)
},
},
integrationType() {
return this.$registry.get(
'integration',
LocalBaserowIntegrationType.getType()
)
},
selectedIntegration() {
return this.$store.getters['integration/getIntegrationById'](
this.builder,
this.values.integration_id
)
},
databases() {
return this.selectedIntegration?.context_data.databases || []
},
},
watch: {
'values.table_id': {
handler(newValue, oldValue) {
if (oldValue && newValue !== oldValue) {
this.values.row_id = ''
}
},
},
},
}
</script>

View file

@ -1,41 +1,15 @@
<template>
<form @submit.prevent>
<FormGroup
:label="$t('upsertRowWorkflowActionForm.integrationDropdownLabel')"
small-label
required
class="margin-bottom-2"
>
<IntegrationDropdown
v-model="values.integration_id"
:application="application"
:integrations="integrations"
:integration-type="integrationType"
/>
</FormGroup>
<LocalBaserowTableSelector
v-if="selectedIntegration"
v-model="fakeTableId"
:databases="databases"
:display-view-dropdown="false"
/>
<FormGroup
v-if="enableRowId && values.integration_id"
small-label
:label="$t('upsertRowWorkflowActionForm.rowIdLabel')"
class="margin-bottom-2"
required
>
<InjectedFormulaInput
v-model="values.row_id"
:placeholder="$t('upsertRowWorkflowActionForm.rowIdPlaceholder')"
/>
</FormGroup>
<p v-if="selectedIntegration && !values.table_id">
<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>
<div v-if="tableLoading" class="loading margin-bottom-1"></div>
<FieldMappingForm
v-if="!tableLoading"
v-model="values.field_mappings"
@ -45,28 +19,19 @@
</template>
<script>
import LocalBaserowTableSelector from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowTableSelector'
import { LocalBaserowIntegrationType } from '@baserow/modules/integrations/integrationTypes'
import _ from 'lodash'
import FieldMappingForm from '@baserow/modules/integrations/localBaserow/components/services/FieldMappingForm'
import InjectedFormulaInput from '@baserow/modules/core/components/formula/InjectedFormulaInput'
import IntegrationDropdown from '@baserow/modules/core/components/integrations/IntegrationDropdown'
import form from '@baserow/modules/core/mixins/form'
import LocalBaserowServiceForm from '@baserow/modules/integrations/localBaserow/components/services/LocalBaserowServiceForm'
export default {
name: 'LocalBaserowUpsertRowServiceForm',
components: {
IntegrationDropdown,
LocalBaserowServiceForm,
FieldMappingForm,
LocalBaserowTableSelector,
InjectedFormulaInput,
},
mixins: [form],
props: {
application: {
type: Object,
required: true,
},
workflowAction: {
type: Object,
required: false,
@ -80,61 +45,28 @@ export default {
},
data() {
return {
allowedValues: ['row_id', 'table_id', 'integration_id', 'field_mappings'],
allowedValues: ['field_mappings'],
values: {
row_id: '',
table_id: null,
field_mappings: [],
integration_id: null,
},
state: null,
tableLoading: false,
}
},
computed: {
integrations() {
return this.$store.getters['integration/getIntegrations'](
this.application
)
},
/**
* 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
)
},
fakeTableId: {
get() {
return this.values.table_id
},
set(newValue) {
// If we currently have a `table_id` selected, and the `newValue`
// is different to the current `table_id`, then reset the
// `field_mappings` to a blank array.
if (this.values.table_id !== newValue) {
this.tableLoading = true
if (this.values.table_id) {
this.values.field_mappings = []
}
}
this.values.table_id = newValue
},
},
integrationType() {
return this.$registry.get(
'integration',
LocalBaserowIntegrationType.getType()
)
},
selectedIntegration() {
return this.$store.getters['integration/getIntegrationById'](
this.application,
this.values.integration_id
)
},
databases() {
return this.selectedIntegration?.context_data.databases || []
},
/**
* Returns the writable fields in the schema, which the
* `FieldMappingForm` can use to display the field mapping options.
*/
getWritableSchemaFields() {
if (
this.workflowAction.service == null ||
@ -159,5 +91,41 @@ export default {
},
},
},
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>