Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TSK-1370] Show selected filter values on top #3174

Merged
merged 9 commits into from
May 16, 2023
14 changes: 12 additions & 2 deletions common/config/rush/pnpm-lock.yaml

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

50 changes: 29 additions & 21 deletions plugins/contact-resources/src/components/ChannelFilter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@
-->
<script lang="ts">
import { ChannelProvider } from '@hcengineering/contact'
import { Class, Doc, Ref } from '@hcengineering/core'
import { Button, CheckBox, Icon, Label, resizeObserver } from '@hcengineering/ui'
import { Ref } from '@hcengineering/core'
import { CheckBox, Icon, Label, resizeObserver } from '@hcengineering/ui'
import { Filter } from '@hcengineering/view'
import { FilterQuery } from '@hcengineering/view-resources'
import view from '@hcengineering/view-resources/src/plugin'
import { createEventDispatcher } from 'svelte'
import contact from '../plugin'
import {
FILTER_DEBOUNCE_MS,
FilterQuery,
debounce,
filterDebounceOptions,
sortFilterValues
} from '@hcengineering/view-resources'
import { createEventDispatcher, onDestroy } from 'svelte'
import { channelProviders } from '../utils'
import contact from '../plugin'

export let _class: Ref<Class<Doc>>
export let filter: Filter
export let onChange: (e: Filter) => void
filter.onRemove = () => {
Expand All @@ -40,25 +44,40 @@
return false
}

