-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathview-container.component.js
More file actions
139 lines (121 loc) · 5.51 KB
/
view-container.component.js
File metadata and controls
139 lines (121 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { ReferenceComponent } from "./reference.component.js";
import { Utils } from "../../helpers/utils.js";
import { BaseComponent } from "../base.component.js";
const TAG = "[ViewContainerComponent]";
export class ViewContainerComponent extends BaseComponent {
jsComponentPConnectData = {};
childComponent;
props = {
children: [],
};
init() {
this.jsComponentPConnectData = this.jsComponentPConnect.registerAndSubscribeComponent(
this,
this.#checkAndUpdate
);
this.componentsManager.onComponentAdded(this);
const { CONTAINER_TYPE, APP } = PCore.getConstants();
const { name = "", mode = "single", limit = 16 } = this.pConn.resolveConfigProps(this.pConn.getConfigProps());
const containerMgr = this.pConn.getContainerManager();
const type = mode === CONTAINER_TYPE.MULTIPLE ? CONTAINER_TYPE.MULTIPLE : CONTAINER_TYPE.SINGLE;
if (!Utils.hasViewContainer()) {
containerMgr.initializeContainers({ type: type });
if (mode === CONTAINER_TYPE.MULTIPLE) {
/* NOTE: setContainerLimit use is temporary. It is a non-public, unsupported API. */
PCore.getContainerUtils().setContainerLimit(`${APP.APP}/${name}`, limit);
}
if (!PCore.checkIfSemanticURL()) {
// PCore.checkIfSemanticURL() logic inside c11n-core-js is that it compares app path and path in url.
// If they are equal then it returns false. In code these values are set to be equal.
containerMgr.addContainerItem(this.#prepareDispatchObject());
}
Utils.setHasViewContainer("true");
}
// cannot call #checkAndUpdate because first time through, will call #updateSelf and that is incorrect (causes issues).
// however, need jsComponentPConnect to be initialized with currentProps for future updates, so calling shouldComponentUpdate directly
// without checking to update here in init, will initialize and this is correct
this.jsComponentPConnect.shouldComponentUpdate(this);
}
destroy() {
super.destroy();
this.jsComponentPConnectData.unsubscribeFn?.();
this.childComponent?.destroy?.();
this.props.children = [];
this.componentsManager.onComponentPropsUpdate(this);
this.componentsManager.onComponentRemoved(this);
}
update(pConn) {
if (this.pConn !== pConn) {
this.pConn = pConn;
this.#checkAndUpdate();
}
}
#checkAndUpdate() {
// added Utils.hasViewContainer() check because call to addContainerItem in init()
// causes redux to dispatch event and this method is called too early
if (Utils.hasViewContainer() && this.jsComponentPConnect.shouldComponentUpdate(this)) {
this.#updateSelf();
}
}
#updateSelf() {
// routingInfo was added as component prop in populateAdditionalProps
const routingInfo = this.jsComponentPConnect.getComponentProp(this, "routingInfo");
if (!routingInfo) {
console.error(TAG, "routingInfo is not available.");
return;
}
const { accessedOrder, items } = routingInfo;
if (accessedOrder && items) {
const lastItemKey = accessedOrder[accessedOrder.length - 1];
if (this.#hasViewsInRoutingInfo(lastItemKey, items)) {
const newCompPConn = this.#createNewPConn(lastItemKey, items);
const newCompName = newCompPConn.getComponentName();
if (newCompName !== "reference") {
console.error(
TAG,
`newComp name is '${newCompName}. 'Only 'reference' is supported as newComp in ViewContainer`
);
return;
}
const viewPConn = ReferenceComponent.normalizePConn(newCompPConn);
this.childComponent?.destroy?.();
this.childComponent = this.componentsManager.create(viewPConn.meta.type, [viewPConn]);
this.childComponent.init();
this.props.children = [this.childComponent.compId];
this.componentsManager.onComponentPropsUpdate(this);
}
}
}
#hasViewsInRoutingInfo(key, items) {
return items[key] && items[key].view && Object.keys(items[key].view).length > 0;
}
#createNewPConn(lastItemKey, items) {
const config = this.#createNewConfig(lastItemKey, items);
return PCore.createPConnect(config).getPConnect();
}
/**
* Creates a new configuration object based on the last item view in the routing info.
*/
#createNewConfig(lastItemKey, items) {
const { CREATE_DETAILS_VIEW_NAME } = PCore.getConstants();
const latestItem = items[lastItemKey];
const rootView = latestItem.view;
const { context, name: viewName } = rootView.config;
const config = { meta: rootView };
config.options = {
context: latestItem.context,
pageReference: context || this.pConn.getPageReference(),
containerName: this.pConn.getContainerName(),
containerItemName: lastItemKey,
hasForm: viewName === CREATE_DETAILS_VIEW_NAME,
};
return config;
}
#prepareDispatchObject() {
return {
semanticURL: "",
context: this.pConn.getContextName(),
acName: this.pConn.getContainerName() ?? "primary",
};
}
}