Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions models/task/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,14 @@ export function createModel (builder: Builder): void {
presenter: task.component.StatePresenter
})

builder.mixin(task.class.DoneState, core.class.Class, view.mixin.AttributeEditor, {
editor: task.component.DoneStateEditor
})

builder.mixin(task.class.DoneState, core.class.Class, view.mixin.AttributePresenter, {
presenter: task.component.DoneStatePresenter
})

builder.createDoc(
view.class.ViewletDescriptor,
core.space.Model,
Expand Down
1 change: 1 addition & 0 deletions models/task/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export default mergeIds(taskId, task, {
StatePresenter: '' as AnyComponent,
DoneStatePresenter: '' as AnyComponent,
StateEditor: '' as AnyComponent,
DoneStateEditor: '' as AnyComponent,
KanbanView: '' as AnyComponent,
Todos: '' as AnyComponent,
TodoItemPresenter: '' as AnyComponent,
Expand Down
41 changes: 33 additions & 8 deletions packages/presentation/src/components/AttributeBarEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-->

<script lang="ts">
import type { Doc } from '@anticrm/core'
import { getResource } from '@anticrm/platform'
Expand All @@ -37,7 +36,7 @@

$: attribute = typeof key === 'string' ? hierarchy.getAttribute(_class, key) : key.attr
$: attributeKey = typeof key === 'string' ? key : key.key
$: typeClassId = (attribute !== undefined) ? getAttributePresenterClass(attribute) : undefined
$: typeClassId = attribute !== undefined ? getAttributePresenterClass(attribute) : undefined

let editor: Promise<AnySvelteComponent> | undefined

Expand All @@ -57,7 +56,6 @@
{#await editor}
...
{:then instance}

{#if attribute.icon}
<div class="flex-row-center">
<CircleButton icon={attribute.icon} size={'large'} />
Expand All @@ -66,19 +64,46 @@
{#if showHeader}
<Label label={attribute.label} />
{/if}
<div class="value"><svelte:component this={instance} label={attribute?.label} placeholder={attribute?.label} {maxWidth} value={getAttribute(client, object, { key: attributeKey, attr: attribute })} {onChange} {focus}/></div>
<div class="value">
<svelte:component
this={instance}
label={attribute?.label}
placeholder={attribute?.label}
{maxWidth}
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
space={object.space}
{onChange}
{focus}
/>
</div>
</div>
{/if}
</div>
{:else if showHeader}
<div class="flex-col">
<Label label={attribute.label} />
<div class="value"><svelte:component this={instance} label={attribute?.label} placeholder={attribute?.label} {maxWidth} value={getAttribute(client, object, { key: attributeKey, attr: attribute })} {onChange} {focus}/></div>
<div class="value">
<svelte:component
this={instance}
label={attribute?.label}
placeholder={attribute?.label}
{maxWidth}
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
space={object.space}
{onChange}
{focus}
/>
</div>
</div>
{:else}
<svelte:component this={instance} {maxWidth} value={getAttribute(client, object, { key: attributeKey, attr: attribute })} {onChange} {focus}/>
<svelte:component
this={instance}
{maxWidth}
value={getAttribute(client, object, { key: attributeKey, attr: attribute })}
space={object.space}
{onChange}
{focus}
/>
{/if}

{/await}
{/if}

3 changes: 2 additions & 1 deletion plugins/task-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"DoneStates": "Done states",
"States": "States",
"ChooseAColor": "Choose a color",
"SearchTask": "Search for task..."
"SearchTask": "Search for task...",
"NoDoneState": "Not done"
}
}
1 change: 1 addition & 0 deletions plugins/task-resources/src/components/TaskHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
</div>
</div>
<AttributeBarEditor key={'state'} {object} showHeader={false} />
<AttributeBarEditor key={'doneState'} {object} showHeader={false} />
</div>

<style lang="scss">
Expand Down
70 changes: 70 additions & 0 deletions plugins/task-resources/src/components/state/DoneStateEditor.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 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 { Ref } from '@anticrm/core'
import { createQuery } from '@anticrm/presentation'
import { DoneState, SpaceWithStates } from '@anticrm/task'
import { Label, showPopup } from '@anticrm/ui'
import DoneStatePresenter from './DoneStatePresenter.svelte'
import DoneStatesPopup from './DoneStatesPopup.svelte'
import task from '../../plugin'

export let value: Ref<DoneState> | null | undefined
export let onChange: (value: any) => void
export let space: Ref<SpaceWithStates>
let state: DoneState | undefined
let container: HTMLElement
let opened: boolean = false

const query = createQuery()
$: if (value != null) {
query.query(
task.class.DoneState,
{ _id: value },
(res) => {
state = res[0]
},
{ limit: 1 }
)
}
</script>

<div
class="flex-row-center cursor-pointer"
bind:this={container}
on:click|preventDefault={() => {
if (!opened) {
opened = true
showPopup(DoneStatesPopup, { space }, container, (result) => {
if (result) {
value = result._id
onChange(value)
} else if (result == null) {
value = null
onChange(value)
}

opened = false
})
}
}}
>
{#if state}
<DoneStatePresenter value={state} showTitle />
{:else}
<Label label={task.string.NoDoneState} />
{/if}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,21 @@
<script lang="ts">
import type { DoneState } from '@anticrm/task'
import task from '@anticrm/task'
import { getPlatformColor } from '@anticrm/ui'

export let value: DoneState
export let showTitle: boolean = false

$: color = value._class === task.class.WonState ? '#a5d179' : '#f28469'
$: color = value._class === task.class.WonState ? getPlatformColor(0) : getPlatformColor(11)

</script>

{#if value }
<div class="flex-center">
<div class="state-container" style="background-color: {color};" />
<div class="state-container" class:state-container-title={showTitle} style="background-color: {color};" />
{#if showTitle}
{value.title}
{/if}
</div>
{/if}

Expand All @@ -36,4 +41,7 @@
height: .5rem;
border-radius: .5rem;
}
.state-container-title {
margin-right: 0.75rem;
}
</style>
100 changes: 100 additions & 0 deletions plugins/task-resources/src/components/state/DoneStatesPopup.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 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 { Class, Doc, Ref, SortingOrder } from '@anticrm/core'
import { createQuery } from '@anticrm/presentation'
import { DoneState, SpaceWithStates } from '@anticrm/task'
import { getPlatformColor, Label } from '@anticrm/ui'
import { createEventDispatcher } from 'svelte'
import task from '../../plugin'

export let space: Ref<SpaceWithStates>
let states: DoneState[] = []
const dispatch = createEventDispatcher()
const statesQuery = createQuery()
statesQuery.query(
task.class.DoneState,
{ space },
(res) => {
states = res
},
{
sort: {
rank: SortingOrder.Ascending
}
}
)
function getColor (_class: Ref<Class<Doc>>): string {
return _class === task.class.WonState ? getPlatformColor(0) : getPlatformColor(11)
}
</script>

<div class="flex-col statuses-container">
{#each states as state}
<div
class="flex-row-center state"
on:click={() => {
dispatch('close', state)
}}
>
<div class="color" style="background-color: {getColor(state._class)}" />
{state.title}
</div>
{/each}
<div
class="flex-row-center state"
on:click={() => {
dispatch('close', null)
}}
>
<div class='not-done'>
<Label label={task.string.NoDoneState}/>
</div>
</div>
</div>

<style lang="scss">
.statuses-container {
padding: 0.5rem;
max-height: 100%;
min-width: 10rem;
color: var(--theme-caption-color);
background-color: var(--theme-button-bg-focused);
border: 1px solid var(--theme-button-border-enabled);
border-radius: 0.75rem;
user-select: none;
filter: drop-shadow(0 1.5rem 4rem rgba(0, 0, 0, 0.35));

.state {
padding: 0.5rem;
border-radius: 0.5rem;
cursor: pointer;

&:hover {
background-color: var(--theme-button-bg-hovered);
}
.color {
margin-right: 0.75rem;
width: .5rem;
height: .5rem;
border-radius: .5rem;
}
}
}
.not-done {
margin-left: 1.25rem;
}
</style>
4 changes: 3 additions & 1 deletion plugins/task-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import EditIssue from './components/EditIssue.svelte'
import KanbanView from './components/kanban/KanbanView.svelte'
import KanbanCard from './components/KanbanCard.svelte'
import DoneStatePresenter from './components/state/DoneStatePresenter.svelte'
import DoneStateEditor from './components/state/DoneStateEditor.svelte'
import EditStatuses from './components/state/EditStatuses.svelte'
import StateEditor from './components/state/StateEditor.svelte'
import StatePresenter from './components/state/StatePresenter.svelte'
Expand Down Expand Up @@ -140,7 +141,8 @@ export default async (): Promise<Resources> => ({
TodoItemPresenter,
TodoStatePresenter,
StatusTableView,
TaskHeader
TaskHeader,
DoneStateEditor
},
actionImpl: {
CreateTask: createTask,
Expand Down
3 changes: 2 additions & 1 deletion plugins/task-resources/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export default mergeIds(taskId, task, {
DoneStatesWon: '' as IntlString,
DoneStatesLost: '' as IntlString,
AllStates: '' as IntlString,
ChooseAColor: '' as IntlString
ChooseAColor: '' as IntlString,
NoDoneState: '' as IntlString
},
status: {
AssigneeRequired: '' as IntlString
Expand Down