Skip to content

Commit

Permalink
added ability to off parameter and fix chunk height
Browse files Browse the repository at this point in the history
  • Loading branch information
molotgor committed Nov 25, 2024
1 parent aec34ac commit 75cb958
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 109 deletions.
1 change: 1 addition & 0 deletions src/components/JSONViewer/FileChoosing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const FileChoosing = ({
id: nanoid(),
parentIds: [],
key: filePath,
height: 22,
failed: false,
viewInstruction: '',
simpleFields: [],
Expand Down
1 change: 1 addition & 0 deletions src/components/JSONViewer/JSONPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const JSONPanel = ({ type }: { type: PanelType }) => {
childIds: [],
isGeneratedKey: true,
isRoot: true,
height: 22,
};
try {
node.complexFields.push(...parseText(text, '0', true));
Expand Down
23 changes: 20 additions & 3 deletions src/components/JSONViewer/NotebookParamsCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
convertParameterToInput,
convertParameterValue,
getParameterType,
OFF_VALUE,
parseText,
validateParameter,
} from '../../helpers/JSONViewer';
Expand Down Expand Up @@ -51,7 +52,7 @@ const NotebookParamsCell = ({
const [taskId, setTaskId] = React.useState<string | null>();
const [resultCount, setResultCount] = React.useState<string>(String(notebook.resultsCount));
const [results, setResults] = React.useState<string[]>(notebook.results);
const isValid = React.useMemo(() => paramsValue.every(v => v.isValid), [paramsValue]);
const isValid = React.useMemo(() => paramsValue.every(v => v.isValid || v.isOff), [paramsValue]);
const reloadRef = React.useRef<HTMLButtonElement>(null);
const inputJSONRef = React.useRef<HTMLInputElement>(null);

Expand Down Expand Up @@ -93,6 +94,7 @@ const NotebookParamsCell = ({
name: val.name,
value: val.value,
type: val.type,
isOff: val.isOff,
})),
),
],
Expand All @@ -117,6 +119,7 @@ const NotebookParamsCell = ({
childIds: [],
isGeneratedKey: true,
isRoot: true,
height: 22,
};
try {
node.complexFields.push(...parseText(result, '0', true));
Expand Down Expand Up @@ -197,7 +200,10 @@ const NotebookParamsCell = ({
const paramsWithType = Object.fromEntries(
paramsValue
.filter(filterParameters)
.map(({ name, type: paramType, value }) => [name, convertParameterValue(value, paramType)]),
.map(({ name, type: paramType, value, isOff }) => [
name,
isOff ? { value: OFF_VALUE, type: 'str' } : convertParameterValue(value, paramType),
]),
);
const res = await api.jsonViewer.launchNotebook(notebook.name, paramsWithType);
if (res.task_id !== '') {
Expand All @@ -218,7 +224,8 @@ const NotebookParamsCell = ({
const prevValue = JSON.parse(JSON.stringify(paramsValue));
let params = JSON.parse(JSON.stringify(paramsValue));
try {
const preset: Array<{ name: string; value: string; type: string }> = JSON.parse(presetText);
const preset: Array<{ name: string; value: string; type: string; isOff: string }> =
JSON.parse(presetText);
const presetKeys = preset.map(p => p.name);
const parametersKeys = parameters.map(p => p.name);
const indexes = presetKeys.map(p => parametersKeys.indexOf(p));
Expand Down Expand Up @@ -299,6 +306,7 @@ const NotebookParamsCell = ({
<thead>
{parameters.length > 0 && (
<tr style={{ textAlign: 'left' }}>
<th>Off</th>
<th>Name</th>
<th>Type</th>
<th>Value</th>
Expand Down Expand Up @@ -330,6 +338,15 @@ const NotebookParamsCell = ({
...paramsValue.slice(index + 1),
]);
}}
toggleParameter={(newToggle: boolean) => {
const newState = paramsValue[index];
newState.isOff = newToggle;
setParamsValue([
...paramsValue.slice(0, index),
newState,
...paramsValue.slice(index + 1),
]);
}}
key={parameter.name}
/>
))}
Expand Down
19 changes: 18 additions & 1 deletion src/components/JSONViewer/ParametersRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import FileChoosing from './FileChoosing';
import { DateTimeInputType, DateTimeMask, TimeInputType } from '../../models/filter/FilterInputs';
import { DATE_TIME_ISO_INPUT_MASK } from '../../util/filterInputs';
import TimestampParameter from './TimestampParameter';
import Checkbox from '../util/Checkbox';

const possibleTypes = ['int', 'float', 'str', 'bool', 'file path', 'timestamp', 'pycode'];

Expand All @@ -18,11 +19,13 @@ const ParametersRow = ({
parameterValue,
setParametersValue,
setParametersType,
toggleParameter,
}: {
parameter: NotebookParameter;
parameterValue: InputNotebookParameter;
setParametersValue: (newValue: string) => void;
setParametersType: (newValue: string) => void;
toggleParameter: (toggle: boolean) => void;
}) => {
const [browserOpen, setBrowserOpen] = React.useState(false);
const [timestamp, setTimestampNumber] = React.useState<number | null>(moment.utc().valueOf());
Expand Down Expand Up @@ -57,16 +60,27 @@ const ParametersRow = ({
dateMask: DateTimeMask.DATE_TIME_ISO_MASK,
placeholder: '',
inputMask: DATE_TIME_ISO_INPUT_MASK,
disabled: parameterValue.isOff,
};

return (
<tr>
<td>
<Checkbox
checked={parameterValue.isOff}
onChange={e => {
toggleParameter(e.target.checked);
}}
label=''
id={`{parameter.name}-toggle`}
/>
</td>
<td>
<label>{parameter.name}</label>
</td>
<td>
<select
disabled={parameter.inferred_type_name !== 'None'}
disabled={parameter.inferred_type_name !== 'None' || parameterValue.isOff}
value={parameterValue.type}
onChange={(ev: React.ChangeEvent<HTMLSelectElement>) =>
setParametersType(ev.target.value)
Expand All @@ -89,6 +103,7 @@ const ParametersRow = ({
className='open-browser'
onClick={() => setBrowserOpen(true)}
title='Open file browser'
disabled={parameterValue.isOff}
/>
)}
{parameterValue.type === 'pycode' && (
Expand All @@ -104,6 +119,7 @@ const ParametersRow = ({
borderRadius: '5px',
}}>
<AceEditor
readOnly={parameterValue.isOff}
mode='python'
showGutter={false}
height='100%'
Expand All @@ -126,6 +142,7 @@ const ParametersRow = ({
const newValue = ev.target.value;
setParametersValue(newValue);
}}
disabled={parameterValue.isOff}
/>
)}
</>
Expand Down
78 changes: 24 additions & 54 deletions src/components/JSONViewer/TreeLeaf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ const TreeLeaf = ({ treeNode, type }: { treeNode: TreeNode; type: PanelType }) =
const [open, setOpen] = React.useState(
viewType === TreeViewType.DISPLAY_TABLE || JSONViewerStore.openTreeNodes[type].has(treeNode.id),
);
const convertType = type === 'default' ? 'compare' : 'default';

const closeDisplayed = React.useMemo(
() =>
JSONViewerStore.displayedLeafs[convertType].find(leaf =>
type === 'default' ? leaf.prevId === treeNode.id : leaf.nextId === treeNode.id,
),
[JSONViewerStore.displayedLeafs[convertType]],
);

const nodeName = useMemo(() => {
if (treeNode.displayName) return treeNode.displayName;
Expand All @@ -52,13 +43,9 @@ const TreeLeaf = ({ treeNode, type }: { treeNode: TreeNode; type: PanelType }) =
[treeNode.displayTimestamp, JSONViewerStore.сhunkInterval],
);

const closeChunk = React.useMemo(
() =>
closeDisplayed
? Math.floor(closeDisplayed.displayTimestamp / JSONViewerStore.сhunkInterval) %
COLORS.length
: null,
[closeDisplayed, JSONViewerStore.сhunkInterval],
const closeChunk = useMemo(
() => JSONViewerStore.chunkHeights[type].find(chunkHeight => chunkHeight.id === treeNode.id),
[JSONViewerStore.chunkHeights[type]],
);

const leafRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -91,37 +78,34 @@ const TreeLeaf = ({ treeNode, type }: { treeNode: TreeNode; type: PanelType }) =
}, [JSONViewerStore.openTreeNodes[type].values]);

useEffect(() => {
if (treeNode.displayTimestamp)
JSONViewerStore.addDisplayed(
const observer = new ResizeObserver(entries => {
JSONViewerStore.setNodeHeight(
treeNode.id,
treeNode.displayTimestamp,
leafRef.current ? leafRef.current.clientHeight : 0,
entries[0].borderBoxSize?.length > 0
? entries[0].borderBoxSize[0].blockSize
: entries[0].contentRect.height,
type,
);

});
if (leafRef.current) {
observer.observe(leafRef.current);
}
return () => {
if (treeNode.displayTimestamp) JSONViewerStore.removeDisplayed(treeNode.id, type);
if (leafRef.current) observer.unobserve(leafRef.current);
};
}, []);

useEffect(() => {
if (treeNode.displayTimestamp) {
JSONViewerStore.updateDisplayed(
treeNode.id,
leafRef.current ? leafRef.current.clientHeight : 0,
type,
);
}
}, [leafRef]);

const toggleNode = () => {
if (open) {
setOpen(false);
JSONViewerStore.closeNode(treeNode.id, type);
} else {
setOpen(true);
if (viewType !== TreeViewType.DISPLAY_TABLE) {
JSONViewerStore.openNode(treeNode.id, type);
if (treeNode.isRoot) {
JSONViewerStore.openNodeAndCloseOthers([treeNode.id, ...treeNode.parentIds], type);
JSONViewerStore.scrollToId(treeNode.id, type);
} else JSONViewerStore.openNode(treeNode.id, type);
}
}
};
Expand Down Expand Up @@ -152,19 +136,6 @@ const TreeLeaf = ({ treeNode, type }: { treeNode: TreeNode; type: PanelType }) =

return (
<>
{closeDisplayed && type === 'compare' && closeDisplayed.nextId === treeNode.id && (
<div
className='leaf'
style={{
height: closeDisplayed.height,
backgroundColor: closeChunk !== null ? BACKGROUND_COLORS[closeChunk] : undefined,
[`border${borderSide}Color`]: closeChunk !== null ? COLORS[closeChunk] : undefined,
[`border${borderSide}Width`]: closeChunk !== null ? '5px' : undefined,
[`borderTop${borderSide}Radius`]: closeChunk !== null ? '0px' : undefined,
[`borderBottom${borderSide}Radius`]: closeChunk !== null ? '0px' : undefined,
}}
/>
)}
<div
ref={leafRef}
className={createBemBlock(
Expand All @@ -173,7 +144,6 @@ const TreeLeaf = ({ treeNode, type }: { treeNode: TreeNode; type: PanelType }) =
isSelected ? 'selected' : null,
)}
style={{
marginBottom: needBounding ? '5px' : undefined,
backgroundColor: chunk !== null ? BACKGROUND_COLORS[chunk] : undefined,
...borderStyle,
}}>
Expand Down Expand Up @@ -278,16 +248,16 @@ const TreeLeaf = ({ treeNode, type }: { treeNode: TreeNode; type: PanelType }) =
</div>
)}
</div>
{closeDisplayed && type === 'default' && closeDisplayed.prevId === treeNode.id && (
{closeChunk && closeChunk.height > 0 && (
<div
className='leaf'
style={{
height: closeDisplayed.height,
backgroundColor: closeChunk !== null ? BACKGROUND_COLORS[closeChunk] : undefined,
[`border${borderSide}Color`]: closeChunk !== null ? COLORS[closeChunk] : undefined,
[`border${borderSide}Width`]: closeChunk !== null ? '5px' : undefined,
[`borderTop${borderSide}Radius`]: closeChunk !== null ? '0px' : undefined,
[`borderBottom${borderSide}Radius`]: closeChunk !== null ? '0px' : undefined,
height: closeChunk.height,
backgroundColor: BACKGROUND_COLORS[closeChunk.chunk % BACKGROUND_COLORS.length],
[`border${borderSide}Color`]: COLORS[closeChunk.chunk % COLORS.length],
[`border${borderSide}Width`]: '5px',
[`borderTop${borderSide}Radius`]: '0px',
[`borderBottom${borderSide}Radius`]: '0px',
}}
/>
)}
Expand Down
8 changes: 7 additions & 1 deletion src/components/JSONViewer/TreeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ const TreeList = ({ type }: { type: PanelType }) => {
}, []);

useEffect(() => {
virtuoso.current?.scrollToIndex(JSONViewerStore.activeIndex[type]);
if (JSONViewerStore.activeIndex[type] !== -1) {
virtuoso.current?.scrollToIndex(JSONViewerStore.activeIndex[type]);
JSONViewerStore.activeIndex = {
...JSONViewerStore.activeIndex,
[type]: -1,
};
}
}, [JSONViewerStore.activeIndex[type]]);

return (
Expand Down
7 changes: 6 additions & 1 deletion src/helpers/JSONViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const isNotebook = (obj: Object): obj is Notebook => {
);
};

export const isTreeNode = (obj: Object): obj is TreeNode => 'displayTimestamp' in obj;

export const isKeyFailed = (key: string) => key.includes('[fail]') || key.trim().startsWith('#');
export const isValueFailed = (value: string) =>
value.trim().startsWith('#') || value.trim().startsWith('!#');
Expand Down Expand Up @@ -84,6 +86,7 @@ export const convertJSONtoNode = (
simpleFields,
complexFields,
childIds: complexFields.map(node => node.id),
height: 22,
};
};

Expand All @@ -104,6 +107,7 @@ export const parseText = (text: string, name = '', isGeneratedKey = false): Tree

const stringPunct = `'"\``;
const numberReg = /^-?\d*\.?\d{0,}$/;
export const OFF_VALUE = `'[NA]'`;

export const convertParameterValue = (
value: string,
Expand All @@ -120,7 +124,7 @@ export const convertParameterValue = (
}
case 'str': {
return {
value: cutString ? value.slice(1, value.length - 1) : value,
value: value === OFF_VALUE ? '' : cutString ? value.slice(1, value.length - 1) : value,
type,
};
}
Expand Down Expand Up @@ -237,6 +241,7 @@ export const convertParameterToInput = (parameter: NotebookParameter): InputNote
value: String(convertParameterValue(parameter.default, type, true).value),
type,
isValid: validateParameter(parameter.default, type),
isOff: parameter.default === OFF_VALUE,
};
};

Expand Down
2 changes: 2 additions & 0 deletions src/models/JSONSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface TreeNode {
isGeneratedKey?: boolean;
isRoot?: boolean;
viewType?: TreeViewType;
height: number;
}

export interface NotebookNode {
Expand All @@ -67,6 +68,7 @@ export interface InputNotebookParameter {
type: string;
value: string;
isValid: boolean;
isOff: boolean;
}

export interface NotebookParameters {
Expand Down
Loading

0 comments on commit 75cb958

Please sign in to comment.