Added basic support for linking DatasetBuilder datasets to lcp-data-collection CPT, and support for deleting datasets and datapoint in the DatasetBuilder.
This commit is contained in:
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'a7190cef9649b69f1e40');
|
||||
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'e934cc621b90f4fd2b9c');
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -14,12 +14,13 @@ import {
|
||||
import { useState, useRef } from '@wordpress/element';
|
||||
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
const ItemTypes = {
|
||||
DATASET_ITEM: 'dataset_item'
|
||||
};
|
||||
|
||||
const DatasetItem = ({ item, datasetKey, moveItem, updateItem, items }) => {
|
||||
const DatasetItem = ({ item, datasetKey, moveItem, updateItem, items, onDelete }) => {
|
||||
const [showColorPicker, setShowColorPicker] = useState(false);
|
||||
const ref = useRef(null);
|
||||
|
||||
@ -132,6 +133,18 @@ const DatasetItem = ({ item, datasetKey, moveItem, updateItem, items }) => {
|
||||
</Popover>
|
||||
)}
|
||||
</div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
isDestructive
|
||||
isSmall
|
||||
onClick={() => {
|
||||
if (window.confirm(__('Are you sure you want to delete this item?', 'lcp'))) {
|
||||
onDelete(item.id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{__('Delete', 'lcp')}
|
||||
</Button>
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
@ -145,6 +158,7 @@ const DatasetItem = ({ item, datasetKey, moveItem, updateItem, items }) => {
|
||||
moveItem={moveItem}
|
||||
updateItem={updateItem}
|
||||
items={items}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@ -154,14 +168,25 @@ const DatasetItem = ({ item, datasetKey, moveItem, updateItem, items }) => {
|
||||
const LCPDatasetBuilder = ({ value, onChange }) => {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [datasets, setDatasets] = useState(value || {});
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [editingDataset, setEditingDataset] = useState(null);
|
||||
|
||||
const addNewDataset = () => {
|
||||
const newDatasetName = `Dataset ${Object.keys(datasets).length + 1}`;
|
||||
const defaultName = 'New Dataset';
|
||||
let newName = defaultName;
|
||||
let counter = 1;
|
||||
|
||||
// Ensure unique name
|
||||
while (datasets[newName]) {
|
||||
newName = `${defaultName} ${counter}`;
|
||||
counter++;
|
||||
}
|
||||
|
||||
const updatedDatasets = {
|
||||
...datasets,
|
||||
[newDatasetName]: [{
|
||||
[newName]: [{
|
||||
id: `dataset-${Date.now()}`,
|
||||
label: newDatasetName,
|
||||
label: 'New Item',
|
||||
parent: null,
|
||||
value: 0,
|
||||
color: '#000000'
|
||||
@ -169,6 +194,44 @@ const LCPDatasetBuilder = ({ value, onChange }) => {
|
||||
};
|
||||
setDatasets(updatedDatasets);
|
||||
onChange(updatedDatasets);
|
||||
setEditingDataset(newName);
|
||||
};
|
||||
|
||||
const renameDataset = (oldName, newName) => {
|
||||
if (oldName === newName || !newName.trim() || datasets[newName]) {
|
||||
setEditingDataset(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedDatasets = { ...datasets };
|
||||
updatedDatasets[newName] = updatedDatasets[oldName];
|
||||
delete updatedDatasets[oldName];
|
||||
setDatasets(updatedDatasets);
|
||||
onChange(updatedDatasets);
|
||||
setEditingDataset(null);
|
||||
};
|
||||
|
||||
const deleteDataset = (datasetKey) => {
|
||||
const updatedDatasets = { ...datasets };
|
||||
delete updatedDatasets[datasetKey];
|
||||
setDatasets(updatedDatasets);
|
||||
onChange(updatedDatasets);
|
||||
};
|
||||
|
||||
const deleteItem = (datasetKey, itemId) => {
|
||||
const updatedDatasets = { ...datasets };
|
||||
// Remove the item and its children
|
||||
const removeItemAndChildren = (items, targetId) => {
|
||||
return items.filter(item => {
|
||||
if (item.id === targetId) return false;
|
||||
if (item.parent === targetId) return false;
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
updatedDatasets[datasetKey] = removeItemAndChildren(updatedDatasets[datasetKey], itemId);
|
||||
setDatasets(updatedDatasets);
|
||||
onChange(updatedDatasets);
|
||||
};
|
||||
|
||||
const addNewItem = (datasetKey) => {
|
||||
@ -231,45 +294,127 @@ const LCPDatasetBuilder = ({ value, onChange }) => {
|
||||
onChange(updatedDatasets);
|
||||
};
|
||||
|
||||
const saveToCollection = async () => {
|
||||
try {
|
||||
setIsSaving(true);
|
||||
console.log('Chart data:', datasets);
|
||||
|
||||
const formattedDatasets = Object.entries(datasets).map(([name, data]) => ({
|
||||
dataset_name: name,
|
||||
dataset_source: 'json',
|
||||
dataset_json: data
|
||||
}));
|
||||
|
||||
console.log('Formatted datasets:', formattedDatasets);
|
||||
|
||||
// Create the post first
|
||||
const postResponse = await apiFetch({
|
||||
path: '/wp/v2/lcp-data-collection',
|
||||
method: 'POST',
|
||||
data: {
|
||||
title: Object.keys(datasets)[0] || 'Dataset Collection',
|
||||
status: 'publish',
|
||||
meta: {
|
||||
lcp_datasets: formattedDatasets
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Post created:', postResponse);
|
||||
console.log('Meta data in response:', postResponse.meta);
|
||||
|
||||
// Double-check the meta was saved by fetching the post
|
||||
const savedPost = await apiFetch({
|
||||
path: `/wp/v2/lcp-data-collection/${postResponse.id}`,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
console.log('Saved post data:', savedPost);
|
||||
console.log('Saved meta data:', savedPost.meta?.lcp_datasets);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error saving dataset:', error);
|
||||
console.log('Error details:', {
|
||||
message: error.message,
|
||||
code: error.code,
|
||||
data: error.data
|
||||
});
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
setIsModalOpen(true);
|
||||
if (Object.keys(datasets).length === 0) {
|
||||
addNewDataset();
|
||||
}
|
||||
}}
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
>
|
||||
{__('Open Dataset Builder', 'lcp')}
|
||||
</Button>
|
||||
|
||||
{isModalOpen && (
|
||||
<Modal
|
||||
title={__('Dataset Builder', 'lcp')}
|
||||
onRequestClose={() => setIsModalOpen(false)}
|
||||
style={{ width: '90vw' }}
|
||||
style={{ width: '100%', maxWidth: '800px' }}
|
||||
>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<div style={{ padding: '20px' }}>
|
||||
{Object.entries(datasets).map(([datasetKey, items]) => (
|
||||
<div key={datasetKey} style={{ marginBottom: '20px' }}>
|
||||
<h3>{datasetKey}</h3>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
|
||||
{editingDataset === datasetKey ? (
|
||||
<TextControl
|
||||
value={datasetKey}
|
||||
onChange={(newName) => renameDataset(datasetKey, newName)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
renameDataset(datasetKey, e.target.value);
|
||||
} else if (e.key === 'Escape') {
|
||||
setEditingDataset(null);
|
||||
}
|
||||
}}
|
||||
autoFocus
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<h3 style={{ margin: 0 }}>{datasetKey}</h3>
|
||||
<Button
|
||||
variant="secondary"
|
||||
isSmall
|
||||
onClick={() => setEditingDataset(datasetKey)}
|
||||
>
|
||||
{__('Rename', 'lcp')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
isDestructive
|
||||
isSmall
|
||||
onClick={() => {
|
||||
if (window.confirm(__('Are you sure you want to delete this dataset?', 'lcp'))) {
|
||||
deleteDataset(datasetKey);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{__('Delete', 'lcp')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{items
|
||||
.filter(item => !item.parent) // Only render top-level items
|
||||
.filter(item => !item.parent)
|
||||
.map(item => (
|
||||
<DatasetItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
datasetKey={datasetKey}
|
||||
item={item}
|
||||
items={items}
|
||||
moveItem={moveItem}
|
||||
updateItem={updateItem}
|
||||
items={items}
|
||||
onDelete={(itemId) => deleteItem(datasetKey, itemId)}
|
||||
/>
|
||||
))
|
||||
}
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
@ -280,13 +425,21 @@ const LCPDatasetBuilder = ({ value, onChange }) => {
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
<div style={{ display: 'flex', gap: '10px', marginTop: '20px' }}>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={addNewDataset}
|
||||
style={{ marginTop: '20px' }}
|
||||
>
|
||||
{__('Add New Dataset', 'lcp')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={saveToCollection}
|
||||
disabled={isSaving}
|
||||
>
|
||||
{isSaving ? __('Saving...', 'lcp') : __('Save to Collection', 'lcp')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DndProvider>
|
||||
</Modal>
|
||||
|
||||
@ -99,26 +99,29 @@ add_action('init', 'lcp_register_data_collection_post_type');
|
||||
// Register meta field for datasets
|
||||
function lcp_register_meta_fields() {
|
||||
register_post_meta('lcp-data-collection', 'lcp_datasets', array(
|
||||
'show_in_rest' => true,
|
||||
'show_in_rest' => array(
|
||||
'schema' => array(
|
||||
'type' => 'array',
|
||||
'items' => array(
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'dataset_name' => array(
|
||||
'type' => 'string'
|
||||
),
|
||||
'dataset_source' => array(
|
||||
'type' => 'string'
|
||||
),
|
||||
'dataset_json' => array(
|
||||
'type' => 'array'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
'single' => true,
|
||||
'type' => 'array',
|
||||
'auth_callback' => function() {
|
||||
return current_user_can('edit_posts');
|
||||
},
|
||||
'sanitize_callback' => function($meta_value) {
|
||||
if (!is_array($meta_value)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sanitized = array();
|
||||
foreach ($meta_value as $key => $dataset) {
|
||||
$sanitized[$key] = array(
|
||||
'dataset_name' => sanitize_text_field($dataset['dataset_name']),
|
||||
'dataset_source' => sanitize_text_field($dataset['dataset_source']),
|
||||
'dataset_json' => json_decode(wp_unslash($dataset['dataset_json']), true)
|
||||
);
|
||||
}
|
||||
return $sanitized;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user