mirror of
https://github.com/directus/directus.git
synced 2026-01-25 23:48:58 -05:00
Prevent racing condition in fast subsequent field reorders
This commit is contained in:
@@ -8,6 +8,7 @@ import notify from '@/utils/notify';
|
||||
import { useRelationsStore } from '@/stores/';
|
||||
import { Relation, FieldRaw, Field } from '@/types';
|
||||
import { merge } from 'lodash';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
const fakeFilesField: Field = {
|
||||
collection: 'directus_files',
|
||||
@@ -36,6 +37,15 @@ const fakeFilesField: Field = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @NOTE
|
||||
* This keeps track of what update is the last one that's in progress. After every update, the store
|
||||
* gets flushed with the updated values, which means that you can have racing conditions if you do
|
||||
* multiple updates at the same time. By keeping track which one is the last one that's fired, we
|
||||
* can ensure that only the last update gets used to flush the store with.
|
||||
*/
|
||||
let currentUpdate: string;
|
||||
|
||||
export const useFieldsStore = createStore({
|
||||
id: 'fieldsStore',
|
||||
state: () => ({
|
||||
@@ -165,8 +175,11 @@ export const useFieldsStore = createStore({
|
||||
}
|
||||
},
|
||||
async updateFields(collectionKey: string, updates: Partial<Field>[]) {
|
||||
const updateID = nanoid();
|
||||
const stateClone = [...this.state.fields];
|
||||
|
||||
currentUpdate = updateID;
|
||||
|
||||
// Update locally first, so the changes are visible immediately
|
||||
this.state.fields = this.state.fields.map((field) => {
|
||||
if (field.collection === collectionKey) {
|
||||
@@ -185,16 +198,18 @@ export const useFieldsStore = createStore({
|
||||
// API
|
||||
const response = await api.patch(`/fields/${collectionKey}`, updates);
|
||||
|
||||
this.state.fields = this.state.fields.map((field) => {
|
||||
if (field.collection === collectionKey) {
|
||||
const newDataForField = response.data.data.find(
|
||||
(update: Field) => update.field === field.field
|
||||
);
|
||||
if (newDataForField) return this.parseField(newDataForField);
|
||||
}
|
||||
if (currentUpdate === updateID) {
|
||||
this.state.fields = this.state.fields.map((field) => {
|
||||
if (field.collection === collectionKey) {
|
||||
const newDataForField = response.data.data.find(
|
||||
(update: Field) => update.field === field.field
|
||||
);
|
||||
if (newDataForField) return this.parseField(newDataForField);
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
return field;
|
||||
});
|
||||
}
|
||||
|
||||
notify({
|
||||
title: i18n.t('fields_update_success'),
|
||||
|
||||
Reference in New Issue
Block a user