Add AttachmentPresenter (#1452)

Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com>
This commit is contained in:
Alex 2022-04-20 13:07:22 +07:00 committed by GitHub
parent e4e39469c6
commit 2e5982f2fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 167 additions and 8 deletions

View File

@ -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."
}
}

View File

@ -78,6 +78,10 @@
"Remove": "Удалить",
"NullDate": "М/Д/ГГГГ",
"ViewProfile": "Перейти в профиль",
"RemoveFromCard": "Удалить из карточки"
"RemoveFromCard": "Удалить из карточки",
"LinkName": "Имя ссылки",
"Edit": "Изменить",
"Update": "Обновить",
"DeleteAttachment": "Удаление вложения необратимо. Отмена невозможна."
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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,