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
Fenn-CS committed Nov 10, 2023
1 parent 8feacd0 commit 360a372
Show file tree
Hide file tree
Showing 116 changed files with 239 additions and 240 deletions.
2 changes: 1 addition & 1 deletion core/css/server.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion core/css/server.css.map

Large diffs are not rendered by default.

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
6 changes: 3 additions & 3 deletions dist/7683-7683.js → dist/1436-1436.js

Large diffs are not rendered by default.

File renamed without changes.
1 change: 1 addition & 0 deletions dist/1436-1436.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions dist/2250-2250.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
2 changes: 1 addition & 1 deletion dist/3998-3998.js.map → dist/2250-2250.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions dist/2550-2550.js

Large diffs are not rendered by default.

22 changes: 0 additions & 22 deletions dist/9064-9064.js.LICENSE.txt → dist/2550-2550.js.LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,6 @@
*
*/

/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
Expand Down
1 change: 1 addition & 0 deletions dist/2550-2550.js.map

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions dist/3240-3240.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/3240-3240.js.map

This file was deleted.

3 changes: 0 additions & 3 deletions dist/3998-3998.js

This file was deleted.

4 changes: 2 additions & 2 deletions dist/4107-4107.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/4107-4107.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/6318-6318.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/6318-6318.js.map

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion dist/7683-7683.js.map

This file was deleted.

3 changes: 0 additions & 3 deletions dist/9064-9064.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/9064-9064.js.map

This file was deleted.

4 changes: 2 additions & 2 deletions dist/comments-comments-app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/comments-comments-app.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit 360a372

Please sign in to comment.