mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-13 07:47:05 +08:00
* refactor: migrate to pure esm * chore: revert `useDefineForClassFields` tsconf * chore: remove patch.js
96 lines
2.4 KiB
TypeScript
96 lines
2.4 KiB
TypeScript
/*
|
|
* CloudBeaver - Cloud Database Manager
|
|
* Copyright (C) 2020-2024 DBeaver Corp and others
|
|
*
|
|
* Licensed under the Apache License, Version 2.0.
|
|
* you may not use this file except in compliance with the License.
|
|
*/
|
|
import { action, makeObservable, observable } from 'mobx';
|
|
|
|
import { type ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor';
|
|
import { isNotNullDefined } from '@cloudbeaver/core-utils';
|
|
|
|
import type { ISettingChangeData, ISettingsSource } from './ISettingsSource.js';
|
|
|
|
export abstract class SettingsSource implements ISettingsSource {
|
|
readonly onChange: ISyncExecutor<ISettingChangeData>;
|
|
private updating: boolean;
|
|
protected readonly changes: Map<any, any>;
|
|
constructor() {
|
|
this.onChange = new SyncExecutor();
|
|
this.updating = false;
|
|
this.changes = new Map();
|
|
|
|
makeObservable<this, 'update' | 'changes'>(this, {
|
|
changes: observable.shallow,
|
|
update: action,
|
|
});
|
|
}
|
|
|
|
has(key: any): boolean {
|
|
return this.changes.has(key);
|
|
}
|
|
|
|
isEdited(key?: any): boolean {
|
|
if (isNotNullDefined(key)) {
|
|
return this.changes.has(key);
|
|
}
|
|
|
|
return this.changes.size > 0;
|
|
}
|
|
|
|
protected abstract getSnapshot(): Record<string, any>;
|
|
abstract isReadOnly(key: any): boolean;
|
|
abstract getValue(key: any): any;
|
|
abstract save(): Promise<void>;
|
|
|
|
clear(): void {
|
|
this.changes.clear();
|
|
}
|
|
|
|
getEditedValue(key: any): any {
|
|
if (this.changes.has(key)) {
|
|
return this.changes.get(key);
|
|
}
|
|
|
|
return this.getValue(key);
|
|
}
|
|
|
|
setValue(key: any, value: any): void {
|
|
const currentValue = this.getValue(key);
|
|
if (currentValue === value || (!isNotNullDefined(currentValue) && value === null)) {
|
|
this.changes.delete(key);
|
|
} else {
|
|
this.changes.set(key, value);
|
|
}
|
|
}
|
|
|
|
protected update(action: () => void) {
|
|
if (this.updating) {
|
|
action();
|
|
return;
|
|
}
|
|
|
|
this.updating = true;
|
|
try {
|
|
const snapshot = this.getSnapshot();
|
|
action();
|
|
const newSnapshot = this.getSnapshot();
|
|
|
|
for (const [key, value] of Object.entries(newSnapshot)) {
|
|
if (snapshot[key] !== value) {
|
|
this.onChange.execute({ key, value });
|
|
}
|
|
}
|
|
|
|
for (const key of Object.keys(snapshot)) {
|
|
if (!(key in newSnapshot)) {
|
|
this.onChange.execute({ key, value: undefined });
|
|
}
|
|
}
|
|
} finally {
|
|
this.updating = false;
|
|
}
|
|
}
|
|
}
|