dashboard/shell/plugins/dashboard-store/normalize.js

61 lines
2.4 KiB
JavaScript

import { SCHEMA } from '@shell/config/types';
import { applyChangeset, changeset, changesetConflicts } from '@shell/utils/object';
export const KEY_FIELD_FOR = {
[SCHEMA]: '_id',
default: 'id',
};
export function keyFieldFor(type) {
return KEY_FIELD_FOR[type] || KEY_FIELD_FOR['default'];
}
export function normalizeType(type) {
type = (type?.type || type || '').toLowerCase();
return type;
}
/**
* Detect and resolve conflicts from a 409 response.
*
* @param {*} initialValue the initial value before changes
* @param {*} userValue the value containing the local changes. this function will intentionally mutate this to contain changes made from the server
* @param {*} serverValue the very latest value from the server
* @returns If `value` has been successfully updated return a false-y value. Else they can't be resolved, return an array of errors to show the user.
*/
export async function handleConflict(initialValue, userValue, serverValue, store, storeNamespace, toJSON = (x) => x.toJSON()) {
// initial value
const initial = await store.dispatch(`${ storeNamespace }/cleanForDiff`, toJSON(initialValue), { root: true });
// changed value (user edits)
const user = await store.dispatch(`${ storeNamespace }/cleanForDiff`, toJSON(userValue), { root: true });
// server value
const server = await store.dispatch(`${ storeNamespace }/cleanForDiff`, toJSON(serverValue), { root: true });
// changes made to the server value
const serverChanges = changeset(initial, server);
// changes made locally
const userChanges = changeset(initial, user);
// Any incompatibilities between changes made locally and the server?
const actualConflicts = changesetConflicts(serverChanges, userChanges);
console.log('Background Change', serverChanges); // eslint-disable-line no-console
console.log('User Change', userChanges); // eslint-disable-line no-console
console.log('Conflicts', actualConflicts); // eslint-disable-line no-console
userValue.metadata.resourceVersion = serverValue.metadata.resourceVersion;
// Apply changes made on the server to the changed (user) value
applyChangeset(userValue, serverChanges);
if ( actualConflicts.length ) {
// Stop the save and let the user inspect and continue editing
const out = [store.getters['i18n/t']('validation.conflict', { fields: actualConflicts.join(', '), fieldCount: actualConflicts.length })];
return out;
} else {
// The save can continue
return false;
}
}