From 53821621c6411221f6b35da07c988c57006561a2 Mon Sep 17 00:00:00 2001 From: Ruslan Izhitsky Date: Sat, 23 Apr 2022 09:40:38 +0700 Subject: [PATCH] Chunter: file browser (#1407) (#1488) Signed-off-by: Ruslan Izhitsky --- models/attachment/src/plugin.ts | 3 +- models/chunter/src/index.ts | 6 + .../src/components/DropdownLabelsIntl.svelte | 75 ++++ .../components/DropdownLabelsPopupIntl.svelte | 71 ++++ packages/ui/src/index.ts | 1 + packages/ui/src/types.ts | 5 + plugins/attachment-assets/assets/icons.svg | 3 + plugins/attachment-assets/lang/en.json | 25 +- plugins/attachment-assets/lang/ru.json | 25 +- plugins/attachment-assets/src/index.ts | 3 +- plugins/attachment-resources/package.json | 1 + .../src/components/AddAttachment.svelte | 4 +- .../src/components/AttachmentDocList.svelte | 11 +- .../src/components/AttachmentDroppable.svelte | 2 +- .../src/components/AttachmentList.svelte | 5 +- .../src/components/AttachmentPopup.svelte | 8 +- .../src/components/Attachments.svelte | 5 +- .../components/AttachmentsPresenter.svelte | 9 +- .../src/components/AudioPlayer.svelte | 15 +- .../src/components/FileBrowser.svelte | 375 ++++++++++++++++++ .../activity/TxAttachmentCreate.svelte | 9 +- plugins/attachment-resources/src/index.ts | 13 +- plugins/attachment-resources/src/plugin.ts | 24 +- plugins/attachment-resources/src/utils.ts | 10 +- plugins/attachment/src/index.ts | 4 +- .../EditChannelDescriptionAttachments.svelte | 23 +- .../EditChannelDescriptionTab.svelte | 48 +-- 27 files changed, 700 insertions(+), 83 deletions(-) create mode 100644 packages/ui/src/components/DropdownLabelsIntl.svelte create mode 100644 packages/ui/src/components/DropdownLabelsPopupIntl.svelte create mode 100644 plugins/attachment-resources/src/components/FileBrowser.svelte diff --git a/models/attachment/src/plugin.ts b/models/attachment/src/plugin.ts index 28161beae0..f96cc3d466 100644 --- a/models/attachment/src/plugin.ts +++ b/models/attachment/src/plugin.ts @@ -23,7 +23,8 @@ import type { TxViewlet } from '@anticrm/activity' export default mergeIds(attachmentId, attachment, { component: { - AttachmentPresenter: '' as AnyComponent + AttachmentPresenter: '' as AnyComponent, + FileBrowser: '' as AnyComponent }, string: { AddAttachment: '' as IntlString, diff --git a/models/chunter/src/index.ts b/models/chunter/src/index.ts index 1bb080d891..f4962dd147 100644 --- a/models/chunter/src/index.ts +++ b/models/chunter/src/index.ts @@ -329,6 +329,12 @@ export function createModel (builder: Builder): void { label: chunter.string.SavedMessages, icon: chunter.icon.Bookmark, component: chunter.component.SavedMessages + }, + { + id: 'fileBrowser', + label: attachment.string.FileBrowser, + icon: attachment.icon.FileBrowser, + component: attachment.component.FileBrowser } ], spaces: [ diff --git a/packages/ui/src/components/DropdownLabelsIntl.svelte b/packages/ui/src/components/DropdownLabelsIntl.svelte new file mode 100644 index 0000000000..619fb0dd8f --- /dev/null +++ b/packages/ui/src/components/DropdownLabelsIntl.svelte @@ -0,0 +1,75 @@ + + + + +
+ + + +
diff --git a/packages/ui/src/components/DropdownLabelsPopupIntl.svelte b/packages/ui/src/components/DropdownLabelsPopupIntl.svelte new file mode 100644 index 0000000000..0c1d4fae9c --- /dev/null +++ b/packages/ui/src/components/DropdownLabelsPopupIntl.svelte @@ -0,0 +1,71 @@ + + + + +
+
+ { }} on:change/> +
+
+
+ {#each items.filter((x) => x.label.toLowerCase().includes(search.toLowerCase())) as item, i} + + + {/each} +
+
+
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 0054ebee97..e01d1f9d6f 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -71,6 +71,7 @@ export { default as TimeSince } from './components/TimeSince.svelte' export { default as Dropdown } from './components/Dropdown.svelte' export { default as DropdownPopup } from './components/DropdownPopup.svelte' export { default as DropdownLabels } from './components/DropdownLabels.svelte' +export { default as DropdownLabelsIntl } from './components/DropdownLabelsIntl.svelte' export { default as ShowMore } from './components/ShowMore.svelte' export { default as Menu } from './components/Menu.svelte' export { default as TimeShiftPicker } from './components/TimeShiftPicker.svelte' diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index f0b9e50033..2695bec4fd 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -97,3 +97,8 @@ export interface DropdownTextItem { id: string label: string } + +export interface DropdownIntlItem { + id: string + label: IntlString +} diff --git a/plugins/attachment-assets/assets/icons.svg b/plugins/attachment-assets/assets/icons.svg index f744c478a3..4483c9e96d 100644 --- a/plugins/attachment-assets/assets/icons.svg +++ b/plugins/attachment-assets/assets/icons.svg @@ -9,4 +9,7 @@ + + + diff --git a/plugins/attachment-assets/lang/en.json b/plugins/attachment-assets/lang/en.json index 894156da05..5e07c693c0 100644 --- a/plugins/attachment-assets/lang/en.json +++ b/plugins/attachment-assets/lang/en.json @@ -2,6 +2,7 @@ "string": { "UploadDropFilesHere": "Upload or drop files here", "NoAttachments": "There are no attachments for this", + "NoParticipants": "No participants added", "AddAttachment": "uploaded an attachment", "Attachments": "Attachments", "Photos": "Photos", @@ -13,6 +14,28 @@ "Size": "Size", "Photo": "Photo", "Date": "Date", - "Name": "Name" + "Name": "Name", + "FileBrowser": "File browser", + "FileBrowserFileCounter": "{results, plural, =1 {# result} other {# results}}", + "FileBrowserFilterFrom": "From", + "FileBrowserFilterIn": "In", + "FileBrowserFilterDate": "Date", + "FileBrowserFilterFileType": "File type", + "FileBrowserSortNewest": "Newest file", + "FileBrowserSortOldest": "Oldest file", + "FileBrowserSortAZ": "A to Z", + "FileBrowserSortZA": "Z to A", + "FileBrowserDateFilterAny": "Any time", + "FileBrowserDateFilterToday": "Today", + "FileBrowserDateFilterYesterday": "Yesterday", + "FileBrowserDateFilter7Days": "Last 7 days", + "FileBrowserDateFilter30Days": "Last 30 days", + "FileBrowserDateFilter3Months": "Last 3 months", + "FileBrowserDateFilter12Months": "Last 12 months", + "FileBrowserTypeFilterAny": "Any file type", + "FileBrowserTypeFilterImages": "Images", + "FileBrowserTypeFilterAudio": "Audio", + "FileBrowserTypeFilterVideos": "Videos", + "FileBrowserTypeFilterPDFs": "PDFs" } } \ No newline at end of file diff --git a/plugins/attachment-assets/lang/ru.json b/plugins/attachment-assets/lang/ru.json index f88b0f99a8..b9d668462e 100644 --- a/plugins/attachment-assets/lang/ru.json +++ b/plugins/attachment-assets/lang/ru.json @@ -2,6 +2,7 @@ "string": { "UploadDropFilesHere": "Загрузите или перетащите файлы сюда", "NoAttachments": "Нет вложений", + "NoParticipants": "Участники не добавлены", "AddAttachment": "загрузил вложение", "Attachments": "Вложения", "Photos": "Фотографии", @@ -13,6 +14,28 @@ "Size": "Размер", "Photo": "Фотография", "Date": "Дата", - "Name": "Название" + "Name": "Название", + "FileBrowser": "Браузер файлов", + "FileBrowserFileCounter": "{results, plural, =1 {# результат} =2 {# результата} =3 {# результата} =4 {# результата} other {# результатов}}", + "FileBrowserFilterFrom": "От", + "FileBrowserFilterIn": "В", + "FileBrowserFilterDate": "Дата", + "FileBrowserFilterFileType": "Тип файла", + "FileBrowserSortNewest": "Самый новый файл", + "FileBrowserSortOldest": "Самый старый файл", + "FileBrowserSortAZ": "От А до Я", + "FileBrowserSortZA": "От Я до А", + "FileBrowserDateFilterAny": "В любое время", + "FileBrowserDateFilterToday": "Сегодня", + "FileBrowserDateFilterYesterday": "Вчера", + "FileBrowserDateFilter7Days": "Последние 7 дней", + "FileBrowserDateFilter30Days": "Последние 30 дней", + "FileBrowserDateFilter3Months": "Последние 3 месяца", + "FileBrowserDateFilter12Months": "Последние 12 месяцев", + "FileBrowserTypeFilterAny": "Любой тип файла", + "FileBrowserTypeFilterImages": "Изображения", + "FileBrowserTypeFilterAudio": "Звук", + "FileBrowserTypeFilterVideos": "Видео", + "FileBrowserTypeFilterPDFs": "PDF-файлы" } } \ No newline at end of file diff --git a/plugins/attachment-assets/src/index.ts b/plugins/attachment-assets/src/index.ts index 56b7509672..3c85962b5e 100644 --- a/plugins/attachment-assets/src/index.ts +++ b/plugins/attachment-assets/src/index.ts @@ -18,7 +18,8 @@ import attachment, { attachmentId } from '@anticrm/attachment' const icons = require('../assets/icons.svg') as string // eslint-disable-line loadMetadata(attachment.icon, { - Attachment: `${icons}#chunter` + Attachment: `${icons}#chunter`, + FileBrowser: `${icons}#fileBrowser` }) addStringsLoader(attachmentId, async (lang: string) => await import(`../lang/${lang}.json`)) diff --git a/plugins/attachment-resources/package.json b/plugins/attachment-resources/package.json index d4969bb46b..34de309c04 100644 --- a/plugins/attachment-resources/package.json +++ b/plugins/attachment-resources/package.json @@ -36,6 +36,7 @@ "@anticrm/ui": "~0.6.0", "@anticrm/presentation": "~0.6.2", "@anticrm/attachment": "~0.6.1", + "@anticrm/contact": "~0.6.5", "@anticrm/core": "~0.6.16", "@anticrm/view": "~0.6.0", "@anticrm/view-resources": "~0.6.0", diff --git a/plugins/attachment-resources/src/components/AddAttachment.svelte b/plugins/attachment-resources/src/components/AddAttachment.svelte index e139499301..545a4b622c 100644 --- a/plugins/attachment-resources/src/components/AddAttachment.svelte +++ b/plugins/attachment-resources/src/components/AddAttachment.svelte @@ -29,7 +29,7 @@ const client = getClient() const dispatch = createEventDispatcher() - async function fileSelected() { + async function fileSelected () { const list = inputFile.files if (list === null || list.length === 0) return @@ -43,7 +43,7 @@ dispatch('attached') } - function openFile() { + function openFile () { inputFile.click() } diff --git a/plugins/attachment-resources/src/components/AttachmentDocList.svelte b/plugins/attachment-resources/src/components/AttachmentDocList.svelte index 9ba1dcb138..596bc0b26f 100644 --- a/plugins/attachment-resources/src/components/AttachmentDocList.svelte +++ b/plugins/attachment-resources/src/components/AttachmentDocList.svelte @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. --> - {#if attachments.length} -
+
{#each attachments as attachment} -
+
{/each} diff --git a/plugins/attachment-resources/src/components/AttachmentPopup.svelte b/plugins/attachment-resources/src/components/AttachmentPopup.svelte index 8d13f056bf..fb1b990352 100644 --- a/plugins/attachment-resources/src/components/AttachmentPopup.svelte +++ b/plugins/attachment-resources/src/components/AttachmentPopup.svelte @@ -13,7 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. --> - - diff --git a/plugins/attachment-resources/src/components/Attachments.svelte b/plugins/attachment-resources/src/components/Attachments.svelte index 5665e10368..15baad05a4 100644 --- a/plugins/attachment-resources/src/components/Attachments.svelte +++ b/plugins/attachment-resources/src/components/Attachments.svelte @@ -33,7 +33,6 @@ let inputFile: HTMLInputElement let loading = 0 let dragover = false -
@@ -66,7 +65,8 @@ config={['', 'lastModified']} options={{}} query={{ attachedTo: objectId }} - loadingProps={{ length: attachments ?? 0 }} /> + loadingProps={{ length: attachments ?? 0 }} + /> {/if}
@@ -93,5 +93,4 @@ border-style: solid; } } - diff --git a/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte b/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte index 50e61e480c..1a1c027fa8 100644 --- a/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte +++ b/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte @@ -13,7 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. --> - {#if value && value.attachments && value.attachments > 0} - +
- + {#if showCounter}  {value.attachments} {/if} diff --git a/plugins/attachment-resources/src/components/AudioPlayer.svelte b/plugins/attachment-resources/src/components/AudioPlayer.svelte index 8bfd34521a..ac97d649c9 100644 --- a/plugins/attachment-resources/src/components/AudioPlayer.svelte +++ b/plugins/attachment-resources/src/components/AudioPlayer.svelte @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. --> - -
+
- +
-
+
\ No newline at end of file + diff --git a/plugins/attachment-resources/src/components/FileBrowser.svelte b/plugins/attachment-resources/src/components/FileBrowser.svelte new file mode 100644 index 0000000000..1110608a61 --- /dev/null +++ b/plugins/attachment-resources/src/components/FileBrowser.svelte @@ -0,0 +1,375 @@ + + + +
+
+ +
+
+
+
+ { + participants = evt.detail + }} + noItems={attachment.string.NoParticipants} + /> +
+ + +
+ +
+
+ +
+
+
+
+
+
+
showSortMenu(event)}> + {'Sort: '} +
+
+ {#if attachments?.length} +
+ {#each attachments as attachment, i} +
+
+ +
+
+
showFileMenu(event, attachment, i)}> + +
+
+
+ {/each} +
+ {:else} +
+
+ {/if} +
+ + diff --git a/plugins/attachment-resources/src/components/activity/TxAttachmentCreate.svelte b/plugins/attachment-resources/src/components/activity/TxAttachmentCreate.svelte index 5c806f8a83..3b483ed497 100644 --- a/plugins/attachment-resources/src/components/activity/TxAttachmentCreate.svelte +++ b/plugins/attachment-resources/src/components/activity/TxAttachmentCreate.svelte @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. --> - - \ No newline at end of file + diff --git a/plugins/attachment-resources/src/index.ts b/plugins/attachment-resources/src/index.ts index 04b7d96a4a..60719fff73 100644 --- a/plugins/attachment-resources/src/index.ts +++ b/plugins/attachment-resources/src/index.ts @@ -22,17 +22,28 @@ import AttachmentList from './components/AttachmentList.svelte' import AttachmentRefInput from './components/AttachmentRefInput.svelte' import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte' import Attachments from './components/Attachments.svelte' +import FileBrowser from './components/FileBrowser.svelte' import Photos from './components/Photos.svelte' import { Resources } from '@anticrm/platform' import { uploadFile, deleteFile } from './utils' -export { AddAttachment, AttachmentDroppable, Attachments, AttachmentsPresenter, AttachmentPresenter, AttachmentRefInput, AttachmentList, AttachmentDocList } +export { + AddAttachment, + AttachmentDroppable, + Attachments, + AttachmentsPresenter, + AttachmentPresenter, + AttachmentRefInput, + AttachmentList, + AttachmentDocList +} export default async (): Promise => ({ component: { AttachmentsPresenter, AttachmentPresenter, Attachments, + FileBrowser, Photos }, activity: { diff --git a/plugins/attachment-resources/src/plugin.ts b/plugins/attachment-resources/src/plugin.ts index c295596fa5..bad20efd5a 100644 --- a/plugins/attachment-resources/src/plugin.ts +++ b/plugins/attachment-resources/src/plugin.ts @@ -24,6 +24,28 @@ export default mergeIds(attachmentId, attachment, { NoAttachments: '' as IntlString, UploadDropFilesHere: '' as IntlString, Attachments: '' as IntlString, - Photos: '' as IntlString + Photos: '' as IntlString, + FileBrowser: '' as IntlString, + FileBrowserFileCounter: '' as IntlString, + FileBrowserFilterFrom: '' as IntlString, + FileBrowserFilterIn: '' as IntlString, + FileBrowserFilterDate: '' as IntlString, + FileBrowserFilterFileType: '' as IntlString, + FileBrowserSortNewest: '' as IntlString, + FileBrowserSortOldest: '' as IntlString, + FileBrowserSortAZ: '' as IntlString, + FileBrowserSortZA: '' as IntlString, + FileBrowserDateFilterAny: '' as IntlString, + FileBrowserDateFilterToday: '' as IntlString, + FileBrowserDateFilterYesterday: '' as IntlString, + FileBrowserDateFilter7Days: '' as IntlString, + FileBrowserDateFilter30Days: '' as IntlString, + FileBrowserDateFilter3Months: '' as IntlString, + FileBrowserDateFilter12Months: '' as IntlString, + FileBrowserTypeFilterAny: '' as IntlString, + FileBrowserTypeFilterImages: '' as IntlString, + FileBrowserTypeFilterAudio: '' as IntlString, + FileBrowserTypeFilterVideos: '' as IntlString, + FileBrowserTypeFilterPDFs: '' as IntlString } }) diff --git a/plugins/attachment-resources/src/utils.ts b/plugins/attachment-resources/src/utils.ts index bcc700d847..0da4daf770 100644 --- a/plugins/attachment-resources/src/utils.ts +++ b/plugins/attachment-resources/src/utils.ts @@ -20,7 +20,7 @@ import { getMetadata, setPlatformStatus, unknownError } from '@anticrm/platform' import attachment from './plugin' -export async function uploadFile(file: File, opts?: { space: Ref; attachedTo: Ref }): Promise { +export async function uploadFile (file: File, opts?: { space: Ref, attachedTo: Ref }): Promise { const uploadUrl = getMetadata(login.metadata.UploadUrl) if (uploadUrl === undefined) { @@ -58,7 +58,7 @@ export async function uploadFile(file: File, opts?: { space: Ref; attache return await resp.text() } -export async function deleteFile(id: string): Promise { +export async function deleteFile (id: string): Promise { const uploadUrl = getMetadata(login.metadata.UploadUrl) const url = `${uploadUrl as string}?file=${id}` @@ -74,10 +74,10 @@ export async function deleteFile(id: string): Promise { } } -export async function createAttachments( +export async function createAttachments ( client: Client, list: FileList, - attachTo: { objectClass: Ref>; space: Ref; objectId: Ref } + attachTo: { objectClass: Ref>, space: Ref, objectId: Ref } ) { const { objectClass, objectId, space } = attachTo try { @@ -100,7 +100,7 @@ export async function createAttachments( } } -export function getType(type: string): 'image' | 'video' | 'audio' | 'pdf' | 'other' { +export function getType (type: string): 'image' | 'video' | 'audio' | 'pdf' | 'other' { if (type.startsWith('image/')) { return 'image' } diff --git a/plugins/attachment/src/index.ts b/plugins/attachment/src/index.ts index 4dd30df544..5f5fad7a4e 100644 --- a/plugins/attachment/src/index.ts +++ b/plugins/attachment/src/index.ts @@ -47,7 +47,8 @@ export default plugin(attachmentId, { AttachmentsPresenter: '' as AnyComponent }, icon: { - Attachment: '' as Asset + Attachment: '' as Asset, + FileBrowser: '' as Asset }, class: { Attachment: '' as Ref>, @@ -60,6 +61,7 @@ export default plugin(attachmentId, { string: { Files: '' as IntlString, NoFiles: '' as IntlString, + NoParticipants: '' as IntlString, ShowMoreAttachments: '' as IntlString } }) diff --git a/plugins/chunter-resources/src/components/EditChannelDescriptionAttachments.svelte b/plugins/chunter-resources/src/components/EditChannelDescriptionAttachments.svelte index 3d558f0f91..fc0c9c00d6 100644 --- a/plugins/chunter-resources/src/components/EditChannelDescriptionAttachments.svelte +++ b/plugins/chunter-resources/src/components/EditChannelDescriptionAttachments.svelte @@ -20,14 +20,14 @@ import { Doc, SortingOrder } from '@anticrm/core' import { createQuery } from '@anticrm/presentation' import { Menu } from '@anticrm/view-resources' - import { showPopup, IconMoreV, Label } from '@anticrm/ui' + import { getCurrentLocation, showPopup, IconMoreV, Label, navigate } from '@anticrm/ui' export let channel: ChunterSpace | undefined const query = createQuery() let visibleAttachments: Attachment[] | undefined let totalAttachments = 0 - let attachmentsLimit: number | undefined = 5 + const ATTACHEMNTS_LIMIT = 5 let selectedRowNumber: number | undefined const sort = { modifiedOn: SortingOrder.Descending } @@ -48,14 +48,10 @@ visibleAttachments = res totalAttachments = res.total }, - attachmentsLimit - ? { - limit: attachmentsLimit, - sort: sort - } - : { - sort: sort - } + { + limit: ATTACHEMNTS_LIMIT, + sort: sort + } ) @@ -75,12 +71,13 @@
{/each} - {#if attachmentsLimit && visibleAttachments.length < totalAttachments} + {#if visibleAttachments.length < totalAttachments}
{ - // TODO: replace this with an external attachments page - attachmentsLimit = undefined + const loc = getCurrentLocation() + loc.path[2] = 'fileBrowser' + navigate(loc) }} >