Skip to content

Commit 4188d6a

Browse files
authored
Reminders (#1200)
Signed-off-by: Denis Bykhov <[email protected]>
1 parent e875f51 commit 4188d6a

File tree

45 files changed

+983
-51
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+983
-51
lines changed

models/calendar/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@anticrm/calendar": "~0.6.0",
3535
"@anticrm/calendar-resources": "~0.6.0",
3636
"@anticrm/platform": "~0.6.5",
37+
"@anticrm/notification": "~0.6.0",
3738
"@anticrm/model-core": "~0.6.0",
3839
"@anticrm/model-view": "~0.6.0",
3940
"@anticrm/model-workbench": "~0.6.1",

models/calendar/src/index.ts

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@
1313
// limitations under the License.
1414
//
1515

16-
import { Calendar, Event } from '@anticrm/calendar'
16+
import activity from '@anticrm/activity'
17+
import { Calendar, Event, Reminder } from '@anticrm/calendar'
1718
import { Employee } from '@anticrm/contact'
1819
import type { Domain, Markup, Ref, Timestamp } from '@anticrm/core'
1920
import { IndexKind } from '@anticrm/core'
20-
import { Builder, Collection, Index, Model, Prop, TypeDate, TypeMarkup, TypeString, UX } from '@anticrm/model'
21+
import { Builder, Collection, Index, Mixin, Model, Prop, TypeDate, TypeMarkup, TypeString, UX } from '@anticrm/model'
2122
import attachment from '@anticrm/model-attachment'
2223
import chunter from '@anticrm/model-chunter'
2324
import contact from '@anticrm/model-contact'
2425
import core, { TAttachedDoc } from '@anticrm/model-core'
2526
import { TSpaceWithStates } from '@anticrm/model-task'
27+
import view from '@anticrm/model-view'
2628
import workbench from '@anticrm/model-workbench'
29+
import notification from '@anticrm/notification'
2730
import calendar from './plugin'
28-
import view from '@anticrm/model-view'
2931

3032
export * from '@anticrm/calendar'
3133

@@ -42,9 +44,6 @@ export class TEvent extends TAttachedDoc implements Event {
4244
@Index(IndexKind.FullText)
4345
title!: string
4446

45-
@Prop(TypeString(), calendar.string.EventNumber)
46-
number!: number
47-
4847
@Prop(TypeMarkup(), calendar.string.Description)
4948
@Index(IndexKind.FullText)
5049
description!: Markup
@@ -69,8 +68,19 @@ export class TEvent extends TAttachedDoc implements Event {
6968
participants!: Ref<Employee>[]
7069
}
7170

71+
@Mixin(calendar.mixin.Reminder, calendar.class.Event)
72+
@UX(calendar.string.Reminder, calendar.icon.Calendar)
73+
export class TReminder extends TEvent implements Reminder {
74+
@Prop(TypeDate(true), calendar.string.Shift)
75+
shift!: Timestamp
76+
77+
@Prop(TypeString(), calendar.string.State)
78+
@Index(IndexKind.Indexed)
79+
state!: 'active' | 'done'
80+
}
81+
7282
export function createModel (builder: Builder): void {
73-
builder.createModel(TCalendar, TEvent)
83+
builder.createModel(TCalendar, TEvent, TReminder)
7484

7585
builder.createDoc(workbench.class.Application, core.space.Model, {
7686
label: calendar.string.ApplicationLabelCalendar,
@@ -88,6 +98,21 @@ export function createModel (builder: Builder): void {
8898
}
8999
}, calendar.app.Calendar)
90100

101+
builder.createDoc(notification.class.NotificationType, core.space.Model, {
102+
label: calendar.string.Reminder
103+
}, calendar.ids.ReminderNotification)
104+
105+
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
106+
objectClass: calendar.mixin.Reminder,
107+
icon: calendar.icon.Reminder,
108+
txClass: core.class.TxMixin,
109+
label: calendar.string.CreatedReminder,
110+
component: calendar.activity.ReminderViewlet,
111+
display: 'emphasized',
112+
editable: false,
113+
hideOnRemove: true
114+
}, calendar.ids.ReminderViewlet)
115+
91116
builder.createDoc(
92117
view.class.ViewletDescriptor,
93118
core.space.Model,
@@ -99,6 +124,30 @@ export function createModel (builder: Builder): void {
99124
calendar.viewlet.Calendar
100125
)
101126

127+
builder.createDoc(
128+
view.class.Action,
129+
core.space.Model,
130+
{
131+
label: calendar.string.RemindMeAt,
132+
icon: calendar.icon.Reminder,
133+
action: calendar.actionImpl.SaveEventReminder
134+
},
135+
calendar.action.SaveEventReminder
136+
)
137+
138+
builder.createDoc(view.class.ActionTarget, core.space.Model, {
139+
target: calendar.class.Event,
140+
action: calendar.action.SaveEventReminder
141+
})
142+
143+
builder.mixin(calendar.mixin.Reminder, core.class.Class, view.mixin.AttributePresenter, {
144+
presenter: calendar.component.ReminderPresenter
145+
})
146+
147+
builder.mixin(calendar.class.Event, core.class.Class, view.mixin.ObjectEditor, {
148+
editor: calendar.component.EditEvent
149+
})
150+
102151
// Use generic child presenter
103152
builder.mixin(calendar.class.Event, core.class.Class, view.mixin.AttributePresenter, {
104153
presenter: view.component.ObjectPresenter

models/calendar/src/plugin.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,40 @@
1313
// limitations under the License.
1414
//
1515

16+
import { TxViewlet } from '@anticrm/activity'
1617
import { calendarId } from '@anticrm/calendar'
1718
import calendar from '@anticrm/calendar-resources/src/plugin'
18-
import { Ref } from '@anticrm/core'
19-
import type { IntlString } from '@anticrm/platform'
19+
import { Doc, Ref } from '@anticrm/core'
20+
import type { IntlString, Resource } from '@anticrm/platform'
2021
import { mergeIds } from '@anticrm/platform'
2122
import { AnyComponent } from '@anticrm/ui'
22-
import { ViewletDescriptor } from '@anticrm/view'
23+
import { Action, ViewletDescriptor } from '@anticrm/view'
2324

2425
export default mergeIds(calendarId, calendar, {
2526
component: {
2627
CreateCalendar: '' as AnyComponent,
27-
CalendarView: '' as AnyComponent
28+
CalendarView: '' as AnyComponent,
29+
EditEvent: '' as AnyComponent,
30+
ReminderPresenter: '' as AnyComponent
31+
},
32+
action: {
33+
SaveEventReminder: '' as Ref<Action>
34+
},
35+
actionImpl: {
36+
SaveEventReminder: '' as Resource<(object: Doc) => Promise<void>>
2837
},
2938
string: {
3039
ApplicationLabelCalendar: '' as IntlString,
31-
Event: '' as IntlString
40+
Event: '' as IntlString,
41+
Reminder: '' as IntlString,
42+
Shift: '' as IntlString,
43+
State: '' as IntlString,
44+
CreatedReminder: '' as IntlString
3245
},
3346
viewlet: {
3447
Calendar: '' as Ref<ViewletDescriptor>
48+
},
49+
ids: {
50+
ReminderViewlet: '' as Ref<TxViewlet>
3551
}
3652
})

models/core/src/tx.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
// limitations under the License.
1414
//
1515

16-
import type {
16+
import {
1717
AttachedDoc,
1818
Class,
1919
Data,
2020
Doc,
2121
DocumentUpdate,
22+
DOMAIN_TX,
23+
IndexKind,
2224
Mixin,
2325
MixinUpdate,
2426
PropertyType,
@@ -34,8 +36,7 @@ import type {
3436
TxRemoveDoc,
3537
TxUpdateDoc
3638
} from '@anticrm/core'
37-
import { DOMAIN_TX } from '@anticrm/core'
38-
import { Model } from '@anticrm/model'
39+
import { Index, Model } from '@anticrm/model'
3940
import core from './component'
4041
import { TDoc } from './core'
4142

@@ -48,7 +49,9 @@ export class TTx extends TDoc implements Tx {
4849

4950
@Model(core.class.TxCUD, core.class.Tx)
5051
export class TTxCUD<T extends Doc> extends TTx implements TxCUD<T> {
52+
@Index(IndexKind.Indexed)
5153
objectId!: Ref<T>
54+
5255
objectClass!: Ref<Class<T>>
5356
}
5457

models/recruit/src/review-model.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export class TReview extends TEvent implements Review {
2424
@Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Candidate)
2525
declare attachedTo: Ref<Candidate>
2626

27+
@Prop(TypeString(), recruit.string.Review)
28+
number!: number
29+
2730
@Prop(TypeString(), recruit.string.Verdict)
2831
@Index(IndexKind.FullText)
2932
verdict!: string

packages/core/src/memdb.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export abstract class MemDb extends TxProcessor {
140140
result = this.getObjectsByClass(baseClass)
141141
}
142142

143-
result = matchQuery(result, query)
143+
result = matchQuery(result, query, _class, this.hierarchy)
144144

145145
if (baseClass !== _class) {
146146
// We need to filter instances without mixin was set

packages/core/src/query.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { DocumentQuery } from '.'
2-
import { Doc } from './classes'
2+
import { Class, Doc, Ref } from './classes'
3+
import { Hierarchy } from './hierarchy'
34
import { getObjectValue } from './objvalue'
45
import { createPredicates, isPredicate } from './predicate'
56
import { SortingOrder, SortingQuery } from './storage'
@@ -71,15 +72,31 @@ function getValue (key: string, obj: any): any {
7172
/**
7273
* @public
7374
*/
74-
export function matchQuery<T extends Doc> (docs: Doc[], query: DocumentQuery<T>): Doc[] {
75+
export function matchQuery<T extends Doc> (docs: Doc[], query: DocumentQuery<T>, clazz: Ref<Class<T>>, hierarchy: Hierarchy): Doc[] {
7576
let result = [...docs]
7677
for (const key in query) {
7778
if (key === '_id' && ((query._id as any)?.$like === undefined || query._id === undefined)) continue
7879
const value = (query as any)[key]
79-
result = findProperty(result, key, value)
80+
const tkey = checkMixinKey(key, clazz, hierarchy)
81+
result = findProperty(result, tkey, value)
8082
if (result.length === 0) {
8183
break
8284
}
8385
}
8486
return result
8587
}
88+
89+
function checkMixinKey<T extends Doc> (key: string, clazz: Ref<Class<T>>, hierarchy: Hierarchy): string {
90+
if (!key.includes('.')) {
91+
try {
92+
const attr = hierarchy.getAttribute(clazz, key)
93+
if (hierarchy.isMixin(attr.attributeOf)) {
94+
// It is mixin
95+
key = attr.attributeOf + '.' + key
96+
}
97+
} catch (err: any) {
98+
// ignore, if
99+
}
100+
}
101+
return key
102+
}

packages/panel/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"@anticrm/chunter": "~0.6.1",
4040
"@anticrm/presentation": "~0.6.2",
4141
"@anticrm/activity": "~0.6.0",
42+
"@anticrm/calendar": "~0.6.0",
4243
"@anticrm/notification": "~0.6.0"
4344
}
4445
}

packages/panel/src/components/Panel.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import activity from '@anticrm/activity'
1818
import type { Doc } from '@anticrm/core'
1919
import notification from '@anticrm/notification'
20+
import calendar from '@anticrm/calendar'
2021
import type { Asset } from '@anticrm/platform'
2122
import { ActionIcon,AnyComponent,AnySvelteComponent,Component,Icon,IconClose,IconExpand,IconMoreH,Scroller } from '@anticrm/ui'
2223
import { createEventDispatcher } from 'svelte'
@@ -43,7 +44,12 @@
4344
{#if subtitle }<span class="ac-header__description">{subtitle}</span>{/if}
4445
</div>
4546
</div>
46-
<Component is={notification.component.LastViewEditor} props={{ value: object }} />
47+
<div class="flex">
48+
<Component is={calendar.component.DocReminder} props={{ value: object, title }} />
49+
<div class="ml-2">
50+
<Component is={notification.component.LastViewEditor} props={{ value: object }} />
51+
</div>
52+
</div>
4753
</div>
4854
{#if $$slots.subtitle}
4955
<div class="ac-subtitle">

packages/presentation/src/components/Card.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import presentation from '..'
2626
2727
export let spaceClass: Ref<Class<Space>> | undefined = undefined
28-
export let space: Ref<Space>
28+
export let space: Ref<Space> | undefined = undefined
2929
export let spaceQuery: DocumentQuery<Space> | undefined = { archived: false }
3030
export let spaceLabel: IntlString | undefined = undefined
3131
export let spacePlaceholder: IntlString | undefined = undefined

0 commit comments

Comments
 (0)