Skip to content

Commit

Permalink
Use new SearchableList component for people filter
Browse files Browse the repository at this point in the history
This commit migrates away from NcSelect which has a couple of
accesibility and display problems currently, hence a new component
`SearchableList` is now used.

Signed-off-by: fenn-cs <fenn25.fn@gmail.com>
  • Loading branch information
nfebe committed Nov 10, 2023
1 parent 8feacd0 commit 4f4cec2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 59 deletions.
1 change: 0 additions & 1 deletion core/src/components/GlobalSearch/SearchFilterChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export default {
display: flex;
align-items: center;
padding-right: 5px;
filter: grayscale(100%) invert(100%);
img {
width: 20px;
Expand Down
24 changes: 16 additions & 8 deletions core/src/components/GlobalSearch/SearchableList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
-->

<template>
<NcPopover>
<NcPopover :shown="opened">
<template #trigger>
<slot name="trigger" />
</template>
Expand All @@ -35,17 +35,17 @@
</NcTextField>
<ul v-if="filteredList.length > 0" class="searchable-list__list">
<li v-for="element in filteredList"
:key="element"
:title="element"
:key="element.id"
:title="element.displayName"
role="button">
<NcButton alignment="start"
type="tertiary"
:wide="true"
@click="$emit(element)">
@click="itemSelected(element)">
<template #icon>
<NcAvatar :display-name="element" :hide-favorite="false" />
<NcAvatar :user="element.user" :show-user-status="false" :hide-favorite="false" />
</template>
{{ element }}
{{ element.displayName }}
</NcButton>
</li>
</ul>
Expand Down Expand Up @@ -98,6 +98,7 @@ export default {

data() {
return {
opened: false,
error: false,
searchTerm: '',
}
Expand All @@ -106,7 +107,10 @@ export default {
computed: {
filteredList() {
return this.searchList.filter((element) => {
return element.toLowerCase().includes(this.searchTerm.toLowerCase())
if (!this.searchTerm.toLowerCase().length) {
return true
}
return ['displayName'].some(prop => element[prop].toLowerCase().includes(this.searchTerm.toLowerCase()))
})
},
},
Expand All @@ -115,12 +119,16 @@ export default {
clearSearch() {
this.searchTerm = ''
},
itemSelected(element) {
this.$emit('item-selected', element)
this.clearSearch()
this.opened = false
},
},
}
</script>

<style lang="scss" scoped>

.searchable-list {
&__wrapper {
padding: calc(var(--default-grid-baseline) * 3);
Expand Down
97 changes: 47 additions & 50 deletions core/src/views/GlobalSearchModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,19 @@
{{ t('core', 'Custom date range') }}
</NcActionButton>
</NcActions>
<NcSelect v-bind="peopleSeclectProps"
v-model="peopleSeclectProps.value"
@search="filterContacts"
@option:selected="applyPersonFilter" />
<SearchableList :label-text="t('core', 'Search people')"
:search-list="userContacts"
:empty-content-text="t('core', 'Not found')"
@item-selected="applyPersonFilter">
<template #trigger>
<NcButton>
<template #icon>
<AccountGroup :size="20" />
</template>
{{ t('core', 'People') }}
</NcButton>
</template>
</SearchableList>
</div>
<div class="global-search-modal__filters-applied">
<FilterChip v-for="filter in filters"
Expand All @@ -64,7 +73,10 @@
:pretext="''"
@delete="removeFilter(filter)">
<template #icon>
<AccountIcon v-if="filter.type === 'person'" />
<NcAvatar v-if="filter.type === 'person'"
:user="filter.user"
:show-user-status="false"
:hide-favorite="false" />
<CalendarRangeIcon v-else-if="filter.type === 'date'" />
<img v-else :src="filter.icon" alt="">
</template>
Expand Down Expand Up @@ -130,44 +142,46 @@

<script>
import ArrowRight from 'vue-material-design-icons/ArrowRight.vue'
import AccountIcon from 'vue-material-design-icons/AccountCircle.vue'
import AccountGroup from 'vue-material-design-icons/AccountGroup.vue'
import CalendarRangeIcon from 'vue-material-design-icons/CalendarRange.vue'
import CustomDateRangeModal from '../components/GlobalSearch/CustomDateRangeModal.vue'
import DotsHorizontalIcon from 'vue-material-design-icons/DotsHorizontal.vue'
import FilterChip from '../components/GlobalSearch/SearchFilterChip.vue'
import ListBox from 'vue-material-design-icons/ListBox.vue'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import MagnifyIcon from 'vue-material-design-icons/Magnify.vue'
import SearchableList from '../components/GlobalSearch/SearchableList.vue'
import debounce from 'debounce'
import { getProviders, search as globalSearch, getContacts } from '../services/GlobalSearchService.js'
export default {
name: 'GlobalSearchModal',
components: {
AccountIcon,
ArrowRight,
AccountGroup,
CalendarRangeIcon,
CustomDateRangeModal,
DotsHorizontalIcon,
FilterChip,
ListBox,
NcActions,
NcActionButton,
NcAvatar,
NcButton,
NcEmptyContent,
NcModal,
NcListItem,
NcSelect,
NcInputField,
MagnifyIcon,
SearchableList,
},
props: {
isVisible: {
Expand All @@ -182,7 +196,7 @@ export default {
dateActionMenuIsOpen: false,
providerResultLimit: 5,
dateFilter: { id: 'date', type: 'date', text: '', startFrom: null, endAt: null },
personFilter: { id: 'person', type: 'person', text: '' },
personFilter: { id: 'person', type: 'person', name: '' },
dateFilterIsApplied: false,
personFilterIsApplied: false,
filteredProviders: [],
Expand All @@ -198,17 +212,9 @@ export default {
},
computed: {
peopleSeclectProps: {
userContacts: {
get() {
return {
// inputId: getRandomId(),
userSelect: true,
label: t('core', 'People filter'),
placeholder: t('core', 'Search people'),
placement: 'top',
options: this.contacts,
value: null,
}
return this.contacts
},
},
Expand Down Expand Up @@ -258,7 +264,7 @@ export default {
}
}
if (this.providerResultLimit > 5) {
if (this.providerResultLimit > 5) {
params.limit = this.providerResultLimit
}
Expand Down Expand Up @@ -345,7 +351,18 @@ export default {
},
applyPersonFilter(person) {
this.personFilterIsApplied = true
this.personFilter.id = person.id
const existingPersonFilter = this.filters.findIndex(filter => filter.id === person.id)
if (existingPersonFilter === -1) {
this.personFilter.id = person.id
this.personFilter.user = person.user
this.personFilter.name = person.displayName
this.filters.push(this.personFilter)
} else {
this.filters[existingPersonFilter].id = person.id
this.filters[existingPersonFilter].user = person.user
this.filters[existingPersonFilter].name = person.displayName
}
this.debouncedFind(this.searchQuery)
console.debug('Person filter applied', person)
},
Expand Down Expand Up @@ -504,39 +521,19 @@ $margin: 10px;
&__filters {
display: flex;
padding-top: 5px;
align-items: center;
justify-content: space-between;
/* Overwrite NcSelect styles */
::v-deep div.v-select {
min-width: 0; // reset NcSelect min width
div.vs__dropdown-toggle {
height: 44px; // Overwrite height of NcSelect component to match button
}
>*:not(:last-child) {
// flex: 1;
margin-right: 0.5m;
}
::v-deep>* {
min-width: auto;
/* Reset hard set min widths */
min-height: 0;
/* Reset any min heights */
display: flex;
align-items: center;
flex: 1;
>* {
flex: 1;
min-width: auto;
/* Reset hard set min widths */
min-height: 0;
>* {
button {
min-width: 160px;
}
}
::v-deep>*:not(:last-child) {
margin: 0 2px;
}
}
&__filters-applied {
Expand Down Expand Up @@ -641,9 +638,9 @@ div.v-popper__wrapper {
img {
width: 24px;
margin: 0 4px;
// filter: invert(100%) grayscale(1) contrast(100) brightness(1);
filter: grayscale(100%);
filter: var(--background-invert-if-bright);
}
}
}
}
Expand Down

0 comments on commit 4f4cec2

Please sign in to comment.