mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 16:27:22 +00:00
Comments presenter (#364)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
0953576fac
commit
88bc3c6f88
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,7 @@ export class TMessage extends TDoc implements Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Model(chunter.class.Comment, core.class.Doc, DOMAIN_COMMENT)
|
@Model(chunter.class.Comment, core.class.Doc, DOMAIN_COMMENT)
|
||||||
|
@UX('Comment' as IntlString)
|
||||||
export class TComment extends TAttachedDoc implements Comment {
|
export class TComment extends TAttachedDoc implements Comment {
|
||||||
@Prop(TypeString(), 'Message' as IntlString)
|
@Prop(TypeString(), 'Message' as IntlString)
|
||||||
@Index(IndexKind.FullText)
|
@Index(IndexKind.FullText)
|
||||||
@ -127,6 +128,10 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: chunter.component.AttachmentPresenter
|
presenter: chunter.component.AttachmentPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.mixin(chunter.class.Comment, core.class.Class, view.mixin.AttributePresenter, {
|
||||||
|
presenter: chunter.component.CommentPresenter
|
||||||
|
})
|
||||||
|
|
||||||
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
|
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
|
||||||
objectClass: chunter.class.Comment,
|
objectClass: chunter.class.Comment,
|
||||||
icon: chunter.icon.Chunter,
|
icon: chunter.icon.Chunter,
|
||||||
|
@ -25,7 +25,9 @@ import type { TxViewlet } from '@anticrm/activity'
|
|||||||
export default mergeIds(chunterId, chunter, {
|
export default mergeIds(chunterId, chunter, {
|
||||||
component: {
|
component: {
|
||||||
AttachmentsPresenter: '' as AnyComponent,
|
AttachmentsPresenter: '' as AnyComponent,
|
||||||
AttachmentPresenter: '' as AnyComponent
|
AttachmentPresenter: '' as AnyComponent,
|
||||||
|
CommentsPresenter: '' as AnyComponent,
|
||||||
|
CommentPresenter: '' as AnyComponent
|
||||||
},
|
},
|
||||||
string: {
|
string: {
|
||||||
ApplicationLabelChunter: '' as IntlString,
|
ApplicationLabelChunter: '' as IntlString,
|
||||||
|
@ -46,6 +46,9 @@ export class TCandidate extends TPerson implements Candidate {
|
|||||||
@Prop(TypeString(), 'Attachments' as IntlString)
|
@Prop(TypeString(), 'Attachments' as IntlString)
|
||||||
attachments?: number
|
attachments?: number
|
||||||
|
|
||||||
|
@Prop(TypeString(), 'Comments' as IntlString)
|
||||||
|
comments?: number
|
||||||
|
|
||||||
@Prop(TypeString(), 'Applications' as IntlString)
|
@Prop(TypeString(), 'Applications' as IntlString)
|
||||||
applications?: number
|
applications?: number
|
||||||
|
|
||||||
@ -133,6 +136,7 @@ export function createModel (builder: Builder): void {
|
|||||||
'city',
|
'city',
|
||||||
{ presenter: recruit.component.ApplicationsPresenter, label: 'Apps' },
|
{ presenter: recruit.component.ApplicationsPresenter, label: 'Apps' },
|
||||||
{ presenter: chunter.component.AttachmentsPresenter, label: 'Files' },
|
{ presenter: chunter.component.AttachmentsPresenter, label: 'Files' },
|
||||||
|
{ presenter: chunter.component.CommentsPresenter, label: 'Comments' },
|
||||||
'modifiedOn',
|
'modifiedOn',
|
||||||
'channels'
|
'channels'
|
||||||
]
|
]
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
"@anticrm/view": "~0.6.0",
|
"@anticrm/view": "~0.6.0",
|
||||||
"svelte": "^3.37.0",
|
"svelte": "^3.37.0",
|
||||||
"@anticrm/contact": "~0.6.2",
|
"@anticrm/contact": "~0.6.2",
|
||||||
"@anticrm/chunter": "~0.6.0",
|
|
||||||
"@anticrm/login": "~0.6.1"
|
"@anticrm/login": "~0.6.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
<!--
|
|
||||||
// Copyright © 2020, 2021 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import type { Comment } from '@anticrm/chunter'
|
|
||||||
import { getClient } from '../utils'
|
|
||||||
import type { Ref } from '@anticrm/core'
|
|
||||||
|
|
||||||
import MessageViewer from './MessageViewer.svelte'
|
|
||||||
import Avatar from './Avatar.svelte'
|
|
||||||
import { TimeSince } from '@anticrm/ui'
|
|
||||||
|
|
||||||
import contact, { Employee, EmployeeAccount, formatName } from '@anticrm/contact'
|
|
||||||
|
|
||||||
export let comment: Comment
|
|
||||||
|
|
||||||
let employee: EmployeeAccount | undefined
|
|
||||||
|
|
||||||
console.log('comment modified by', comment.modifiedBy)
|
|
||||||
|
|
||||||
const client = getClient()
|
|
||||||
client.findOne(contact.class.EmployeeAccount, { _id: comment.modifiedBy as Ref<EmployeeAccount> }).then(account => {employee = account})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="flex-nowrap">
|
|
||||||
<div class="avatar"><Avatar size={'medium'} /></div>
|
|
||||||
<div class="flex-col-stretch message">
|
|
||||||
<div class="header">{#if employee}{formatName(employee.name)}{/if}<span><TimeSince value={comment.modifiedOn}/></span></div>
|
|
||||||
<div class="text"><MessageViewer message={comment.message} /></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.avatar {
|
|
||||||
margin-right: 1rem;
|
|
||||||
}
|
|
||||||
.message {
|
|
||||||
margin-right: 1.25rem;
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin-bottom: .25rem;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 150%;
|
|
||||||
color: var(--theme-caption-color);
|
|
||||||
|
|
||||||
span {
|
|
||||||
margin-left: .5rem;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: .875rem;
|
|
||||||
color: var(--theme-content-dark-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
line-height: 150%;
|
|
||||||
color: var(--theme-content-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -24,7 +24,6 @@ export { default as AttributeEditor } from './components/AttributeEditor.svelte'
|
|||||||
export { default as AttributeBarEditor } from './components/AttributeBarEditor.svelte'
|
export { default as AttributeBarEditor } from './components/AttributeBarEditor.svelte'
|
||||||
export { default as Card } from './components/Card.svelte'
|
export { default as Card } from './components/Card.svelte'
|
||||||
export { default as Channels } from './components/Channels.svelte'
|
export { default as Channels } from './components/Channels.svelte'
|
||||||
export { default as Backlink } from './components/Backlink.svelte'
|
|
||||||
export { default as PDFViewer } from './components/PDFViewer.svelte'
|
export { default as PDFViewer } from './components/PDFViewer.svelte'
|
||||||
export { default as MessageBox } from './components/MessageBox.svelte'
|
export { default as MessageBox } from './components/MessageBox.svelte'
|
||||||
export { default as SpaceCreateCard } from './components/SpaceCreateCard.svelte'
|
export { default as SpaceCreateCard } from './components/SpaceCreateCard.svelte'
|
||||||
|
@ -19,10 +19,11 @@
|
|||||||
import type { Doc, Ref, Space } from '@anticrm/core'
|
import type { Doc, Ref, Space } from '@anticrm/core'
|
||||||
import type { Comment } from '@anticrm/chunter'
|
import type { Comment } from '@anticrm/chunter'
|
||||||
import { ReferenceInput } from '@anticrm/text-editor'
|
import { ReferenceInput } from '@anticrm/text-editor'
|
||||||
import { createQuery, getClient, Backlink } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
import { ScrollBox, Grid } from '@anticrm/ui'
|
import { ScrollBox, Grid } from '@anticrm/ui'
|
||||||
|
|
||||||
import chunter from '@anticrm/chunter'
|
import chunter from '@anticrm/chunter'
|
||||||
|
import CommentPresenter from './CommentPresenter.svelte'
|
||||||
|
|
||||||
export let object: Doc
|
export let object: Doc
|
||||||
export let space: Ref<Space>
|
export let space: Ref<Space>
|
||||||
@ -48,7 +49,7 @@ function onMessage(event: CustomEvent) {
|
|||||||
{#if comments}
|
{#if comments}
|
||||||
<Grid column={1} rowGap={1.5}>
|
<Grid column={1} rowGap={1.5}>
|
||||||
{#each comments as comment}
|
{#each comments as comment}
|
||||||
<Backlink {comment} />
|
<CommentPresenter value={comment} />
|
||||||
{/each}
|
{/each}
|
||||||
</Grid>
|
</Grid>
|
||||||
{/if}
|
{/if}
|
||||||
|
32
plugins/chunter-resources/src/components/CommentPopup.svelte
Normal file
32
plugins/chunter-resources/src/components/CommentPopup.svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Ref, Doc, SortingOrder } from '@anticrm/core'
|
||||||
|
import { Table } from '@anticrm/view-resources'
|
||||||
|
|
||||||
|
import chunter from '@anticrm/chunter'
|
||||||
|
|
||||||
|
export let objectId: Ref<Doc>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
_class={chunter.class.Comment}
|
||||||
|
config={['']}
|
||||||
|
options={ { limit: 3, sort: { modifiedOn: SortingOrder.Descending }} }
|
||||||
|
query={ { attachedTo: objectId } }
|
||||||
|
/>
|
@ -0,0 +1,98 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Avatar, getClient } from '@anticrm/presentation'
|
||||||
|
import type { Comment } from '@anticrm/chunter'
|
||||||
|
import contact, { EmployeeAccount, formatName } from '@anticrm/contact'
|
||||||
|
|
||||||
|
import { MessageViewer } from '@anticrm/presentation'
|
||||||
|
import { Account, Ref } from '@anticrm/core'
|
||||||
|
|
||||||
|
export let value: Comment
|
||||||
|
|
||||||
|
const client = getClient()
|
||||||
|
|
||||||
|
async function getUser (user: Ref<EmployeeAccount> | Ref<Account>): Promise<EmployeeAccount | undefined> {
|
||||||
|
return await client.findOne(contact.class.EmployeeAccount, { _id: user as Ref<EmployeeAccount> })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTime (time: number): string {
|
||||||
|
let options: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric'}
|
||||||
|
if (!isToday(time)) {
|
||||||
|
options = {
|
||||||
|
month: 'numeric',
|
||||||
|
day: 'numeric',
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Date(value.modifiedOn).toLocaleString('default', options)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isToday (time: number): boolean {
|
||||||
|
const current = new Date()
|
||||||
|
const target = new Date(time)
|
||||||
|
return current.getDate() === target.getDate() && current.getMonth() === target.getMonth() && current.getFullYear() === target.getFullYear()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="avatar"><Avatar size={'medium'} /></div>
|
||||||
|
<div class="message">
|
||||||
|
<div class="header">
|
||||||
|
{#await getUser(value.modifiedBy) then user}
|
||||||
|
{#if user}{formatName(user.name)}{/if}
|
||||||
|
{/await}
|
||||||
|
<span>{getTime(value.modifiedOn)}</span>
|
||||||
|
</div>
|
||||||
|
<div class="text"><MessageViewer message={value.message}/></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.avatar { min-width: 2.25rem; }
|
||||||
|
|
||||||
|
.message {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 1rem;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 150%;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
margin-bottom: .25rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-left: .5rem;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: .875rem;
|
||||||
|
line-height: 1.125rem;
|
||||||
|
opacity: .4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
line-height: 150%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,32 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Doc } from '@anticrm/core'
|
||||||
|
import { Tooltip, IconComments } from '@anticrm/ui'
|
||||||
|
import CommentPopup from './CommentPopup.svelte'
|
||||||
|
|
||||||
|
export let value: Doc & { comments?: number }
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if value.comments && value.comments > 0}
|
||||||
|
<Tooltip label={'Comments (' + value.comments + ')'} component={CommentPopup} props={{ objectId: value._id }}>
|
||||||
|
<div class="sm-tool-icon">
|
||||||
|
<span class="icon"><IconComments size="small"/></span>{value.comments}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
@ -18,6 +18,8 @@ import ChannelView from './components/ChannelView.svelte'
|
|||||||
import Activity from './components/Activity.svelte'
|
import Activity from './components/Activity.svelte'
|
||||||
import AttachmentsPresenter from './components/AttachmentsPresenter.svelte'
|
import AttachmentsPresenter from './components/AttachmentsPresenter.svelte'
|
||||||
import AttachmentPresenter from './components/AttachmentPresenter.svelte'
|
import AttachmentPresenter from './components/AttachmentPresenter.svelte'
|
||||||
|
import CommentPresenter from './components/CommentPresenter.svelte'
|
||||||
|
import CommentsPresenter from './components/CommentsPresenter.svelte'
|
||||||
import TxCommentCreate from './components/activity/TxCommentCreate.svelte'
|
import TxCommentCreate from './components/activity/TxCommentCreate.svelte'
|
||||||
import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte'
|
import TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte'
|
||||||
|
|
||||||
@ -29,10 +31,12 @@ export default async () => ({
|
|||||||
ChannelView,
|
ChannelView,
|
||||||
Activity,
|
Activity,
|
||||||
AttachmentsPresenter,
|
AttachmentsPresenter,
|
||||||
AttachmentPresenter
|
AttachmentPresenter,
|
||||||
|
CommentPresenter,
|
||||||
|
CommentsPresenter
|
||||||
},
|
},
|
||||||
activity: {
|
activity: {
|
||||||
TxCommentCreate: TxCommentCreate,
|
TxCommentCreate,
|
||||||
TxAttachmentCreate
|
TxAttachmentCreate
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -34,6 +34,7 @@ export interface Candidates extends Space {}
|
|||||||
export interface Candidate extends Person {
|
export interface Candidate extends Person {
|
||||||
title?: string
|
title?: string
|
||||||
attachments?: number
|
attachments?: number
|
||||||
|
comments?: number
|
||||||
applications?: number
|
applications?: number
|
||||||
onsite?: boolean
|
onsite?: boolean
|
||||||
remote?: boolean
|
remote?: boolean
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user