Unfinished support for updating attributes
This commit is contained in:
@ -11,6 +11,10 @@
|
|||||||
"html": false
|
"html": false
|
||||||
},
|
},
|
||||||
"attributes": {
|
"attributes": {
|
||||||
|
"selectedDataset": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
"columnTypes": {
|
"columnTypes": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"default": {}
|
"default": {}
|
||||||
@ -39,29 +43,93 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"default": 1
|
"default": 1
|
||||||
},
|
},
|
||||||
"datasets": {
|
"gridColumnDefinitions": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [
|
"default": [
|
||||||
{
|
{
|
||||||
"name": "Data",
|
"name": "Data",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"field": "Department",
|
||||||
|
"dataType": "text",
|
||||||
|
"renderFormat": "text",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 150,
|
||||||
|
"editable": true,
|
||||||
|
"position": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Budget",
|
||||||
|
"dataType": "number",
|
||||||
|
"renderFormat": "currency",
|
||||||
|
"sorted": "asc",
|
||||||
|
"width": 120,
|
||||||
|
"editable": true,
|
||||||
|
"position": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "MeetAt",
|
||||||
|
"dataType": "date",
|
||||||
|
"renderFormat": "datetime",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 150,
|
||||||
|
"editable": true,
|
||||||
|
"position": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Locations",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"field": "State",
|
||||||
|
"dataType": "text",
|
||||||
|
"renderFormat": "text",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 150,
|
||||||
|
"editable": true,
|
||||||
|
"position": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Coordinates",
|
||||||
|
"dataType": "number",
|
||||||
|
"renderFormat": "number",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 120,
|
||||||
|
"editable": true,
|
||||||
|
"position": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"datasets": {
|
||||||
|
"type": "array",
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"name": "Main",
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
"Department": "Sheriffs Office",
|
"Department": "Sheriffs Office",
|
||||||
"Budget": "150",
|
"Budget": 1,
|
||||||
"MeetAt": "2025-01-26T14:30:00Z",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"preferredColor": "red",
|
"preferredColor": "red",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Department": "Assessor",
|
"Department": "Assessor",
|
||||||
"Budget": "100",
|
"Budget": 2,
|
||||||
"MeetAt": "2025-01-26T14:30:00Z",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"preferredColor": "#232323",
|
"preferredColor": "#232323",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Department": "Treasurer",
|
"Department": "Treasurer",
|
||||||
"Budget": "50",
|
"Budget": 3,
|
||||||
"MeetAt": "2025-01-26T14:30:00Z",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"preferredColor": "#E72323",
|
"preferredColor": "#E72323",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<?php return array('dependencies' => array('react', 'react-dom', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '5afb8b4f337b11cc4837');
|
<?php return array('dependencies' => array('react', 'react-dom', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '7a75b5732cbc1928c7a2');
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -11,6 +11,10 @@
|
|||||||
"html": false
|
"html": false
|
||||||
},
|
},
|
||||||
"attributes": {
|
"attributes": {
|
||||||
|
"selectedDataset": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
"columnTypes": {
|
"columnTypes": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"default": {
|
"default": {
|
||||||
@ -41,14 +45,79 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"default": 1
|
"default": 1
|
||||||
},
|
},
|
||||||
|
"gridColumnDefinitions": {
|
||||||
|
"type": "array",
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"name": "Data",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"field": "Department",
|
||||||
|
"dataType": "text",
|
||||||
|
"renderFormat": "text",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 150,
|
||||||
|
"editable": true,
|
||||||
|
"position": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Budget",
|
||||||
|
"dataType": "number",
|
||||||
|
"renderFormat": "currency",
|
||||||
|
"sorted": "asc",
|
||||||
|
"width": 120,
|
||||||
|
"editable": true,
|
||||||
|
"position": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "MeetAt",
|
||||||
|
"dataType": "date",
|
||||||
|
"renderFormat": "datetime",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 150,
|
||||||
|
"editable": true,
|
||||||
|
"position": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Locations",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"field": "State",
|
||||||
|
"dataType": "text",
|
||||||
|
"renderFormat": "text",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 150,
|
||||||
|
"editable": true,
|
||||||
|
"position": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Coordinates",
|
||||||
|
"dataType": "number",
|
||||||
|
"renderFormat": "number",
|
||||||
|
"sorted": "",
|
||||||
|
"width": 120,
|
||||||
|
"editable": true,
|
||||||
|
"position": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"test": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
"datasets": {
|
"datasets": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [{
|
"default": [{
|
||||||
"name": "Data",
|
"name": "Main",
|
||||||
"data": [
|
"data": [
|
||||||
{ "Department": "Sheriffs Office", "Budget": "150", "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "red", "PostContent": "<div> </div>" },
|
{ "Department": "Sheriffs Office", "Budget": 1, "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "red", "PostContent": "<div> </div>" },
|
||||||
{ "Department": "Assessor", "Budget": "100", "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "#232323", "PostContent": "<div> </div>" },
|
{ "Department": "Assessor", "Budget": 2, "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "#232323", "PostContent": "<div> </div>" },
|
||||||
{ "Department": "Treasurer", "Budget": "50", "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "#E72323", "PostContent": "<div> </div>" }
|
{ "Department": "Treasurer", "Budget": 3, "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "#E72323", "PostContent": "<div> </div>" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
|
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
|
||||||
import { ToggleControl, TextControl,PanelBody, ColorPicker, SelectControl, __experimentalNumberControl as NumberControl} from '@wordpress/components';
|
import { ToggleControl, TextControl, PanelBody, ColorPicker, SelectControl, __experimentalNumberControl as NumberControl } from '@wordpress/components';
|
||||||
import './editor.scss';
|
import './editor.scss';
|
||||||
import BarGraph from './components/BarGraph';
|
import BarGraph from './components/BarGraph';
|
||||||
import LCPDatasetBuilder from '../../components/LCPDatasetBuilder';
|
import LCPDatasetBuilder from '../../components/LCPDatasetBuilder';
|
||||||
@ -8,23 +8,18 @@ import LCPDimensionControl from '../../components/LCPDimensionControl';
|
|||||||
import LCPChartBlockSettings from '../../components/LCPChartBlockSettings';
|
import LCPChartBlockSettings from '../../components/LCPChartBlockSettings';
|
||||||
import LCPLegend from '../../components/LCPLegend';
|
import LCPLegend from '../../components/LCPLegend';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function Edit({ attributes, setAttributes }) {
|
export default function Edit({ attributes, setAttributes }) {
|
||||||
|
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{ Label: "Category 1", color: "#ff0000" },
|
{ Label: "Category 1", color: "#ff0000" },
|
||||||
{ Label: "Category 2", color: "#00ff00" },
|
{ Label: "Category 2", color: "#00ff00" },
|
||||||
{ Label: "Category 1", color: "#ff0000" },
|
{ Label: "Category 1", color: "#ff0000" },
|
||||||
{ Label: "Categokhkjhkjhkjhky 2", color: "#00ff00" },
|
{ Label: "Category 2", color: "#00ff00" },
|
||||||
{ Label: "Category 1", color: "#ff0000" },
|
{ Label: "Category 1", color: "#ff0000" },
|
||||||
{ Label: "Category 2", color: "#00ff00" },
|
{ Label: "Category 2", color: "#00ff00" },
|
||||||
{ Label: "Category 1", color: "#ff0000" },
|
{ Label: "Category 1", color: "#ff0000" },
|
||||||
{ Label: "Cat 2", color: "#00ff00" },
|
{ Label: "Category 2", color: "#00ff00" },
|
||||||
{ Label: "Coy 1", color: "#ff0000" },
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -45,18 +40,12 @@ export default function Edit({ attributes, setAttributes }) {
|
|||||||
renderLegend = false,
|
renderLegend = false,
|
||||||
toolbarLocation = 'top',
|
toolbarLocation = 'top',
|
||||||
enableGroupedBars = false,
|
enableGroupedBars = false,
|
||||||
groupedBarsColumn = ''
|
groupedBarsColumn = '',
|
||||||
|
datasets
|
||||||
} = attributes;
|
} = attributes;
|
||||||
|
|
||||||
const blockProps = useBlockProps();
|
const blockProps = useBlockProps();
|
||||||
|
|
||||||
const handleDatasetChange = (newData) => {
|
|
||||||
setAttributes({ chartData: newData });
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...blockProps}>
|
<div {...blockProps}>
|
||||||
<InspectorControls>
|
<InspectorControls>
|
||||||
@ -64,10 +53,10 @@ export default function Edit({ attributes, setAttributes }) {
|
|||||||
<PanelBody title={__('Chart Settings', 'lcp')}>
|
<PanelBody title={__('Chart Settings', 'lcp')}>
|
||||||
<LCPDatasetBuilder
|
<LCPDatasetBuilder
|
||||||
chartType="bar"
|
chartType="bar"
|
||||||
chartData={chartData}
|
datasets={attributes.datasets} // Ensure datasets are passed to the component
|
||||||
onChange={handleDatasetChange}
|
attributes={attributes} // Pass the full attributes
|
||||||
attributes={attributes}
|
setAttributes={setAttributes} // Pass setAttributes to LCPDatasetBuilder
|
||||||
setAttributes={setAttributes}
|
|
||||||
/>
|
/>
|
||||||
{/* Select the source of the hierarchies */}
|
{/* Select the source of the hierarchies */}
|
||||||
<SelectControl
|
<SelectControl
|
||||||
@ -87,7 +76,7 @@ export default function Edit({ attributes, setAttributes }) {
|
|||||||
onChange={(value) => setAttributes({ hierarchicalColumnOrder: value })}
|
onChange={(value) => setAttributes({ hierarchicalColumnOrder: value })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{/* Enable Drilling Down through hierarchies */}
|
{/* Enable Drilling Down through hierarchies */}
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
label={__('Enable Drill Down', 'lcp')}
|
label={__('Enable Drill Down', 'lcp')}
|
||||||
checked={enableDrillDown}
|
checked={enableDrillDown}
|
||||||
@ -108,36 +97,34 @@ export default function Edit({ attributes, setAttributes }) {
|
|||||||
value={chartWidth}
|
value={chartWidth}
|
||||||
onChange={(value) => setAttributes({ chartWidth: value })}
|
onChange={(value) => setAttributes({ chartWidth: value })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
|
|
||||||
{/* Color Settings */}
|
{/* Color Settings */}
|
||||||
<PanelBody title={__('Color Settings', 'lcp-visualize')} initialOpen={true}>
|
<PanelBody title={__('Color Settings', 'lcp-visualize')} initialOpen={true}>
|
||||||
{/* Color Settings */}
|
|
||||||
{/* Select how the colors will be chosen */}
|
|
||||||
<SelectControl
|
<SelectControl
|
||||||
label={__('Color Source', 'lcp')}
|
label={__('Color Source', 'lcp')}
|
||||||
help={__('Select the logic for setting the colors', 'lcp')}
|
help={__('Select the logic for setting the colors', 'lcp')}
|
||||||
value={barsColorSource || 'default'}
|
value={barsColorSource || 'default'}
|
||||||
options={[
|
options={[
|
||||||
{ label: 'Default', value: 'default' }, // Use the default color logic, value: 'option1' },
|
{ label: 'Default', value: 'default' },
|
||||||
{ label: 'Swatch', value: 'swatch' }
|
{ label: 'Swatch', value: 'swatch' }
|
||||||
]}
|
]}
|
||||||
onChange={(value) => setAttributes({ barsColorSource: value })}
|
onChange={(value) => setAttributes({ barsColorSource: value })}
|
||||||
/>
|
/>
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
|
|
||||||
{/* Common Chart Settings */}
|
{/* Common Chart Settings */}
|
||||||
<LCPChartBlockSettings
|
<LCPChartBlockSettings
|
||||||
attributes={attributes}
|
attributes={attributes}
|
||||||
setAttributes={setAttributes}
|
setAttributes={setAttributes}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</InspectorControls>
|
</InspectorControls>
|
||||||
|
|
||||||
<div className="lcp-bar-graph-container">
|
<div className="lcp-bar-graph-container">
|
||||||
{toolbarLocation === 'top' && (
|
{toolbarLocation === 'top' && (
|
||||||
<div className="lcp-visualizer-toolbar">
|
<div className="lcp-visualizer-toolbar">
|
||||||
<span>Toolbar</span>
|
<span>Toolbar</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{renderLegend && (
|
{renderLegend && (
|
||||||
<LCPLegend
|
<LCPLegend
|
||||||
@ -165,7 +152,6 @@ export default function Edit({ attributes, setAttributes }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,40 @@ import { AgGridReact } from 'ag-grid-react';
|
|||||||
import 'ag-grid-community/styles/ag-grid.css';
|
import 'ag-grid-community/styles/ag-grid.css';
|
||||||
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
||||||
|
|
||||||
|
import LCPDataGridHeader from './LCPDataGridHeader';
|
||||||
import LCPGridColorRender from './LCPGridColorRender';
|
import LCPGridColorRender from './LCPGridColorRender';
|
||||||
|
|
||||||
const LCPDataGrid = ({dataset}) => {
|
const LCPDataGrid = ({ dataset, index, updateDataset }) => {
|
||||||
|
|
||||||
|
|
||||||
|
const onCellValueChanged = (event) => {
|
||||||
|
// console.log('Cell value changed. Grid index:', index);
|
||||||
|
|
||||||
|
// Access the grid API
|
||||||
|
const gridApi = gridRef.current.api;
|
||||||
|
|
||||||
|
// Fetch all the data in the grid after the change
|
||||||
|
const allRowData = [];
|
||||||
|
gridApi.forEachNode(node => allRowData.push(node.data));
|
||||||
|
|
||||||
|
// Log the entire row data
|
||||||
|
//console.log('All Grid Data:', allRowData);
|
||||||
|
|
||||||
|
// Optionally, log the updated row data (just the changed row)
|
||||||
|
// console.log('Updated Row Data:', event.data);
|
||||||
|
|
||||||
|
// Optionally, log the updated cell value
|
||||||
|
// console.log('Updated Cell Value:', event.newValue);
|
||||||
|
|
||||||
|
// Create a fresh copy of the dataset and update its data
|
||||||
|
const updatedDataset = { data: allRowData };
|
||||||
|
console.log(updatedDataset.data);
|
||||||
|
|
||||||
|
// Send the updated data back to the parent (LCPDatasetBuilder) through updateDataset
|
||||||
|
updateDataset(index, updatedDataset); // Call the parent function to update the dataset
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// lcpCellRenderer to dynamically assign the right cellRenderer
|
// lcpCellRenderer to dynamically assign the right cellRenderer
|
||||||
function lcpCellRenderer(params) {
|
function lcpCellRenderer(params) {
|
||||||
@ -66,6 +97,10 @@ function lcpCellRenderer(params) {
|
|||||||
const isValidCSSColor = (value) => {
|
const isValidCSSColor = (value) => {
|
||||||
// Ensure the value is a string before trimming
|
// Ensure the value is a string before trimming
|
||||||
value = String(value).trim(); // Convert to string if it's not already
|
value = String(value).trim(); // Convert to string if it's not already
|
||||||
|
// If the value is a Date object, it should not be processed as a CSS color
|
||||||
|
if (value instanceof Date) {
|
||||||
|
return false; // Return false if it's a Date object
|
||||||
|
}
|
||||||
|
|
||||||
// Regex to match valid CSS color formats (hex, rgb, rgba, hsl, hsla, named colors)
|
// Regex to match valid CSS color formats (hex, rgb, rgba, hsl, hsla, named colors)
|
||||||
const cssColorRegex = /^(#([0-9a-fA-F]{3}){1,2}|[a-zA-Z]+|rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)|rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0(\.\d+)?|1(\.0+)?)\)|hsl\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%\)|hsla\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%,\s*(0(\.\d+)?|1(\.0+)?)\))$/i;
|
const cssColorRegex = /^(#([0-9a-fA-F]{3}){1,2}|[a-zA-Z]+|rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)|rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0(\.\d+)?|1(\.0+)?)\)|hsl\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%\)|hsla\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%,\s*(0(\.\d+)?|1(\.0+)?)\))$/i;
|
||||||
@ -215,13 +250,21 @@ const isValidCSSColor = (value) => {
|
|||||||
// If it's the pinned top row, return the value as-is
|
// If it's the pinned top row, return the value as-is
|
||||||
return params.newValue;
|
return params.newValue;
|
||||||
} else {
|
} else {
|
||||||
|
// Check if the value is a Date object first
|
||||||
|
let value = params.newValue;
|
||||||
|
|
||||||
|
if (value instanceof Date) {
|
||||||
|
// If it's a Date object, return the string representation (this could be customized if needed)
|
||||||
|
return value.toLocaleString(); // or use `toISOString()` if you prefer
|
||||||
|
}
|
||||||
|
|
||||||
// Process based on the detected data type
|
// Process based on the detected data type
|
||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case 'number':
|
case 'number':
|
||||||
// If it's a number, return the number or NaN
|
// If it's a number, return the number or NaN
|
||||||
return Number(params.newValue);
|
return Number(value);
|
||||||
case 'date':
|
case 'date':
|
||||||
const dateStr = params.newValue;
|
const dateStr = value;
|
||||||
|
|
||||||
// Check if the value is an empty string or undefined
|
// Check if the value is an empty string or undefined
|
||||||
if (!dateStr || dateStr.trim() === '') {
|
if (!dateStr || dateStr.trim() === '') {
|
||||||
@ -245,13 +288,13 @@ const isValidCSSColor = (value) => {
|
|||||||
return !isNaN(parsedDate.getTime()) ? parsedDate : dateStr;
|
return !isNaN(parsedDate.getTime()) ? parsedDate : dateStr;
|
||||||
case 'color':
|
case 'color':
|
||||||
// If it's a color, return the value as-is
|
// If it's a color, return the value as-is
|
||||||
return params.newValue;
|
return value;
|
||||||
case 'html':
|
case 'html':
|
||||||
// If it's HTML, we can either sanitize or leave the value as is (for now, leaving it as is)
|
// If it's HTML, we can either sanitize or leave the value as is (for now, leaving it as is)
|
||||||
return params.newValue;
|
return value;
|
||||||
default:
|
default:
|
||||||
// If it's text (or any other type), return the value as-is
|
// If it's text (or any other type), return the value as-is
|
||||||
return params.newValue;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,6 +302,7 @@ const isValidCSSColor = (value) => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create columnDefs dynamically
|
// Create columnDefs dynamically
|
||||||
const [columnDefs, setColumnDefs] = useState([]);
|
const [columnDefs, setColumnDefs] = useState([]);
|
||||||
const [pinnedTopRowData, setPinnedTopRowData] = useState([]);
|
const [pinnedTopRowData, setPinnedTopRowData] = useState([]);
|
||||||
@ -275,7 +319,7 @@ const isValidCSSColor = (value) => {
|
|||||||
field: key, // Field will match the key (Department2, Budget, etc.)
|
field: key, // Field will match the key (Department2, Budget, etc.)
|
||||||
valueParser: lcpDataTypeParser,
|
valueParser: lcpDataTypeParser,
|
||||||
cellRenderer: lcpCellRenderer, // Reference the custom cell renderer
|
cellRenderer: lcpCellRenderer, // Reference the custom cell renderer
|
||||||
|
headerComponent: LCPDataGridHeader
|
||||||
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -378,6 +422,8 @@ const isValidCSSColor = (value) => {
|
|||||||
onSortChanged={onSortChanged}
|
onSortChanged={onSortChanged}
|
||||||
onFilterChanged={onFilterChanged}
|
onFilterChanged={onFilterChanged}
|
||||||
onGridReady={onGridReady}
|
onGridReady={onGridReady}
|
||||||
|
onCellValueChanged={onCellValueChanged}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,67 +1,46 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import {Icon, calendar } from '@wordpress/icons'; // Make sure to use the correct import
|
||||||
|
|
||||||
const LCPDataGridHeader = (props) => {
|
const LCPDataGridHeader = (props) => {
|
||||||
const { displayName, column, updateData, sort, menu } = props;
|
const { displayName, column, updateData, sort, menu } = props;
|
||||||
|
|
||||||
const [editing, setEditing] = useState(false);
|
|
||||||
const [newHeader, setNewHeader] = useState(displayName);
|
|
||||||
const colId = column.colId;
|
const colId = column.colId;
|
||||||
const handleEditClick = () => {
|
|
||||||
setEditing(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleBlur = () => {
|
// Sorting function
|
||||||
setEditing(false);
|
const handleSort = () => {
|
||||||
if (updateData && typeof updateData === 'function') {
|
if (sort === 'asc') {
|
||||||
updateData(newHeader); // Save the new header name
|
updateData(colId, 'desc'); // Assuming updateData is a function to set sort direction
|
||||||
|
} else {
|
||||||
|
updateData(colId, 'asc');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
setNewHeader(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="custom-header">
|
<div className="lcp-data-grid-column-header" style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
|
||||||
|
|
||||||
|
{/* Calendar Icon */}
|
||||||
|
<span style={{ marginRight: '8px', display: 'inline-block' }}>
|
||||||
|
<Icon icon={ calendar } />
|
||||||
|
|
||||||
{/* Column ID
|
|
||||||
<div>
|
|
||||||
<span style={{ marginRight: '8px' }}>
|
|
||||||
<strong>{colId}</strong>
|
|
||||||
</span>
|
</span>
|
||||||
</div>*/}
|
|
||||||
{/* Editable Header Text */}
|
{/* Editable Header Text */}
|
||||||
{/* Icon */}
|
<span
|
||||||
<span style={{ marginRight: '8px' }}>
|
style={{ fontWeight: 'bold', fontSize: '16px' }}
|
||||||
<img src="your-icon-path.svg" alt="icon" style={{ width: '20px', height: '20px' }} />
|
onClick={handleSort} // Click header for sorting
|
||||||
|
>
|
||||||
|
{displayName}
|
||||||
</span>
|
</span>
|
||||||
{editing ? (
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={newHeader}
|
|
||||||
onBlur={handleBlur}
|
|
||||||
onChange={handleChange}
|
|
||||||
style={{ fontSize: '14px', padding: '2px 5px', width: '100%' }}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<span
|
|
||||||
onClick={handleEditClick}
|
|
||||||
style={{ cursor: 'pointer', fontWeight: 'bold', fontSize: '16px' }}
|
|
||||||
>
|
|
||||||
{newHeader}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Sorting *
|
{/* Sorting Indicators */}
|
||||||
<span style={{ marginLeft: '8px' }}>
|
<span style={{ marginLeft: '8px' }}>
|
||||||
{sort === 'asc' && <span>↑</span>}
|
{sort === 'asc' && <span>↑</span>}
|
||||||
{sort === 'desc' && <span>↓</span>}
|
{sort === 'desc' && <span>↓</span>}
|
||||||
</span> */}
|
</span>
|
||||||
|
|
||||||
{/* Additional Menu *
|
{/* Additional Menu */}
|
||||||
<span style={{ marginLeft: '8px' }}>
|
<span style={{ marginLeft: '8px' }}>
|
||||||
<button onClick={menu}>Menu</button>
|
<button onClick={menu}>Menu</button>
|
||||||
</span> */}
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,9 +3,36 @@ import { Button, Modal } from '@wordpress/components';
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import LCPDataGrid from './LCPDataGrid';
|
import LCPDataGrid from './LCPDataGrid';
|
||||||
|
|
||||||
const LCPDatasetBuilder = ({ attributes }) => {
|
const LCPDatasetBuilder = ({ attributes, setAttributes }) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState(0); // Track the active tab
|
const [activeTab, setActiveTab] = useState(0); // Track the active tab
|
||||||
|
const handleUpdateDataset = (index, newData) => {
|
||||||
|
// Log the newData in a readable format
|
||||||
|
console.log("newData (formatted for copy-pasting):", JSON.stringify(newData, null, 2));
|
||||||
|
|
||||||
|
// Make a shallow copy of the datasets to avoid mutation
|
||||||
|
const datasets = [...attributes.datasets];
|
||||||
|
|
||||||
|
// Ensure the data structure is correct before replacing
|
||||||
|
if (newData && newData.data) {
|
||||||
|
// Replace the data array at the specified index with the new data
|
||||||
|
datasets[0].data = newData.data;
|
||||||
|
|
||||||
|
// Log the datasets before the update
|
||||||
|
console.log("Before Update:", JSON.stringify(datasets, null, 2));
|
||||||
|
|
||||||
|
// Update the attributes with the modified datasets
|
||||||
|
setAttributes({
|
||||||
|
datasets: datasets
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log the updated attributes (you can check this after re-rendering)
|
||||||
|
console.log("After Update:", JSON.stringify(datasets, null, 2));
|
||||||
|
} else {
|
||||||
|
console.error("Invalid data format:", newData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -56,7 +83,11 @@ const LCPDatasetBuilder = ({ attributes }) => {
|
|||||||
transition: 'display 0.3s ease',
|
transition: 'display 0.3s ease',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<LCPDataGrid dataset={dataset.data} />
|
<LCPDataGrid
|
||||||
|
dataset={dataset.data} // Pass the specific dataset data (only the data, not the entire dataset)
|
||||||
|
index={index}
|
||||||
|
updateDataset={handleUpdateDataset} // Function defined outside of class context
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Popover, ColorPicker } from '@wordpress/components';
|
||||||
|
|
||||||
// AG-Grid Cell Renderer Component
|
// AG-Grid Cell Renderer Component
|
||||||
const LCPGridColorRender = (props) => {
|
const LCPGridColorRender = (props) => {
|
||||||
const [color, setColor] = useState(props.value || ''); // Get the color value from the cell data
|
const [color, setColor] = useState(props.value || ''); // Get the color value from the cell data
|
||||||
|
const [isPopoverVisible, setPopoverVisible] = useState(false); // To toggle the visibility of the Popover
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Update color if the value from AG-Grid changes
|
// Update color if the value from AG-Grid changes
|
||||||
@ -11,18 +13,44 @@ const LCPGridColorRender = (props) => {
|
|||||||
}
|
}
|
||||||
}, [props.value]); // Dependency on props.value so it updates when the cell value changes
|
}, [props.value]); // Dependency on props.value so it updates when the cell value changes
|
||||||
|
|
||||||
|
// Handle the color change from the color picker
|
||||||
|
const handleColorChange = (newColor) => {
|
||||||
|
setColor(newColor);
|
||||||
|
// Optionally, update the cell value in AG-Grid here
|
||||||
|
if (props.setValue) {
|
||||||
|
props.setValue(newColor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div>
|
||||||
style={{
|
{/* Color square */}
|
||||||
width: '30px',
|
<div
|
||||||
height: '30px',
|
onClick={() => setPopoverVisible(!isPopoverVisible)} // Toggle popover visibility on click
|
||||||
backgroundColor: color,
|
style={{
|
||||||
border: '1px solid #000',
|
width: '30px',
|
||||||
margin: '0 auto'
|
height: '30px',
|
||||||
}}
|
backgroundColor: color,
|
||||||
/>
|
border: '1px solid #000',
|
||||||
|
margin: '0 auto',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Popover for color picker */}
|
||||||
|
{isPopoverVisible && (
|
||||||
|
<Popover
|
||||||
|
position="bottom center"
|
||||||
|
onClose={() => setPopoverVisible(false)} // Close popover when clicking outside
|
||||||
|
>
|
||||||
|
<ColorPicker
|
||||||
|
color={color}
|
||||||
|
onChangeComplete={(value) => handleColorChange(value.hex)} // Update color on change
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LCPGridColorRender;
|
export default LCPGridColorRender;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user