diff --git a/changelog.md b/changelog.md index 9847e903c1..ea7c32b168 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ Tracker: - Issue preview +- Enabled issue notifications ## 0.6.25 diff --git a/models/inventory/package.json b/models/inventory/package.json index d0056fd325..d90ba1e1a9 100644 --- a/models/inventory/package.json +++ b/models/inventory/package.json @@ -32,6 +32,7 @@ "@anticrm/model-core": "~0.6.0", "@anticrm/ui": "~0.6.0", "@anticrm/platform": "~0.6.6", + "@anticrm/notification": "~0.6.0", "@anticrm/inventory": "~0.6.0", "@anticrm/inventory-resources": "~0.6.0", "@anticrm/view": "~0.6.0", diff --git a/models/inventory/src/index.ts b/models/inventory/src/index.ts index e65167ac3d..47e27b0a43 100644 --- a/models/inventory/src/index.ts +++ b/models/inventory/src/index.ts @@ -20,9 +20,10 @@ import attachment from '@anticrm/model-attachment' import core, { TAttachedDoc } from '@anticrm/model-core' import { createAction } from '@anticrm/model-view' import workbench from '@anticrm/model-workbench' +import notification from '@anticrm/notification' +import setting from '@anticrm/setting' import type {} from '@anticrm/view' import view from '@anticrm/view' -import setting from '@anticrm/setting' import inventory from './plugin' export const DOMAIN_INVENTORY = 'inventory' as Domain @@ -149,6 +150,8 @@ export function createModel (builder: Builder): void { inventory.category.Inventory ) + builder.mixin(inventory.class.Product, core.class.Class, notification.mixin.LastViewAttached, {}) + createAction(builder, { label: inventory.string.CreateSubcategory, icon: inventory.icon.Categories, diff --git a/models/notification/src/index.ts b/models/notification/src/index.ts index 5c95b123a3..76ce6e4b40 100644 --- a/models/notification/src/index.ts +++ b/models/notification/src/index.ts @@ -18,18 +18,20 @@ import { Account, Doc, Domain, DOMAIN_MODEL, Ref, Timestamp, TxCUD } from '@anti import { ArrOf, Builder, Mixin, Model, Prop, TypeRef, TypeString, TypeTimestamp } from '@anticrm/model' import core, { TAttachedDoc, TClass, TDoc } from '@anticrm/model-core' import type { + AnotherUserNotifications, EmailNotification, LastView, - NotificationType, + LastViewAttached, + Notification, NotificationProvider, NotificationSetting, - Notification, NotificationStatus, + NotificationType, SpaceLastEdit } from '@anticrm/notification' import type { IntlString } from '@anticrm/platform' -import notification from './plugin' import setting from '@anticrm/setting' +import notification from './plugin' export const DOMAIN_NOTIFICATION = 'notification' as Domain @@ -95,6 +97,14 @@ export class TSpaceLastEdit extends TClass implements SpaceLastEdit { lastEditField!: string } +@Mixin(notification.mixin.AnotherUserNotifications, core.class.Class) +export class TAnotherUserNotifications extends TClass implements AnotherUserNotifications { + fields!: string[] +} + +@Mixin(notification.mixin.LastViewAttached, core.class.Class) +export class TLastViewAttached extends TClass implements LastViewAttached {} + export function createModel (builder: Builder): void { builder.createModel( TLastView, @@ -103,7 +113,9 @@ export function createModel (builder: Builder): void { TNotificationType, TNotificationProvider, TNotificationSetting, - TSpaceLastEdit + TSpaceLastEdit, + TAnotherUserNotifications, + TLastViewAttached ) builder.createDoc( diff --git a/models/server-inventory/src/index.ts b/models/server-inventory/src/index.ts index 131c9a526d..bb36dc2397 100644 --- a/models/server-inventory/src/index.ts +++ b/models/server-inventory/src/index.ts @@ -17,9 +17,8 @@ import { Builder } from '@anticrm/model' import core from '@anticrm/core' import inventory from '@anticrm/inventory' -import view from '@anticrm/view' import serverInventory from '@anticrm/server-inventory' -import serverCore from '@anticrm/server-core' +import view from '@anticrm/view' export function createModel (builder: Builder): void { builder.mixin(inventory.class.Product, core.class.Class, view.mixin.HTMLPresenter, { @@ -29,12 +28,4 @@ export function createModel (builder: Builder): void { builder.mixin(inventory.class.Product, core.class.Class, view.mixin.TextPresenter, { presenter: serverInventory.function.ProductTextPresenter }) - - builder.createDoc(serverCore.class.Trigger, core.space.Model, { - trigger: serverInventory.trigger.OnProductCreate - }) - - builder.createDoc(serverCore.class.Trigger, core.space.Model, { - trigger: serverInventory.trigger.OnProductUpdate - }) } diff --git a/models/server-task/src/index.ts b/models/server-task/src/index.ts index 8ae6c635fc..b76864526d 100644 --- a/models/server-task/src/index.ts +++ b/models/server-task/src/index.ts @@ -16,10 +16,9 @@ import { Builder } from '@anticrm/model' import core from '@anticrm/core' +import serverTask from '@anticrm/server-task' import task from '@anticrm/task' import view from '@anticrm/view' -import serverTask from '@anticrm/server-task' -import serverCore from '@anticrm/server-core' export function createModel (builder: Builder): void { builder.mixin(task.class.Issue, core.class.Class, view.mixin.HTMLPresenter, { @@ -29,12 +28,4 @@ export function createModel (builder: Builder): void { builder.mixin(task.class.Issue, core.class.Class, view.mixin.TextPresenter, { presenter: serverTask.function.IssueTextPresenter }) - - builder.createDoc(serverCore.class.Trigger, core.space.Model, { - trigger: serverTask.trigger.OnTaskCreate - }) - - builder.createDoc(serverCore.class.Trigger, core.space.Model, { - trigger: serverTask.trigger.OnTaskUpdate - }) } diff --git a/models/task/package.json b/models/task/package.json index 66b040a8ca..f5546e10cf 100644 --- a/models/task/package.json +++ b/models/task/package.json @@ -35,6 +35,7 @@ "@anticrm/model-workbench": "~0.6.1", "@anticrm/model-contact": "~0.6.1", "@anticrm/model-attachment": "~0.6.0", + "@anticrm/notification": "~0.6.0", "@anticrm/task": "~0.6.0", "@anticrm/task-resources": "~0.6.0", "@anticrm/model-chunter": "~0.6.0", diff --git a/models/task/src/index.ts b/models/task/src/index.ts index 6367646903..53360ea833 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -36,6 +36,7 @@ import attachment from '@anticrm/model-attachment' import chunter from '@anticrm/model-chunter' import core, { TAttachedDoc, TClass, TDoc, TSpace } from '@anticrm/model-core' import view, { actionTemplates as viewTemplates, createAction, template } from '@anticrm/model-view' +import notification from '@anticrm/notification' import { IntlString } from '@anticrm/platform' import tags from '@anticrm/tags' import { @@ -375,6 +376,11 @@ export function createModel (builder: Builder): void { editor: task.component.TaskHeader }) + builder.mixin(task.class.Task, core.class.Class, notification.mixin.LastViewAttached, {}) + builder.mixin(task.class.Task, core.class.Class, notification.mixin.AnotherUserNotifications, { + fields: ['assignee'] + }) + builder.createDoc(view.class.Viewlet, core.space.Model, { attachTo: task.class.Issue, descriptor: task.viewlet.Kanban, diff --git a/models/tracker/package.json b/models/tracker/package.json index 6f8dfbde9a..76db6f6477 100644 --- a/models/tracker/package.json +++ b/models/tracker/package.json @@ -35,6 +35,7 @@ "@anticrm/model-workbench": "~0.6.1", "@anticrm/model-contact": "~0.6.1", "@anticrm/model-attachment": "~0.6.0", + "@anticrm/notification": "~0.6.0", "@anticrm/tracker": "~0.6.0", "@anticrm/tracker-resources": "~0.6.0", "@anticrm/model-chunter": "~0.6.0", diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index 9fd898cba5..6b08ee6348 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -35,8 +35,8 @@ import attachment from '@anticrm/model-attachment' import chunter from '@anticrm/model-chunter' import core, { DOMAIN_SPACE, TAttachedDoc, TDoc, TSpace, TType } from '@anticrm/model-core' import view, { createAction } from '@anticrm/model-view' -import { KeyBinding } from '@anticrm/view' import workbench, { createNavigateAction } from '@anticrm/model-workbench' +import notification from '@anticrm/notification' import { Asset, IntlString } from '@anticrm/platform' import setting from '@anticrm/setting' import { @@ -49,6 +49,7 @@ import { ProjectStatus, Team } from '@anticrm/tracker' +import { KeyBinding } from '@anticrm/view' import tracker from './plugin' import presentation from '@anticrm/model-presentation' @@ -403,6 +404,11 @@ export function createModel (builder: Builder): void { editor: tracker.component.ProjectStatusEditor }) + builder.mixin(tracker.class.Issue, core.class.Class, notification.mixin.LastViewAttached, {}) + builder.mixin(tracker.class.Issue, core.class.Class, notification.mixin.AnotherUserNotifications, { + fields: ['assignee'] + }) + builder.createDoc( workbench.class.Application, core.space.Model, diff --git a/packages/theme/styles/components.scss b/packages/theme/styles/components.scss index 455b8045a5..74522c66aa 100644 --- a/packages/theme/styles/components.scss +++ b/packages/theme/styles/components.scss @@ -462,6 +462,38 @@ } } +/* List */ + +.antiList-cells { + display: flex; + align-items: center; + white-space: nowrap; + + &__checkCell, &__notifyCell { + display: flex; + justify-content: center; + align-items: center; + } + &__checkCell { visibility: hidden; } +} + +.antiList__row { + .antiList-cells__notifyCell { + z-index: 1; + } + + &:hover, &.checking { + .antiList-cells__checkCell { visibility: visible; } + .antiList-cells__notifyCell .notify-table-kind { + width: 1.15rem; + height: 1.15rem; + background-color: var(--highlight-hover); + border: 1px solid currentColor; + border-radius: .375rem; + } + } +} + /* Select */ .antiSelect { display: flex; diff --git a/plugins/notification-resources/src/components/LastViewEditor.svelte b/plugins/notification-resources/src/components/LastViewEditor.svelte index f2baf540ad..ca48a060e7 100644 --- a/plugins/notification-resources/src/components/LastViewEditor.svelte +++ b/plugins/notification-resources/src/components/LastViewEditor.svelte @@ -14,7 +14,7 @@ --> - +
diff --git a/plugins/notification/src/index.ts b/plugins/notification/src/index.ts index 3e89ae9cb3..917f857492 100644 --- a/plugins/notification/src/index.ts +++ b/plugins/notification/src/index.ts @@ -86,6 +86,18 @@ export interface SpaceLastEdit extends Class { lastEditField: string } +/** + * @public + */ +export interface LastViewAttached extends Class {} + +/** + * @public + */ +export interface AnotherUserNotifications extends Class { + fields: string[] +} + /** * @public */ @@ -109,7 +121,9 @@ export type NotificationClientFactoy = () => NotificationClient */ const notification = plugin(notificationId, { mixin: { - SpaceLastEdit: '' as Ref> + SpaceLastEdit: '' as Ref>, + AnotherUserNotifications: '' as Ref>, + LastViewAttached: '' as Ref> }, class: { LastView: '' as Ref>, diff --git a/plugins/tracker-resources/src/components/issues/Board.svelte b/plugins/tracker-resources/src/components/issues/Board.svelte index d89c3c8cec..04e0405363 100644 --- a/plugins/tracker-resources/src/components/issues/Board.svelte +++ b/plugins/tracker-resources/src/components/issues/Board.svelte @@ -18,12 +18,13 @@ import { Kanban, TypeState } from '@anticrm/kanban' import { createQuery } from '@anticrm/presentation' import type { Issue, IssueStatus, Team } from '@anticrm/tracker' - import { Button, Icon, IconAdd, showPopup, Tooltip, showPanel } from '@anticrm/ui' + import { Button, Icon, IconAdd, showPopup, Tooltip, showPanel, Component } from '@anticrm/ui' import { focusStore, ListSelectionProvider, SelectDirection, selectionStore } from '@anticrm/view-resources' import ActionContext from '@anticrm/view-resources/src/components/ActionContext.svelte' import Menu from '@anticrm/view-resources/src/components/Menu.svelte' import { onMount } from 'svelte' import tracker from '../../plugin' + import notification from '@anticrm/notification' import CreateIssue from '../CreateIssue.svelte' import AssigneePresenter from './AssigneePresenter.svelte' import IssuePresenter from './IssuePresenter.svelte' @@ -34,8 +35,6 @@ export let currentSpace: Ref export let baseMenuClass: Ref> | undefined = undefined - /* eslint-disable no-undef */ - const spaceQuery = createQuery() const statusesQuery = createQuery() @@ -64,10 +63,6 @@ } ) - /* eslint-disable prefer-const */ - /* eslint-disable no-unused-vars */ - let issue: Issue - function toIssue (object: any): WithLookup { return object as WithLookup } @@ -175,6 +170,9 @@ {currentSpace} isEditable={true} /> +
+ +
{#if issue && issueStatuses && issue.subIssues > 0} diff --git a/plugins/tracker-resources/src/components/issues/IssuesList.svelte b/plugins/tracker-resources/src/components/issues/IssuesList.svelte index 6ef6f0d780..88ea0b98db 100644 --- a/plugins/tracker-resources/src/components/issues/IssuesList.svelte +++ b/plugins/tracker-resources/src/components/issues/IssuesList.svelte @@ -17,13 +17,24 @@ import { Class, Doc, FindOptions, getObjectValue, Ref, WithLookup } from '@anticrm/core' import { getClient } from '@anticrm/presentation' import { Issue, IssueStatus, Team } from '@anticrm/tracker' - import { Button, CheckBox, Component, eventToHTMLElement, IconAdd, showPopup, Spinner, Tooltip } from '@anticrm/ui' + import { + Button, + CheckBox, + Component, + eventToHTMLElement, + IconAdd, + showPopup, + Spinner, + tooltip, + Tooltip + } from '@anticrm/ui' import { AttributeModel, BuildModelKey } from '@anticrm/view' import { buildModel, getObjectPresenter, LoadingProps, Menu } from '@anticrm/view-resources' import { createEventDispatcher } from 'svelte' import tracker from '../../plugin' import { IssuesGroupByKeys, issuesGroupEditorMap, IssuesOrderByKeys, issuesSortOrderMap } from '../../utils' import CreateIssue from '../CreateIssue.svelte' + import notification from '@anticrm/notification' export let _class: Ref> export let currentSpace: Ref | undefined = undefined @@ -181,8 +192,8 @@ {#each groupedIssues[category] as docObject (docObject._id)}
x === docObject)]} - class="listGrid" - class:mListGridChecked={selectedObjectIdsSet.has(docObject._id)} + class="listGrid antiList__row" + class:checking={selectedObjectIdsSet.has(docObject._id)} class:mListGridFixed={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)} class:mListGridSelected={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)} on:contextmenu|preventDefault={(event) => @@ -195,26 +206,33 @@ on:mouseover={() => handleRowFocused(docObject)} >
+
+
+
+ { + onObjectChecked([docObject], event.detail) + }} + /> +
+ +
+
{#each itemModels as attributeModel, attributeModelIndex} {#if attributeModelIndex === 0} -
- -
- { - onObjectChecked([docObject], event.detail) - }} - /> -
-
-
- -
+
+
{:else if attributeModelIndex === 1}
@@ -299,28 +317,13 @@ color: var(--theme-caption-color); border-bottom: 1px solid var(--theme-button-border-hovered); - &.mListGridChecked { + &.checking { background-color: var(--theme-table-bg-hover); - - .eListGridCheckBox { - opacity: 1; - } } &.mListGridSelected { background-color: var(--menu-bg-select); } - - .eListGridCheckBox { - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - - &:hover { - opacity: 1; - } - } } .filler { diff --git a/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte b/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte index c8ac6cfc86..48cc50adad 100644 --- a/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/EditIssue.svelte @@ -13,7 +13,7 @@ // limitations under the License. -->