Fix full text search control behaviour (#838)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2022-01-19 16:05:40 +07:00 committed by GitHub
parent 0d8daf2fea
commit 22652d72a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 126 additions and 55 deletions

View File

@ -5,6 +5,7 @@
"Hours": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}",
"Days": "{days, plural, =0 {today} =1 {yesterday} other {# days ago}}",
"ShowMore": "Show more",
"ShowLess": "Show less"
"ShowLess": "Show less",
"Search": "Search"
}
}

View File

@ -15,6 +15,7 @@
<script lang="ts">
import type { Asset } from '@anticrm/platform'
import { createEventDispatcher } from 'svelte'
import type { AnySvelteComponent } from '../types'
import Icon from './Icon.svelte'
import IconClose from './icons/Close.svelte'
@ -33,13 +34,14 @@
focus = false
}
}
const dispatch = createEventDispatcher()
</script>
<div class="flex-between editbox" style={width ? 'width: ' + width : ''} on:click={() => textHTML.focus()}>
<div class="mr-2"><Icon {icon} size={'small'} /></div>
<input bind:this={textHTML} type="text" bind:value {placeholder} on:change/>
<input bind:this={textHTML} type="text" bind:value {placeholder} on:change on:input on:keydown/>
{#if value}
<div class="ml-2 btn" on:click={() => { textHTML.value = ''; textHTML.dispatchEvent(new Event('change')) }}>
<div class="ml-2 btn" on:click={() => { value = ''; dispatch('change', '') }}>
<Icon icon={IconClose} size={'x-small'} />
</div>
{/if}

View File

@ -0,0 +1,42 @@
<script lang="ts">
import { translate } from '@anticrm/platform'
import { createEventDispatcher } from 'svelte'
import ui from '../plugin'
import EditWithIcon from './EditWithIcon.svelte'
import IconSearch from './icons/Search.svelte'
export let value: string = ''
$: _search = value
const dispatch = createEventDispatcher()
let placeholder = ''
translate(ui.string.Search, {}).then((v) => {
placeholder = v
})
</script>
<EditWithIcon
icon={IconSearch}
placeholder={placeholder}
bind:value={_search}
on:change={() => {
if (_search === '') {
value = ''
dispatch('change', '')
}
}}
on:input={() => {
if (_search === '') {
value = ''
dispatch('change', '')
}
}}
on:keydown={(evt) => {
if (evt.key === 'Enter') {
value = _search
dispatch('change', _search)
}
}}
/>

View File

@ -53,6 +53,7 @@ export { default as Row } from './components/Row.svelte'
// export { default as CheckBoxWithLabel } from './components/CheckBoxWithLabel.svelte'
// export { default as CheckBoxList } from './components/CheckBoxList.svelte.txt'
export { default as EditWithIcon } from './components/EditWithIcon.svelte'
export { default as SearchEdit } from './components/SearchEdit.svelte'
export { default as Loading } from './components/Loading.svelte'
export { default as Spinner } from './components/Spinner.svelte'
export { default as Popup } from './components/Popup.svelte'

View File

@ -1,15 +1,15 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
@ -29,6 +29,7 @@ export default plugin(uiId, {
Hours: '' as IntlString,
Days: '' as IntlString,
ShowMore: '' as IntlString,
ShowLess: '' as IntlString
ShowLess: '' as IntlString,
Search: '' as IntlString
}
})
})

View File

@ -15,15 +15,20 @@
-->
<script lang="ts">
import { Doc, DocumentQuery } from '@anticrm/core'
import { getClient } from '@anticrm/presentation'
import { Button, EditWithIcon, Icon, IconAdd, IconSearch, Label, ScrollBox, showPopup } from '@anticrm/ui'
import { Button, Icon, IconAdd, Label, ScrollBox, SearchEdit, showPopup } from '@anticrm/ui'
import view, { Viewlet } from '@anticrm/view'
import { Table } from '@anticrm/view-resources'
import contact from '../plugin'
import CreateContact from './CreateContact.svelte'
let search = ''
$: resultQuery = search === '' ? { } : { $search: search }
let resultQuery: DocumentQuery<Doc> = {}
function updateResultQuery (search: string): void {
resultQuery = (search === '') ? { } : { $search: search }
}
const client = getClient()
const tableDescriptor = client.findOne<Viewlet>(view.class.Viewlet, { attachTo: contact.class.Contact, descriptor: view.viewlet.Table })
@ -42,7 +47,9 @@
</div>
</div>
<EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} on:change={() => { resultQuery = {} } } />
<SearchEdit bind:value={search} on:change={() => {
updateResultQuery(search)
}}/>
<Button icon={IconAdd} label={contact.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)}/>
</div>

