1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-25 00:46:46 +00:00
bramw_baserow/web-frontend/modules/database/store/view/fieldOptions.js

179 lines
5.3 KiB
JavaScript

import _ from 'lodash'
import { clone } from '@baserow/modules/core/utils/object'
import ViewService from '@baserow/modules/database/services/view'
/**
* This store mixin can in combination with a view, if it needs to store options per
* field. I noticed that we needed exactly the same code for the grid, gallery and
* form view, so it made sense to make something reusable.
*
* @TODO add this mixin to the other view stores. Currently it's only used by the
* gallery view.
*/
export default () => {
const state = () => ({
fieldOptions: {},
})
const mutations = {
REPLACE_ALL_FIELD_OPTIONS(state, fieldOptions) {
state.fieldOptions = fieldOptions
},
UPDATE_ALL_FIELD_OPTIONS(state, fieldOptions) {
state.fieldOptions = _.merge({}, state.fieldOptions, fieldOptions)
},
UPDATE_FIELD_OPTIONS_OF_FIELD(state, { fieldId, values }) {
if (Object.prototype.hasOwnProperty.call(state.fieldOptions, fieldId)) {
Object.assign(state.fieldOptions[fieldId], values)
} else {
state.fieldOptions = Object.assign({}, state.fieldOptions, {
[fieldId]: values,
})
}
},
DELETE_FIELD_OPTIONS(state, fieldId) {
if (Object.prototype.hasOwnProperty.call(state.fieldOptions, fieldId)) {
delete state.fieldOptions[fieldId]
}
},
}
const actions = {
/**
* Updates the field options of a given field and also makes an API request to the
* backend with the changed values. If the request fails the action is reverted.
*/
async updateFieldOptionsOfField(
{ commit, getters, rootGetters },
{
field,
values,
oldValues,
readOnly = false,
undoRedoActionGroupId = null,
}
) {
commit('UPDATE_FIELD_OPTIONS_OF_FIELD', {
fieldId: field.id,
values,
})
const viewId = getters.getViewId
if (!readOnly) {
const updateValues = { field_options: {} }
updateValues.field_options[field.id] = values
try {
await ViewService(this.$client).updateFieldOptions({
viewId,
values: updateValues,
undoRedoActionGroupId,
})
} catch (error) {
commit('UPDATE_FIELD_OPTIONS_OF_FIELD', {
fieldId: field.id,
values: oldValues,
})
throw error
}
}
},
/**
* Updates the field options of a given field in the store. So no API request to
* the backend is made.
*/
setFieldOptionsOfField({ commit }, { field, values }) {
commit('UPDATE_FIELD_OPTIONS_OF_FIELD', {
fieldId: field.id,
values,
})
},
/**
* Replaces all field options with new values and also makes an API request to the
* backend with the changed values. If the request fails the action is reverted.
*/
async updateAllFieldOptions(
{ dispatch, getters, rootGetters },
{ newFieldOptions, oldFieldOptions, readOnly = false }
) {
dispatch('forceUpdateAllFieldOptions', newFieldOptions)
const viewId = getters.getViewId
if (!readOnly) {
const updateValues = { field_options: newFieldOptions }
try {
await ViewService(this.$client).updateFieldOptions({
viewId,
values: updateValues,
})
} catch (error) {
dispatch('forceUpdateAllFieldOptions', oldFieldOptions)
throw error
}
}
},
/**
* Forcefully updates all field options without making a call to the backend.
*/
forceUpdateAllFieldOptions({ commit }, fieldOptions) {
commit('UPDATE_ALL_FIELD_OPTIONS', fieldOptions)
},
/**
* Updates the order of all the available field options. The provided order parameter
* should be an array containing the field ids in the correct order.
*/
async updateFieldOptionsOrder(
{ commit, getters, dispatch },
{ order, readOnly = false }
) {
const oldFieldOptions = clone(getters.getAllFieldOptions)
const newFieldOptions = clone(getters.getAllFieldOptions)
// Update the order of the field options that have not been provided in the order.
// They will get a position that places them after the provided field ids.
let i = 0
Object.keys(newFieldOptions).forEach((fieldId) => {
if (!order.includes(parseInt(fieldId))) {
newFieldOptions[fieldId].order = order.length + i
i++
}
})
// Update create the field options and set the correct order value.
order.forEach((fieldId, index) => {
const id = fieldId.toString()
if (Object.prototype.hasOwnProperty.call(newFieldOptions, id)) {
newFieldOptions[fieldId.toString()].order = index
}
})
return await dispatch('updateAllFieldOptions', {
oldFieldOptions,
newFieldOptions,
readOnly,
})
},
/**
* Deletes the field options of the provided field id if they exist.
*/
forceDeleteFieldOptions({ commit }, fieldId) {
commit('DELETE_FIELD_OPTIONS', fieldId)
},
}
const getters = {
getAllFieldOptions(state) {
return state.fieldOptions
},
}
return {
namespaced: true,
state,
getters,
actions,
mutations,
}
}