Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix [Artifacts, Functions] selected item is missing from the list of visible items #2567

Merged
merged 6 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/Datasets/Datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,8 @@ const Datasets = () => {
headerRowHeight: cssVariables.datasetsHeaderRowHeight,
rowHeight: cssVariables.datasetsRowHeight,
rowHeightExtended: cssVariables.datasetsRowHeightExtended
}
},
activateTableScroll: true
})

return (
Expand Down
3 changes: 2 additions & 1 deletion src/components/Files/Files.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ const Files = () => {
headerRowHeight: cssVariables.filesHeaderRowHeight,
rowHeight: cssVariables.filesRowHeight,
rowHeightExtended: cssVariables.filesRowHeightExtended
}
},
activateTableScroll: true
})

return (
Expand Down
3 changes: 2 additions & 1 deletion src/components/FunctionsPage/Functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,8 @@ const Functions = ({
headerRowHeight: cssVariables.functionsHeaderRowHeight,
rowHeight: cssVariables.functionsRowHeight,
rowHeightExtended: cssVariables.functionsRowHeightExtended
}
},
activateTableScroll: true
})

return (
Expand Down
3 changes: 2 additions & 1 deletion src/components/ModelsPage/Models/Models.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ const Models = ({ fetchModelFeatureVector }) => {
headerRowHeight: cssVariables.modelsHeaderRowHeight,
rowHeight: cssVariables.modelsRowHeight,
rowHeightExtended: cssVariables.modelsRowHeightExtended
}
},
activateTableScroll: true
})

