Add candidate create presenter ()

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2021-11-24 01:46:34 +07:00 committed by GitHub
parent 24aa40317d
commit 2faf60d74e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1093 additions and 1211 deletions
dev
storage/src
tool/src
models/recruit/src
plugins
activity-resources
activity/src
recruit-assets/lang
recruit-resources/src
view-resources/src
view/src
server/workspace/src

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -197,31 +197,13 @@ export function createModel (builder: Builder): void {
sequence: 0
})
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
objectClass: recruit.class.Applicant,
icon: recruit.icon.RecruitApplication,
txClass: core.class.TxCreateDoc,
component: recruit.activity.TxApplicantCreate,
label: recruit.string.TxApplicantCreate,
display: 'emphasized'
}, recruit.ids.TxApplicantCreate)
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
objectClass: recruit.class.Applicant,
icon: recruit.icon.RecruitApplication,
txClass: core.class.TxUpdateDoc,
component: recruit.activity.TxApplicantUpdate,
label: recruit.string.TxApplicantUpdate,
display: 'inline'
}, recruit.ids.TxApplicantUpdate)
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
objectClass: recruit.class.Candidate,
icon: recruit.icon.RecruitApplication,
txClass: core.class.TxCreateDoc,
label: recruit.string.TxCandidateCreate,
display: 'emphasized'
}, recruit.ids.TxCandidateCreate)
}
export { default } from './plugin'

View File

@ -33,10 +33,7 @@ export default mergeIds(recruitId, recruit, {
RecruitApplication: '' as IntlString,
Vacancies: '' as IntlString,
CandidatePools: '' as IntlString,
Vacancy: '' as IntlString,
TxApplicantCreate: '' as IntlString,
TxCandidateCreate: '' as IntlString,
TxApplicantUpdate: '' as IntlString
Vacancy: '' as IntlString
},
component: {
CreateVacancy: '' as AnyComponent,
@ -52,12 +49,9 @@ export default mergeIds(recruitId, recruit, {
CandidatesPublic: '' as Ref<Space>
},
ids: {
TxApplicantCreate: '' as Ref<TxViewlet>,
TxCandidateCreate: '' as Ref<TxViewlet>,
TxApplicantUpdate: '' as Ref<TxViewlet>
},
activity: {
TxApplicantCreate: '' as AnyComponent,
TxApplicantUpdate: '' as AnyComponent
}
})

View File

@ -38,6 +38,7 @@
"@anticrm/chunter":"~0.6.1",
"@anticrm/text-editor":"~0.6.0",
"@anticrm/contact":"~0.6.2",
"@anticrm/view": "~0.6.0"
"@anticrm/view": "~0.6.0",
"@anticrm/view-resources": "~0.6.0"
}
}

View File

@ -74,7 +74,6 @@
client.addCollection(chunter.class.Comment, object.space, object._id, object._class, 'comments', {
message: event.detail
})
console.log(event.detail)
}
let viewlets: Map<ActivityKey, TxViewlet>

View File

