Merge branch 'master' into 5441-wrench-refactor-groupform-select-make-a-component

This commit is contained in:
mahula 2023-04-25 15:20:07 +02:00 committed by GitHub
commit 7732e2a890
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 45 deletions

View File

@ -310,6 +310,7 @@ export default {
` `
MATCH (user:User {id: $userId}) WHERE user.role = 'admin' MATCH (user:User {id: $userId}) WHERE user.role = 'admin'
MATCH (post:Post {id: $params.id}) MATCH (post:Post {id: $params.id})
WHERE NOT((post)-[:IN]->(:Group))
MERGE (user)-[pinned:PINNED {createdAt: toString(datetime())}]->(post) MERGE (user)-[pinned:PINNED {createdAt: toString(datetime())}]->(post)
SET post.pinned = true SET post.pinned = true
RETURN post, pinned.createdAt as pinnedAt RETURN post, pinned.createdAt as pinnedAt
@ -322,10 +323,12 @@ export default {
})) }))
}) })
const [transactionResult] = await writeTxResultPromise const [transactionResult] = await writeTxResultPromise
const { pinnedPost, pinnedAt } = transactionResult if (transactionResult) {
pinnedPostWithNestedAttributes = { const { pinnedPost, pinnedAt } = transactionResult
...pinnedPost, pinnedPostWithNestedAttributes = {
pinnedAt, ...pinnedPost,
pinnedAt,
}
} }
} finally { } finally {
session.close() session.close()

View File

@ -223,8 +223,7 @@ export default {
}, },
searchResults: async (_parent, args, context, _resolveInfo) => { searchResults: async (_parent, args, context, _resolveInfo) => {
const { query, limit } = args const { query, limit } = args
let userId = null const userId = context.user?.id || null
if (context.user) userId = context.user.id
const searchType = query.replace(/^([!@#&]?).*$/, '$1') const searchType = query.replace(/^([!@#&]?).*$/, '$1')
const searchString = query.replace(/^([!@#&])/, '') const searchString = query.replace(/^([!@#&])/, '')

View File

@ -33,7 +33,7 @@ const matchSomeWordsExactly = (str, boost = 2) => {
const matchBeginningOfWords = (str) => { const matchBeginningOfWords = (str) => {
return str return str
.split(' ') .split(' ')
.filter((s) => s.length > 3) .filter((s) => s.length >= 2)
.map((s) => s + '*') .map((s) => s + '*')
.join(' ') .join(' ')
} }

View File

@ -37,7 +37,7 @@ describe('queryString', () => {
describe('globbing for longer words', () => { describe('globbing for longer words', () => {
it('globs words with more than three characters', () => { it('globs words with more than three characters', () => {
expect(queryString('a couple of words')).toContain('couple* words*') expect(queryString('a couple of words')).toContain('couple* of* words*')
}) })
}) })
}) })

View File

@ -80,7 +80,7 @@ export default {
}) })
} }
if (this.isAdmin) { if (this.isAdmin && !this.resource.group) {
if (!this.resource.pinnedBy) { if (!this.resource.pinnedBy) {
routes.push({ routes.push({
label: this.$t(`post.menu.pin`), label: this.$t(`post.menu.pin`),

View File

@ -63,13 +63,6 @@ describe('SearchableInput.vue', () => {
expect(select.element.value).toBe('abcd') expect(select.element.value).toBe('abcd')
}) })
it('calls onDelete when the delete key is pressed', () => {
const spy = jest.spyOn(wrapper.vm, 'onDelete')
select.trigger('input')
select.trigger('keyup.delete')
expect(spy).toHaveBeenCalledTimes(1)
})
describe('navigating to resource', () => { describe('navigating to resource', () => {
beforeEach(() => { beforeEach(() => {
propsData = { options: searchResults } propsData = { options: searchResults }

View File

@ -1,9 +1,10 @@
<template> <template>
<div class="searchable-input" aria-label="search" role="search"> <div class="searchable-input" aria-label="search" role="search">
<ds-select <ds-select
ref="select"
type="search" type="search"
icon="search" icon="search"
v-model="searchValue" v-model="value"
:id="id" :id="id"
label-prop="id" label-prop="id"
:icon-right="null" :icon-right="null"
@ -11,12 +12,11 @@
:loading="loading" :loading="loading"
:filter="(item) => item" :filter="(item) => item"
:no-options-available="emptyText" :no-options-available="emptyText"
:auto-reset-search="!searchValue" :auto-reset-search="!value"
:placeholder="$t('search.placeholder')" :placeholder="$t('search.placeholder')"
@focus.capture.native="onFocus" @focus.capture.native="onFocus"
@input.native="handleInput" @input.native="onInput"
@keyup.enter.native="onEnter" @keyup.enter.native="onEnter"
@keyup.delete.native="onDelete"
@keyup.esc.native="clear" @keyup.esc.native="clear"
@blur.capture.native="onBlur" @blur.capture.native="onBlur"
@input.exact="onSelect" @input.exact="onSelect"
@ -77,23 +77,29 @@ export default {
}, },
data() { data() {
return { return {
searchValue: '',
value: '', value: '',
unprocessedSearchInput: '',
searchProcess: null, searchProcess: null,
previousSearchTerm: '',
delay: 300, delay: 300,
} }
}, },
computed: { computed: {
emptyText() { emptyText() {
return this.isActive && !this.loading ? this.$t('search.failed') : this.$t('search.hint') return !this.loading && this.isSearchable()
? this.$t('search.failed')
: this.$t('search.hint')
}, },
isActive() { isActive() {
return !isEmpty(this.previousSearchTerm) return !isEmpty(this.value)
}, },
}, },
methods: { methods: {
isSearchable() {
return (
!isEmpty(this.value) &&
typeof this.value === 'string' &&
this.value.replace(/\s+/g, '').length >= 3
)
},
isFirstOfType(option) { isFirstOfType(option) {
return ( return (
this.options.findIndex((o) => o === option) === this.options.findIndex((o) => o === option) ===
@ -103,49 +109,36 @@ export default {
onFocus(event) { onFocus(event) {
clearTimeout(this.searchProcess) clearTimeout(this.searchProcess)
}, },
handleInput(event) { onInput(event) {
clearTimeout(this.searchProcess) clearTimeout(this.searchProcess)
this.value = event.target ? event.target.value.replace(/\s+/g, ' ').trim() : '' this.value = event.target ? event.target.value.replace(/\s+/g, ' ').trim() : ''
this.unprocessedSearchInput = this.value if (!this.isSearchable()) {
if (isEmpty(this.value) || this.value.replace(/\s+/g, '').length < 3) { this.$emit('clearSearch')
return return
} }
this.searchProcess = setTimeout(() => { this.searchProcess = setTimeout(() => {
this.previousSearchTerm = this.value
this.$emit('query', this.value) this.$emit('query', this.value)
}, this.delay) }, this.delay)
}, },
onEnter(event) { onEnter(event) {
this.$router.push({ this.$router.push({
path: '/search/search-results', path: '/search/search-results',
query: { search: this.unprocessedSearchInput }, query: { search: this.value },
}) })
this.$emit('clearSearch') this.$refs.select.close()
},
onDelete(event) {
clearTimeout(this.searchProcess)
const value = event.target ? event.target.value.trim() : ''
if (isEmpty(value)) {
this.clear()
} else {
this.handleInput(event)
}
}, },
clear() { clear() {
this.unprocessedSearchInput = '' this.value = ''
this.previousSearchTerm = ''
this.searchValue = ''
this.$emit('clearSearch') this.$emit('clearSearch')
clearTimeout(this.searchProcess) clearTimeout(this.searchProcess)
}, },
onBlur(event) { onBlur(event) {
this.searchValue = this.previousSearchTerm
clearTimeout(this.searchProcess) clearTimeout(this.searchProcess)
}, },
onSelect(item) { onSelect(item) {
this.goToResource(item) this.goToResource(item)
this.$nextTick(() => { this.$nextTick(() => {
this.searchValue = this.previousSearchTerm this.value = this.$refs.select.$data.searchString
}) })
}, },
getRouteName(item) { getRouteName(item) {