View File

@ -14,13 +14,18 @@
// limitations under the License.
-->
<script lang="ts">
import { Button, EditWithIcon, Icon, IconSearch, Label, ScrollBox, showPopup } from '@anticrm/ui'
import HierarchyView from './HierarchyView.svelte'
import CreateCategory from './CreateCategory.svelte'
import { Doc, DocumentQuery } from '@anticrm/core'
import { Button, Icon, Label, ScrollBox, SearchEdit, showPopup } from '@anticrm/ui'
import inventory from '../plugin'
import CreateCategory from './CreateCategory.svelte'
import HierarchyView from './HierarchyView.svelte'
let search = ''
$: resultQuery = search === '' ? {} : { $search: search }
let resultQuery: DocumentQuery<Doc> = {}
function updateResultQuery (search: string): void {
resultQuery = (search === '') ? { } : { $search: search }
}
function showCreateDialog (ev: Event) {
showPopup(CreateCategory, { space: inventory.space.Category }, ev.target as HTMLElement)
@ -35,14 +40,9 @@
</div>
</div>
<EditWithIcon
icon={IconSearch}
placeholder={'Search'}
bind:value={search}
on:change={() => {
resultQuery = {}
}}
/>
<SearchEdit bind:value={search} on:change={() => {
updateResultQuery(search)
}}/>
<Button
label={inventory.string.CreateCategoryShort}
primary={true}

View File

@ -15,13 +15,17 @@
-->
<script lang="ts">
import { EditWithIcon, Icon, IconSearch, Label, ScrollBox } from '@anticrm/ui'
import { Doc, DocumentQuery } from '@anticrm/core'
import { Icon, Label, ScrollBox, SearchEdit } from '@anticrm/ui'
import { Table } from '@anticrm/view-resources'
import lead from '../plugin'
let search = ''
$: resultQuery = search === '' ? { } : { $search: search }
let resultQuery: DocumentQuery<Doc> = {}
function updateResultQuery (search: string): void {
resultQuery = (search === '') ? { } : { $search: search }
}
</script>
<div class="customers-header-container">
@ -32,7 +36,9 @@
</div>
</div>
<EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} on:change={() => { resultQuery = {} } } />
<SearchEdit bind:value={search} on:change={() => {
updateResultQuery(search)
}}/>
</div>
<div class="container">

View File

@ -15,18 +15,21 @@
-->
<script lang="ts">
import contact from '@anticrm/contact'
import { Doc, DocumentQuery } from '@anticrm/core'
import { getClient } from '@anticrm/presentation'
import { Button, EditWithIcon, Icon, IconSearch, Label, ScrollBox, showPopup } from '@anticrm/ui'
import { Button, Icon, Label, ScrollBox, SearchEdit, showPopup } from '@anticrm/ui'
import view, { Viewlet } from '@anticrm/view'
import { Table } from '@anticrm/view-resources'
import recruit from '../plugin'
import contact from '@anticrm/contact'
import view, { Viewlet } from '@anticrm/view'
import CreateCandidate from './CreateCandidate.svelte'
let search = ''
$: resultQuery = search === '' ? { } : { $search: search }
let resultQuery: DocumentQuery<Doc> = {}
function updateResultQuery (search: string): void {
resultQuery = (search === '') ? { } : { $search: search }
}
const client = getClient()
const tableDescriptor = client.findOne<Viewlet>(view.class.Viewlet, { attachTo: recruit.mixin.Candidate, descriptor: view.viewlet.Table })
@ -34,6 +37,7 @@
function showCreateDialog (ev: Event) {
showPopup(CreateCandidate, { space: recruit.space.CandidatesPublic }, ev.target as HTMLElement)
}
</script>
<div class="candidates-header-container">
@ -44,7 +48,9 @@
</div>
</div>
<EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} on:change={() => { resultQuery = {} } } />
<SearchEdit bind:value={search} on:change={() => {
updateResultQuery(search)
}}/>
<Button label={recruit.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)}/>
</div>

