Unfinished support for updating attributes
This commit is contained in:
@ -3,24 +3,55 @@ import { AgGridReact } from 'ag-grid-react';
|
||||
import 'ag-grid-community/styles/ag-grid.css';
|
||||
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
||||
|
||||
import LCPDataGridHeader from './LCPDataGridHeader';
|
||||
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
|
||||
function lcpCellRenderer(params) {
|
||||
const value = params.value;
|
||||
|
||||
|
||||
// First, check if the value is a Date object
|
||||
if (value instanceof Date) {
|
||||
return value.toLocaleString(); // Return a formatted string (you can format it however you want)
|
||||
}
|
||||
|
||||
|
||||
// Check if the value is a valid CSS color (this works for string values like '#232323' or 'red')
|
||||
if (isValidCSSColor(value)) {
|
||||
return <LCPGridColorRender value={value} />; // Use the color renderer
|
||||
}
|
||||
|
||||
|
||||
// Default rendering for other types of data (like text, number, etc.)
|
||||
return value;
|
||||
}
|
||||
@ -66,6 +97,10 @@ function lcpCellRenderer(params) {
|
||||
const isValidCSSColor = (value) => {
|
||||
// Ensure the value is a string before trimming
|
||||
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)
|
||||
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,14 +250,22 @@ const isValidCSSColor = (value) => {
|
||||
// If it's the pinned top row, return the value as-is
|
||||
return params.newValue;
|
||||
} 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
|
||||
switch (dataType) {
|
||||
case 'number':
|
||||
// If it's a number, return the number or NaN
|
||||
return Number(params.newValue);
|
||||
return Number(value);
|
||||
case 'date':
|
||||
const dateStr = params.newValue;
|
||||
|
||||
const dateStr = value;
|
||||
|
||||
// Check if the value is an empty string or undefined
|
||||
if (!dateStr || dateStr.trim() === '') {
|
||||
return null; // If empty, return null or any default value you prefer
|
||||
@ -245,19 +288,20 @@ const isValidCSSColor = (value) => {
|
||||
return !isNaN(parsedDate.getTime()) ? parsedDate : dateStr;
|
||||
case 'color':
|
||||
// If it's a color, return the value as-is
|
||||
return params.newValue;
|
||||
return value;
|
||||
case 'html':
|
||||
// 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:
|
||||
// If it's text (or any other type), return the value as-is
|
||||
return params.newValue;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Create columnDefs dynamically
|
||||
const [columnDefs, setColumnDefs] = useState([]);
|
||||
@ -275,7 +319,7 @@ const isValidCSSColor = (value) => {
|
||||
field: key, // Field will match the key (Department2, Budget, etc.)
|
||||
valueParser: lcpDataTypeParser,
|
||||
cellRenderer: lcpCellRenderer, // Reference the custom cell renderer
|
||||
|
||||
headerComponent: LCPDataGridHeader
|
||||
|
||||
};
|
||||
});
|
||||
@ -378,6 +422,8 @@ const isValidCSSColor = (value) => {
|
||||
onSortChanged={onSortChanged}
|
||||
onFilterChanged={onFilterChanged}
|
||||
onGridReady={onGridReady}
|
||||
onCellValueChanged={onCellValueChanged}
|
||||
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,67 +1,46 @@
|
||||
import React, { useState } from 'react';
|
||||
import {Icon, calendar } from '@wordpress/icons'; // Make sure to use the correct import
|
||||
|
||||
const LCPDataGridHeader = (props) => {
|
||||
const { displayName, column, updateData, sort, menu } = props;
|
||||
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [newHeader, setNewHeader] = useState(displayName);
|
||||
const colId = column.colId;
|
||||
const handleEditClick = () => {
|
||||
setEditing(true);
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
setEditing(false);
|
||||
if (updateData && typeof updateData === 'function') {
|
||||
updateData(newHeader); // Save the new header name
|
||||
// Sorting function
|
||||
const handleSort = () => {
|
||||
if (sort === 'asc') {
|
||||
updateData(colId, 'desc'); // Assuming updateData is a function to set sort direction
|
||||
} else {
|
||||
updateData(colId, 'asc');
|
||||
}
|
||||
};
|
||||
|
||||
const handleChange = (e) => {
|
||||
setNewHeader(e.target.value);
|
||||
};
|
||||
|
||||
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>
|
||||
</div>*/}
|
||||
|
||||
{/* Editable Header Text */}
|
||||
{/* Icon */}
|
||||
<span style={{ marginRight: '8px' }}>
|
||||
<img src="your-icon-path.svg" alt="icon" style={{ width: '20px', height: '20px' }} />
|
||||
<span
|
||||
style={{ fontWeight: 'bold', fontSize: '16px' }}
|
||||
onClick={handleSort} // Click header for sorting
|
||||
>
|
||||
{displayName}
|
||||
</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' }}>
|
||||
{sort === 'asc' && <span>↑</span>}
|
||||
{sort === 'desc' && <span>↓</span>}
|
||||
</span> */}
|
||||
</span>
|
||||
|
||||
{/* Additional Menu *
|
||||
{/* Additional Menu */}
|
||||
<span style={{ marginLeft: '8px' }}>
|
||||
<button onClick={menu}>Menu</button>
|
||||
</span> */}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -3,9 +3,36 @@ import { Button, Modal } from '@wordpress/components';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import LCPDataGrid from './LCPDataGrid';
|
||||
|
||||
const LCPDatasetBuilder = ({ attributes }) => {
|
||||
const LCPDatasetBuilder = ({ attributes, setAttributes }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
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 (
|
||||
<>
|
||||
@ -56,7 +83,11 @@ const LCPDatasetBuilder = ({ attributes }) => {
|
||||
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>
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Popover, ColorPicker } from '@wordpress/components';
|
||||
|
||||
// AG-Grid Cell Renderer Component
|
||||
const LCPGridColorRender = (props) => {
|
||||
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(() => {
|
||||
// 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
|
||||
|
||||
// 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 (
|
||||
<div
|
||||
style={{
|
||||
width: '30px',
|
||||
height: '30px',
|
||||
backgroundColor: color,
|
||||
border: '1px solid #000',
|
||||
margin: '0 auto'
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
{/* Color square */}
|
||||
<div
|
||||
onClick={() => setPopoverVisible(!isPopoverVisible)} // Toggle popover visibility on click
|
||||
style={{
|
||||
width: '30px',
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user