Files
huly-platform/plugins/drive-resources/src/components/GridView.svelte
T
2024-06-18 16:31:08 +07:00

98 lines
2.9 KiB
Svelte

<!--
// Copyright © 2024 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.
-->
<script lang="ts">
import type { Class, Doc, DocumentQuery, FindOptions, Ref, WithLookup } from '@hcengineering/core'
import { type Resource } from '@hcengineering/drive'
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
import { BuildModelKey, ViewOptions } from '@hcengineering/view'
import { ListSelectionProvider, SelectDirection, buildConfigLookup, focusStore } from '@hcengineering/view-resources'
import GridItem from './GridItem.svelte'
export let _class: Ref<Class<Resource>>
export let query: DocumentQuery<Resource>
export let config: Array<BuildModelKey | string>
export let options: FindOptions<Resource> | undefined = undefined
export let viewOptions: ViewOptions
const client = getClient()
const hierarchy = client.getHierarchy()
const q = createQuery()
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
if (dir === 'vertical') {
let pos = objects.findIndex((p) => p._id === of?._id)
pos += offset
if (pos < 0) {
pos = 0
}
if (pos >= objects.length) {
pos = objects.length - 1
}
listProvider.updateFocus(objects[pos])
}
})
let objects: WithLookup<Resource>[] = []
$: orderBy = viewOptions.orderBy
$: lookup = buildConfigLookup(hierarchy, _class, config, options?.lookup)
$: q.query(
_class,
query,
(result) => {
objects = result
},
{
...options,
sort: {
...(options != null ? options.sort : {}),
...(orderBy != null ? { [orderBy[0]]: orderBy[1] } : {})
},
lookup
}
)
$: listProvider.update(objects)
$: selection = listProvider.current($focusStore)
</script>
<ActionContext context={{ mode: 'browser' }} />
<div class="grid-container">
{#each objects as object, i}
{@const selected = selection === i}
<div class="grid-cell">
<GridItem
{object}
{selected}
on:obj-focus={(evt) => {
listProvider.updateFocus(evt.detail)
}}
/>
</div>
{/each}
</div>
<style lang="scss">
.grid-container {
display: grid;
margin: 0.5rem 1rem;
padding-bottom: 0.5rem;
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
gap: 1rem;
}
</style>