View File

@ -14,17 +14,15 @@
-->
<script lang="ts">
import core, { Class, Doc, WithLookup } from '@anticrm/core'
import type { Ref, Space } from '@anticrm/core'
import { getClient, createQuery } from '@anticrm/presentation'
import { Icon, Button, EditWithIcon, IconSearch, Tooltip } from '@anticrm/ui'
import core, { Class, Doc, WithLookup } from '@anticrm/core'
import { createQuery, getClient } from '@anticrm/presentation'
import type { AnyComponent } from '@anticrm/ui'
import { showPopup } from '@anticrm/ui'
import view, { Viewlet } from '@anticrm/view'
import { classIcon } from '../utils'
import { Button, Icon, SearchEdit, showPopup, Tooltip } from '@anticrm/ui'
import { Viewlet } from '@anticrm/view'
import { createEventDispatcher } from 'svelte'
import workbench from '../plugin'
import { classIcon } from '../utils'
import Header from './Header.svelte'
export let spaceId: Ref<Space> | undefined
@ -37,15 +35,24 @@
const client = getClient()
const query = createQuery()
let space: Space | undefined
const dispatch = createEventDispatcher()
const prevSpaceId = spaceId
$: query.query(core.class.Space, { _id: spaceId }, result => { space = result[0] })
function showCreateDialog(ev: Event) {
function showCreateDialog (ev: Event) {
showPopup(createItemDialog as AnyComponent, { space: spaceId }, ev.target as HTMLElement)
}
let selectedViewlet = 0
$: viewlet = viewlets[selectedViewlet]
$: if (prevSpaceId !== spaceId) {
search = ''
dispatch('search', '')
}
</script>
<div class="spaceheader-container">
@ -55,14 +62,16 @@
<div class="flex">
{#each viewlets as viewlet, i}
<Tooltip label={viewlet.$lookup?.descriptor?.label} direction={'top'}>
<div class="flex-center btn" class:selected={selectedViewlet === i} on:click={()=>{ selectedViewlet = i }}>
<div class="flex-center btn" class:selected={selectedViewlet === i} on:click={() => { selectedViewlet = i }}>
<Icon icon={viewlet.$lookup?.descriptor?.icon} size={'small'}/>
</div>
</Tooltip>
{/each}
</div>
{/if}
<EditWithIcon icon={IconSearch} placeholder={'Search'} bind:value={search} />
<SearchEdit bind:value={search} on:change={() => {
dispatch('search', search)
}}/>
{#if createItemDialog}
<Button label={workbench.string.Create} primary={true} size={'small'} on:click={(ev) => showCreateDialog(ev)}/>
{/if}

View File

@ -36,11 +36,13 @@
let viewlets: WithLookup<Viewlet>[] = []
async function update(attachTo?: Ref<Class<Doc>>, currentSpace?: Ref<Space>): Promise<void> {
async function update (attachTo?: Ref<Class<Doc>>, currentSpace?: Ref<Space>): Promise<void> {
if (attachTo) {
viewlets = await client.findAll(view.class.Viewlet, { attachTo }, { lookup: {
descriptor: core.class.Class
}})
viewlets = await client.findAll(view.class.Viewlet, { attachTo }, {
lookup: {
descriptor: core.class.Class
}
})
_class = attachTo
}
viewlet = viewlets[0]
@ -48,12 +50,6 @@
}
$: update(currentView?.class, currentSpace)
function resetSearch (_space: Ref<Space> | undefined): void {
search = ''
}
$: resetSearch(currentSpace)
</script>
<SpaceHeader spaceId={space} {_class} {viewlets} {createItemDialog} bind:search={search} bind:viewlet={viewlet} />