Skip to content

Commit

Permalink
DualList add empty state
Browse files Browse the repository at this point in the history
Change-Id: I6e041f792f554157d76e27f14b9116d5485ae721
  • Loading branch information
hojjat-afsharan committed Oct 9, 2024
1 parent 54b1674 commit dec2a8d
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 37 deletions.
2 changes: 2 additions & 0 deletions cmk/gui/form_specs/vue/shared_type_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class DualListChoiceI18n:
available_options: str
selected_options: str
selected: str
no_elements_available: str
no_elements_selected: str


class CascadingChoiceLayout(str, Enum):
Expand Down
2 changes: 2 additions & 0 deletions cmk/gui/form_specs/vue/visitors/multiple_choice.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ def _to_vue(
available_options=_("Available options"),
selected_options=_("Selected options"),
selected=_("Selected"),
no_elements_available=_("No elements available"),
no_elements_selected=_("No elements selected"),
),
show_toggle_all=self.form_spec.show_toggle_all,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
DualListChoice,
MultipleChoiceElement
} from '@/form/components/vue_formspec_components'

import { useId } from '@/form/utils'

const props = defineProps<{
Expand Down Expand Up @@ -198,23 +199,29 @@ const handleDoubleClickToRemoveItem = (elementName: string) => {

<tr>
<td>
<select
:id="`${componentId}_available`"
v-model="availableSelected"
tabindex="2"
aria-label="available"
multiple
:style="selectStyle"
>
<option
v-for="element in items.inactive"
:key="JSON.stringify(element.name)"
:value="element.name"
@dblclick="() => handleDoubleClickToAddItem(element.name)"
<div v-if="items.inactive.length > 0">
<select
:id="`${componentId}_available`"
v-model="availableSelected"
tabindex="2"
aria-label="available"
multiple
:style="selectStyle"
>
{{ element.title }}
</option>
</select>
<option
v-for="element in items.inactive"
:key="JSON.stringify(element.name)"
:value="element.name"
@dblclick="() => handleDoubleClickToAddItem(element.name)"
>
{{ element.title }}
</option>
</select>
</div>

<div v-else :style="selectStyle" class="no-element-in-select">
{{ props.spec.i18n.no_elements_available }}
</div>
</td>
<td>
<div class="centered-container">
Expand All @@ -236,23 +243,28 @@ const handleDoubleClickToRemoveItem = (elementName: string) => {
</div>
</td>
<td>
<select
:id="`${componentId}_active`"
v-model="activeSelected"
tabindex="4"
aria-label="active"
multiple
:style="selectStyle"
>
<option
v-for="element in items.active"
:key="JSON.stringify(element.name)"
:value="element.name"
@dblclick="() => handleDoubleClickToRemoveItem(element.name)"
<div v-if="items.active.length > 0">
<select
:id="`${componentId}_active`"
v-model="activeSelected"
tabindex="4"
aria-label="active"
multiple
:style="selectStyle"
>
{{ element.title }}
</option>
</select>
<option
v-for="element in items.active"
:key="JSON.stringify(element.name)"
:value="element.name"
@dblclick="() => handleDoubleClickToRemoveItem(element.name)"
>
{{ element.title }}
</option>
</select>
</div>
<div v-else :style="selectStyle" class="no-element-in-select">
{{ props.spec.i18n.no_elements_selected }}
</div>
</td>
</tr>
</table>
Expand Down Expand Up @@ -347,6 +359,17 @@ const handleDoubleClickToRemoveItem = (elementName: string) => {
}
}

.no-element-in-select {
display: flex;
justify-content: center;
align-items: center;
background-color: var(--default-select-background-color);
height: 100%;
user-select: none;
opacity: 0.5;
border-radius: 3px;
}

/* custom scroll bar => should be removed or moved to globals*/
*::-webkit-scrollbar {
width: 8px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ export interface DualListChoiceI18N {
available_options: string;
selected_options: string;
selected: string;
no_elements_available: string;
no_elements_selected: string;
}
export interface TimeSpanI18N {
millisecond: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const spec: FormSpec.DualListChoice = {
remove: 'Remove',
available_options: 'Available options',
selected_options: 'Selected options',
selected: 'Selected'
selected: 'Selected',
no_elements_available: 'No elements available',
no_elements_selected: 'No elements selected'
},
validators: [],
show_toggle_all: false
Expand Down Expand Up @@ -70,9 +72,7 @@ describe('FormDualListChoice', () => {

const filterInactiveElements = screen.getByTestId('search-inactive')
await fireEvent.update(filterInactiveElements, 'Choice 1')
expect(
screen.getByRole<HTMLSelectElement>('listbox', { name: 'available' }).options.length
).equal(0)
expect(screen.getByText('No elements available')).toBeInTheDocument()
})

test('add all while filter on available options', async () => {
Expand Down Expand Up @@ -109,6 +109,8 @@ describe('FormDualListChoice', () => {
expect(
screen.getByRole<HTMLSelectElement>('listbox', { name: 'available' }).options.length
).equal(2)

expect(screen.getByText('No elements selected')).toBeInTheDocument()
})

test('add by double click on available item', async () => {
Expand Down
10 changes: 9 additions & 1 deletion packages/cmk-shared-typing/source/vue_formspec/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,12 @@
},
"selected": {
"type": "string"
},
"no_elements_available": {
"type": "string"
},
"no_elements_selected": {
"type": "string"
}
},
"required": [
Expand All @@ -415,7 +421,9 @@
"remove_all",
"available_options",
"selected_options",
"selected"
"selected",
"no_elements_available",
"no_elements_selected"
]
}
},
Expand Down

0 comments on commit dec2a8d

Please sign in to comment.