From 2e5982f2fe1b6d6dd13a2c8f570bc02ca88029fd Mon Sep 17 00:00:00 2001 From: Alex <41288429+Dvinyanin@users.noreply.github.com> Date: Wed, 20 Apr 2022 13:07:22 +0700 Subject: [PATCH] Add AttachmentPresenter (#1452) Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com> --- plugins/board-assets/lang/en.json | 6 +- plugins/board-assets/lang/ru.json | 6 +- .../components/popups/EditAttachment.svelte | 44 +++++++++++ .../components/popups/RemoveAttachment.svelte | 40 ++++++++++ .../presenters/AttachmentPresenter.svelte | 73 +++++++++++++++++-- plugins/board-resources/src/plugin.ts | 6 +- 6 files changed, 167 insertions(+), 8 deletions(-) create mode 100644 plugins/board-resources/src/components/popups/EditAttachment.svelte create mode 100644 plugins/board-resources/src/components/popups/RemoveAttachment.svelte diff --git a/plugins/board-assets/lang/en.json b/plugins/board-assets/lang/en.json index c6a96e5882..32595d4a1f 100644 --- a/plugins/board-assets/lang/en.json +++ b/plugins/board-assets/lang/en.json @@ -78,6 +78,10 @@ "Remove": "Remove", "NullDate": "M/D/YYYY", "ViewProfile": "View profile", - "RemoveFromCard": "Remove from card" + "RemoveFromCard": "Remove from card", + "LinkName": "Link name", + "Edit": "Edit", + "Update": "Update", + "DeleteAttachment": "Deleting an attachment is permanent. There is no undo." } } diff --git a/plugins/board-assets/lang/ru.json b/plugins/board-assets/lang/ru.json index ed11b294c4..71df39afa8 100644 --- a/plugins/board-assets/lang/ru.json +++ b/plugins/board-assets/lang/ru.json @@ -78,6 +78,10 @@ "Remove": "Удалить", "NullDate": "М/Д/ГГГГ", "ViewProfile": "Перейти в профиль", - "RemoveFromCard": "Удалить из карточки" + "RemoveFromCard": "Удалить из карточки", + "LinkName": "Имя ссылки", + "Edit": "Изменить", + "Update": "Обновить", + "DeleteAttachment": "Удаление вложения необратимо. Отмена невозможна." } } diff --git a/plugins/board-resources/src/components/popups/EditAttachment.svelte b/plugins/board-resources/src/components/popups/EditAttachment.svelte new file mode 100644 index 0000000000..0939d732a2 --- /dev/null +++ b/plugins/board-resources/src/components/popups/EditAttachment.svelte @@ -0,0 +1,44 @@ +<script lang="ts"> + import { createEventDispatcher } from 'svelte' + import { Label, Button, ActionIcon, IconClose, EditBox } from '@anticrm/ui' + import board from '../../plugin' + import { getClient } from '@anticrm/presentation'; + import { Attachment } from '@anticrm/attachment'; + + export let object: Attachment + + let {name} = object + + const client = getClient() + const dispatch = createEventDispatcher() +</script> + +<div class="antiPopup antiPopup-withHeader antiPopup-withCategory w-85"> + <div class="ap-space"/> + <div class="flex-row-center header"> + <div class="flex-center flex-grow"> + <Label label={board.string.Edit}/> + </div> + <div class="close-icon"> + <ActionIcon icon={IconClose} size={'small'} action={() => {dispatch("close")}} /> + </div> + </div> + <div class="ap-space bottom-divider"/> + <div class="ap-category"> + <div class="ap-categoryItem"> + <EditBox bind:value={name} maxWidth="18rem" label={board.string.LinkName} placeholder={board.string.LinkName}/> + </div> + </div> + <div class="ap-footer"> + <Button + size={'small'} + label={board.string.Update} + kind={'primary'} + on:click={() => { + if (!name) return + client.update(object, {name}) + dispatch('close') + }} + /> + </div> +</div> diff --git a/plugins/board-resources/src/components/popups/RemoveAttachment.svelte b/plugins/board-resources/src/components/popups/RemoveAttachment.svelte new file mode 100644 index 0000000000..09925615fa --- /dev/null +++ b/plugins/board-resources/src/components/popups/RemoveAttachment.svelte @@ -0,0 +1,40 @@ +<script lang="ts"> + import { createEventDispatcher } from 'svelte' + import { Label, Button, ActionIcon, IconClose } from '@anticrm/ui' + import board from '../../plugin' + import { getClient } from '@anticrm/presentation'; + import { Attachment } from '@anticrm/attachment'; + + export let object: Attachment + + const client = getClient() + const dispatch = createEventDispatcher() +</script> + +<div class="antiPopup antiPopup-withHeader antiPopup-withTitle antiPopup-withCategory w-85"> + <div class="ap-space"/> + <div class="flex-row-center header"> + <div class="flex-center flex-grow"> + <Label label={board.string.Delete} /> + </div> + <div class="close-icon"> + <ActionIcon icon={IconClose} size={'small'} action={() => {dispatch("close")}} /> + </div> + </div> + <div class="ap-space bottom-divider"/> + <div class="ap-box ml-4 mr-4 mt-4"> + <Label label={board.string.DeleteAttachment}/> + </div> + <div class="ap-footer"> + <Button + size={'small'} + width="100%" + label={board.string.Delete} + kind={'dangerous'} + on:click={() => { + client.remove(object) + dispatch('close') + }} + /> + </div> +</div> diff --git a/plugins/board-resources/src/components/presenters/AttachmentPresenter.svelte b/plugins/board-resources/src/components/presenters/AttachmentPresenter.svelte index 943d4d1301..5ab83e2098 100644 --- a/plugins/board-resources/src/components/presenters/AttachmentPresenter.svelte +++ b/plugins/board-resources/src/components/presenters/AttachmentPresenter.svelte @@ -12,14 +12,77 @@ // See the License for the specific language governing permissions and // limitations under the License. --> + <script lang="ts"> - import { Attachment } from '@anticrm/attachment' - import { AttachmentPresenter } from '@anticrm/attachment-resources' + import type { Attachment } from '@anticrm/attachment' + import { PDFViewer, getFileUrl } from '@anticrm/presentation' + import { Button, showPopup, TimeSince, closeTooltip } from '@anticrm/ui' + import board from '../../plugin' + import EditAttachment from '../popups/EditAttachment.svelte'; + import RemoveAttachment from '../popups/RemoveAttachment.svelte'; export let value: Attachment - // TODO: implement + + const maxLenght: number = 30 + const trimFilename = (fname: string): string => (fname.length > maxLenght) + ? fname.substr(0, (maxLenght - 1) / 2) + '...' + fname.substr(-(maxLenght - 1) / 2) + : fname + + function iconLabel (name: string): string { + const parts = name.split('.') + const ext = parts[parts.length - 1] + return ext.substring(0, 4).toUpperCase() + } + + function openEmbedded (contentType: string) { + return contentType.includes('application/pdf') || contentType.startsWith('image/') + } + + const handleClick = openEmbedded(value.type) + ? () => { + closeTooltip(); + showPopup(PDFViewer, { file: value.file, name: value.name, contentType: value.type }, 'right') + } : undefined </script> -<div> - <AttachmentPresenter {value} /> +<div class="flex-row-center"> + {#if openEmbedded(value.type)} + <div class="flex-center content mr-2 cursor-pointer" on:click={handleClick}> + <img src={getFileUrl(value.file)} alt={value.name} /> + </div> + {:else} + <a class="no-line" href={getFileUrl(value.file)} download={value.name}><div class="flex-center icon">{iconLabel(value.name)}</div></a> + {/if} + <div class="flex-col-centre info"> + <div class="fs-title">{trimFilename(value.name)}</div> + <div class="flex-row-center"> + <TimeSince value={value.lastModified}/> + <Button label={board.string.Edit} on:click={() => {showPopup(EditAttachment, {object: value})}} kind="transparent"/> + <Button label={board.string.Delete} on:click={() => {showPopup(RemoveAttachment, {object: value})}} kind="transparent"/> + </div> + </div> </div> + +<style lang="scss"> + .icon { + flex-shrink: 0; + margin-right: 1rem; + width: 8rem; + height: 6rem; + font-weight: 500; + font-size: 1rem; + color: var(--primary-button-color); + background-color: var(--primary-button-enabled); + border: 1px solid rgba(0, 0, 0, .1); + border-radius: .5rem; + } + .content { + width: 8rem; + max-height: 6rem; + + img { + max-width: 8rem; + max-height: 6rem; + } + } +</style> diff --git a/plugins/board-resources/src/plugin.ts b/plugins/board-resources/src/plugin.ts index 38ab9fc2b2..45a959edf3 100644 --- a/plugins/board-resources/src/plugin.ts +++ b/plugins/board-resources/src/plugin.ts @@ -99,7 +99,11 @@ export default mergeIds(boardId, board, { Remove: '' as IntlString, NullDate: '' as IntlString, ViewProfile: '' as IntlString, - RemoveFromCard: '' as IntlString + RemoveFromCard: '' as IntlString, + LinkName: '' as IntlString, + Edit: '' as IntlString, + Update: '' as IntlString, + DeleteAttachment: '' as IntlString }, component: { Boards: '' as AnyComponent,