UBERF-8058: Fix to allow create customers (#6514)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-09-11 12:00:58 +07:00 committed by GitHub
parent ef5fd3a879
commit e497946805
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 119 additions and 44 deletions

View File

@ -149,7 +149,7 @@ export function createModel (builder: Builder): void {
attachTo: lead.class.Funnel, attachTo: lead.class.Funnel,
descriptor: view.viewlet.Table, descriptor: view.viewlet.Table,
configOptions: { configOptions: {
hiddenKeys: ['identifier', 'name', 'description'], hiddenKeys: ['identifier', 'name', 'customerDescription'],
sortable: true sortable: true
}, },
config: ['', 'members', 'private', 'archived'] config: ['', 'members', 'private', 'archived']

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
// //
import { AccountRole, DOMAIN_TX, TxOperations, type Ref, type Status } from '@hcengineering/core' import { AccountRole, DOMAIN_TX, makeCollaborativeDoc, TxOperations, type Ref, type Status } from '@hcengineering/core'
import { leadId, type Lead } from '@hcengineering/lead' import { leadId, type Lead } from '@hcengineering/lead'
import { import {
tryMigrate, tryMigrate,
@ -25,7 +25,7 @@ import {
} from '@hcengineering/model' } from '@hcengineering/model'
import core, { DOMAIN_SPACE } from '@hcengineering/model-core' import core, { DOMAIN_SPACE } from '@hcengineering/model-core'
import contact from '@hcengineering/model-contact' import contact, { DOMAIN_CONTACT } from '@hcengineering/model-contact'
import task, { DOMAIN_TASK, createSequence, migrateDefaultStatusesBase } from '@hcengineering/model-task' import task, { DOMAIN_TASK, createSequence, migrateDefaultStatusesBase } from '@hcengineering/model-task'
import lead from './plugin' import lead from './plugin'
@ -191,6 +191,60 @@ export const leadOperation: MigrateOperation = {
{ {
state: 'migrateDefaultProjectOwners', state: 'migrateDefaultProjectOwners',
func: migrateDefaultProjectOwners func: migrateDefaultProjectOwners
},
{
state: 'migrate-customer-description',
func: async (client) => {
await client.update(
DOMAIN_CONTACT,
{
[lead.mixin.Customer + '.description']: { $exists: true }
},
{
$rename: {
[lead.mixin.Customer + '.description']: lead.mixin.Customer + '.customerDescription'
}
}
)
const it = await client.traverse(DOMAIN_CONTACT, {
_class: contact.class.Organization,
description: { $exists: false }
})
while (true) {
const docs = await it.next(50)
if (docs == null || docs.length === 0) {
break
}
await client.bulk(
DOMAIN_CONTACT,
docs.map((doc) => ({
filter: { _id: doc._id },
update: { $set: { description: makeCollaborativeDoc(doc._id, 'description') } }
}))
)
}
const it2 = await client.traverse(DOMAIN_CONTACT, { [lead.mixin.Customer + '.customerDescription']: null })
while (true) {
const docs = await it2.next(50)
if (docs == null || docs.length === 0) {
break
}
await client.bulk(
DOMAIN_CONTACT,
docs.map((doc) => ({
filter: { _id: doc._id },
update: {
$set: {
[lead.mixin.Customer + '.customerDescription']: makeCollaborativeDoc(
docs[0]._id,
'customerDescription'
)
}
}
}))
)
}
}
} }
]) ])
}, },

View File

@ -95,9 +95,9 @@ export class TCustomer extends TContact implements Customer {
@Prop(Collection(lead.class.Lead), lead.string.Leads) @Prop(Collection(lead.class.Lead), lead.string.Leads)
leads?: number leads?: number
@Prop(TypeCollaborativeDoc(), core.string.Description) @Prop(TypeCollaborativeDoc(), lead.string.Description)
@Index(IndexKind.FullText) @Index(IndexKind.FullText)
description!: CollaborativeDoc customerDescription!: CollaborativeDoc
} }
@Mixin(lead.mixin.DefaultFunnelTypeData, lead.class.Funnel) @Mixin(lead.mixin.DefaultFunnelTypeData, lead.class.Funnel)

View File

@ -25,7 +25,7 @@
"CreateCustomer": "Create Customer", "CreateCustomer": "Create Customer",
"CreateCustomerLabel": "New Customer", "CreateCustomerLabel": "New Customer",
"NoLeadsForDocument": "No leads for document", "NoLeadsForDocument": "No leads for document",
"Description": "Description", "Description": "Customer Description",
"FullDescription": "Full description", "FullDescription": "Full description",
"FunnelPlaceholder": "The simple funnel", "FunnelPlaceholder": "The simple funnel",
"Members": "Members", "Members": "Members",

