@ruc-lib/org-chart 2.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,421 +1,403 @@
1
- import * as i0 from '@angular/core';
2
- import { Component, Input, ViewChild, NgModule } from '@angular/core';
3
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import { ButtonModule } from 'primeng/button';
6
- import * as i4 from 'primeng/organizationchart';
7
- import { OrganizationChartModule } from 'primeng/organizationchart';
1
+ import * as i6 from '@angular/material/menu';
2
+ import { MatMenuModule } from '@angular/material/menu';
8
3
  import * as i5 from '@angular/material/input';
9
4
  import { MatInputModule } from '@angular/material/input';
10
- import * as i3 from '@angular/forms';
11
- import { FormsModule } from '@angular/forms';
12
- import * as i7 from '@angular/material/menu';
13
- import { MatMenuModule } from '@angular/material/menu';
14
- import * as i8 from '@angular/material/button';
5
+ import * as i4 from '@angular/material/form-field';
6
+ import { MatFormFieldModule } from '@angular/material/form-field';
7
+ import * as i3 from '@angular/material/button';
15
8
  import { MatButtonModule } from '@angular/material/button';
16
- import * as i9 from '@angular/material/icon';
9
+ import * as i2 from '@angular/material/icon';
17
10
  import { MatIconModule } from '@angular/material/icon';
11
+ import * as i0 from '@angular/core';
12
+ import { ViewChild, Input, Component } from '@angular/core';
18
13
  import { jsPDF } from 'jspdf';
19
14
  import html2canvas from 'html2canvas';
20
- import * as i2 from 'primeng/api';
21
- import * as i6 from '@angular/material/form-field';
22
- import { BrowserModule } from '@angular/platform-browser';
15
+ import * as i7 from 'primeng/organizationchart';
16
+ import { OrganizationChartModule } from 'primeng/organizationchart';
17
+ import * as i1 from '@angular/common';
18
+ import { CommonModule } from '@angular/common';
19
+ import * as i9 from '@angular/forms';
20
+ import { FormsModule } from '@angular/forms';
21
+ import * as i8 from 'primeng/api';
23
22
 
