1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-03-15 04:54:50 +00:00

Resolve "Edit row when clicking on the card in the gallery view"

This commit is contained in:
Bram Wiepjes 2022-01-04 08:56:44 +00:00
parent ff8a0e3060
commit 3581250cb0
6 changed files with 136 additions and 11 deletions
web-frontend/modules
core/assets/scss/components/views
database

View file

@ -34,4 +34,14 @@
.gallery-view__card {
@include absolute(0, auto, auto, 0);
& * {
pointer-events: none;
user-select: none;
}
&:not(.card--loading):hover {
cursor: pointer;
box-shadow: 0 1px 3px 0 rgba($black, 0.32);
}
}

View file

@ -1,5 +1,11 @@
<template>
<div class="card" :class="{ 'card--loading': loading }" v-on="$listeners">
<div
class="card"
:class="{ 'card--loading': loading }"
@click="$emit('click', $event)"
@mousedown="$emit('mousedown', $event)"
@mousemove="$emit('mousemove', $event)"
>
<div v-for="field in fields" :key="field.id" class="card__field">
<div class="card__field-name">{{ field.name }}</div>
<div class="card__field-value">

View file

@ -112,7 +112,7 @@ export default {
* switch to that version to maintain reactivity between the two.
*/
rows(value) {
const row = value.find((r) => r.id === this.rowId)
const row = value.find((r) => r !== null && r.id === this.rowId)
if (row === undefined && this.rowExists) {
this.$store.dispatch('rowModal/doesNotExist')
} else if (row !== undefined && !this.rowExists) {
@ -122,7 +122,7 @@ export default {
},
methods: {
show(rowId, ...args) {
const row = this.rows.find((r) => r.id === rowId)
const row = this.rows.find((r) => r !== null && r.id === rowId)
this.$store.dispatch('rowModal/open', {
id: rowId,
row: row || {},

View file

@ -16,20 +16,20 @@
>
<RowCard
v-for="slot in buffer"
v-show="slot.position !== undefined"
v-show="slot.item !== undefined"
:key="'card-' + slot.id"
:fields="cardFields"
:row="slot.item === null || slot.item === undefined ? {} : slot.item"
:row="slot.item || {}"
:loading="slot.item === null"
class="gallery-view__card"
:style="{
width: cardWidth + 'px',
height: slot.item === null ? cardHeight + 'px' : undefined,
transform:
slot.position !== undefined
? `translateX(${slot.position.left}px) translateY(${slot.position.top}px)`
: false,
transform: `translateX(${slot.position.left || 0}px) translateY(${
slot.position.top || 0
}px)`,
}"
@click="slot.item && $refs.rowEditModal.show(slot.item.id)"
></RowCard>
</div>
</div>
@ -43,6 +43,17 @@
@field-updated="$emit('refresh', $event)"
@field-deleted="$emit('refresh')"
></RowCreateModal>
<RowEditModal
ref="rowEditModal"
:table="table"
:fields="fields"
:primary="primary"
:rows="allRows"
:read-only="false"
@update="updateValue"
@field-updated="$emit('refresh', $event)"
@field-deleted="$emit('refresh')"
></RowEditModal>
</div>
</template>
@ -59,10 +70,12 @@ import {
import { maxPossibleOrderValue } from '@baserow/modules/database/viewTypes'
import RowCard from '@baserow/modules/database/components/card/RowCard'
import RowCreateModal from '@baserow/modules/database/components/row/RowCreateModal'
import RowEditModal from '@baserow/modules/database/components/row/RowEditModal'
import { notifyIf } from '@baserow/modules/core/utils/error'
export default {
name: 'GalleryView',
components: { RowCard, RowCreateModal },
components: { RowCard, RowCreateModal, RowEditModal },
props: {
primary: {
type: Object,
@ -327,6 +340,25 @@ export default {
callback(error)
}
},
async updateValue({ field, row, value, oldValue }) {
try {
await this.$store.dispatch(
this.storePrefix + 'view/gallery/updateRowValue',
{
table: this.table,
view: this.view,
fields: this.fields,
primary: this.primary,
row,
field,
value,
oldValue,
}
)
} catch (error) {
notifyIf(error, 'field')
}
},
},
}
</script>

View file

@ -169,6 +169,14 @@ export default ({ service, populateRow }) => {
MOVE_ROW(state, { oldIndex, newIndex }) {
state.rows.splice(newIndex, 0, state.rows.splice(oldIndex, 1)[0])
},
UPDATE_ROW(state, { row, values }) {
const index = state.rows.findIndex(
(item) => item !== null && item.id === row.id
)
if (index !== -1) {
Object.assign(state.rows[index], values)
}
},
UPDATE_ROW_AT_INDEX(state, { index, values }) {
Object.assign(state.rows[index], values)
},
@ -570,6 +578,71 @@ export default ({ service, populateRow }) => {
commit('INSERT_ROW_AT_INDEX', { index, row })
},
/**
* Updates the value of a row and make the updates to the store accordingly.
*/
async updateRowValue(
{ commit, dispatch },
{ table, view, row, field, fields, primary, value, oldValue }
) {
const fieldType = this.$registry.get('field', field._.type.type)
const allFields = [primary].concat(fields)
const newValues = {}
const newValuesForUpdate = {}
const oldValues = {}
const fieldName = `field_${field.id}`
newValues[fieldName] = value
newValuesForUpdate[fieldName] = fieldType.prepareValueForUpdate(
field,
value
)
oldValues[fieldName] = oldValue
allFields.forEach((fieldToCall) => {
const fieldType = this.$registry.get('field', fieldToCall._.type.type)
const fieldToCallName = `field_${fieldToCall.id}`
const currentFieldValue = row[fieldToCallName]
const optimisticFieldValue = fieldType.onRowChange(
row,
field,
value,
oldValue,
fieldToCall,
currentFieldValue
)
if (currentFieldValue !== optimisticFieldValue) {
newValues[fieldToCallName] = optimisticFieldValue
oldValues[fieldToCallName] = currentFieldValue
}
})
await dispatch('afterExistingRowUpdated', {
view,
fields,
primary,
row,
values: newValues,
})
try {
const { data } = await RowService(this.$client).update(
table.id,
row.id,
newValuesForUpdate
)
commit('UPDATE_ROW', { row, values: data })
} catch (error) {
dispatch('updatedExistingRow', {
view,
fields,
primary,
row,
values: oldValues,
})
throw error
}
},
/**
* When an existing row is updated, the state in the store must also be updated.
* Because we always receive the old and new state we can calculate if the row

View file

@ -103,7 +103,11 @@ export const recycleSlots = (slots, items, getPosition, min = items.length) => {
}
const slotPosition = getPosition(item, position)
Object.assign(slots[index].position, slotPosition)
if (
JSON.stringify(slotPosition) !== JSON.stringify(slots[index].position)
) {
slots[index].position = slotPosition
}
})
// The remaining empty slots must be cleared because they could contain old items.