Skip to content
Permalink
Newer
Older
100644 195 lines (175 sloc) 5.8 KB
Oct 26, 2021
1
var getClient = function getClient(baseUrl, endpointName) {
2
return {
3
baseUrl: baseUrl,
4
endpointName: endpointName,
5
getItems: function getItems(path) {
6
return clientFunctions.makeCall(this.baseUrl + "/.rest/delivery/" + endpointName + path + "@nodes").then(function (data) {
7
return JSON.parse(data);
8
}).then(function (json) {
9
return json.map(jsonToItem);
10
});
11
}
12
};
13
};
14
15
var jsonToItem = function jsonToItem(data) {
16
var map = new Map(Object.entries(data)).set('isFolder', data['@nodeType'] === "mgnl:folder");
17
map["delete"]('@nodes');
18
map["delete"]('@nodeType');
19
map["delete"]('@name');
20
return map;
21
};
22
23
var makeCall = function makeCall(url) {
24
return new Promise(function (resolve, reject) {
25
var request = new XMLHttpRequest();
26
request.open('GET', url);
27
request.onload = function () {
28
if (request.status === 200) {
29
resolve(request.response);
30
} else {
31
reject(Error('Error making call to ' + url + '; error code:' + request.statusText));
32
}
33
};
34
35
request.onerror = function () {
36
reject(Error('There was a network error making call to ' + url));
37
};
38
39
request.send();
40
});
41
};
42
43
var clientFunctions = {
44
makeCall: makeCall,
45
getClient: getClient
46
};
47
48
export default class HierarchicalBrowser extends HTMLElement {
49
constructor() {
50
super();
51
this.baseUrl = this.getAttribute("baseUrl");
52
this.endpoint = this.getAttribute("endpoint");
53
const columns = this.getAttribute("columns");
54
if (!columns) {
55
this.columns = ["@path", "@name"];
56
} else {
57
this.columns = columns.split(",");
58
}
59
this.sh = this.attachShadow({mode: 'open'});
60
this.client = getClient(this.baseUrl, this.endpoint);
61
this.loadItems('/');
62
}
63
64
loadItems(path) {
65
console.log("Go path ->" + path);
66
if (path != "/") {
67
let parent = path.substring(0, path.length - 1);
68
const lastSlash = parent.lastIndexOf('/');
69
this.parent = lastSlash == 0 ? "/" : parent.substring(0, lastSlash);
70
} else {
71
this.parent = null;
72
}
73
this.path = path;
74
this.state = "loading";
75
this.client.getItems(path).then(result => {
76
this.items = result;
77
this.state = 'ready';
78
}).catch(error => {
79
this.errorMessage = error.name + ": " + error.message;
80
this.state = 'error';
81
});
82
}
83
84
get state() {
85
return this.getAttribute('state');
86
}
87
88
set state(value) {
89
this.setAttribute('state', value);
90
}
91
92
static get observedAttributes() { return ['state']; }
93
94
attributeChangedCallback(name, oldValue, newValue) {
95
this.render();
96
}
97
98
connectedCallback() {
99
this.render();
100
}
101
102
render() {
103
this.sh.innerHTML = '';
104
if (this.getAttribute('state') == "loading") {
105
this.sh.appendChild(this.loading());
106
}
107
if (this.getAttribute('state') == "ready") {
108
this.sh.appendChild(this.showItems());
109
}
110
if (this.getAttribute('state') == "error") {
111
this.sh.innerHTML = '<p class="error">' + this.errorMessage || "Unknown Error" + '<p>';
112
}
113
}
114
115
loading() {
116
const template = document.getElementById('browser-loading');
117
const instance = document.importNode(template.content, true);
118
instance.querySelector('.endpoint-name').innerHTML = this.endpoint;
119
return instance;
120
}
121
122
showItems() {
123
const template = document.getElementById('browser-items');
124
const instance = document.importNode(template.content, true);
125
instance.querySelector('.items-path').innerHTML = this.path;
126
instance.querySelector('.content-list').innerHTML = this.getItemsHtml();
127
this.addFolderClickEvent(instance);
128
return instance;
129
}
130
131
getItemsHtml() {
132
if (this.items.size < 1) {
133
return "<thead><tr><th>empty</th></tr></thead>"
134
} else {
135
let result = "";
136
if (this.parent != null) {
137
result += '<thead><tr><td class="folder" folder="' + this.parent + '">Go to ' + this.parent + '</td></tr></thead>';
138
}
139
result += this.getItemsHeader(this.columns) + this.getItemsBody(this.items, this.columns);
140
return result;
141
}
142
}
143
144
getItemsHeader(columns) {
145
let headers = "";
146
columns.forEach(column => headers += "<td>" + column + "</td>");
147
return "<thead><tr>" + headers + "</tr></thead>";
148
}
149
150
getItemsBody(items, columns) {
151
let rows = "";
152
items.forEach(content => {
153
let row = "<tr>";
154
if (content.get("isFolder")) {
155
row = '<tr class="folder" folder="' + content.get('@path') + '">'
156
}
157
columns.forEach(column => {
158
const value = content.get(column);
159
if (value == undefined) {
160
row = row + "<td></td>";
161
} else {
162
row = row + "<td>" + content.get(column) + "</td>";
163
}
164
});
165
row = row + "</tr>";
166
rows = rows + row;
167
});
168
return "<tbody>" + rows + "</tbody>";
169
}
170
171
addFolderClickEvent(instance) {
172
if (instance.querySelector('.folder')) {
173
const that = this;
174
const elements = instance.querySelectorAll('.folder');
175
elements.forEach(element => {
176
element.addEventListener('click', function(event) {
177
event.preventDefault();
178
let row = event.target;
179
while (row.getAttribute("folder") == undefined) {
180
row = row.parentElement;
181
}
182
let path = row.getAttribute("folder");
183
if (!path.endsWith("/")) {
184
path = path + "/";
185
}
186
that.loadItems(path);
187
});
188
});
189
}
190
}
191
}
192
193
if (!customElements.get('hierarchical-browser')) {
194
customElements.define('hierarchical-browser', HierarchicalBrowser);
195
}