24
- const downloadChart = (chartContainer, format) => {
25
- if (!chartContainer) {
26
- console.error('Chart container not found!');
27
- return;
28
- }
29
- // Capture the chart container as an image (either PNG or JPEG)
30
- if (format === 'pdf') {
31
- createPDF(chartContainer);
32
- }
33
- else {
34
- captureElementAsImage(chartContainer, format)
35
- .then((imgData) => {
36
- downloadImage(imgData, format); // Download as PNG or JPEG
37
- })
38
- .catch(handleCanvasError);
39
- }
40
- };
41
- // Capture the element as an image and return a promise
42
- const captureElementAsImage = (element, format) => {
43
- return new Promise((resolve, reject) => {
44
- html2canvas(element, {
45
- useCORS: true,
46
- scrollX: 0,
47
- scrollY: -window.scrollY,
48
- logging: false,
49
- backgroundColor: null,
50
- })
51
- .then((canvas) => {
52
- const imgData = canvas.toDataURL(`image/${format}`);
53
- resolve(imgData);
54
- })
55
- .catch((error) => reject(error));
56
- });
57
- };
58
- // Downloads the org chart as a PDF document.
59
- const createPDF = (element) => {
60
- html2canvas(element, {
61
- useCORS: true,
62
- scale: 4,
63
- scrollX: 0,
64
- scrollY: -window.scrollY,
65
- logging: false,
66
- backgroundColor: null,
67
- })
68
- .then((canvas) => {
69
- const imgData = canvas.toDataURL('image/png'); // Capture as PNG (or you can use JPEG)
70
- const pdf = new jsPDF('p', 'mm', 'a4'); // Standard A4 page size
71
- // Get the dimensions of the PDF page
72
- const pdfWidth = pdf.internal.pageSize.width;
73
- const pdfHeight = pdf.internal.pageSize.height;
74
- const canvasWidth = canvas.width;
75
- const canvasHeight = canvas.height;
76
- const aspectRatio = canvasWidth / canvasHeight;
77
- let imgWidth = pdfWidth;
78
- let imgHeight = pdfWidth / aspectRatio;
79
- // If the image height exceeds the PDF page height, adjust it
80
- if (imgHeight > pdfHeight) {
81
- imgHeight = pdfHeight;
82
- imgWidth = pdfHeight * aspectRatio;
83
- }
84
- // Add the image to the PDF
85
- pdf.addImage(imgData, 'PNG', 0, 20, imgWidth, imgHeight); // Fit image on PDF page
86
- pdf.save('organization-chart.pdf'); // Download the PDF
87
- })
88
- .catch(handleCanvasError);
89
- };
90
- // Download the captured image in the required format (PNG/JPEG)
91
- const downloadImage = (imgData, format) => {
92
- const link = document.createElement('a');
93
- link.href = imgData;
94
- link.download = `organization-chart.${format}`;
95
- link.click();
96
- };
97
- // Error handler for any issues during canvas generation or file creation
98
- const handleCanvasError = (error) => {
99
- console.error('Error generating file:', error);
100
- };
101
- const checkPropsType = (props) => {
102
- if (props.isDisplayHambergerMenu !== undefined && typeof props.isDisplayHambergerMenu !== 'boolean') {
103
- console.error('Error: isDisplayHambergerMenu should be a boolean.');
104
- }
105
- if (props.isDisplaySearchBar !== undefined && typeof props.isDisplaySearchBar !== 'boolean') {
106
- console.error('Error: isDisplaySearchBar should be a boolean.');
107
- }
108
- if (!['portrait', 'triangle', 'landscape'].includes(props.nodeTemplate)) {
109
- console.error('Error: nodeTemplate should be "portrait", "triangle", or "landscape".');
110
- }
111
- if (!Array.isArray(props.hambergerMenuList)) {
112
- console.error('Error: hambergerMenuList should be an array.');
113
- }
114
- else {
115
- props.hambergerMenuList.forEach(item => {
116
- if (typeof item.label !== 'string') {
117
- console.error('Error: hambergerMenuList label should be a string.');
118
- }
119
- if (typeof item.id !== 'number') {
120
- console.error('Error: hambergerMenuList id should be a number.');
121
- }
122
- });
123
- }
124
- // Check if greyNodeStyle is of type CustomNodeStyle
125
- const greyNodeStyle = props.greyNodeStyle;
126
- if (greyNodeStyle) {
127
- if (greyNodeStyle.backgroundColor && typeof greyNodeStyle.backgroundColor !== 'string') {
128
- console.error('Error: greyNodeStyle.backgroundColor should be a string.');
129
- }
130
- if (greyNodeStyle.color && typeof greyNodeStyle.color !== 'string') {
131
- console.error('Error: greyNodeStyle.color should be a string.');
132
- }
133
- if (greyNodeStyle.padding && typeof greyNodeStyle.padding !== 'string') {
134
- console.error('Error: greyNodeStyle.padding should be a string.');
135
- }
136
- if (greyNodeStyle.borderRadius && typeof greyNodeStyle.borderRadius !== 'string') {
137
- console.error('Error: greyNodeStyle.borderRadius should be a string.');
138
- }
139
- }
140
- // Check if orgData is an array of OrgDataItem objects
141
- if (!Array.isArray(props.orgData)) {
142
- console.error('Error: orgData should be an array.');
143
- }
144
- else {
145
- props.orgData.forEach(item => checkOrgDataItem(item));
146
- }
147
- };
148
- const checkOrgDataItem = (item) => {
149
- if (item.label !== undefined && typeof item.label !== 'string') {
150
- console.error('Error: OrgDataItem label should be a string.');
151
- }
152
- if (item.expanded !== undefined && typeof item.expanded !== 'boolean') {
153
- console.error('Error: OrgDataItem expanded should be a boolean.');
154
- }
155
- if (item.description !== undefined && typeof item.description !== 'string') {
156
- console.error('Error: OrgDataItem description should be a string.');
157
- }
158
- if (item.customNodeStyle !== undefined) {
159
- const customNodeStyle = item.customNodeStyle;
160
- if (customNodeStyle.backgroundColor && typeof customNodeStyle.backgroundColor !== 'string') {
161
- console.error('Error: customNodeStyle.backgroundColor should be a string.');
162
- }
163
- if (customNodeStyle.color && typeof customNodeStyle.color !== 'string') {
164
- console.error('Error: customNodeStyle.color should be a string.');
165
- }
166
- if (customNodeStyle.padding && typeof customNodeStyle.padding !== 'string') {
167
- console.error('Error: customNodeStyle.padding should be a string.');
168
- }
169
- if (customNodeStyle.borderRadius && typeof customNodeStyle.borderRadius !== 'string') {
170
- console.error('Error: customNodeStyle.borderRadius should be a string.');
171
- }
172
- }
173
- if (item.data) {
174
- if (item.data.image !== undefined && typeof item.data.image !== 'string') {
175
- console.error('Error: OrgDataItem data.image should be a string.');
176
- }
177
- if (item.data.name !== undefined && typeof item.data.name !== 'string') {
178
- console.error('Error: OrgDataItem data.name should be a string.');
179
- }
180
- if (typeof item.data.title !== 'string') {
181
- console.error('Error: OrgDataItem data.title should be a string.');
182
- }
183
- }
184
- if (item.children && Array.isArray(item.children)) {
185
- item.children.forEach(child => checkOrgDataItem(child)); // Recursive call for children
186
- }
187
- if (item.originalStyle) {
188
- const originalStyle = item.originalStyle;
189
- if (originalStyle.backgroundColor && typeof originalStyle.backgroundColor !== 'string') {
190
- console.error('Error: originalStyle.backgroundColor should be a string.');
191
- }
192
- if (originalStyle.color && typeof originalStyle.color !== 'string') {
193
- console.error('Error: originalStyle.color should be a string.');
194
- }
195
- if (originalStyle.padding && typeof originalStyle.padding !== 'string') {
196
- console.error('Error: originalStyle.padding should be a string.');
197
- }
198
- if (originalStyle.borderRadius && typeof originalStyle.borderRadius !== 'string') {
199
- console.error('Error: originalStyle.borderRadius should be a string.');
200
- }
201
- }
23
+ const downloadChart = (chartContainer, format) => {
24
+ if (!chartContainer) {
25
+ console.error('Chart container not found!');
26
+ return;
27
+ }
28
+ // Capture the chart container as an image (either PNG or JPEG)
29
+ if (format === 'pdf') {
30
+ createPDF(chartContainer);
31
+ }
32
+ else {
33
+ captureElementAsImage(chartContainer, format)
34
+ .then((imgData) => {
35
+ downloadImage(imgData, format); // Download as PNG or JPEG
36
+ })
37
+ .catch(handleCanvasError);
38
+ }
39
+ };
40
+ // Capture the element as an image and return a promise
41
+ const captureElementAsImage = (element, format) => {
42
+ return new Promise((resolve, reject) => {
43
+ html2canvas(element, {
44
+ useCORS: true,
45
+ scrollX: 0,
46
+ scrollY: -window.scrollY,
47
+ logging: false,
48
+ backgroundColor: null,
49
+ })
50
+ .then((canvas) => {
51
+ const imgData = canvas.toDataURL(`image/${format}`);
52
+ resolve(imgData);
53
+ })
54
+ .catch((error) => reject(error));
55
+ });
56
+ };
57
+ // Downloads the org chart as a PDF document.
58
+ const createPDF = (element) => {
59
+ html2canvas(element, {
60
+ useCORS: true,
61
+ scale: 4,
62
+ scrollX: 0,
63
+ scrollY: -window.scrollY,
64
+ logging: false,
65
+ backgroundColor: null,
66
+ })
67
+ .then((canvas) => {
68
+ const imgData = canvas.toDataURL('image/png'); // Capture as PNG (or you can use JPEG)
69
+ const pdf = new jsPDF('p', 'mm', 'a4'); // Standard A4 page size
70
+ // Get the dimensions of the PDF page
71
+ const pdfWidth = pdf.internal.pageSize.width;
72
+ const pdfHeight = pdf.internal.pageSize.height;
73
+ const canvasWidth = canvas.width;
74
+ const canvasHeight = canvas.height;
75
+ const aspectRatio = canvasWidth / canvasHeight;
76
+ let imgWidth = pdfWidth;
77
+ let imgHeight = pdfWidth / aspectRatio;
78
+ // If the image height exceeds the PDF page height, adjust it
79
+ if (imgHeight > pdfHeight) {
80
+ imgHeight = pdfHeight;
81
+ imgWidth = pdfHeight * aspectRatio;
82
+ }
83
+ // Add the image to the PDF
84
+ pdf.addImage(imgData, 'PNG', 0, 20, imgWidth, imgHeight); // Fit image on PDF page
85
+ pdf.save('organization-chart.pdf'); // Download the PDF
86
+ })
87
+ .catch(handleCanvasError);
88
+ };
89
+ // Download the captured image in the required format (PNG/JPEG)
90
+ const downloadImage = (imgData, format) => {
91
+ const link = document.createElement('a');
92
+ link.href = imgData;
93
+ link.download = `organization-chart.${format}`;
94
+ link.click();
95
+ };
96
+ // Error handler for any issues during canvas generation or file creation
97
+ const handleCanvasError = (error) => {
98
+ console.error('Error generating file:', error);
99
+ };
100
+ const checkPropsType = (props) => {
101
+ if (props.isDisplayHambergerMenu !== undefined && typeof props.isDisplayHambergerMenu !== 'boolean') {
102
+ console.error('Error: isDisplayHambergerMenu should be a boolean.');
103
+ }
104
+ if (props.isDisplaySearchBar !== undefined && typeof props.isDisplaySearchBar !== 'boolean') {
105
+ console.error('Error: isDisplaySearchBar should be a boolean.');
106
+ }
107
+ if (!['portrait', 'triangle', 'landscape'].includes(props.nodeTemplate)) {
108
+ console.error('Error: nodeTemplate should be "portrait", "triangle", or "landscape".');
109
+ }
110
+ if (!Array.isArray(props.hambergerMenuList)) {
111
+ console.error('Error: hambergerMenuList should be an array.');
112
+ }
113
+ else {
114
+ props.hambergerMenuList.forEach(item => {
115
+ if (typeof item.label !== 'string') {
116
+ console.error('Error: hambergerMenuList label should be a string.');
117
+ }
118
+ if (typeof item.id !== 'number') {
119
+ console.error('Error: hambergerMenuList id should be a number.');
120
+ }
121
+ });
122
+ }
123
+ // Check if greyNodeStyle is of type CustomNodeStyle
124
+ const greyNodeStyle = props.greyNodeStyle;
125
+ if (greyNodeStyle) {
126
+ if (greyNodeStyle.backgroundColor && typeof greyNodeStyle.backgroundColor !== 'string') {
127
+ console.error('Error: greyNodeStyle.backgroundColor should be a string.');
128
+ }
129
+ if (greyNodeStyle.color && typeof greyNodeStyle.color !== 'string') {
130
+ console.error('Error: greyNodeStyle.color should be a string.');
131
+ }
132
+ if (greyNodeStyle.padding && typeof greyNodeStyle.padding !== 'string') {
133
+ console.error('Error: greyNodeStyle.padding should be a string.');
134
+ }
135
+ if (greyNodeStyle.borderRadius && typeof greyNodeStyle.borderRadius !== 'string') {
136
+ console.error('Error: greyNodeStyle.borderRadius should be a string.');
137
+ }
138
+ }
139
+ // Check if orgData is an array of OrgDataItem objects
140
+ if (!Array.isArray(props.orgData)) {
141
+ console.error('Error: orgData should be an array.');
142
+ }
143
+ else {
144
+ props.orgData.forEach(item => checkOrgDataItem(item));
145
+ }
146
+ };
147
+ const checkOrgDataItem = (item) => {
148
+ if (item.label !== undefined && typeof item.label !== 'string') {
149
+ console.error('Error: OrgDataItem label should be a string.');
150
+ }
151
+ if (item.expanded !== undefined && typeof item.expanded !== 'boolean') {
152
+ console.error('Error: OrgDataItem expanded should be a boolean.');
153
+ }
154
+ if (item.description !== undefined && typeof item.description !== 'string') {
155
+ console.error('Error: OrgDataItem description should be a string.');
156
+ }
157
+ if (item.customNodeStyle !== undefined) {
158
+ const customNodeStyle = item.customNodeStyle;
159
+ if (customNodeStyle.backgroundColor && typeof customNodeStyle.backgroundColor !== 'string') {
160
+ console.error('Error: customNodeStyle.backgroundColor should be a string.');
161
+ }
162
+ if (customNodeStyle.color && typeof customNodeStyle.color !== 'string') {
163
+ console.error('Error: customNodeStyle.color should be a string.');
164
+ }
165
+ if (customNodeStyle.padding && typeof customNodeStyle.padding !== 'string') {
166
+ console.error('Error: customNodeStyle.padding should be a string.');
167
+ }
168
+ if (customNodeStyle.borderRadius && typeof customNodeStyle.borderRadius !== 'string') {
169
+ console.error('Error: customNodeStyle.borderRadius should be a string.');
170
+ }
171
+ }
172
+ if (!item.data || typeof item.data.title !== 'string') {
173
+ console.error('Error: OrgDataItem data.title should be a string.');
174
+ }
175
+ else {
176
+ if (item.data.image !== undefined && typeof item.data.image !== 'string') {
177
+ console.error('Error: OrgDataItem data.image should be a string.');
178
+ }
179
+ if (item.data.name !== undefined && typeof item.data.name !== 'string') {
180
+ console.error('Error: OrgDataItem data.name should be a string.');
181
+ }
182
+ }
183
+ if (item.children && Array.isArray(item.children)) {
184
+ item.children.forEach(child => checkOrgDataItem(child)); // Recursive call for children
185
+ }
186
+ if (item.originalStyle) {
187
+ const originalStyle = item.originalStyle;
188
+ if (originalStyle.backgroundColor && typeof originalStyle.backgroundColor !== 'string') {
189
+ console.error('Error: originalStyle.backgroundColor should be a string.');
190
+ }
191
+ if (originalStyle.color && typeof originalStyle.color !== 'string') {
192
+ console.error('Error: originalStyle.color should be a string.');
193
+ }
194
+ if (originalStyle.padding && typeof originalStyle.padding !== 'string') {
195
+ console.error('Error: originalStyle.padding should be a string.');
196
+ }
197
+ if (originalStyle.borderRadius && typeof originalStyle.borderRadius !== 'string') {
198
+ console.error('Error: originalStyle.borderRadius should be a string.');
199
+ }
200
+ }
202
201
  };
203
202
 
204
- /** Displays an organizational chart with nodes and relationships (Org Chart Component) */
205
- class OrgChartComponent {
206
- constructor() {
207
- this.searchText = '';
208
- this.hoveredNode = null;
209
- }
210
- /** Initializes the component */
211
- ngOnInit() {
212
- let updatedJson = this.addDefaultKeysIfNotAvailable(this.rucInputData);
213
- this.rucInputData.orgData = this.updateRucInputData(updatedJson.orgData);
214
- checkPropsType(this.rucInputData); // To check rucInputData is in correct format or not
215
- this.expandAllNodes();
216
- }
217
- /** add default property for grey nodes if user does not provided */
218
- addDefaultKeysIfNotAvailable(orgData) {
219
- if (!orgData.hasOwnProperty('greyNodeStyle')) {
220
- orgData.greyNodeStyle = {
221
- backgroundColor: '#d3d3d3',
222
- color: '#808080',
223
- };
224
- }
225
- return orgData;
226
- }
227
- /** manipulate input json as If customNodeStyle exists, create originalStyle for node and its children */
228
- updateRucInputData(data) {
229
- return data.map((node) => {
230
- node['type'] = 'person';
231
- if (node.customNodeStyle) {
232
- node.originalStyle = { ...node.customNodeStyle };
233
- }
234
- if (node.children && node.children.length > 0) {
235
- node['type'] = 'person';
236
- node.children = this.updateRucInputData(node.children); // Recursive call
237
- }
238
- return node;
239
- });
240
- }
241
- /** Expands all nodes in the org chart */
242
- expandAllNodes() {
243
- this.rucInputData.orgData = this.expandNodes(this.rucInputData.orgData);
244
- }
245
- /** Recursively expands all nodes in the given array
246
- * @param nodes Nodes to expand @returns Expanded nodes */
247
- expandNodes(nodes) {
248
- return nodes.map((node) => ({
249
- ...node,
250
- expanded: true,
251
- children: node.children ? this.expandNodes(node.children) : [],
252
- }));
253
- }
254
- /** Collapses all nodes in the org chart */
255
- collapseAllNodes() {
256
- this.rucInputData.orgData = this.collapseNodes(this.rucInputData.orgData);
257
- }
258
- /** Recursively collapses all nodes in the given array
259
- * @param nodes Nodes to collapse @returns Collapsed nodes */
260
- collapseNodes(nodes) {
261
- return nodes.map((node) => ({
262
- ...node,
263
- expanded: false,
264
- children: node.children ? this.collapseNodes(node.children) : [],
265
- }));
266
- }
267
- /** Gets the background color of a node based on search text
268
- @param node Node to check @returns Whether the node matches the search text */
269
- getBackgroungColorOfNode(node) {
270
- return (!this.searchText ||
271
- node.data.title.toLowerCase().includes(this.searchText.toLowerCase()) ||
272
- node.data.name.toLowerCase().includes(this.searchText.toLowerCase()) ||
273
- node.label?.toLowerCase().includes(this.searchText.toLowerCase()));
274
- }
275
- /** Handles node hover event @param node Hovered node */
276
- onNodeHover(node) {
277
- if (this.searchText)
278
- return;
279
- this.hoveredNode = node;
280
- this.updateNodeStyles();
281
- }
282
- /** Handles node leave event */
283
- onNodeLeave() {
284
- this.hoveredNode = null;
285
- this.resetNodeStyles();
286
- }
287
- /** Updates node styles based on the hovered node */
288
- updateNodeStyles() {
289
- this.applyStyles(this.rucInputData.orgData, true);
290
- }
291
- /** Resets node styles to their original state */
292
- resetNodeStyles() {
293
- this.applyStyles(this.rucInputData.orgData, false);
294
- }
295
- /** Applies grey node style to non-matching nodes @param nodes Nodes to apply styles to */
296
- applyGreyNodes(nodes) {
297
- nodes.forEach((node) => {
298
- const isMatching = this.searchText
299
- ? node.data?.title.includes(this.searchText)
300
- : false;
301
- node.customNodeStyle = isMatching
302
- ? node.customNodeStyle || node.originalStyle
303
- : {
304
- ...node.originalStyle,
305
- backgroundColor: this.rucInputData.greyNodeStyle.backgroundColor,
306
- color: this.rucInputData.greyNodeStyle.color,
307
- };
308
- if (node.children) {
309
- this.applyGreyNodes(node.children);
310
- }
311
- });
312
- }
313
- /** Applies styles to nodes based on the hovered node
314
- * @param nodes Nodes to apply styles @param isHovered Whether the node is hovered */
315
- applyStyles(nodes, isHovered) {
316
- nodes.forEach((node) => {
317
- if (isHovered) {
318
- node.customNodeStyle =
319
- node === this.hoveredNode ||
320
- this.isParent(node, this.hoveredNode) ||
321
- this.isChild(node, this.hoveredNode)
322
- ? node.customNodeStyle || node.originalStyle
323
- : {
324
- ...node.originalStyle,
325
- backgroundColor: this.rucInputData.greyNodeStyle.backgroundColor,
326
- color: this.rucInputData.greyNodeStyle.color,
327
- };
328
- }
329
- else {
330
- node.customNodeStyle = node.originalStyle;
331
- }
332
- if (node.children) {
333
- this.applyStyles(node.children, isHovered);
334
- }
335
- });
336
- }
337
- /** Use the downloadChart utility method */
338
- downloadChart(format) {
339
- const chartContainer = this.orgChart.el.nativeElement;
340
- downloadChart(chartContainer, format); // Calls the utility function
341
- }
342
- /** Handles menu click event @param id Menu item ID */
343
- onMenuClick(id, event) {
344
- event.preventDefault();
345
- event.stopPropagation();
346
- switch (id) {
347
- case 1:
348
- this.downloadChart('pdf');
349
- break;
350
- case 2:
351
- this.downloadChart('png');
352
- break;
353
- case 3:
354
- this.downloadChart('jpeg');
355
- break;
356
- case 4:
357
- this.expandAllNodes();
358
- break;
359
- case 5:
360
- this.collapseAllNodes();
361
- break;
362
- default:
363
- console.warn(`Unknown menu item ID: ${id}. Please enter valid id.`);
364
- break;
365
- }
366
- }
367
- /** Gets tooltip data for a node @param node Node to get tooltip data */
368
- getTooltipData(node) {
369
- return node.description || '';
370
- }
371
- /** Checks if a node is a parent of another node.
372
- * @param currentNode The current node to check.
373
- * @param hoveredNode The node to check for parentage.
374
- * @returns Whether the current node is a parent of the hovered node. */
375
- isParent(currentNode, hoveredNode) {
376
- return hoveredNode && currentNode.children?.includes(hoveredNode);
377
- }
378
- /** Checks if a node is a child of another node.
379
- * @param node The node to check for child status
380
- * @param target The node to check for parentage.
381
- * @returns Whether the node is a child of the target node.*/
382
- isChild(node, target) {
383
- return target && target.children?.includes(node);
384
- }
385
- }
386
- OrgChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OrgChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
387
- OrgChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OrgChartComponent, selector: "uxp-org-chart", inputs: { rucInputData: "rucInputData", customTheme: "customTheme" }, viewQueries: [{ propertyName: "orgChart", first: true, predicate: ["orgChart"], descendants: true }], ngImport: i0, template: "<div class={{customTheme}}>\r\n <div class=\"container\">\r\n <!-- Hamburger Menu -->\r\n <button *ngIf=\"rucInputData.isDisplayHambergerMenu === true\" mat-icon-button [matMenuTriggerFor]=\"menu\" \r\n class=\"left hamburger-button\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n \r\n <!-- Menu -->\r\n <mat-menu #menu=\"matMenu\">\r\n <button *ngFor=\"let menu of rucInputData.hambergerMenuList\" mat-menu-item (click)=\"onMenuClick(menu.id, $event);\" \r\n [id]=\"'menu-item-' + menu.id\">\r\n {{ menu.label }}\r\n </button>\r\n </mat-menu>\r\n \r\n <!-- Search Bar -->\r\n <mat-form-field *ngIf=\"rucInputData.isDisplaySearchBar === true\" class=\"search-box right\" \r\n >\r\n <mat-label>Search</mat-label>\r\n <input matInput placeholder=\"Type to search...\" [(ngModel)]=\"searchText\" />\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n </div>\r\n \r\n \r\n <div class=\"org-chart-container \" id=\"org-chart-data\">\r\n <p-organizationChart #orgChart class=\"org-chart\" [value]=\"this.rucInputData.orgData\" selectionMode=\"multiple\"\r\n [(selection)]=\"selectedNodes\">\r\n <ng-template let-node pTemplate=\"person\">\r\n <div *ngIf=\"this.rucInputData.nodeTemplate === 'portrait'\" class=\"flex flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\"> \r\n <div class=\"flex flex-col items-center\" >\r\n <span><img *ngIf=\"node.data.image\" [src]=\"node.data.image\" class=\"portraitImageDimension\" /></span>\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div *ngIf=\"this.rucInputData.nodeTemplate === 'triangle'\" class=\"flex trianlge-up flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\"> \r\n <div class=\"flex flex-col items-center\" >\r\n <div *ngIf=\"!node.data.image\" class=\"triangleImageDimension\">\r\n </div>\r\n <img *ngIf=\"node.data.image\" [src]=\"node.data.image\" class=\"triangleImageDimension\" />\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"this.rucInputData.nodeTemplate === 'landscape'\">\r\n <div class=\"card borderSolidGrey\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\"\r\n (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"body\" >\r\n <div class=\"icon\">\r\n <img *ngIf=\"node.data.image\" [src]=\"node.data.image\" class=\"landscapeImageDimension\" />\r\n </div>\r\n <div class=\"content\">\r\n <div>{{node.data.name}}</div>\r\n <div>{{node.data.title}}</div>\r\n </div>\r\n </div> \r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-organizationChart>\r\n </div>\r\n \r\n</div>", styles: [".org-chart-container{overflow-x:auto}.nodeContent{border:none;padding:1.5em;border-radius:\"8px\";background-color:none;color:#000}.card{display:flex;width:250px;height:100px;padding:24px;align-self:stretch;align-items:flex-start}.card .body{width:100%;display:flex}.card .body .icon{width:64px;height:64px}.trianlge-up{width:220px;background-color:#980104;clip-path:polygon(50% 0%,0% 100%,100% 100%)}mat-form-field{margin:10px}::ng-deep .p-organizationchart .p-organizationchart-node-content{border:none;background:none;color:#495057;padding:0!important}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler{background-color:#dee2e6;cursor:pointer}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon{top:.2rem}.container{display:flex;justify-content:space-between;width:100%}.container .left{margin-right:auto}.container .right{margin-left:auto}mat-icon-button{margin-right:10px}.mat-form-field{margin-left:10px}.borderSolidGrey{border:1px solid lightgray}.landscapeImageDimension{width:3em;height:3em}.portraitImageDimension,.triangleImageDimension{margin-bottom:4px;width:3em;height:3em}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.OrganizationChart, selector: "p-organizationChart", inputs: ["value", "style", "styleClass", "selectionMode", "preserveSpace", "selection"], outputs: ["selectionChange", "onNodeSelect", "onNodeUnselect", "onNodeExpand", "onNodeCollapse"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
388
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OrgChartComponent, decorators: [{
389
- type: Component,
390
- args: [{ selector: 'uxp-org-chart', template: "<div class={{customTheme}}>\r\n <div class=\"container\">\r\n <!-- Hamburger Menu -->\r\n <button *ngIf=\"rucInputData.isDisplayHambergerMenu === true\" mat-icon-button [matMenuTriggerFor]=\"menu\" \r\n class=\"left hamburger-button\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n \r\n <!-- Menu -->\r\n <mat-menu #menu=\"matMenu\">\r\n <button *ngFor=\"let menu of rucInputData.hambergerMenuList\" mat-menu-item (click)=\"onMenuClick(menu.id, $event);\" \r\n [id]=\"'menu-item-' + menu.id\">\r\n {{ menu.label }}\r\n </button>\r\n </mat-menu>\r\n \r\n <!-- Search Bar -->\r\n <mat-form-field *ngIf=\"rucInputData.isDisplaySearchBar === true\" class=\"search-box right\" \r\n >\r\n <mat-label>Search</mat-label>\r\n <input matInput placeholder=\"Type to search...\" [(ngModel)]=\"searchText\" />\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n </div>\r\n \r\n \r\n <div class=\"org-chart-container \" id=\"org-chart-data\">\r\n <p-organizationChart #orgChart class=\"org-chart\" [value]=\"this.rucInputData.orgData\" selectionMode=\"multiple\"\r\n [(selection)]=\"selectedNodes\">\r\n <ng-template let-node pTemplate=\"person\">\r\n <div *ngIf=\"this.rucInputData.nodeTemplate === 'portrait'\" class=\"flex flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\"> \r\n <div class=\"flex flex-col items-center\" >\r\n <span><img *ngIf=\"node.data.image\" [src]=\"node.data.image\" class=\"portraitImageDimension\" /></span>\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div *ngIf=\"this.rucInputData.nodeTemplate === 'triangle'\" class=\"flex trianlge-up flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\"> \r\n <div class=\"flex flex-col items-center\" >\r\n <div *ngIf=\"!node.data.image\" class=\"triangleImageDimension\">\r\n </div>\r\n <img *ngIf=\"node.data.image\" [src]=\"node.data.image\" class=\"triangleImageDimension\" />\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"this.rucInputData.nodeTemplate === 'landscape'\">\r\n <div class=\"card borderSolidGrey\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\"\r\n (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"body\" >\r\n <div class=\"icon\">\r\n <img *ngIf=\"node.data.image\" [src]=\"node.data.image\" class=\"landscapeImageDimension\" />\r\n </div>\r\n <div class=\"content\">\r\n <div>{{node.data.name}}</div>\r\n <div>{{node.data.title}}</div>\r\n </div>\r\n </div> \r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-organizationChart>\r\n </div>\r\n \r\n</div>", styles: [".org-chart-container{overflow-x:auto}.nodeContent{border:none;padding:1.5em;border-radius:\"8px\";background-color:none;color:#000}.card{display:flex;width:250px;height:100px;padding:24px;align-self:stretch;align-items:flex-start}.card .body{width:100%;display:flex}.card .body .icon{width:64px;height:64px}.trianlge-up{width:220px;background-color:#980104;clip-path:polygon(50% 0%,0% 100%,100% 100%)}mat-form-field{margin:10px}::ng-deep .p-organizationchart .p-organizationchart-node-content{border:none;background:none;color:#495057;padding:0!important}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler{background-color:#dee2e6;cursor:pointer}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon{top:.2rem}.container{display:flex;justify-content:space-between;width:100%}.container .left{margin-right:auto}.container .right{margin-left:auto}mat-icon-button{margin-right:10px}.mat-form-field{margin-left:10px}.borderSolidGrey{border:1px solid lightgray}.landscapeImageDimension{width:3em;height:3em}.portraitImageDimension,.triangleImageDimension{margin-bottom:4px;width:3em;height:3em}\n"] }]
391
- }], propDecorators: { rucInputData: [{
392
- type: Input
393
- }], customTheme: [{
394
- type: Input
395
- }], orgChart: [{
396
- type: ViewChild,
397
- args: ['orgChart', { static: false }]
203
+ class RuclibOrgChartComponent {
204
+ constructor() {
205
+ this.searchText = '';
206
+ this.hoveredNode = null;
207
+ }
208
+ /** Initializes the component */
209
+ ngOnInit() {
210
+ const updatedJson = this.addDefaultKeysIfNotAvailable(this.rucInputData);
211
+ this.rucInputData.orgData = this.updateRucInputData(updatedJson.orgData);
212
+ checkPropsType(this.rucInputData); // To check rucInputData is in correct format or not
213
+ this.expandAllNodes();
214
+ }
215
+ /** add default property for grey nodes if user does not provided */
216
+ addDefaultKeysIfNotAvailable(orgData) {
217
+ if (!orgData.hasOwnProperty('greyNodeStyle')) {
218
+ orgData.greyNodeStyle = {
219
+ backgroundColor: '#d3d3d3',
220
+ color: '#808080',
221
+ };
222
+ }
223
+ return orgData;
224
+ }
225
+ /** manipulate input json as If customNodeStyle exists, create originalStyle for node and its children */
226
+ updateRucInputData(data) {
227
+ return data.map((node) => {
228
+ node['type'] = 'person';
229
+ if (node.customNodeStyle) {
230
+ node.originalStyle = { ...node.customNodeStyle };
231
+ }
232
+ if (node.children && node.children.length > 0) {
233
+ node['type'] = 'person';
234
+ node.children = this.updateRucInputData(node.children); // Recursive call
235
+ }
236
+ return node;
237
+ });
238
+ }
239
+ /** Expands all nodes in the org chart */
240
+ expandAllNodes() {
241
+ this.rucInputData.orgData = this.expandNodes(this.rucInputData.orgData);
242
+ }
243
+ /** Recursively expands all nodes in the given array
244
+ * @param nodes Nodes to expand @returns Expanded nodes */
245
+ expandNodes(nodes) {
246
+ return nodes.map((node) => ({
247
+ ...node,
248
+ expanded: true,
249
+ children: node.children ? this.expandNodes(node.children) : [],
250
+ }));
251
+ }
252
+ /** Collapses all nodes in the org chart */
253
+ collapseAllNodes() {
254
+ this.rucInputData.orgData = this.collapseNodes(this.rucInputData.orgData);
255
+ }
256
+ /** Recursively collapses all nodes in the given array
257
+ * @param nodes Nodes to collapse @returns Collapsed nodes */
258
+ collapseNodes(nodes) {
259
+ return nodes.map((node) => ({
260
+ ...node,
261
+ expanded: false,
262
+ children: node.children ? this.collapseNodes(node.children) : [],
263
+ }));
264
+ }
265
+ /** Gets the background color of a node based on search text
266
+ @param node Node to check @returns Whether the node matches the search text */
267
+ getBackgroungColorOfNode(node) {
268
+ return (!this.searchText ||
269
+ node.data.title.toLowerCase().includes(this.searchText.toLowerCase()) ||
270
+ node.data.name.toLowerCase().includes(this.searchText.toLowerCase()) ||
271
+ node.label?.toLowerCase().includes(this.searchText.toLowerCase()));
272
+ }
273
+ /** Handles node hover event @param node Hovered node */
274
+ onNodeHover(node) {
275
+ if (this.searchText)
276
+ return;
277
+ this.hoveredNode = node;
278
+ this.updateNodeStyles();
279
+ }
280
+ /** Handles node leave event */
281
+ onNodeLeave() {
282
+ this.hoveredNode = null;
283
+ this.resetNodeStyles();
284
+ }
285
+ /** Updates node styles based on the hovered node */
286
+ updateNodeStyles() {
287
+ this.applyStyles(this.rucInputData.orgData, true);
288
+ }
289
+ /** Resets node styles to their original state */
290
+ resetNodeStyles() {
291
+ this.applyStyles(this.rucInputData.orgData, false);
292
+ }
293
+ /** Applies grey node style to non-matching nodes @param nodes Nodes to apply styles to */
294
+ applyGreyNodes(nodes) {
295
+ nodes.forEach((node) => {
296
+ const isMatching = this.searchText
297
+ ? node.data?.title.includes(this.searchText)
298
+ : false;
299
+ node.customNodeStyle = isMatching
300
+ ? node.customNodeStyle || node.originalStyle
301
+ : {
302
+ ...node.originalStyle,
303
+ backgroundColor: this.rucInputData.greyNodeStyle.backgroundColor,
304
+ color: this.rucInputData.greyNodeStyle.color,
305
+ };
306
+ if (node.children) {
307
+ this.applyGreyNodes(node.children);
308
+ }
309
+ });
310
+ }
311
+ /** Applies styles to nodes based on the hovered node
312
+ * @param nodes Nodes to apply styles @param isHovered Whether the node is hovered */
313
+ applyStyles(nodes, isHovered) {
314
+ nodes.forEach((node) => {
315
+ if (isHovered) {
316
+ node.customNodeStyle =
317
+ node === this.hoveredNode ||
318
+ this.isParent(node, this.hoveredNode) ||
319
+ this.isChild(node, this.hoveredNode)
320
+ ? node.customNodeStyle || node.originalStyle
321
+ : {
322
+ ...node.originalStyle,
323
+ backgroundColor: this.rucInputData.greyNodeStyle.backgroundColor,
324
+ color: this.rucInputData.greyNodeStyle.color,
325
+ };
326
+ }
327
+ else {
328
+ node.customNodeStyle = node.originalStyle;
329
+ }
330
+ if (node.children) {
331
+ this.applyStyles(node.children, isHovered);
332
+ }
333
+ });
334
+ }
335
+ /** Use the downloadChart utility method */
336
+ downloadChart(format) {
337
+ const chartContainer = this.orgChart.el.nativeElement;
338
+ downloadChart(chartContainer, format); // Calls the utility function
339
+ }
340
+ /** Handles menu click event @param id Menu item ID */
341
+ onMenuClick(id, event) {
342
+ event.preventDefault();
343
+ event.stopPropagation();
344
+ switch (id) {
345
+ case 1:
346
+ this.downloadChart('pdf');
347
+ break;
348
+ case 2:
349
+ this.downloadChart('png');
350
+ break;
351
+ case 3:
352
+ this.downloadChart('jpeg');
353
+ break;
354
+ case 4:
355
+ this.expandAllNodes();
356
+ break;
357
+ case 5:
358
+ this.collapseAllNodes();
359
+ break;
360
+ default:
361
+ console.warn(`Unknown menu item ID: ${id}. Please enter valid id.`);
362
+ break;
363
+ }
364
+ }
365
+ /** Gets tooltip data for a node @param node Node to get tooltip data */
366
+ getTooltipData(node) {
367
+ return node.description || '';
368
+ }
369
+ /** Checks if a node is a parent of another node.
370
+ * @param currentNode The current node to check.
371
+ * @param hoveredNode The node to check for parentage.
372
+ * @returns Whether the current node is a parent of the hovered node. */
373
+ isParent(currentNode, hoveredNode) {
374
+ return hoveredNode && currentNode.children?.includes(hoveredNode);
375
+ }
376
+ /** Checks if a node is a child of another node.
377
+ * @param node The node to check for child status
378
+ * @param target The node to check for parentage.
379
+ * @returns Whether the node is a child of the target node.*/
380
+ isChild(node, target) {
381
+ return target && target.children?.includes(node);
382
+ }
383
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibOrgChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
384
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: RuclibOrgChartComponent, isStandalone: true, selector: "uxp-ruclib-org-chart", inputs: { rucInputData: "rucInputData", customTheme: "customTheme" }, viewQueries: [{ propertyName: "orgChart", first: true, predicate: ["orgChart"], descendants: true }], ngImport: i0, template: "<div class={{customTheme}}>\r\n <div class=\"container\">\r\n <!-- Hamburger Menu -->\r\n @if (rucInputData.isDisplayHambergerMenu === true) {\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\"\r\n class=\"left hamburger-button\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n }\r\n\r\n <!-- Menu -->\r\n <mat-menu #menu=\"matMenu\">\r\n @for (menu of rucInputData.hambergerMenuList; track menu) {\r\n <button mat-menu-item (click)=\"onMenuClick(menu.id, $event);\"\r\n [id]=\"'menu-item-' + menu.id\">\r\n {{ menu.label }}\r\n </button>\r\n }\r\n </mat-menu>\r\n\r\n <!-- Search Bar -->\r\n @if (rucInputData.isDisplaySearchBar === true) {\r\n <mat-form-field class=\"search-box right\"\r\n >\r\n <mat-label>Search</mat-label>\r\n <input matInput placeholder=\"Type to search...\" [(ngModel)]=\"searchText\" />\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n }\r\n </div>\r\n\r\n\r\n <div class=\"org-chart-container \" id=\"org-chart-data\">\r\n <p-organizationChart #orgChart class=\"org-chart\" [value]=\"this.rucInputData.orgData\" selectionMode=\"multiple\"\r\n [(selection)]=\"selectedNodes\">\r\n <ng-template let-node pTemplate=\"person\">\r\n @if (this.rucInputData.nodeTemplate === 'portrait') {\r\n <div class=\"flex flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"flex flex-col items-center\" >\r\n <span>@if (node.data.image) {\r\n <img [src]=\"node.data.image\" class=\"portraitImageDimension\" />\r\n }</span>\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (this.rucInputData.nodeTemplate === 'triangle') {\r\n <div class=\"flex trianlge-up flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"flex flex-col items-center\" >\r\n @if (!node.data.image) {\r\n <div class=\"triangleImageDimension\">\r\n </div>\r\n }\r\n @if (node.data.image) {\r\n <img [src]=\"node.data.image\" class=\"triangleImageDimension\" />\r\n }\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n @if (this.rucInputData.nodeTemplate === 'landscape') {\r\n <div>\r\n <div class=\"card borderSolidGrey\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\"\r\n (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"body\" >\r\n <div class=\"icon\">\r\n @if (node.data.image) {\r\n <img [src]=\"node.data.image\" class=\"landscapeImageDimension\" />\r\n }\r\n </div>\r\n <div class=\"content\">\r\n <div>{{node.data.name}}</div>\r\n <div>{{node.data.title}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </p-organizationChart>\r\n </div>\r\n\r\n</div>\r\n", styles: [".org-chart-container{overflow-x:auto}.nodeContent{border:none;padding:1.5em;border-radius:\"8px\";background-color:none;color:#000}.card{display:flex;width:250px;height:100px;padding:24px;align-self:stretch;align-items:flex-start}.card .body{width:100%;display:flex}.card .body .icon{width:64px;height:64px}.trianlge-up{width:220px;background-color:#980104;clip-path:polygon(50% 0%,0% 100%,100% 100%)}mat-form-field{margin:10px}::ng-deep .p-organizationchart .p-organizationchart-node-content{border:none;background:none;color:#495057;padding:0!important}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler{background-color:#dee2e6;cursor:pointer}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon{top:.2rem}.container{display:flex;justify-content:space-between;width:100%}.container .left{margin-right:auto}.container .right{margin-left:auto}mat-icon-button{margin-right:10px}.mat-form-field{margin-left:10px}.borderSolidGrey{border:1px solid lightgray}.landscapeImageDimension{width:3em;height:3em}.portraitImageDimension,.triangleImageDimension{margin-bottom:4px;width:3em;height:3em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: OrganizationChartModule }, { kind: "component", type: i7.OrganizationChart, selector: "p-organizationChart", inputs: ["value", "style", "styleClass", "selectionMode", "collapsible", "preserveSpace", "selection"], outputs: ["selectionChange", "onNodeSelect", "onNodeUnselect", "onNodeExpand", "onNodeCollapse"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
385
+ }
386
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibOrgChartComponent, decorators: [{
387
+ type: Component,
388
+ args: [{ selector: 'uxp-ruclib-org-chart', imports: [CommonModule, MatIconModule, MatButtonModule, MatFormFieldModule, MatInputModule, MatMenuModule, OrganizationChartModule, FormsModule], template: "<div class={{customTheme}}>\r\n <div class=\"container\">\r\n <!-- Hamburger Menu -->\r\n @if (rucInputData.isDisplayHambergerMenu === true) {\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\"\r\n class=\"left hamburger-button\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n }\r\n\r\n <!-- Menu -->\r\n <mat-menu #menu=\"matMenu\">\r\n @for (menu of rucInputData.hambergerMenuList; track menu) {\r\n <button mat-menu-item (click)=\"onMenuClick(menu.id, $event);\"\r\n [id]=\"'menu-item-' + menu.id\">\r\n {{ menu.label }}\r\n </button>\r\n }\r\n </mat-menu>\r\n\r\n <!-- Search Bar -->\r\n @if (rucInputData.isDisplaySearchBar === true) {\r\n <mat-form-field class=\"search-box right\"\r\n >\r\n <mat-label>Search</mat-label>\r\n <input matInput placeholder=\"Type to search...\" [(ngModel)]=\"searchText\" />\r\n <mat-icon matSuffix>search</mat-icon>\r\n </mat-form-field>\r\n }\r\n </div>\r\n\r\n\r\n <div class=\"org-chart-container \" id=\"org-chart-data\">\r\n <p-organizationChart #orgChart class=\"org-chart\" [value]=\"this.rucInputData.orgData\" selectionMode=\"multiple\"\r\n [(selection)]=\"selectedNodes\">\r\n <ng-template let-node pTemplate=\"person\">\r\n @if (this.rucInputData.nodeTemplate === 'portrait') {\r\n <div class=\"flex flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"flex flex-col items-center\" >\r\n <span>@if (node.data.image) {\r\n <img [src]=\"node.data.image\" class=\"portraitImageDimension\" />\r\n }</span>\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (this.rucInputData.nodeTemplate === 'triangle') {\r\n <div class=\"flex trianlge-up flex-col nodeContent\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\" (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"flex flex-col items-center\" >\r\n @if (!node.data.image) {\r\n <div class=\"triangleImageDimension\">\r\n </div>\r\n }\r\n @if (node.data.image) {\r\n <img [src]=\"node.data.image\" class=\"triangleImageDimension\" />\r\n }\r\n <div class=\"font-bold mb-2\">{{ node.data.name }}</div>\r\n <div>{{ node.data.title }}\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n @if (this.rucInputData.nodeTemplate === 'landscape') {\r\n <div>\r\n <div class=\"card borderSolidGrey\" [ngStyle]=\"getBackgroungColorOfNode(node) ? node.customNodeStyle : rucInputData.greyNodeStyle\"\r\n (mouseenter)=\"onNodeHover(node)\"\r\n [title]=\"getTooltipData(node)\" (mouseleave)=\"onNodeLeave()\">\r\n <div class=\"body\" >\r\n <div class=\"icon\">\r\n @if (node.data.image) {\r\n <img [src]=\"node.data.image\" class=\"landscapeImageDimension\" />\r\n }\r\n </div>\r\n <div class=\"content\">\r\n <div>{{node.data.name}}</div>\r\n <div>{{node.data.title}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </p-organizationChart>\r\n </div>\r\n\r\n</div>\r\n", styles: [".org-chart-container{overflow-x:auto}.nodeContent{border:none;padding:1.5em;border-radius:\"8px\";background-color:none;color:#000}.card{display:flex;width:250px;height:100px;padding:24px;align-self:stretch;align-items:flex-start}.card .body{width:100%;display:flex}.card .body .icon{width:64px;height:64px}.trianlge-up{width:220px;background-color:#980104;clip-path:polygon(50% 0%,0% 100%,100% 100%)}mat-form-field{margin:10px}::ng-deep .p-organizationchart .p-organizationchart-node-content{border:none;background:none;color:#495057;padding:0!important}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler{background-color:#dee2e6;cursor:pointer}::ng-deep .p-organizationchart .p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon{top:.2rem}.container{display:flex;justify-content:space-between;width:100%}.container .left{margin-right:auto}.container .right{margin-left:auto}mat-icon-button{margin-right:10px}.mat-form-field{margin-left:10px}.borderSolidGrey{border:1px solid lightgray}.landscapeImageDimension{width:3em;height:3em}.portraitImageDimension,.triangleImageDimension{margin-bottom:4px;width:3em;height:3em}\n"] }]
389
+ }], propDecorators: { rucInputData: [{
390
+ type: Input
391
+ }], customTheme: [{
392
+ type: Input
393
+ }], orgChart: [{
394
+ type: ViewChild,
395
+ args: ['orgChart', { static: false }]
398
396
  }] } });
399
397
 
400
- class RuclibOrgChartModule {
401
- }
402
- RuclibOrgChartModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibOrgChartModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
403
- RuclibOrgChartModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: RuclibOrgChartModule, declarations: [OrgChartComponent], imports: [CommonModule, ButtonModule, BrowserModule, FormsModule, OrganizationChartModule, MatInputModule, MatMenuModule, MatButtonModule, MatIconModule], exports: [OrgChartComponent] });
404
- RuclibOrgChartModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibOrgChartModule, imports: [CommonModule, ButtonModule, BrowserModule, FormsModule, OrganizationChartModule, MatInputModule, MatMenuModule, MatButtonModule, MatIconModule] });
405
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibOrgChartModule, decorators: [{
406
- type: NgModule,
407
- args: [{
408
- imports: [CommonModule, ButtonModule, BrowserModule, FormsModule, OrganizationChartModule, MatInputModule, MatMenuModule, MatButtonModule, MatIconModule],
409
- declarations: [OrgChartComponent],
410
- exports: [OrgChartComponent]
411
- }]
412
- }] });
413
-
414
- // export * from './services/org-chart.service';
415
-
416
- /**
417
- * Generated bundle index. Do not edit.
398
+ /**
399
+ * Generated bundle index. Do not edit.
418
400
  */
419
401
 
420
- export { OrgChartComponent, RuclibOrgChartModule };
402
+ export { RuclibOrgChartComponent };
421
403
  //# sourceMappingURL=ruc-lib-org-chart.mjs.map