From 8e43fcec51ef3c662b61faf6eecf2ee65021c9ef Mon Sep 17 00:00:00 2001 From: Sergey Semenov <lvfx@ya.ru> Date: Tue, 19 Apr 2022 16:48:29 +0700 Subject: [PATCH] Add EditMember popup (#1448) Signed-off-by: Sergey Semenov <lvfx@ya.ru> --- plugins/board-assets/lang/en.json | 4 +- plugins/board-assets/lang/ru.json | 4 +- .../src/components/editor/CardDetails.svelte | 20 ++++- .../src/components/popups/EditMember.svelte | 88 +++++++++++++++++++ .../presenters/MemberPresenter.svelte | 21 ++--- plugins/board-resources/src/plugin.ts | 4 +- 6 files changed, 127 insertions(+), 14 deletions(-) create mode 100644 plugins/board-resources/src/components/popups/EditMember.svelte diff --git a/plugins/board-assets/lang/en.json b/plugins/board-assets/lang/en.json index 2814887b9d..894c3da014 100644 --- a/plugins/board-assets/lang/en.json +++ b/plugins/board-assets/lang/en.json @@ -72,6 +72,8 @@ "DueDate": "Due date", "Save": "Save", "Remove": "Remove", - "NullDate": "M/D/YYYY" + "NullDate": "M/D/YYYY", + "ViewProfile": "View profile", + "RemoveFromCard": "Remove from card" } } diff --git a/plugins/board-assets/lang/ru.json b/plugins/board-assets/lang/ru.json index 924a5fb060..439702081a 100644 --- a/plugins/board-assets/lang/ru.json +++ b/plugins/board-assets/lang/ru.json @@ -72,6 +72,8 @@ "DueDate": "Срок", "Save": "Сохранить", "Remove": "Удалить", - "NullDate": "М/Д/ГГГГ" + "NullDate": "М/Д/ГГГГ", + "ViewProfile": "Перейти в профиль", + "RemoveFromCard": "Удалить из карточки" } } diff --git a/plugins/board-resources/src/components/editor/CardDetails.svelte b/plugins/board-resources/src/components/editor/CardDetails.svelte index 078f2056f0..a4ab5b47ee 100644 --- a/plugins/board-resources/src/components/editor/CardDetails.svelte +++ b/plugins/board-resources/src/components/editor/CardDetails.svelte @@ -37,6 +37,24 @@ let labelsHandler: () => void let dateHandler: () => void + $: membersIds = members?.map(m => m._id) ?? [] + + const getMenuItems = (member: Employee) => { + return [ + [{ + title: board.string.ViewProfile, + handler: () => console.log('TODO: implement') + }], + [{ + title: board.string.RemoveFromCard, + handler: () => { + const newMembers = membersIds.filter((m) => m !== member._id) + client.update(value, { members: newMembers }) + } + }] + ] + } + $: if (value.members && value.members.length > 0) { query.query(contact.class.Employee, { _id: { $in: value.members } }, (result) => { members = result @@ -80,7 +98,7 @@ </div> <div class="flex-row-center flex-gap-1"> {#each members as member} - <MemberPresenter value={member} size="large" /> + <MemberPresenter value={member} size="large" menuItems={getMenuItems(member)} /> {/each} <Button icon={IconAdd} shape="circle" kind="no-border" size="large" on:click={membersHandler} /> </div> diff --git a/plugins/board-resources/src/components/popups/EditMember.svelte b/plugins/board-resources/src/components/popups/EditMember.svelte new file mode 100644 index 0000000000..8d11d6c94e --- /dev/null +++ b/plugins/board-resources/src/components/popups/EditMember.svelte @@ -0,0 +1,88 @@ +<script lang="ts"> + import { Employee, formatName } from '@anticrm/contact' + import { getFirstName, getLastName } from '@anticrm/contact' + import type { IntlString } from '@anticrm/platform' + import { ActionIcon, IconClose, Label } from '@anticrm/ui' + + export let member: Employee + export let menuItems: { title: IntlString; handler: () => void }[][] + export let onClose: () => void + + const firstName = getFirstName(member.name) + const lastName = getLastName(member.name) + const nameLabel = `${firstName?.[0] ?? ''}${lastName?.[0] ?? ''}`.toUpperCase() + const formattedName = formatName(member.name) +</script> + +<div class="antiPopup container pb-4 w-85"> + <div class="close-icon"> + <ActionIcon icon={IconClose} size={'small'} action={onClose} /> + </div> + <div class="flex top p-4"> + <div class="avatar flex-center"> + <span class="name-label fs-bold">{nameLabel}</span> + </div> + <div class="fs-title mt-4 ml-4"> + {formattedName} + </div> + </div> + {#if menuItems && menuItems.length > 0} + {#each menuItems as menuSubgroup, i} + {#each menuSubgroup as menuItem} + <div + class="menu-item" + on:click={() => { + menuItem.handler() + onClose() + }} + > + <Label label={menuItem.title} /> + </div> + {/each} + {#if i + 1 < menuItems.length} + <div class="divisor" /> + {/if} + {/each} + {/if} +</div> + +<style lang="scss"> + .avatar { + width: 6rem; + height: 6rem; + background-color: var(--popup-bg-hover); + border: 1px solid var(--caption-color); + border-radius: 3rem; + } + + .name-label { + font-size: 2rem; + color: var(--caption-color); + } + + .top { + background-image: linear-gradient(to bottom, var(--popup-bg-hover) 0%, var(--popup-bg-hover) 100%); + background-repeat: no-repeat; + background-size: 100% 5rem; + } + + .menu-item { + padding: 0.5rem 1rem; + + &:hover { + cursor: pointer; + background-color: var(--popup-bg-hover); + } + } + + .divisor { + margin: 0.5rem 1rem; + border-bottom: 1px solid var(--divider-color); + } + + .close-icon { + position: absolute; + top: 0.75rem; + right: 0.75rem; + } +</style> diff --git a/plugins/board-resources/src/components/presenters/MemberPresenter.svelte b/plugins/board-resources/src/components/presenters/MemberPresenter.svelte index f03da14ded..8d0f5e82e0 100644 --- a/plugins/board-resources/src/components/presenters/MemberPresenter.svelte +++ b/plugins/board-resources/src/components/presenters/MemberPresenter.svelte @@ -1,27 +1,28 @@ <script lang="ts"> import { Employee, formatName } from '@anticrm/contact' import { getFirstName, getLastName } from '@anticrm/contact' - import { ContactPresenter } from '@anticrm/contact-resources' import { Button, showPopup } from '@anticrm/ui' + import type { IntlString } from '@anticrm/platform' + import EditMember from '../popups/EditMember.svelte'; export let value: Employee export let size: 'large' | 'medium' + export let menuItems: { title: IntlString; handler: () => void }[][] + const firstName = getFirstName(value.name) const lastName = getLastName(value.name) const nameLabel = `${firstName?.[0] ?? ''}${lastName?.[0] ?? ''}`.toUpperCase() const formattedName = formatName(value.name) + + const openPopup = () => { + const onClose = () => closePopup() + + const closePopup = showPopup(EditMember, { member: value, menuItems, onClose }) + } </script> {#if value} - <Button - {size} - kind="no-border" - shape="circle" - title={formattedName} - on:click={() => { - showPopup(ContactPresenter, { value }) // TODO: show proper popup - }} - > + <Button {size} kind="no-border" shape="circle" title={formattedName} on:click={openPopup}> <div slot="content" class="text-md">{nameLabel}</div> </Button> {/if} diff --git a/plugins/board-resources/src/plugin.ts b/plugins/board-resources/src/plugin.ts index a6370bd2a0..5e92fc36bb 100644 --- a/plugins/board-resources/src/plugin.ts +++ b/plugins/board-resources/src/plugin.ts @@ -93,7 +93,9 @@ export default mergeIds(boardId, board, { DueDate: '' as IntlString, Save: '' as IntlString, Remove: '' as IntlString, - NullDate: '' as IntlString + NullDate: '' as IntlString, + ViewProfile: '' as IntlString, + RemoveFromCard: '' as IntlString }, component: { CreateCustomer: '' as AnyComponent,