Skip to content

Commit 6fc848d

Browse files
committed
EmbeddedCollection with HasItems (remove legacy CanHaveItems)
1 parent 56a6a23 commit 6fc848d

File tree

4 files changed

+29
-126
lines changed

4 files changed

+29
-126
lines changed

src/CanHaveItems.ts

-107
This file was deleted.

src/EmbeddedCollection.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import CanHaveItems from './CanHaveItems'
21
// import LoadingStoreCollection from './LoadingStoreCollection'
32
import Resource, { EmbeddedCollectionType } from './interfaces/Resource'
4-
import ApiActions from './interfaces/ApiActions'
5-
import { InternalConfig } from './interfaces/Config'
6-
import StoreData, { Link } from './interfaces/StoreData'
3+
import { Link } from './interfaces/StoreData'
74

85
/**
96
* Imitates a full standalone collection with an items property, even if there is no separate URI (as it
@@ -12,7 +9,7 @@ import StoreData, { Link } from './interfaces/StoreData'
129
* URI, we need to reload the whole entity containing the embedded collection. Some extra info about the
1310
* containing entity must therefore be passed to the constrcutor.
1411
*/
15-
class EmbeddedCollection extends CanHaveItems implements EmbeddedCollectionType {
12+
class EmbeddedCollection implements EmbeddedCollectionType {
1613
public _meta: {
1714
load: Promise<EmbeddedCollectionType>,
1815
reload: { // TODO: do we want/need to expose this externally? or sufficient if we keep this in the store and expose $reload()?
@@ -21,6 +18,10 @@ class EmbeddedCollection extends CanHaveItems implements EmbeddedCollectionType
2118
}
2219
}
2320

21+
_storeData: {
22+
items: Array<Link>
23+
}
24+
2425
/**
2526
* @param items array of items, which can be mixed primitive values and entity references
2627
* @param reloadUri URI of the entity containing the embedded collection (for reloading)
@@ -29,29 +30,30 @@ class EmbeddedCollection extends CanHaveItems implements EmbeddedCollectionType
2930
* @param config dependency injection of config object
3031
* @param loadParent a promise that will resolve when the parent entity has finished (re-)loading
3132
*/
32-
constructor (items: Array<Link>, reloadUri: string, reloadProperty: string, apiActions: ApiActions, config: InternalConfig, loadParent: Promise<StoreData> | null = null) {
33-
super(apiActions, config, items, reloadUri, reloadProperty)
33+
constructor (items: Array<Link>, reloadUri: string, reloadProperty: string, loadCollection: Promise<EmbeddedCollectionType> | null = null) {
34+
this._storeData = {
35+
items
36+
}
3437

3538
this._meta = {
36-
load: loadParent
37-
? loadParent.then(parentResource => new EmbeddedCollection(parentResource[reloadProperty], reloadUri, reloadProperty, apiActions, config))
38-
: Promise.resolve(this),
39+
load: loadCollection || Promise.resolve(this),
3940
reload: {
4041
uri: reloadUri,
4142
property: reloadProperty
4243
}
4344
}
4445
}
4546

47+
/*
4648
$loadItems () :Promise<Array<Resource>> {
4749
return new Promise((resolve) => {
48-
const items = this.items
50+
const items = this._storeData.items
4951
// TODO: this is probably broken as LoadingStoreCollection has no constructor anymore
5052
// if (items instanceof LoadingStoreCollection) items._meta.load.then(result => resolve(result))
5153
// else resolve(items)
5254
resolve(items)
5355
})
54-
}
56+
} */
5557
}
5658

5759
export default EmbeddedCollection

src/HasItems.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isEntityReference } from './halHelpers'
22
import LoadingStoreCollection from './LoadingStoreCollection'
33
import Resource from './interfaces/Resource'
4-
import StoreDataCollection, { Link } from './interfaces/StoreData'
4+
import { Link } from './interfaces/StoreData'
55
import ApiActions from './interfaces/ApiActions'
66
import { InternalConfig } from './interfaces/Config'
77

@@ -14,10 +14,10 @@ import { InternalConfig } from './interfaces/Config'
1414
type GConstructor<T> = new (...args: any[]) => T;
1515

1616
// Ensure property _storeData.items exist
17-
type HasStoreData = GConstructor<{ _storeData: StoreDataCollection }>;
17+
type HasStoreData = GConstructor<{ _storeData: { items: Array<Link> } }>;
1818

1919
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
20-
function HasItems<TBase extends HasStoreData> (Base: TBase, apiActions: ApiActions, config: InternalConfig) {
20+
function HasItems<TBase extends HasStoreData> (Base: TBase, apiActions: ApiActions, config: InternalConfig, reloadUri?: string, reloadProperty?: string) {
2121
/**
2222
* Filter out items that are marked as deleting (eager removal)
2323
*/
@@ -75,8 +75,8 @@ function HasItems<TBase extends HasStoreData> (Base: TBase, apiActions: ApiActio
7575
}
7676

7777
const HasItems = class extends Base {
78-
fetchAllUri = ''
79-
fetchAllProperty = ''
78+
fetchAllUri = reloadUri || ''
79+
fetchAllProperty = reloadProperty || ''
8080

8181
/**
8282
* Get items excluding ones marked as 'deleting' (eager remove)

src/StoreValue.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import { isTemplatedLink, isEntityReference } from './halHelpers'
33
import EmbeddedCollection from './EmbeddedCollection'
44
import Resource from './interfaces/Resource'
55
import ApiActions from './interfaces/ApiActions'
6-
import { StoreData } from './interfaces/StoreData'
6+
import { StoreData, StoreDataEntity } from './interfaces/StoreData'
77
import StoreValueCreator from './StoreValueCreator'
88
import { InternalConfig } from './interfaces/Config'
9+
import HasItems from './HasItems'
910

1011
/**
1112
* Represents an actual StoreValue, by wrapping the given Vuex store storeData. The storeData must not be loading.
@@ -41,7 +42,14 @@ class StoreValue implements Resource {
4142

4243
// storeData[key] is an embedded collection
4344
if (Array.isArray(value)) {
44-
this[key] = () => new EmbeddedCollection(value, storeData._meta.self, key, this.apiActions, config, storeData._meta.load)
45+
// build complete Collection class = EmbeddedCollection + HasItems mixin
46+
const EmbeddedCollectionClass = HasItems(EmbeddedCollection, this.apiActions, this.config, storeData._meta.self, key)
47+
48+
const loadCollection = storeData._meta.load
49+
? (storeData._meta.load as Promise<StoreDataEntity>).then(parentResource => new EmbeddedCollectionClass(parentResource[key], storeData._meta.self, key))
50+
: null
51+
52+
this[key] = () => new EmbeddedCollectionClass(value, storeData._meta.self, key, loadCollection)
4553

4654
// storeData[key] is a reference only (contains only href; no data)
4755
} else if (isEntityReference(value)) {

0 commit comments

Comments
 (0)