// // Copyright © 2020 Anticrm Platform Contributors. // // Licensed under the Eclipse Public License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. You may // obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // limitations under the License. // import attachment, { Attachment } from '@hcengineering/attachment' import { ObjQueryType, SortingOrder, SortingQuery, Markup } from '@hcengineering/core' import { IntlString, Resources } from '@hcengineering/platform' import preference from '@hcengineering/preference' import { getClient } from '@hcengineering/presentation' import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte' import AddAttachment from './components/AddAttachment.svelte' import AttachmentDocList from './components/AttachmentDocList.svelte' import AttachmentDroppable from './components/AttachmentDroppable.svelte' import AttachmentGalleryPresenter from './components/AttachmentGalleryPresenter.svelte' import AttachmentList from './components/AttachmentList.svelte' import AttachmentPresenter from './components/AttachmentPresenter.svelte' import AttachmentRefInput from './components/AttachmentRefInput.svelte' import Attachments from './components/Attachments.svelte' import AttachmentsPresenter from './components/AttachmentsPresenter.svelte' import FileBrowser from './components/FileBrowser.svelte' import FileDownload from './components/icons/FileDownload.svelte' import Photos from './components/Photos.svelte' import AttachmentStyledBox from './components/AttachmentStyledBox.svelte' import AccordionEditor from './components/AccordionEditor.svelte' import { deleteFile, uploadFile } from './utils' import { DisplayTx } from '@hcengineering/activity' export { AddAttachment, AttachmentDroppable, Attachments, AttachmentsPresenter, AttachmentPresenter, AttachmentGalleryPresenter, AttachmentRefInput, AttachmentList, AttachmentDocList, FileDownload, FileBrowser, AttachmentStyledBox, AccordionEditor } export enum FileBrowserSortMode { NewestFile, OldestFile, AscendingAlphabetical, DescendingAlphabetical, SmallestSize, BiggestSize } export const sortModeToOptionObject = (sortMode: FileBrowserSortMode): SortingQuery => { switch (sortMode) { case FileBrowserSortMode.NewestFile: return { modifiedOn: SortingOrder.Descending } case FileBrowserSortMode.OldestFile: return { modifiedOn: SortingOrder.Ascending } case FileBrowserSortMode.AscendingAlphabetical: return { name: SortingOrder.Ascending } case FileBrowserSortMode.DescendingAlphabetical: return { name: SortingOrder.Descending } case FileBrowserSortMode.SmallestSize: return { size: SortingOrder.Ascending } case FileBrowserSortMode.BiggestSize: return { size: SortingOrder.Descending } } } const msInDay = 24 * 60 * 60 * 1000 const getBeginningOfDate = (customDate?: Date): number => { if (customDate == null) { customDate = new Date() } customDate.setUTCHours(0, 0, 0, 0) return customDate.getTime() } interface Filter { id: string label: IntlString } interface DateFilter extends Filter { getDate: () => ObjQueryType | undefined } interface TypeFilter extends Filter { getType: () => ObjQueryType | undefined } export const dateFileBrowserFilters: DateFilter[] = [ { id: 'dateAny', label: attachment.string.FileBrowserDateFilterAny, getDate: () => { return undefined } }, { id: 'dateToday', label: attachment.string.FileBrowserDateFilterToday, getDate: () => { return { $gte: getBeginningOfDate() } } }, { id: 'dateYesterday', label: attachment.string.FileBrowserDateFilterYesterday, getDate: () => { return { $gte: getBeginningOfDate() - msInDay, $lt: getBeginningOfDate() } } }, { id: 'date7Days', label: attachment.string.FileBrowserDateFilter7Days, getDate: () => { return { $gte: getBeginningOfDate() - msInDay * 6 } } }, { id: 'date30Days', label: attachment.string.FileBrowserDateFilter30Days, getDate: () => { return { $gte: getBeginningOfDate() - msInDay * 29 } } }, { id: 'date3Months', label: attachment.string.FileBrowserDateFilter3Months, getDate: () => { const now = new Date() now.setMonth(now.getMonth() - 3) return { $gte: getBeginningOfDate(now) } } }, { id: 'date12Months', label: attachment.string.FileBrowserDateFilter12Months, getDate: () => { const now = new Date() now.setMonth(now.getMonth() - 12) return { $gte: getBeginningOfDate(now) } } } ] export const fileTypeFileBrowserFilters: TypeFilter[] = [ { id: 'typeAny', label: attachment.string.FileBrowserTypeFilterAny, getType: () => { return undefined } }, { id: 'typeImage', label: attachment.string.FileBrowserTypeFilterImages, getType: () => { return { $like: '%image/%' } } }, { id: 'typeAudio', label: attachment.string.FileBrowserTypeFilterAudio, getType: () => { return { $like: '%audio/%' } } }, { id: 'typeVideo', label: attachment.string.FileBrowserTypeFilterVideos, getType: () => { return { $like: '%video/%' } } }, { id: 'typePDF', label: attachment.string.FileBrowserTypeFilterPDFs, getType: () => { return 'application/pdf' } } ] export async function AddAttachmentToSaved (attach: Attachment): Promise { const client = getClient() await client.createDoc(attachment.class.SavedAttachments, preference.space.Preference, { attachedTo: attach._id }) } export async function DeleteAttachmentFromSaved (attach: Attachment): Promise { const client = getClient() const current = await client.findOne(attachment.class.SavedAttachments, { attachedTo: attach._id }) if (current !== undefined) { await client.remove(current) } } export async function DeleteAttachment (attach: Attachment): Promise { const client = getClient() await client.removeCollection( attach._class, attach.space, attach._id, attach.attachedTo, attach.attachedToClass, 'attachments' ) } export function attachmentsFilter (txes: DisplayTx[]): DisplayTx[] { return txes.filter((tx) => tx.tx.objectClass === attachment.class.Attachment) } export default async (): Promise => ({ filter: { AttachmentsFilter: attachmentsFilter }, component: { AttachmentsPresenter, AttachmentPresenter, AttachmentGalleryPresenter, Attachments, FileBrowser, Photos }, activity: { TxAttachmentCreate }, helper: { UploadFile: uploadFile, DeleteFile: deleteFile }, actionImpl: { AddAttachmentToSaved, DeleteAttachmentFromSaved, DeleteAttachment } }) export interface AccordionItem { id: string label: IntlString tooltip: IntlString content: Markup state: 'opened' | 'closed' placeholder?: IntlString }