react-antd-admin-panel
Version:
Modern TypeScript-first React admin panel builder with Ant Design 6
170 lines • 4.19 kB
JavaScript
/**
* Formula - Form value collection and submission manager
*
* Collects values from form controls registered via `value()` method,
* and submits them via a Post model when `submit()` is called.
*
* @typeParam T - Type of the collected form data
* @typeParam R - Type of the response from Post
*
* @example
* ```typescript
* const formula = new Formula<UserInput, User>(
* new Post<UserInput, User>()
* .target('/api/users')
* .onThen((user) => console.log('Created:', user.id))
* );
*
* // Register values from form controls
* formula.value('name', 'John');
* formula.value('email', 'john@example.com');
*
* // Get all collected values
* const data = formula.params(); // { name: 'John', email: 'john@example.com' }
*
* // Submit the form
* await formula.submit();
* ```
*/
export class Formula {
_values = new Map();
_post;
_action = null;
_callbacks = {};
_isSubmitting = false;
constructor(post) {
this._post = post;
}
/**
* Register or update a value in the formula
* @param key - Field key
* @param value - Field value
* @param reset - Optional reset callback
*/
value(key, value, reset) {
this._values.set(key, { value, reset });
return this;
}
/**
* Get a single value by key
*/
get(key) {
return this._values.get(key)?.value;
}
/**
* Check if a value is registered
*/
has(key) {
return this._values.has(key);
}
/**
* Remove a value from the formula
*/
remove(key) {
this._values.delete(key);
return this;
}
/**
* Get all collected values as an object
*/
params() {
const result = {};
this._values.forEach((entry, key) => {
result[key] = entry.value;
});
return result;
}
/**
* Reset all registered values
*/
reset() {
this._values.forEach((entry) => {
entry.reset?.();
});
this._values.clear();
return this;
}
/**
* Link an action to this formula
*/
action(action) {
this._action = action;
return this;
}
/**
* Get the linked action
*/
getAction() {
return this._action;
}
/**
* Get the Post model
*/
getPost() {
return this._post;
}
/**
* Set callback for successful completion
*/
onComplete(callback) {
this._callbacks.onComplete = callback;
return this;
}
/**
* Set callback for errors
*/
onError(callback) {
this._callbacks.onError = callback;
return this;
}
/**
* Set callback for finally (always runs)
*/
onFinally(callback) {
this._callbacks.onFinally = callback;
return this;
}
/**
* Check if formula is currently submitting
*/
isSubmitting() {
return this._isSubmitting;
}
/**
* Submit the formula via Post
* @param additionalData - Additional data to merge with form values
*/
async submit(additionalData) {
if (this._isSubmitting) {
return undefined;
}
this._isSubmitting = true;
try {
// Merge form values with additional data
const body = {
...this.params(),
...additionalData,
};
// Set body on Post and execute
this._post.body(body);
const result = await this._post.execute();
// Call success callbacks
this._callbacks.onComplete?.(result);
this._action?.callComplete?.(result);
return result;
}
catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
// Call error callbacks
this._callbacks.onError?.(err);
this._action?.callError?.(err);
throw err;
}
finally {
this._isSubmitting = false;
this._callbacks.onFinally?.();
}
}
}
export default Formula;
//# sourceMappingURL=Formula.js.map