mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-07 07:56:34 +00:00
183 lines
6.1 KiB
Svelte
183 lines
6.1 KiB
Svelte
<!--
|
|
// Copyright © 2022 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 { Attachment } from '@hcengineering/attachment'
|
|
import contact, { Person, PersonAccount } from '@hcengineering/contact'
|
|
import core, { Class, getCurrentAccount, Ref, Space } from '@hcengineering/core'
|
|
import { getClient } from '@hcengineering/presentation'
|
|
import { Label, Loading, navigate, TabList, SearchEdit, getLocation } from '@hcengineering/ui'
|
|
import view from '@hcengineering/view'
|
|
import { dateFileBrowserFilters, FileBrowserSortMode, fileTypeFileBrowserFilters, sortModeToOptionObject } from '..'
|
|
import attachment from '../plugin'
|
|
import AttachmentsGalleryView from './AttachmentsGalleryView.svelte'
|
|
import AttachmentsListView from './AttachmentsListView.svelte'
|
|
import FileBrowserFilters from './FileBrowserFilters.svelte'
|
|
import FileBrowserSortMenu from './FileBrowserSortMenu.svelte'
|
|
|
|
export let withHeader: boolean = true
|
|
|
|
const client = getClient()
|
|
const loc = getLocation()
|
|
const spaceId: Ref<Space> | undefined = loc.query?.spaceId as Ref<Space> | undefined
|
|
|
|
$: if (spaceId !== undefined) {
|
|
const loc = getLocation()
|
|
loc.query = undefined
|
|
navigate(loc)
|
|
}
|
|
export let requestedSpaceClasses: Ref<Class<Space>>[] = []
|
|
const currentUser = getCurrentAccount() as PersonAccount
|
|
let selectedParticipants: Ref<Person>[] = [currentUser.person]
|
|
let selectedSpaces: Ref<Space>[] = []
|
|
export let search: string = ''
|
|
let isLoading = false
|
|
|
|
let attachments: Attachment[] = []
|
|
|
|
let selectedSort: FileBrowserSortMode = FileBrowserSortMode.NewestFile
|
|
let selectedDateId = 'dateAny'
|
|
let selectedFileTypeId = 'typeAny'
|
|
let isListDisplayMode = true
|
|
|
|
$: fetch(search, selectedSort, selectedFileTypeId, selectedDateId, selectedParticipants, selectedSpaces)
|
|
|
|
async function fetch (
|
|
searchQuery_: string,
|
|
selectedSort_: FileBrowserSortMode,
|
|
selectedFileTypeId_: string,
|
|
selectedDateId_: string,
|
|
selectedParticipants_: Ref<Person>[],
|
|
selectedSpaces_: Ref<Space>[]
|
|
) {
|
|
isLoading = true
|
|
|
|
const nameQuery = searchQuery_ ? { name: { $like: '%' + searchQuery_ + '%' } } : {}
|
|
|
|
const accounts = await client.findAll(contact.class.PersonAccount, { person: { $in: selectedParticipants_ } })
|
|
const senderQuery = accounts.length ? { modifiedBy: { $in: accounts.map((a) => a._id) } } : {}
|
|
|
|
let spaceQuery: { space: any }
|
|
if (selectedSpaces_.length > 0) {
|
|
spaceQuery = { space: { $in: selectedSpaces_ } }
|
|
} else {
|
|
// nothing is selected in space filter - show all available attachments (except for the archived channels)
|
|
const allSpaces = await client.findAll(core.class.Space, {
|
|
archived: false,
|
|
_class: { $in: requestedSpaceClasses }
|
|
})
|
|
const availableSpaces = allSpaces.map((sp) => sp._id)
|
|
spaceQuery = { space: { $in: availableSpaces } }
|
|
}
|
|
|
|
const date = dateFileBrowserFilters.find((o) => o.id === selectedDateId_)?.getDate()
|
|
const dateQuery = date && { modifiedOn: date }
|
|
|
|
const fileType = fileTypeFileBrowserFilters.find((o) => o.id === selectedFileTypeId_)?.getType()
|
|
const fileTypeQuery = fileType && { type: fileType }
|
|
|
|
attachments = await client.findAll(
|
|
attachment.class.Attachment,
|
|
{ ...nameQuery, ...senderQuery, ...spaceQuery, ...dateQuery, ...fileTypeQuery },
|
|
{
|
|
sort: sortModeToOptionObject(selectedSort_),
|
|
limit: 200,
|
|
lookup: {
|
|
file: core.class.Blob
|
|
}
|
|
}
|
|
)
|
|
isLoading = false
|
|
}
|
|
</script>
|
|
|
|
{#if withHeader}
|
|
<div class="ac-header full divide caption-height">
|
|
<div class="ac-header__wrap-title">
|
|
<span class="ac-header__title"><Label label={attachment.string.FileBrowser} /></span>
|
|
</div>
|
|
<div class="mb-1 clear-mins">
|
|
<TabList
|
|
items={[
|
|
{ id: 'table', icon: view.icon.Table, tooltip: attachment.string.FileBrowserListView },
|
|
{ id: 'card', icon: view.icon.Card, tooltip: attachment.string.FileBrowserGridView }
|
|
]}
|
|
selected={isListDisplayMode ? 'table' : 'card'}
|
|
on:select={(result) => {
|
|
if (result.detail !== undefined) isListDisplayMode = result.detail === 'table' ?? false
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
<div class="ac-header full divide search-start">
|
|
<div class="ac-header-full small-gap">
|
|
<SearchEdit bind:value={search} on:change={() => {}} />
|
|
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
|
|
<div class="buttons-divider" />
|
|
</div>
|
|
<FileBrowserFilters
|
|
{requestedSpaceClasses}
|
|
{spaceId}
|
|
bind:selectedParticipants
|
|
bind:selectedSpaces
|
|
bind:selectedDateId
|
|
bind:selectedFileTypeId
|
|
/>
|
|
</div>
|
|
<div class="group">
|
|
<div class="groupHeader">
|
|
<div class="eGroupHeaderCount">
|
|
<Label label={attachment.string.FileBrowserFileCounter} params={{ results: attachments?.length ?? 0 }} />
|
|
</div>
|
|
<FileBrowserSortMenu bind:selectedSort />
|
|
</div>
|
|
{#if isLoading}
|
|
<div class="flex-grow">
|
|
<Loading />
|
|
</div>
|
|
{:else if attachments?.length}
|
|
{#if isListDisplayMode}
|
|
<AttachmentsListView {attachments} />
|
|
{:else}
|
|
<AttachmentsGalleryView {attachments} />
|
|
{/if}
|
|
{:else}
|
|
<div class="flex-between ml-6">
|
|
<Label label={attachment.string.NoFiles} />
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
.group {
|
|
overflow: auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 1rem 0 1rem 0.5rem;
|
|
height: 100%;
|
|
}
|
|
|
|
.groupHeader {
|
|
margin: 0 1.5rem 0.75rem 1.5rem;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
.eGroupHeaderCount {
|
|
font-size: 0.75rem;
|
|
color: var(--caption-color);
|
|
}
|
|
}
|
|
</style>
|