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 / feature-request / index.js

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

177 lines 13.0 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 PanelColorSettings = wp.blockEditor.PanelColorSettings;
5 var useBlockProps = wp.blockEditor.useBlockProps;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var TextControl = wp.components.TextControl;
8 var TextareaControl = wp.components.TextareaControl;
9 var ToggleControl = wp.components.ToggleControl;
10 var RangeControl = wp.components.RangeControl;
11 var SelectControl = wp.components.SelectControl;
12 var PanelBody = wp.components.PanelBody;
13 var Button = wp.components.Button;
14 var __ = wp.i18n.__;
15
16 var _frTC, _frTV;
17 function _tc() { return _frTC || (_frTC = window.bkbgTypographyControl); }
18 function _tv() { return _frTV || (_frTV = window.bkbgTypoCssVars); }
19
20 var statusOptions = [
21 { label: 'Planned', value: 'planned' },
22 { label: 'In Progress', value: 'in-progress' },
23 { label: 'Done', value: 'done' },
24 { label: 'Under Review', value: 'under-review' },
25 { label: 'Declined', value: 'declined' }
26 ];
27
28 function upd(arr, idx, field, val) {
29 return arr.map(function (e, i) {
30 if (i !== idx) return e;
31 var u = {}; u[field] = val;
32 return Object.assign({}, e, u);
33 });
34 }
35
36 function statusInfo(s, a) {
37 var map = {
38 'planned': { label: 'Planned', bg: a.plannedBg, color: a.plannedColor },
39 'in-progress': { label: 'In Progress', bg: a.inProgressBg, color: a.inProgressColor },
40 'done': { label: 'Done', bg: a.doneBg, color: a.doneColor },
41 'declined': { label: 'Declined', bg: a.declinedBg, color: a.declinedColor },
42 'under-review': { label: 'Under Review', bg: a.underReviewBg, color: a.underReviewColor }
43 };
44 return map[s] || map['planned'];
45 }
46
47 function renderCard(req, a, lh) {
48 var si = statusInfo(req.status, a);
49 var card = el('div', {
50 className: 'bkbg-fr-card',
51 style: { background: a.cardBg, border: '1px solid ' + a.borderColor, borderRadius: a.cardRadius + 'px' }
52 },
53 el('div', { className: 'bkbg-fr-card-top' },
54 el('div', { className: 'bkbg-fr-card-info' },
55 el('div', { className: 'bkbg-fr-card-title', style: { color: a.cardTitleColor } }, req.title),
56 el('div', { className: 'bkbg-fr-card-desc', style: { color: a.cardDescColor } }, req.description)
57 ),
58 a.showVotes && el('div', { className: 'bkbg-fr-votes', style: { background: a.votesBg, color: a.votesColor } },
59 el('span', { className: 'bkbg-fr-votes-arrow' }, ''),
60 el('span', null, req.votes)
61 )
62 ),
63 el('div', { className: 'bkbg-fr-card-bottom' },
64 el('span', { className: 'bkbg-fr-status-badge', style: { background: si.bg, color: si.color } }, si.label),
65 a.showCategory && req.category && el('span', { className: 'bkbg-fr-category', style: { background: a.categoryBg, color: a.categoryColor } }, req.category),
66 a.showDate && req.date && el('span', { className: 'bkbg-fr-date', style: { color: a.dateColor } }, req.date)
67 )
68 );
69 return card;
70 }
71
72 wp.blocks.registerBlockType('blockenberg/feature-request', {
73 edit: function (props) {
74 var a = props.attributes;
75 var setAttr = props.setAttributes;
76 var lh = (a.lineHeight / 100).toFixed(2);
77
78 function sortedRequests() {
79 return a.requests.slice().sort(function (x, y) { return y.votes - x.votes; });
80 }
81
82 return el(Fragment, null,
83 el(InspectorControls, null,
84 el(PanelBody, { title: __('Board Settings'), initialOpen: true },
85 el(TextControl, { label: __('Board Title'), value: a.boardTitle, onChange: function (v) { setAttr({ boardTitle: v }); }, __nextHasNoMarginBottom: true }),
86 el(TextareaControl, { label: __('Description'), value: a.description, onChange: function (v) { setAttr({ description: v }); }, __nextHasNoMarginBottom: true }),
87 el(ToggleControl, { label: __('Show Description'), checked: a.showDescription, onChange: function (v) { setAttr({ showDescription: v }); }, __nextHasNoMarginBottom: true }),
88 el(ToggleControl, { label: __('Show Votes'), checked: a.showVotes, onChange: function (v) { setAttr({ showVotes: v }); }, __nextHasNoMarginBottom: true }),
89 el(ToggleControl, { label: __('Show Category'), checked: a.showCategory, onChange: function (v) { setAttr({ showCategory: v }); }, __nextHasNoMarginBottom: true }),
90 el(ToggleControl, { label: __('Show Date'), checked: a.showDate, onChange: function (v) { setAttr({ showDate: v }); }, __nextHasNoMarginBottom: true })
91 ),
92 el(PanelBody, { title: __('Requests'), initialOpen: false },
93 a.requests.map(function (req, i) {
94 return el('div', { key: i, style: { border: '1px solid #e2e8f0', borderRadius: 8, padding: 12, marginBottom: 12, background: '#fafafa' } },
95 el('strong', { style: { display: 'block', marginBottom: 6 } }, 'Request ' + (i + 1)),
96 el(TextControl, { label: __('Title'), value: req.title, onChange: function (v) { setAttr({ requests: upd(a.requests, i, 'title', v) }); }, __nextHasNoMarginBottom: true }),
97 el(TextareaControl, { label: __('Description'), value: req.description, onChange: function (v) { setAttr({ requests: upd(a.requests, i, 'description', v) }); }, __nextHasNoMarginBottom: true }),
98 el(TextControl, { label: __('Votes'), type: 'number', value: String(req.votes), onChange: function (v) { setAttr({ requests: upd(a.requests, i, 'votes', parseInt(v, 10) || 0) }); }, __nextHasNoMarginBottom: true }),
99 el(SelectControl, { label: __('Status'), value: req.status, options: statusOptions, onChange: function (v) { setAttr({ requests: upd(a.requests, i, 'status', v) }); }, __nextHasNoMarginBottom: true }),
100 el(TextControl, { label: __('Category'), value: req.category, onChange: function (v) { setAttr({ requests: upd(a.requests, i, 'category', v) }); }, __nextHasNoMarginBottom: true }),
101 el(TextControl, { label: __('Date'), value: req.date, onChange: function (v) { setAttr({ requests: upd(a.requests, i, 'date', v) }); }, __nextHasNoMarginBottom: true }),
102 el(Button, { isDestructive: true, variant: 'secondary', onClick: function () { setAttr({ requests: a.requests.filter(function (_, j) { return j !== i; }) }); } }, __('Remove'))
103 );
104 }),
105 el(Button, { variant: 'primary', onClick: function () { setAttr({ requests: a.requests.concat([{ title: 'New Feature Request', description: 'Describe the feature here.', votes: 0, status: 'under-review', category: 'General', date: '' }]) }); } }, __('+ Add Request'))
106 ),
107 el(PanelBody, { title: __('Typography'), initialOpen: false },
108 _tc() && el(_tc(), {
109 label: __('Board Title Typography', 'blockenberg'),
110 value: a.typoTitle,
111 onChange: function (v) { setAttr({ typoTitle: v }); }
112 }),
113 _tc() && el(_tc(), {
114 label: __('Body Typography', 'blockenberg'),
115 value: a.typoBody,
116 onChange: function (v) { setAttr({ typoBody: v }); }
117 }),
118 _tc() && el(_tc(), {
119 label: __('Card Title Typography', 'blockenberg'),
120 value: a.typoCardTitle,
121 onChange: function (v) { setAttr({ typoCardTitle: v }); }
122 })
123 ),
124 el(PanelColorSettings, {
125 title: __('Layout Colors'),
126 initialOpen: false,
127 colorSettings: [
128 { label: __('Background'), value: a.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#f8fafc' }); } },
129 { label: __('Card Background'), value: a.cardBg, onChange: function (v) { setAttr({ cardBg: v || '#ffffff' }); } },
130 { label: __('Border'), value: a.borderColor, onChange: function (v) { setAttr({ borderColor: v || '#e2e8f0' }); } },
131 { label: __('Board Title'), value: a.titleColor, onChange: function (v) { setAttr({ titleColor: v || '#0f172a' }); } },
132 { label: __('Board Description'), value: a.descColor, onChange: function (v) { setAttr({ descColor: v || '#64748b' }); } },
133 { label: __('Card Title'), value: a.cardTitleColor, onChange: function (v) { setAttr({ cardTitleColor: v || '#1e293b' }); } },
134 { label: __('Card Description'), value: a.cardDescColor, onChange: function (v) { setAttr({ cardDescColor: v || '#64748b' }); } },
135 { label: __('Votes BG'), value: a.votesBg, onChange: function (v) { setAttr({ votesBg: v || '#f1f5f9' }); } },
136 { label: __('Votes Text'), value: a.votesColor, onChange: function (v) { setAttr({ votesColor: v || '#334155' }); } },
137 { label: __('Category BG'), value: a.categoryBg, onChange: function (v) { setAttr({ categoryBg: v || '#f1f5f9' }); } },
138 { label: __('Category Text'), value: a.categoryColor, onChange: function (v) { setAttr({ categoryColor: v || '#475569' }); } },
139 { label: __('Date Text'), value: a.dateColor, onChange: function (v) { setAttr({ dateColor: v || '#94a3b8' }); } }
140 ]
141 }),
142 el(PanelColorSettings, {
143 title: __('Status Badge Colors'),
144 initialOpen: false,
145 colorSettings: [
146 { label: __('Planned BG'), value: a.plannedBg, onChange: function (v) { setAttr({ plannedBg: v || '#dbeafe' }); } },
147 { label: __('Planned Text'), value: a.plannedColor, onChange: function (v) { setAttr({ plannedColor: v || '#1e40af' }); } },
148 { label: __('In Progress BG'), value: a.inProgressBg, onChange: function (v) { setAttr({ inProgressBg: v || '#ede9fe' }); } },
149 { label: __('In Progress Text'), value: a.inProgressColor, onChange: function (v) { setAttr({ inProgressColor: v || '#5b21b6' }); } },
150 { label: __('Done BG'), value: a.doneBg, onChange: function (v) { setAttr({ doneBg: v || '#dcfce7' }); } },
151 { label: __('Done Text'), value: a.doneColor, onChange: function (v) { setAttr({ doneColor: v || '#14532d' }); } },
152 { label: __('Declined BG'), value: a.declinedBg, onChange: function (v) { setAttr({ declinedBg: v || '#fee2e2' }); } },
153 { label: __('Declined Text'), value: a.declinedColor, onChange: function (v) { setAttr({ declinedColor: v || '#991b1b' }); } },
154 { label: __('Under Review BG'), value: a.underReviewBg, onChange: function (v) { setAttr({ underReviewBg: v || '#fef9c3' }); } },
155 { label: __('Under Review Text'), value: a.underReviewColor, onChange: function (v) { setAttr({ underReviewColor: v || '#713f12' }); } }
156 ]
157 })
158 ),
159 el('div', useBlockProps({ className: 'bkbg-fr-wrap', style: Object.assign({ background: a.bgColor, borderRadius: a.borderRadius + 'px', padding: 32 }, _tv()(a.typoTitle, '--bkbg-fr-tt-'), _tv()(a.typoBody, '--bkbg-fr-bd-'), _tv()(a.typoCardTitle, '--bkbg-fr-ct-')) }),
160 el('div', { className: 'bkbg-fr-header' },
161 el('h2', { className: 'bkbg-fr-title', style: { color: a.titleColor } }, a.boardTitle),
162 a.showDescription && el('p', { className: 'bkbg-fr-desc', style: { color: a.descColor } }, a.description)
163 ),
164 el('div', { className: 'bkbg-fr-grid' },
165 sortedRequests().map(function (req, i) { return renderCard(req, a, lh); })
166 )
167 )
168 );
169 },
170 save: function (props) {
171 return el('div', useBlockProps.save(),
172 el('div', { className: 'bkbg-feature-request-app', 'data-opts': JSON.stringify(props.attributes) })
173 );
174 }
175 });
176 }() );
177