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

TD-3359 TransferList update to have combined search and check functionality #1035

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

IvanLazarov-TVM
Copy link
Contributor

@IvanLazarov-TVM IvanLazarov-TVM commented Jan 31, 2025

Closes: TD-3359
Contributes to: TD-3333

Changes

  • Updated the handle check all logic for both the source and the target
  • Updated the Search component in order to clear the state of the "SearchBox" on transfer
  • Added one more test for the combined logic of the search and check functionality

Dependencies

N/A

UI/UX

Before:
image

After:
image

Testing notes

In the TransferList component:

  • Check when we have search parameter if the check all checks only the searched values.
  • Check when we have a seacrh parameter and we check only the searched values and then delete the search if the only checked items are the previously searched once.

Author checklist

Before I request a review:

  • I have reviewed my own code-diff.
  • I have tested the changes in Docker / a deploy-preview.
  • I have assigned the PR to myself or an appropriate delegate.
  • I have added the relevant labels to the PR.
  • I have included appropriate tests.
  • I have checked that the Lint and Test workflows pass on Github.
  • I have populated the deploy-preview with relevant test data.
  • I have tagged a UI/UX designer for review if this PR includes UI/UX changes.

@IvanLazarov-TVM IvanLazarov-TVM added the enhancement New feature or request label Jan 31, 2025
@IvanLazarov-TVM IvanLazarov-TVM self-assigned this Jan 31, 2025
Copy link

