Fix release issues (#2146)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2022-06-27 13:36:27 +07:00 committed by GitHub
parent 6f0bd0a6fe
commit faaad5bd6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 159 additions and 28 deletions

View File

@ -1,6 +1,12 @@
# Changelog
## 0.6.29 (upcoming)
## 0.6.30 (upcoming)
HR:
- Allow to change assignee in Kanban
## 0.6.29
Platform:

View File

@ -25,7 +25,6 @@ export default mergeIds(contactId, contact, {
component: {
PersonPresenter: '' as AnyComponent,
ContactPresenter: '' as AnyComponent,
ChannelsPresenter: '' as AnyComponent,
EditPerson: '' as AnyComponent,
EditOrganization: '' as AnyComponent,
CreatePersons: '' as AnyComponent,

View File

@ -334,7 +334,14 @@ export function createModel (builder: Builder): void {
)
const applicantKanbanLookup: Lookup<Applicant> = {
attachedTo: recruit.mixin.Candidate,
attachedTo: [
recruit.mixin.Candidate,
{
_id: {
channels: contact.class.Channel
}
}
],
assignee: contact.class.Employee,
_id: {
todoItems: task.class.TodoItem

View File

@ -294,6 +294,10 @@ input.search {
grid-template-columns: repeat(4, min-content);
grid-auto-flow: row;
}
&.tiny {
grid-template-columns: repeat(2, min-content);
grid-auto-flow: row;
}
}
.buttons-divider {
min-width: 1px;

View File

@ -42,7 +42,7 @@
export let editable: boolean | undefined = undefined
export let kind: ButtonKind = 'no-border'
export let size: ButtonSize = 'small'
export let length: 'short' | 'full' = 'full'
export let length: 'tiny' | 'short' | 'full' = 'full'
export let shape: 'circle' | undefined = undefined
export let integrations: Set<Ref<Doc>> = new Set<Ref<Doc>>()
export let focusIndex = -1
@ -221,6 +221,7 @@
? 'xsmall-gap'
: 'xxsmall-gap'}"
class:short={displayItems.length > 4 && length === 'short'}
class:tiny={displayItems.length > 2 && length === 'tiny'}
>
{#each displayItems as item, i}
<Button

View File

@ -25,7 +25,7 @@
export let editable: boolean | undefined = undefined
export let kind: ButtonKind = 'link-bordered'
export let size: ButtonSize = 'small'
export let length: 'short' | 'full' = 'short'
export let length: 'tiny' | 'short' | 'full' = 'short'
export let shape: 'circle' | undefined = 'circle'
export let object: Doc

View File

@ -171,7 +171,8 @@ const contactPlugin = plugin(contactId, {
component: {
SocialEditor: '' as AnyComponent,
CreateOrganization: '' as AnyComponent,
CreatePerson: '' as AnyComponent
CreatePerson: '' as AnyComponent,
ChannelsPresenter: '' as AnyComponent
},
channelProvider: {
Email: '' as Ref<ChannelProvider>,

View File

@ -15,12 +15,13 @@
<script lang="ts">
import { AttachmentsPresenter } from '@anticrm/attachment-resources'
import { CommentsPresenter } from '@anticrm/chunter-resources'
import { formatName } from '@anticrm/contact'
import contact, { formatName } from '@anticrm/contact'
import type { WithLookup } from '@anticrm/core'
import notification from '@anticrm/notification'
import { Avatar } from '@anticrm/presentation'
import type { Applicant } from '@anticrm/recruit'
import type { Applicant, Candidate } from '@anticrm/recruit'
import task, { TodoItem } from '@anticrm/task'
import { AssigneePresenter } from '@anticrm/task-resources'
import { Component, showPanel, Tooltip } from '@anticrm/ui'
import view from '@anticrm/view'
import ApplicationPresenter from './ApplicationPresenter.svelte'
@ -29,19 +30,21 @@
export let dragged: boolean
function showCandidate () {
showPanel(view.component.EditDoc, object.attachedTo, object.attachedToClass, 'content')
showPanel(view.component.EditDoc, object._id, object._class, 'content')
}
$: todoItems = (object.$lookup?.todoItems as TodoItem[]) ?? []
$: doneTasks = todoItems.filter((it) => it.done)
$: channels = (object.$lookup?.attachedTo as WithLookup<Candidate>)?.$lookup?.channels
</script>
<div class="flex-col pt-2 pb-2 pr-4 pl-4">
<div class="flex-col pt-2 pb-2 pr-4 pl-4 cursor-pointer" on:click={showCandidate}>
<div class="flex-between mb-3">
<div class="flex-row-center">
<Avatar avatar={object.$lookup?.attachedTo?.avatar} size={'medium'} />
<div class="flex-grow flex-col min-w-0 ml-2">
<div class="fs-title over-underline lines-limit-2" on:click={showCandidate}>
<div class="fs-title over-underline lines-limit-2">
{formatName(object.$lookup?.attachedTo?.name ?? '')}
</div>
<div class="text-sm lines-limit-2">{object.$lookup?.attachedTo?.title ?? ''}</div>
@ -54,6 +57,16 @@
</div>
{/if}
</div>
{#if channels && channels.length > 0}
<div class="tool mr-1 flex-row-center">
<div class="step-lr75">
<Component
is={contact.component.ChannelsPresenter}
props={{ value: channels, object: object.$lookup?.attachedTo, length: 'tiny' }}
/>
</div>
</div>
{/if}
</div>
<div class="flex-between">
<div class="flex-row-center">
@ -76,6 +89,11 @@
</div>
{/if}
</div>
<Avatar avatar={object.$lookup?.assignee?.avatar} size={'x-small'} />
<AssigneePresenter
value={object.$lookup?.assignee}
issueId={object._id}
defaultClass={contact.class.Employee}
currentSpace={object.space}
/>
</div>
</div>

View File

@ -0,0 +1,107 @@
<!--
// 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 contact, { Employee } from '@anticrm/contact'
import { Class, Doc, Ref, Space } from '@anticrm/core'
import { Task } from '@anticrm/task'
import { UsersPopup, getClient } from '@anticrm/presentation'
import { AttributeModel } from '@anticrm/view'
import { eventToHTMLElement, showPopup } from '@anticrm/ui'
import { getObjectPresenter } from '@anticrm/view-resources'
import { IntlString } from '@anticrm/platform'
import task from '../plugin'
export let value: Employee | null | undefined
export let issueId: Ref<Task>
export let defaultClass: Ref<Class<Doc>> | undefined = undefined
export let currentSpace: Ref<Space> | undefined = undefined
export let isEditable: boolean = true
export let shouldShowLabel: boolean = false
export let defaultName: IntlString | undefined = undefined
const client = getClient()
let presenter: AttributeModel | undefined
$: if (value || defaultClass) {
if (value) {
getObjectPresenter(client, value._class, { key: '' }).then((p) => {
presenter = p
})
} else if (defaultClass) {
getObjectPresenter(client, defaultClass, { key: '' }).then((p) => {
presenter = p
})
}
}
const handleAssigneeChanged = async (result: Employee | null | undefined) => {
if (!isEditable || result === undefined) {
return
}
const currentIssue = await client.findOne(task.class.Task, { space: currentSpace, _id: issueId })
if (currentIssue === undefined) {
return
}
const newAssignee = result === null ? null : result._id
await client.updateCollection(
currentIssue._class,
currentIssue.space,
currentIssue._id,
currentIssue.attachedTo,
currentIssue.attachedToClass,
currentIssue.collection,
{ assignee: newAssignee }
)
}
const handleAssigneeEditorOpened = async (event: MouseEvent) => {
if (!isEditable) {
return
}
event?.preventDefault()
event?.stopPropagation()
showPopup(
UsersPopup,
{
_class: contact.class.Employee,
selected: value?._id,
allowDeselect: true,
placeholder: task.string.AssignThisTask
},
eventToHTMLElement(event),
handleAssigneeChanged
)
}
</script>
{#if presenter}
<svelte:component
this={presenter.presenter}
{value}
{defaultName}
avatarSize={'x-small'}
isInteractive={true}
shouldShowPlaceholder={true}
shouldShowName={shouldShowLabel}
onEmployeeEdit={handleAssigneeEditorOpened}
tooltipLabels={{ personLabel: task.string.TaskAssignee, placeholderLabel: task.string.TaskUnAssign }}
/>
{/if}

View File

@ -38,6 +38,8 @@ import TodoItemsPopup from './components/todos/TodoItemsPopup.svelte'
import Todos from './components/todos/Todos.svelte'
import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte'
export { default as AssigneePresenter } from './components/AssigneePresenter.svelte'
async function editStatuses (object: SpaceWithStates): Promise<void> {
showPopup(EditStatuses, { _id: object._id, spaceClass: object._class }, 'float')
}

View File

@ -174,15 +174,14 @@ async function ShowPopup (
const docs = Array.isArray(doc) ? doc : doc !== undefined ? [doc] : []
const element = await getPopupAlignment(props.element, evt)
evt.preventDefault()
let cprops = {
const cprops = {
...(props?.props ?? {})
}
for (const [docKey, propKey] of Object.entries(props.fillProps ?? {})) {
for (const dv of docs) {
const dvv = (dv as any)[docKey]
if (dvv !== undefined) {
;(cprops as any)[propKey] = { dvv }
;(cprops as any)[propKey] = dvv
}
}
if (docKey === '_object') {
@ -190,19 +189,6 @@ async function ShowPopup (
}
}
if (docs.length > 0) {
cprops = {
...cprops,
...{
[props._id ?? '_id']: docs[0]._id,
[props._class ?? '_class']: docs[0]._class,
[props._space ?? 'space']: docs[0].space,
[props.value ?? 'value']: docs[0],
[props.values ?? 'values']: docs
}
}
}
showPopup(props.component, cprops, element)
}