const checkSelected = (element: ChannelProvider): void => {
function handleFilterToggle (element: ChannelProvider) {
if (isSelected(element, selected)) {
selected = selected.filter((p) => p !== element._id)
} else {
selected = [...selected, element._id]
}

updateFilter(filter, selected, level, onChange)
}

const updateFilter = debounce(
(filter: Filter, newValues: Ref<ChannelProvider>[], level: number, onChange: (e: Filter) => void) => {
filter.value = [...newValues]
// Replace last one with value with level
filter.props = { level }
onChange(filter)
},
FILTER_DEBOUNCE_MS,
filterDebounceOptions
)

const dispatch = createEventDispatcher()

onDestroy(() => updateFilter.flush())
</script>

<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
<div class="scroll">
<div class="box">
{#each $channelProviders as element}
{#each sortFilterValues($channelProviders, (v) => isSelected(v, selected)) as element}
<button
class="menu-item"
on:click={() => {
checkSelected(element)
handleFilterToggle(element)
}}
>
<div class="flex-between w-full">
Expand All @@ -76,15 +95,4 @@
{/each}
</div>
</div>
<Button
shape={'round'}
label={view.string.Apply}
on:click={async () => {
filter.value = [...selected]
// Replace last one with value with level
filter.props = { level }
onChange(filter)
dispatch('close')
}}
/>
</div>
34 changes: 25 additions & 9 deletions plugins/tags-resources/src/components/TagsFilter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@
showPopup
} from '@hcengineering/ui'
import { Filter } from '@hcengineering/view'
import { FilterQuery } from '@hcengineering/view-resources'
import { createEventDispatcher, onMount } from 'svelte'
import {
FILTER_DEBOUNCE_MS,
FilterQuery,
debounce,
filterDebounceOptions,
sortFilterValues
} from '@hcengineering/view-resources'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import tags from '../plugin'
import { tagLevel } from '../utils'
import WeightPopup from './WeightPopup.svelte'
Expand Down Expand Up @@ -100,7 +106,7 @@
return false
}

const checkSelected = (element: TagElement): void => {
function handleFilterToggle (element: TagElement): void {
if (isSelected(element)) {
selected = selected.filter((p) => p !== element._id)
} else {
Expand All @@ -109,19 +115,29 @@
objects = objects
categories = categories

filter.value = [...selected]
// Replace last one with value with level
filter.props = { level }
onChange(filter)
updateFilter(filter, selected, level, onChange)
}

const updateFilter = debounce(
(filter, newValues: Ref<TagElement>[], level: number, onChange: (e: Filter) => void) => {
filter.value = [...newValues]
// Replace last one with value with level
filter.props = { level }
onChange(filter)
},
FILTER_DEBOUNCE_MS,
filterDebounceOptions
)

$: schema = filter.key.attribute.schema ?? '0'

const dispatch = createEventDispatcher()
getValues(search)

$: tagLevelIcon = schema === '3' ? undefined : tagLevel[((level % 3) + 1) as 1 | 2 | 3]
$: tagLevelLabel = [tags.string.Initial, tags.string.Meaningfull, tags.string.Expert][Math.floor(level / 3)]

onDestroy(() => updateFilter.flush())
</script>

<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
Expand Down Expand Up @@ -185,11 +201,11 @@
{/if}
</button>
<div class="menu-group">
{#each values as element}
{#each sortFilterValues(values, isSelected) as element}
<button
class="menu-item"
on:click={() => {
checkSelected(element)
handleFilterToggle(element)
}}
>
<div class="flex-between w-full">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
// limitations under the License.
-->
<script lang="ts">
import { Class, Doc, DocumentQuery, FindResult, Ref, SortingOrder } from '@hcengineering/core'
import { DocumentQuery, FindResult, Ref, SortingOrder } from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import presentation, { getClient } from '@hcengineering/presentation'
import { Project, Sprint, SprintStatus } from '@hcengineering/tracker'
import ui, { deviceOptionsStore, Icon, Label, CheckBox, Loading, resizeObserver } from '@hcengineering/ui'
import { FILTER_DEBOUNCE_MS, debounce, filterDebounceOptions, sortFilterValues } from '@hcengineering/view-resources'
import view, { Filter } from '@hcengineering/view'
import { createEventDispatcher, onMount } from 'svelte'
import { createEventDispatcher, onMount, onDestroy } from 'svelte'
import tracker from '../../plugin'
import { sprintStatusAssets } from '../../types'
import SprintTitlePresenter from './SprintTitlePresenter.svelte'

export let _class: Ref<Class<Doc>>
export let space: Ref<Project> | undefined = undefined
export let filter: Filter
export let onChange: (e: Filter) => void
Expand Down Expand Up @@ -79,17 +79,26 @@
return values.has(value)
}

function toggle (value: Ref<Sprint> | undefined): void {
function handleFilterToggle (value: Ref<Sprint> | undefined): void {
if (isSelected(value, selectedValues)) {
selectedValues.delete(value)
} else {
selectedValues.add(value)
}
selectedValues = selectedValues
filter.value = Array.from(selectedValues)
onChange(filter)

updateFilter(filter, selectedValues, onChange)
}

const updateFilter = debounce(
(filter: Filter, newValues: Set<Ref<Sprint> | null | undefined>, onChange: (e: Filter) => void) => {
filter.value = Array.from(newValues)
onChange(filter)
},
FILTER_DEBOUNCE_MS,
filterDebounceOptions
)

function getStatusItem (status: SprintStatus, docs: Sprint[]): Sprint[] {
return docs.filter((p) => p.status === status)
}
Expand All @@ -102,6 +111,8 @@
onMount(() => {
if (searchInput && !$deviceOptionsStore.isMobile) searchInput.focus()
})
onDestroy(() => updateFilter.flush())

getValues(search)
</script>

Expand All @@ -125,7 +136,7 @@
<button
class="menu-item"
on:click={() => {
toggle(undefined)
handleFilterToggle(undefined)
}}
>
<div class="flex clear-mins">
Expand All @@ -145,11 +156,11 @@
<Label label={status.label} />
</div>
</div>
{#each items as doc}
{#each sortFilterValues(items, (v) => isSelected(v._id, selectedValues)) as doc}
<button
class="menu-item"
on:click={() => {
toggle(doc._id)
handleFilterToggle(doc._id)
}}
>
<div class="flex clear-mins">
Expand Down
6 changes: 4 additions & 2 deletions plugins/view-resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"eslint": "^8.26.0",
"prettier": "^2.7.1",
"svelte-check": "3.2.0",
"typescript": "^4.3.5"
"typescript": "^4.3.5",
"@types/lodash.debounce": "~4.0.7"
},
"dependencies": {
"svelte": "3.55.1",
Expand All @@ -45,7 +46,8 @@
"@hcengineering/notification": "^0.6.12",
"@hcengineering/presentation": "^0.6.2",
"@hcengineering/setting": "^0.6.7",
"@hcengineering/text-editor": "^0.6.0",
"fast-equals": "^2.0.3",
"@hcengineering/text-editor": "^0.6.0"
"lodash.debounce": "~4.0.8"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need it?

}
}
24 changes: 17 additions & 7 deletions plugins/view-resources/src/components/filter/ObjectFilter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
resizeObserver
} from '@hcengineering/ui'
import { Filter } from '@hcengineering/view'
import { createEventDispatcher, onMount } from 'svelte'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import view from '../../plugin'
import { buildConfigLookup, getPresenter } from '../../utils'
import { FILTER_DEBOUNCE_MS, filterDebounceOptions, sortFilterValues } from '../../filter'
import { buildConfigLookup, debounce, getPresenter } from '../../utils'
import FilterRemovedNotification from './FilterRemovedNotification.svelte'

export let filter: Filter
Expand Down Expand Up @@ -129,7 +130,7 @@
return values.includes(value?._id ?? value)
}

function toggle (value: Doc | undefined | null): void {
function handleFilterToggle (value: any): void {
if (isSelected(value, filter.value)) {
filter.value = filter.value.filter((p) => (value ? p !== value._id : p != null))
} else {
Expand All @@ -140,9 +141,15 @@
}
}

onChange(filter)
updateFilter(filter, onChange)
}

const updateFilter = debounce(
(filter: Filter, onChange: (e: Filter) => void) => onChange(filter),
FILTER_DEBOUNCE_MS,
filterDebounceOptions
)

let search: string = ''
let phTraslate: string = ''
let searchInput: HTMLInputElement
Expand All @@ -153,6 +160,7 @@
onMount(() => {
if (searchInput && !$deviceOptionsStore.isMobile) searchInput.focus()
})
onDestroy(() => updateFilter.flush())

const dispatch = createEventDispatcher()
$: if (targetClass) getValues(search)
Expand Down Expand Up @@ -183,11 +191,11 @@
{#if objectsPromise}
<Loading />
{:else}
{#each values as value, i}
{#each sortFilterValues(values, (v) => isSelected(v, filter.value)) as value}
<button
class="menu-item no-focus"
on:click={() => {
toggle(value)
handleFilterToggle(value)
}}
>
<div class="flex-between w-full">
Expand All @@ -198,7 +206,9 @@
{/if}
</div>
{#if value}
<svelte:component this={attribute.presenter} {value} {...attribute.props} disabled oneLine />
{#key value._id}
<svelte:component this={attribute.presenter} {value} {...attribute.props} disabled oneLine />
{/key}
{:else}
<Label label={ui.string.NotSelected} />
{/if}
Expand Down