View File

@ -22,10 +22,10 @@
"ManageFunnelStatuses": "Gestionar estados del Embudo", "ManageFunnelStatuses": "Gestionar estados del Embudo",
"GotoLeadApplication": "Cambiar a la aplicación de Clientes Potenciales", "GotoLeadApplication": "Cambiar a la aplicación de Clientes Potenciales",
"IssueDescriptionPlaceholder": "Añadir descripción...", "IssueDescriptionPlaceholder": "Añadir descripción...",
"CreateCustomer": "Crear Cliente", "CreateCustomer": "Cliente Cliente",
"CreateCustomerLabel": "Nuevo Cliente", "CreateCustomerLabel": "Nuevo Cliente",
"NoLeadsForDocument": "No hay Clientes Potenciales para el documento", "NoLeadsForDocument": "No hay Clientes Potenciales para el documento",
"Description": "Descripción", "Description": "Customer Descripción",
"FullDescription": "Descripción completa", "FullDescription": "Descripción completa",
"FunnelPlaceholder": "El Embudo simple", "FunnelPlaceholder": "El Embudo simple",
"Members": "Miembros", "Members": "Miembros",

View File

@ -25,7 +25,7 @@
"CreateCustomer": "Créer un client", "CreateCustomer": "Créer un client",
"CreateCustomerLabel": "Nouveau client", "CreateCustomerLabel": "Nouveau client",
"NoLeadsForDocument": "Aucun prospect pour le document", "NoLeadsForDocument": "Aucun prospect pour le document",
"Description": "Description", "Description": "Client Description",
"FullDescription": "Description complète", "FullDescription": "Description complète",
"FunnelPlaceholder": "Le pipeline simple", "FunnelPlaceholder": "Le pipeline simple",
"Members": "Membres", "Members": "Membres",

View File

@ -25,7 +25,7 @@
"CreateCustomer": "Criar Cliente", "CreateCustomer": "Criar Cliente",
"CreateCustomerLabel": "Novo Cliente", "CreateCustomerLabel": "Novo Cliente",
"NoLeadsForDocument": "Sem leads para o documento", "NoLeadsForDocument": "Sem leads para o documento",
"Description": "Descrição", "Description": "Cliente Descrição",
"FullDescription": "Descrição completa", "FullDescription": "Descrição completa",
"FunnelPlaceholder": "O Funil simples", "FunnelPlaceholder": "O Funil simples",
"Members": "Membros", "Members": "Membros",

View File

@ -25,7 +25,7 @@
"CreateCustomer": "Добавить Клиента", "CreateCustomer": "Добавить Клиента",
"CreateCustomerLabel": "Новый Клиент", "CreateCustomerLabel": "Новый Клиент",
"NoLeadsForDocument": "Нет потенциальных клиентов для документа", "NoLeadsForDocument": "Нет потенциальных клиентов для документа",
"Description": "Описание", "Description": "Описание Клиента",
"FullDescription": "Детальное описание", "FullDescription": "Детальное описание",
"FunnelPlaceholder": "Простая воронка", "FunnelPlaceholder": "Простая воронка",
"Members": "Пользователи", "Members": "Пользователи",

View File

@ -25,7 +25,7 @@
"CreateCustomer": "创建客户", "CreateCustomer": "创建客户",
"CreateCustomerLabel": "新客户", "CreateCustomerLabel": "新客户",
"NoLeadsForDocument": "此文档没有潜在客户", "NoLeadsForDocument": "此文档没有潜在客户",
"Description": "描述", "Description": "客户描述",
"FullDescription": "完整描述", "FullDescription": "完整描述",
"FunnelPlaceholder": "简单漏斗", "FunnelPlaceholder": "简单漏斗",
"Members": "成员", "Members": "成员",

View File

@ -55,6 +55,7 @@
"@hcengineering/task-resources": "^0.6.0", "@hcengineering/task-resources": "^0.6.0",
"@hcengineering/tracker": "^0.6.24", "@hcengineering/tracker": "^0.6.24",
"@hcengineering/text-editor-resources": "^0.6.0", "@hcengineering/text-editor-resources": "^0.6.0",
"@hcengineering/text": "^0.6.5",
"@hcengineering/ui": "^0.6.15", "@hcengineering/ui": "^0.6.15",
"@hcengineering/view": "^0.6.13", "@hcengineering/view": "^0.6.13",
"@hcengineering/view-resources": "^0.6.0", "@hcengineering/view-resources": "^0.6.0",

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { AvatarType, Channel, combineName, Contact, findContacts } from '@hcengineering/contact' import { AvatarType, Channel, combineName, Contact, findContacts, type Organization } from '@hcengineering/contact'
import { ChannelsDropdown, EditableAvatar, PersonPresenter } from '@hcengineering/contact-resources' import { ChannelsDropdown, EditableAvatar, PersonPresenter } from '@hcengineering/contact-resources'
import contact from '@hcengineering/contact-resources/src/plugin' import contact from '@hcengineering/contact-resources/src/plugin'
import { import {
@ -29,7 +29,8 @@
} from '@hcengineering/core' } from '@hcengineering/core'
import { Customer, LeadEvents } from '@hcengineering/lead' import { Customer, LeadEvents } from '@hcengineering/lead'
import { Card, getClient, InlineAttributeBar, updateMarkup } from '@hcengineering/presentation' import { Card, getClient, InlineAttributeBar, updateMarkup } from '@hcengineering/presentation'
import { EmptyMarkup, StyledTextBox } from '@hcengineering/text-editor-resources' import { StyledTextBox } from '@hcengineering/text-editor-resources'
import { EmptyMarkup } from '@hcengineering/text'
import { import {
Button, Button,
createFocusManager, createFocusManager,
@ -82,11 +83,16 @@
candidate.avatarType = info.avatarType candidate.avatarType = info.avatarType
candidate.avatarProps = info.avatarProps candidate.avatarProps = info.avatarProps
} }
const candidateData: MixinData<Contact, Customer> = {
description: makeCollaborativeDoc(customerId, 'description') if (client.getHierarchy().isDerived(targetClass._id, contact.class.Organization)) {
;(candidate as Organization).description = makeCollaborativeDoc(customerId, 'description')
} }
await updateMarkup(candidateData.description, { description }) const candidateData: MixinData<Contact, Customer> = {
customerDescription: makeCollaborativeDoc(customerId, 'customerDescription')
}
await updateMarkup(candidateData.customerDescription, { customerDescription: description })
const id = await client.createDoc(targetClass._id, contact.space.Contacts, { ...candidate, ...object }, customerId) const id = await client.createDoc(targetClass._id, contact.space.Contacts, { ...candidate, ...object }, customerId)
await client.createMixin( await client.createMixin(
@ -232,6 +238,18 @@
focusIndex={1} focusIndex={1}
/> />
</div> </div>
<div class="flex-col flex-grow">
<div class="mt-1">
<StyledTextBox
bind:content={description}
placeholder={lead.string.IssueDescriptionPlaceholder}
kind={'normal'}
alwaysEdit={true}
showButtons={false}
focusIndex={4}
/>
</div>
</div>
{/if} {/if}
<svelte:fragment slot="pool"> <svelte:fragment slot="pool">
<ChannelsDropdown <ChannelsDropdown

View File

@ -36,7 +36,7 @@ export interface Funnel extends Project {
export interface Customer extends Contact { export interface Customer extends Contact {
leads?: number leads?: number
description: CollaborativeDoc customerDescription: CollaborativeDoc
} }
/** /**

View File

@ -88,29 +88,31 @@
] ]
</script> </script>
<CollaborativeTextEditor {#if collaborativeDoc != null}
bind:this={editor} <CollaborativeTextEditor
{collaborativeDoc} bind:this={editor}
objectId={object._id} {collaborativeDoc}
objectClass={key.attr.attributeOf} objectId={object._id}
objectSpace={object.space} objectClass={key.attr.attributeOf}
objectAttr={key.key} objectSpace={object.space}
{user} objectAttr={key.key}
{userComponent} {user}
{refActions} {userComponent}
{extensions} {refActions}
{attachFile} {extensions}
{placeholder} {attachFile}
{boundary} {placeholder}
{readonly} {boundary}
field={key.key} {readonly}
canEmbedFiles={false} field={key.key}
withSideMenu={false} canEmbedFiles={false}
kitOptions={{ withSideMenu={false}
note: false kitOptions={{
}} note: false
on:focus }}
on:blur on:focus
on:update on:blur
on:open-document on:update
/> on:open-document
/>
{/if}