diff --git a/webapp/packages/core-authentication/src/UserInfoResource.ts b/webapp/packages/core-authentication/src/UserInfoResource.ts index 447e2d7ee8..f7952ae74a 100644 --- a/webapp/packages/core-authentication/src/UserInfoResource.ts +++ b/webapp/packages/core-authentication/src/UserInfoResource.ts @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ -import { computed, makeObservable, runInAction } from 'mobx'; +import { computed, makeObservable, observable, runInAction } from 'mobx'; import { injectable } from '@cloudbeaver/core-di'; import { SyncExecutor, ISyncExecutor, ITask, AutoRunningTask, whileTask } from '@cloudbeaver/core-executor'; @@ -253,7 +253,7 @@ UserInfoIncludes protected resetIncludes(): void { const metadata = this.getMetadata(); - metadata.includes = [...this.defaultIncludes]; + metadata.includes = observable([...this.defaultIncludes]); } getIncludes(key: void): string[] { diff --git a/webapp/packages/core-blocks/src/useMapResource.ts b/webapp/packages/core-blocks/src/useMapResource.ts index ae9f4cfd7d..eb7ceaefdf 100644 --- a/webapp/packages/core-blocks/src/useMapResource.ts +++ b/webapp/packages/core-blocks/src/useMapResource.ts @@ -14,6 +14,7 @@ import { NotificationService } from '@cloudbeaver/core-events'; import { CachedResourceIncludeArgs, CachedMapResource, CachedMapResourceGetter, ResourceKey, CachedMapResourceValue, CachedMapResourceKey, CachedMapResourceArguments, CachedMapResourceLoader, ResourceKeyList, CachedMapResourceListGetter, isResourceKeyList } from '@cloudbeaver/core-sdk'; import { isArraysEqual } from '@cloudbeaver/core-utils'; +import { getComputed } from './getComputed'; import type { ILoadableState } from './Loader/ILoadableState'; import { useObservableRef } from './useObservableRef'; @@ -364,20 +365,22 @@ export function useMapResource< loading: computed, }, false); - // TODO: getComputed skips update somehow ... - const outdated = ( - !result.loading - && (result.outdated || !result.loaded) - ); - - const preloaded = refObj.preloaded; // make mobx subscription + const canLoad = getComputed(() => ( + ( + !keyRef.actual + || result.outdated + || !result.loaded + ) + && refObj.preloaded + && keyRef.key !== null + && ( + result.exception === null + || (Array.isArray(result.exception) && !result.exception.some(Boolean)) + ) + )); useEffect(() => { - if (!preloaded || (!outdated && keyRef.actual) || keyRef.key === null) { - return; - } - - if (result.exception === null || (Array.isArray(result.exception) && !result.exception.some(Boolean))) { + if (canLoad) { (refObj as any)[loadFunctionName](); } }); diff --git a/webapp/packages/core-connections/src/DBDriverResource.ts b/webapp/packages/core-connections/src/DBDriverResource.ts index d8a2c5ab1e..08b14aff81 100644 --- a/webapp/packages/core-connections/src/DBDriverResource.ts +++ b/webapp/packages/core-connections/src/DBDriverResource.ts @@ -37,7 +37,7 @@ export class DBDriverResource extends CachedMapResource this.markOutdated()); makeObservable(this, { enabledDrivers: computed, @@ -69,7 +69,7 @@ export class DBDriverResource extends CachedMapResource driver.id === driverId)) { @@ -77,10 +77,9 @@ export class DBDriverResource extends CachedMapResource { - if (all) { - this.resetIncludes(); - this.data.clear(); + const removedDrivers = this.keys.filter(key => !drivers.some(driver => driver.id === key)); + this.delete(resourceKeyList(removedDrivers)); } this.updateDriver(...drivers); @@ -94,6 +93,6 @@ export class DBDriverResource extends CachedMapResource driver.id)); const oldDriver = this.get(keys); - this.set(keys, oldDriver.map((oldDriver, i) => ({ ...oldDriver, ...drivers[i] }))); + this.set(keys, oldDriver.map((oldDriver, i) => (Object.assign(oldDriver ?? {}, drivers[i])))); } } diff --git a/webapp/packages/core-sdk/src/Resource/CachedMapResource.ts b/webapp/packages/core-sdk/src/Resource/CachedMapResource.ts index c43a0bfe68..4ef124c396 100644 --- a/webapp/packages/core-sdk/src/Resource/CachedMapResource.ts +++ b/webapp/packages/core-sdk/src/Resource/CachedMapResource.ts @@ -366,25 +366,21 @@ export abstract class CachedMapResource< } includes(param: ResourceKey, key: ResourceKey): boolean { - if (param === key) { + if + ( + this.isAliasEqual(param, key) + || (ResourceKeyUtils.isEmpty(param) && ResourceKeyUtils.isEmpty(key)) + ) { return true; } if (this.isAlias(param) || this.isAlias(key)) { - return this.isAliasEqual(param, key); - } - - if (ResourceKeyUtils.isEmpty(param) || ResourceKeyUtils.isEmpty(key)) { - return ResourceKeyUtils.isEmpty(param) && ResourceKeyUtils.isEmpty(key); + return true; } param = ResourceKeyUtils.mapKey(param, this.getKeyRef.bind(this)); key = ResourceKeyUtils.mapKey(key, this.getKeyRef.bind(this)); - if (param === key) { - return true; - } - return ResourceKeyUtils.includes(param, key, this.isKeyEqual); } @@ -467,10 +463,10 @@ export abstract class CachedMapResource< key = this.transformParam(key); } - runInAction(() => ResourceKeyUtils.forEach(key!, key => { + ResourceKeyUtils.forEach(key, key => { const metadata = this.getMetadata(key); metadata.outdated = true; - })); + }); this.onDataOutdated.execute(key); } diff --git a/webapp/packages/core-sdk/src/Resource/CachedResource.ts b/webapp/packages/core-sdk/src/Resource/CachedResource.ts index 4e751b2682..a4fc7956ad 100644 --- a/webapp/packages/core-sdk/src/Resource/CachedResource.ts +++ b/webapp/packages/core-sdk/src/Resource/CachedResource.ts @@ -366,7 +366,7 @@ export abstract class CachedResource< break transform; } } else { - if (this.includes(alias.param, param)) { + if (alias.param === param) { param = alias.getAlias(param); deep++; // eslint-disable-next-line no-labels @@ -412,7 +412,7 @@ export abstract class CachedResource< protected resetIncludes(): void { for (const metadata of this.metadata.values()) { - metadata.includes = [...this.defaultIncludes]; + metadata.includes = observable([...this.defaultIncludes]); } } @@ -447,12 +447,16 @@ export abstract class CachedResource< } isAliasEqual(param: TParam, second: TParam): boolean { + if (param === second) { + return true; + } + return this.paramAliases.some(alias => { if ('getter' in alias && alias.getter) { return alias.param(param) && alias.param(second); - } else { - return alias.param === param && alias.param === second; } + + return false; }); } @@ -461,14 +465,10 @@ export abstract class CachedResource< } protected includes(param: TParam, second: TParam): boolean { - if (param === second) { + if (this.isAliasEqual(param, second)) { return true; } - if (this.isAlias(param) || this.isAlias(second)) { - return this.isAliasEqual(param, second); - } - param = this.transformParam(param); second = this.transformParam(second); return this.isKeyEqual(param, second); diff --git a/webapp/packages/core-sdk/src/Resource/ResourceKeyList.ts b/webapp/packages/core-sdk/src/Resource/ResourceKeyList.ts index 44f8ca306f..ca23605a08 100644 --- a/webapp/packages/core-sdk/src/Resource/ResourceKeyList.ts +++ b/webapp/packages/core-sdk/src/Resource/ResourceKeyList.ts @@ -188,6 +188,10 @@ export const ResourceKeyUtils: ResourceKeyUtils = { key: ResourceKey, isEqual = (keyA: TKey, keyB: TKey) => keyA === keyB ): boolean { + if (param === key) { + return true; + } + if (isResourceKeyList(param)) { return param.includes(key); }