mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
Fix TSK-96 (#2052)
This commit is contained in:
parent
77ee575bbd
commit
546eac5dee
@ -35,10 +35,9 @@ import {
|
|||||||
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 core, { TAttachedDoc, TClass, TDoc, TSpace } from '@anticrm/model-core'
|
import core, { TAttachedDoc, TClass, TDoc, TSpace } from '@anticrm/model-core'
|
||||||
import presentation from '@anticrm/model-presentation'
|
|
||||||
import view, { actionTemplates as viewTemplates, createAction, template } from '@anticrm/model-view'
|
import view, { actionTemplates as viewTemplates, createAction, template } from '@anticrm/model-view'
|
||||||
import { IntlString } from '@anticrm/platform'
|
import { IntlString } from '@anticrm/platform'
|
||||||
import { ViewAction } from '@anticrm/view'
|
import tags from '@anticrm/tags'
|
||||||
import {
|
import {
|
||||||
DOMAIN_STATE,
|
DOMAIN_STATE,
|
||||||
DoneState,
|
DoneState,
|
||||||
@ -60,7 +59,7 @@ import {
|
|||||||
WonStateTemplate
|
WonStateTemplate
|
||||||
} from '@anticrm/task'
|
} from '@anticrm/task'
|
||||||
import { AnyComponent } from '@anticrm/ui'
|
import { AnyComponent } from '@anticrm/ui'
|
||||||
import tags from '@anticrm/tags'
|
import { ViewAction } from '@anticrm/view'
|
||||||
import task from './plugin'
|
import task from './plugin'
|
||||||
|
|
||||||
export { createKanbanTemplate, createSequence, taskOperation } from './migration'
|
export { createKanbanTemplate, createSequence, taskOperation } from './migration'
|
||||||
@ -501,17 +500,6 @@ export function createModel (builder: Builder): void {
|
|||||||
target: task.class.TodoItem
|
target: task.class.TodoItem
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.createDoc(
|
|
||||||
presentation.class.ObjectSearchCategory,
|
|
||||||
core.space.Model,
|
|
||||||
{
|
|
||||||
icon: task.icon.Task,
|
|
||||||
label: task.string.SearchTask,
|
|
||||||
query: task.completion.IssueQuery
|
|
||||||
},
|
|
||||||
task.completion.IssueCategory
|
|
||||||
)
|
|
||||||
|
|
||||||
createAction(
|
createAction(
|
||||||
builder,
|
builder,
|
||||||
{
|
{
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import type { Ref, Space } from '@anticrm/core'
|
import type { Ref, Space } from '@anticrm/core'
|
||||||
import { ObjectSearchCategory, ObjectSearchFactory } from '@anticrm/model-presentation'
|
|
||||||
import type { Resource } from '@anticrm/platform'
|
|
||||||
import { mergeIds } from '@anticrm/platform'
|
import { mergeIds } from '@anticrm/platform'
|
||||||
import { TagCategory } from '@anticrm/tags'
|
import { TagCategory } from '@anticrm/tags'
|
||||||
import { KanbanTemplate, taskId } from '@anticrm/task'
|
import { KanbanTemplate, taskId } from '@anticrm/task'
|
||||||
@ -66,10 +64,6 @@ export default mergeIds(taskId, task, {
|
|||||||
template: {
|
template: {
|
||||||
DefaultProject: '' as Ref<KanbanTemplate>
|
DefaultProject: '' as Ref<KanbanTemplate>
|
||||||
},
|
},
|
||||||
completion: {
|
|
||||||
IssueQuery: '' as Resource<ObjectSearchFactory>,
|
|
||||||
IssueCategory: '' as Ref<ObjectSearchCategory>
|
|
||||||
},
|
|
||||||
viewlet: {
|
viewlet: {
|
||||||
TableIssue: '' as Ref<Viewlet>
|
TableIssue: '' as Ref<Viewlet>
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ import {
|
|||||||
} from '@anticrm/tracker'
|
} from '@anticrm/tracker'
|
||||||
import tracker from './plugin'
|
import tracker from './plugin'
|
||||||
|
|
||||||
|
import presentation from '@anticrm/model-presentation'
|
||||||
|
|
||||||
export { trackerOperation } from './migration'
|
export { trackerOperation } from './migration'
|
||||||
export { default } from './plugin'
|
export { default } from './plugin'
|
||||||
|
|
||||||
@ -568,4 +570,15 @@ export function createModel (builder: Builder): void {
|
|||||||
builder.mixin(tracker.class.Issue, core.class.Class, view.mixin.ClassFilters, {
|
builder.mixin(tracker.class.Issue, core.class.Class, view.mixin.ClassFilters, {
|
||||||
filters: ['status', 'priority', 'project']
|
filters: ['status', 'priority', 'project']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.createDoc(
|
||||||
|
presentation.class.ObjectSearchCategory,
|
||||||
|
core.space.Model,
|
||||||
|
{
|
||||||
|
icon: tracker.icon.TrackerApplication,
|
||||||
|
label: tracker.string.SearchIssue,
|
||||||
|
query: tracker.completion.IssueQuery
|
||||||
|
},
|
||||||
|
tracker.completion.IssueCategory
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import { Ref } from '@anticrm/core'
|
import { Ref } from '@anticrm/core'
|
||||||
import { IntlString, mergeIds } from '@anticrm/platform'
|
import { ObjectSearchCategory, ObjectSearchFactory } from '@anticrm/model-presentation'
|
||||||
|
import { IntlString, mergeIds, Resource } from '@anticrm/platform'
|
||||||
import { Team, trackerId } from '@anticrm/tracker'
|
import { Team, trackerId } from '@anticrm/tracker'
|
||||||
import tracker from '@anticrm/tracker-resources/src/plugin'
|
import tracker from '@anticrm/tracker-resources/src/plugin'
|
||||||
import type { AnyComponent } from '@anticrm/ui'
|
import type { AnyComponent } from '@anticrm/ui'
|
||||||
@ -31,7 +32,8 @@ export default mergeIds(trackerId, tracker, {
|
|||||||
GotoBacklog: '' as IntlString,
|
GotoBacklog: '' as IntlString,
|
||||||
GotoBoard: '' as IntlString,
|
GotoBoard: '' as IntlString,
|
||||||
GotoProjects: '' as IntlString,
|
GotoProjects: '' as IntlString,
|
||||||
GotoTrackerApplication: '' as IntlString
|
GotoTrackerApplication: '' as IntlString,
|
||||||
|
SearchIssue: '' as IntlString
|
||||||
},
|
},
|
||||||
team: {
|
team: {
|
||||||
DefaultTeam: '' as Ref<Team>
|
DefaultTeam: '' as Ref<Team>
|
||||||
@ -45,5 +47,9 @@ export default mergeIds(trackerId, tracker, {
|
|||||||
},
|
},
|
||||||
viewlet: {
|
viewlet: {
|
||||||
List: '' as Ref<ViewletDescriptor>
|
List: '' as Ref<ViewletDescriptor>
|
||||||
|
},
|
||||||
|
completion: {
|
||||||
|
IssueQuery: '' as Resource<ObjectSearchFactory>,
|
||||||
|
IssueCategory: '' as Ref<ObjectSearchCategory>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -93,7 +93,9 @@ export class LiveQuery {
|
|||||||
callback: (result: FindResult<T>) => void,
|
callback: (result: FindResult<T>) => void,
|
||||||
options?: FindOptions<T>
|
options?: FindOptions<T>
|
||||||
): boolean {
|
): boolean {
|
||||||
|
console.log(_class, query, callback, options)
|
||||||
if (!this.needUpdate(_class, query, callback, options)) {
|
if (!this.needUpdate(_class, query, callback, options)) {
|
||||||
|
console.log('matched')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
this.oldCallback = callback
|
this.oldCallback = callback
|
||||||
@ -104,6 +106,10 @@ export class LiveQuery {
|
|||||||
const unsub = liveQuery.query(_class, query, callback, options)
|
const unsub = liveQuery.query(_class, query, callback, options)
|
||||||
this.unsubscribe = () => {
|
this.unsubscribe = () => {
|
||||||
unsub()
|
unsub()
|
||||||
|
this.oldCallback = undefined
|
||||||
|
this.oldClass = undefined
|
||||||
|
this.oldOptions = undefined
|
||||||
|
this.oldQuery = undefined
|
||||||
this.unsubscribe = () => {}
|
this.unsubscribe = () => {}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -170,7 +170,9 @@
|
|||||||
selected = i
|
selected = i
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svelte:component this={item.component} value={item.doc} {...item.componentProps ?? {}} />
|
<div class="ml-2 mt-1 mb-1">
|
||||||
|
<svelte:component this={item.component} value={item.doc} {...item.componentProps ?? {}} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{#if !items.length}
|
{#if !items.length}
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
personQuery.query(contact.class.Contact, { _id: object.contact }, (result) => {
|
personQuery.query(contact.class.Contact, { _id: object.contact }, (result) => {
|
||||||
refContact = result[0]
|
refContact = result[0]
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
personQuery.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
let organization: Organization
|
let organization: Organization
|
||||||
@ -37,6 +39,8 @@
|
|||||||
orgQuery.query(contact.class.Organization, { _id: object.attachedTo as Ref<Organization> }, (result) => {
|
orgQuery.query(contact.class.Organization, { _id: object.attachedTo as Ref<Organization> }, (result) => {
|
||||||
organization = result[0]
|
organization = result[0]
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
orgQuery.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex item">
|
<div class="flex item">
|
||||||
<Icon icon={recruit.icon.Application} size={'large'} />
|
<Icon icon={recruit.icon.Application} size={'medium'} />
|
||||||
<div class="ml-2">
|
<div class="ml-2">
|
||||||
{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}
|
{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
templatesQ.query(task.class.KanbanTemplate, { space: folder._id as Ref<Doc> as Ref<Space> }, (result) => {
|
templatesQ.query(task.class.KanbanTemplate, { space: folder._id as Ref<Doc> as Ref<Space> }, (result) => {
|
||||||
templates = result
|
templates = result
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
templatesQ.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
let selectedId: Ref<KanbanTemplate> | undefined
|
let selectedId: Ref<KanbanTemplate> | undefined
|
||||||
|
@ -54,6 +54,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
elementsQuery.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagElementInfo = { count: number; modifiedOn: number }
|
type TagElementInfo = { count: number; modifiedOn: number }
|
||||||
|
@ -62,8 +62,7 @@
|
|||||||
"DoneStatesLost": "Done status / Lost",
|
"DoneStatesLost": "Done status / Lost",
|
||||||
"AllStates": "All states",
|
"AllStates": "All states",
|
||||||
"DoneStates": "Done states",
|
"DoneStates": "Done states",
|
||||||
"States": "States",
|
"States": "States",
|
||||||
"SearchTask": "Search for task...",
|
|
||||||
"NoDoneState": "Not done",
|
"NoDoneState": "Not done",
|
||||||
"ManageStatusesWithin": "Manage application statuses within",
|
"ManageStatusesWithin": "Manage application statuses within",
|
||||||
"ManageProjectStatues": "Manage project statues",
|
"ManageProjectStatues": "Manage project statues",
|
||||||
|
@ -63,7 +63,6 @@
|
|||||||
"AllStates": "Все статусы",
|
"AllStates": "Все статусы",
|
||||||
"DoneStates": "Завершенные статусы",
|
"DoneStates": "Завершенные статусы",
|
||||||
"States": "Статусы",
|
"States": "Статусы",
|
||||||
"SearchTask": "Поиск задачи...",
|
|
||||||
"NoDoneState": "Не завершено",
|
"NoDoneState": "Не завершено",
|
||||||
"ManageStatusesWithin": "Управление статусами для",
|
"ManageStatusesWithin": "Управление статусами для",
|
||||||
"ManageProjectStatues": "Управление статусами задачи",
|
"ManageProjectStatues": "Управление статусами задачи",
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
wonStates = result.filter((x) => x._class === task.class.WonState)
|
wonStates = result.filter((x) => x._class === task.class.WonState)
|
||||||
lostStates = result.filter((x) => x._class === task.class.LostState)
|
lostStates = result.filter((x) => x._class === task.class.LostState)
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
doneStatesQ.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
let hoveredDoneState: Ref<DoneState> | undefined
|
let hoveredDoneState: Ref<DoneState> | undefined
|
||||||
|
@ -45,6 +45,8 @@
|
|||||||
},
|
},
|
||||||
{ limit: 1 }
|
{ limit: 1 }
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
query.unsubscribe()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -14,11 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import { Class, Client, Ref } from '@anticrm/core'
|
import { Resources } from '@anticrm/platform'
|
||||||
import { IntlString, Resources, translate } from '@anticrm/platform'
|
import { SpaceWithStates } from '@anticrm/task'
|
||||||
import { ObjectSearchResult } from '@anticrm/presentation'
|
|
||||||
import { SpaceWithStates, Task } from '@anticrm/task'
|
|
||||||
import { showPopup } from '@anticrm/ui'
|
import { showPopup } from '@anticrm/ui'
|
||||||
|
import AssignedTasks from './components/AssignedTasks.svelte'
|
||||||
import CreateProject from './components/CreateProject.svelte'
|
import CreateProject from './components/CreateProject.svelte'
|
||||||
import EditIssue from './components/EditIssue.svelte'
|
import EditIssue from './components/EditIssue.svelte'
|
||||||
import KanbanTemplateEditor from './components/kanban/KanbanTemplateEditor.svelte'
|
import KanbanTemplateEditor from './components/kanban/KanbanTemplateEditor.svelte'
|
||||||
@ -32,59 +31,17 @@ import StateEditor from './components/state/StateEditor.svelte'
|
|||||||
import StatePresenter from './components/state/StatePresenter.svelte'
|
import StatePresenter from './components/state/StatePresenter.svelte'
|
||||||
import StatusTableView from './components/StatusTableView.svelte'
|
import StatusTableView from './components/StatusTableView.svelte'
|
||||||
import TaskHeader from './components/TaskHeader.svelte'
|
import TaskHeader from './components/TaskHeader.svelte'
|
||||||
import TaskItem from './components/TaskItem.svelte'
|
|
||||||
import TaskPresenter from './components/TaskPresenter.svelte'
|
import TaskPresenter from './components/TaskPresenter.svelte'
|
||||||
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
import TemplatesIcon from './components/TemplatesIcon.svelte'
|
||||||
import TodoItemPresenter from './components/todos/TodoItemPresenter.svelte'
|
import TodoItemPresenter from './components/todos/TodoItemPresenter.svelte'
|
||||||
import TodoItemsPopup from './components/todos/TodoItemsPopup.svelte'
|
import TodoItemsPopup from './components/todos/TodoItemsPopup.svelte'
|
||||||
import Todos from './components/todos/Todos.svelte'
|
import Todos from './components/todos/Todos.svelte'
|
||||||
import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte'
|
import TodoStatePresenter from './components/todos/TodoStatePresenter.svelte'
|
||||||
import AssignedTasks from './components/AssignedTasks.svelte'
|
|
||||||
import task from './plugin'
|
|
||||||
|
|
||||||
async function editStatuses (object: SpaceWithStates): Promise<void> {
|
async function editStatuses (object: SpaceWithStates): Promise<void> {
|
||||||
showPopup(EditStatuses, { _id: object._id, spaceClass: object._class }, 'float')
|
showPopup(EditStatuses, { _id: object._id, spaceClass: object._class }, 'float')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function queryTask<D extends Task> (
|
|
||||||
_class: Ref<Class<D>>,
|
|
||||||
client: Client,
|
|
||||||
search: string
|
|
||||||
): Promise<ObjectSearchResult[]> {
|
|
||||||
const cl = client.getHierarchy().getClass(_class)
|
|
||||||
const shortLabel = (await translate(cl.shortLabel ?? ('' as IntlString), {})).toUpperCase()
|
|
||||||
|
|
||||||
// Check number pattern
|
|
||||||
|
|
||||||
const sequence = (await client.findOne(task.class.Sequence, { attachedTo: _class }))?.sequence ?? 0
|
|
||||||
|
|
||||||
const named = new Map(
|
|
||||||
(await client.findAll<Task>(_class, { name: { $like: `%${search}%` } }, { limit: 200 })).map((e) => [e._id, e])
|
|
||||||
)
|
|
||||||
const nids: number[] = []
|
|
||||||
if (sequence > 0) {
|
|
||||||
for (let n = 0; n < sequence; n++) {
|
|
||||||
const v = `${n}`
|
|
||||||
if (v.includes(search)) {
|
|
||||||
nids.push(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const numbered = await client.findAll<Task>(_class, { number: { $in: nids } }, { limit: 200 })
|
|
||||||
for (const d of numbered) {
|
|
||||||
if (!named.has(d._id)) {
|
|
||||||
named.set(d._id, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.from(named.values()).map((e) => ({
|
|
||||||
doc: e,
|
|
||||||
title: `${shortLabel}-${e.number}`,
|
|
||||||
icon: task.icon.Task,
|
|
||||||
component: TaskItem
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StatesBarPosition = 'start' | 'middle' | 'end' | undefined
|
export type StatesBarPosition = 'start' | 'middle' | 'end' | undefined
|
||||||
|
|
||||||
export default async (): Promise<Resources> => ({
|
export default async (): Promise<Resources> => ({
|
||||||
@ -111,8 +68,5 @@ export default async (): Promise<Resources> => ({
|
|||||||
},
|
},
|
||||||
actionImpl: {
|
actionImpl: {
|
||||||
EditStatuses: editStatuses
|
EditStatuses: editStatuses
|
||||||
},
|
|
||||||
completion: {
|
|
||||||
IssueQuery: async (client: Client, query: string) => await queryTask(task.class.Issue, client, query)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -221,7 +221,6 @@ const task = plugin(taskId, {
|
|||||||
Kanban: '' as IntlString,
|
Kanban: '' as IntlString,
|
||||||
ApplicationLabelTask: '' as IntlString,
|
ApplicationLabelTask: '' as IntlString,
|
||||||
Projects: '' as IntlString,
|
Projects: '' as IntlString,
|
||||||
SearchTask: '' as IntlString,
|
|
||||||
ManageProjectStatues: '' as IntlString,
|
ManageProjectStatues: '' as IntlString,
|
||||||
TodoItems: '' as IntlString
|
TodoItems: '' as IntlString
|
||||||
},
|
},
|
||||||
|
@ -139,7 +139,8 @@
|
|||||||
"IncludeItemsThatMatch": "Include items that match",
|
"IncludeItemsThatMatch": "Include items that match",
|
||||||
"AnyFilter": "any filter",
|
"AnyFilter": "any filter",
|
||||||
"AllFilters": "all filters",
|
"AllFilters": "all filters",
|
||||||
"NoDescription": "No description"
|
"NoDescription": "No description",
|
||||||
|
"SearchIssue": "Search for task..."
|
||||||
},
|
},
|
||||||
"status": {}
|
"status": {}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,8 @@
|
|||||||
"IncludeItemsThatMatch": "Включить элементы, которые соответствуют",
|
"IncludeItemsThatMatch": "Включить элементы, которые соответствуют",
|
||||||
"AnyFilter": "любому фильтру",
|
"AnyFilter": "любому фильтру",
|
||||||
"AllFilters": "всем фильтрам",
|
"AllFilters": "всем фильтрам",
|
||||||
"NoDescription": "Нет описания"
|
"NoDescription": "Нет описания",
|
||||||
|
"SearchIssue": "Поиск задачи..."
|
||||||
},
|
},
|
||||||
"status": {}
|
"status": {}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
<!--
|
||||||
|
// 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 { WithLookup } from '@anticrm/core'
|
||||||
|
import type { Issue, Team } from '@anticrm/tracker'
|
||||||
|
import { Icon } from '@anticrm/ui'
|
||||||
|
import tracker from '../../plugin'
|
||||||
|
import { getIssueId } from '../../utils'
|
||||||
|
|
||||||
|
export let value: WithLookup<Issue>
|
||||||
|
$: title = getIssueId(value.$lookup?.space as Team, value)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex item">
|
||||||
|
<Icon icon={tracker.icon.TrackerApplication} size={'medium'} />
|
||||||
|
<div class="ml-2">
|
||||||
|
{title} - {value.title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.item {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
$: if (!currentTeam) {
|
$: if (!currentTeam) {
|
||||||
spaceQuery.query(tracker.class.Team, { _id: value.space }, (res) => ([currentTeam] = res))
|
spaceQuery.query(tracker.class.Team, { _id: value.space }, (res) => ([currentTeam] = res))
|
||||||
|
} else {
|
||||||
|
spaceQuery.unsubscribe()
|
||||||
}
|
}
|
||||||
$: issueName = currentTeam && getIssueId(currentTeam, value)
|
$: issueName = currentTeam && getIssueId(currentTeam, value)
|
||||||
</script>
|
</script>
|
||||||
|
@ -86,13 +86,16 @@
|
|||||||
|
|
||||||
$: areSubIssuesLoading = !subIssues
|
$: areSubIssuesLoading = !subIssues
|
||||||
$: parentIssue = issue.$lookup?.attachedTo ? (issue.$lookup?.attachedTo as Issue) : null
|
$: parentIssue = issue.$lookup?.attachedTo ? (issue.$lookup?.attachedTo as Issue) : null
|
||||||
$: parentIssue &&
|
$: if (parentIssue) {
|
||||||
subIssuesQeury.query(
|
subIssuesQeury.query(
|
||||||
tracker.class.Issue,
|
tracker.class.Issue,
|
||||||
{ space: issue.space, attachedTo: parentIssue._id },
|
{ space: issue.space, attachedTo: parentIssue._id },
|
||||||
(res) => (subIssues = res),
|
(res) => (subIssues = res),
|
||||||
{ sort: { modifiedOn: SortingOrder.Descending } }
|
{ sort: { modifiedOn: SortingOrder.Descending } }
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
subIssuesQeury.unsubscribe()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if parentIssue}
|
{#if parentIssue}
|
||||||
|
@ -37,19 +37,25 @@
|
|||||||
closePopup()
|
closePopup()
|
||||||
|
|
||||||
projectId = loc.path[4] as Ref<Project>
|
projectId = loc.path[4] as Ref<Project>
|
||||||
|
console.log('PROJECT SELECTED', projectId)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const projectQuery = createQuery()
|
const projectQuery = createQuery()
|
||||||
$: if (projectId !== undefined) {
|
$: if (projectId !== undefined) {
|
||||||
|
console.log('call query for', projectId)
|
||||||
projectQuery.query(tracker.class.Project, { _id: projectId }, (result) => {
|
projectQuery.query(tracker.class.Project, { _id: projectId }, (result) => {
|
||||||
;[project] = result
|
project = result.shift()
|
||||||
|
console.log('recieve result for', projectId, project)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
projectQuery.unsubscribe()
|
||||||
project = undefined
|
project = undefined
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{projectId}
|
||||||
|
{JSON.stringify(project)}
|
||||||
{#if project}
|
{#if project}
|
||||||
<EditProject {project} />
|
<EditProject {project} />
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -13,47 +13,99 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import { Class, Client, Ref } from '@anticrm/core'
|
||||||
import { Resources } from '@anticrm/platform'
|
import { Resources } from '@anticrm/platform'
|
||||||
|
import { ObjectSearchResult } from '@anticrm/presentation'
|
||||||
import NopeComponent from './components/NopeComponent.svelte'
|
import { Issue, Team } from '@anticrm/tracker'
|
||||||
|
import Inbox from './components/inbox/Inbox.svelte'
|
||||||
import Active from './components/issues/Active.svelte'
|
import Active from './components/issues/Active.svelte'
|
||||||
|
import AssigneePresenter from './components/issues/AssigneePresenter.svelte'
|
||||||
import Backlog from './components/issues/Backlog.svelte'
|
import Backlog from './components/issues/Backlog.svelte'
|
||||||
import Board from './components/issues/Board.svelte'
|
import Board from './components/issues/Board.svelte'
|
||||||
import Inbox from './components/inbox/Inbox.svelte'
|
|
||||||
import Issues from './components/issues/Issues.svelte'
|
|
||||||
import MyIssues from './components/myissues/MyIssues.svelte'
|
|
||||||
import Projects from './components/projects/Projects.svelte'
|
|
||||||
import ProjectPresenter from './components/projects/ProjectPresenter.svelte'
|
|
||||||
import ProjectTitlePresenter from './components/projects/ProjectTitlePresenter.svelte'
|
|
||||||
import Views from './components/views/Views.svelte'
|
|
||||||
import IssuePresenter from './components/issues/IssuePresenter.svelte'
|
|
||||||
import TitlePresenter from './components/issues/TitlePresenter.svelte'
|
|
||||||
import PriorityPresenter from './components/issues/PriorityPresenter.svelte'
|
|
||||||
import PriorityEditor from './components/issues/PriorityEditor.svelte'
|
|
||||||
import ProjectEditor from './components/projects/ProjectEditor.svelte'
|
|
||||||
import StatusPresenter from './components/issues/StatusPresenter.svelte'
|
|
||||||
import StatusEditor from './components/issues/StatusEditor.svelte'
|
|
||||||
import SetDueDateActionPopup from './components/SetDueDateActionPopup.svelte'
|
|
||||||
import SetParentIssueActionPopup from './components/SetParentIssueActionPopup.svelte'
|
|
||||||
import DueDatePresenter from './components/issues/DueDatePresenter.svelte'
|
import DueDatePresenter from './components/issues/DueDatePresenter.svelte'
|
||||||
import AssigneePresenter from './components/issues/AssigneePresenter.svelte'
|
import EditIssue from './components/issues/edit/EditIssue.svelte'
|
||||||
|
import IssueItem from './components/issues/IssueItem.svelte'
|
||||||
|
import IssuePresenter from './components/issues/IssuePresenter.svelte'
|
||||||
|
import IssuePreview from './components/issues/IssuePreview.svelte'
|
||||||
|
import Issues from './components/issues/Issues.svelte'
|
||||||
|
import IssuesView from './components/issues/IssuesView.svelte'
|
||||||
|
import ListView from './components/issues/ListView.svelte'
|
||||||
|
import ModificationDatePresenter from './components/issues/ModificationDatePresenter.svelte'
|
||||||
|
import PriorityEditor from './components/issues/PriorityEditor.svelte'
|
||||||
|
import PriorityPresenter from './components/issues/PriorityPresenter.svelte'
|
||||||
|
import StatusEditor from './components/issues/StatusEditor.svelte'
|
||||||
|
import StatusPresenter from './components/issues/StatusPresenter.svelte'
|
||||||
|
import TitlePresenter from './components/issues/TitlePresenter.svelte'
|
||||||
import ViewOptionsPopup from './components/issues/ViewOptionsPopup.svelte'
|
import ViewOptionsPopup from './components/issues/ViewOptionsPopup.svelte'
|
||||||
|
import MyIssues from './components/myissues/MyIssues.svelte'
|
||||||
|
import NewIssueHeader from './components/NewIssueHeader.svelte'
|
||||||
|
import NopeComponent from './components/NopeComponent.svelte'
|
||||||
|
import EditProject from './components/projects/EditProject.svelte'
|
||||||
import IconPresenter from './components/projects/IconPresenter.svelte'
|
import IconPresenter from './components/projects/IconPresenter.svelte'
|
||||||
import LeadPresenter from './components/projects/LeadPresenter.svelte'
|
import LeadPresenter from './components/projects/LeadPresenter.svelte'
|
||||||
import TargetDatePresenter from './components/projects/TargetDatePresenter.svelte'
|
import ProjectEditor from './components/projects/ProjectEditor.svelte'
|
||||||
import ProjectMembersPresenter from './components/projects/ProjectMembersPresenter.svelte'
|
import ProjectMembersPresenter from './components/projects/ProjectMembersPresenter.svelte'
|
||||||
import ProjectStatusPresenter from './components/projects/ProjectStatusPresenter.svelte'
|
import ProjectPresenter from './components/projects/ProjectPresenter.svelte'
|
||||||
import EditProject from './components/projects/EditProject.svelte'
|
import Projects from './components/projects/Projects.svelte'
|
||||||
import ProjectStatusEditor from './components/projects/ProjectStatusEditor.svelte'
|
import ProjectStatusEditor from './components/projects/ProjectStatusEditor.svelte'
|
||||||
|
import ProjectStatusPresenter from './components/projects/ProjectStatusPresenter.svelte'
|
||||||
|
import ProjectTitlePresenter from './components/projects/ProjectTitlePresenter.svelte'
|
||||||
|
import TargetDatePresenter from './components/projects/TargetDatePresenter.svelte'
|
||||||
|
import SetDueDateActionPopup from './components/SetDueDateActionPopup.svelte'
|
||||||
|
import SetParentIssueActionPopup from './components/SetParentIssueActionPopup.svelte'
|
||||||
|
import Views from './components/views/Views.svelte'
|
||||||
|
import tracker from './plugin'
|
||||||
|
import { getIssueId } from './utils'
|
||||||
|
|
||||||
import ModificationDatePresenter from './components/issues/ModificationDatePresenter.svelte'
|
export async function queryIssue<D extends Issue> (
|
||||||
import EditIssue from './components/issues/edit/EditIssue.svelte'
|
_class: Ref<Class<D>>,
|
||||||
import NewIssueHeader from './components/NewIssueHeader.svelte'
|
client: Client,
|
||||||
import ListView from './components/issues/ListView.svelte'
|
search: string
|
||||||
import IssuesView from './components/issues/IssuesView.svelte'
|
): Promise<ObjectSearchResult[]> {
|
||||||
import IssuePreview from './components/issues/IssuePreview.svelte'
|
const teams = await client.findAll<Team>(tracker.class.Team, {})
|
||||||
|
|
||||||
|
const named = new Map(
|
||||||
|
(
|
||||||
|
await client.findAll<Issue>(
|
||||||
|
_class,
|
||||||
|
{ title: { $like: `%${search}%` } },
|
||||||
|
{
|
||||||
|
limit: 200,
|
||||||
|
lookup: { space: tracker.class.Team }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).map((e) => [e._id, e])
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const currentTeam of teams) {
|
||||||
|
const nids: number[] = []
|
||||||
|
for (let n = 0; n < currentTeam.sequence; n++) {
|
||||||
|
const v = `${currentTeam.identifier}-${n}`
|
||||||
|
if (v.includes(search)) {
|
||||||
|
nids.push(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nids.length > 0) {
|
||||||
|
const numbered = await client.findAll<Issue>(
|
||||||
|
_class,
|
||||||
|
{ number: { $in: nids } },
|
||||||
|
{ limit: 200, lookup: { space: tracker.class.Team } }
|
||||||
|
)
|
||||||
|
for (const d of numbered) {
|
||||||
|
if (!named.has(d._id)) {
|
||||||
|
named.set(d._id, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(named.values()).map((e) => ({
|
||||||
|
doc: e,
|
||||||
|
title: getIssueId(e.$lookup?.space as Team, e),
|
||||||
|
icon: tracker.icon.TrackerApplication,
|
||||||
|
component: IssueItem
|
||||||
|
}))
|
||||||
|
}
|
||||||
export default async (): Promise<Resources> => ({
|
export default async (): Promise<Resources> => ({
|
||||||
component: {
|
component: {
|
||||||
NopeComponent,
|
NopeComponent,
|
||||||
@ -95,5 +147,8 @@ export default async (): Promise<Resources> => ({
|
|||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
ProjectVisible: () => false
|
ProjectVisible: () => false
|
||||||
|
},
|
||||||
|
completion: {
|
||||||
|
IssueQuery: async (client: Client, query: string) => await queryIssue(tracker.class.Issue, client, query)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -63,12 +63,14 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
$: _id &&
|
$: if (_id && _class) {
|
||||||
_class &&
|
|
||||||
query.query(_class, { _id }, (result) => {
|
query.query(_class, { _id }, (result) => {
|
||||||
object = result[0]
|
object = result[0]
|
||||||
realObjectClass = object._class
|
realObjectClass = object._class
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
query.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
let keys: KeyedAttribute[] = []
|
let keys: KeyedAttribute[] = []
|
||||||
let collectionEditors: { key: KeyedAttribute; editor: AnyComponent }[] = []
|
let collectionEditors: { key: KeyedAttribute; editor: AnyComponent }[] = []
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
doc = r.shift()
|
doc = r.shift()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
docQuery.unsubscribe()
|
||||||
doc = value
|
doc = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
let preference: ViewletPreference | undefined
|
let preference: ViewletPreference | undefined
|
||||||
const preferenceQuery = createQuery()
|
const preferenceQuery = createQuery()
|
||||||
|
|
||||||
$: viewlet &&
|
$: if (viewlet) {
|
||||||
preferenceQuery.query(
|
preferenceQuery.query(
|
||||||
view.class.ViewletPreference,
|
view.class.ViewletPreference,
|
||||||
{
|
{
|
||||||
@ -41,6 +41,9 @@
|
|||||||
},
|
},
|
||||||
{ limit: 1 }
|
{ limit: 1 }
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
preferenceQuery.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "EPL-2.0",
|
"license": "EPL-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -rf ./dist && cross-env NODE_ENV=production webpack --stats-error-details && echo 'done'",
|
"build": "echo 'disabled'",
|
||||||
"bundle": "cp -r ../../server/front/bundle.js .",
|
"*build": "rm -rf ./dist && cross-env NODE_ENV=production webpack --stats-error-details && echo 'done'",
|
||||||
"docker:build": "docker build -t hardcoreeng/tracker-front .",
|
"*bundle": "cp -r ../../server/front/bundle.js .",
|
||||||
"docker:staging": "../../common/scripts/docker_tag.sh hardcoreeng/tracker-front staging",
|
"bundle": "echo 'disabled'",
|
||||||
"docker:push": "../../common/scripts/docker_tag.sh hardcoreeng/tracker-front",
|
"*docker:build": "docker build -t hardcoreeng/tracker-front .",
|
||||||
|
"*docker:staging": "../../common/scripts/docker_tag.sh hardcoreeng/tracker-front staging",
|
||||||
|
"*docker:push": "../../common/scripts/docker_tag.sh hardcoreeng/tracker-front",
|
||||||
"analyze": "cross-env NODE_ENV=production webpack --json > stats.json",
|
"analyze": "cross-env NODE_ENV=production webpack --json > stats.json",
|
||||||
"show": "webpack-bundle-analyzer stats.json dist",
|
"show": "webpack-bundle-analyzer stats.json dist",
|
||||||
"dev": "cross-env CLIENT_TYPE=dev webpack serve",
|
"dev": "cross-env CLIENT_TYPE=dev webpack serve",
|
||||||
@ -15,8 +17,8 @@
|
|||||||
"start": "cross-env NODE_ENV=production webpack serve",
|
"start": "cross-env NODE_ENV=production webpack serve",
|
||||||
"preformat-svelte": "prettier -w src/**/*.svelte",
|
"preformat-svelte": "prettier -w src/**/*.svelte",
|
||||||
"lint": "",
|
"lint": "",
|
||||||
"lint:fix": "yarn preformat-svelte && eslint --fix src",
|
"lint:fix": "",
|
||||||
"deploy": "cp -p public/* dist && aws s3 sync dist s3://anticrm-platform --delete --acl public-read"
|
"*deploy": "cp -p public/* dist && aws s3 sync dist s3://anticrm-platform --delete --acl public-read"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "~7.0.3",
|
"cross-env": "~7.0.3",
|
||||||
|
Loading…
Reference in New Issue
Block a user