-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmesh-data.service.ts
161 lines (140 loc) · 5.34 KB
/
mesh-data.service.ts
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import { Injectable, OnDestroy } from '@angular/core';
import { ParamMap, ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Subject } from 'rxjs/Subject';
import { map } from 'rxjs/operators';
import { distinctUntilChanged } from 'rxjs/operators/distinctUntilChanged';
import { switchMap } from 'rxjs/operators/switchMap';
import { takeUntil } from 'rxjs/operators/takeUntil';
import { ListRequest, MeshNode, Project } from './mesh-models';
const API_URL = '/api/v1/';
/**
* This service makes the REST calls to the Mesh API. Since this is a very basic demo, only a few of the Mesh
* API endpoints are used. In reality, every function of Mesh is exposed via the REST API. For a full overview
* of the endpoints available, see https://getmesh.io/docs/beta/raml/.
*/
@Injectable()
export class MeshDataService implements OnDestroy {
username = 'webclient';
password = 'webclient';
projectName = 'demo';
language = 'de';
isPreview = new BehaviorSubject<boolean>(false);
nodeStatus = ENodeStatus.PUBLISHED;
private destroy$ = new Subject<void>();
constructor(
private http: HttpClient,
private route: ActivatedRoute
) {
// Watch URL parameter to check if in preview mode
this.route.queryParamMap
.pipe(
map((paramMap: ParamMap) => {
if (paramMap.get('preview')) {
return true;
} else {
return false;
}
}),
distinctUntilChanged(),
takeUntil(this.destroy$)
)
.subscribe(urlParamPreview => this.isPreview.next(urlParamPreview));
// Listen if preview mode gets enabled
this.isPreview
.pipe(takeUntil(this.destroy$))
.subscribe((isPreview: boolean) => {
if (isPreview === true) {
this.nodeStatus = ENodeStatus.DRAFT;
} else {
this.nodeStatus = ENodeStatus.PUBLISHED;
}
});
}
// On service instance destroy lifecycle hook
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
/** This should be called first, as it will get set the auth cookie which is required by all subsequent requests. */
login() {
return this.post('auth/login', {
username: this.username,
password: this.password
});
}
/** Get a single node by the node's uuid. */
getNode(uuid: string) {
return this.get<MeshNode>(
`${this.projectName}/nodes/${uuid}`,
{ version: this.nodeStatus }
);
}
/** Returns a list of children of a node. */
getChildren(parentNodeUuid: string) {
return this.get<ListRequest<MeshNode>>(
`${this.projectName}/nodes/${parentNodeUuid}/children`,
{ version: this.nodeStatus }
)
.pipe(map(response => response.data));
}
/** Returns the demo project object. */
getProject(projectName = this.projectName) {
return this.get<ListRequest<Project>>('projects')
.pipe(map(response => response.data.find(project => project.name === projectName)));
}
/**
* Returns the url of the binary field of a node. A binary field is a field
* with the type "binary", for example an image or video file.
* The contents of anay binary field can be received via `<nodeUuid>/binary/<fieldName>`.
*/
getBinaryUrl(nodeUuid: string, fieldName: string) {
if (nodeUuid) {
return `${API_URL}${this.projectName}/nodes/${nodeUuid}/binary/${fieldName}`;
}
return undefined;
}
/**
* Returns a list of the immediate children of the root node. The root node is a special
* node which is the top-level node of a project node tree. Each project in Mesh has a
* property `rootNode` which can be used to query the root node itself.
*/
getRootNodeChildren(projectName = this.projectName) {
return this.getProject(projectName)
.pipe(switchMap(project => project ? this.getChildren(project.rootNode.uuid) : [undefined]));
}
/** Update the fields of an existing node. */
updateNode(node: MeshNode) {
return this.post<MeshNode>(this.projectName + '/nodes/' + node.uuid, node);
}
/**
* Convenience helper for GET requests that ensures cookies are sent.
* @param url destination URL of request
* @param params URL query parameter
* */
private get<T>(
url: string,
params?: { [param: string]: string | string[]; }
) {
const options = { withCredentials: true };
// if params provided assign them
if (params) {
Object.assign(options, {params});
}
return this.http.get<T>(`${API_URL}${url}`, options);
}
/**
* Convenience helper for POST requests that ensures cookies are sent.
* @param url destination URL of request
* @param body request body
* */
private post<T>(url: string, body: any) {
return this.http.post<T>(`${API_URL}${url}`, body, { withCredentials: true });
}
}
/** Node states */
export enum ENodeStatus {
DRAFT = 'draft',
PUBLISHED = 'published'
}