// // Copyright © 2020, 2021 Anticrm Platform Contributors. // // 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. // import type { Person } from '@hcengineering/contact' import { AttachedDoc, Attribute, Class, Doc, Mixin, type Rank, Ref, Space, Status, StatusCategory, Timestamp, SpaceType, SpaceTypeDescriptor, TypedSpace } from '@hcengineering/core' import { NotificationType } from '@hcengineering/notification' import type { Asset, IntlString, Plugin, Resource } from '@hcengineering/platform' import { plugin } from '@hcengineering/platform' import type { AnyComponent, ComponentExtensionId } from '@hcengineering/ui' import { Action, IconProps, ViewletDescriptor } from '@hcengineering/view' export * from './utils' export type { Rank } from '@hcengineering/rank' /** @public */ export interface DocWithRank extends Doc { rank: Rank } export interface Project extends TypedSpace { type: Ref } /** * @public */ export interface Task extends AttachedDoc { kind: Ref status: Ref isDone?: boolean number: number assignee: Ref | null dueDate: Timestamp | null comments?: number attachments?: number labels?: number identifier: string rank: Rank } /** * @public */ export interface KanbanCard extends Class { card: AnyComponent } export interface ProjectStatus extends IconProps { _id: Ref taskType: Ref } /** * @public */ export type TaskTypeKind = 'task' | 'subtask' | 'both' /** * @public */ export interface TaskTypeDescriptor extends Doc { name: IntlString description: IntlString icon: Asset baseClass: Ref> // If specified, will allow to be created by users, system type overwise allowCreate: boolean statusCategoriesFunc?: Resource<(project: ProjectType) => Ref[]> openTasks?: Resource<(value: TaskType) => Promise> } /** * @public */ export interface TaskStatusFactory { category: Ref statuses: (string | [string, number, Ref?])[] } /** * @public */ export interface TaskType extends Doc, IconProps { parent: Ref descriptor: Ref name: string kind: TaskTypeKind // Specify if task is allowed to be used as subtask of following tasks. allowedAsChildOf?: Ref[] ofClass: Ref> // Base class for task targetClass: Ref> // Class or Mixin mixin to hold all user defined attributes. // Allowed statuses and ordering statuses: Ref[] statusClass: Ref> statusCategories: Ref[] } /** * @public * * A a mixin for Class bind to taskType. */ export interface TaskTypeClass extends Class { taskType: Ref projectType: Ref } /** * @public * * A a mixin for Class bind to taskType. */ export interface ProjectTypeClass extends Class { projectType: Ref } /** * @public * * Define a user customized project type. */ export interface ProjectType extends SpaceType { descriptor: Ref tasks: Ref[] description: string // Color and extra options per project type. // All statuses per project has same color. statuses: ProjectStatus[] // A mixin for project targetClass: Ref> // disable automation workflow classic: boolean } /** * @public */ export interface ProjectTypeDescriptor extends SpaceTypeDescriptor { allowedClassic?: boolean allowedTaskTypeDescriptors?: Ref[] // if undefined we allow all possible baseClass: Ref> editor?: AnyComponent } /** * @public */ export enum TaskOrdering { State = 'state', LastUpdated = 'modifiedOn', DueDate = 'dueDate', Manual = 'rank' } /** * @public */ export const taskId = 'task' as Plugin /** * @public */ const task = plugin(taskId, { app: { Tasks: '' as Ref }, action: { Move: '' as Ref }, mixin: { KanbanCard: '' as Ref>, TaskTypeClass: '' as Ref>, ProjectTypeClass: '' as Ref> }, attribute: { State: '' as Ref> }, string: { StartDate: '' as IntlString, DueDate: '' as IntlString, TaskState: '' as IntlString, TaskStateTitle: '' as IntlString, TaskStateDone: '' as IntlString, TaskNumber: '' as IntlString, Todo: '' as IntlString, TaskDone: '' as IntlString, TaskDueTo: '' as IntlString, TaskParent: '' as IntlString, IssueName: '' as IntlString, TaskComments: '' as IntlString, TaskLabels: '' as IntlString, Rank: '' as IntlString, EditStates: '' as IntlString, MarkAsDone: '' as IntlString, MarkAsUndone: '' as IntlString, Kanban: '' as IntlString, ApplicationLabelTask: '' as IntlString, AssignedToMe: '' as IntlString, Dashboard: '' as IntlString, ProjectTypes: '' as IntlString, TaskType: '' as IntlString, ProjectType: '' as IntlString, Identifier: '' as IntlString }, class: { ProjectTypeDescriptor: '' as Ref>, ProjectType: '' as Ref>, Project: '' as Ref>, TaskTypeDescriptor: '' as Ref>, TaskType: '' as Ref>, Task: '' as Ref> }, viewlet: { Kanban: '' as Ref, Dashboard: '' as Ref, StatusTable: '' as Ref }, icon: { Task: '' as Asset, Kanban: '' as Asset, TodoCheck: '' as Asset, TodoUnCheck: '' as Asset, ManageTemplates: '' as Asset, TaskState: '' as Asset, Dashboard: '' as Asset }, global: { // Global task root, if not attached to some other object. Task: '' as Ref }, space: { Sequence: '' as Ref, Statuses: '' as Ref }, statusCategory: { UnStarted: '' as Ref, // For classic project type ToDo: '' as Ref, Active: '' as Ref, Won: '' as Ref, Lost: '' as Ref }, component: { ProjectTypeSelector: '' as AnyComponent, CreateStatePopup: '' as AnyComponent }, ids: { AssigneedNotification: '' as Ref, ManageProjects: '' as Ref }, extensions: { ProjectEditorExtension: '' as ComponentExtensionId } }) export default task