mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge branch 'master' into 5441-wrench-refactor-groupform-select-make-a-component
This commit is contained in:
commit
7732e2a890
@ -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()
|
||||||
|
|||||||
@ -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(/^([!@#&])/, '')
|
||||||
|
|||||||
@ -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(' ')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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*')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -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`),
|
||||||
|
|||||||
@ -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 }
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user