HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/agentcloud/webapp/src/components/DatasourceStream.tsx
'use strict';

import {
	ChevronDownIcon,
	ChevronRightIcon
} from '@heroicons/react/24/outline';
import { useReducer, useState } from 'react';

export function StreamRow({ stream, existingStream, readonly, descriptionsMap }
	: { stream?: any, existingStream?: any, readonly?: boolean, descriptionsMap?: any }) {
	const [isExpanded, setIsExpanded] = useState(existingStream != null && !readonly);

	const initialCheckedChildren = stream?.stream?.jsonSchema && Object.entries(stream.stream.jsonSchema.properties)
		.map(([key, value]) => {
			if (existingStream?.config?.selectedFields?.some(sf => sf['fieldPath'].includes(key))) {
				return key;
			}
		})
		.filter(x => x);

	function handleCheckedChild(state, action) {
		if (action.array) {
			return action.array;
		}
		if (state.includes(action.name)) {
			return state.filter(s => s !== action.name);
		}
		return state.concat([action.name]);
	}
	const [checkedChildren, setCheckedChildren] = useReducer(handleCheckedChild, initialCheckedChildren);
	
	const [datasourceDescriptions, setDatasourceDescriptions] = useState(descriptionsMap||{});

	return (
		<div className='border-b'>
			<div className='flex items-center p-4'>
				{!readonly && <div className='me-4'>
					<label className='switch'>
						<input
							onClick={() => {
								checkedChildren?.length === 0 && setIsExpanded(true);
								setCheckedChildren({
									array: checkedChildren?.length === 0 ? Object.keys(stream.stream.jsonSchema.properties) : [],
								});
							}}
							type='checkbox'
							className='rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 dark:bg-slate-800 dark:ring-slate-600'
							name={stream?.stream?.name || stream?.name}
							checked={checkedChildren?.length > 0}
						/>
						<span className='slider round'></span>
					</label>
				</div>}
				<div className='flex items-center cursor-pointer select-none' onClick={() => setIsExpanded(!isExpanded)}>
					<span>
						{isExpanded ? <ChevronDownIcon className='h-4 w-4' /> : <ChevronRightIcon className='h-4 w-4' />}
					</span>
					<span className='ml-2'>{stream?.stream?.name || stream?.name}</span>
				</div>
			</div>
			{stream?.stream?.jsonSchema && (
				<div className={`p-4 bg-gray-100 rounded ${isExpanded ? '' : 'hidden'}`}>
					<table className='w-full'>
						<thead>
							<tr>
								<th className='px-2 py-1 text-left w-1'></th>
								<th className='px-2 py-1 text-left'>Field Name</th>
								<th className='px-2 py-1 text-left'>Type</th>
								<th className='px-2 py-1 text-left'>Description</th>
							</tr>
						</thead>
						<tbody>
							{Object.entries(stream.stream.jsonSchema.properties).map(([key, value]) => (
								<tr key={key}>
									<td className='p-2'>
										<label className='switch'>
											<input
												onChange={() => setCheckedChildren({
													name: key,
													parent: stream?.stream?.name || stream?.name,
												})}
												type='checkbox'
												className='rounded border-gray-300 text-indigo-600 disabled:text-gray-600 focus:ring-indigo-600 disabled:ring-gray-600 dark:bg-slate-800 dark:ring-slate-600 mx-2'
												name={key}
												data-parent={stream?.stream?.name || stream?.name}
												disabled={readonly}
												defaultChecked={existingStream?.config?.selectedFields?.some(sf => sf['fieldPath'].includes(key))}
												checked={checkedChildren.includes(key)}
											/>
											<span className='slider round'></span>
										</label>
									</td>
									<td className='p-2 font-semibold'>{key}</td>
									<td className='p-2'>{value['type']}</td>
									<td className='p-2'>
										<input
											type='text'
											name={key}
											id={`${key}_description`}
											disabled={readonly}
											data-checked={existingStream?.config?.selectedFields?.some(sf => sf['fieldPath'].includes(key)) || checkedChildren.includes(key)}
											defaultValue={datasourceDescriptions[key]}
											className='block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 dark:bg-slate-800 dark:ring-slate-600 dark:text-white'
											placeholder='Enter description'
										/>
									</td>
								</tr>
							))}
						</tbody>
					</table>
				</div>
			)}

		</div>
	);
}

export function StreamsList({ streams, existingStreams, readonly, descriptionsMap }
: { streams?: any, existingStreams?: any, readonly?: boolean, descriptionsMap?: any }) {
	return (
		<div className='my-4'>
			{streams.map((stream, index) => (
				<StreamRow
					readonly={readonly}
					key={index}
					stream={stream}
					existingStream={existingStreams?.find(es => es.stream.name === stream?.stream?.name)}
					descriptionsMap={descriptionsMap}
				/>
			))}
		</div>
	);
}