github-actions bot commented Jan 31, 2025

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 70.14% (🎯 66%) 10212 / 14559
🟢 Statements 70.14% (🎯 66%) 10212 / 14559
🟢 Functions 72.66% (🎯 70%) 420 / 578
🟢 Branches 85.87% (🎯 80%) 1052 / 1225
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/TransferList/TransferList.tsx 99.4% 97.1% 100% 99.4% 121, 145
Unchanged Files
src/ActionDialog/ActionDialog.tsx 98.36% 66.66% 100% 98.36% 64
src/AlignHorizontal/AlignHorizontal.tsx 100% 100% 100% 100%
src/AlignVertical/AlignVertical.tsx 100% 100% 100% 100%
src/AppHeader/AppHeader.tsx 100% 71.42% 100% 100%
src/AppLauncher/AppLauncher.tsx 97.36% 76.92% 83.33% 97.36% 80-81, 91, 137
src/AppLayout/AppLayout.tsx 100% 100% 85.71% 100%
src/Autocomplete/Autocomplete.tsx 94.85% 81.08% 100% 94.85% 75-77, 79, 122, 178-183
src/Breadcrumbs/Breadcrumbs.tsx 98% 66.66% 100% 98% 31
src/BulletGauge/BulletGauge.tsx 0% 0% 0% 0% 1-85
src/BulletGauge/BulletGaugeClientOnly.tsx 0% 0% 0% 0% 1-19
src/Canvas/Canvas.jsx 93% 33.33% 0% 93% 49-51, 59-62
src/Canvas/Grid.jsx 100% 100% 100% 100%
src/Canvas/ResizeHandle.jsx 100% 100% 100% 100%
src/Canvas/SelectionRectangle.jsx 31.03% 100% 0% 31.03% 10-30
src/Canvas/useResize.jsx 37.14% 100% 25% 37.14% 18-26, 30-33, 37-45
src/Canvas/useSelectionRectangle.jsx 30.15% 50% 25% 30.15% 36-103
src/CanvasItem/CanvasItem.jsx 44.11% 100% 25% 44.11% 35-58, 71-104, 112-120
src/CanvasItem/Rect.jsx 38.12% 25% 40% 38.12% 37-102, 112-176, 184-232, 260-269
src/CanvasItem/ResizeHandle.jsx 10.97% 100% 0% 10.97% 10-89
src/CanvasItem/RotateHandle.jsx 12.76% 100% 0% 12.76% 9-51
src/CanvasItem/utils.jsx 21.03% 100% 9.09% 21.03% 16-20, 48-59, 69-80, 94-269, 318-322, 330-341
src/Card/DetailCard/DetailCard.tsx 0% 0% 0% 0% 1-179
src/Card/SummaryCard/SummaryCard.tsx 0% 0% 0% 0% 1-165
src/Card/TableCard/TableCard.tsx 0% 0% 0% 0% 1-75
src/CardContent/FileDetails/FileDetails.tsx 98.12% 100% 80% 98.12% 43-45
src/CardContent/Infographic/Infographic.tsx 0% 0% 0% 0% 1-116
src/Checkbox/Checkbox.jsx 100% 100% 50% 100%
src/ClientOnly/ClientOnly.tsx 0% 0% 0% 0% 1-17
src/Color/Color.jsx 97.67% 96.77% 90% 97.67% 68-69, 82-84
src/ConditionalDialog/ConditionalDialog.tsx 0% 0% 0% 0% 1-29
src/ConfirmProvider/ConfirmContext.tsx 100% 100% 100% 100%
src/ConfirmProvider/ConfirmProvider.tsx 97.16% 100% 100% 97.16% 93, 112-113
src/ConfirmProvider/ConfirmationDialog.tsx 98.86% 75% 100% 98.86% 78
src/ConfirmProvider/useConfirm.tsx 100% 100% 100% 100%
src/Copyright/Copyright.jsx 100% 100% 100% 100%
src/DateLabel/DateLabel.tsx 100% 100% 100% 100%
src/DeletableList/DeletableList.tsx 100% 100% 75% 100%
src/DialogTitle/DialogTitle.tsx 100% 100% 100% 100%
src/EditLabelDialog/EditLabelDialog.jsx 91.95% 100% 41.66% 91.95% 42-48, 127-138
src/FeedbackForm/FeedbackForm.jsx 98.63% 100% 91.66% 98.63% 67-71
src/Figure/Figure.tsx 0% 0% 0% 0% 1-46
src/Figure/FigureClientOnly.tsx 0% 0% 0% 0% 1-16
src/FileLabel/FileLabel.tsx 100% 100% 100% 100%
src/FileUploader/FileUploader.tsx 99.3% 92.3% 50% 99.3% 98
src/FileUploader/__data__/uploaderTestFiles.ts 100% 100% 100% 100%
src/Filter/sortFilterOptions.ts 82.75% 76.92% 100% 82.75% 13-14, 24-25, 45
src/Filter/sortLabelOptions.ts 82.75% 76.92% 100% 82.75% 15-16, 26-27, 47
src/Filter/CheckboxFilter/CheckboxFilter.tsx 95.77% 83.33% 100% 95.77% 75-77
src/Filter/ClearFilterButton/ClearFilterButton.tsx 100% 100% 100% 100%
src/Filter/LabelFilter/LabelFilter.tsx 94.31% 90% 80% 94.31% 84-89
src/Filter/RangeFilter/RangeFilter.jsx 100% 83.33% 100% 100%
src/Filter/SetFilterButton/SetFilterButton.tsx 100% 100% 100% 100%
src/Filter/SidebarFilter/SidebarFilter.tsx 100% 100% 75% 100%
src/FontPicker/FontPicker.jsx 93.62% 62.5% 66.66% 93.62% 160-166, 174, 206-210
src/FontStyle/FontStyle.jsx 100% 100% 50% 100%
src/FormatLabel/FormatLabel.tsx 100% 100% 100% 100%
src/FormatVersionLabel/FormatVersionLabel.tsx 100% 100% 100% 100%
src/IconWithLabel/IconWithLabel.tsx 100% 100% 100% 100%
src/ImageUploader/ImageUploader.tsx 99.18% 95.45% 100% 99.18% 85
src/ImageUploader/__data__/uploaderTestFiles.ts 100% 100% 100% 100%
src/LabelSelector/LabelSelector.jsx 98.09% 96.15% 77.77% 98.09% 135-139, 260-261
src/LabelSelector/DeleteLabelDialog/DeleteLabelDialog.jsx 89.36% 100% 40% 89.36% 23-29
src/LabelSelector/LabelChip/LabelChip.tsx 100% 100% 100% 100%
src/LabelSelector/LabelChipGroup/LabelChipGroup.tsx 30.87% 83.33% 20% 30.87% 52-79, 94-104, 121-173, 187-229
src/LabelSelector/LabelChipGroup/sortLabelChips.ts 100% 100% 100% 100%
src/LazyLoadImage/LazyLoadImage.tsx 0% 0% 0% 0% 1-97
src/LinePlot/LinePlot.tsx 0% 0% 0% 0% 1-188
src/LinePlot/LinePlotClientOnly.tsx 0% 0% 0% 0% 1-19
src/LinkWithPreview/LinkWithPreview.tsx 78.15% 100% 37.5% 78.15% 37-38, 43-46, 75-87, 91-102
src/LoadErrorMessage/LoadErrorMessage.tsx 0% 0% 0% 0% 1-167
src/Loading/Loading.jsx 96.55% 50% 100% 96.55% 29
src/LoginForm/LoginForm.jsx 100% 66.66% 50% 100%
src/ModelButton/ModelButton.tsx 96.78% 83.67% 75% 96.78% 119, 166, 168-169, 205, 218-219, 221-222, 246
src/ModelButtonImage/ModelButtonImage.tsx 100% 100% 100% 100%
src/ModelButtonImage/color2filter.ts 95.6% 100% 95.83% 95.6% 60-71
src/MultiColor/MultiColor.jsx 63.15% 80% 25% 63.15% 40, 52-59, 85-88, 92-93, 97-101, 105-109, 113-116, 150-183
src/MultiLabelPopover/MultiLabelPopover.jsx 97.56% 100% 66.66% 97.56% 22-23
src/MultiText/MultiText.jsx 95.55% 100% 71.42% 95.55% 74-77
src/NoWrapTypography/NoWrapTypography.tsx 100% 100% 100% 100%
src/NumberField/NumberField.tsx 96.46% 87.87% 100% 96.46% 112-115
src/PartSelector/PartSelector.tsx 0% 0% 0% 0% 1-103
src/PasswordChangeDialog/PasswordChangeDialog.jsx 95.29% 72.72% 100% 95.29% 100, 138-140, 143-145, 244
src/PasswordChangeForm/PasswordChangeForm.jsx 100% 84.61% 100% 100%
src/PasswordResetForm/PasswordResetForm.jsx 100% 66.66% 100% 100%
src/PrototypePreview/PrototypePreview.tsx 99.42% 71.42% 100% 99.42% 150
src/RadioButtons/RadioButtons.jsx 100% 100% 50% 100%
src/RegistrationForm/RegistrationForm.jsx 100% 76.47% 100% 100%
src/RoadLabel/RoadLabel.tsx 100% 100% 100% 100%
src/RoadMarking/RoadMarking.tsx 0% 0% 0% 0% 1-50
src/RoadMarking/RoadMarkingClientOnly.tsx 0% 0% 0% 0% 1-16
src/RoadPreview/RoadPreview.tsx 100% 83.33% 100% 100%
src/RoadSurface/RoadSurface.tsx 0% 0% 0% 0% 1-20
src/RoadSurface/RoadSurfaceClientOnly.tsx 0% 0% 0% 0% 1-16
src/ScenarioPreview/ScenarioPreview.tsx 95.75% 66.66% 100% 95.75% 33-36, 180-182
src/SearchBar/SearchBar.tsx 100% 100% 100% 100%
src/Select/Select.jsx 100% 100% 50% 100%
src/SelectorButton/SelectorButton.tsx 100% 100% 100% 100%
src/Sidebar/Sidebar.tsx 100% 87.5% 100% 100%
src/Sidebar/SidebarDivider/SidebarDivider.tsx 100% 100% 100% 100%
src/Sidebar/SidebarItem/SidebarItem.tsx 70.07% 80.95% 66.66% 70.07% 63, 101-136, 149-152
src/Slider/Slider.jsx 92.5% 36.84% 60% 92.5% 55-56, 65-69, 95, 99
src/Snackbar/Snackbar.tsx 100% 90% 85.71% 100%
src/SnackbarProvider/SnackbarContext.tsx 100% 100% 100% 100%
src/SnackbarProvider/SnackbarProvider.tsx 60.46% 100% 50% 60.46% 32-35, 42-55
src/SnackbarProvider/useSnackbar.ts 22.22% 100% 0% 22.22% 7-13
src/Status/statuses.ts 100% 100% 100% 100%
src/Status/StatusCard/StatusCard.tsx 100% 100% 100% 100%
src/Status/StatusCountBar/StatusCountBar.tsx 93.61% 80% 66.66% 93.61% 58-60
src/Status/StatusCountTable/StatusCountTable.tsx 100% 100% 100% 100%
src/Status/StatusIcon/StatusIcon.tsx 100% 100% 100% 100%
src/Status/StatusLabel/StatusLabel.tsx 100% 100% 100% 100%
src/SurfacePlot/SurfacePlot.tsx 0% 0% 0% 0% 1-156
src/SurfacePlot/SurfacePlotClientOnly.tsx 0% 0% 0% 0% 1-19
src/SvgIcons/AsamLogo/AsamLogo.tsx 100% 100% 100% 100%
src/SvgIcons/CarMakerLogo/CarMakerLogo.tsx 100% 100% 100% 100%
src/SvgIcons/IpgLogo/IpgLogo.tsx 100% 100% 100% 100%
src/SvgIcons/RoadOutlined/RoadOutlined.tsx 100% 100% 100% 100%
src/SvgIcons/TruckMakerLogo/TruckMakerLogo.tsx 100% 100% 100% 100%
src/SvgIcons/VirtoBuild/VirtoBuild.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoData/VirtoData.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoFleet/VirtoFleet.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoID/VirtoID.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoLogo/VirtoLogo.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoMascots/VirtoHeadScratching/VirtoHeadScratching.tsx 11.11% 100% 0% 11.11% 6-32
src/SvgIcons/VirtoMascots/VirtoShrugging/VirtoShrugging.tsx 11.11% 100% 0% 11.11% 6-32
src/SvgIcons/VirtoMascots/VirtoThinking/VirtoThinking.tsx 11.11% 100% 0% 11.11% 6-32
src/SvgIcons/VirtoMascots/VirtoThumbsUpLeft/VirtoThumbsUpLeft.tsx 11.11% 100% 0% 11.11% 6-32
src/SvgIcons/VirtoModel/VirtoModel.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoResult/VirtoResult.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoScene/VirtoScene.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoTest/VirtoTest.jsx 100% 100% 100% 100%
src/SvgIcons/VirtoVehicle/VirtoVehicle.jsx 100% 100% 100% 100%
src/SwitchField/SwitchField.jsx 93.84% 90.9% 100% 93.84% 112-115
src/TabPanel/TabPanel.tsx 0% 0% 0% 0% 1-121
src/TextField/TextField.tsx 89.47% 100% 66.66% 89.47% 8-13
src/ThemeProvider/ThemeContext.tsx 100% 100% 100% 100%
src/ThemeProvider/ThemeProvider.tsx 98.68% 93.75% 66.66% 98.68% 102, 189-190
src/ThemeProvider/useTheme.ts 77.77% 50% 100% 77.77% 10-11
src/ToggleColorMode/ToggleColorMode.jsx 100% 100% 100% 100%
src/TrafficLight/TrafficLight.tsx 0% 0% 0% 0% 1-107
src/TrafficLight/TrafficLightClientOnly.tsx 0% 0% 0% 0% 1-16
src/TrafficLight/TrafficLightSelector.tsx 0% 0% 0% 0% 1-780
src/TrafficLight/trafficLightUtils.ts 0% 100% 100% 0% 2-40
src/TrafficSign/TrafficSign.tsx 0% 0% 0% 0% 1-33
src/TrafficSign/TrafficSignClientOnly.tsx 0% 0% 0% 0% 1-16
src/TrafficSign/TrafficSignHelper.ts 0% 0% 0% 0% 1-333
src/TreeViewList/TreeViewList.tsx 0% 0% 0% 0% 1-513
src/TruncatedTooltip/TruncatedTooltip.tsx 91.76% 64.7% 75% 91.76% 61-62, 64-65, 83-84, 86
src/Uploader/UploaderHeader.tsx 87.69% 83.33% 100% 87.69% 30-33, 35-38
src/Uploader/useUploader.ts 89.74% 79.16% 100% 89.74% 39-41, 58, 63-67, 103, 181-182
src/UserAvatar/UserAvatar.tsx 100% 90.9% 100% 100%
src/UserAvatar/colorMap.tsx 100% 100% 100% 100%
src/UserLabel/UserLabel.tsx 100% 100% 100% 100%
src/UserMenu/UserMenu.tsx 100% 100% 100% 100%
src/VehiclePath/Marker.tsx 0% 0% 0% 0% 1-15
src/VehiclePath/Vehicle.tsx 0% 0% 0% 0% 1-59
src/VehiclePath/VehiclePath.tsx 0% 0% 0% 0% 1-55
src/VehiclePath/VehiclePathClientOnly.tsx 0% 0% 0% 0% 1-16
src/VehicleSelect/VehicleSelect.tsx 52.79% 88.46% 28.57% 52.79% 86-96, 108-118, 131-175, 188-218
src/VehicleSelectDialog/VehicleSelectDialog.tsx 87% 71.42% 40% 87% 40-47, 51-54, 93
src/VehicleSelector/VehicleSelector.tsx 57.14% 92.68% 16.66% 57.14% 96-106, 131-141, 168-224, 257-301
src/VersionChip/VersionChip.tsx 88.7% 70% 100% 88.7% 12, 46, 50, 77-80
src/VersionLabel/VersionLabel.tsx 100% 100% 100% 100%
src/ViewToggleButton/ViewToggleButton.jsx 100% 100% 66.66% 100%
src/VirtoAppHeader/VirtoAppHeader.tsx 100% 85.71% 78.57% 100%
src/VirtoAppLayout/VirtoAppLayout.tsx 100% 100% 60% 100%
src/Wizard/Wizard.tsx 100% 100% 100% 100%
src/Wizard/WizardActions/WizardActions.tsx 100% 100% 100% 100%
src/Wizard/WizardActions/BackButton/BackButton.tsx 100% 100% 100% 100%
src/Wizard/WizardActions/CancelButton/CancelButton.tsx 100% 100% 100% 100%
src/Wizard/WizardActions/NextButton/NextButton.tsx 100% 100% 100% 100%
src/Wizard/WizardContent/WizardContent.tsx 100% 100% 100% 100%
src/Wizard/WizardSteps/WizardSteps.tsx 100% 75% 100% 100%
src/Wizard/WizardSteps/WizardStep/WizardStep.tsx 92.15% 71.42% 100% 92.15% 49-52
src/hover/useDelayedHover.ts 60% 100% 100% 60% 26-40, 50-54
src/utils/common.ts 100% 83.33% 100% 100%
src/utils/form.jsx 100% 100% 100% 100%
src/utils/plotlyConfig.ts 0% 100% 100% 0% 2-34
src/utils/readAsDataURL.ts 80% 100% 66.66% 80% 20-22
Generated in workflow #3312 for commit f146c06 by the Vitest Coverage Report Action

