Bugfix for data parser and data formatter
This commit is contained in:
@ -48,22 +48,22 @@
|
|||||||
{
|
{
|
||||||
"Department": "Sheriffs Office",
|
"Department": "Sheriffs Office",
|
||||||
"Budget": "150",
|
"Budget": "150",
|
||||||
"MeetAt": "12/12/2025",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"PreferredColor": "#e0e0e0",
|
"preferredColor": "red",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Department": "Assessor",
|
"Department": "Assessor",
|
||||||
"Budget": "100",
|
"Budget": "100",
|
||||||
"MeetAt": "12/12/2025",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"PreferredColor": "#e0e0e0",
|
"preferredColor": "#232323",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Department": "Treasurer",
|
"Department": "Treasurer",
|
||||||
"Budget": "50",
|
"Budget": "50",
|
||||||
"MeetAt": "12/12/2025",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"PreferredColor": "#e0e0e0",
|
"preferredColor": "#E72323",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -74,21 +74,21 @@
|
|||||||
{
|
{
|
||||||
"State": "California",
|
"State": "California",
|
||||||
"Coordinates": "150,000",
|
"Coordinates": "150,000",
|
||||||
"MeetAt": "12/12/2025",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"PreferredColor": "#e0e0e0",
|
"PreferredColor": "#e0e0e0",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"State": "Texas",
|
"State": "Texas",
|
||||||
"Coordinates": "100,000",
|
"Coordinates": "100,000",
|
||||||
"MeetAt": "12/12/2025",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"PreferredColor": "#e0e0e0",
|
"PreferredColor": "#e0e0e0",
|
||||||
"PostContent": "<div> </div>"
|
"PostContent": "<div> </div>"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"State": "Florida",
|
"State": "Florida",
|
||||||
"Coordinates": "50,000",
|
"Coordinates": "50,000",
|
||||||
"MeetAt": "12/12/2025",
|
"MeetAt": "2025-01-26T14:30:00Z",
|
||||||
"PreferredColor": "#e0e0e0",
|
"PreferredColor": "#e0e0e0",
|
||||||
"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' => '0c512545db897b1c5c5e');
|
<?php return array('dependencies' => array('react', 'react-dom', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '5afb8b4f337b11cc4837');
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -46,17 +46,17 @@
|
|||||||
"default": [{
|
"default": [{
|
||||||
"name": "Data",
|
"name": "Data",
|
||||||
"data": [
|
"data": [
|
||||||
{ "Department": "Sheriffs Office", "Budget": "150", "MeetAt": "12/12/2025", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" },
|
{ "Department": "Sheriffs Office", "Budget": "150", "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "red", "PostContent": "<div> </div>" },
|
||||||
{ "Department": "Assessor", "Budget": "100", "MeetAt": "12/12/2025", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" },
|
{ "Department": "Assessor", "Budget": "100", "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "#232323", "PostContent": "<div> </div>" },
|
||||||
{ "Department": "Treasurer", "Budget": "50", "MeetAt": "12/12/2025", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" }
|
{ "Department": "Treasurer", "Budget": "50", "MeetAt": "2025-01-26T14:30:00Z", "preferredColor": "#E72323", "PostContent": "<div> </div>" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Locations",
|
"name": "Locations",
|
||||||
"data": [
|
"data": [
|
||||||
{ "State": "California", "Coordinates": "150,000", "MeetAt": "12/12/2025", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" },
|
{ "State": "California", "Coordinates": "150,000", "MeetAt": "2025-01-26T14:30:00Z", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" },
|
||||||
{ "State": "Texas", "Coordinates": "100,000", "MeetAt": "12/12/2025", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" },
|
{ "State": "Texas", "Coordinates": "100,000", "MeetAt": "2025-01-26T14:30:00Z", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" },
|
||||||
{ "State": "Florida", "Coordinates": "50,000", "MeetAt": "12/12/2025", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" }
|
{ "State": "Florida", "Coordinates": "50,000", "MeetAt": "2025-01-26T14:30:00Z", "PreferredColor": "#e0e0e0", "PostContent": "<div> </div>" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,9 +3,27 @@ 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 LCPGridColorRender from './LCPGridColorRender';
|
||||||
|
|
||||||
const LCPDataGrid = ({dataset}) => {
|
const LCPDataGrid = ({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;
|
||||||
|
}
|
||||||
const [rowsToAdd, setRowsToAdd] = useState(1); // Number of rows the user wants to add
|
const [rowsToAdd, setRowsToAdd] = useState(1); // Number of rows the user wants to add
|
||||||
|
|
||||||
const [currentRowCount, setCurrentRowCount] = useState(dataset.length); // Track the current row count
|
const [currentRowCount, setCurrentRowCount] = useState(dataset.length); // Track the current row count
|
||||||
@ -43,12 +61,86 @@ const LCPDataGrid = ({dataset}) => {
|
|||||||
return 'text'; // Defaults to 'text' for strings and others
|
return 'text'; // Defaults to 'text' for strings and others
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Helper function to detect if a value is a valid CSS color
|
// Helper function to detect if a value is a valid CSS color
|
||||||
const isValidCSSColor = (value) => {
|
const isValidCSSColor = (value) => {
|
||||||
|
// Ensure the value is a string before trimming
|
||||||
|
value = String(value).trim(); // Convert to string if it's not already
|
||||||
|
|
||||||
|
// 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;
|
||||||
return cssColorRegex.test(value);
|
|
||||||
|
// First check if the value matches the general color regex
|
||||||
|
if (!cssColorRegex.test(value)) {
|
||||||
|
return false; // If it doesn't match any known color format, it's not valid
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, we'll do more detailed checks for RGB, RGBA, HSL, and HSLA formats
|
||||||
|
|
||||||
|
// Check if it's a valid RGB format (rgb(r, g, b))
|
||||||
|
const rgbMatch = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/i.exec(value);
|
||||||
|
if (rgbMatch) {
|
||||||
|
const r = parseInt(rgbMatch[1], 10);
|
||||||
|
const g = parseInt(rgbMatch[2], 10);
|
||||||
|
const b = parseInt(rgbMatch[3], 10);
|
||||||
|
// RGB values should be in the range 0-255
|
||||||
|
return r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a valid RGBA format (rgba(r, g, b, a))
|
||||||
|
const rgbaMatch = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0(\.\d+)?|1(\.0+)?)\)$/i.exec(value);
|
||||||
|
if (rgbaMatch) {
|
||||||
|
const r = parseInt(rgbaMatch[1], 10);
|
||||||
|
const g = parseInt(rgbaMatch[2], 10);
|
||||||
|
const b = parseInt(rgbaMatch[3], 10);
|
||||||
|
const a = parseFloat(rgbaMatch[4]);
|
||||||
|
// RGBA values should be in the range 0-255 for RGB and 0-1 for alpha
|
||||||
|
return r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && a >= 0 && a <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a valid HSL format (hsl(h, s%, l%))
|
||||||
|
const hslMatch = /^hsl\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%\)$/i.exec(value);
|
||||||
|
if (hslMatch) {
|
||||||
|
const h = parseInt(hslMatch[1], 10);
|
||||||
|
const s = parseInt(hslMatch[2], 10);
|
||||||
|
const l = parseInt(hslMatch[3], 10);
|
||||||
|
// Hue should be 0-360, saturation and lightness should be 0-100
|
||||||
|
return h >= 0 && h <= 360 && s >= 0 && s <= 100 && l >= 0 && l <= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a valid HSLA format (hsla(h, s%, l%, a))
|
||||||
|
const hslaMatch = /^hsla\((\d{1,3}),\s*(\d{1,3})%,\s*(\d{1,3})%,\s*(0(\.\d+)?|1(\.0+)?)\)$/i.exec(value);
|
||||||
|
if (hslaMatch) {
|
||||||
|
const h = parseInt(hslaMatch[1], 10);
|
||||||
|
const s = parseInt(hslaMatch[2], 10);
|
||||||
|
const l = parseInt(hslaMatch[3], 10);
|
||||||
|
const a = parseFloat(hslaMatch[4]);
|
||||||
|
// Hue should be 0-360, saturation and lightness should be 0-100, alpha should be 0-1
|
||||||
|
return h >= 0 && h <= 360 && s >= 0 && s <= 100 && l >= 0 && l <= 100 && a >= 0 && a <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's a valid named color (like "red", "blue", etc.)
|
||||||
|
const namedColors = [
|
||||||
|
"red", "green", "blue", "yellow", "black", "white", "gray", "purple", "orange", "brown", "pink", "cyan", "magenta",
|
||||||
|
// Add more CSS named colors as necessary
|
||||||
|
];
|
||||||
|
if (namedColors.includes(value.toLowerCase())) {
|
||||||
|
return true; // It's a valid named color
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's a valid hex color (hex format should be valid)
|
||||||
|
const hexMatch = /^#([0-9a-fA-F]{3}){1,2}$/i.exec(value);
|
||||||
|
if (hexMatch) {
|
||||||
|
return true; // It's a valid hex color
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it passed regex but didn't pass the detailed checks, it's invalid
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Helper function to detect if a value contains HTML tags
|
// Helper function to detect if a value contains HTML tags
|
||||||
const isHTML = (value) => {
|
const isHTML = (value) => {
|
||||||
const htmlRegex = /<([a-z][\s\S]*)>/i; // A simple check for any HTML tag
|
const htmlRegex = /<([a-z][\s\S]*)>/i; // A simple check for any HTML tag
|
||||||
@ -115,7 +207,6 @@ const LCPDataGrid = ({dataset}) => {
|
|||||||
return label;
|
return label;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Data parser for Ag Grid based on detected data types
|
|
||||||
function lcpDataTypeParser(params) {
|
function lcpDataTypeParser(params) {
|
||||||
const columnName = params.colDef.field; // Get the column field name (e.g., 'Budget', 'MeetAt')
|
const columnName = params.colDef.field; // Get the column field name (e.g., 'Budget', 'MeetAt')
|
||||||
const dataType = gridDataTypes[columnName]; // Get the data type for this column from gridDataTypes
|
const dataType = gridDataTypes[columnName]; // Get the data type for this column from gridDataTypes
|
||||||
@ -130,11 +221,30 @@ const LCPDataGrid = ({dataset}) => {
|
|||||||
// 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(params.newValue);
|
||||||
case 'date':
|
case 'date':
|
||||||
// If it's a date, try to parse the value as a Date
|
const dateStr = params.newValue;
|
||||||
const parsedDate = new Date(params.newValue);
|
|
||||||
return !isNaN(parsedDate.getTime()) ? parsedDate : params.newValue; // Return parsed date or original value if invalid
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsedDate;
|
||||||
|
// Check if the date is in the format "MM/DD/YYYY"
|
||||||
|
const isValidMMDDYYYY = /^\d{2}\/\d{2}\/\d{4}$/.test(dateStr);
|
||||||
|
|
||||||
|
if (isValidMMDDYYYY) {
|
||||||
|
const [month, day, year] = dateStr.split('/');
|
||||||
|
const isoDateStr = `${year}-${month}-${day}`;
|
||||||
|
parsedDate = new Date(isoDateStr);
|
||||||
|
} else {
|
||||||
|
// For other formats, try using the default Date parser
|
||||||
|
parsedDate = new Date(dateStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return parsed date if valid, otherwise return the original string
|
||||||
|
return !isNaN(parsedDate.getTime()) ? parsedDate : dateStr;
|
||||||
case 'color':
|
case 'color':
|
||||||
// If it's a color, we don't need to change the value (it's already a valid color)
|
// If it's a color, return the value as-is
|
||||||
return params.newValue;
|
return params.newValue;
|
||||||
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)
|
||||||
@ -146,6 +256,9 @@ const LCPDataGrid = ({dataset}) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create columnDefs dynamically
|
// Create columnDefs dynamically
|
||||||
const [columnDefs, setColumnDefs] = useState([]);
|
const [columnDefs, setColumnDefs] = useState([]);
|
||||||
const [pinnedTopRowData, setPinnedTopRowData] = useState([]);
|
const [pinnedTopRowData, setPinnedTopRowData] = useState([]);
|
||||||
@ -161,6 +274,9 @@ const LCPDataGrid = ({dataset}) => {
|
|||||||
headerName: getColumnLabel(index), // 'A', 'B', 'C', ...
|
headerName: getColumnLabel(index), // 'A', 'B', 'C', ...
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
28
blocks/components/LCPGridColorRender.js
Normal file
28
blocks/components/LCPGridColorRender.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
// AG-Grid Cell Renderer Component
|
||||||
|
const LCPGridColorRender = (props) => {
|
||||||
|
const [color, setColor] = useState(props.value || ''); // Get the color value from the cell data
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Update color if the value from AG-Grid changes
|
||||||
|
if (props.value !== color) {
|
||||||
|
setColor(props.value);
|
||||||
|
}
|
||||||
|
}, [props.value]); // Dependency on props.value so it updates when the cell value changes
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '30px',
|
||||||
|
height: '30px',
|
||||||
|
backgroundColor: color,
|
||||||
|
border: '1px solid #000',
|
||||||
|
margin: '0 auto'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LCPGridColorRender;
|
||||||
|
|
||||||
Reference in New Issue
Block a user