Skip to content

Commit f723738

Browse files
lumburovskalinaanmarhindiJWittmeyer
authored
Release updates (#24)
* Version number to 1.14.0 * fix prepareRecordExport * Pages with bottom part gray & edit records only records scrollable * erros aren’t displayed if the request fails * only dynamic slice has tooltip for long names * Dropdown values hidden (z-index seems off) * Tooltip overlaps button ( 3x occurences) * Loading sign is shown on close * Heading for Calculation progress always visible * Space on edit name is not automatically replaced * Allow removal of last character in heuristic name (wont save but for changes) * Adds fix for heuristic layout * Import snapshot with PW → keep modal open * new line is added on SHIFT + ENTER * when saving the code, load is not available until reload of page * run on 10 error * Dropdown Type is always reset to Attribute on page navigation * Clear the tmp value in store * fixes: (Zero Shot) on some refresh, input attribute options are empty * fixes key for prepare-record-export --------- Co-authored-by: anmarhindi <[email protected]> Co-authored-by: JWittmeyer <[email protected]>
1 parent 6c477ed commit f723738

File tree

23 files changed

+215
-92
lines changed

23 files changed

+215
-92
lines changed

src/components/projects/ButtonsContainer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import SampleProjectsDropdown from "./SampleProjectsDropdown";
1212
import { CurrentPage, CurrentPageSubKey } from "@/src/types/shared/general";
1313
import { useWebsocket } from "@/src/services/base/web-sockets/useWebsocket";
1414

15-
const BASE_OPTIONS = { reloadOnFinish: false, deleteProjectOnFail: true, closeModalOnClick: true, isModal: true, navigateToProject: true, showBadPasswordMsg: null };
15+
const BASE_OPTIONS = { reloadOnFinish: false, deleteProjectOnFail: true, closeModalOnClick: false, isModal: true, navigateToProject: true, showBadPasswordMsg: null };
1616

1717
export default function ButtonsContainer() {
1818
const router = useRouter();

src/components/projects/projectId/attributes/attributeId/AttributeCalculations.tsx

+15-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { useRouter } from "next/router";
1414
import { useCallback, useEffect, useState } from "react";
1515
import { useDispatch, useSelector } from "react-redux"
1616
import ExecutionContainer from "./ExecutionContainer";
17-
import { getPythonFunctionRegExMatch } from "@/submodules/javascript-functions/python-functions-parser";
17+
import { getPythonFunctionRegExMatch, toPythonFunctionName } from "@/submodules/javascript-functions/python-functions-parser";
1818
import DangerZone from "@/src/components/shared/danger-zone/DangerZone";
1919
import { DangerZoneEnum } from "@/src/types/shared/danger-zone";
2020
import ContainerLogs from "@/src/components/shared/logs/ContainerLogs";
@@ -58,6 +58,7 @@ export default function AttributeCalculation() {
5858
const [editorValue, setEditorValue] = useState('');
5959
const [attributeName, setAttributeName] = useState('');
6060
const [checkUnsavedChanges, setCheckUnsavedChanges] = useState(false);
61+
const [enableRunButton, setEnableButton] = useState(false);
6162

6263
useEffect(() => {
6364
if (!currentAttribute) return;
@@ -285,9 +286,9 @@ export default function AttributeCalculation() {
285286

286287
useWebsocket(CurrentPage.ATTRIBUTE_CALCULATION, handleWebsocketNotification, projectId);
287288

288-
return (projectId && <div className="bg-white p-4 overflow-y-auto max-h-full" style={{ width: 'calc(100vw - 95px)', minWidth: '1175px' }} onScroll={(e: any) => onScrollEvent(e)}>
289+
return (projectId && <div className={`bg-white p-4 overflow-y-auto min-h-full h-[calc(100vh-4rem)]`} onScroll={(e: any) => onScrollEvent(e)}>
289290
{currentAttribute && <div>
290-
<div className={`sticky z-40 h-12 ${isHeaderNormal ? 'top-1' : '-top-5'}`}>
291+
<div className={`sticky z-50 h-12 ${isHeaderNormal ? 'top-1' : '-top-5'}`}>
291292
<div className={`bg-white flex-grow ${isHeaderNormal ? '' : 'shadow'}`}>
292293
<div className={`flex-row justify-start items-center inline-block ${isHeaderNormal ? 'p-0' : 'flex py-2'}`} style={{ transition: 'all .25s ease-in-out' }}>
293294
<a href={`/refinery/projects/${projectId}/settings`} onClick={(e) => {
@@ -305,15 +306,15 @@ export default function AttributeCalculation() {
305306
<div className="w-full">
306307
<div className={`grid gap-4 ${isHeaderNormal ? 'grid-cols-2' : 'grid-cols-1'}`}>
307308
{isHeaderNormal && <div className="flex items-center mt-2">
308-
<Tooltip color="invert" placement="right" content={currentAttribute.state == AttributeState.USABLE || currentAttribute.state == AttributeState.RUNNING ? TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.CANNOT_EDIT_NAME : TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.EDIT_NAME}>
309+
<Tooltip color="invert" placement="bottom" content={currentAttribute.state == AttributeState.USABLE || currentAttribute.state == AttributeState.RUNNING ? TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.CANNOT_EDIT_NAME : TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.EDIT_NAME}>
309310
<button onClick={() => openName(true)} disabled={currentAttribute.state == AttributeState.USABLE || currentAttribute.state == AttributeState.RUNNING}
310311
className={`flex-shrink-0 bg-white text-gray-700 text-xs font-semibold mr-3 px-4 py-2 rounded-md border border-gray-300 block float-left hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${currentAttribute.state == AttributeState.USABLE || currentAttribute.state == AttributeState.RUNNING}`}>
311312
Edit name
312313
</button>
313314
</Tooltip>
314315
<div className="inline-block" onDoubleClick={() => openName(true)}>
315316
{(isNameOpen && currentAttribute.state != AttributeState.USABLE && currentAttribute.state != AttributeState.RUNNING)
316-
? (<input type="text" value={attributeName} onInput={(e: any) => setAttributeName(e.target.value)}
317+
? (<input type="text" value={attributeName} onInput={(e: any) => setAttributeName(toPythonFunctionName(e.target.value))}
317318
onBlur={() => openName(false)} onKeyDown={(e) => { if (e.key == 'Enter') openName(false) }}
318319
className="h-8 text-sm border-gray-300 rounded-md placeholder-italic border text-gray-700 pl-4 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-300 focus:ring-offset-2 focus:ring-offset-gray-100" />)
319320
: (<div className="mr-4 text-sm leading-5 font-medium text-gray-500 inline-block">{currentAttribute.name}</div>)}
@@ -324,7 +325,7 @@ export default function AttributeCalculation() {
324325
<div className="grid grid-cols-2 gap-2 items-center mt-8" style={{ gridTemplateColumns: 'max-content auto' }}>
325326
<div className="text-sm leading-5 font-medium text-gray-700">Visibility</div>
326327
<Dropdown2 buttonName={currentAttribute.visibilityName} options={ATTRIBUTES_VISIBILITY_STATES} dropdownWidth="w-52" tooltipArrayPlacement="right" tooltipsArray={tooltipsArray}
327-
selectedOption={(option: any) => updateVisibility(option)} disabled={currentAttribute.state == AttributeState.USABLE} />
328+
selectedOption={(option: any) => updateVisibility(option)} disabled={currentAttribute.state == AttributeState.USABLE} dropdownClasses="z-40" />
328329

329330
<div className="text-sm leading-5 font-medium text-gray-700">Data type</div>
330331
<div className="flex flex-row items-center">
@@ -372,7 +373,7 @@ export default function AttributeCalculation() {
372373
if (currentAttribute.state == AttributeState.USABLE) return;
373374
updateNameAndCodeBricksIntegrator(code);
374375
}} />
375-
<Tooltip content={TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.AVAILABLE_LIBRARIES} placement="left" color="invert">
376+
<Tooltip content={TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.AVAILABLE_LIBRARIES} placement="bottom" color="invert">
376377
<a href="https://github.com/code-kern-ai/refinery-ac-exec-env/blob/dev/requirements.txt"
377378
target="_blank"
378379
className="ml-2 bg-white text-gray-700 text-xs font-semibold px-4 py-2 rounded-md border border-gray-300 hover:bg-gray-50 focus:outline-none">
@@ -403,6 +404,7 @@ export default function AttributeCalculation() {
403404
options={editorOptions}
404405
onChange={(value) => {
405406
setEditorValue(value);
407+
setEnableButton(true);
406408
}}
407409
/>
408410
</div>
@@ -415,7 +417,8 @@ export default function AttributeCalculation() {
415417
</div>
416418

417419

418-
<ExecutionContainer currentAttribute={currentAttribute} tokenizationProgress={tokenizationProgress} checkUnsavedChanges={checkUnsavedChanges}
420+
<ExecutionContainer currentAttribute={currentAttribute} tokenizationProgress={tokenizationProgress} enableRunButton={enableRunButton} checkUnsavedChanges={checkUnsavedChanges}
421+
setEnabledButton={(value: boolean) => setEnableButton(value)}
419422
refetchCurrentAttribute={() => {
420423
getAttributeByAttributeId(projectId, currentAttribute?.id, (res) => {
421424
const attribute = res.data['attributeByAttributeId'];
@@ -427,7 +430,10 @@ export default function AttributeCalculation() {
427430

428431
<div className="mt-8">
429432
<div className="text-sm leading-5 font-medium text-gray-700 inline-block">Calculation progress</div>
430-
{currentAttribute.progress == 0 && currentAttribute.state == AttributeState.INITIAL && <div className="bg-white">
433+
{(currentAttribute.progress == 0 || isNaN(currentAttribute.progress)) && currentAttribute.state == AttributeState.INITIAL && <div className="bg-white">
434+
<div className="py-6 text-sm leading-5 font-normal text-gray-500">This attribute was not yet run.</div>
435+
</div>}
436+
{currentAttribute.progress == 0.9 && currentAttribute.state == AttributeState.INITIAL && <div className="bg-white">
431437
<div className="py-6 text-sm leading-5 font-normal text-gray-500">This attribute was not yet run.</div>
432438
</div>}
433439
{currentAttribute.progress < 1 && currentAttribute.state == AttributeState.RUNNING &&

src/components/projects/projectId/attributes/attributeId/ExecutionContainer.tsx

+11-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { AttributeState } from "@/src/types/components/projects/projectId/settin
66
import { ModalEnum } from "@/src/types/shared/modal";
77
import { postProcessRecordByRecordId } from "@/src/util/components/projects/projectId/settings/attribute-calculation-helper";
88
import { Tooltip } from "@nextui-org/react";
9-
import { useState } from "react";
9+
import { useEffect, useState } from "react";
1010
import { useDispatch, useSelector } from "react-redux";
1111
import { TOOLTIPS_DICT } from "@/src/util/tooltip-constants";
1212
import ConfirmExecutionModal from "./ConfirmExecutionModal";
@@ -26,12 +26,20 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
2626
const [checkIfAtLeastRunning, setCheckIfAtLeastRunning] = useState(false);
2727
const [checkIfAtLeastQueued, setCheckIfAtLeastQueued] = useState(false);
2828

29+
useEffect(() => {
30+
if (props.enableRunButton) {
31+
setRunOn10HasError(false);
32+
setRequestedSomething(false);
33+
}
34+
}, [props.enableRunButton]);
35+
2936
function calculateUserAttributeSampleRecords() {
3037
if (requestedSomething) return;
3138
setRequestedSomething(true);
3239
getSampleRecords(projectId, props.currentAttribute.id, (res) => {
3340
const sampleRecordsFinal = { ...res.data['calculateUserAttributeSampleRecords'] };
3441
setRequestedSomething(false);
42+
props.setEnabledButton(false);
3543
setRunOn10HasError(sampleRecordsFinal.calculatedAttributes.length > 0 ? false : true);
3644
if (props.currentAttribute.dataType == 'EMBEDDING_LIST') {
3745
sampleRecordsFinal.calculatedAttributesList = sampleRecordsFinal.calculatedAttributes.map((record: string) => JSON.parse(record));
@@ -64,15 +72,15 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
6472
<LoadingIcon color="indigo" />
6573
</div>}
6674

67-
<Tooltip content={TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.EXECUTE_10_RECORDS} color="invert" placement="left" className="ml-auto">
75+
<Tooltip content={TOOLTIPS_DICT.ATTRIBUTE_CALCULATION.EXECUTE_10_RECORDS} color="invert" placement="bottom" className="ml-auto">
6876
<button onClick={calculateUserAttributeSampleRecords}
6977
disabled={props.currentAttribute.state == AttributeState.USABLE || props.currentAttribute.state == AttributeState.RUNNING || requestedSomething || props.tokenizationProgress < 1 || props.checkUnsavedChanges}
7078
className={`bg-white text-gray-700 text-xs font-semibold px-4 py-2 rounded-md border border-gray-300 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed`}>
7179
Run on 10
7280
</button>
7381
</Tooltip>
7482

75-
<Tooltip color="invert" placement="left" content={props.currentAttribute.state == AttributeState.USABLE ? 'Attribute is already in use' : requestedSomething ? 'Test is running' : checkIfAtLeastRunning ? 'Another attribute is running' : checkIfAtLeastQueued ? 'Another attribute is queued for execution' : props.tokenizationProgress < 1 ? 'Tokenization is in progress' : runOn10HasError ? 'Run on 10 records has an error' : 'Execute the attribute on all records'}>
83+
<Tooltip color="invert" placement="bottom" content={props.currentAttribute.state == AttributeState.USABLE ? 'Attribute is already in use' : requestedSomething ? 'Test is running' : checkIfAtLeastRunning ? 'Another attribute is running' : checkIfAtLeastQueued ? 'Another attribute is queued for execution' : props.tokenizationProgress < 1 ? 'Tokenization is in progress' : runOn10HasError ? 'Run on 10 records has an error' : 'Execute the attribute on all records'}>
7684
<button onClick={() => dispatch(setModalStates(ModalEnum.EXECUTE_ATTRIBUTE_CALCULATION, { open: true, requestedSomething: requestedSomething }))}
7785
disabled={props.currentAttribute.state == AttributeState.USABLE || props.currentAttribute.state == AttributeState.RUNNING || requestedSomething || checkIfAtLeastRunning || checkIfAtLeastQueued || props.tokenizationProgress < 1 || runOn10HasError || props.checkUnsavedChanges}
7886
className={`bg-indigo-700 text-white text-xs leading-4 font-semibold px-4 py-2 rounded-md cursor-pointer ml-3 hover:bg-indigo-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed`}>

src/components/projects/projectId/attributes/attributeId/ViewRecordDetailsModal.tsx

+22-23
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,34 @@ import { useSelector } from "react-redux";
55
import style from '@/src/styles/components/projects/projectId/attribute-calculation.module.css';
66
import { RecordDisplay } from "@/src/components/shared/record-display/RecordDisplay";
77
import { DataTypeEnum } from "@/src/types/shared/general";
8-
import LoadingIcon from "@/src/components/shared/loading/LoadingIcon";
98
import { ViewRecordDetailsModalProps } from "@/src/types/components/projects/projectId/settings/attribute-calculation";
109
import { selectVisibleAttributesHeuristics } from "@/src/reduxStore/states/pages/settings";
1110

12-
1311
export default function ViewRecordDetailsModal(props: ViewRecordDetailsModalProps) {
1412
const modalViewRecordDetails = useSelector(selectModal(ModalEnum.VIEW_RECORD_DETAILS));
1513
const attributes = useSelector(selectVisibleAttributesHeuristics);
1614

17-
return (<Modal modalName={ModalEnum.VIEW_RECORD_DETAILS}>
18-
<h1 className="text-lg text-gray-900 mb-2 text-center">View details</h1>
19-
{modalViewRecordDetails.record ? (
20-
<div className={`overflow-y-auto max-height-modal text-sm text-gray-500 my-2 ${style.scrollableSize}`}>
21-
<RecordDisplay
22-
attributes={attributes}
23-
record={modalViewRecordDetails.record} />
24-
<div className="text-sm leading-5 text-left text-gray-900 font-bold">Calculated value</div>
25-
<div className="text-sm leading-5 text-left text-gray-500 font-normal">
26-
{props.currentAttribute.dataType != DataTypeEnum.EMBEDDING_LIST ? <span>
27-
{props.sampleRecords.calculatedAttributes[modalViewRecordDetails.recordIdx]}
28-
</span> : <div className="flex flex-col gap-y-2 divide-y">
29-
{props.sampleRecords.calculatedAttributesListDisplay[modalViewRecordDetails.recordIdx].map((item: any) => <span key={item.id} className="mt-1">
30-
{props.sampleRecords.calculatedAttributesList[modalViewRecordDetails.recordIdx]}
31-
</span>)}
32-
</div>}
33-
</div>
34-
</div>
35-
) : (<LoadingIcon />)}
36-
</Modal>
15+
return (<>
16+
{modalViewRecordDetails.open && modalViewRecordDetails.record && props.sampleRecords && <>
17+
<Modal modalName={ModalEnum.VIEW_RECORD_DETAILS}>
18+
<h1 className="text-lg text-gray-900 mb-2 text-center">View details</h1>
3719

38-
)
20+
<div className={`overflow-y-auto max-height-modal text-sm text-gray-500 my-2 ${style.scrollableSize}`}>
21+
<RecordDisplay
22+
attributes={attributes}
23+
record={modalViewRecordDetails.record} />
24+
<div className="text-sm leading-5 text-left text-gray-900 font-bold">Calculated value</div>
25+
<div className="text-sm leading-5 text-left text-gray-500 font-normal">
26+
{props.currentAttribute.dataType != DataTypeEnum.EMBEDDING_LIST ? <span>
27+
{props.sampleRecords.calculatedAttributes[modalViewRecordDetails.recordIdx]}
28+
</span> : <div className="flex flex-col gap-y-2 divide-y">
29+
{props.sampleRecords.calculatedAttributesListDisplay[modalViewRecordDetails.recordIdx].map((item: any) => <span key={item.id} className="mt-1">
30+
{props.sampleRecords.calculatedAttributesList[modalViewRecordDetails.recordIdx]}
31+
</span>)}
32+
</div>}
33+
</div>
34+
</div>
35+
</Modal>
36+
</>}
37+
</>)
3938
}

src/components/projects/projectId/data-browser/DataBrowserSidebar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export default function DataBrowserSidebar() {
9494

9595
{dataSlices && <div className="mt-2 mb-4">
9696
{dataSlices.length > 0 && <div className="w-full grid grid-cols-2 gap-y-1 items-center justify-center" style={{ gridColumnGap: '26px' }}>
97-
{filteredSlices.map((slice: DataSlice, index: number) => (<Tooltip content={!slice.static ? <div className="w-24 break-words">{slice.name}</div> : null} color="invert" placement={index % 2 == 0 ? 'right' : 'left'} key={slice.id}>
97+
{filteredSlices.map((slice: DataSlice, index: number) => (<Tooltip content={<div className="w-24 break-words">{slice.displayName}</div>} color="invert" placement={index % 2 == 0 ? 'right' : 'left'} key={slice.id}>
9898
<button onClick={() => toggleSlice(slice)} style={{ width: '170px' }}
9999
className={`cursor-pointer inline-flex border items-center justify-between px-2.5 py-1.5 shadow-sm text-sm font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none ${activeSlice?.id == slice.id ? 'ring-blue-500 ring-2' : ' border-gray-200'}`}>
100100
<label className="cursor-pointer mr-2" onClick={(e) => { updateSliceInfo(slice); e.stopPropagation(); }}>

src/components/projects/projectId/edit-records/EditRecords.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export default function EditRecords() {
7373

7474
useWebsocket(CurrentPage.EDIT_RECORDS, handleWebsocketNotification, projectId);
7575

76-
return (<>{projectId && <div className="h-full bg-white flex flex-col">
76+
return (<>{projectId && <div className="bg-white flex flex-col min-h-full h-[calc(100vh-4rem)]">
7777
<NavBarTopEditRecords erdData={erdData} setErdData={(erdData) => setErdData(erdData)} />
7878
<div className={`grid items-start p-2 gap-2 flex-grow overflow-y-auto auto-rows-max ${erdData.columnClass}`} >
7979
{erdData.data && <>

0 commit comments

Comments
 (0)