Finished HTTP node creation and extensive node creation documentation in project

This commit is contained in:
Richard Osborne
2025-12-29 08:56:46 +01:00
parent fad9f1006d
commit 6fd59e83e6
13 changed files with 1008 additions and 247 deletions

View File

@@ -116,10 +116,14 @@ export function ComponentItem({
// If this item is a valid drop target, execute the drop
if (isDropTarget && onDrop) {
e.stopPropagation(); // Prevent bubble to Tree (for root drop fallback)
// End drag IMMEDIATELY at event handler level (before action chain)
// This matches the working root drop pattern
PopupLayer.instance.dragCompleted();
const node: TreeNode = { type: 'component', data: component };
onDrop(node);
setIsDropTarget(false);
// Note: dragCompleted() is called by handleDropOn - don't call it here
}
},
[isDropTarget, component, onDrop]

View File

@@ -111,10 +111,14 @@ export function FolderItem({
// If this folder is a valid drop target, execute the drop
if (isDropTarget && onDrop) {
e.stopPropagation(); // Prevent bubble to Tree (for root drop fallback)
// End drag IMMEDIATELY at event handler level (before action chain)
// This matches the working root drop pattern
PopupLayer.instance.dragCompleted();
const node: TreeNode = { type: 'folder', data: folder };
onDrop(node);
setIsDropTarget(false);
// Note: dragCompleted() is called by handleDropOn - don't call it here
}
},
[isDropTarget, folder, onDrop]

View File

@@ -523,15 +523,12 @@ export function useComponentActions() {
// Check for naming conflicts
if (ProjectModel.instance?.getComponentWithName(newName)) {
alert(`Component "${newName}" already exists in that folder`);
PopupLayer.instance.dragCompleted();
return;
}
const oldName = component.name;
// End drag operation FIRST - before the rename triggers a re-render
// This prevents the drag state from persisting across the tree rebuild
PopupLayer.instance.dragCompleted();
// Note: dragCompleted() now called by ComponentItem.handleMouseUp before this action
UndoQueue.instance.pushAndDo(
new UndoActionGroup({
@@ -554,7 +551,6 @@ export function useComponentActions() {
// Prevent moving folder into itself
if (targetPath.startsWith(sourcePath + '/') || targetPath === sourcePath) {
alert('Cannot move folder into itself');
PopupLayer.instance.dragCompleted();
return;
}
@@ -565,7 +561,6 @@ export function useComponentActions() {
if (!componentsToMove || componentsToMove.length === 0) {
console.log('Folder is empty, nothing to move');
PopupLayer.instance.dragCompleted();
return;
}
@@ -584,8 +579,7 @@ export function useComponentActions() {
renames.push({ component: comp, oldName: comp.name, newName });
});
// End drag operation FIRST - before the rename triggers a re-render
PopupLayer.instance.dragCompleted();
// Note: dragCompleted() now called by FolderItem.handleMouseUp before this action
UndoQueue.instance.pushAndDo(
new UndoActionGroup({
@@ -612,14 +606,12 @@ export function useComponentActions() {
// Check for naming conflicts
if (ProjectModel.instance?.getComponentWithName(newName)) {
alert(`Component "${newName}" already exists`);
PopupLayer.instance.dragCompleted();
return;
}
const oldName = component.name;
// End drag operation FIRST - before the rename triggers a re-render
PopupLayer.instance.dragCompleted();
// Note: dragCompleted() now called by ComponentItem.handleMouseUp before this action
UndoQueue.instance.pushAndDo(
new UndoActionGroup({
@@ -646,7 +638,6 @@ export function useComponentActions() {
if (!componentsToMove || componentsToMove.length === 0) {
console.log('Folder is empty, nothing to move');
PopupLayer.instance.dragCompleted();
return;
}
@@ -670,12 +661,10 @@ export function useComponentActions() {
if (hasConflict) {
alert(`Some components would conflict with existing names`);
PopupLayer.instance.dragCompleted();
return;
}
// End drag operation FIRST - before the rename triggers a re-render
PopupLayer.instance.dragCompleted();
// Note: dragCompleted() now called by ComponentItem.handleMouseUp before this action
UndoQueue.instance.pushAndDo(
new UndoActionGroup({

View File

@@ -3,11 +3,26 @@ import StringListTemplate from '../../../../../templates/propertyeditor/stringli
import PopupLayer from '../../../../popuplayer';
import { ToastLayer } from '../../../../ToastLayer/ToastLayer';
// Helper to normalize list input - handles both string and array formats
function normalizeList(value) {
if (value === undefined || value === null || value === '') {
return [];
}
if (Array.isArray(value)) {
// Already an array (legacy proplist data) - extract labels if objects
return value.map((item) => (typeof item === 'object' && item.label ? item.label : String(item)));
}
if (typeof value === 'string') {
return value.split(',').filter(Boolean);
}
return [];
}
var StringList = function (args) {
View.call(this);
this.parent = args.parent;
this.list = args.list !== undefined && args.list !== '' ? args.list.split(',') : [];
this.list = normalizeList(args.list);
this.type = args.type;
this.plug = args.plug;
this.title = args.title;
@@ -32,7 +47,7 @@ StringList.prototype.listUpdated = function () {
if (this.onUpdate) {
var updated = this.onUpdate(this.list.join(','));
if (updated) {
this.list = updated.value ? updated.value.split(',') : [];
this.list = normalizeList(updated.value);
this.isDefault = updated.isDefault;
}
}