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 / commit-history / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/commit-history/index.js

349 lines 19.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 var el = wp.element.createElement;
3 var Fragment = wp.element.Fragment;
4 var registerBlockType = wp.blocks.registerBlockType;
5 var __ = wp.i18n.__;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var PanelBody = wp.components.PanelBody;
10 var TextControl = wp.components.TextControl;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var Button = wp.components.Button;
14 var SelectControl = wp.components.SelectControl;
15
16 function getTypographyControl() { return (window.bkbgTypographyControl || function () { return null; }); }
17 function getTypoCssVars() { return (window.bkbgTypoCssVars || function () { return {}; }); }
18 function _tv(typo, prefix) { var fn = getTypoCssVars(); return fn(typo || {}, prefix); }
19
20 // ── helpers ────────────────────────────────────────────────────
21 function upd(arr, idx, field, val) {
22 return arr.map(function (e, i) {
23 if (i !== idx) return e;
24 var u = {}; u[field] = val;
25 return Object.assign({}, e, u);
26 });
27 }
28
29 // detect prefix from commit message (feat / fix / chore / docs / refactor / etc.)
30 function getPrefix(msg) {
31 var m = msg.match(/^(\w+)[\s:!]/);
32 return m ? m[1].toLowerCase() : '';
33 }
34
35 // convert author name to 1–2 initials
36 function initials(name) {
37 var parts = (name || 'A').trim().split(/\s+/);
38 if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
39 return parts[0][0].toUpperCase();
40 }
41
42 // color for prefix type badge
43 function prefixColor(prefix, a) {
44 if (prefix === 'feat') return a.featColor;
45 if (prefix === 'fix') return a.fixColor;
46 if (prefix === 'chore') return a.choreColor;
47 if (prefix === 'docs') return a.docsColor;
48 if (prefix === 'refactor') return a.refactorColor;
49 return a.choreColor;
50 }
51
52 // ── row renderer ───────────────────────────────────────────────
53 function renderCommitRow(commit, a, idx, isLast) {
54 var prefix = getPrefix(commit.message);
55 var msgText = commit.message;
56 var initText = initials(commit.author);
57
58 // Left timeline column
59 var dot = el('div', {
60 style: {
61 width: '10px', height: '10px',
62 borderRadius: '50%',
63 background: a.dotColor,
64 flexShrink: '0',
65 marginTop: '5px',
66 position: 'relative',
67 zIndex: '1',
68 boxShadow: '0 0 0 3px ' + a.bgColor + ', 0 0 0 5px ' + a.dotColor + '22'
69 }
70 });
71 var line = !isLast ? el('div', {
72 style: {
73 width: '2px',
74 flex: '1',
75 background: a.lineColor,
76 margin: '4px auto 0',
77 minHeight: '24px'
78 }
79 }) : null;
80 var leftCol = el('div', {
81 style: { display: 'flex', flexDirection: 'column', alignItems: 'center', width: '20px', flexShrink: '0', marginTop: '2px' }
82 }, dot, line);
83
84 // Avatar
85 var avatar = a.showAuthorInitials ? el('div', {
86 style: {
87 width: '26px', height: '26px', borderRadius: '50%',
88 background: a.authorBg,
89 color: a.authorColor,
90 display: 'flex', alignItems: 'center', justifyContent: 'center',
91 fontSize: '11px', fontWeight: '700', flexShrink: '0'
92 }
93 }, initText) : null;
94
95 // Prefix type badge
96 var prefixBadge = prefix ? el('span', {
97 style: {
98 fontSize: '11px', fontWeight: '600',
99 color: prefixColor(prefix, a),
100 marginRight: '6px', letterSpacing: '0.02em'
101 }
102 }, prefix) : null;
103
104 // Tags
105 var tagEls = (a.showTags && commit.tags && commit.tags.length) ? commit.tags.map(function (tag) {
106 return el('span', {
107 style: {
108 display: 'inline-flex', alignItems: 'center',
109 background: a.tagBg, color: a.tagColor,
110 borderRadius: '4px', padding: '1px 7px',
111 fontSize: '11px', fontWeight: '600', letterSpacing: '0.04em',
112 marginLeft: '6px'
113 }
114 }, '🏷 ' + tag);
115 }) : [];
116
117 // Message row (prefix badge + message text + tags)
118 var msgRow = el('div', { style: { display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '4px', marginBottom: '6px' } },
119 prefixBadge,
120 el('span', { className: 'bkcmh-msg', style: { color: a.messageColor } }, msgText)
121 );
122 var tagRow = tagEls.length ? el('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '4px', marginBottom: '6px' } }, tagEls) : null;
123
124 // Meta row (avatar + author + hash + date)
125 var hashSpan = a.showHash ? el('span', {
126 className: 'bkcmh-hash',
127 style: {
128 color: a.hashColor,
129 background: a.tagBg,
130 borderRadius: '4px', padding: '1px 6px'
131 }
132 }, commit.hash) : null;
133 var authorSpan = el('span', { className: 'bkcmh-meta', style: { color: a.authorColor } }, commit.author);
134 var dateSpan = a.showDate ? el('span', { className: 'bkcmh-meta', style: { color: a.dateColor, marginLeft: 'auto' } }, commit.date) : null;
135
136 var metaRow = el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap' } },
137 avatar, authorSpan, hashSpan, dateSpan
138 );
139
140 var rightCol = el('div', {
141 style: { flex: '1', minWidth: '0', paddingBottom: !isLast ? '16px' : '0' }
142 }, msgRow, tagRow, metaRow);
143
144 return el('div', {
145 key: idx,
146 style: { display: 'flex', gap: '14px' }
147 }, leftCol, rightCol);
148 }
149
150 // ── edit ───────────────────────────────────────────────────────
151 function Edit(props) {
152 var a = props.attributes;
153 var set = props.setAttributes;
154
155 // colour panel definitions
156 var themeColors = [
157 { label: __('Background'), value: a.bgColor, onChange: function (v) { set({ bgColor: v || '#0f172a' }); } },
158 { label: __('Header BG'), value: a.headerBg, onChange: function (v) { set({ headerBg: v || '#1e293b' }); } },
159 { label: __('Border'), value: a.borderColor, onChange: function (v) { set({ borderColor: v || '#1e293b' }); } },
160 { label: __('Repo Name'), value: a.repoColor, onChange: function (v) { set({ repoColor: v || '#f8fafc' }); } },
161 { label: __('Branch BG'), value: a.branchBg, onChange: function (v) { set({ branchBg: v || '#166534' }); } },
162 { label: __('Branch Text'),value: a.branchColor, onChange: function (v) { set({ branchColor: v || '#4ade80' }); } },
163 { label: __('Commit Dot'), value: a.dotColor, onChange: function (v) { set({ dotColor: v || '#3b82f6' }); } },
164 { label: __('Branch Line'),value: a.lineColor, onChange: function (v) { set({ lineColor: v || '#1e3a5f' }); } },
165 { label: __('Hash Badge'), value: a.hashColor, onChange: function (v) { set({ hashColor: v || '#60a5fa' }); } },
166 { label: __('Message'), value: a.messageColor, onChange: function (v) { set({ messageColor: v || '#e2e8f0' }); } },
167 { label: __('Avatar BG'), value: a.authorBg, onChange: function (v) { set({ authorBg: v || '#334155' }); } },
168 { label: __('Author Text'),value: a.authorColor, onChange: function (v) { set({ authorColor: v || '#94a3b8' }); } },
169 { label: __('Date Text'), value: a.dateColor, onChange: function (v) { set({ dateColor: v || '#64748b' }); } },
170 { label: __('Tag BG'), value: a.tagBg, onChange: function (v) { set({ tagBg: v || '#1e3a5f' }); } },
171 { label: __('Tag Text'), value: a.tagColor, onChange: function (v) { set({ tagColor: v || '#60a5fa' }); } },
172 ];
173 var typeColors = [
174 { label: __('feat'), value: a.featColor, onChange: function (v) { set({ featColor: v || '#4ade80' }); } },
175 { label: __('fix'), value: a.fixColor, onChange: function (v) { set({ fixColor: v || '#f87171' }); } },
176 { label: __('chore'), value: a.choreColor, onChange: function (v) { set({ choreColor: v || '#94a3b8' }); } },
177 { label: __('docs'), value: a.docsColor, onChange: function (v) { set({ docsColor: v || '#fbbf24' }); } },
178 { label: __('refactor'), value: a.refactorColor, onChange: function (v) { set({ refactorColor: v || '#a78bfa' }); } },
179 ];
180
181 // Inspector
182 var inspector = el(InspectorControls, {},
183 // Repo / display settings
184 el(PanelBody, { title: __('Repository'), initialOpen: true },
185 el(TextControl, {
186 label: __('Repo name'), value: a.repoName, __nextHasNoMarginBottom: true,
187 onChange: function (v) { set({ repoName: v }); }
188 }),
189 el(TextControl, {
190 label: __('Branch'), value: a.branchName, __nextHasNoMarginBottom: true,
191 onChange: function (v) { set({ branchName: v }); }
192 }),
193 el(ToggleControl, {
194 label: __('Show branch badge'), checked: a.showBranch, __nextHasNoMarginBottom: true,
195 onChange: function (v) { set({ showBranch: v }); }
196 }),
197 el(ToggleControl, {
198 label: __('Show hash'), checked: a.showHash, __nextHasNoMarginBottom: true,
199 onChange: function (v) { set({ showHash: v }); }
200 }),
201 el(ToggleControl, {
202 label: __('Show author avatar'), checked: a.showAuthorInitials, __nextHasNoMarginBottom: true,
203 onChange: function (v) { set({ showAuthorInitials: v }); }
204 }),
205 el(ToggleControl, {
206 label: __('Show date'), checked: a.showDate, __nextHasNoMarginBottom: true,
207 onChange: function (v) { set({ showDate: v }); }
208 }),
209 el(ToggleControl, {
210 label: __('Show version tags'), checked: a.showTags, __nextHasNoMarginBottom: true,
211 onChange: function (v) { set({ showTags: v }); }
212 })
213 ),
214 // Typography
215 el(PanelBody, { title: __('Typography'), initialOpen: false },
216 el(getTypographyControl(), { label: __('Message', 'blockenberg'), value: a.typoMessage, onChange: function (v) { set({ typoMessage: v }); } }),
217 el(getTypographyControl(), { label: __('Meta', 'blockenberg'), value: a.typoMeta, onChange: function (v) { set({ typoMeta: v }); } })
218 ),
219 // Appearance
220 el(PanelBody, { title: __('Appearance'), initialOpen: false },
221 el(RangeControl, {
222 label: __('Border radius'), value: a.borderRadius, min: 0, max: 32, __nextHasNoMarginBottom: true,
223 onChange: function (v) { set({ borderRadius: v }); }
224 })
225 ),
226 // Commits editor
227 el(PanelBody, { title: __('Commits (' + a.commits.length + ')'), initialOpen: false },
228 a.commits.map(function (c, idx) {
229 return el(PanelBody, {
230 key: idx,
231 title: (idx + 1) + '. ' + c.message.substring(0, 32) + (c.message.length > 32 ? '' : ''),
232 initialOpen: false
233 },
234 el(TextControl, {
235 label: __('Commit message'), value: c.message, __nextHasNoMarginBottom: true,
236 onChange: function (v) { set({ commits: upd(a.commits, idx, 'message', v) }); }
237 }),
238 el(TextControl, {
239 label: __('Short hash (7 chars)'), value: c.hash, __nextHasNoMarginBottom: true,
240 onChange: function (v) { set({ commits: upd(a.commits, idx, 'hash', v) }); }
241 }),
242 el(TextControl, {
243 label: __('Author name'), value: c.author, __nextHasNoMarginBottom: true,
244 onChange: function (v) { set({ commits: upd(a.commits, idx, 'author', v) }); }
245 }),
246 el(TextControl, {
247 label: __('Date'), value: c.date, __nextHasNoMarginBottom: true,
248 onChange: function (v) { set({ commits: upd(a.commits, idx, 'date', v) }); }
249 }),
250 el(TextControl, {
251 label: __('Tags (comma-separated)'), value: (c.tags || []).join(', '), __nextHasNoMarginBottom: true,
252 onChange: function (v) {
253 var tags = v.split(',').map(function (t) { return t.trim(); }).filter(Boolean);
254 set({ commits: upd(a.commits, idx, 'tags', tags) });
255 }
256 }),
257 el(Button, {
258 variant: 'secondary', isDestructive: true, __nextHasNoMarginBottom: true,
259 onClick: function () {
260 var next = a.commits.slice(); next.splice(idx, 1);
261 set({ commits: next });
262 }
263 }, __('Remove commit'))
264 );
265 }),
266 el(Button, {
267 variant: 'primary', __nextHasNoMarginBottom: true,
268 onClick: function () {
269 set({ commits: a.commits.concat([{ hash: 'a1b2c3d', message: 'feat: add new feature', author: 'Author Name', date: 'Jan 1, 2026', tags: [] }]) });
270 }
271 }, __('+ Add commit'))
272 ),
273 // Colors
274 el(PanelColorSettings, {
275 title: __('Theme Colors'),
276 initialOpen: false,
277 colorSettings: themeColors
278 }),
279 el(PanelColorSettings, {
280 title: __('Type Prefix Colors'),
281 initialOpen: false,
282 colorSettings: typeColors
283 })
284 );
285
286 // ── Preview ───────────────────────────────────────────────
287 // Header traffic lights
288 var dots = el('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
289 el('span', { style: { width: '12px', height: '12px', borderRadius: '50%', background: '#ef4444', display: 'block' } }),
290 el('span', { style: { width: '12px', height: '12px', borderRadius: '50%', background: '#f59e0b', display: 'block' } }),
291 el('span', { style: { width: '12px', height: '12px', borderRadius: '50%', background: '#22c55e', display: 'block' } })
292 );
293 var repoSpan = el('span', { style: { color: a.repoColor, fontWeight: '700', fontSize: (a.fontSize + 1) + 'px', letterSpacing: '0.01em' } },
294 '📁 ' + a.repoName
295 );
296 var branchBadge = a.showBranch ? el('span', {
297 style: {
298 display: 'inline-flex', alignItems: 'center', gap: '5px',
299 background: a.branchBg, color: a.branchColor,
300 borderRadius: '20px', padding: '2px 10px',
301 fontSize: '12px', fontWeight: '600'
302 }
303 },
304 el('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: a.branchColor, display: 'inline-block' } }),
305 a.branchName
306 ) : null;
307
308 var header = el('div', {
309 style: {
310 display: 'flex', alignItems: 'center', gap: '12px', flexWrap: 'wrap',
311 padding: '12px 16px',
312 background: a.headerBg,
313 borderBottom: '1px solid ' + a.borderColor,
314 borderRadius: a.borderRadius + 'px ' + a.borderRadius + 'px 0 0'
315 }
316 }, dots, repoSpan, branchBadge);
317
318 var body = el('div', { style: { padding: '20px 20px 12px' } },
319 a.commits.map(function (c, idx) {
320 return renderCommitRow(c, a, idx, idx === a.commits.length - 1);
321 })
322 );
323
324 var wrapStyle = Object.assign({
325 background: a.bgColor,
326 border: '1px solid ' + a.borderColor,
327 borderRadius: a.borderRadius + 'px',
328 overflow: 'hidden',
329 fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
330 }, _tv(a.typoMessage, '--bkcmh-msg-'), _tv(a.typoMeta, '--bkcmh-meta-'));
331
332 return el(Fragment, {},
333 inspector,
334 el('div', Object.assign({}, useBlockProps(), { style: wrapStyle }), header, body)
335 );
336 }
337
338 registerBlockType('blockenberg/commit-history', {
339 edit: Edit,
340 save: function (props) {
341 var a = props.attributes;
342 var sv = Object.assign({}, _tv(a.typoMessage, '--bkcmh-msg-'), _tv(a.typoMeta, '--bkcmh-meta-'));
343 return el('div', useBlockProps.save({ style: sv }),
344 el('div', { className: 'bkbg-commit-history-app', 'data-opts': JSON.stringify(a) })
345 );
346 }
347 });
348 })();
349