@ -15,21 +15,35 @@
-->
<script lang="ts">
import type { TxViewlet } from '@anticrm/activity'
import contact, { EmployeeAccount, formatName } from '@anticrm/contact'
import type { AttachedDoc, Doc, Ref, Tx, TxCollectionCUD, TxCUD, TxUpdateDoc } from '@anticrm/core'
import core from '@anticrm/core'
import { getResource } from '@anticrm/platform'
import { getClient } from '@anticrm/presentation'
import { Component, Icon, Label, TimeSince } from '@anticrm/ui'
import type { AttributeModel } from '@anticrm/view'
import view, { BuildModelOptions } from '@anticrm/view'
import { activityKey, ActivityKey } from '../utils'
import activity from '@anticrm/activity'
import contact, { EmployeeAccount, formatName } from '@anticrm/contact'
import core, {
AttachedDoc,
Doc,
Ref,
Tx,
TxCollectionCUD,
TxCreateDoc,
TxCUD,
TxProcessor,
TxUpdateDoc
} from '@anticrm/core'
import { IntlString } from '@anticrm/platform'
import { getClient } from '@anticrm/presentation'
import { AnyComponent, AnySvelteComponent, Component, Icon, Label, TimeSince } from '@anticrm/ui'
import type { AttributeModel } from '@anticrm/view'
import { buildModel, getObjectPresenter } from '@anticrm/view-resources'
import { activityKey, ActivityKey } from '../utils'
export let tx: Tx
export let viewlets: Map<ActivityKey, TxViewlet>
let viewlet: TxViewlet | undefined
type TxDisplayViewlet =
| (Pick<TxViewlet, 'icon' | 'label' | 'display'> & { component?: AnyComponent | AnySvelteComponent })
| undefined
let viewlet: TxDisplayViewlet
let props: any
let displayTx: TxCUD<Doc> | undefined
let utx: TxUpdateDoc<Doc> | undefined
@ -38,17 +52,44 @@
$: if (client.getHierarchy().isDerived(tx._class, core.class.TxCollectionCUD)) {
const colCUD = tx as TxCollectionCUD<Doc, AttachedDoc>
displayTx = colCUD.tx
viewlet = undefined
} else if (client.getHierarchy().isDerived(tx._class, core.class.TxCUD)) {
displayTx = tx as TxCUD<Doc>
}
$: if (displayTx !== undefined) {
const key = activityKey(displayTx.objectClass, displayTx._class)
viewlet = viewlets.get(key)
} else {
viewlet = undefined
}
async function updateViewlet (displayTx?: TxCUD<Doc>): Promise<TxDisplayViewlet> {
if (displayTx === undefined) {
return undefined
}
const key = activityKey(displayTx.objectClass, displayTx._class)
let viewlet: TxDisplayViewlet = viewlets.get(key)
props = { tx: displayTx }
if (viewlet === undefined && displayTx._class === core.class.TxCreateDoc) {
// Check if we have a class presenter we could have a pseudo viewlet based on class presenter.
const doc = TxProcessor.createDoc2Doc(displayTx as TxCreateDoc<Doc>)
const docClass = client.getModel().getObject(doc._class)
const presenter = await getObjectPresenter(client, doc._class, 'doc-presenter')
if (presenter !== undefined) {
viewlet = {
display: 'inline',
icon: docClass.icon ?? activity.icon.Activity,
label: ('created ' + docClass.label) as IntlString,
component: presenter.presenter
}
props = { value: doc }
}
}
return viewlet
}
$: updateViewlet(displayTx).then((result) => {
viewlet = result
})
let employee: EmployeeAccount | undefined
$: client.findOne(contact.class.EmployeeAccount, { _id: tx.modifiedBy as Ref<EmployeeAccount> }).then((account) => {
employee = account
@ -56,16 +97,11 @@
let model: AttributeModel[] = []
let buildModel: ((options: BuildModelOptions) => Promise<AttributeModel[]>) | undefined
getResource(view.api.buildModel).then((bm) => {
buildModel = bm
})
$: if (displayTx !== undefined && displayTx._class === core.class.TxUpdateDoc) {
utx = displayTx as TxUpdateDoc<Doc>
const ops = { client, _class: utx.objectClass, keys: Object.keys(utx.operations), ignoreMissing: true }
model = []
buildModel?.(ops).then((m) => {
buildModel(ops).then((m) => {
model = m
})
} else {
@ -98,7 +134,7 @@
No employee
{/if}
</b>
{#if viewlet}
{#if viewlet && viewlet.label}
<Label label={viewlet.label} />
{/if}
{#if viewlet === undefined && model.length > 0 && utx}
@ -107,14 +143,22 @@
<strong><svelte:component this={m.presenter} value={getValue(utx, m.key)} /></strong>
{/each}
{:else if viewlet && viewlet.display === 'inline' && viewlet.component}
<Component is={viewlet.component} props={{ tx: displayTx }} />
{#if typeof viewlet.component === 'string'}
<Component is={viewlet.component} {props} />
{:else}
<svelte:component this={viewlet.component} {...props} />
{/if}
{/if}
</div>
<div class="content-trans-color"><TimeSince value={tx.modifiedOn} /></div>
</div>
{#if viewlet && viewlet.component && viewlet.display !== 'inline'}
<div class="content" class:emphasize={viewlet.display === 'emphasized'}>
<Component is={viewlet.component} props={{ tx: displayTx }} />
{#if typeof viewlet.component === 'string'}
<Component is={viewlet.component} {props} />
{:else}
<svelte:component this={viewlet.component} {...props} />
{/if}
</div>
{/if}
</div>

View File

@ -32,7 +32,7 @@ export interface TxViewlet extends Doc {
match?: DocumentQuery<Tx>
// Label will be displayed right after author
label: IntlString
label?: IntlString
// Do component need to be emphasized or not.
display: 'inline' | 'content' | 'emphasized'
}

View File

@ -6,9 +6,6 @@
"VacancyDescription": "Vacancy Description",
"CreateVacancy": "Create Vacancy",
"CreateCandidate": "Create Candidate",
"MakePrivate": "Make Private",
"TxApplicantCreate": "created application",
"TxApplicantUpdate": "",
"TxCandidateCreate": "created candidate"
"MakePrivate": "Make Private"
}
}

View File

@ -1,25 +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 { Applicant } from '@anticrm/recruit'
import type { TxCreateDoc } from '@anticrm/core'
import { TxProcessor } from '@anticrm/core'
import ApplicationPresenter from '../ApplicationPresenter.svelte'
export let tx: TxCreateDoc<Applicant>
</script>
<ApplicationPresenter value={TxProcessor.createDoc2Doc(tx)}/>

View File

@ -25,7 +25,6 @@ import KanbanCard from './components/KanbanCard.svelte'
import ApplicationPresenter from './components/ApplicationPresenter.svelte'
import ApplicationsPresenter from './components/ApplicationsPresenter.svelte'
import TxApplicantCreate from './components/activity/TxApplicantCreate.svelte'
import TxApplicantUpdate from './components/activity/TxApplicantUpdate.svelte'
import { showPopup } from '@anticrm/ui'
@ -51,7 +50,6 @@ export default async (): Promise<Resources> => ({
ApplicationsPresenter
},
activity: {
TxApplicantCreate,
TxApplicantUpdate
}
})

View File

@ -30,7 +30,7 @@ import { showPopup } from '@anticrm/ui'
import {buildModel} from './utils'
export { Table }
export { buildModel } from './utils'
export { buildModel, getObjectPresenter } from './utils'
function Delete(object: Doc): void {
showPopup(MessageBox, {
@ -57,8 +57,5 @@ export default async () => ({
TableView,
KanbanView,
TimestampPresenter
},
api: {
buildModel
}
})

View File

@ -22,7 +22,10 @@ import type { Action, ActionTarget, BuildModelOptions } from '@anticrm/view'
import view, { AttributeModel } from '@anticrm/view'
async function getObjectPresenter(client: Client, _class: Ref<Class<Obj>>, preserveKey: string): Promise<AttributeModel> {
/**
* @public
*/
export async function getObjectPresenter(client: Client, _class: Ref<Class<Obj>>, preserveKey: string): Promise<AttributeModel> {
const clazz = client.getHierarchy().getClass(_class)
const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter)
if (presenterMixin.presenter === undefined) {

View File

@ -148,8 +148,5 @@ export default plugin(viewId, {
icon: {
Table: '' as Asset,
Kanban: '' as Asset
},
api: {
buildModel: '' as Resource<(options: BuildModelOptions) => Promise<AttributeModel[]>>
}
})

File diff suppressed because it is too large Load Diff