mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-30 21:45:01 +02:00
Chunter: file browser additional fixes (#1547)
Signed-off-by: Ruslan Izhitsky <ruslan.izhitskiy@xored.com>
This commit is contained in:
@@ -14,9 +14,10 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { IconFolder } from '@anticrm/ui'
|
||||
import { IconFolder, Label } from '@anticrm/ui'
|
||||
|
||||
import type { Space } from '@anticrm/core'
|
||||
import presentation from '..'
|
||||
|
||||
export let value: Space
|
||||
export let subtitle: string | undefined = undefined
|
||||
@@ -27,7 +28,12 @@
|
||||
<div class="flex-center {size} caption-color flex-no-shrink"><IconFolder size={'small'} /></div>
|
||||
<div class="flex-col ml-2 min-w-0">
|
||||
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
|
||||
<div class="content-accent-color overflow-label">{value.name}</div>
|
||||
<div class="content-accent-color overflow-label">
|
||||
{value.name}
|
||||
{#if value.archived}
|
||||
<Label label={presentation.string.Archived}/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<!--
|
||||
// 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 core, { Class, Ref, Space } from '@anticrm/core'
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { translate } from '@anticrm/platform'
|
||||
import type { ButtonKind, ButtonSize, TooltipAlignment } from '@anticrm/ui'
|
||||
import { Tooltip, showPopup, Button } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import presentation, { SpacesMultiPopup } from '..'
|
||||
|
||||
export let selectedItems: Ref<Space>[] = []
|
||||
export let _classes: Ref<Class<Space>>[] = []
|
||||
export let label: IntlString
|
||||
|
||||
export let kind: ButtonKind = 'no-border'
|
||||
export let size: ButtonSize = 'small'
|
||||
export let justify: 'left' | 'center' = 'center'
|
||||
export let width: string | undefined = undefined
|
||||
export let labelDirection: TooltipAlignment | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
async function addSpace (evt: Event): Promise<void> {
|
||||
showPopup(
|
||||
SpacesMultiPopup,
|
||||
{
|
||||
_classes,
|
||||
label,
|
||||
selectedSpaces: selectedItems
|
||||
},
|
||||
evt.target as HTMLElement,
|
||||
() => { },
|
||||
(result) => {
|
||||
if (result !== undefined) {
|
||||
selectedItems = result
|
||||
dispatch('update', selectedItems)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Tooltip {label} fill={width === '100%'} direction={labelDirection}>
|
||||
<Button
|
||||
label={selectedItems.length === 0 ? presentation.string.Spaces : undefined}
|
||||
width={width ?? 'min-content'}
|
||||
{kind} {size} {justify}
|
||||
on:click={addSpace}
|
||||
>
|
||||
<svelte:fragment slot="content">
|
||||
{#if selectedItems.length > 0}
|
||||
<div class="flex-row-center flex-nowrap">
|
||||
{#await translate(presentation.string.NumberSpaces, { count: selectedItems.length }) then text}
|
||||
<span class="ml-1-5">{text}</span>
|
||||
{/await}
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
@@ -0,0 +1,114 @@
|
||||
<!--
|
||||
// Copyright © 2020 Anticrm Platform Contributors.
|
||||
//
|
||||
// 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 { IntlString } from '@anticrm/platform'
|
||||
import { translate } from '@anticrm/platform'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
|
||||
import core, { Class, getCurrentAccount, Ref, Space } from '@anticrm/core'
|
||||
import { Tooltip, CheckBox, Label } from '@anticrm/ui'
|
||||
|
||||
import { createQuery } from '../utils'
|
||||
import presentation from '..'
|
||||
import SpaceInfo from './SpaceInfo.svelte';
|
||||
|
||||
export let _classes: Ref<Class<Space>>[] = []
|
||||
export let allowDeselect: boolean = false
|
||||
export let titleDeselect: IntlString | undefined = undefined
|
||||
export let placeholder: IntlString = presentation.string.Search
|
||||
export let selected: Ref<Space> | undefined
|
||||
export let selectedSpaces: Ref<Space>[] = []
|
||||
|
||||
let searchQuery: string = ''
|
||||
let spaces: Space[] = []
|
||||
let shownSpaces: Space[] = []
|
||||
let input: HTMLInputElement
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const query = createQuery()
|
||||
const myAccId = getCurrentAccount()._id
|
||||
|
||||
$: query.query<Space>(
|
||||
core.class.Space,
|
||||
{
|
||||
name: { $like: '%' + searchQuery + '%' },
|
||||
_class: { $in: _classes },
|
||||
},
|
||||
result => {
|
||||
spaces = result
|
||||
},
|
||||
{ limit: 200 }
|
||||
)
|
||||
|
||||
$: update(spaces)
|
||||
const update = (spaces_: Space[]) => {
|
||||
shownSpaces = spaces_.filter((sp) => {
|
||||
// don't show archived unless search is specified or this space is selected
|
||||
// show private only if it includes the current user
|
||||
return (!sp.archived || searchQuery || selectedSpaces.includes(sp._id)) && (!sp.private || sp.members.includes(myAccId))
|
||||
})
|
||||
}
|
||||
|
||||
let phTraslate: string = ''
|
||||
$: if (placeholder) translate(placeholder, {}).then(res => { phTraslate = res })
|
||||
|
||||
const isSelected = (space: Space): boolean => {
|
||||
if (selectedSpaces.filter(s => s === space._id).length > 0) return true
|
||||
return false
|
||||
}
|
||||
|
||||
const checkSelected = (space: Space): void => {
|
||||
if (isSelected(space)) {
|
||||
selectedSpaces = selectedSpaces.filter(s => s !== space._id)
|
||||
} else {
|
||||
selectedSpaces.push(space._id)
|
||||
}
|
||||
spaces = spaces
|
||||
dispatch('update', selectedSpaces)
|
||||
}
|
||||
|
||||
onMount(() => { if (input) input.focus() })
|
||||
</script>
|
||||
|
||||
<div class="selectPopup">
|
||||
<div class="header">
|
||||
<input bind:this={input} type='text' bind:value={searchQuery} placeholder={phTraslate} on:change/>
|
||||
</div>
|
||||
<div class="scroll">
|
||||
<div class="box">
|
||||
{#each shownSpaces as space}
|
||||
<button class="menu-item" on:click={() => {
|
||||
checkSelected(space)
|
||||
}}>
|
||||
<div class="check pointer-events-none">
|
||||
<CheckBox checked={isSelected(space)} primary />
|
||||
</div>
|
||||
<SpaceInfo size={'medium'} value={space} />
|
||||
{#if allowDeselect && space._id === selected}
|
||||
<div class="check-right pointer-events-none">
|
||||
{#if titleDeselect}
|
||||
<Tooltip label={titleDeselect ?? presentation.string.Deselect}>
|
||||
<CheckBox checked circle primary />
|
||||
</Tooltip>
|
||||
{:else}
|
||||
<CheckBox checked circle primary />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user