return (
Expand Down
1 change: 1 addition & 0 deletions src/elements/ArtifactsTableRow/ArtifactsTableRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const ArtifactsTableRow = ({
const cellClassName = classnames(
index >= mainRowItemsCount && 'table-body__cell_hidden'
)

return (
!data.hidden && (
<TableCell
Expand Down
135 changes: 131 additions & 4 deletions src/hooks/useVirtualization.hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ illegal under applicable law, and the grant of the foregoing license
under the Apache 2.0 license is conditioned upon your compliance with
such restriction.
*/
import { useLayoutEffect, useMemo, useState } from 'react'
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import { isEmpty, isEqual, sum, throttle } from 'lodash'
import { MAIN_TABLE_ID, MAIN_TABLE_BODY_ID } from '../constants'

Expand Down Expand Up @@ -71,6 +71,121 @@ export const getRowsSizes = (
})
}

/**
* Hook for scrolling a table to a selected item.
* @param {Object} options - Options object.
* @param {React.RefObject} options.tableRef - Ref object for the table element.
* @param {Object[]} options.content - Array containing content for each row.
* @param {Object{}} options.selectedItem - Object representing the currently selected item.
* @param {Object} options.expandedRowsData - Object containing data for expanded rows.
* @param {string|number} options.rowHeight - Height of a regular row.
* @param {string|number} options.rowHeightExtended - Height of an extended row.
* @param {string|number} options.headerRowHeight - Height of an table header.
* @param {boolean} options.useHook - Bool indicate if trigger the hooks logic.
* @returns {void}
*/
const useTableScroll = ({
rowHeight,
rowHeightExtended,
headerRowHeight,
selectedItem,
expandedRowsData,
content,
activateHook
}) => {
const lastSelectedItemDataRef = useRef(null)

const getSpaceToSelectedItem = useCallback(
(lastSelectedItemData, tableElement) => {
const baseRowHeight = isEmpty(selectedItem) ? rowHeight : rowHeightExtended
const tableHeight = tableElement?.offsetHeight
const rowsSizes = getRowsSizes(
content,
selectedItem,
expandedRowsData,
rowHeight,
rowHeightExtended
)
let spaceToSelectedItem =
sum(rowsSizes.slice(0, lastSelectedItemData.index)) -
(tableHeight ? (tableHeight - headerRowHeight) / 2 - baseRowHeight / 2 : 0)

if (!isEmpty(lastSelectedItemData?.expandedRowData?.content)) {
const selectedChildItemPosition =
lastSelectedItemData?.expandedRowData?.content.findIndex(
item => item.data.ui.identifierUnique === lastSelectedItemData.identifierUnique
) + 1

if (selectedChildItemPosition > 0) {
const diffBetweenParentRowAndOtherMainRows = baseRowHeight - rowHeight
spaceToSelectedItem +=
baseRowHeight * selectedChildItemPosition - diffBetweenParentRowAndOtherMainRows
}
}

return spaceToSelectedItem
},
[content, expandedRowsData, headerRowHeight, rowHeight, rowHeightExtended, selectedItem]
)

const handleSelectItemChanges = useCallback((identifier, content, getSpaceToSelectedItem, async = false) => {
const selectedItemIndex = content.findIndex(
item => item.data.ui.identifier === identifier
)
const triggerScroll = () => {
const tableElement = document.getElementById(MAIN_TABLE_ID)

tableElement?.scroll({
top: getSpaceToSelectedItem(
{
...lastSelectedItemDataRef.current,
index: selectedItemIndex
},
tableElement
)
})
}

if (selectedItemIndex >= 0) {
if (async) {
requestAnimationFrame(() => {
triggerScroll()
})
} else {
triggerScroll()
}
}
}, [])

useEffect(() => {
if (!activateHook) return

try {
if (!isEmpty(selectedItem)) {
if (!lastSelectedItemDataRef.current) {
lastSelectedItemDataRef.current = {
...selectedItem?.ui,
expandedRowData: expandedRowsData[selectedItem?.ui?.identifier]
}
handleSelectItemChanges(selectedItem?.ui?.identifier, content, getSpaceToSelectedItem, true)
} else {
lastSelectedItemDataRef.current = {
...selectedItem?.ui,
expandedRowData: expandedRowsData[selectedItem?.ui?.identifier]
}
}
} else if (lastSelectedItemDataRef.current && isEmpty(selectedItem)) {
handleSelectItemChanges(lastSelectedItemDataRef.current?.identifier, content, getSpaceToSelectedItem)

lastSelectedItemDataRef.current = null
}
} catch (e) {
lastSelectedItemDataRef.current = null
console.warn('useTableScrollHook:: Error during table scroll attempt', e)
}
}, [content, getSpaceToSelectedItem, selectedItem, expandedRowsData, activateHook, handleSelectItemChanges])
}

/**
* Hook for virtualizing a table.
* @param {Object} options - Options object.
Expand All @@ -84,6 +199,7 @@ export const getRowsSizes = (
* @param {string|number} options.heightData.rowHeight - Height of a regular row.
* @param {string|number} options.heightData.rowHeightExtended - Height of an extended row.
* @param {string|number} options.heightData.headerRowHeight - Height of the table header row.
* @param {boolean} options.activateTableScroll - Boolean indicator for useTableScroll hook.
* @returns {Object} - Object containing virtualization configuration.
*/
export const useVirtualization = ({
Expand All @@ -92,7 +208,8 @@ export const useVirtualization = ({
rowsData = {
content: []
},
heightData: { rowHeight, rowHeightExtended, headerRowHeight }
heightData: { rowHeight, rowHeightExtended, headerRowHeight },
activateTableScroll = false
}) => {
const [virtualizationConfig, setVirtualizationConfig] = useState(virtualizationConfigInitialState)
const [rowsSizesLocal, setRowsSizesLocal] = useState(rowsSizes)
Expand Down Expand Up @@ -130,8 +247,8 @@ export const useVirtualization = ({
])

useLayoutEffect(() => {
const tableElement = document.querySelector(`#${MAIN_TABLE_ID}`)
const tableBodyElement = document.querySelector(`#${MAIN_TABLE_BODY_ID}`)
const tableElement = document.getElementById(MAIN_TABLE_ID)
const tableBodyElement = document.getElementById(MAIN_TABLE_BODY_ID)
const elementsHeight = sum(rowsSizesLocal)

const calculateVirtualizationConfig = throttle(() => {
Expand Down Expand Up @@ -219,5 +336,15 @@ export const useVirtualization = ({
}
}, [renderTriggerItem, headerRowHeightLocal, rowsSizesLocal, rowsData.content])

useTableScroll({
rowHeight: rowHeightLocal,
rowHeightExtended: extendedRowHeightLocal,
headerRowHeight: headerRowHeightLocal,
selectedItem: rowsData.selectedItem,
expandedRowsData: rowsData.expandedRowsData,
content: rowsData.content,
activateHook: activateTableScroll
})

return virtualizationConfig
}
10 changes: 6 additions & 4 deletions src/utils/parseArtifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getArtifactIdentifier } from './getUniqueIdentifier'
import { isEmpty } from 'lodash'

export const parseArtifacts = artifacts =>
(artifacts ?? []).map(artifact => {
(artifacts ?? []).reduce((parsedArtifacts, artifact) => {
if (!isEmpty(artifact)) {
let item = { ...artifact }

Expand All @@ -35,14 +35,16 @@ export const parseArtifacts = artifacts =>
}
}

return {
parsedArtifacts.push({
...item,
kind: artifact.kind,
ui: {
originalContent: artifact,
identifier: getArtifactIdentifier(item),
identifierUnique: getArtifactIdentifier(item, true)
}
}
})
}
})

return parsedArtifacts
}, [])
Loading