Skip to content

Commit 47815cb

Browse files
committed
ALDASH-497 bar component
ALDASH-497 bar component
1 parent 2396df1 commit 47815cb

3 files changed

Lines changed: 549 additions & 0 deletions

File tree

Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
import {InspectorControls, MediaUpload, PanelColorSettings, useBlockProps} from '@wordpress/block-editor';
2+
import {
3+
Panel,
4+
PanelBody,
5+
PanelRow,
6+
ResizableBox,
7+
SelectControl,
8+
TextControl,
9+
FontSizePicker,
10+
__experimentalText as Text,
11+
ToggleControl,
12+
TextareaControl
13+
} from '@wordpress/components';
14+
import {__} from '@wordpress/i18n';
15+
import {BlockEditWithAPIMetadata, SizeConfig} from '@devgateway/dvz-wp-commons'
16+
import {CSVSourceConfig} from '@devgateway/dvz-wp-commons';
17+
import {togglePanel} from '@devgateway/dvz-wp-commons';
18+
import {Measures} from '@devgateway/dvz-wp-commons';
19+
import {DataFilters} from '@devgateway/dvz-wp-commons';
20+
import {isSupersetAPI} from '@devgateway/dvz-wp-commons';
21+
import Format from "../charts/Format.jsx";
22+
import {getTranslation} from '@devgateway/dvz-wp-commons';
23+
24+
25+
class BlockEdit extends BlockEditWithAPIMetadata {
26+
constructor(props) {
27+
super(props);
28+
}
29+
30+
componentDidMount() {
31+
super.componentDidMount()
32+
}
33+
34+
decodeManualColors(manualColors) {
35+
if (!manualColors) return {};
36+
try {
37+
// if it's already decoded JSON, this will just work
38+
let raw = manualColors;
39+
40+
// If it looks like URL-encoded JSON (starts with %7B = '{')
41+
if (typeof raw === 'string' && raw.trim().startsWith('%7B')) {
42+
raw = decodeURIComponent(raw);
43+
}
44+
45+
return JSON.parse(raw);
46+
} catch (e) {
47+
console.warn('Failed to parse manualColors', manualColors, e);
48+
return {};
49+
}
50+
};
51+
52+
catColors(){
53+
const {
54+
attributes: {
55+
app,
56+
dimension1,
57+
manualColors
58+
}
59+
} = this.props;
60+
61+
if (this.state.categories && dimension1 && dimension1 != 'none') {
62+
63+
const colors = this.decodeManualColors(manualColors);
64+
colors[app] = colors[app] || {};
65+
66+
const cat = this.state.categories.filter(d => d.type == dimension1)
67+
if (cat && cat.length > 0) {
68+
const list = cat[0].items.filter(c => c.code !== null && c.code !== undefined && c.code !== "").sort((a, b) => b.position - a.position).map(item => {
69+
return <PanelColorSettings
70+
key={item.code}
71+
colorSettings={[{
72+
value: colors[app][item.code] || (item.categoryStyle ? item.categoryStyle.color : "#3182ce"),
73+
onChange: (color) => {
74+
if (color) {
75+
this.updateColor(item.code, color)
76+
} else {
77+
this.updateColor(item.code, item.categoryStyle ? item.categoryStyle.color : "#3182ce")
78+
}
79+
}, label: getTranslation(item)
80+
}]}
81+
/>
82+
})
83+
84+
return list
85+
} else {
86+
return null
87+
}
88+
}
89+
return null
90+
}
91+
92+
updateColor(value, color) {
93+
const { setAttributes, attributes: { app, manualColors } } = this.props;
94+
95+
const colorsObj = manualColors ? JSON.parse(manualColors) : {};
96+
colorsObj[app] = colorsObj[app] || {};
97+
colorsObj[app][value] = color;
98+
99+
setAttributes({ manualColors: JSON.stringify(colorsObj) });
100+
}
101+
102+
103+
render() {
104+
const {
105+
className, isSelected,
106+
toggleSelection, setAttributes,
107+
attributes: {
108+
measures,
109+
height,
110+
app,
111+
format,
112+
filters,
113+
group,
114+
panelStatus,
115+
dvzProxyDatasetId,
116+
fontSize,
117+
textColor,
118+
backGroundColor,
119+
dimension1,
120+
csv,
121+
type,
122+
waitForFilters,
123+
noDataText,
124+
manualColors,
125+
defaultBarColor,
126+
barBackgroundColor
127+
}
128+
} = this.props;
129+
130+
131+
const datasets = [{label: 'Select Dataset', value: '0'}]
132+
if (this.state.datasets) {
133+
this.state.datasets.forEach(d => {
134+
datasets.push({label: d.label, value: d.id})
135+
})
136+
}
137+
138+
let params = {}
139+
filters.forEach(f => {
140+
if (f.value != null && f.value.filter(v => v != null && v.toString().trim() != "").length > 0)
141+
params[f.param] = f.value
142+
})
143+
const divStyles = {height: height+10 + 'px', width: '100%'}
144+
145+
return ([isSelected && (
146+
<InspectorControls>
147+
148+
<Panel header={__("Chart Configuration")}>
149+
<PanelBody
150+
panelStatus={panelStatus['GROUP']}
151+
onToggle={e => togglePanel("GROUP", panelStatus, setAttributes)}
152+
title={__("Group")}>
153+
<PanelRow>
154+
<TextControl
155+
label={__('Name')}
156+
value={group}
157+
onChange={(group) => setAttributes({group})}
158+
/>
159+
</PanelRow>
160+
<PanelRow>
161+
<ToggleControl
162+
label={__('Wait For Filters')}
163+
checked={waitForFilters}
164+
onChange={() => setAttributes({waitForFilters: !waitForFilters})}
165+
/>
166+
</PanelRow>
167+
</PanelBody>
168+
<SizeConfig setAttributes={setAttributes} panelStatus={panelStatus}
169+
height={height}></SizeConfig>
170+
171+
<>
172+
<PanelBody initialOpen={false} title={__("API & Source")}>
173+
<PanelRow>
174+
<SelectControl
175+
value={[app]}
176+
onChange={(app) => {
177+
setAttributes({
178+
app: app
179+
})
180+
}}
181+
options={this.state.apps}
182+
/>
183+
</PanelRow>
184+
185+
186+
{isSupersetAPI(app, this.state.apps) && <PanelRow>
187+
<SelectControl
188+
label={__('Datasets')}
189+
value={[dvzProxyDatasetId]}
190+
onChange={(newDatasetId) => {
191+
setAttributes({
192+
dvzProxyDatasetId: newDatasetId
193+
})
194+
195+
this.loadMetadata(app, newDatasetId)
196+
}}
197+
options={datasets}
198+
/>
199+
</PanelRow>
200+
}
201+
</PanelBody>
202+
203+
{app != 'csv' && <PanelBody initialOpen={false} title={__("Dimensions")}>
204+
<PanelRow>
205+
<SelectControl
206+
label={__("First Dimension")}
207+
value={[dimension1]}
208+
onChange={(value) => {
209+
setAttributes({
210+
dimension1: value
211+
});
212+
}}
213+
options={this.state.dimensions}
214+
/>
215+
</PanelRow>
216+
</PanelBody>
217+
}
218+
{app == 'csv' &&
219+
<>
220+
<PanelBody initialOpen={false} title={__("CSV Configuration")}
221+
onToggle={e => togglePanel("csv_cfg", panelStatus, setAttributes)}>
222+
<PanelRow>
223+
<TextareaControl
224+
label={__("CSV Data")}
225+
value={csv}
226+
onChange={(csv) => setAttributes({csv})}
227+
/>
228+
</PanelRow>
229+
230+
<Format
231+
hiddenCustomAxisFormat={type == 'radar' || type == 'grouped-bars'}
232+
format={format}
233+
customFormat={{}}
234+
useCustomAxisFormat={false}
235+
onFormatChange={(newFormat, field) => {
236+
console.log("newFormat", newFormat)
237+
setAttributes({format: newFormat})
238+
}}
239+
onUseCustomAxisFormatChange={value => {
240+
}}
241+
>
242+
</Format>
243+
</PanelBody>
244+
</>
245+
}
246+
247+
{app != 'csv' &&
248+
<Measures
249+
title={__(`Measure`)}
250+
onSetSingleMeasure={value => {
251+
setAttributes({measures: [value]})
252+
}}
253+
onFormatChange={value => {
254+
setAttributes({format: value})
255+
}}
256+
allMeasures={this.state.measures}
257+
format={format}
258+
measures={measures}
259+
{...this.props}/>
260+
}
261+
262+
263+
<DataFilters
264+
allFilters={this.state.filters}
265+
allCategories={this.state.categories}
266+
{...this.props}/>
267+
268+
</>
269+
270+
271+
<PanelBody title={__('Settings')} initialOpen={false}>
272+
<PanelRow>
273+
<TextControl
274+
label={__('No Data Text')}
275+
value={noDataText}
276+
onChange={(noDataText) => setAttributes({noDataText})}
277+
/>
278+
</PanelRow>
279+
280+
<PanelRow>
281+
<Text>{__("Font Size")}</Text>
282+
</PanelRow>
283+
<FontSizePicker
284+
fontSizes={[]}
285+
value={fontSize}
286+
fallbackFontSize={14}
287+
onChange={(newFontSize) => {
288+
setAttributes({fontSize: newFontSize})
289+
}}
290+
/>
291+
292+
293+
<PanelColorSettings
294+
title={__('Color Settings')}
295+
colorSettings={[
296+
{
297+
value: textColor, // Label color value
298+
299+
onChange: (color) => {
300+
setAttributes({ textColor: color }); // Update label color
301+
},
302+
label: __("Text Color") // Label for the color picker
303+
},
304+
{
305+
value: backGroundColor, // Percent color value
306+
clearable: true,
307+
enableAlpha: true,
308+
onChange: (color) => {
309+
setAttributes({ backGroundColor: color }); // Update percent color
310+
},
311+
label: __("Back Ground Color") // Label for the color picker
312+
},
313+
{
314+
value: defaultBarColor, // Default Bar color value
315+
316+
onChange: (color) => {
317+
setAttributes({ defaultBarColor: color }); // Update Default Bar color
318+
},
319+
label: __("Default Bar Color") // Label for the color picker
320+
},
321+
{
322+
value: barBackgroundColor, // Bar Background color value
323+
324+
onChange: (color) => {
325+
setAttributes({ barBackgroundColor: color }); // Update Bar Background color
326+
},
327+
label: __("Bar Background Color") // Label for the color picker
328+
}
329+
]}
330+
/>
331+
332+
333+
<PanelBody title={__('Manual Colors')} initialOpen={false}></PanelBody>
334+
{this.catColors()}
335+
</PanelBody>
336+
</Panel>
337+
</InspectorControls>),
338+
(<ResizableBox
339+
size={{height}}
340+
style={{"margin": "auto", width: "100%"}}
341+
minHeight="0"
342+
minWidth="50"
343+
enable={{
344+
top: false,
345+
right: false,
346+
bottom: true,
347+
left: false,
348+
topRight: false,
349+
bottomRight: false,
350+
bottomLeft: false,
351+
topLeft: false,
352+
}}
353+
onResizeStop={(event, direction, elt, delta) => {
354+
setAttributes({
355+
height: parseInt(height + delta.height, 10),
356+
});
357+
toggleSelection(true);
358+
}}
359+
onResizeStart={() => {
360+
toggleSelection(false);
361+
}}>
362+
363+
<div className={className}>
364+
{this.state.react_ui_url && <iframe ref={this.iframe} style={divStyles} scrolling={"no"}
365+
src={this.state.react_ui_url + "/embeddable/groupedbars?"}/>}
366+
367+
</div>
368+
</ResizableBox>
369+
)]
370+
);
371+
372+
}
373+
}
374+
375+
const Edit = (props) => {
376+
const blockProps = useBlockProps();
377+
return <div {...blockProps}><BlockEdit {...props}/></div>;
378+
}
379+
export default Edit;

0 commit comments

Comments
 (0)