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,