work on igor note
This commit is contained in:
@@ -1271,7 +1271,7 @@ function Flow() {
|
||||
if (!isTrackedNodeRequestCurrent(loadNodeOutputRequestVersionsRef.current, nodeId, requestVersion)) {
|
||||
return;
|
||||
}
|
||||
setNodeOutputs(nodeId, ['DATA_FIELD'], ['field'], { output_paths: [] });
|
||||
setNodeOutputs(nodeId, ['FILE_PATH', 'DATA_FIELD'], ['path', 'field'], { output_paths: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1281,8 +1281,8 @@ function Flow() {
|
||||
}
|
||||
setNodeOutputs(
|
||||
nodeId,
|
||||
channels.map((channel) => channel.type),
|
||||
channels.map((channel) => channel.name),
|
||||
['FILE_PATH', ...channels.map((channel) => channel.type)],
|
||||
['path', ...channels.map((channel) => channel.name)],
|
||||
{ output_paths: [] },
|
||||
);
|
||||
}, [getResolvedPathInput, reactFlow, setNodeOutputs]);
|
||||
|
||||
@@ -786,6 +786,17 @@ function ColorMapStopsEditor({ nodeId, name, value, onChange }) {
|
||||
}
|
||||
|
||||
function NodeTable({ rows }) {
|
||||
const [query, setQuery] = useState('');
|
||||
const scrollRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const el = scrollRef.current;
|
||||
if (!el) return;
|
||||
const handler = (e) => e.stopPropagation();
|
||||
el.addEventListener('wheel', handler, { passive: false });
|
||||
return () => el.removeEventListener('wheel', handler);
|
||||
}, []);
|
||||
|
||||
const columns = getTableColumns(rows);
|
||||
if (columns.length === 0) return null;
|
||||
const lowerColumns = columns.map((column) => String(column).toLowerCase());
|
||||
@@ -804,9 +815,32 @@ function NodeTable({ rows }) {
|
||||
return '';
|
||||
};
|
||||
|
||||
const filteredRows = query.trim()
|
||||
? rows.filter((row) =>
|
||||
columns.some((col) => {
|
||||
const cell = formatTableRowCell(row, col);
|
||||
return String(cell).toLowerCase().includes(query.toLowerCase());
|
||||
})
|
||||
)
|
||||
: rows;
|
||||
|
||||
return (
|
||||
<div className="node-table-wrap">
|
||||
<div className="node-table-scroll">
|
||||
{rows.length > 5 && (
|
||||
<div
|
||||
className="node-table-search"
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
>
|
||||
<input
|
||||
className="node-table-search-input nodrag"
|
||||
type="text"
|
||||
placeholder="Search…"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="node-table-scroll" ref={scrollRef}>
|
||||
<table className="node-table-grid">
|
||||
{hasMeasurementLayout && (
|
||||
<colgroup>
|
||||
@@ -823,7 +857,7 @@ function NodeTable({ rows }) {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row, rowIndex) => (
|
||||
{filteredRows.map((row, rowIndex) => (
|
||||
<tr key={row.id ?? row.quantity ?? rowIndex}>
|
||||
{columns.map((column) => {
|
||||
const value = row?.[column];
|
||||
@@ -1379,7 +1413,7 @@ function WidgetControl({ widget, nodeId, value, widgetValues, onChange, openFile
|
||||
const tableInputName = opts?.choices_from_table_input;
|
||||
if (!tableInputName) return [];
|
||||
const sourceType = getSourceTypeForInput(s, nodeId, tableInputName);
|
||||
if (sourceType !== 'RECORD_TABLE') return [];
|
||||
if (sourceType !== 'DATA_TABLE') return [];
|
||||
const sourceNode = getSourceNodeForInput(s, nodeId, tableInputName);
|
||||
const rows = sourceNode?.data?.tableRows;
|
||||
return Array.isArray(rows) ? getTableColumns(rows) : [];
|
||||
@@ -1393,7 +1427,7 @@ function WidgetControl({ widget, nodeId, value, widgetValues, onChange, openFile
|
||||
const measurementInputName = opts?.choices_from_measure_input;
|
||||
if (!measurementInputName) return [];
|
||||
const sourceType = getSourceTypeForInput(s, nodeId, measurementInputName);
|
||||
if (sourceType !== 'MEASURE_TABLE') return [];
|
||||
if (sourceType !== 'RECORD_TABLE') return [];
|
||||
const sourceNode = getSourceNodeForInput(s, nodeId, measurementInputName);
|
||||
const rows = sourceNode?.data?.tableRows;
|
||||
return Array.isArray(rows) ? getMeasurementChoices(rows) : [];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ── Shared type & color constants ─────────────────────────────────────
|
||||
|
||||
export const DATA_TYPES = new Set([
|
||||
'DATA_FIELD', 'IMAGE', 'LINE', 'MEASURE_TABLE', 'RECORD_TABLE',
|
||||
'DATA_FIELD', 'IMAGE', 'LINE', 'RECORD_TABLE', 'DATA_TABLE',
|
||||
'COORD', 'ANNOTATION_SOURCE', 'COLORMAP',
|
||||
'MESH_MODEL', 'FONT', 'FILE_PATH', 'DIRECTORY', 'COORDPAIR',
|
||||
]);
|
||||
@@ -12,8 +12,8 @@ export const TYPE_COLORS = {
|
||||
DATA_FIELD: '#3a7abf',
|
||||
IMAGE: '#00ff08a0',
|
||||
LINE: '#ffbe5c',
|
||||
MEASURE_TABLE: '#35e2fd',
|
||||
RECORD_TABLE: '#ff7474',
|
||||
RECORD_TABLE: '#35e2fd',
|
||||
DATA_TABLE: '#ff7474',
|
||||
COORD: '#e91ed1',
|
||||
COORDPAIR: '#5cb861',
|
||||
FLOAT: '#ab3197',
|
||||
|
||||
@@ -1296,6 +1296,26 @@ html, body, #root {
|
||||
padding: 4px 10px 8px;
|
||||
}
|
||||
|
||||
.node-table-search {
|
||||
padding: 0 0 4px;
|
||||
}
|
||||
|
||||
.node-table-search-input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 3px 7px;
|
||||
font-size: 11px;
|
||||
background: var(--bg-deep);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: 4px;
|
||||
color: var(--text-primary);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.node-table-search-input:focus {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.node-table-scroll {
|
||||
max-height: 220px;
|
||||
overflow: auto;
|
||||
@@ -1310,7 +1330,7 @@ html, body, #root {
|
||||
font-family: "SF Mono", "Fira Code", monospace;
|
||||
font-size: 10px;
|
||||
color: var(--text-table);
|
||||
table-layout: auto;
|
||||
table-layout: fixed;
|
||||
font-variant-numeric: tabular-nums lining-nums;
|
||||
}
|
||||
|
||||
@@ -1319,6 +1339,8 @@ html, body, #root {
|
||||
padding: 6px 8px;
|
||||
border-bottom: 1px solid var(--border-table);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ test('retired save alias types are no longer first-class socket types', () => {
|
||||
});
|
||||
|
||||
test('accepted_types extend canonical socket compatibility without reintroducing alias types', () => {
|
||||
const spec = ['MEASURE_TABLE', { accepted_types: ['RECORD_TABLE'] }];
|
||||
const spec = ['RECORD_TABLE', { accepted_types: ['DATA_TABLE'] }];
|
||||
|
||||
assert.equal(isDataSocketSpec(spec), true);
|
||||
assert.deepEqual(
|
||||
Array.from(getAcceptedSocketTypes(spec)).sort(),
|
||||
['MEASURE_TABLE', 'RECORD_TABLE'],
|
||||
['RECORD_TABLE', 'DATA_TABLE'],
|
||||
);
|
||||
assert.equal(socketSpecAcceptsType('RECORD_TABLE', spec), true);
|
||||
assert.equal(socketSpecAcceptsType('DATA_TABLE', spec), true);
|
||||
assert.equal(socketSpecAcceptsType('LINE', spec), false);
|
||||
});
|
||||
|
||||
@@ -487,7 +487,7 @@ test('serializeExecutionGraph treats accepted_types inputs as sockets, not widge
|
||||
className: 'TableSource',
|
||||
definition: {
|
||||
input: { required: {}, optional: {} },
|
||||
output: ['RECORD_TABLE'],
|
||||
output: ['DATA_TABLE'],
|
||||
output_name: ['rows'],
|
||||
manual_trigger: false,
|
||||
},
|
||||
@@ -501,7 +501,7 @@ test('serializeExecutionGraph treats accepted_types inputs as sockets, not widge
|
||||
definition: {
|
||||
input: {
|
||||
required: {
|
||||
table: ['MEASURE_TABLE', { accepted_types: ['RECORD_TABLE'] }],
|
||||
table: ['RECORD_TABLE', { accepted_types: ['DATA_TABLE'] }],
|
||||
},
|
||||
optional: {},
|
||||
},
|
||||
@@ -514,9 +514,9 @@ test('serializeExecutionGraph treats accepted_types inputs as sockets, not widge
|
||||
const edges = [
|
||||
{
|
||||
source: '1',
|
||||
sourceHandle: 'output::0::RECORD_TABLE',
|
||||
sourceHandle: 'output::0::DATA_TABLE',
|
||||
target: '2',
|
||||
targetHandle: 'input::table::MEASURE_TABLE',
|
||||
targetHandle: 'input::table::RECORD_TABLE',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -542,7 +542,7 @@ test('hasBlockingAutoRunInput still blocks unconnected accepted_types sockets',
|
||||
manual_trigger: false,
|
||||
input: {
|
||||
required: {
|
||||
input: ['DATA_FIELD', { accepted_types: ['IMAGE', 'LINE', 'RECORD_TABLE'] }],
|
||||
input: ['DATA_FIELD', { accepted_types: ['IMAGE', 'LINE', 'DATA_TABLE'] }],
|
||||
},
|
||||
optional: {},
|
||||
},
|
||||
@@ -556,7 +556,7 @@ test('hasBlockingAutoRunInput still blocks unconnected accepted_types sockets',
|
||||
hasBlockingAutoRunInput(node, [
|
||||
{
|
||||
source: '1',
|
||||
sourceHandle: 'output::0::RECORD_TABLE',
|
||||
sourceHandle: 'output::0::DATA_TABLE',
|
||||
target: '2',
|
||||
targetHandle: 'input::input::DATA_FIELD',
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ test('buildDefaultWidgetValues keeps non-data required widget defaults', () => {
|
||||
input: {
|
||||
required: {
|
||||
input: ['ANNOTATION_SOURCE', { label: 'Input' }],
|
||||
table: ['MEASURE_TABLE', { accepted_types: ['RECORD_TABLE'] }],
|
||||
table: ['RECORD_TABLE', { accepted_types: ['DATA_TABLE'] }],
|
||||
shape: [['line', 'rectangle', 'circle', 'arrow'], { default: 'arrow' }],
|
||||
stroke_color: ['STRING', { default: '#ff0000', color_picker: true }],
|
||||
stroke_width: ['INT', { default: 3 }],
|
||||
|
||||
Reference in New Issue
Block a user