Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>tags/v20.0.0RC1
</template> | </template> | ||||
<script> | <script> | ||||
import userRow from './UserList/UserRow' | |||||
import { Multiselect, Actions, ActionButton } from '@nextcloud/vue' | |||||
import { subscribe, unsubscribe } from '@nextcloud/event-bus' | |||||
import InfiniteLoading from 'vue-infinite-loading' | import InfiniteLoading from 'vue-infinite-loading' | ||||
import Vue from 'vue' | import Vue from 'vue' | ||||
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect' | |||||
import Actions from '@nextcloud/vue/dist/Components/Actions' | |||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' | |||||
import userRow from './UserList/UserRow' | |||||
const unlimitedQuota = { | const unlimitedQuota = { | ||||
id: 'none', | id: 'none', | ||||
label: t('settings', 'Unlimited'), | label: t('settings', 'Unlimited'), | ||||
} | } | ||||
}, | }, | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
if (!this.settings.canChangePassword) { | if (!this.settings.canChangePassword) { | ||||
OC.Notification.showTemporary(t('settings', 'Password change is disabled because the master key is disabled')) | OC.Notification.showTemporary(t('settings', 'Password change is disabled because the master key is disabled')) | ||||
/** | /** | ||||
* Register search | * Register search | ||||
*/ | */ | ||||
this.userSearch = new OCA.Search(this.search, this.resetSearch) | |||||
subscribe('nextcloud:unified-search:search', this.search) | |||||
subscribe('nextcloud:unified-search:reset', this.resetSearch) | |||||
/** | /** | ||||
* If disabled group but empty, redirect | * If disabled group but empty, redirect | ||||
*/ | */ | ||||
this.redirectIfDisabled() | this.redirectIfDisabled() | ||||
}, | }, | ||||
beforeDestroy() { | |||||
unsubscribe('nextcloud:unified-search:search', this.search) | |||||
unsubscribe('nextcloud:unified-search:reset', this.resetSearch) | |||||
}, | |||||
methods: { | methods: { | ||||
onScroll(event) { | onScroll(event) { | ||||
this.scrolled = event.target.scrollTo > 0 | this.scrolled = event.target.scrollTo > 0 | ||||
}, | }, | ||||
/* SEARCH */ | /* SEARCH */ | ||||
search(query) { | |||||
search({ query }) { | |||||
this.searchQuery = query | this.searchQuery = query | ||||
this.$store.commit('resetUsers') | this.$store.commit('resetUsers') | ||||
this.$refs.infiniteLoading.stateChanger.reset() | this.$refs.infiniteLoading.stateChanger.reset() | ||||
}, | }, | ||||
resetSearch() { | resetSearch() { | ||||
this.search('') | |||||
this.search({ query: '' }) | |||||
}, | }, | ||||
resetForm() { | resetForm() { |
</template> | </template> | ||||
<script> | <script> | ||||
import { subscribe, unsubscribe } from '@nextcloud/event-bus' | |||||
import Vue from 'vue' | |||||
import VueLocalStorage from 'vue-localstorage' | |||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent' | import AppContent from '@nextcloud/vue/dist/Components/AppContent' | ||||
import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation' | import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation' | ||||
import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter' | import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter' | ||||
import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar' | import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar' | ||||
import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab' | import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab' | ||||
import Content from '@nextcloud/vue/dist/Components/Content' | import Content from '@nextcloud/vue/dist/Components/Content' | ||||
import Vue from 'vue' | |||||
import VueLocalStorage from 'vue-localstorage' | |||||
import AppList from '../components/AppList' | import AppList from '../components/AppList' | ||||
import AppDetails from '../components/AppDetails' | import AppDetails from '../components/AppDetails' | ||||
}, | }, | ||||
watch: { | watch: { | ||||
category(val, old) { | |||||
this.setSearch('') | |||||
category() { | |||||
this.searchQuery = '' | |||||
}, | }, | ||||
app() { | app() { | ||||
this.$store.dispatch('getGroups', { offset: 0, limit: 5 }) | this.$store.dispatch('getGroups', { offset: 0, limit: 5 }) | ||||
this.$store.commit('setUpdateCount', this.$store.getters.getServerData.updateCount) | this.$store.commit('setUpdateCount', this.$store.getters.getServerData.updateCount) | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
/** | |||||
* Register search | |||||
*/ | |||||
this.appSearch = new OCA.Search(this.setSearch, this.resetSearch) | |||||
subscribe('nextcloud:unified-search:search', this.setSearch) | |||||
subscribe('nextcloud:unified-search:reset', this.resetSearch) | |||||
}, | |||||
beforeDestroy() { | |||||
unsubscribe('nextcloud:unified-search:search', this.setSearch) | |||||
unsubscribe('nextcloud:unified-search:reset', this.resetSearch) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
setSearch(query) { | |||||
setSearch({ query }) { | |||||
this.searchQuery = query | this.searchQuery = query | ||||
}, | }, | ||||
resetSearch() { | resetSearch() { | ||||
this.setSearch('') | |||||
this.searchQuery = '' | |||||
}, | }, | ||||
hideAppDetails() { | hideAppDetails() { | ||||
this.$router.push({ | this.$router.push({ | ||||
name: 'apps-category', | name: 'apps-category', |
<script> | <script> | ||||
import { directive as ClickOutside } from 'v-click-outside' | import { directive as ClickOutside } from 'v-click-outside' | ||||
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus' | |||||
import excludeClickOutsideClasses from '@nextcloud/vue/dist/Mixins/excludeClickOutsideClasses' | import excludeClickOutsideClasses from '@nextcloud/vue/dist/Mixins/excludeClickOutsideClasses' | ||||
export default { | export default { | ||||
mounted() { | mounted() { | ||||
document.addEventListener('keydown', this.onKeyDown) | document.addEventListener('keydown', this.onKeyDown) | ||||
}, | }, | ||||
beforeMount() { | |||||
subscribe(`header-menu-${this.id}-close`, this.closeMenu) | |||||
subscribe(`header-menu-${this.id}-open`, this.openMenu) | |||||
}, | |||||
beforeDestroy() { | beforeDestroy() { | ||||
unsubscribe(`header-menu-${this.id}-close`, this.closeMenu) | |||||
unsubscribe(`header-menu-${this.id}-open`, this.openMenu) | |||||
document.removeEventListener('keydown', this.onKeyDown) | |||||
}, | }, | ||||
methods: { | methods: { | ||||
this.opened = false | this.opened = false | ||||
this.$emit('close') | this.$emit('close') | ||||
this.$emit('update:open', false) | this.$emit('update:open', false) | ||||
emit(`header-menu-${this.id}-close`) | |||||
}, | }, | ||||
/** | /** | ||||
this.opened = true | this.opened = true | ||||
this.$emit('open') | this.$emit('open') | ||||
this.$emit('update:open', true) | this.$emit('update:open', true) | ||||
emit(`header-menu-${this.id}-open`) | |||||
}, | }, | ||||
onKeyDown(event) { | onKeyDown(event) { | ||||
// If opened and escape pressed, close | // If opened and escape pressed, close | ||||
if (event.key === 'Escape' && this.opened) { | if (event.key === 'Escape' && this.opened) { | ||||
event.preventDefault() | event.preventDefault() | ||||
this.closeMenu() | |||||
/** user cancelled the menu by pressing escape */ | |||||
this.$emit('cancel') | |||||
/** we do NOT fire a close event to differentiate cancel and close */ | |||||
this.opened = false | |||||
this.$emit('update:open', false) | |||||
} | } | ||||
}, | }, | ||||
}, | }, |
type="search" | type="search" | ||||
:placeholder="t('core', 'Search {types} …', { types: typesNames.join(', ').toLowerCase() })" | :placeholder="t('core', 'Search {types} …', { types: typesNames.join(', ').toLowerCase() })" | ||||
@input="onInputDebounced" | @input="onInputDebounced" | ||||
@keypress.enter.prevent.stop="onInputEnter"> | |||||
@keypress.enter.prevent.stop="onInputEnter" | |||||
@search="onSearch"> | |||||
<!-- Search filters --> | <!-- Search filters --> | ||||
<Actions v-if="availableFilters.length > 1" class="unified-search__filters" placement="bottom"> | <Actions v-if="availableFilters.length > 1" class="unified-search__filters" placement="bottom"> | ||||
<ActionButton v-for="type in availableFilters" | <ActionButton v-for="type in availableFilters" | ||||
this.types = await getTypes() | this.types = await getTypes() | ||||
}, | }, | ||||
onClose() { | onClose() { | ||||
this.resetState() | |||||
this.query = '' | |||||
emit('nextcloud:unified-search:close') | emit('nextcloud:unified-search:close') | ||||
}, | }, | ||||
/** | |||||
* Reset the search state | |||||
*/ | |||||
resetSearch() { | |||||
emit('nextcloud:unified-search:reset') | |||||
this.query = '' | |||||
this.resetState() | |||||
}, | |||||
resetState() { | resetState() { | ||||
this.cursors = {} | this.cursors = {} | ||||
this.limits = {} | this.limits = {} | ||||
}) | }) | ||||
}, | }, | ||||
/** | |||||
* Watch the search event on the input | |||||
* Used to detect the reset button press | |||||
* @param {Event} event the search event | |||||
*/ | |||||
onSearch(event) { | |||||
// If value is empty, the reset button has been pressed | |||||
if (event.target.value === '') { | |||||
this.resetSearch() | |||||
} | |||||
}, | |||||
/** | /** | ||||
* If we have results already, open first one | * If we have results already, open first one | ||||
* If not, trigger the search again | * If not, trigger the search again |