PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / org-chart / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/org-chart/frontend.js

146 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2
3 function hexLuma(hex) {
4 if (!hex) return 0;
5 var c = hex.replace('#','');
6 if (c.length === 3) c = c[0]+c[0]+c[1]+c[1]+c[2]+c[2];
7 var r = parseInt(c.substr(0,2),16), g = parseInt(c.substr(2,2),16), b = parseInt(c.substr(4,2),16);
8 return 0.299*r + 0.587*g + 0.114*b;
9 }
10
11 function buildTree(nodes) {
12 var map = {};
13 nodes.forEach(function (n) { map[n.id] = Object.assign({}, n, { children: [] }); });
14 var roots = [];
15 nodes.forEach(function (n) {
16 if (!n.parentId || !map[n.parentId]) { roots.push(map[n.id]); }
17 else { map[n.parentId].children.push(map[n.id]); }
18 });
19 return roots;
20 }
21
22 function buildNodeEl(node, opts, depth, allCards) {
23 var wrap = document.createElement('div');
24 wrap.className = 'bkbg-oc-node-wrap';
25 wrap.setAttribute('data-id', node.id);
26
27 /* connector line upward (drawn by parent actually) */
28
29 var card = document.createElement('div');
30 card.className = 'bkbg-oc-card';
31 card.style.borderColor = node.color || '';
32
33 /* Avatar */
34 if (opts.showAvatars) {
35 var av = document.createElement('div');
36 av.className = 'bkbg-oc-avatar';
37 av.style.background = node.color || '';
38 if (node.avatarUrl) {
39 var img = document.createElement('img');
40 img.src = node.avatarUrl;
41 img.alt = node.name;
42 av.appendChild(img);
43 } else {
44 var sp = document.createElement('span');
45 sp.className = 'bkbg-oc-avatar-initial';
46 sp.textContent = (node.name || '?').charAt(0).toUpperCase();
47 av.appendChild(sp);
48 }
49 card.appendChild(av);
50 }
51
52 var nameEl = document.createElement('p'); nameEl.className = 'bkbg-oc-name'; nameEl.textContent = node.name; card.appendChild(nameEl);
53 var roleEl = document.createElement('p'); roleEl.className = 'bkbg-oc-role'; roleEl.textContent = node.role; card.appendChild(roleEl);
54 if (opts.showDept && node.department) {
55 var deptEl = document.createElement('p'); deptEl.className = 'bkbg-oc-dept'; deptEl.textContent = node.department; card.appendChild(deptEl);
56 }
57
58 /* Collapse toggle */
59 if (opts.collapse && node.children && node.children.length > 0) {
60 card.style.cursor = 'pointer';
61 card.title = 'Click to expand/collapse';
62 card.addEventListener('click', function () { wrap.classList.toggle('is-collapsed'); });
63 }
64
65 allCards.push(card);
66 wrap.appendChild(card);
67
68 if (node.children && node.children.length > 0) {
69 /* vertical line down */
70 var vDown = document.createElement('div');
71 vDown.className = 'bkbg-oc-conn-v-down';
72 wrap.appendChild(vDown);
73
74 if (node.children.length > 1) {
75 var hLine = document.createElement('div');
76 hLine.className = 'bkbg-oc-conn-h';
77 wrap.appendChild(hLine);
78 }
79
80 var row = document.createElement('div');
81 row.className = 'bkbg-oc-children-row';
82 node.children.forEach(function (child) {
83 var childWrap = buildNodeEl(child, opts, depth + 1, allCards);
84 /* connector up for child */
85 var vUp = document.createElement('div');
86 vUp.className = 'bkbg-oc-conn-v-up';
87 childWrap.insertBefore(vUp, childWrap.firstChild);
88 row.appendChild(childWrap);
89 });
90 wrap.appendChild(row);
91 }
92
93 return wrap;
94 }
95
96 function initOrgChart(wrapper) {
97 if (wrapper.dataset.initialized) return;
98 wrapper.dataset.initialized = '1';
99
100 var treeEl = wrapper.querySelector('.bkbg-oc-tree');
101 if (!treeEl) return;
102
103 var nodes = [];
104 try { nodes = JSON.parse(treeEl.getAttribute('data-nodes') || '[]'); } catch (e) {}
105
106 var opts = {
107 showAvatars: treeEl.getAttribute('data-show-avatars') === '1',
108 showDept: treeEl.getAttribute('data-show-dept') === '1',
109 collapse: treeEl.getAttribute('data-collapse') === '1',
110 };
111
112 treeEl.innerHTML = '';
113 treeEl.style.display = 'flex';
114 treeEl.style.flexDirection = 'column';
115 treeEl.style.alignItems = 'center';
116 treeEl.style.minWidth = 'max-content';
117
118 var allCards = [];
119 var roots = buildTree(nodes);
120 roots.forEach(function (root) {
121 treeEl.appendChild(buildNodeEl(root, opts, 0, allCards));
122 });
123
124 /* Fade-in per card */
125 if ('IntersectionObserver' in window) {
126 var obs = new IntersectionObserver(function (entries) {
127 entries.forEach(function (e, idx) {
128 if (e.isIntersecting) {
129 setTimeout(function () { e.target.classList.add('is-visible'); }, idx * 80);
130 obs.unobserve(e.target);
131 }
132 });
133 }, { threshold: 0.2 });
134 allCards.forEach(function (c) { obs.observe(c); });
135 } else {
136 allCards.forEach(function (c) { c.classList.add('is-visible'); });
137 }
138 }
139
140 function init() {
141 document.querySelectorAll('.bkbg-oc-wrapper').forEach(initOrgChart);
142 }
143
144 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); }
145 }());
146