mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-25 01:39:53 +00:00
refactor attachments
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
7cdaaf9224
commit
b3e88daf3c
dev
models
packages/core/src
plugins
chunter-resources/src/components
chunter/src
recruit-resources/src/components
recruit/src
server
@ -14,8 +14,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory } from '@anticrm/core'
|
||||
import type { Message, Backlink } from '@anticrm/chunter'
|
||||
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory, Class } from '@anticrm/core'
|
||||
import type { FindAll } from '@anticrm/server-core'
|
||||
import type { Message, Backlink, Attachment } from '@anticrm/chunter'
|
||||
|
||||
import core from '@anticrm/core'
|
||||
import chunter from '@anticrm/chunter'
|
||||
@ -26,6 +27,7 @@ function extractBacklinks (backlinkId: Ref<Doc>, message: string, kids: NodeList
|
||||
if (kid.nodeName === 'span') {
|
||||
result.push({
|
||||
attachedTo: kid.getAttribute('data-id') as Ref<Doc>,
|
||||
attachedToClass: kid.getAttribute('data-class') as Ref<Class<Doc>>,
|
||||
backlinkId,
|
||||
backlinkClass: chunter.class.Message,
|
||||
message
|
||||
@ -57,9 +59,30 @@ export async function OnMessage (tx: Tx, txFactory: TxFactory): Promise<Tx[]> {
|
||||
return []
|
||||
}
|
||||
|
||||
interface WithAttachements extends Doc {
|
||||
attachments: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function OnAttachment (tx: Tx, txFactory: TxFactory, findAll: FindAll<Doc>): Promise<Tx[]> {
|
||||
if (tx._class === core.class.TxCreateDoc) {
|
||||
const createTx = tx as TxCreateDoc<Attachment>
|
||||
if (createTx.objectClass === chunter.class.Attachment) {
|
||||
const _id = createTx.attributes.attachedTo as Ref<WithAttachements>
|
||||
const _class = createTx.attributes.attachedToClass as Ref<Class<WithAttachements>>
|
||||
const attachedTo = (await findAll(_class, { _id }))[0]
|
||||
return [txFactory.createTxUpdateDoc(_class, attachedTo.space, _id, { $inc: { attachments: 1 } })]
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
OnMessage
|
||||
OnMessage,
|
||||
OnAttachment
|
||||
}
|
||||
})
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ import type { IntlString } from '@anticrm/platform'
|
||||
import { Builder, Model, Prop, UX, TypeString, Index } from '@anticrm/model'
|
||||
import type { Ref, Doc, Class, Domain } from '@anticrm/core'
|
||||
import { IndexKind } from '@anticrm/core'
|
||||
import core, { TSpace, TDoc, TObj } from '@anticrm/model-core'
|
||||
import core, { TSpace, TDoc } from '@anticrm/model-core'
|
||||
import type { Backlink, Channel, Message, Comment, Attachment } from '@anticrm/chunter'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
|
||||
@ -44,6 +44,7 @@ export class TMessage extends TDoc implements Message {
|
||||
@Model(chunter.class.Comment, core.class.Doc, DOMAIN_COMMENT)
|
||||
export class TComment extends TDoc implements Comment {
|
||||
attachedTo!: Ref<Doc>
|
||||
attachedToClass!: Ref<Class<Doc>>
|
||||
@Prop(TypeString(), 'Message' as IntlString)
|
||||
@Index(IndexKind.FullText)
|
||||
message!: string
|
||||
@ -55,8 +56,10 @@ export class TBacklink extends TComment implements Backlink {
|
||||
backlinkClass!: Ref<Class<Doc>>
|
||||
}
|
||||
|
||||
@Model(chunter.class.Attachment, core.class.Obj, DOMAIN_ATTACHMENT)
|
||||
export class TAttachment extends TObj implements Attachment {
|
||||
@Model(chunter.class.Attachment, core.class.Doc, DOMAIN_ATTACHMENT)
|
||||
export class TAttachment extends TDoc implements Attachment {
|
||||
attachedTo!: Ref<Doc>
|
||||
attachedToClass!: Ref<Class<Doc>>
|
||||
name!: string
|
||||
file!: string
|
||||
size!: number
|
||||
|
@ -44,8 +44,7 @@ export function createDemo (builder: Builder): void {
|
||||
provider: contact.channelProvider.Email,
|
||||
value: 'andrey@hc.engineering'
|
||||
}
|
||||
],
|
||||
attachments: {}
|
||||
]
|
||||
})
|
||||
|
||||
builder.createDoc(recruit.class.Candidate, recruit.space.CandidatesPublic, {
|
||||
@ -57,8 +56,7 @@ export function createDemo (builder: Builder): void {
|
||||
provider: contact.channelProvider.Email,
|
||||
value: 'marina@hc.engineering'
|
||||
}
|
||||
],
|
||||
attachments: {}
|
||||
]
|
||||
})
|
||||
|
||||
builder.createDoc(recruit.class.Candidate, recruit.space.CandidatesPublic, {
|
||||
@ -70,7 +68,6 @@ export function createDemo (builder: Builder): void {
|
||||
provider: contact.channelProvider.Email,
|
||||
value: 'alex@hc.engineering'
|
||||
}
|
||||
],
|
||||
attachments: {}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ export class TCandidate extends TPerson implements Candidate {
|
||||
@Prop(TypeString(), 'Title' as IntlString)
|
||||
title?: string
|
||||
|
||||
@Prop(TypeBag(), 'Attachments' as IntlString)
|
||||
attachments!: Bag<Attachment>
|
||||
@Prop(TypeString(), 'Attachments' as IntlString)
|
||||
attachments?: number
|
||||
|
||||
@Prop(TypeString(), 'Applications' as IntlString)
|
||||
applications?: number
|
||||
|
@ -24,4 +24,7 @@ export function createModel (builder: Builder): void {
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverChunter.trigger.OnMessage
|
||||
})
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverChunter.trigger.OnAttachment
|
||||
})
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ export interface UXObject extends Obj {
|
||||
*/
|
||||
export interface AttachedDoc extends Doc {
|
||||
attachedTo: Ref<Doc>
|
||||
attachedToClass: Ref<Class<Doc>>
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,13 +15,13 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { Bag } from '@anticrm/core'
|
||||
import type { Doc } from '@anticrm/core'
|
||||
import type { Attachment } from '@anticrm/chunter'
|
||||
import { IconFile, Link, Tooltip, IconAttachment } from '@anticrm/ui'
|
||||
import { PDFViewer } from '@anticrm/presentation'
|
||||
import AttachmentPopup from './AttachmentPopup.svelte'
|
||||
|
||||
export let value: { attachments: Bag<Attachment> }
|
||||
export let value: Doc & { attachments?: number }
|
||||
|
||||
</script>
|
||||
|
||||
@ -33,10 +33,10 @@
|
||||
</Tooltip>
|
||||
{/if} -->
|
||||
|
||||
{#if value.attachments && Object.keys(value.attachments).length > 0}
|
||||
<Tooltip label={'Attachments (' + Object.values(value.attachments).length + ')'} component={AttachmentPopup} props={{ files: value.attachments }}>
|
||||
{#if value.attachments && value.attachments > 0}
|
||||
<Tooltip label={'Attachments (' + value.attachments + ')'} component={AttachmentPopup} props={{ files: value._id }}>
|
||||
<div class="sm-tool-icon">
|
||||
<span class="icon"><IconAttachment size="small"/></span>{Object.keys(value.attachments).length}
|
||||
<span class="icon"><IconAttachment size="small"/></span>{value.attachments}
|
||||
</div>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import type { Asset, Plugin } from '@anticrm/platform'
|
||||
import type { Space, Obj, Doc, Ref, Class, AttachedDoc } from '@anticrm/core'
|
||||
import type { Space, Doc, Ref, Class, AttachedDoc } from '@anticrm/core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -47,7 +47,7 @@ export interface Backlink extends Comment {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Attachment extends Obj {
|
||||
export interface Attachment extends AttachedDoc {
|
||||
name: string
|
||||
file: string
|
||||
size: number
|
||||
|
@ -26,14 +26,14 @@
|
||||
|
||||
import chunter from '@anticrm/chunter'
|
||||
|
||||
export let objectId: Ref<Doc & { attachments: Bag<Attachment> }>
|
||||
export let objectId: Ref<Doc>
|
||||
export let space: Ref<Space>
|
||||
export let _class: Ref<Class<Doc & { attachments: Bag<Attachment> }>>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
|
||||
export let object: Doc & { attachments: Bag<Attachment> } | undefined = undefined
|
||||
let attachments: Attachment[] = []
|
||||
|
||||
// const query = createQuery()
|
||||
// $: query.query(_class, { _id: objectId }, result => { object = result[0] })
|
||||
const query = createQuery()
|
||||
$: query.query(chunter.class.Attachment, { attachedTo: objectId }, result => { attachments = result })
|
||||
|
||||
let inputFile: HTMLInputElement
|
||||
let loading = false
|
||||
@ -45,8 +45,9 @@
|
||||
try {
|
||||
const uuid = await uploadFile(space, file, objectId)
|
||||
console.log('uploaded file uuid', uuid)
|
||||
client.putBag(_class, space, objectId, 'attachments', encodeURIComponent(uuid), {
|
||||
_class: chunter.class.Attachment,
|
||||
client.createDoc(chunter.class.Attachment, space, {
|
||||
attachedTo: objectId,
|
||||
attachedToClass: _class,
|
||||
name: file.name,
|
||||
file: uuid,
|
||||
type: file.type,
|
||||
@ -81,7 +82,6 @@
|
||||
{/if}
|
||||
<input bind:this={inputFile} type="file" name="file" id="file" style="display: none" on:change={fileSelected}/>
|
||||
</div>
|
||||
{#if object?.attachments !== undefined}
|
||||
<table class="table-body">
|
||||
<thead>
|
||||
<tr class="tr-head">
|
||||
@ -90,7 +90,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each Object.values(object.attachments) as file}
|
||||
{#each attachments as file}
|
||||
<tr class="tr-body">
|
||||
<td class="item flex-row-center">
|
||||
<div class="flex-center file-icon">pdf</div>
|
||||
@ -104,7 +104,6 @@
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -34,7 +34,7 @@ export interface Candidates extends Space {}
|
||||
*/
|
||||
export interface Candidate extends Person {
|
||||
title?: string
|
||||
attachments: Bag<Attachment>
|
||||
attachments?: number
|
||||
applications?: number
|
||||
onsite?: boolean
|
||||
remote?: boolean
|
||||
|
@ -14,8 +14,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory } from '@anticrm/core'
|
||||
import type { Message, Backlink } from '@anticrm/chunter'
|
||||
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory, Class } from '@anticrm/core'
|
||||
import type { FindAll } from '@anticrm/server-core'
|
||||
import type { Message, Backlink, Attachment } from '@anticrm/chunter'
|
||||
import { parse, Node, HTMLElement } from 'node-html-parser'
|
||||
|
||||
import core from '@anticrm/core'
|
||||
@ -27,6 +28,7 @@ function extractBacklinks (backlinkId: Ref<Doc>, message: string, kids: Node[]):
|
||||
if ((kid as HTMLElement).localName === 'span') {
|
||||
result.push({
|
||||
attachedTo: (kid as HTMLElement).getAttribute('data-id') as Ref<Doc>,
|
||||
attachedToClass: (kid as HTMLElement).getAttribute('data-class') as Ref<Class<Doc>>,
|
||||
backlinkId,
|
||||
backlinkClass: chunter.class.Message,
|
||||
message
|
||||
@ -57,9 +59,30 @@ export async function OnMessage (tx: Tx, txFactory: TxFactory): Promise<Tx[]> {
|
||||
return []
|
||||
}
|
||||
|
||||
interface WithAttachements extends Doc {
|
||||
attachments: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function OnAttachment (tx: Tx, txFactory: TxFactory, findAll: FindAll<Doc>): Promise<Tx[]> {
|
||||
if (tx._class === core.class.TxCreateDoc) {
|
||||
const createTx = tx as TxCreateDoc<Attachment>
|
||||
if (createTx.objectClass === chunter.class.Attachment) {
|
||||
const _id = createTx.attributes.attachedTo as Ref<WithAttachements>
|
||||
const _class = createTx.attributes.attachedToClass as Ref<Class<WithAttachements>>
|
||||
const attachedTo = (await findAll(_class, { _id }))[0]
|
||||
return [txFactory.createTxUpdateDoc(_class, attachedTo.space, _id, { $inc: { attachments: 1 } })]
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
trigger: {
|
||||
OnMessage
|
||||
OnMessage,
|
||||
OnAttachment
|
||||
}
|
||||
})
|
||||
|
@ -28,6 +28,7 @@ export const serverChunterId = 'server-chunter' as Plugin
|
||||
*/
|
||||
export default plugin(serverChunterId, {
|
||||
trigger: {
|
||||
OnMessage: '' as Resource<TriggerFunc>
|
||||
OnMessage: '' as Resource<TriggerFunc>,
|
||||
OnAttachment: '' as Resource<TriggerFunc>
|
||||
}
|
||||
})
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user