initial state implementation

Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
Andrey Platov 2021-09-05 14:03:33 +02:00
parent 711bfb1ac6
commit b072099c0b
No known key found for this signature in database
GPG Key ID: C8787EFEB4B64AF0
15 changed files with 564 additions and 413 deletions

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
import { Builder } from '@anticrm/model' import { Builder } from '@anticrm/model'
import core from './component' import core from './component'
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString } from './core' import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString } from './core'
import { TSpace, TAccount } from './security' import { TSpace, TAccount, TState } from './security'
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD } from './tx' import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD } from './tx'
export * from './core' export * from './core'
@ -39,6 +39,7 @@ export function createModel (builder: Builder): void {
TAccount, TAccount,
TAttribute, TAttribute,
TType, TType,
TTypeString TTypeString,
TState
) )
} }

View File

@ -13,12 +13,14 @@
// limitations under the License. // limitations under the License.
// //
import type { Account, Arr, Ref, Space } from '@anticrm/core' import type { Account, Arr, Ref, Space, Domain, UXObject } from '@anticrm/core'
import { DOMAIN_MODEL } from '@anticrm/core' import { DOMAIN_MODEL } from '@anticrm/core'
import { Model } from '@anticrm/model' import { Model } from '@anticrm/model'
import core from './component' import core from './component'
import { TDoc } from './core' import { TDoc } from './core'
export const DOMAIN_STATE = 'state' as Domain
// S E C U R I T Y // S E C U R I T Y
@Model(core.class.Space, core.class.Doc, DOMAIN_MODEL) @Model(core.class.Space, core.class.Doc, DOMAIN_MODEL)
@ -33,3 +35,8 @@ export class TSpace extends TDoc implements Space {
export class TAccount extends TDoc implements Account { export class TAccount extends TDoc implements Account {
email!: string email!: string
} }
@Model(core.class.State, core.class.Doc, DOMAIN_STATE)
export class TState extends TDoc implements UXObject {
machine!: Ref<Space>
}

View File

@ -15,7 +15,7 @@
import type { IntlString } from '@anticrm/platform' import type { IntlString } from '@anticrm/platform'
import { Builder, Model, UX, Prop, TypeString } from '@anticrm/model' import { Builder, Model, UX, Prop, TypeString } from '@anticrm/model'
import type { Ref, FindOptions, Doc, Domain } from '@anticrm/core' import type { Ref, FindOptions, Doc, Domain, State } from '@anticrm/core'
import core, { TSpace, TDoc } from '@anticrm/model-core' import core, { TSpace, TDoc } from '@anticrm/model-core'
import type { Vacancy, Candidates, Candidate, Applicant } from '@anticrm/recruit' import type { Vacancy, Candidates, Candidate, Applicant } from '@anticrm/recruit'
import type { Attachment } from '@anticrm/chunter' import type { Attachment } from '@anticrm/chunter'
@ -49,6 +49,9 @@ export class TCandidate extends TPerson implements Candidate {
export class TApplicant extends TDoc implements Applicant { export class TApplicant extends TDoc implements Applicant {
@Prop(TypeString(), 'Candidate' as IntlString) @Prop(TypeString(), 'Candidate' as IntlString)
candidate!: Ref<Person> candidate!: Ref<Person>
@Prop(TypeString(), 'State' as IntlString)
state!: Ref<State>
} }
export function createModel (builder: Builder): void { export function createModel (builder: Builder): void {
@ -115,10 +118,11 @@ export function createModel (builder: Builder): void {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
options: { options: {
lookup: { lookup: {
candidate: recruit.class.Candidate candidate: recruit.class.Candidate,
state: core.class.State
} }
} as FindOptions<Doc>, // TODO: fix } as FindOptions<Doc>, // TODO: fix
config: ['$lookup.candidate', '$lookup.candidate.city', '$lookup.candidate.channels'] config: ['$lookup.candidate', '$lookup.state', '$lookup.candidate.city', '$lookup.candidate.channels']
}) })
} }

View File

