@dhis2-ui/transfer 10.16.2 → 10.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -9
- package/src/__e2e__/add_remove-highlighted-options.e2e.stories.js +30 -0
- package/src/__e2e__/common/options.js +90 -0
- package/src/__e2e__/common/stateful-decorator.js +33 -0
- package/src/__e2e__/common.js +0 -0
- package/src/__e2e__/disabled-transfer-buttons.e2e.stories.js +49 -0
- package/src/__e2e__/disabled-transfer-options.e2e.stories.js +21 -0
- package/src/__e2e__/display-order.e2e.stories.js +24 -0
- package/src/__e2e__/filter-options-list.e2e.stories.js +87 -0
- package/src/__e2e__/highlight-range-of-options.e2e.stories.js +52 -0
- package/src/__e2e__/loading_lists.e2e.stories.js +26 -0
- package/src/__e2e__/notify_at_end_of_list.e2e.stories.js +116 -0
- package/src/__e2e__/reorder-with-buttons.e2e.stories.js +35 -0
- package/src/__e2e__/set_unset-highlighted-option.e2e.stories.js +30 -0
- package/src/__e2e__/transferring-items.e2e.stories.js +27 -0
- package/src/__tests__/common.test.js +131 -0
- package/src/__tests__/helper/add-all-selectable-source-options.test.js +46 -0
- package/src/__tests__/helper/add-individual-source-options.test.js +80 -0
- package/src/__tests__/helper/default-filter-callback.test.js +45 -0
- package/src/__tests__/helper/is-reorder-down-disabled.test.js +96 -0
- package/src/__tests__/helper/is-reorder-up-disabled.test.js +96 -0
- package/src/__tests__/helper/move-highlighted-picked-option-down.test.js +111 -0
- package/src/__tests__/helper/move-highlighted-picked-option-to-bottom.test.js +101 -0
- package/src/__tests__/helper/move-highlighted-picked-option-to-top.test.js +101 -0
- package/src/__tests__/helper/move-highlighted-picked-option-up.test.js +111 -0
- package/src/__tests__/helper/remove-all-picked-options.test.js +29 -0
- package/src/__tests__/helper/remove-individual-picked-options.test.js +38 -0
- package/src/__tests__/helper/use-highlighted-option/create-toggle-highlighted-option.test.js +104 -0
- package/src/__tests__/helper/use-highlighted-option/toggle-add.test.js +84 -0
- package/src/__tests__/helper/use-highlighted-option/toggle-range.test.js +150 -0
- package/src/__tests__/helper/use-highlighted-option/toggle-replace.test.js +39 -0
- package/src/__tests__/helper/use-highlighted-option.test.js +41 -0
- package/src/__tests__/reordering-actions.test.js +165 -0
- package/src/__tests__/transfer.test.js +137 -0
- package/src/actions.js +33 -0
- package/src/add-all.js +27 -0
- package/src/add-individual.js +27 -0
- package/src/common/find-option-index.js +9 -0
- package/src/common/get-mode-by-modifier-key.js +35 -0
- package/src/common/index.js +5 -0
- package/src/common/is-option.js +7 -0
- package/src/common/modes.js +11 -0
- package/src/common/remove-option.js +19 -0
- package/src/common/toggle-value.js +18 -0
- package/src/container.js +23 -0
- package/src/end-intersection-detector.js +37 -0
- package/src/features/add_remove-highlighted-options/index.js +92 -0
- package/src/features/add_remove-highlighted-options.feature +41 -0
- package/src/features/common/index.js +8 -0
- package/src/features/disabled-transfer-buttons/index.js +118 -0
- package/src/features/disabled-transfer-buttons.feature +46 -0
- package/src/features/disabled-transfer-options/index.js +182 -0
- package/src/features/disabled-transfer-options.feature +42 -0
- package/src/features/display-order/index.js +205 -0
- package/src/features/display-order.feature +30 -0
- package/src/features/filter-options-list/index.js +133 -0
- package/src/features/filter-options-list.feature +40 -0
- package/src/features/highlight-range-of-options/index.js +336 -0
- package/src/features/highlight-range-of-options.feature +70 -0
- package/src/features/loading_lists/index.js +43 -0
- package/src/features/loading_lists.feature +19 -0
- package/src/features/notify_at_end_of_list/index.js +125 -0
- package/src/features/notify_at_end_of_list.feature +64 -0
- package/src/features/reorder-with-buttons/index.js +181 -0
- package/src/features/reorder-with-buttons.feature +138 -0
- package/src/features/set_unset-highlighted-option/index.js +121 -0
- package/src/features/set_unset-highlighted-option.feature +42 -0
- package/src/features/transferring-items/index.js +375 -0
- package/src/features/transferring-items.feature +44 -0
- package/src/filter.js +38 -0
- package/src/icons.js +194 -0
- package/src/index.js +2 -0
- package/src/left-footer.js +22 -0
- package/src/left-header.js +22 -0
- package/src/left-side.js +34 -0
- package/src/locales/en/translations.json +7 -0
- package/src/locales/index.js +16 -0
- package/src/options-container.js +127 -0
- package/src/remove-all.js +27 -0
- package/src/remove-individual.js +27 -0
- package/src/reordering-actions.js +136 -0
- package/src/right-footer.js +22 -0
- package/src/right-header.js +22 -0
- package/src/right-side.js +33 -0
- package/src/transfer/add-all-selectable-source-options.js +37 -0
- package/src/transfer/add-individual-source-options.js +61 -0
- package/src/transfer/create-double-click-handlers.js +36 -0
- package/src/transfer/default-filter-callback.js +17 -0
- package/src/transfer/get-highlighted-picked-indices.js +26 -0
- package/src/transfer/get-option-click-handlers.js +19 -0
- package/src/transfer/index.js +17 -0
- package/src/transfer/is-reorder-down-disabled.js +34 -0
- package/src/transfer/is-reorder-up-disabled.js +30 -0
- package/src/transfer/move-highlighted-picked-option-down.js +54 -0
- package/src/transfer/move-highlighted-picked-option-to-bottom.js +44 -0
- package/src/transfer/move-highlighted-picked-option-to-top.js +38 -0
- package/src/transfer/move-highlighted-picked-option-up.js +47 -0
- package/src/transfer/remove-all-picked-options.js +13 -0
- package/src/transfer/remove-individual-picked-options.js +49 -0
- package/src/transfer/use-filter.js +17 -0
- package/src/transfer/use-highlighted-options/create-toggle-highlighted-option.js +64 -0
- package/src/transfer/use-highlighted-options/toggle-add.js +20 -0
- package/src/transfer/use-highlighted-options/toggle-range.js +61 -0
- package/src/transfer/use-highlighted-options/toggle-replace.js +26 -0
- package/src/transfer/use-highlighted-options.js +34 -0
- package/src/transfer/use-options-key-monitor.js +41 -0
- package/src/transfer-option.js +91 -0
- package/src/transfer.js +539 -0
- package/src/transfer.prod.stories.js +621 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Click modes when clicking on an option with/without
|
|
3
|
+
* a modifier key (ctrl, alt, cmd, shift)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// no or multiple modifier keys
|
|
7
|
+
export const REPLACE_MODE = 'REPLACE_MODE'
|
|
8
|
+
// add/remove options from selection
|
|
9
|
+
export const ADD_MODE = 'ADD_MODE'
|
|
10
|
+
// create selection range
|
|
11
|
+
export const RANGE_MODE = 'RANGE_MODE'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { findOptionIndex } from './find-option-index.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {Object[]} options
|
|
5
|
+
* @param {Object} option
|
|
6
|
+
* @returns {Object}
|
|
7
|
+
*/
|
|
8
|
+
export const removeOption = (options, option) => {
|
|
9
|
+
const index = findOptionIndex(options, option)
|
|
10
|
+
|
|
11
|
+
if (index === -1) {
|
|
12
|
+
return options
|
|
13
|
+
}
|
|
14
|
+
if (index === 0) {
|
|
15
|
+
return options.slice(1)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return [...options.slice(0, index), ...options.slice(index + 1)]
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string[]} values
|
|
3
|
+
* @param {string} value
|
|
4
|
+
* @returns {string[]}
|
|
5
|
+
*/
|
|
6
|
+
export const toggleValue = (values, value) => {
|
|
7
|
+
const index = values.indexOf(value)
|
|
8
|
+
|
|
9
|
+
if (index === -1) {
|
|
10
|
+
return [...values, value]
|
|
11
|
+
} else if (index === 0) {
|
|
12
|
+
values.slice(1)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const prevSlice = values.slice(0, index)
|
|
16
|
+
const nextSlice = values.slice(index + 1)
|
|
17
|
+
return [...prevSlice, ...nextSlice]
|
|
18
|
+
}
|
package/src/container.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import PropTypes from 'prop-types'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
export const Container = ({ children, dataTest, className, height }) => (
|
|
5
|
+
<div data-test={dataTest} className={className}>
|
|
6
|
+
{children}
|
|
7
|
+
|
|
8
|
+
<style jsx>{`
|
|
9
|
+
div {
|
|
10
|
+
display: flex;
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: ${height};
|
|
13
|
+
}
|
|
14
|
+
`}</style>
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
Container.propTypes = {
|
|
19
|
+
height: PropTypes.string.isRequired,
|
|
20
|
+
children: PropTypes.node,
|
|
21
|
+
className: PropTypes.string,
|
|
22
|
+
dataTest: PropTypes.string,
|
|
23
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IntersectionDetector } from '@dhis2-ui/intersection-detector'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
export const INTERSECTION_DETECTOR_HEIGHT = 50
|
|
6
|
+
|
|
7
|
+
export const EndIntersectionDetector = ({
|
|
8
|
+
rootRef,
|
|
9
|
+
onEndReached,
|
|
10
|
+
dataTest,
|
|
11
|
+
}) => (
|
|
12
|
+
<div data-test={dataTest}>
|
|
13
|
+
<IntersectionDetector
|
|
14
|
+
rootRef={rootRef}
|
|
15
|
+
onChange={({ isIntersecting }) => isIntersecting && onEndReached()}
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<style jsx>{`
|
|
19
|
+
div {
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: ${INTERSECTION_DETECTOR_HEIGHT}px;
|
|
22
|
+
position: absolute;
|
|
23
|
+
z-index: -1;
|
|
24
|
+
bottom: 0;
|
|
25
|
+
inset-inline-start: 0;
|
|
26
|
+
}
|
|
27
|
+
`}</style>
|
|
28
|
+
</div>
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
EndIntersectionDetector.propTypes = {
|
|
32
|
+
rootRef: PropTypes.shape({
|
|
33
|
+
current: PropTypes.instanceOf(HTMLElement),
|
|
34
|
+
}).isRequired,
|
|
35
|
+
onEndReached: PropTypes.func.isRequired,
|
|
36
|
+
dataTest: PropTypes.string,
|
|
37
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('the option list has two or more items', () => {
|
|
4
|
+
cy.visitStory('Transfer add & remove highlighted options', 'Has Options')
|
|
5
|
+
cy.get('{transfer-sourceoptions}').as('list')
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
Given('the selected list has two or more items', () => {
|
|
9
|
+
cy.visitStory('Transfer add & remove highlighted options', 'Has Selected')
|
|
10
|
+
cy.get('{transfer-pickedoptions}').as('list')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
Given('some items are highlighted', () => {
|
|
14
|
+
cy.get('@list')
|
|
15
|
+
.find('{transferoption}')
|
|
16
|
+
.then(($options) => {
|
|
17
|
+
const multipleOptions = $options.filter((index) => index < 3)
|
|
18
|
+
return cy.wrap(multipleOptions)
|
|
19
|
+
})
|
|
20
|
+
.as('highlightedMultipleOptions')
|
|
21
|
+
.each(($option) => cy.wrap($option).clickWith('ctrl'))
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
When(
|
|
25
|
+
'the user clicks multiple items with {string} which are not highlighted',
|
|
26
|
+
(modifierKey) => {
|
|
27
|
+
cy.get('@list')
|
|
28
|
+
.find('{transferoption}')
|
|
29
|
+
.then(($options) => {
|
|
30
|
+
const multipleOptions = $options.filter((index) => index < 3)
|
|
31
|
+
return cy.wrap(multipleOptions)
|
|
32
|
+
})
|
|
33
|
+
.as('multipleOptions')
|
|
34
|
+
.each(($option) =>
|
|
35
|
+
cy
|
|
36
|
+
.wrap($option)
|
|
37
|
+
.clickWith(modifierKey === 'cmd' ? 'meta' : modifierKey)
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
When(
|
|
43
|
+
'the user clicks on one item with {string} which is highlighted',
|
|
44
|
+
(modifierKey) => {
|
|
45
|
+
cy.get('@highlightedMultipleOptions')
|
|
46
|
+
.first()
|
|
47
|
+
.clickWith(modifierKey === 'cmd' ? 'meta' : modifierKey)
|
|
48
|
+
.as('clickedOption')
|
|
49
|
+
cy.get('@highlightedMultipleOptions')
|
|
50
|
+
.filter((index) => index !== 0)
|
|
51
|
+
.as('remainingHighlightedOptions')
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
When(
|
|
56
|
+
'the user clicks on one item without a modifier key which is highlighted',
|
|
57
|
+
() => {
|
|
58
|
+
cy.get('@highlightedMultipleOptions')
|
|
59
|
+
.first()
|
|
60
|
+
.click()
|
|
61
|
+
.as('clickedOption')
|
|
62
|
+
cy.get('@highlightedMultipleOptions')
|
|
63
|
+
.filter((index) => index !== 0)
|
|
64
|
+
.as('remainingHighlightedOptions')
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
Then('all of the clicked items should be highlighted', () => {
|
|
69
|
+
cy.get('@multipleOptions').each(($option) => {
|
|
70
|
+
expect($option).to.have.class('highlighted')
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
Then('the clicked item should not be highlighted', () => {
|
|
75
|
+
cy.get('@clickedOption').should('not.have.class', 'highlighted')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
Then('the other previously highlighted items should remain highlighted', () => {
|
|
79
|
+
cy.get('@remainingHighlightedOptions').each(($option) => {
|
|
80
|
+
expect($option).to.have.class('highlighted')
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
Then('the clicked option is highlighted', () => {
|
|
85
|
+
cy.get('@clickedOption').should('have.class', 'highlighted')
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
Then('the other previously highlighted items should not be highlighted', () => {
|
|
89
|
+
cy.get('@remainingHighlightedOptions').each(($option) => {
|
|
90
|
+
expect($option).to.not.have.class('highlighted')
|
|
91
|
+
})
|
|
92
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Feature: Add/Remove options to/from the highlighted options
|
|
2
|
+
|
|
3
|
+
Scenario Outline: Highlight multiple items using CMD/CTRL+click
|
|
4
|
+
Given the <type> list has two or more items
|
|
5
|
+
When the user clicks multiple items with "<metaKey>" which are not highlighted
|
|
6
|
+
Then all of the clicked items should be highlighted
|
|
7
|
+
|
|
8
|
+
Examples:
|
|
9
|
+
| type | metaKey |
|
|
10
|
+
| option | cmd |
|
|
11
|
+
| option | ctrl |
|
|
12
|
+
| selected | cmd |
|
|
13
|
+
| selected | ctrl |
|
|
14
|
+
|
|
15
|
+
Scenario Outline: Unhighlight items using CMD/CTRL+click
|
|
16
|
+
Given the <type> list has two or more items
|
|
17
|
+
And some items are highlighted
|
|
18
|
+
When the user clicks on one item with "<metaKey>" which is highlighted
|
|
19
|
+
Then the clicked item should not be highlighted
|
|
20
|
+
And the other previously highlighted items should remain highlighted
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
| type | metaKey |
|
|
24
|
+
| option | cmd |
|
|
25
|
+
| option | ctrl |
|
|
26
|
+
| selected | cmd |
|
|
27
|
+
| selected | ctrl |
|
|
28
|
+
|
|
29
|
+
Scenario Outline: A user clicks a highlighted option without a modifier key when multiple options are highlighted
|
|
30
|
+
Given the <type> list has two or more items
|
|
31
|
+
And some items are highlighted
|
|
32
|
+
When the user clicks on one item without a modifier key which is highlighted
|
|
33
|
+
Then the clicked option is highlighted
|
|
34
|
+
And the other previously highlighted items should not be highlighted
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
| type | metaKey |
|
|
38
|
+
| option | cmd |
|
|
39
|
+
| option | ctrl |
|
|
40
|
+
| selected | cmd |
|
|
41
|
+
| selected | ctrl |
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('the options list has items', () => {
|
|
4
|
+
cy.visitStory('Transfer Disabled Transfer Buttons', 'Has Options')
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
Given('the selected list has items', () => {
|
|
8
|
+
cy.visitStory('Transfer Disabled Transfer Buttons', 'Some Options Selected')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
Given('the transfer does not have any options', () => {
|
|
12
|
+
cy.visitStory('Transfer Disabled Transfer Buttons', 'No Options')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
Given('all options have been selected', () => {
|
|
16
|
+
cy.visitStory('Transfer Disabled Transfer Buttons', 'All Options Selected')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
Given('the selected list does not have items', () => {
|
|
20
|
+
cy.visitStory('Transfer Disabled Transfer Buttons', 'Has Options')
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
Given('no option items are highlighted', () => {
|
|
24
|
+
cy.get(
|
|
25
|
+
'[data-test="dhis2-uicore-transfer-sourceoptions"] [data-test="dhis2-uicore-transferoption"]'
|
|
26
|
+
).each(($option) =>
|
|
27
|
+
cy.wrap($option).should('not.have.class', 'highlighted')
|
|
28
|
+
)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
Given('some option items are highlighted', () => {
|
|
32
|
+
cy.get(
|
|
33
|
+
'[data-test="dhis2-uicore-transfer-sourceoptions"] [data-test="dhis2-uicore-transferoption"]'
|
|
34
|
+
)
|
|
35
|
+
.first()
|
|
36
|
+
.click()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
Given('no selected items are highlighted', () => {
|
|
40
|
+
cy.get(
|
|
41
|
+
'[data-test="dhis2-uicore-transfer-pickedoptions"] [data-test="dhis2-uicore-transferoption"]'
|
|
42
|
+
).each(($option) =>
|
|
43
|
+
cy.wrap($option).should('not.have.class', 'highlighted')
|
|
44
|
+
)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
Given('some selected items are highlighted', () => {
|
|
48
|
+
cy.get(
|
|
49
|
+
'[data-test="dhis2-uicore-transfer-pickedoptions"] [data-test="dhis2-uicore-transferoption"]'
|
|
50
|
+
)
|
|
51
|
+
.first()
|
|
52
|
+
.click()
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
Given('a source list that has only disabled options', () => {
|
|
56
|
+
cy.visitStory(
|
|
57
|
+
'Transfer Disabled Transfer Buttons',
|
|
58
|
+
'Only Disabled Source Options'
|
|
59
|
+
)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
Then("the 'move to picked list' button should be disabled", () => {
|
|
63
|
+
cy.get(
|
|
64
|
+
'[data-test="dhis2-uicore-transfer-actions-addindividual"][disabled]'
|
|
65
|
+
).should('exist')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
Then("the 'move to picked list' button should be enabled", () => {
|
|
69
|
+
cy.get('[data-test="dhis2-uicore-transfer-actions-addindividual"]').should(
|
|
70
|
+
'exist'
|
|
71
|
+
)
|
|
72
|
+
cy.get(
|
|
73
|
+
'[data-test="dhis2-uicore-transfer-actions-addindividual"][disabled]'
|
|
74
|
+
).should('not.exist')
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
Then("the 'move to source list' button should be disabled", () => {
|
|
78
|
+
cy.get(
|
|
79
|
+
'[data-test="dhis2-uicore-transfer-actions-removeindividual"][disabled]'
|
|
80
|
+
).should('exist')
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
Then("the 'move to source list' button should be enabled", () => {
|
|
84
|
+
cy.get(
|
|
85
|
+
'[data-test="dhis2-uicore-transfer-actions-removeindividual"]'
|
|
86
|
+
).should('exist')
|
|
87
|
+
cy.get(
|
|
88
|
+
'[data-test="dhis2-uicore-transfer-actions-removeindividual"][disabled]'
|
|
89
|
+
).should('not.exist')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
Then("the 'move all to picked list' button should be disabled", () => {
|
|
93
|
+
cy.get(
|
|
94
|
+
'[data-test="dhis2-uicore-transfer-actions-addall"][disabled]'
|
|
95
|
+
).should('exist')
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
Then("the 'move all to picked list' button should be enabled", () => {
|
|
99
|
+
cy.get('[data-test="dhis2-uicore-transfer-actions-addall"]').should('exist')
|
|
100
|
+
cy.get(
|
|
101
|
+
'[data-test="dhis2-uicore-transfer-actions-addall"][disabled]'
|
|
102
|
+
).should('not.exist')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
Then("the 'move all to source list' button should be disabled", () => {
|
|
106
|
+
cy.get(
|
|
107
|
+
'[data-test="dhis2-uicore-transfer-actions-removeall"][disabled]'
|
|
108
|
+
).should('exist')
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
Then("the 'move all to source list' button should be enabled", () => {
|
|
112
|
+
cy.get('[data-test="dhis2-uicore-transfer-actions-removeall"]').should(
|
|
113
|
+
'exist'
|
|
114
|
+
)
|
|
115
|
+
cy.get(
|
|
116
|
+
'[data-test="dhis2-uicore-transfer-actions-removeall"][disabled]'
|
|
117
|
+
).should('not.exist')
|
|
118
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
@component-transfer @button-states
|
|
2
|
+
Feature: Disable transfer buttons when actions are not possible
|
|
3
|
+
|
|
4
|
+
Scenario: None of the selectable options are highlighted
|
|
5
|
+
Given the options list has items
|
|
6
|
+
And no option items are highlighted
|
|
7
|
+
Then the 'move to picked list' button should be disabled
|
|
8
|
+
|
|
9
|
+
Scenario: Some of the selectable options are highlighted
|
|
10
|
+
Given the options list has items
|
|
11
|
+
And some option items are highlighted
|
|
12
|
+
Then the 'move to picked list' button should be enabled
|
|
13
|
+
|
|
14
|
+
Scenario: None of the selected options are highlighted
|
|
15
|
+
Given the selected list has items
|
|
16
|
+
And no selected items are highlighted
|
|
17
|
+
Then the 'move to source list' button should be disabled
|
|
18
|
+
|
|
19
|
+
Scenario: Some of the selected options are highlighted
|
|
20
|
+
Given the selected list has items
|
|
21
|
+
And some selected items are highlighted
|
|
22
|
+
Then the 'move to source list' button should be enabled
|
|
23
|
+
|
|
24
|
+
Scenario: The transfer does not have any options at all
|
|
25
|
+
Given the transfer does not have any options
|
|
26
|
+
Then the 'move all to picked list' button should be disabled
|
|
27
|
+
|
|
28
|
+
Scenario: All options are on the selected side
|
|
29
|
+
Given all options have been selected
|
|
30
|
+
Then the 'move all to picked list' button should be disabled
|
|
31
|
+
|
|
32
|
+
Scenario: Some items in options list
|
|
33
|
+
Given the options list has items
|
|
34
|
+
Then the 'move all to picked list' button should be enabled
|
|
35
|
+
|
|
36
|
+
Scenario: No items in selected list
|
|
37
|
+
Given the selected list does not have items
|
|
38
|
+
Then the 'move all to source list' button should be disabled
|
|
39
|
+
|
|
40
|
+
Scenario: Some items in selected list
|
|
41
|
+
Given the selected list has items
|
|
42
|
+
Then the 'move all to source list' button should be enabled
|
|
43
|
+
|
|
44
|
+
Scenario: Only disabled options in source list
|
|
45
|
+
Given a source list that has only disabled options
|
|
46
|
+
Then the 'move all to picked list' button should be disabled
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
import { extractOptionFromElement } from '../common/index.js'
|
|
3
|
+
|
|
4
|
+
const enabledSourceOptionSelector =
|
|
5
|
+
'{transfer-sourceoptions} {transferoption}:not(.disabled)'
|
|
6
|
+
|
|
7
|
+
const disabledSourceOptionSelector =
|
|
8
|
+
'{transfer-sourceoptions} {transferoption}.disabled'
|
|
9
|
+
|
|
10
|
+
Given('a source list that contains a disabled option', () => {
|
|
11
|
+
cy.visitStory('Disabled Source Options', 'One Disabled')
|
|
12
|
+
cy.get(disabledSourceOptionSelector)
|
|
13
|
+
.first()
|
|
14
|
+
.as('disabledSourceOption')
|
|
15
|
+
.should('exist')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
Given(
|
|
19
|
+
'a source list that contains at least one disabled option and at least one enabled option',
|
|
20
|
+
() => {
|
|
21
|
+
cy.visitStory('Disabled Source Options', 'One Disabled')
|
|
22
|
+
cy.get(disabledSourceOptionSelector)
|
|
23
|
+
.first()
|
|
24
|
+
.as('disabledSourceOption')
|
|
25
|
+
.should('exist')
|
|
26
|
+
cy.get(enabledSourceOptionSelector)
|
|
27
|
+
.as('enabledSourceOptions')
|
|
28
|
+
.should('exist')
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
Given(
|
|
33
|
+
'a source list that contains at least one disabled option and at least one enabled highlighted option',
|
|
34
|
+
() => {
|
|
35
|
+
cy.visitStory('Disabled Source Options', 'One Disabled')
|
|
36
|
+
cy.get(disabledSourceOptionSelector)
|
|
37
|
+
.first()
|
|
38
|
+
.as('disabledSourceOption')
|
|
39
|
+
.should('exist')
|
|
40
|
+
cy.get(enabledSourceOptionSelector)
|
|
41
|
+
.invoke('slice', 0, 2)
|
|
42
|
+
.as('enabledHighlightedSourceOptions')
|
|
43
|
+
.each(($option) => cy.wrap($option).click())
|
|
44
|
+
.should('have.class', 'highlighted')
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
Given(
|
|
49
|
+
'a source list that contains at least one disabled option and several enabled options',
|
|
50
|
+
() => {
|
|
51
|
+
cy.visitStory('Disabled Source Options', 'One Disabled')
|
|
52
|
+
cy.get(disabledSourceOptionSelector)
|
|
53
|
+
.first()
|
|
54
|
+
.as('disabledSourceOption')
|
|
55
|
+
.should('exist')
|
|
56
|
+
cy.get(enabledSourceOptionSelector)
|
|
57
|
+
.as('enabledSourceOptions')
|
|
58
|
+
.should('have.length.of.at.least', 2)
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
When('the user clicks a disabled option', () => {
|
|
63
|
+
cy.get(disabledSourceOptionSelector).click().as('clickedDisabledOption')
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
When('the user double clicks a disabled option', () => {
|
|
67
|
+
cy.get(disabledSourceOptionSelector)
|
|
68
|
+
.dblclick()
|
|
69
|
+
.as('doubleClickedDisabledOption')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
When("the user clicks the 'move all to picked list' button", () => {
|
|
73
|
+
cy.get('{transfer-actions-addall}').click()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
When('the user clicks the disabled item with {string}', (type) => {
|
|
77
|
+
cy.get(disabledSourceOptionSelector)
|
|
78
|
+
.clickWith(type)
|
|
79
|
+
.as('clickedWithModifierDisabledOption')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
When('the user SHIFT+clicks the disabled item', () => {
|
|
83
|
+
cy.get(disabledSourceOptionSelector)
|
|
84
|
+
.clickWith('shift')
|
|
85
|
+
.as('clickedWithShiftDisabledOption')
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
When('the user clicks an enabled option', () => {
|
|
89
|
+
cy.get(enabledSourceOptionSelector)
|
|
90
|
+
.first()
|
|
91
|
+
.click()
|
|
92
|
+
.as('clickedEnabledOption')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
When(
|
|
96
|
+
'SHIFT+clicks another enabled option, including a disabled item in the range of options',
|
|
97
|
+
() => {
|
|
98
|
+
cy.get(disabledSourceOptionSelector)
|
|
99
|
+
.next()
|
|
100
|
+
.clickWith('shift')
|
|
101
|
+
.as('clickedWithShiftEnabledOption')
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
Then('the disabled option is not highlighted', () => {
|
|
106
|
+
cy.get('@disabledSourceOption').should('not.have.class', 'highlighted')
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
Then('the disabled option is not transferred to the picked list', () => {
|
|
110
|
+
// if the aliased element still exists, it hasn't been removed
|
|
111
|
+
// from the source list. Transferring does not need to be tested
|
|
112
|
+
// here as that's covered by another test
|
|
113
|
+
cy.get('@disabledSourceOption').should('exist')
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
Then('the disabled options are not transferred to the picked list', () => {
|
|
117
|
+
// if the aliased element still exists, it hasn't been removed
|
|
118
|
+
// from the source list. Transferring does not need to be tested
|
|
119
|
+
// here as that's covered by another test
|
|
120
|
+
cy.get('@disabledSourceOption').should('exist')
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
Then('the enabled options are transferred to the picked list', () => {
|
|
124
|
+
// if the aliased elements don't exist, it hasn't been removed
|
|
125
|
+
// from the source list. Transferring does not need to be tested
|
|
126
|
+
// here as that's covered by another test
|
|
127
|
+
cy.get('@enabledSourceOptions').should('not.exist')
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
Then('the previously highlighted items are still highlighted', () => {
|
|
131
|
+
cy.get('@enabledHighlightedSourceOptions').should(
|
|
132
|
+
'have.class',
|
|
133
|
+
'highlighted'
|
|
134
|
+
)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
Then('only the previously highlighted items are highlighted', () => {
|
|
138
|
+
cy.get('@enabledHighlightedSourceOptions').should(
|
|
139
|
+
'have.class',
|
|
140
|
+
'highlighted'
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
cy.all(
|
|
144
|
+
() => cy.get('{transfer-sourceoptions} {transferoption}'),
|
|
145
|
+
() => cy.get('@enabledHighlightedSourceOptions')
|
|
146
|
+
).should(([$sourceOptions, $previouslyHighlightedOptions]) => {
|
|
147
|
+
const previouslyHighlightedOptions = $previouslyHighlightedOptions
|
|
148
|
+
.toArray()
|
|
149
|
+
.map(extractOptionFromElement)
|
|
150
|
+
|
|
151
|
+
const $notHighlightedSourceOptions = $sourceOptions.filter(
|
|
152
|
+
(_index, sourceOptionEl) => {
|
|
153
|
+
const label = sourceOptionEl.innerText
|
|
154
|
+
const value = sourceOptionEl.dataset.value
|
|
155
|
+
!previouslyHighlightedOptions.find(
|
|
156
|
+
(option) => value === option.value && label === option.label
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
$notHighlightedSourceOptions.each((_index, option) => {
|
|
162
|
+
cy.wrap(option).should('not.have.class', 'highlighted')
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
Then('the enabled options in the range are highlighted', () => {
|
|
168
|
+
cy.all(
|
|
169
|
+
() => cy.get('{transfer-sourceoptions} {transferoption}'),
|
|
170
|
+
() => cy.get('@clickedEnabledOption'),
|
|
171
|
+
() => cy.get('@clickedWithShiftEnabledOption')
|
|
172
|
+
).should(
|
|
173
|
+
([$all, $clickedEnabledOption, $clickedWithShiftEnabledOption]) => {
|
|
174
|
+
const from = $clickedEnabledOption.index()
|
|
175
|
+
const to = $clickedWithShiftEnabledOption.index()
|
|
176
|
+
const $allInRange = $all.slice(from, to + 1)
|
|
177
|
+
const $allInRangeEnabled = $allInRange.filter(':not(.disabled)')
|
|
178
|
+
|
|
179
|
+
expect($allInRangeEnabled).to.have.class('highlighted')
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@component-transfer @disabled-options
|
|
2
|
+
Feature: Options can be disabled
|
|
3
|
+
|
|
4
|
+
Scenario: The user clicks a disabled option
|
|
5
|
+
Given a source list that contains a disabled option
|
|
6
|
+
When the user clicks a disabled option
|
|
7
|
+
Then the disabled option is not highlighted
|
|
8
|
+
|
|
9
|
+
Scenario: The user double clicks a disabled option
|
|
10
|
+
Given a source list that contains a disabled option
|
|
11
|
+
When the user double clicks a disabled option
|
|
12
|
+
Then the disabled option is not transferred to the picked list
|
|
13
|
+
|
|
14
|
+
Scenario: The user clicks the 'move all to picked list' button with disabled options in the source list
|
|
15
|
+
Given a source list that contains at least one disabled option and at least one enabled option
|
|
16
|
+
When the user clicks the 'move all to picked list' button
|
|
17
|
+
Then the disabled options are not transferred to the picked list
|
|
18
|
+
And the enabled options are transferred to the picked list
|
|
19
|
+
|
|
20
|
+
Scenario Outline: The user CMD/CTRL+clicks a disabled item with other items highlighted
|
|
21
|
+
Given a source list that contains at least one disabled option and at least one enabled highlighted option
|
|
22
|
+
When the user clicks the disabled item with "<type>"
|
|
23
|
+
Then the disabled option is not highlighted
|
|
24
|
+
And the previously highlighted items are still highlighted
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
| type |
|
|
28
|
+
| ctrl |
|
|
29
|
+
| cmd |
|
|
30
|
+
|
|
31
|
+
Scenario: The user SHIFT+clicks a disabled item with other items highlighted
|
|
32
|
+
Given a source list that contains at least one disabled option and at least one enabled highlighted option
|
|
33
|
+
When the user SHIFT+clicks the disabled item
|
|
34
|
+
Then the disabled option is not highlighted
|
|
35
|
+
And only the previously highlighted items are highlighted
|
|
36
|
+
|
|
37
|
+
Scenario: The user SHIFT+clicks to select a range of options that include a disabled option
|
|
38
|
+
Given a source list that contains at least one disabled option and several enabled options
|
|
39
|
+
When the user clicks an enabled option
|
|
40
|
+
And SHIFT+clicks another enabled option, including a disabled item in the range of options
|
|
41
|
+
Then the enabled options in the range are highlighted
|
|
42
|
+
And the disabled option is not highlighted
|