Remove project button ()

Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
Vyacheslav Tumanov 2023-02-07 09:48:59 +05:00 committed by GitHub
parent 33b06c24dc
commit 61fbb4b78b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 35 deletions
models
server-tracker/src
tracker/src
plugins
server-plugins
tracker-resources/src
tracker/src

View File

@ -32,4 +32,8 @@ export function createModel (builder: Builder): void {
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverTracker.trigger.OnIssueUpdate
})
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverTracker.trigger.OnProjectRemove
})
}

View File

@ -56,7 +56,6 @@ import setting from '@hcengineering/setting'
import tags, { TagElement } from '@hcengineering/tags'
import task from '@hcengineering/task'
import {
Document,
Issue,
IssueChildInfo,
IssueParentInfo,
@ -343,28 +342,6 @@ export class TTimeSpendReport extends TAttachedDoc implements TimeSpendReport {
@Prop(TypeString(), tracker.string.TimeSpendReportDescription)
description!: string
}
/**
* @public
*/
@Model(tracker.class.Document, core.class.Doc, DOMAIN_TRACKER)
@UX(tracker.string.Document, tracker.icon.Document, tracker.string.Document)
export class TDocument extends TDoc implements Document {
@Prop(TypeString(), tracker.string.Title)
@Index(IndexKind.FullText)
title!: string
@Prop(TypeString(), tracker.string.DocumentIcon)
icon!: string | null
@Prop(TypeString(), tracker.string.DocumentColor)
color!: number
@Prop(TypeMarkup(), tracker.string.Description)
@Index(IndexKind.FullText)
content!: Markup
declare space: Ref<Team>
}
/**
* @public
@ -394,9 +371,6 @@ export class TProject extends TDoc implements Project {
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
comments!: number
@Prop(Collection(tracker.class.Document), tracker.string.Document)
documents!: number
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number

View File

@ -109,6 +109,8 @@
"AddIssueTooltip": "Add issue...",
"NewIssueDialogClose": "Do you want to close this dialog?",
"NewIssueDialogCloseNote": "All changes will be lost",
"RemoveProjectDialogClose": "Delete the project?",
"RemoveProjectDialogCloseNote": "Are you sure you want to delete this project? This operation cannot be undone",
"DueDatePopupTitle": "Due on {value}",
"DueDatePopupOverdueTitle": "Was due on {value}",
"DueDatePopupDescription": "{value, plural, =0 {Today} =1 {Tomorrow} other {# days remaining}}",

View File

@ -109,6 +109,8 @@
"AddIssueTooltip": "Добавить задачу\u2026",
"NewIssueDialogClose": "Вы действительно хотите закрыть окно?",
"NewIssueDialogCloseNote": "Все внесенные изменения будут потеряны",
"RemoveProjectDialogClose": "Удалить проект?",
"RemoveProjectDialogCloseNote": "Уверены, что хотите удалить этот проект? Эта операция не может быть отменена",
"DueDatePopupTitle": "Срок {value}",
"DueDatePopupOverdueTitle": "Должна была завершится {value}",
"DueDatePopupDescription": "{value, plural, =0 {Сегодня} =1 {Завтра} other {# дней осталось}}",

View File

@ -0,0 +1,57 @@
<!--
// Copyright © 2023 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 view from '@hcengineering/view'
import { Button, ButtonSize, LabelAndProps, showPopup } from '@hcengineering/ui'
import { getClient, MessageBox } from '@hcengineering/presentation'
import type { Project } from '@hcengineering/tracker'
import tracker from '../../plugin'
import { Ref, Space } from '@hcengineering/core'
import { createEventDispatcher } from 'svelte'
export let space: Ref<Space>
export let value: Project
export let size: ButtonSize = 'medium'
export let justify: 'left' | 'center' = 'center'
export let width: string | undefined = 'min-content'
export let showTooltip: LabelAndProps | undefined = undefined
const client = getClient()
const dispatch = createEventDispatcher()
async function showConfirmationDialog () {
showPopup(
MessageBox,
{
label: tracker.string.RemoveProjectDialogClose,
message: tracker.string.RemoveProjectDialogCloseNote
},
'top',
(result?: boolean) => {
if (result === true) {
dispatch('close')
removeProject()
}
}
)
}
async function removeProject () {
await client.removeDoc(tracker.class.Project, space, value._id)
}
</script>
{#if value}
<Button {size} {width} {justify} {showTooltip} icon={view.icon.Delete} on:click={() => showConfirmationDialog()} />
{/if}

View File

@ -37,8 +37,7 @@
comments: 0,
attachments: 0,
startDate: null,
targetDate: null,
documents: 0
targetDate: null
}
async function onSave () {

View File

@ -151,7 +151,8 @@
}
},
{ key: '', presenter: tracker.component.TargetDatePresenter },
{ key: '', presenter: tracker.component.ProjectStatusPresenter }
{ key: '', presenter: tracker.component.ProjectStatusPresenter },
{ key: '', presenter: tracker.component.DeleteProjectPresenter, props: { space } }
]}
projects={resultProjects}
{viewMode}

View File

@ -115,6 +115,7 @@ import IssueStatistics from './components/sprints/IssueStatistics.svelte'
import StatusRefPresenter from './components/issues/StatusRefPresenter.svelte'
import SprintRefPresenter from './components/sprints/SprintRefPresenter.svelte'
import { EmployeeAccount } from '@hcengineering/contact'
import DeleteProjectPresenter from './components/projects/DeleteProjectPresenter.svelte'
export { default as SubIssueList } from './components/issues/edit/SubIssueList.svelte'
@ -366,7 +367,8 @@ export default async (): Promise<Resources> => ({
IssueStatistics,
StatusRefPresenter,
RelatedIssuesSection,
RelatedIssueSelector
RelatedIssueSelector,
DeleteProjectPresenter
},
completion: {
IssueQuery: async (client: Client, query: string, filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }) =>

View File

@ -178,6 +178,9 @@ export default mergeIds(trackerId, tracker, {
NewIssueDialogClose: '' as IntlString,
NewIssueDialogCloseNote: '' as IntlString,
RemoveProjectDialogClose: '' as IntlString,
RemoveProjectDialogCloseNote: '' as IntlString,
CopyIssueUrl: '' as IntlString,
CopyIssueId: '' as IntlString,
CopyIssueBranch: '' as IntlString,
@ -351,6 +354,7 @@ export default mergeIds(trackerId, tracker, {
TimeSpendReport: '' as AnyComponent,
EstimationEditor: '' as AnyComponent,
TemplateEstimationEditor: '' as AnyComponent,
DeleteProjectPresenter: '' as AnyComponent,
Scrums: '' as AnyComponent,
ScrumRecordPanel: '' as AnyComponent,

View File

@ -354,7 +354,6 @@ export interface Project extends Doc {
targetDate: Timestamp | null
// Ref<Document>[]
documents: number
}
/**
@ -412,7 +411,6 @@ export default plugin(trackerId, {
Issue: '' as Ref<Class<Issue>>,
IssueDraft: '' as Ref<Class<IssueDraft>>,
IssueTemplate: '' as Ref<Class<IssueTemplate>>,
Document: '' as Ref<Class<Document>>,
Project: '' as Ref<Class<Project>>,
IssueStatus: '' as Ref<Class<IssueStatus>>,
IssueStatusCategory: '' as Ref<Class<IssueStatusCategory>>,

View File

@ -36,7 +36,7 @@ import { getMetadata } from '@hcengineering/platform'
import { Resource } from '@hcengineering/platform/lib/platform'
import { TriggerControl } from '@hcengineering/server-core'
import { addAssigneeNotification } from '@hcengineering/server-task-resources'
import tracker, { Issue, IssueParentInfo, TimeSpendReport, trackerId } from '@hcengineering/tracker'
import tracker, { Issue, IssueParentInfo, Project, TimeSpendReport, trackerId } from '@hcengineering/tracker'
async function updateSubIssues (
updateTx: TxUpdateDoc<Issue>,
@ -96,6 +96,34 @@ export async function addTrackerAssigneeNotification (
)
}
/**
* @public
*/
export async function OnProjectRemove (tx: Tx, control: TriggerControl): Promise<Tx[]> {
const actualTx = TxProcessor.extractTx(tx)
if (actualTx._class !== core.class.TxRemoveDoc) {
return []
}
const ctx = actualTx as TxUpdateDoc<Project>
const issues = await control.findAll(tracker.class.Issue, {
project: ctx.objectId
})
if (issues === undefined) return []
const res: Tx[] = []
for (const issue of issues) {
const issuePush = {
...issue,
project: null
}
const tx = control.txFactory.createTxUpdateDoc(issue._class, issue.space, issue._id, issuePush)
res.push(tx)
}
return res
}
/**
* @public
*/
@ -173,7 +201,8 @@ export default async () => ({
IssueTextPresenter: issueTextPresenter
},
trigger: {
OnIssueUpdate
OnIssueUpdate,
OnProjectRemove
}
})

View File

@ -32,6 +32,7 @@ export default plugin(serverTrackerId, {
IssueTextPresenter: '' as Resource<Presenter>
},
trigger: {
OnIssueUpdate: '' as Resource<TriggerFunc>
OnIssueUpdate: '' as Resource<TriggerFunc>,
OnProjectRemove: '' as Resource<TriggerFunc>
}
})