mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-15 04:49:00 +00:00
Signed-off-by: budaeva <irina.budaeva@xored.com>
This commit is contained in:
parent
eb9526f015
commit
21f0928e71
@ -16,13 +16,17 @@
|
||||
import contact, { Employee, EmployeeAccount } from '@anticrm/contact'
|
||||
import { Account, DocumentQuery, Ref, SortingOrder, Space } from '@anticrm/core'
|
||||
import { translate } from '@anticrm/platform'
|
||||
import { Label, Scroller, SearchEdit } from '@anticrm/ui'
|
||||
import { IconAdd, Label, Scroller, SearchEdit } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import presentation from '../plugin'
|
||||
import { getClient } from '../utils'
|
||||
import UserInfo from './UserInfo.svelte'
|
||||
|
||||
export let space: Space
|
||||
export let withAddButton: boolean = false
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
const hierarchy = client.getHierarchy()
|
||||
$: label = hierarchy.getClass(space._class).label
|
||||
let spaceClass = ''
|
||||
@ -77,6 +81,16 @@
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if !isSearch && withAddButton}
|
||||
<div class="item fs-title">
|
||||
<div class="flex-row-center" on:click={() => dispatch('addMembers')}>
|
||||
<div class="flex-center ml-1 mr-1"><IconAdd size={'large'} /></div>
|
||||
<div class="flex-col ml-2 min-w-0 content-accent-color">
|
||||
<Label label={presentation.string.Add} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#each current as person}
|
||||
<div class="item fs-title"><UserInfo size={'medium'} value={person} /></div>
|
||||
{/each}
|
||||
|
@ -34,6 +34,7 @@
|
||||
export let placeholder: IntlString = presentation.string.Search
|
||||
export let selectedUsers: Ref<Person>[] = []
|
||||
export let ignoreUsers: Ref<Person>[] = []
|
||||
export let shadows: boolean = true
|
||||
|
||||
let search: string = ''
|
||||
let objects: Person[] = []
|
||||
@ -72,7 +73,7 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="selectPopup">
|
||||
<div class="selectPopup" class:plainContainer={!shadows}>
|
||||
<div class="header">
|
||||
<input bind:this={input} type="text" bind:value={search} placeholder={phTraslate} on:change />
|
||||
</div>
|
||||
@ -110,3 +111,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.plainContainer {
|
||||
color: var(--caption-color);
|
||||
background-color: var(--body-color);
|
||||
border: 1px solid var(--button-border-color);
|
||||
border-radius: .25rem;
|
||||
box-shadow: none;
|
||||
}
|
||||
</style>
|
||||
|
@ -57,6 +57,7 @@
|
||||
"SharedBy": "Shared by {name} {time}",
|
||||
"LeaveChannel": "Leave channel",
|
||||
"ChannelBrowser": "Channel browser",
|
||||
"SavedItems": "Saved items"
|
||||
"SavedItems": "Saved items",
|
||||
"AddMembersHeader": "Add members to {channel}:"
|
||||
}
|
||||
}
|
@ -56,6 +56,7 @@
|
||||
"SharedBy": "Доступ открыт {name} {time}",
|
||||
"LeaveChannel": "Покинуть канал",
|
||||
"ChannelBrowser": "Браузер каналов",
|
||||
"SavedItems": "Сохраненные объекты"
|
||||
"SavedItems": "Сохраненные объекты",
|
||||
"AddMembersHeader": "Добавить пользователей в {channel}:"
|
||||
}
|
||||
}
|
107
plugins/chunter-resources/src/components/AddMembersPopup.svelte
Normal file
107
plugins/chunter-resources/src/components/AddMembersPopup.svelte
Normal file
@ -0,0 +1,107 @@
|
||||
<script lang="ts">
|
||||
import { Channel } from '@anticrm/chunter'
|
||||
import contact, { Employee, EmployeeAccount, formatName } from '@anticrm/contact'
|
||||
import core, { Ref } from '@anticrm/core'
|
||||
import presentation, { getClient, UsersPopup } from '@anticrm/presentation'
|
||||
import { Label, Button, ActionIcon, IconClose } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import chunter from '../plugin'
|
||||
|
||||
export let channel: Channel
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
|
||||
let membersToAdd: EmployeeAccount[] = []
|
||||
let channelMembers: Ref<Employee>[] = []
|
||||
client.findAll(core.class.Account, { _id: { $in: channel.members } }).then((res) => {
|
||||
channelMembers = res
|
||||
.filter((e) => e._class === contact.class.EmployeeAccount)
|
||||
.map((e) => (e as EmployeeAccount).employee)
|
||||
})
|
||||
|
||||
async function changeMembersToAdd (employees: Ref<Employee>[]) {
|
||||
if (employees) {
|
||||
await client.findAll(contact.class.EmployeeAccount, { employee: { $in: employees } }).then((res) => {
|
||||
if (res) {
|
||||
membersToAdd = res
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$: selectedEmployees = membersToAdd.map((e) => e.employee)
|
||||
|
||||
function removeMember (_id: Ref<EmployeeAccount>) {
|
||||
membersToAdd = membersToAdd.filter((m) => m._id !== _id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup antiPopup-withHeader">
|
||||
<div class="ap-header flex-between header">
|
||||
<div class="ap-caption">
|
||||
<Label label={chunter.string.AddMembersHeader} params={{ channel: channel.name }} />
|
||||
</div>
|
||||
<div class="tool">
|
||||
<ActionIcon
|
||||
icon={IconClose}
|
||||
size={'small'}
|
||||
action={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{#if membersToAdd.length}
|
||||
<div class="flex-row-top flex-wrap ml-6 mr-6 mt-4">
|
||||
{#each membersToAdd as m}
|
||||
<div class=" mr-2 p-1 item">
|
||||
{formatName(m.name)}
|
||||
<div class="tool">
|
||||
<ActionIcon
|
||||
icon={IconClose}
|
||||
size={'small'}
|
||||
action={() => {
|
||||
removeMember(m._id)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="ml-8 mr-8 mb-6 mt-4">
|
||||
<UsersPopup
|
||||
selected={undefined}
|
||||
_class={contact.class.Employee}
|
||||
multiSelect={true}
|
||||
allowDeselect={true}
|
||||
selectedUsers={selectedEmployees}
|
||||
ignoreUsers={channelMembers}
|
||||
shadows={false}
|
||||
on:update={(ev) => changeMembersToAdd(ev.detail)}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
on:click={() => {
|
||||
dispatch(
|
||||
'update',
|
||||
membersToAdd.map((m) => m._id)
|
||||
)
|
||||
dispatch('close')
|
||||
}}
|
||||
label={presentation.string.Add}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.header {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: fit-content;
|
||||
background-color: var(--popup-bg-hover);
|
||||
}
|
||||
</style>
|
@ -20,6 +20,7 @@
|
||||
import chunter from '../plugin'
|
||||
import { classIcon } from '../utils'
|
||||
import Header from './Header.svelte'
|
||||
import Lock from './icons/Lock.svelte'
|
||||
|
||||
export let spaceId: Ref<Channel> | undefined
|
||||
|
||||
@ -40,7 +41,7 @@
|
||||
<div class="ac-header divide full">
|
||||
{#if channel}
|
||||
<Header
|
||||
icon={classIcon(client, channel._class)}
|
||||
icon={channel.private ? Lock : classIcon(client, channel._class)}
|
||||
label={channel.name}
|
||||
description={channel.topic}
|
||||
on:click={onSpaceEdit}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let isPrivate: boolean = false
|
||||
let name: string = ''
|
||||
export function canClose (): boolean {
|
||||
return name === ''
|
||||
@ -33,7 +34,7 @@
|
||||
client.createDoc(chunter.class.Channel, core.space.Space, {
|
||||
name,
|
||||
description: '',
|
||||
private: false,
|
||||
private: isPrivate,
|
||||
archived: false,
|
||||
members: [getCurrentAccount()._id]
|
||||
})
|
||||
@ -57,6 +58,10 @@
|
||||
maxWidth={'16rem'}
|
||||
focus
|
||||
/>
|
||||
<ToggleWithLabel label={chunter.string.MakePrivate} description={chunter.string.MakePrivateDescription} />
|
||||
<ToggleWithLabel
|
||||
label={chunter.string.MakePrivate}
|
||||
description={chunter.string.MakePrivateDescription}
|
||||
bind:on={isPrivate}
|
||||
/>
|
||||
</Grid>
|
||||
</SpaceCreateCard>
|
||||
|
@ -15,15 +15,18 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { ChunterSpace } from '@anticrm/chunter'
|
||||
import { EmployeeAccount } from '@anticrm/contact'
|
||||
import type { Class, Ref } from '@anticrm/core'
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { createQuery, getClient, Members } from '@anticrm/presentation'
|
||||
import { Icon, IconClose, Label, ActionIcon, Scroller } from '@anticrm/ui'
|
||||
import { ActionIcon, Icon, IconClose, Label, Scroller, showPopup } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import chunter from '../plugin'
|
||||
import AddMembersPopup from './AddMembersPopup.svelte'
|
||||
import EditChannelDescriptionTab from './EditChannelDescriptionTab.svelte'
|
||||
import EditChannelSettingsTab from './EditChannelSettingsTab.svelte'
|
||||
import Lock from './icons/Lock.svelte'
|
||||
|
||||
export let _id: Ref<ChunterSpace>
|
||||
export let _class: Ref<Class<ChunterSpace>>
|
||||
@ -46,6 +49,24 @@
|
||||
...(_class === chunter.class.Channel ? [chunter.string.Settings] : [])
|
||||
]
|
||||
let selectedTabIndex = 0
|
||||
|
||||
function openAddMembersPopup () {
|
||||
showPopup(
|
||||
AddMembersPopup,
|
||||
{ channel },
|
||||
undefined,
|
||||
() => {},
|
||||
async (membersIds: Ref<EmployeeAccount>[]) => {
|
||||
if (membersIds) {
|
||||
membersIds
|
||||
.filter((m: Ref<EmployeeAccount>) => !channel.members.includes(m))
|
||||
.forEach(async (m) => {
|
||||
await client.update(channel, { $push: { members: m } })
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -57,7 +78,11 @@
|
||||
<div class="ac-header short mirror divide">
|
||||
<div class="ac-header__wrap-title">
|
||||
<div class="ac-header__icon">
|
||||
{#if clazz.icon}<Icon icon={clazz.icon} size={'medium'} />{/if}
|
||||
{#if channel}
|
||||
{#if channel.private}
|
||||
<Lock size={'medium'} />
|
||||
{:else if clazz.icon}<Icon icon={clazz.icon} size={'medium'} />{/if}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="ac-header__title"><Label label={clazz.label} /></div>
|
||||
</div>
|
||||
@ -91,7 +116,7 @@
|
||||
<EditChannelDescriptionTab {channel} on:close />
|
||||
</Scroller>
|
||||
{:else if selectedTabIndex === 1}
|
||||
<Members space={channel} />
|
||||
<Members space={channel} withAddButton={true} on:addMembers={openAddMembersPopup} />
|
||||
{:else if selectedTabIndex === 2}
|
||||
<EditChannelSettingsTab {channel} on:close />
|
||||
{/if}
|
||||
|
@ -14,9 +14,9 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Asset } from '@anticrm/platform'
|
||||
import { Icon } from '@anticrm/ui'
|
||||
import { AnySvelteComponent, Icon } from '@anticrm/ui'
|
||||
|
||||
export let icon: Asset | undefined
|
||||
export let icon: Asset | AnySvelteComponent | undefined
|
||||
export let label: string
|
||||
export let description: string | undefined
|
||||
</script>
|
||||
|
10
plugins/chunter-resources/src/components/icons/Lock.svelte
Normal file
10
plugins/chunter-resources/src/components/icons/Lock.svelte
Normal file
@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M13,6.9h-1.1V4.8c0-2.2-1.8-3.9-3.9-3.9c-2.2,0-3.9,1.8-3.9,3.9v2.1H3c-0.9,0-1.6,0.7-1.6,1.6v5.3 c0,0.9,0.7,1.6,1.6,1.6h10c0.9,0,1.6-0.7,1.6-1.6V8.5C14.6,7.6,13.9,6.9,13,6.9z M5.3,4.8c0-1.5,1.2-2.7,2.7-2.7s2.7,1.2,2.7,2.7 v2.1H5.3V4.8z M13.4,13.8c0,0.2-0.2,0.4-0.4,0.4H3c-0.2,0-0.4-0.2-0.4-0.4V8.5c0-0.2,0.2-0.4,0.4-0.4h10c0.2,0,0.4,0.2,0.4,0.4V13.8 z"
|
||||
/>
|
||||
</svg>
|
@ -80,6 +80,7 @@ export default mergeIds(chunterId, chunter, {
|
||||
SharedBy: '' as IntlString,
|
||||
LeaveChannel: '' as IntlString,
|
||||
ChannelBrowser: '' as IntlString,
|
||||
SavedItems: '' as IntlString
|
||||
SavedItems: '' as IntlString,
|
||||
AddMembersHeader: '' as IntlString
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user