mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03: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)
|
||||
@UX('Comment' as IntlString)
|
||||
export class TComment extends TAttachedDoc implements Comment {
|
||||
@Prop(TypeString(), 'Message' as IntlString)
|
||||
@Index(IndexKind.FullText)
|
||||
@ -127,6 +128,10 @@ export function createModel (builder: Builder): void {
|
||||
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, {
|
||||
objectClass: chunter.class.Comment,
|
||||
icon: chunter.icon.Chunter,
|
||||
|
@ -25,7 +25,9 @@ import type { TxViewlet } from '@anticrm/activity'
|
||||
export default mergeIds(chunterId, chunter, {
|
||||
component: {
|
||||
AttachmentsPresenter: '' as AnyComponent,
|
||||
AttachmentPresenter: '' as AnyComponent
|
||||
AttachmentPresenter: '' as AnyComponent,
|
||||
CommentsPresenter: '' as AnyComponent,
|
||||
CommentPresenter: '' as AnyComponent
|
||||
},
|
||||
string: {
|
||||
ApplicationLabelChunter: '' as IntlString,
|
||||
|
@ -46,6 +46,9 @@ export class TCandidate extends TPerson implements Candidate {
|
||||
@Prop(TypeString(), 'Attachments' as IntlString)
|
||||
attachments?: number
|
||||
|
||||
@Prop(TypeString(), 'Comments' as IntlString)
|
||||
comments?: number
|
||||
|
||||
@Prop(TypeString(), 'Applications' as IntlString)
|
||||
applications?: number
|
||||
|
||||
@ -133,6 +136,7 @@ export function createModel (builder: Builder): void {
|
||||
'city',
|
||||
{ presenter: recruit.component.ApplicationsPresenter, label: 'Apps' },
|
||||
{ presenter: chunter.component.AttachmentsPresenter, label: 'Files' },
|
||||
{ presenter: chunter.component.CommentsPresenter, label: 'Comments' },
|
||||
'modifiedOn',
|
||||
'channels'
|
||||
]
|
||||
|
@ -24,7 +24,6 @@
|
||||
"@anticrm/view": "~0.6.0",
|
||||
"svelte": "^3.37.0",
|
||||
"@anticrm/contact": "~0.6.2",
|
||||
"@anticrm/chunter": "~0.6.0",
|
||||
"@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 Card } from './components/Card.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 MessageBox } from './components/MessageBox.svelte'
|
||||
export { default as SpaceCreateCard } from './components/SpaceCreateCard.svelte'
|
||||
|
@ -19,10 +19,11 @@
|
||||
import type { Doc, Ref, Space } from '@anticrm/core'
|
||||
import type { Comment } from '@anticrm/chunter'
|
||||
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 chunter from '@anticrm/chunter'
|
||||
import CommentPresenter from './CommentPresenter.svelte'
|
||||
|
||||
export let object: Doc
|
||||
export let space: Ref<Space>
|
||||
@ -48,7 +49,7 @@ function onMessage(event: CustomEvent) {
|
||||
{#if comments}
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
{#each comments as comment}
|
||||
<Backlink {comment} />
|
||||
<CommentPresenter value={comment} />
|
||||
{/each}
|
||||
</Grid>
|
||||
{/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 AttachmentsPresenter from './components/AttachmentsPresenter.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 TxAttachmentCreate from './components/activity/TxAttachmentCreate.svelte'
|
||||
|
||||
@ -29,10 +31,12 @@ export default async () => ({
|
||||
ChannelView,
|
||||
Activity,
|
||||
AttachmentsPresenter,
|
||||
AttachmentPresenter
|
||||
AttachmentPresenter,
|
||||
CommentPresenter,
|
||||
CommentsPresenter
|
||||
},
|
||||
activity: {
|
||||
TxCommentCreate: TxCommentCreate,
|
||||
TxCommentCreate,
|
||||
TxAttachmentCreate
|
||||
}
|
||||
})
|
||||
|
@ -34,6 +34,7 @@ export interface Candidates extends Space {}
|
||||
export interface Candidate extends Person {
|
||||
title?: string
|
||||
attachments?: number
|
||||
comments?: number
|
||||
applications?: number
|
||||
onsite?: boolean
|
||||
remote?: boolean
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user