manu-sapiens's picture
copy of omnitool_latest - should be working
b39afbe
raw
history blame
4.18 kB
/**
* Copyright (c) 2023 MERCENARIES.AI PTE. LTD.
* All rights reserved.
*/
import axios from 'axios';
import { BaseWorkflow, omnilog, type IWorkflowMeta } from 'omni-shared';
class ClientWorkflow extends BaseWorkflow {
_errors: any[] = [];
_dirty: number = 0; // 0 = no local changes, 1 = unsaved, any other value is a dirtyCookie, i.e. save-in-progress.
_flags: string[] = [];
get displayName(): string {
let result = this.meta.name || this.id;
if (this.isDirty) result += '*';
if (this.readOnly) result += ' (read-only)';
if (this.copyOnWrite) result += ' (copy-on-write)';
return result;
}
hasFlag(flag: string): boolean {
if (flag !== flag.toLowerCase()) {
throw new Error(`ClientWorkflow Flag "${flag}" must be lower-case`);
}
return this._flags.includes(flag);
}
setFlag(flag: string, value: boolean = true) {
if (flag !== flag.toLowerCase()) {
throw new Error(`ClientWorkflow Flag "${flag}" must be lower-case`);
}
if (value) {
// Set true
if (!this._flags.includes(flag)) {
this._flags.push(flag);
}
return;
}
// Set false, i.e. clear
this._flags = this._flags.filter((f) => f !== flag);
}
clearFlag(flag: string) {
this.setFlag(flag, false);
}
get isDirty(): boolean {
return this._dirty !== 0;
}
setDirty() {
this._dirty = 1; // i.e. unsaved.
}
get copyOnWrite(): boolean {
return this.hasFlag('copyonwrite');
}
set copyOnWrite(value: boolean) {
this.setFlag('copyonwrite', value);
}
get readOnly(): boolean {
return this.hasFlag('readonly');
}
set readOnly(value: boolean) {
this.setFlag('readonly', value);
}
// Clone the recipe on the server
static async clone(data: { id: string; meta?: Partial<IWorkflowMeta> }): Promise<ClientWorkflow> {
const result = await axios.post('/api/v1/workflow/clone', { ...data }, { withCredentials: true });
const json = result.data.workflow;
return ClientWorkflow.fromJSON(json);
}
// Returns 'true' if/when server version matches local version
async syncToServer(): Promise<boolean> {
if (this.readOnly) {
/* TODO: Ensure overwriting a read-only workflow will fail on the server. */
return false;
}
if (this.copyOnWrite) {
this.copyOnWrite = false;
this.id = '';
}
const dirtyCookie = new Date().getTime();
this._dirty = dirtyCookie; // i.e. save in progress.
this.meta.updated = Date.now();
//@ts-ignore
const payload = window.Alpine.raw(this.toJSON());
try {
const result = await axios({
method: this.id ? 'put' : 'post',
url: '/api/v1/workflow',
data: payload,
withCredentials: true
});
if (result.status !== 200) {
return false; /* Unable to write to server. */
}
if (!result.data.workflow) {
return false; /* Unable to write to server. */
}
const serverId = result.data.workflow.id;
if (!serverId) {
throw new Error('Server did not return a valid recipe Id');
}
if (this.id && this.id !== serverId) {
omnilog.log('server updated our id unexpectedly', this.id, serverId);
}
this.id = serverId;
} catch (e) {
omnilog.log('error writing to server', e);
return false; /* Unable to write to server. */
}
if (this._dirty === dirtyCookie) {
this._dirty = 0; // Only set back to 0 if it wasn't changed while we were saving.
}
return true;
}
static fromJSON(json: any, flags: string[] | undefined = undefined): ClientWorkflow {
const result = new ClientWorkflow(json.id);
result.id = json.id;
if (!result.id && json._id) {
result.id = json._id.replace('wf:', '');
}
result.setMeta(json.meta);
result.setRete(json.rete);
result.setAPI(json.api);
if (flags && flags.length > 0) {
result._flags = flags;
} else if (json._flags) {
result._flags = json._flags;
}
return result;
}
toJSON() {
const ret: any = super.toJSON();
ret._flags = this._flags;
return ret;
}
}
export default ClientWorkflow;