From 3818a9c386220d194869d608348ba4afd6794b64 Mon Sep 17 00:00:00 2001 From: yyassi-heartex <104568407+yyassi-heartex@users.noreply.github.com> Date: Wed, 18 Dec 2024 06:21:53 -0500 Subject: [PATCH] fix: OPTIC-1178: Possible LS Memory Leak (#6704) Co-authored-by: yyassi-heartex --- .../datamanager/src/components/App/App.jsx | 26 +++++---- .../CellViews/Agreement/Agreement.jsx | 13 +++-- .../CellViews/Annotators/Annotators.jsx | 29 +++++----- .../AnnotationPreview/AnnotationPreview.jsx | 6 +- .../Common/Dropdown/DropdownComponent.jsx | 11 ++-- .../src/components/Common/Form/Form.jsx | 3 +- .../src/components/Common/Icon/Icon.jsx | 6 +- .../src/components/Common/Menu/Menu.jsx | 16 +++--- .../src/components/Common/Table/Table.jsx | 33 ++++++----- .../Common/Table/TableCell/TableCell.jsx | 10 ++-- .../components/Common/Table/TableContext.js | 6 +- .../Common/Table/TableHead/TableHead.jsx | 28 +++++----- .../Common/Table/TableRow/TableRow.jsx | 23 ++++---- .../src/components/Common/Tabs/Tabs.jsx | 56 ++++++++++--------- .../src/components/Common/Userpic/Userpic.jsx | 27 +++++---- .../components/DataManager/DataManager.jsx | 18 +++--- .../components/MainView/GridView/GridView.jsx | 9 ++- web/libs/datamanager/src/sdk/lsf-sdk.js | 5 -- web/libs/datamanager/src/stores/AppStore.js | 20 ++++--- web/libs/datamanager/src/utils/bem.tsx | 23 ++++---- .../datamanager/src/utils/feature-flags.js | 2 + web/libs/editor/src/components/App/App.jsx | 8 ++- .../src/components/BottomBar/Controls.tsx | 10 ++-- .../InstructionsModal/InstructionsModal.tsx | 2 +- .../src/components/Settings/Settings.jsx | 2 +- 25 files changed, 212 insertions(+), 180 deletions(-) diff --git a/web/libs/datamanager/src/components/App/App.jsx b/web/libs/datamanager/src/components/App/App.jsx index 9fdb0c21fb62..180fa82cd2b9 100644 --- a/web/libs/datamanager/src/components/App/App.jsx +++ b/web/libs/datamanager/src/components/App/App.jsx @@ -1,7 +1,8 @@ import { observer, Provider } from "mobx-react"; import React from "react"; +import clsx from "clsx"; import { SDKProvider } from "../../providers/SDKProvider"; -import { Block, Elem } from "../../utils/bem"; +import { cn } from "../../utils/bem"; import { Spinner } from "../Common/Spinner"; import { DataManager } from "../DataManager/DataManager"; import { Labeling } from "../Label/Label"; @@ -26,27 +27,32 @@ class ErrorBoundary extends React.Component { * @param {{app: import("../../stores/AppStore").AppStore} param0 */ const AppComponent = ({ app }) => { + const rootCN = cn("root"); + const rootClassName = rootCN.mod({ mode: app.SDK.mode }).toString(); + const crashCN = cn("crash"); return ( - +
{app.crashed ? ( - - Oops... - Project has been deleted or not yet created. - +
+ Oops... + + Project has been deleted or not yet created. + +
) : app.loading ? ( - +
- +
) : app.isLabeling ? ( ) : ( )} - - +
+
diff --git a/web/libs/datamanager/src/components/CellViews/Agreement/Agreement.jsx b/web/libs/datamanager/src/components/CellViews/Agreement/Agreement.jsx index eee6fc237f2e..d1896d7be987 100644 --- a/web/libs/datamanager/src/components/CellViews/Agreement/Agreement.jsx +++ b/web/libs/datamanager/src/components/CellViews/Agreement/Agreement.jsx @@ -1,4 +1,5 @@ -import { Block, Elem } from "../../../utils/bem"; +import clsx from "clsx"; +import { cn } from "../../../utils/bem"; import { isDefined } from "../../../utils/utils"; import "./Agreement.scss"; @@ -19,12 +20,14 @@ const formatNumber = (num) => { }; export const Agreement = (column) => { + const agreementCN = cn("agreement"); + const scoreElem = agreementCN.elem("score"); return ( - - +
+ {isDefined(column.value) ? `${formatNumber(column.value)}%` : ""} - - + +
); }; diff --git a/web/libs/datamanager/src/components/CellViews/Annotators/Annotators.jsx b/web/libs/datamanager/src/components/CellViews/Annotators/Annotators.jsx index 44c07e44e80a..c610bb78cbcf 100644 --- a/web/libs/datamanager/src/components/CellViews/Annotators/Annotators.jsx +++ b/web/libs/datamanager/src/components/CellViews/Annotators/Annotators.jsx @@ -1,7 +1,8 @@ import { inject } from "mobx-react"; +import clsx from "clsx"; import { LsCheckAlt, LsCrossAlt } from "../../../assets/icons"; import { useSDK } from "../../../providers/SDKProvider"; -import { Block, Elem } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; import { isDefined } from "../../../utils/utils"; import { Space } from "../../Common/Space/Space"; import { Tooltip } from "../../Common/Tooltip/Tooltip"; @@ -16,10 +17,12 @@ export const Annotators = (cell) => { const userList = Array.from(value); const renderable = userList.slice(0, 10); const extra = userList.length - renderable.length; + const userPickBadge = cn("userpic-badge"); + const annotatorsCN = cn("annotators"); return ( - - {renderable.map((item) => { +
+ {renderable.map((item, index) => { const user = item.user ?? item; const { annotated, reviewed, review } = item; @@ -28,9 +31,9 @@ export const Annotators = (cell) => { const suppressStats = column.alias === "comment_authors"; return ( - { e.preventDefault(); e.stopPropagation(); @@ -43,19 +46,19 @@ export const Annotators = (cell) => { faded={userpicIsFaded} badge={{ bottomRight: review && ( - +
{review === "rejected" ? : } - +
), }} /> -
+
); })} {extra > 0 && ( - { e.preventDefault(); e.stopPropagation(); @@ -63,9 +66,9 @@ export const Annotators = (cell) => { }} > - +
)} -
+ ); }; diff --git a/web/libs/datamanager/src/components/Common/AnnotationPreview/AnnotationPreview.jsx b/web/libs/datamanager/src/components/Common/AnnotationPreview/AnnotationPreview.jsx index c60304897d3d..aec8b85f3bac 100644 --- a/web/libs/datamanager/src/components/Common/AnnotationPreview/AnnotationPreview.jsx +++ b/web/libs/datamanager/src/components/Common/AnnotationPreview/AnnotationPreview.jsx @@ -1,7 +1,7 @@ import { inject, observer } from "mobx-react"; import React from "react"; import { taskToLSFormat } from "../../../sdk/lsf-utils"; -import { Block } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; import { FF_LSDV_4711, isFF } from "../../../utils/feature-flags"; import { Spinner } from "../Spinner"; import "./AnnotationPreview.scss"; @@ -135,7 +135,7 @@ export const AnnotationPreview = injector( height={props.height} /> ) : ( - +
- +
); }), ); diff --git a/web/libs/datamanager/src/components/Common/Dropdown/DropdownComponent.jsx b/web/libs/datamanager/src/components/Common/Dropdown/DropdownComponent.jsx index c19305364b0d..8f7264f8b96d 100644 --- a/web/libs/datamanager/src/components/Common/Dropdown/DropdownComponent.jsx +++ b/web/libs/datamanager/src/components/Common/Dropdown/DropdownComponent.jsx @@ -1,6 +1,7 @@ import React from "react"; import ReactDOM from "react-dom"; -import { Block, cn } from "../../../utils/bem"; +import clsx from "clsx"; +import { cn } from "../../../utils/bem"; import { alignElements } from "../../../utils/dom"; import { aroundTransition } from "../../../utils/transition"; import "./Dropdown.scss"; @@ -151,17 +152,15 @@ export const Dropdown = React.forwardRef(({ animated = true, visible = false, .. ...(offset ?? {}), zIndex: 1000 + dropdownIndex, }; - const result = ( - e.stopPropagation()} > {content} - + ); return props.inline === true ? result : ReactDOM.createPortal(result, document.body); diff --git a/web/libs/datamanager/src/components/Common/Form/Form.jsx b/web/libs/datamanager/src/components/Common/Form/Form.jsx index 1ec1fd459ff8..033cf5d6cf6b 100644 --- a/web/libs/datamanager/src/components/Common/Form/Form.jsx +++ b/web/libs/datamanager/src/components/Common/Form/Form.jsx @@ -474,8 +474,9 @@ Form.Builder = forwardRef( }; const renderColumns = (columns) => { + const columnClassName = cn("form-dm").elem("column").toString(); return columns.map((col, index) => ( -
+
{renderFields(col.fields)}
)); diff --git a/web/libs/datamanager/src/components/Common/Icon/Icon.jsx b/web/libs/datamanager/src/components/Common/Icon/Icon.jsx index 28e599454201..f7123f2aafe8 100644 --- a/web/libs/datamanager/src/components/Common/Icon/Icon.jsx +++ b/web/libs/datamanager/src/components/Common/Icon/Icon.jsx @@ -1,11 +1,11 @@ import React from "react"; -import { Block } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; import "./Icon.scss"; export const Icon = React.forwardRef(({ icon, ...props }, ref) => { return ( - + {React.createElement(icon, props)} - + ); }); diff --git a/web/libs/datamanager/src/components/Common/Menu/Menu.jsx b/web/libs/datamanager/src/components/Common/Menu/Menu.jsx index eaca6b3991fa..2e7daa478017 100644 --- a/web/libs/datamanager/src/components/Common/Menu/Menu.jsx +++ b/web/libs/datamanager/src/components/Common/Menu/Menu.jsx @@ -1,10 +1,13 @@ import React, { useCallback, useMemo } from "react"; -import { Block, cn } from "../../../utils/bem"; +import clsx from "clsx"; +import { cn } from "../../../utils/bem"; import { useDropdown } from "../Dropdown/DropdownTrigger"; import "./Menu.scss"; import { MenuContext } from "./MenuContext"; import { MenuItem } from "./MenuItem"; +const menuCN = cn("menu-dm"); + export const Menu = React.forwardRef( ({ children, className, style, size, selectedKeys, closeDropdownOnItemClick }, ref) => { const dropdown = useDropdown(); @@ -15,7 +18,7 @@ export const Menu = React.forwardRef( const clickHandler = useCallback( (e) => { - const elem = cn("menu-dm").elem("item").closest(e.target); + const elem = menuCN.elem("item").closest(e.target); if (dropdown && elem && closeDropdownOnItemClick !== false) { dropdown.close(); @@ -30,17 +33,14 @@ export const Menu = React.forwardRef( return ( - {children} - + ); }, diff --git a/web/libs/datamanager/src/components/Common/Table/Table.jsx b/web/libs/datamanager/src/components/Common/Table/Table.jsx index 1e51f19f1cf6..4a0a62cd186b 100644 --- a/web/libs/datamanager/src/components/Common/Table/Table.jsx +++ b/web/libs/datamanager/src/components/Common/Table/Table.jsx @@ -13,11 +13,11 @@ import { modal } from "../Modal/Modal"; import { Tooltip } from "../Tooltip/Tooltip"; import "./Table.scss"; import { TableCheckboxCell } from "./TableCheckbox"; -import { TableBlock, TableContext, TableElem } from "./TableContext"; +import { tableCN, TableContext } from "./TableContext"; import { TableHead } from "./TableHead/TableHead"; import { TableRow } from "./TableRow/TableRow"; import { prepareColumns } from "./utils"; -import { Block } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; import { FieldsButton } from "../FieldsButton"; import { LsGear, LsGearNewUI } from "../../../assets/icons"; import { FF_DEV_3873, FF_LOPS_E_10, FF_LOPS_E_3, isFF } from "../../../utils/feature-flags"; @@ -285,18 +285,19 @@ export const Table = observer( tableWrapper.current?.firstChild?.firstChild.offsetWidth - tableWrapper.current?.firstChild?.firstChild?.firstChild.offsetWidth || 0; + const columnsSelectorCN = cn("columns__selector"); return ( <> {view.root.isLabeling && ( - {isFF(FF_DEV_3873) ? ( } style={{ padding: "0" }} @@ -316,9 +317,9 @@ export const Table = observer( }} /> )} - +
)} - +
- +
); }, @@ -388,7 +389,7 @@ const StickyList = observer( return ( - + {({ width, height }) => ( {({ onItemsRendered, ref }) => ( - {ItemWrapper} - + )} )} - + ); }), @@ -430,9 +430,8 @@ const innerElementType = forwardRef(({ children, ...rest }, ref) => { {({ stickyItems, stickyItemsHeight, StickyComponent }) => (
{stickyItems.map((index) => ( - { - return ; +export const TableCell = ({ mix, mod, ...props }) => { + return ; }; TableCell.displayName = "TableCell"; -export const TableCellContent = ({ ...props }) => { - return ; +export const TableCellContent = ({ mix, mod, ...props }) => { + return ; }; TableCellContent.displayName = "TableCellContent"; diff --git a/web/libs/datamanager/src/components/Common/Table/TableContext.js b/web/libs/datamanager/src/components/Common/Table/TableContext.js index 2912f80fa176..9d62720081ee 100644 --- a/web/libs/datamanager/src/components/Common/Table/TableContext.js +++ b/web/libs/datamanager/src/components/Common/Table/TableContext.js @@ -1,6 +1,6 @@ import React from "react"; -import { BemWithSpecifiContext } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; -export const TableContext = React.createContext(); +export const tableCN = cn("table"); -export const { Block: TableBlock, Elem: TableElem } = BemWithSpecifiContext(); +export const TableContext = React.createContext(); diff --git a/web/libs/datamanager/src/components/Common/Table/TableHead/TableHead.jsx b/web/libs/datamanager/src/components/Common/Table/TableHead/TableHead.jsx index f4d58fbc0956..29033bb477b8 100644 --- a/web/libs/datamanager/src/components/Common/Table/TableHead/TableHead.jsx +++ b/web/libs/datamanager/src/components/Common/Table/TableHead/TableHead.jsx @@ -2,7 +2,6 @@ import { observer, useLocalStore } from "mobx-react"; import { toJS } from "mobx"; import React, { forwardRef, useCallback, useEffect, useRef } from "react"; import { ViewColumnType, ViewColumnTypeName, ViewColumnTypeShort } from "../../../../stores/Tabs/tab_column"; -import { BemWithSpecifiContext } from "../../../../utils/bem"; import { Button } from "../../Button/Button"; import { Dropdown } from "../../Dropdown/Dropdown"; import { Menu } from "../../Menu/Menu"; @@ -10,13 +9,14 @@ import { Resizer } from "../../Resizer/Resizer"; import { Space } from "../../Space/Space"; import { Tag } from "../../Tag/Tag"; import { TableCell, TableCellContent } from "../TableCell/TableCell"; -import { TableContext, TableElem } from "../TableContext"; +import { TableContext, tableCN } from "../TableContext"; +import { cn } from "../../../../utils/bem"; import { getStyle } from "../utils"; import "./TableHead.scss"; import { FF_DEV_3873, isFF } from "../../../../utils/feature-flags"; import { getRoot } from "mobx-state-tree"; -const { Block, Elem } = BemWithSpecifiContext(); +const tableHeadCN = cn("table-head"); const DropdownWrapper = observer(({ column, cellViews, children, onChange }) => { const types = ViewColumnType._types @@ -93,9 +93,9 @@ const ColumnRenderer = observer( const { cellClassName: _, headerClassName, ...rest } = column; return ( - +
- +
); } @@ -113,7 +113,7 @@ const ColumnRenderer = observer( {content} - {extra && {extra}} + {extra && {extra}} ); @@ -218,15 +218,13 @@ export const TableHead = observer( }, []); return ( - { const draggedCol = states.getDraggedCol(); @@ -239,8 +237,8 @@ export const TableHead = observer( > {columns.map((col) => { return ( - (colRefs.current[col.id] = ele)} key={col.id} @@ -288,11 +286,11 @@ export const TableHead = observer( onResize={onResize} onReset={onReset} /> - +
); })} - {extra} - + {extra} +
); }, ), diff --git a/web/libs/datamanager/src/components/Common/Table/TableRow/TableRow.jsx b/web/libs/datamanager/src/components/Common/Table/TableRow/TableRow.jsx index aad787749302..7ea7abf49d43 100644 --- a/web/libs/datamanager/src/components/Common/Table/TableRow/TableRow.jsx +++ b/web/libs/datamanager/src/components/Common/Table/TableRow/TableRow.jsx @@ -1,11 +1,11 @@ import { observer } from "mobx-react"; import React from "react"; -import { Block } from "../../../../utils/bem"; +import { cn } from "../../../../utils/bem"; import { FF_LOPS_E_3, isFF } from "../../../../utils/feature-flags"; import { normalizeCellAlias } from "../../../CellViews"; import { SkeletonLoader } from "../../SkeletonLoader"; import "./TableRow.scss"; -import { TableContext, TableElem } from "../TableContext"; +import { TableContext, tableCN } from "../TableContext"; import { getProperty, getStyle } from "../utils"; const CellRenderer = observer(({ col: colInput, data, decoration, cellViews }) => { @@ -15,9 +15,9 @@ const CellRenderer = observer(({ col: colInput, data, decoration, cellViews }) = const { headerClassName: _, cellClassName, ...rest } = col; return ( - + - + ); } @@ -32,7 +32,7 @@ const CellRenderer = observer(({ col: colInput, data, decoration, cellViews }) = const cellIsLoading = isFF(FF_LOPS_E_3) && data.loading === colInput.alias; return ( - +
{cellIsLoading ? : Renderer ? : value}
- +
); }); export const TableRow = observer(({ data, even, style, wrapperStyle, onClick, stopInteractions, decoration }) => { const { columns, cellViews } = React.useContext(TableContext); - + const rowWrapperCN = tableCN.elem("row-wrapper"); + const tableRowCN = cn("table-row"); const mods = { even, selected: data.isSelected, @@ -59,12 +60,12 @@ export const TableRow = observer(({ data, even, style, wrapperStyle, onClick, st }; return ( - onClick?.(data, e)}> - +
onClick?.(data, e)}> +
{columns.map((col) => { return ; })} - - +
+
); }); diff --git a/web/libs/datamanager/src/components/Common/Tabs/Tabs.jsx b/web/libs/datamanager/src/components/Common/Tabs/Tabs.jsx index 0e087a9c9471..fbe7ef7bd3a6 100644 --- a/web/libs/datamanager/src/components/Common/Tabs/Tabs.jsx +++ b/web/libs/datamanager/src/components/Common/Tabs/Tabs.jsx @@ -1,7 +1,7 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; import { DragDropContext, Droppable } from "react-beautiful-dnd"; import { FaEllipsisV } from "react-icons/fa"; -import { BemWithSpecifiContext } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; import { Button } from "../Button/Button"; import { Dropdown } from "../Dropdown/DropdownComponent"; import { Icon } from "../Icon/Icon"; @@ -9,9 +9,8 @@ import Input from "../Input/Input"; import "./Tabs.scss"; import { TabsMenu } from "./TabsMenu"; -const { Block, Elem } = BemWithSpecifiContext(); - const TabsContext = createContext(); +export const tabsCN = cn("tabs-dm"); export const Tabs = ({ children, @@ -45,22 +44,28 @@ export const Tabs = ({ return ( - - +
+ {(provided) => ( - +
{children} {provided.placeholder} - +
)}
- {allowedActions.add !== false && } - - {tabBarExtraContent} - + {allowedActions.add !== false && ( +
); }; @@ -121,18 +126,19 @@ export const TabsItem = ({ ); return ( - setHover(true)} onMouseLeave={() => setHover(false)} > - switchTab?.(tab)} - mod={{ - edit: renameMode, - }} title={currentTitle} > {renameMode ? ( @@ -158,8 +164,8 @@ export const TabsItem = ({ {currentTitle} )} - - + +
{showMenu && ( } > - +
)} - - +
+ ); }; diff --git a/web/libs/datamanager/src/components/Common/Userpic/Userpic.jsx b/web/libs/datamanager/src/components/Common/Userpic/Userpic.jsx index dfaac4009f97..d2baacd83963 100644 --- a/web/libs/datamanager/src/components/Common/Userpic/Userpic.jsx +++ b/web/libs/datamanager/src/components/Common/Userpic/Userpic.jsx @@ -1,5 +1,5 @@ import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { Block, Elem } from "../../../utils/bem"; +import { cn } from "../../../utils/bem"; import { Tooltip } from "../Tooltip/Tooltip"; import "./Userpic.scss"; @@ -13,6 +13,7 @@ export const Userpic = forwardRef( const [finalSrc, setFinalSrc] = useState(user?.avatar ?? src); const [imgVisible, setImgVisible] = useState(false); const [nameVisible, setNameVisible] = useState(true); + const userPicCN = cn("userpic-dm"); if (size) { style = Object.assign({ width: size, height: size, fontSize: size * 0.4 }, style); @@ -45,33 +46,35 @@ export const Userpic = forwardRef( }, [finalSrc]); const userpic = ( - - + {(finalUsername setFinalSrc(FALLBACK_IMAGE)} - mod={{ faded }} /> {nameVisible && ( - - {(finalUsername ?? "").toUpperCase()} - + {(finalUsername ?? "").toUpperCase()} )} {badge && Object.entries(badge).map(([align, content], i) => { return ( - + {content} - + ); })} - + ); const userFullName = useMemo(() => { diff --git a/web/libs/datamanager/src/components/DataManager/DataManager.jsx b/web/libs/datamanager/src/components/DataManager/DataManager.jsx index 833b6417d9a9..0a2c6c831b86 100644 --- a/web/libs/datamanager/src/components/DataManager/DataManager.jsx +++ b/web/libs/datamanager/src/components/DataManager/DataManager.jsx @@ -2,7 +2,7 @@ import { inject, observer } from "mobx-react"; import { useCallback } from "react"; import { Draggable } from "react-beautiful-dnd"; import { LSPlus } from "../../assets/icons"; -import { Block, Elem } from "../../utils/bem"; +import { cn } from "../../utils/bem"; import { Interface } from "../Common/Interface"; import { Space } from "../Common/Space/Space"; import { Spinner } from "../Common/Spinner"; @@ -12,6 +12,8 @@ import { DataView } from "../MainView"; import "./DataManager.scss"; import { Toolbar } from "./Toolbar/Toolbar"; +const tabContentCN = cn("tabs-dm-content"); + const injector = inject(({ store }) => { const { sidebarEnabled, sidebarVisible } = store.viewsStore ?? {}; @@ -88,8 +90,8 @@ const TabsSwitch = switchInjector( {tabs.map((tab, index) => ( {(provided, snapshot) => ( - - + )} ))} @@ -125,8 +127,8 @@ const TabsSwitch = switchInjector( export const DataManager = injector(({ shrinkWidth }) => { return ( - - +
+
@@ -136,8 +138,8 @@ export const DataManager = injector(({ shrinkWidth }) => { - +
- +
); }); diff --git a/web/libs/datamanager/src/components/MainView/GridView/GridView.jsx b/web/libs/datamanager/src/components/MainView/GridView/GridView.jsx index c303869cb05f..6f38220d1c8b 100644 --- a/web/libs/datamanager/src/components/MainView/GridView/GridView.jsx +++ b/web/libs/datamanager/src/components/MainView/GridView/GridView.jsx @@ -17,7 +17,11 @@ const GridHeader = observer(({ row, selected }) => { return ( - + {}} + /> {row.id} @@ -86,8 +90,7 @@ export const GridView = observer(({ data, view, loadMore, fields, onChange, hidd const renderItem = React.useCallback( ({ style, rowIndex, columnIndex }) => { const index = getCellIndex(rowIndex, columnIndex); - const row = data[index]; - + const row = data?.[index]; if (!row) return null; const props = { diff --git a/web/libs/datamanager/src/sdk/lsf-sdk.js b/web/libs/datamanager/src/sdk/lsf-sdk.js index a695e2de78f5..9de0c966197e 100644 --- a/web/libs/datamanager/src/sdk/lsf-sdk.js +++ b/web/libs/datamanager/src/sdk/lsf-sdk.js @@ -167,17 +167,12 @@ export class LSFWrapper { interfaces = this.interfacesModifier(interfaces, this.labelStream); } - console.group("Interfaces"); - console.log([...interfaces]); - if (!this.shouldLoadNext()) { interfaces = interfaces.filter((item) => { return !["topbar:prevnext", "skip"].includes(item); }); } - console.log([...interfaces]); - console.groupEnd(); const queueTotal = dm.store.project.reviewer_queue_total || dm.store.project.queue_total; const queueDone = dm.store.project.queue_done; const queueLeft = dm.store.project.queue_left; diff --git a/web/libs/datamanager/src/stores/AppStore.js b/web/libs/datamanager/src/stores/AppStore.js index 7cd91a3c06de..78a914305576 100644 --- a/web/libs/datamanager/src/stores/AppStore.js +++ b/web/libs/datamanager/src/stores/AppStore.js @@ -204,7 +204,7 @@ export const AppStore = types if (!isDefined(taskID)) return; - self.loadingData = true; + self.setLoadingData(true); if (self.mode === "labelstream") { yield self.taskStore.loadNextTask({ @@ -217,19 +217,25 @@ export const AppStore = types } else { self.taskStore.setSelected(taskID); - yield self.taskStore.loadTask(taskID, { + const taskPromise = self.taskStore.loadTask(taskID, { select: !!taskID && !!annotationID, }); - const annotation = self.LSF?.currentAnnotation; - const id = annotation?.pk ?? annotation?.id; + taskPromise.then(() => { + const annotation = self.LSF?.currentAnnotation; + const id = annotation?.pk ?? annotation?.id; - self.LSF?.setLSFTask(self.taskStore.selected, id); + self.LSF?.setLSFTask(self.taskStore.selected, id); - self.loadingData = false; + self.setLoadingData(false); + }); } }), + setLoadingData(value) { + self.loadingData = value; + }, + unsetTask(options) { try { self.annotationStore.unset(); @@ -296,7 +302,7 @@ export const AppStore = types const nextAction = () => { self.SDK.setMode("labeling"); - if (item && !item.isSelected) { + if (item?.id && !item.isSelected) { const labelingParams = { pushState: options?.pushState, }; diff --git a/web/libs/datamanager/src/utils/bem.tsx b/web/libs/datamanager/src/utils/bem.tsx index 18b0ab2488f6..8fb6768bff0f 100644 --- a/web/libs/datamanager/src/utils/bem.tsx +++ b/web/libs/datamanager/src/utils/bem.tsx @@ -11,6 +11,7 @@ import { type ReactSVG, useContext, } from "react"; +import { FF_MEMORY_LEAK_FIX, isFF } from "./feature-flags"; interface CNMod { [key: string]: unknown; @@ -166,16 +167,18 @@ export const cn = (block: string, options: CNOptions = {}): CN => { }, }; - Object.defineProperty(classNameBuilder, "Block", { value: Block }); - Object.defineProperty(classNameBuilder, "Elem", { value: Elem }); - Object.defineProperty(classNameBuilder, "__class", { - value: { - block, - elem, - mix, - mod, - }, - }); + if (!isFF(FF_MEMORY_LEAK_FIX)) { + Object.defineProperty(classNameBuilder, "Block", { value: Block }); + Object.defineProperty(classNameBuilder, "Elem", { value: Elem }); + Object.defineProperty(classNameBuilder, "__class", { + value: { + block, + elem, + mix, + mod, + }, + }); + } return classNameBuilder; }; diff --git a/web/libs/datamanager/src/utils/feature-flags.js b/web/libs/datamanager/src/utils/feature-flags.js index 4c0e30e80a3e..a3b1a84234ab 100644 --- a/web/libs/datamanager/src/utils/feature-flags.js +++ b/web/libs/datamanager/src/utils/feature-flags.js @@ -68,6 +68,8 @@ export const FF_LOPS_86 = "fflag_feat_front_lops_86_datasets_storage_edit_short" */ export const FF_SELF_SERVE = "fflag_feat_front_leap_482_self_serve_short"; +export const FF_MEMORY_LEAK_FIX = "fflag_feat_all_optic_1178_reduce_memory_leak_short"; + // Customize flags const flags = {}; diff --git a/web/libs/editor/src/components/App/App.jsx b/web/libs/editor/src/components/App/App.jsx index faa3c97cc72e..fa6f648f47fc 100644 --- a/web/libs/editor/src/components/App/App.jsx +++ b/web/libs/editor/src/components/App/App.jsx @@ -104,9 +104,11 @@ class App extends Component { > You have completed all tasks in the queue! - + {store.taskHistory.length > 0 && ( + + )}
); } diff --git a/web/libs/editor/src/components/BottomBar/Controls.tsx b/web/libs/editor/src/components/BottomBar/Controls.tsx index 4540cfde8f90..ff209c9ee197 100644 --- a/web/libs/editor/src/components/BottomBar/Controls.tsx +++ b/web/libs/editor/src/components/BottomBar/Controls.tsx @@ -122,7 +122,7 @@ export const Controls = controlsInjector<{ annotation: MSTAnnotation }>( if (customButton === "accept") { // just an example of internal button usage // @todo move buttons to separate components - buttons.push(); + buttons.push(); } } else { buttons.push( @@ -163,23 +163,23 @@ export const Controls = controlsInjector<{ annotation: MSTAnnotation }>( } }; - buttons.push(); + buttons.push(); }); - buttons.push(); + buttons.push(); } else if (annotation.skipped) { buttons.push( Was skipped , ); - buttons.push(); + buttons.push(); } else { if (store.hasInterface("skip")) { const onSkipWithComment = (e: React.MouseEvent, action: () => any) => { handleActionWithComments(e, action, "Please enter a comment before skipping"); }; - buttons.push(); + buttons.push(); } const isDisabled = disabled || submitDisabled; diff --git a/web/libs/editor/src/components/InstructionsModal/InstructionsModal.tsx b/web/libs/editor/src/components/InstructionsModal/InstructionsModal.tsx index cfba12b7b237..ba758b433e26 100644 --- a/web/libs/editor/src/components/InstructionsModal/InstructionsModal.tsx +++ b/web/libs/editor/src/components/InstructionsModal/InstructionsModal.tsx @@ -19,7 +19,7 @@ export const InstructionsModal = ({ <> { return (