@AronPetrauskas AronPetrauskas self-requested a review February 3, 2025 14:54
Copy link
Contributor

@AronPetrauskas AronPetrauskas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality of the component is as described. I suggest adding a few more tests, creating a common function to deal with the selection logic.

Also I have left a general question asking why are we exposing the onChange callback in a prop? Shouldn't this logic be internal and not up to the consumer of the component to decide?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you be targeting a release branch instead of the main? If so, then the change in the package.json should most likely be done in the release branch.

Comment on lines 142 to +160
const handleCheckAllTarget = () => {
// If all target items are checked, uncheck them
// Otherwise, check all target items
allTargetItemsChecked
? setChecked(
checked.filter(item => !targetItemsToTransfer.includes(item))
)
: setChecked([
...checked.filter(item => !targetItemsToTransfer.includes(item)),
...items
.map(item => filterKey(item))
.filter(item => keys.includes(item))
]);
// Get the items depending on if there is a search
const targetItemsToCheck = targetFilter
? filteredTargetItems
: allTargetItems;

// Get the items keys
const targetItemKeys = targetItemsToCheck.map(item => filterKey(item));

if (targetItemKeys.every(item => checked.includes(item))) {
// If all filtered items are checked, uncheck only those
setChecked(checked.filter(item => !targetItemKeys.includes(item)));
} else {
// Otherwise, check all filtered items
setChecked([
...checked,
...targetItemKeys.filter(item => !checked.includes(item))
]);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The selection/deselection logic for both the source and target are the same (except the the filter and the targetItems. These could be passed as props to a common function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General question, why is the onChange callback exposed? Shouldn't we always use the same logic within the component?

@@ -235,7 +237,7 @@ describe("TransferList", () => {
);

// test subheading is correct
expect(screen.getByText("2/3 selected"));
expect(screen.getByText("2 selected"));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also sanity check here:

Suggested change
// make sure target shows 0 selected
const zeroSelectedHeadings = screen.getAllByText("0 selected");
expect(zeroSelectedHeadings.length).toBe(1);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are a few test cases missing:

  1. When a user selects a value, searches for another value (list shows only one) selects this. Here we would expect to see the label to show 2 Selected (even though only one item is visible because of the search). In this state if we click the transfer button we would also expect both of the selected items to be transferred.
  2. Say I have a the values [AAA, AAC, BBB]. I select BBB, now I search for "AA", I would expect to see ["AAA", "AAC"]. If I click the select all I expect to see 3 Selected. If I click the select all again I expect to see 1 Selected. If I click select all again and clear the search I would expect to see 3 Selected, if I click select all again I expect to see 0 Selected
  3. A test to make sure that the select all on the source list has no affect on the selection of the target list and vice versa.

@AronPetrauskas
Copy link
Contributor

Please remember to solve the merge conflict too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants