mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 00:10:37 +00:00
Allow to create customer for Organization (#1696)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
6c8afa1fda
commit
9266a61c98
@ -149,10 +149,11 @@ export function createModel (builder: Builder): void {
|
|||||||
descriptor: view.viewlet.Table,
|
descriptor: view.viewlet.Table,
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
options: {
|
options: {
|
||||||
lookup: { _id: { channels: contact.class.Channel } }
|
lookup: { _id: { channels: contact.class.Channel }, _class: core.class.Class }
|
||||||
},
|
},
|
||||||
config: [
|
config: [
|
||||||
'',
|
'',
|
||||||
|
'$lookup._class.label',
|
||||||
'city',
|
'city',
|
||||||
{
|
{
|
||||||
presenter: attachment.component.AttachmentsPresenter,
|
presenter: attachment.component.AttachmentsPresenter,
|
||||||
|
@ -20,7 +20,7 @@ import type { Customer, Funnel, Lead } from '@anticrm/lead'
|
|||||||
import { Builder, Collection, Index, Mixin, Model, Prop, TypeRef, TypeString, UX } from '@anticrm/model'
|
import { Builder, Collection, Index, Mixin, Model, Prop, TypeRef, TypeString, UX } from '@anticrm/model'
|
||||||
import attachment from '@anticrm/model-attachment'
|
import attachment from '@anticrm/model-attachment'
|
||||||
import chunter from '@anticrm/model-chunter'
|
import chunter from '@anticrm/model-chunter'
|
||||||
import contact, { TPerson } from '@anticrm/model-contact'
|
import contact, { TContact } from '@anticrm/model-contact'
|
||||||
import core from '@anticrm/model-core'
|
import core from '@anticrm/model-core'
|
||||||
import task, { TSpaceWithStates, TTask } from '@anticrm/model-task'
|
import task, { TSpaceWithStates, TTask } from '@anticrm/model-task'
|
||||||
import view, { createAction } from '@anticrm/model-view'
|
import view, { createAction } from '@anticrm/model-view'
|
||||||
@ -53,7 +53,7 @@ export class TLead extends TTask implements Lead {
|
|||||||
|
|
||||||
@Mixin(lead.mixin.Customer, contact.class.Contact)
|
@Mixin(lead.mixin.Customer, contact.class.Contact)
|
||||||
@UX(lead.string.Customer, lead.icon.LeadApplication)
|
@UX(lead.string.Customer, lead.icon.LeadApplication)
|
||||||
export class TCustomer extends TPerson implements Customer {
|
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
|
||||||
|
|
||||||
@ -112,7 +112,8 @@ export function createModel (builder: Builder): void {
|
|||||||
createComponent: lead.component.CreateFunnel
|
createComponent: lead.component.CreateFunnel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
navHeaderComponent: lead.component.NewItemsHeader
|
||||||
},
|
},
|
||||||
lead.app.Lead
|
lead.app.Lead
|
||||||
)
|
)
|
||||||
@ -122,10 +123,11 @@ export function createModel (builder: Builder): void {
|
|||||||
descriptor: view.viewlet.Table,
|
descriptor: view.viewlet.Table,
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
options: {
|
options: {
|
||||||
lookup: { _id: { channels: contact.class.Channel } } as any
|
lookup: { _id: { channels: contact.class.Channel }, _class: core.class.Class }
|
||||||
} as FindOptions<Doc>, // TODO: fix
|
} as FindOptions<Doc>, // TODO: fix
|
||||||
config: [
|
config: [
|
||||||
'',
|
'',
|
||||||
|
'$lookup._class.label',
|
||||||
{ key: 'leads', presenter: lead.component.LeadsPresenter, label: lead.string.Leads },
|
{ key: 'leads', presenter: lead.component.LeadsPresenter, label: lead.string.Leads },
|
||||||
'modifiedOn',
|
'modifiedOn',
|
||||||
'$lookup.channels'
|
'$lookup.channels'
|
||||||
|
@ -42,7 +42,8 @@ export default mergeIds(leadId, lead, {
|
|||||||
LeadPresenter: '' as AnyComponent,
|
LeadPresenter: '' as AnyComponent,
|
||||||
TemplatesIcon: '' as AnyComponent,
|
TemplatesIcon: '' as AnyComponent,
|
||||||
Customers: '' as AnyComponent,
|
Customers: '' as AnyComponent,
|
||||||
Leads: '' as AnyComponent
|
Leads: '' as AnyComponent,
|
||||||
|
NewItemsHeader: '' as AnyComponent
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
DefaultFunnel: '' as Ref<Space>
|
DefaultFunnel: '' as Ref<Space>
|
||||||
|
@ -41,10 +41,10 @@
|
|||||||
<form class="antiCard dialog" on:submit|preventDefault={() => {}}>
|
<form class="antiCard dialog" on:submit|preventDefault={() => {}}>
|
||||||
<div class="antiCard-header">
|
<div class="antiCard-header">
|
||||||
<div class="antiCard-header__title-wrap">
|
<div class="antiCard-header__title-wrap">
|
||||||
{#if spaceClass && spaceLabel && spacePlaceholder}
|
{#if (spaceClass && spaceLabel && spacePlaceholder) || $$slots.space}
|
||||||
{#if $$slots.space}
|
{#if $$slots.space}
|
||||||
<slot name="space" />
|
<slot name="space" />
|
||||||
{:else}
|
{:else if spaceClass && spaceLabel && spacePlaceholder}
|
||||||
<SpaceSelect _class={spaceClass} {spaceQuery} label={spaceLabel} bind:value={space} />
|
<SpaceSelect _class={spaceClass} {spaceQuery} label={spaceLabel} bind:value={space} />
|
||||||
{/if}
|
{/if}
|
||||||
<span class="antiCard-header__divider">›</span>
|
<span class="antiCard-header__divider">›</span>
|
||||||
@ -78,7 +78,9 @@
|
|||||||
kind={'primary'}
|
kind={'primary'}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
okAction()
|
okAction()
|
||||||
dispatch('close')
|
if (!createMore) {
|
||||||
|
dispatch('close')
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: stretch;
|
justify-content: stretch;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
margin: .5rem .75rem .75rem;
|
margin: .5rem 0.5rem .75rem 1rem;
|
||||||
}
|
}
|
||||||
.antiNav-element {
|
.antiNav-element {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
@ -9,4 +9,10 @@
|
|||||||
<symbol id="lead" viewBox="0 0 16 16">
|
<symbol id="lead" viewBox="0 0 16 16">
|
||||||
<path d="M13.2,9.4h-2.8l0.3-2.7h2.5c0.3,0,0.5-0.2,0.5-0.5s-0.2-0.5-0.5-0.5h-2.4l0.4-3.2c0-0.3-0.2-0.5-0.4-0.6 c-0.3,0-0.5,0.2-0.6,0.4L9.8,5.6H7.1l0.4-3.2c0-0.3-0.2-0.5-0.4-0.6c-0.3,0-0.5,0.2-0.6,0.4L6.1,5.6H3.2c-0.3,0-0.5,0.2-0.5,0.5 s0.2,0.5,0.5,0.5h2.8L5.6,9.4H3.2c-0.3,0-0.5,0.2-0.5,0.5s0.2,0.5,0.5,0.5h2.4l-0.4,3.2c0,0.3,0.2,0.5,0.4,0.6c0,0,0,0,0.1,0 c0.3,0,0.5-0.2,0.5-0.4l0.4-3.3h2.7l-0.4,3.2c0,0.3,0.2,0.5,0.4,0.6c0,0,0,0,0.1,0c0.3,0,0.5-0.2,0.5-0.4l0.4-3.3h2.9 c0.3,0,0.5-0.2,0.5-0.5S13.4,9.4,13.2,9.4z M6.6,9.4l0.3-2.7h2.7L9.4,9.4H6.6z"/>
|
<path d="M13.2,9.4h-2.8l0.3-2.7h2.5c0.3,0,0.5-0.2,0.5-0.5s-0.2-0.5-0.5-0.5h-2.4l0.4-3.2c0-0.3-0.2-0.5-0.4-0.6 c-0.3,0-0.5,0.2-0.6,0.4L9.8,5.6H7.1l0.4-3.2c0-0.3-0.2-0.5-0.4-0.6c-0.3,0-0.5,0.2-0.6,0.4L6.1,5.6H3.2c-0.3,0-0.5,0.2-0.5,0.5 s0.2,0.5,0.5,0.5h2.8L5.6,9.4H3.2c-0.3,0-0.5,0.2-0.5,0.5s0.2,0.5,0.5,0.5h2.4l-0.4,3.2c0,0.3,0.2,0.5,0.4,0.6c0,0,0,0,0.1,0 c0.3,0,0.5-0.2,0.5-0.4l0.4-3.3h2.7l-0.4,3.2c0,0.3,0.2,0.5,0.4,0.6c0,0,0,0,0.1,0c0.3,0,0.5-0.2,0.5-0.4l0.4-3.3h2.9 c0.3,0,0.5-0.2,0.5-0.5S13.4,9.4,13.2,9.4z M6.6,9.4l0.3-2.7h2.7L9.4,9.4H6.6z"/>
|
||||||
</symbol>
|
</symbol>
|
||||||
|
<symbol id="new-customer" viewBox="0 0 16 16">
|
||||||
|
<path d="M14.7826 3.26359C15.1313 2.69123 15.0606 1.93115 14.5705 1.43492C14.0757 0.933932 13.3153 0.865765 12.7483 1.23041C13.2123 2.09277 13.9198 2.79999 14.7826 3.26359Z"/>
|
||||||
|
<path d="M11.8171 2.11829L6.78472 7.18C7.77457 7.47517 8.57699 8.21908 8.95006 9.18198L13.9064 4.20208C13.0535 3.68436 12.3369 2.9696 11.8171 2.11829Z"/>
|
||||||
|
<path d="M7.91486 10.1761C7.80538 9.1186 6.91913 8.30487 5.8592 8.29183C5.53827 8.92804 5.21105 9.90848 5.01729 10.5311C4.93355 10.8002 5.16675 11.0527 5.44262 10.9905C6.16831 10.8268 7.36057 10.5217 7.91486 10.1761Z"/>
|
||||||
|
<path d="M4.75 2C2.67893 2 1 3.67893 1 5.75V11.25C1 13.3211 2.67893 15 4.75 15H10.2501C12.3212 15 14.0001 13.3211 14.0001 11.25V8C14.0001 7.58579 13.6643 7.25 13.2501 7.25C12.8359 7.25 12.5001 7.58579 12.5001 8V11.25C12.5001 12.4926 11.4927 13.5 10.2501 13.5H4.75C3.50736 13.5 2.5 12.4926 2.5 11.25V5.75C2.5 4.50736 3.50736 3.5 4.75 3.5H7C7.41421 3.5 7.75 3.16421 7.75 2.75C7.75 2.33579 7.41421 2 7 2H4.75Z"/>
|
||||||
|
</symbol>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.9 KiB |
@ -21,7 +21,8 @@ const icons = require('../assets/icons.svg') as string // eslint-disable-line
|
|||||||
loadMetadata(lead.icon, {
|
loadMetadata(lead.icon, {
|
||||||
Funnel: `${icons}#funnel`,
|
Funnel: `${icons}#funnel`,
|
||||||
Lead: `${icons}#lead`,
|
Lead: `${icons}#lead`,
|
||||||
LeadApplication: `${icons}#leadapplication`
|
LeadApplication: `${icons}#leadapplication`,
|
||||||
|
CreateCustomer: `${icons}#new-customer`
|
||||||
})
|
})
|
||||||
|
|
||||||
addStringsLoader(leadId, async (lang: string) => await import(`../lang/${lang}.json`))
|
addStringsLoader(leadId, async (lang: string) => await import(`../lang/${lang}.json`))
|
||||||
|
@ -14,53 +14,58 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import attachment from '@anticrm/attachment'
|
import attachment from '@anticrm/attachment'
|
||||||
import { Channel, combineName, findPerson, Person } from '@anticrm/contact'
|
import { Channel, combineName, Contact, findPerson } from '@anticrm/contact'
|
||||||
import { ChannelsDropdown } from '@anticrm/contact-resources'
|
import { ChannelsDropdown } from '@anticrm/contact-resources'
|
||||||
import PersonPresenter from '@anticrm/contact-resources/src/components/PersonPresenter.svelte'
|
import PersonPresenter from '@anticrm/contact-resources/src/components/PersonPresenter.svelte'
|
||||||
import contact from '@anticrm/contact-resources/src/plugin'
|
import contact from '@anticrm/contact-resources/src/plugin'
|
||||||
import { AttachedData, Data, generateId, MixinData, Ref } from '@anticrm/core'
|
import { AttachedData, Class, Data, Doc, generateId, MixinData, Ref } from '@anticrm/core'
|
||||||
import type { Customer } from '@anticrm/lead'
|
import type { Customer } from '@anticrm/lead'
|
||||||
import { getResource } from '@anticrm/platform'
|
import { getResource } from '@anticrm/platform'
|
||||||
import { Card, EditableAvatar, getClient } from '@anticrm/presentation'
|
import { Card, EditableAvatar, getClient } from '@anticrm/presentation'
|
||||||
import { EditBox, IconInfo, Label } from '@anticrm/ui'
|
import { Button, EditBox, eventToHTMLElement, IconInfo, Label, SelectPopup, showPopup } from '@anticrm/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import lead from '../plugin'
|
import lead from '../plugin'
|
||||||
|
|
||||||
let firstName = ''
|
let firstName = ''
|
||||||
let lastName = ''
|
let lastName = ''
|
||||||
|
let createMore: boolean = false
|
||||||
|
|
||||||
export function canClose (): boolean {
|
export function canClose (): boolean {
|
||||||
return firstName === '' && lastName === ''
|
return firstName === '' && lastName === ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const object: Customer = {
|
let object: Customer = {
|
||||||
_class: contact.class.Person
|
_class: contact.class.Person
|
||||||
} as Customer
|
} as Customer
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const customerId = generateId()
|
let customerId = generateId()
|
||||||
|
|
||||||
let channels: AttachedData<Channel>[] = []
|
let channels: AttachedData<Channel>[] = []
|
||||||
let avatar: File | undefined
|
let avatar: File | undefined
|
||||||
|
|
||||||
|
function formatName (targetClass: Ref<Class<Doc>>, firstName: string, lastName: string, objectName: string): string {
|
||||||
|
return targetClass === contact.class.Person ? combineName(firstName, lastName) : objectName
|
||||||
|
}
|
||||||
|
|
||||||
async function createCustomer () {
|
async function createCustomer () {
|
||||||
const candidate: Data<Person> = {
|
const candidate: Data<Contact> = {
|
||||||
name: combineName(firstName, lastName),
|
name: formatName(targetClass._id, firstName, lastName, object.name),
|
||||||
city: object.city
|
city: object.city
|
||||||
}
|
}
|
||||||
if (avatar !== undefined) {
|
if (avatar !== undefined) {
|
||||||
const uploadFile = await getResource(attachment.helper.UploadFile)
|
const uploadFile = await getResource(attachment.helper.UploadFile)
|
||||||
candidate.avatar = await uploadFile(avatar)
|
candidate.avatar = await uploadFile(avatar)
|
||||||
}
|
}
|
||||||
const candidateData: MixinData<Person, Customer> = {
|
const candidateData: MixinData<Contact, Customer> = {
|
||||||
description: object.description
|
description: object.description
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = await client.createDoc(contact.class.Person, contact.space.Contacts, candidate, customerId)
|
const id = await client.createDoc(targetClass._id, contact.space.Contacts, candidate, customerId)
|
||||||
await client.createMixin(
|
await client.createMixin(
|
||||||
id as Ref<Person>,
|
id as Ref<Contact>,
|
||||||
contact.class.Person,
|
targetClass._id,
|
||||||
contact.space.Contacts,
|
contact.space.Contacts,
|
||||||
lead.mixin.Customer,
|
lead.mixin.Customer,
|
||||||
candidateData
|
candidateData
|
||||||
@ -71,7 +76,7 @@
|
|||||||
contact.class.Channel,
|
contact.class.Channel,
|
||||||
contact.space.Contacts,
|
contact.space.Contacts,
|
||||||
customerId,
|
customerId,
|
||||||
contact.class.Person,
|
targetClass._id,
|
||||||
'channels',
|
'channels',
|
||||||
{
|
{
|
||||||
value: channel.value,
|
value: channel.value,
|
||||||
@ -80,7 +85,17 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch('close')
|
if (createMore) {
|
||||||
|
// Prepare for next
|
||||||
|
object = {
|
||||||
|
_class: targetClass._id
|
||||||
|
} as Customer
|
||||||
|
customerId = generateId()
|
||||||
|
avatar = undefined
|
||||||
|
firstName = ''
|
||||||
|
lastName = ''
|
||||||
|
channels = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAvatarDone (e: any) {
|
function onAvatarDone (e: any) {
|
||||||
@ -89,65 +104,127 @@
|
|||||||
avatar = file
|
avatar = file
|
||||||
}
|
}
|
||||||
|
|
||||||
let matches: Person[] = []
|
let matches: Contact[] = []
|
||||||
$: findPerson(client, { ...object, name: combineName(firstName, lastName) }, channels).then((p) => {
|
$: findPerson(
|
||||||
|
client,
|
||||||
|
{ ...object, name: formatName(targetClass._id, firstName, lastName, object.name) },
|
||||||
|
channels
|
||||||
|
).then((p) => {
|
||||||
matches = p
|
matches = p
|
||||||
})
|
})
|
||||||
|
|
||||||
function removeAvatar (): void {
|
function removeAvatar (): void {
|
||||||
avatar = undefined
|
avatar = undefined
|
||||||
}
|
}
|
||||||
|
const targets = [
|
||||||
|
client.getModel().getObject(contact.class.Person),
|
||||||
|
client.getModel().getObject(contact.class.Organization)
|
||||||
|
]
|
||||||
|
let targetClass = targets[0]
|
||||||
|
|
||||||
|
function selectTarget (evt: MouseEvent): void {
|
||||||
|
showPopup(
|
||||||
|
SelectPopup,
|
||||||
|
{
|
||||||
|
value: targets.map((it) => ({ id: it._id, label: it.label, icon: it.icon })),
|
||||||
|
placeholder: contact.string.Contacts,
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
|
eventToHTMLElement(evt),
|
||||||
|
(ref) => {
|
||||||
|
if (ref != null) {
|
||||||
|
const newT = targets.find((it) => it._id === ref)
|
||||||
|
if (newT !== undefined) {
|
||||||
|
if (targetClass._id !== newT._id) {
|
||||||
|
targetClass = newT
|
||||||
|
object.name = ''
|
||||||
|
firstName = ''
|
||||||
|
lastName = ''
|
||||||
|
customerId = generateId()
|
||||||
|
avatar = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
$: canSave = formatName(targetClass._id, firstName, lastName, object.name).length > 0
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card
|
<Card
|
||||||
label={lead.string.CreateCustomer}
|
label={lead.string.CreateCustomer}
|
||||||
okAction={createCustomer}
|
okAction={createCustomer}
|
||||||
canSave={firstName.length > 0 && lastName.length > 0 && matches.length === 0}
|
{canSave}
|
||||||
space={contact.space.Contacts}
|
space={contact.space.Contacts}
|
||||||
on:close={() => {
|
on:close={() => {
|
||||||
dispatch('close')
|
dispatch('close')
|
||||||
}}
|
}}
|
||||||
|
bind:createMore
|
||||||
>
|
>
|
||||||
<div class="flex-between flex-row-top">
|
<svelte:fragment slot="space">
|
||||||
<div class="flex-col flex-grow">
|
<Button
|
||||||
<EditBox
|
icon={targetClass.icon}
|
||||||
placeholder={contact.string.PersonFirstNamePlaceholder}
|
label={targetClass.label}
|
||||||
bind:value={firstName}
|
size={'small'}
|
||||||
kind={'large-style'}
|
kind={'no-border'}
|
||||||
maxWidth={'32rem'}
|
on:click={selectTarget}
|
||||||
focus
|
/>
|
||||||
/>
|
</svelte:fragment>
|
||||||
<EditBox
|
{#if targetClass._id === contact.class.Person}
|
||||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
<div class="flex-between flex-row-top mt-2 mb-2">
|
||||||
bind:value={lastName}
|
<div class="flex-col flex-grow">
|
||||||
kind={'large-style'}
|
|
||||||
maxWidth={'32rem'}
|
|
||||||
/>
|
|
||||||
<div class="mt-1">
|
|
||||||
<EditBox
|
<EditBox
|
||||||
placeholder={contact.string.PersonLocationPlaceholder}
|
placeholder={contact.string.PersonFirstNamePlaceholder}
|
||||||
bind:value={object.city}
|
bind:value={firstName}
|
||||||
|
kind={'large-style'}
|
||||||
|
maxWidth={'32rem'}
|
||||||
|
focus
|
||||||
|
/>
|
||||||
|
<EditBox
|
||||||
|
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||||
|
bind:value={lastName}
|
||||||
|
kind={'large-style'}
|
||||||
|
maxWidth={'32rem'}
|
||||||
|
/>
|
||||||
|
<div class="mt-1">
|
||||||
|
<EditBox
|
||||||
|
placeholder={contact.string.PersonLocationPlaceholder}
|
||||||
|
bind:value={object.city}
|
||||||
|
kind={'small-style'}
|
||||||
|
maxWidth={'32rem'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<EditBox
|
||||||
|
placeholder={lead.string.IssueDescriptionPlaceholder}
|
||||||
|
bind:value={object.description}
|
||||||
kind={'small-style'}
|
kind={'small-style'}
|
||||||
maxWidth={'32rem'}
|
maxWidth={'32rem'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="ml-4 flex">
|
||||||
|
<EditableAvatar
|
||||||
|
bind:direct={avatar}
|
||||||
|
avatar={object.avatar}
|
||||||
|
size={'large'}
|
||||||
|
on:remove={removeAvatar}
|
||||||
|
on:done={onAvatarDone}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="flex-row-center clear-mins mt-2 mb-2">
|
||||||
|
<div class="mr-3">
|
||||||
|
<Button icon={contact.icon.Company} size={'medium'} kind={'link-bordered'} disabled />
|
||||||
|
</div>
|
||||||
<EditBox
|
<EditBox
|
||||||
placeholder={lead.string.IssueDescriptionPlaceholder}
|
placeholder={contact.string.OrganizationNamePlaceholder}
|
||||||
bind:value={object.description}
|
bind:value={object.name}
|
||||||
kind={'small-style'}
|
maxWidth={'37.5rem'}
|
||||||
maxWidth={'32rem'}
|
kind={'large-style'}
|
||||||
|
focus
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex">
|
{/if}
|
||||||
<EditableAvatar
|
|
||||||
bind:direct={avatar}
|
|
||||||
avatar={object.avatar}
|
|
||||||
size={'large'}
|
|
||||||
on:remove={removeAvatar}
|
|
||||||
on:done={onAvatarDone}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<svelte:fragment slot="pool">
|
<svelte:fragment slot="pool">
|
||||||
<ChannelsDropdown bind:value={channels} editable />
|
<ChannelsDropdown bind:value={channels} editable />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Doc, DocumentQuery } from '@anticrm/core'
|
import { Doc, DocumentQuery } from '@anticrm/core'
|
||||||
import { getClient } from '@anticrm/presentation'
|
import { getClient } from '@anticrm/presentation'
|
||||||
import { Button, Icon, IconAdd, Label, Scroller, SearchEdit, showPopup } from '@anticrm/ui'
|
import { Icon, Label, Scroller, SearchEdit } from '@anticrm/ui'
|
||||||
import view, { Viewlet } from '@anticrm/view'
|
import view, { Viewlet } from '@anticrm/view'
|
||||||
import { Table } from '@anticrm/view-resources'
|
import { Table } from '@anticrm/view-resources'
|
||||||
import lead from '../plugin'
|
import lead from '../plugin'
|
||||||
import CreateCustomer from './CreateCustomer.svelte'
|
|
||||||
|
|
||||||
let search = ''
|
let search = ''
|
||||||
let resultQuery: DocumentQuery<Doc> = {}
|
let resultQuery: DocumentQuery<Doc> = {}
|
||||||
@ -34,10 +33,6 @@
|
|||||||
function updateResultQuery (search: string): void {
|
function updateResultQuery (search: string): void {
|
||||||
resultQuery = search === '' ? {} : { $search: search }
|
resultQuery = search === '' ? {} : { $search: search }
|
||||||
}
|
}
|
||||||
|
|
||||||
function showCreateDialog (ev: Event) {
|
|
||||||
showPopup(CreateCustomer, {}, 'top')
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ac-header full">
|
<div class="ac-header full">
|
||||||
@ -52,13 +47,6 @@
|
|||||||
updateResultQuery(search)
|
updateResultQuery(search)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
|
||||||
icon={IconAdd}
|
|
||||||
label={lead.string.CreateCustomerLabel}
|
|
||||||
kind={'primary'}
|
|
||||||
on:click={(ev) => showCreateDialog(ev)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Scroller tableFade>
|
<Scroller tableFade>
|
||||||
|
36
plugins/lead-resources/src/components/NewItemsHeader.svelte
Normal file
36
plugins/lead-resources/src/components/NewItemsHeader.svelte
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2022 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 { Button, showPopup } from '@anticrm/ui'
|
||||||
|
import lead from '../plugin'
|
||||||
|
import CreateCustomer from './CreateCustomer.svelte'
|
||||||
|
|
||||||
|
async function newIssue (): Promise<void> {
|
||||||
|
showPopup(CreateCustomer, {}, 'top')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="antiNav-subheader gap-2">
|
||||||
|
<div class="flex-grow text-md">
|
||||||
|
<Button
|
||||||
|
icon={lead.icon.CreateCustomer}
|
||||||
|
label={lead.string.CreateCustomerLabel}
|
||||||
|
justify={'left'}
|
||||||
|
width={'100%'}
|
||||||
|
on:click={newIssue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- <Button icon={lead.icon.Magnifier} on:click={async () => {}} /> -->
|
||||||
|
</div>
|
@ -25,6 +25,7 @@ import Leads from './components/Leads.svelte'
|
|||||||
import LeadsPresenter from './components/LeadsPresenter.svelte'
|
import LeadsPresenter from './components/LeadsPresenter.svelte'
|
||||||
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
||||||
import CreateCustomer from './components/CreateCustomer.svelte'
|
import CreateCustomer from './components/CreateCustomer.svelte'
|
||||||
|
import NewItemsHeader from './components/NewItemsHeader.svelte'
|
||||||
|
|
||||||
export default async (): Promise<Resources> => ({
|
export default async (): Promise<Resources> => ({
|
||||||
component: {
|
component: {
|
||||||
@ -37,6 +38,7 @@ export default async (): Promise<Resources> => ({
|
|||||||
Customers,
|
Customers,
|
||||||
LeadsPresenter,
|
LeadsPresenter,
|
||||||
Leads,
|
Leads,
|
||||||
CreateCustomer
|
CreateCustomer,
|
||||||
|
NewItemsHeader
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -70,7 +70,8 @@ const lead = plugin(leadId, {
|
|||||||
icon: {
|
icon: {
|
||||||
Funnel: '' as Asset,
|
Funnel: '' as Asset,
|
||||||
Lead: '' as Asset,
|
Lead: '' as Asset,
|
||||||
LeadApplication: '' as Asset
|
LeadApplication: '' as Asset,
|
||||||
|
CreateCustomer: '' as Asset
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
FunnelTemplates: '' as Ref<KanbanTemplateSpace>
|
FunnelTemplates: '' as Ref<KanbanTemplateSpace>
|
||||||
|
Loading…
Reference in New Issue
Block a user