Skip to content

Commit ae1cd24

Browse files
committed
feat: make infinite loading work for simple transfer
1 parent 2a04671 commit ae1cd24

13 files changed

Lines changed: 95 additions & 90 deletions

components/simple-transfer/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
> guide](https://github.com/dhis2/ui/blob/master/docs/getting-started.md)
66
> for more information.
77
8-
For usage instructions see [the documentation for this component](https://ui.dhis2.nu/components/transfer).
8+
For usage instructions see [the documentation for this component](https://ui.dhis2.nu/components/simple-transfer).

components/simple-transfer/src/__e2e__/add_remove-highlighted-options.e2e.stories.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ export default {
88
decorators: [statefulDecorator()],
99
}
1010

11+
export const HasOptions = (_, { onChange, selected }) => (
12+
<SimpleTransfer
13+
filterable
14+
selected={selected}
15+
onChange={onChange}
16+
options={options}
17+
/>
18+
)
1119
export const HasSelected = (_, { onChange, selected }) => (
1220
<SimpleTransfer onChange={onChange} selected={selected} options={options} />
1321
)

components/simple-transfer/src/features/disabled-transfer-buttons.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @button-states
1+
@component-simple-transfer @button-states
22
Feature: Disable transfer buttons when actions are not possible
33

44
Scenario: None of the selectable options are highlighted

components/simple-transfer/src/features/disabled-transfer-options.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @disabled-options
1+
@component-simple-transfer @disabled-options
22
Feature: Options can be disabled
33

44
Scenario: The user clicks a disabled option

components/simple-transfer/src/features/display-order.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @display-ordering
1+
@component-simple-transfer @display-ordering
22
Feature: Display order of items in lists
33

44
Scenario: All supplied options are rendered in the options-side

components/simple-transfer/src/features/filter-options-list.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @filtering
1+
@component-simple-transfer @filtering
22
Feature: Filter options list
33

44
Background:

components/simple-transfer/src/features/reorder-with-buttons.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @reordering
1+
@component-simple-transfer @reordering
22
Feature: Reorder items in the selected list using buttons
33

44
Background:

components/simple-transfer/src/features/set_unset-highlighted-option.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @highlighting
1+
@component-simple-transfer @highlighting
22
Feature: Set&unset the highlighted option
33

44
Scenario Outline: The user clicks an item that is not already highlighted

components/simple-transfer/src/features/transferring-items.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@component-transfer @transferring
1+
@component-simple-transfer @transferring
22
Feature: Transferring items between lists
33

44
Scenario: The user selects multiple items

components/simple-transfer/src/options-container.js

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { spacers } from '@dhis2/ui-constants'
12
import { CircularLoader } from '@dhis2-ui/loader'
23
import PropTypes from 'prop-types'
3-
import React, { Fragment, useRef } from 'react'
4+
import React, { Fragment, useEffect, useRef } from 'react'
45
import { SimpleTransferOption } from './simple-transfer-option.js'
56

67
export const OptionsContainer = ({
78
dataTest,
89
emptyComponent,
10+
onEndReached,
911
highlightedOptions,
1012
loading,
1113
maxSelections,
@@ -14,8 +16,37 @@ export const OptionsContainer = ({
1416
selectionHandler,
1517
setHighlightedOptions,
1618
}) => {
17-
const optionsRef = useRef(null)
19+
const selectRef = useRef(null)
1820
const wrapperRef = useRef(null)
21+
// const resizeCounter = useResizeCounter(wrapperRef.current)
22+
const lastOptionRef = useRef(null)
23+
24+
useEffect(() => {
25+
const observer = new IntersectionObserver(
26+
(entries) => {
27+
entries.forEach((entry) => {
28+
if (entry.isIntersecting) {
29+
onEndReached && onEndReached()
30+
}
31+
})
32+
},
33+
{
34+
root: wrapperRef.current,
35+
threshold: 1.0,
36+
}
37+
)
38+
39+
if (lastOptionRef.current) {
40+
observer.observe(lastOptionRef.current)
41+
}
42+
43+
return () => {
44+
if (lastOptionRef.current) {
45+
observer.unobserve(lastOptionRef.current)
46+
}
47+
observer.disconnect()
48+
}
49+
}, [options])
1950

2051
return (
2152
<div className="optionsContainer">
@@ -25,14 +56,14 @@ export const OptionsContainer = ({
2556
</div>
2657
)}
2758

28-
<div className="container" data-test={dataTest} ref={optionsRef}>
59+
<div className="container" data-test={dataTest} ref={wrapperRef}>
2960
{!options.length && emptyComponent}
3061
{!!options.length && (
3162
<select
63+
ref={selectRef}
64+
className="content-select"
3265
multiple={maxSelections === Infinity}
3366
size={maxSelections === 1 ? 2 : undefined}
34-
className="content-container"
35-
ref={wrapperRef}
3667
onChange={(e) => {
3768
const nextSelected = [...e.target.options].reduce(
3869
(curNextSelected, option) => {
@@ -47,7 +78,7 @@ export const OptionsContainer = ({
4778
setHighlightedOptions(nextSelected)
4879
}}
4980
>
50-
{options.map((option) => {
81+
{options.map((option, index) => {
5182
const highlighted = !!highlightedOptions.find(
5283
(highlightedSourceOption) =>
5384
highlightedSourceOption === option.value
@@ -61,6 +92,11 @@ export const OptionsContainer = ({
6192
highlighted={highlighted}
6293
selected={selected}
6394
onDoubleClick={selectionHandler}
95+
lastOptionReference={
96+
index === options.length - 1
97+
? lastOptionRef
98+
: undefined
99+
}
64100
/>
65101
</Fragment>
66102
)
@@ -70,6 +106,37 @@ export const OptionsContainer = ({
70106
</div>
71107

72108
<style jsx>{`
109+
.optionsContainer {
110+
flex-grow: 1;
111+
padding: ${spacers.dp4} 0;
112+
position: relative;
113+
overflow: hidden;
114+
}
115+
116+
.container {
117+
overflow-y: auto;
118+
height: 100%;
119+
}
120+
121+
.loading {
122+
display: flex;
123+
height: 100%;
124+
width: 100%;
125+
align-items: center;
126+
justify-content: center;
127+
position: absolute;
128+
z-index: 2;
129+
top: 0;
130+
inset-inline-start: 0;
131+
}
132+
133+
.content-select {
134+
border: none;
135+
position: relative;
136+
height: 100%;
137+
width: 100%;
138+
}
139+
73140
.loading + .container .content-container {
74141
filter: blur(2px);
75142
}
@@ -93,4 +160,5 @@ OptionsContainer.propTypes = {
93160
),
94161
selected: PropTypes.bool,
95162
selectionHandler: PropTypes.func,
163+
onEndReached: PropTypes.func,
96164
}

0 commit comments

Comments
 (0)