@ -58,6 +58,10 @@ export function createModel (builder: Builder): void {
presenter: view.component.StringPresenter presenter: view.component.StringPresenter
}) })
builder.mixin(core.class.State, core.class.Class, view.mixin.AttributePresenter, {
presenter: view.component.StatePresenter
})
builder.createDoc(view.class.ViewletDescriptor, core.space.Model, { builder.createDoc(view.class.ViewletDescriptor, core.space.Model, {
label: 'Table' as IntlString, label: 'Table' as IntlString,
icon: view.icon.Table, icon: view.icon.Table,

View File

@ -21,6 +21,7 @@ export default mergeIds(viewId, view, {
component: { component: {
StringEditor: '' as AnyComponent, StringEditor: '' as AnyComponent,
StringPresenter: '' as AnyComponent, StringPresenter: '' as AnyComponent,
StatePresenter: '' as AnyComponent,
TableView: '' as AnyComponent TableView: '' as AnyComponent
} }

View File

@ -186,3 +186,12 @@ export interface Space extends Doc {
export interface Account extends Doc { export interface Account extends Doc {
email: string email: string
} }
// S T A T E
/**
* @public
*/
export interface State extends Doc, UXObject {
machine: Ref<Space>
}

View File

@ -14,7 +14,7 @@
// //
import type { Plugin, StatusCode } from '@anticrm/platform' import type { Plugin, StatusCode } from '@anticrm/platform'
import { plugin } from '@anticrm/platform' import { plugin } from '@anticrm/platform'
import type { Account, Class, Doc, Obj, Ref, Space, AnyAttribute } from './classes' import type { Account, Class, Doc, Obj, Ref, Space, AnyAttribute, State } from './classes'
import type { Tx, TxCreateDoc, TxCUD, TxMixin, TxRemoveDoc, TxUpdateDoc } from './tx' import type { Tx, TxCreateDoc, TxCUD, TxMixin, TxRemoveDoc, TxUpdateDoc } from './tx'
/** /**
@ -35,7 +35,8 @@ export default plugin(coreId, {
TxUpdateDoc: '' as Ref<Class<TxUpdateDoc<Doc>>>, TxUpdateDoc: '' as Ref<Class<TxUpdateDoc<Doc>>>,
TxRemoveDoc: '' as Ref<Class<TxRemoveDoc<Doc>>>, TxRemoveDoc: '' as Ref<Class<TxRemoveDoc<Doc>>>,
Space: '' as Ref<Class<Space>>, Space: '' as Ref<Class<Space>>,
Account: '' as Ref<Class<Account>> Account: '' as Ref<Class<Account>>,
State: '' as Ref<Class<State>>
}, },
space: { space: {
Tx: '' as Ref<Space>, Tx: '' as Ref<Space>,

View File

@ -25,6 +25,7 @@
import { getClient } from '@anticrm/presentation' import { getClient } from '@anticrm/presentation'
import core from '@anticrm/core'
import recruit from '../plugin' import recruit from '../plugin'
export let space: Ref<Space> export let space: Ref<Space>
@ -35,9 +36,11 @@
const client = getClient() const client = getClient()
function createCandidate() { async function createCandidate() {
client.createDoc(recruit.class.Applicant, space, { const state = client.findOne(core.class.State, { space })
await client.createDoc(recruit.class.Applicant, space, {
candidate, candidate,
state
}) })
dispatch('close') dispatch('close')
} }

View File

@ -31,13 +31,25 @@
const client = getClient() const client = getClient()
function createVacancy() { async function createVacancy() {
client.createDoc(recruit.class.Vacancy, core.space.Model, { const id = await client.createDoc(recruit.class.Vacancy, core.space.Model, {
name, name,
description, description,
private: false, private: false,
members: [] members: []
}) })
await client.createDoc(core.class.State, id, {
machine: id,
label: 'Initial'
})
await client.createDoc(core.class.State, id, {
machine: id,
label: 'Interview'
})
await client.createDoc(core.class.State, id, {
machine: id,
label: 'Final'
})
} }
</script> </script>

View File

@ -15,7 +15,7 @@
import { plugin } from '@anticrm/platform' import { plugin } from '@anticrm/platform'
import type { Plugin, Asset } from '@anticrm/platform' import type { Plugin, Asset } from '@anticrm/platform'
import type { Space, Doc, Ref } from '@anticrm/core' import type { Space, Doc, Ref, State } from '@anticrm/core'
import type { Person } from '@anticrm/contact' import type { Person } from '@anticrm/contact'
import type { Attachment } from '@anticrm/chunter' import type { Attachment } from '@anticrm/chunter'
@ -41,6 +41,7 @@ export interface Candidate extends Person {
*/ */
export interface Applicant extends Doc { export interface Applicant extends Doc {
candidate: Ref<Candidate> candidate: Ref<Candidate>
state: Ref<State>
} }
/** /**

View File

@ -1,20 +1,25 @@
// <!--
// Copyright © 2020, 2021 Anticrm Platform Contributors. // Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc. // Copyright © 2021 Hardcore Engineering Inc.
// //
// Licensed under the Eclipse Public License, Version 2.0 (the "License"); // 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 // 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 // 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 // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// //
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// -->
import type { Doc, UXObject } from './classes' <script lang="ts">
export interface State extends Doc, UXObject { import type { State } from '@anticrm/core'
}
export let value: State
</script>
{value.label}

View File

@ -15,12 +15,14 @@
import StringEditor from './components/StringEditor.svelte' import StringEditor from './components/StringEditor.svelte'
import StringPresenter from './components/StringPresenter.svelte' import StringPresenter from './components/StringPresenter.svelte'
import StatePresenter from './components/StatePresenter.svelte'
import TableView from './components/TableView.svelte' import TableView from './components/TableView.svelte'
export default async () => ({ export default async () => ({
component: { component: {
StringEditor, StringEditor,
StringPresenter, StringPresenter,
StatePresenter,
TableView TableView
}, },
}) })

View File

@ -28,6 +28,7 @@ export interface AttributeModel {
} }
async function getObjectPresenter(client: Client, _class: Ref<Class<Obj>>, preserveKey: string): Promise<AttributeModel> { async function getObjectPresenter(client: Client, _class: Ref<Class<Obj>>, preserveKey: string): Promise<AttributeModel> {
console.log('getting object presenter for class', _class, 'key', preserveKey)
const clazz = client.getHierarchy().getClass(_class) const clazz = client.getHierarchy().getClass(_class)
const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter) const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter)
if (presenterMixin.presenter === undefined) { if (presenterMixin.presenter === undefined) {
@ -45,7 +46,8 @@ async function getObjectPresenter(client: Client, _class: Ref<Class<Obj>>, prese
} as AttributeModel } as AttributeModel
} }
async function getAttributePresenter(client: Client, _class: Ref<Class<Obj>>, key: string, preserveKey: string) { async function getAttributePresenter(client: Client, _class: Ref<Class<Obj>>, key: string, preserveKey: string) {
console.log('getting attribute presenter for class', _class)
const attribute = client.getHierarchy().getAttribute(_class, key) const attribute = client.getHierarchy().getAttribute(_class, key)
const clazz = client.getHierarchy().getClass(attribute.type._class) const clazz = client.getHierarchy().getClass(attribute.type._class)
const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter) const presenterMixin = client.getHierarchy().as(clazz, view.mixin.AttributePresenter)
@ -83,7 +85,8 @@ async function getPresenter(client: Client, _class: Ref<Class<Obj>>, key: string
} }
export async function buildModel(client: Client, _class: Ref<Class<Obj>>, keys: string[], options?: FindOptions<Doc>): Promise<AttributeModel[]> { export async function buildModel(client: Client, _class: Ref<Class<Obj>>, keys: string[], options?: FindOptions<Doc>): Promise<AttributeModel[]> {
console.log('building table model for', _class)
const model = keys.map(key => getPresenter(client, _class, key, key, options)) const model = keys.map(key => getPresenter(client, _class, key, key, options))
console.log(model) console.log(model)
return Promise.all(model) return await Promise.all(model)
} }

File diff suppressed because it is too large Load Diff