From 4188d6a32bb389bf1be2bcb2d8d874fd5563b42c Mon Sep 17 00:00:00 2001 From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> Date: Sat, 26 Mar 2022 23:34:06 +0600 Subject: [PATCH] Reminders (#1200) Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> --- models/calendar/package.json | 1 + models/calendar/src/index.ts | 65 +++++++++++-- models/calendar/src/plugin.ts | 26 ++++- models/core/src/tx.ts | 9 +- models/recruit/src/review-model.ts | 3 + packages/core/src/memdb.ts | 2 +- packages/core/src/query.ts | 23 ++++- packages/panel/package.json | 1 + packages/panel/src/components/Panel.svelte | 8 +- .../presentation/src/components/Card.svelte | 2 +- .../src/components/SpaceSelect.svelte | 6 +- .../src/components/StyledTextBox.svelte | 4 + packages/ui/lang/en.json | 8 +- packages/ui/lang/ru.json | 8 +- packages/ui/src/components/ActionIcon.svelte | 2 +- .../ui/src/components/TimeShiftPicker.svelte | 79 +++++++++++++++ .../ui/src/components/TimeShiftPopup.svelte | 40 ++++++++ .../src/components/TimeShiftPresenter.svelte | 55 +++++++++++ packages/ui/src/index.ts | 1 + packages/ui/src/plugin.ts | 8 +- .../src/components/utils.ts | 13 ++- plugins/calendar-assets/assets/icons.svg | 3 + plugins/calendar-assets/lang/en.json | 9 +- plugins/calendar-assets/lang/ru.json | 9 +- plugins/calendar-assets/src/index.ts | 1 + .../src/components/CreateReminder.svelte | 91 +++++++++++++++++ .../src/components/DocReminder.svelte | 52 ++++++++++ .../src/components/DocRemindersPopup.svelte | 50 ++++++++++ .../src/components/EditEvent.svelte | 75 ++++++++++++++ .../src/components/EditReminder.svelte | 97 +++++++++++++++++++ .../src/components/ReminderPresenter.svelte | 42 ++++++++ .../src/components/RemindersPopup.svelte | 38 ++++++++ .../src/components/SaveEventReminder.svelte | 63 ++++++++++++ .../activity/ReminderViewlet.svelte | 43 ++++++++ plugins/calendar-resources/src/index.ts | 29 +++++- plugins/calendar-resources/src/plugin.ts | 9 ++ plugins/calendar/package.json | 1 + plugins/calendar/src/index.ts | 25 ++++- .../src/components/review/CreateReview.svelte | 1 + .../src/components/review/EditReview.svelte | 3 +- plugins/recruit/src/index.ts | 1 + .../src/components/EditDoc.svelte | 17 ++-- plugins/view-resources/src/utils.ts | 2 +- plugins/workbench-resources/package.json | 1 + .../src/components/Workbench.svelte | 10 ++ 45 files changed, 984 insertions(+), 52 deletions(-) create mode 100644 packages/ui/src/components/TimeShiftPicker.svelte create mode 100644 packages/ui/src/components/TimeShiftPopup.svelte create mode 100644 packages/ui/src/components/TimeShiftPresenter.svelte create mode 100644 plugins/calendar-resources/src/components/CreateReminder.svelte create mode 100644 plugins/calendar-resources/src/components/DocReminder.svelte create mode 100644 plugins/calendar-resources/src/components/DocRemindersPopup.svelte create mode 100644 plugins/calendar-resources/src/components/EditEvent.svelte create mode 100644 plugins/calendar-resources/src/components/EditReminder.svelte create mode 100644 plugins/calendar-resources/src/components/ReminderPresenter.svelte create mode 100644 plugins/calendar-resources/src/components/RemindersPopup.svelte create mode 100644 plugins/calendar-resources/src/components/SaveEventReminder.svelte create mode 100644 plugins/calendar-resources/src/components/activity/ReminderViewlet.svelte diff --git a/models/calendar/package.json b/models/calendar/package.json index 72d6c9d0b9..83ef9404ea 100644 --- a/models/calendar/package.json +++ b/models/calendar/package.json @@ -34,6 +34,7 @@ "@anticrm/calendar": "~0.6.0", "@anticrm/calendar-resources": "~0.6.0", "@anticrm/platform": "~0.6.5", + "@anticrm/notification": "~0.6.0", "@anticrm/model-core": "~0.6.0", "@anticrm/model-view": "~0.6.0", "@anticrm/model-workbench": "~0.6.1", diff --git a/models/calendar/src/index.ts b/models/calendar/src/index.ts index 3a0f546b3f..4750de05c6 100644 --- a/models/calendar/src/index.ts +++ b/models/calendar/src/index.ts @@ -13,19 +13,21 @@ // limitations under the License. // -import { Calendar, Event } from '@anticrm/calendar' +import activity from '@anticrm/activity' +import { Calendar, Event, Reminder } from '@anticrm/calendar' import { Employee } from '@anticrm/contact' import type { Domain, Markup, Ref, Timestamp } from '@anticrm/core' import { IndexKind } from '@anticrm/core' -import { Builder, Collection, Index, Model, Prop, TypeDate, TypeMarkup, TypeString, UX } from '@anticrm/model' +import { Builder, Collection, Index, Mixin, Model, Prop, TypeDate, TypeMarkup, TypeString, UX } from '@anticrm/model' import attachment from '@anticrm/model-attachment' import chunter from '@anticrm/model-chunter' import contact from '@anticrm/model-contact' import core, { TAttachedDoc } from '@anticrm/model-core' import { TSpaceWithStates } from '@anticrm/model-task' -import workbench from '@anticrm/model-workbench' -import calendar from './plugin' import view from '@anticrm/model-view' +import workbench from '@anticrm/model-workbench' +import notification from '@anticrm/notification' +import calendar from './plugin' export * from '@anticrm/calendar' @@ -42,9 +44,6 @@ export class TEvent extends TAttachedDoc implements Event { @Index(IndexKind.FullText) title!: string - @Prop(TypeString(), calendar.string.EventNumber) - number!: number - @Prop(TypeMarkup(), calendar.string.Description) @Index(IndexKind.FullText) description!: Markup @@ -69,8 +68,19 @@ export class TEvent extends TAttachedDoc implements Event { participants!: Ref[] } +@Mixin(calendar.mixin.Reminder, calendar.class.Event) +@UX(calendar.string.Reminder, calendar.icon.Calendar) +export class TReminder extends TEvent implements Reminder { + @Prop(TypeDate(true), calendar.string.Shift) + shift!: Timestamp + + @Prop(TypeString(), calendar.string.State) + @Index(IndexKind.Indexed) + state!: 'active' | 'done' +} + export function createModel (builder: Builder): void { - builder.createModel(TCalendar, TEvent) + builder.createModel(TCalendar, TEvent, TReminder) builder.createDoc(workbench.class.Application, core.space.Model, { label: calendar.string.ApplicationLabelCalendar, @@ -88,6 +98,21 @@ export function createModel (builder: Builder): void { } }, calendar.app.Calendar) + builder.createDoc(notification.class.NotificationType, core.space.Model, { + label: calendar.string.Reminder + }, calendar.ids.ReminderNotification) + + builder.createDoc(activity.class.TxViewlet, core.space.Model, { + objectClass: calendar.mixin.Reminder, + icon: calendar.icon.Reminder, + txClass: core.class.TxMixin, + label: calendar.string.CreatedReminder, + component: calendar.activity.ReminderViewlet, + display: 'emphasized', + editable: false, + hideOnRemove: true + }, calendar.ids.ReminderViewlet) + builder.createDoc( view.class.ViewletDescriptor, core.space.Model, @@ -99,6 +124,30 @@ export function createModel (builder: Builder): void { calendar.viewlet.Calendar ) + builder.createDoc( + view.class.Action, + core.space.Model, + { + label: calendar.string.RemindMeAt, + icon: calendar.icon.Reminder, + action: calendar.actionImpl.SaveEventReminder + }, + calendar.action.SaveEventReminder + ) + + builder.createDoc(view.class.ActionTarget, core.space.Model, { + target: calendar.class.Event, + action: calendar.action.SaveEventReminder + }) + + builder.mixin(calendar.mixin.Reminder, core.class.Class, view.mixin.AttributePresenter, { + presenter: calendar.component.ReminderPresenter + }) + + builder.mixin(calendar.class.Event, core.class.Class, view.mixin.ObjectEditor, { + editor: calendar.component.EditEvent + }) + // Use generic child presenter builder.mixin(calendar.class.Event, core.class.Class, view.mixin.AttributePresenter, { presenter: view.component.ObjectPresenter diff --git a/models/calendar/src/plugin.ts b/models/calendar/src/plugin.ts index f1bdce8209..f6f548412d 100644 --- a/models/calendar/src/plugin.ts +++ b/models/calendar/src/plugin.ts @@ -13,24 +13,40 @@ // limitations under the License. // +import { TxViewlet } from '@anticrm/activity' import { calendarId } from '@anticrm/calendar' import calendar from '@anticrm/calendar-resources/src/plugin' -import { Ref } from '@anticrm/core' -import type { IntlString } from '@anticrm/platform' +import { Doc, Ref } from '@anticrm/core' +import type { IntlString, Resource } from '@anticrm/platform' import { mergeIds } from '@anticrm/platform' import { AnyComponent } from '@anticrm/ui' -import { ViewletDescriptor } from '@anticrm/view' +import { Action, ViewletDescriptor } from '@anticrm/view' export default mergeIds(calendarId, calendar, { component: { CreateCalendar: '' as AnyComponent, - CalendarView: '' as AnyComponent + CalendarView: '' as AnyComponent, + EditEvent: '' as AnyComponent, + ReminderPresenter: '' as AnyComponent + }, + action: { + SaveEventReminder: '' as Ref + }, + actionImpl: { + SaveEventReminder: '' as Resource<(object: Doc) => Promise> }, string: { ApplicationLabelCalendar: '' as IntlString, - Event: '' as IntlString + Event: '' as IntlString, + Reminder: '' as IntlString, + Shift: '' as IntlString, + State: '' as IntlString, + CreatedReminder: '' as IntlString }, viewlet: { Calendar: '' as Ref + }, + ids: { + ReminderViewlet: '' as Ref } }) diff --git a/models/core/src/tx.ts b/models/core/src/tx.ts index d5a83901fb..ac0aaf8c61 100644 --- a/models/core/src/tx.ts +++ b/models/core/src/tx.ts @@ -13,12 +13,14 @@ // limitations under the License. // -import type { +import { AttachedDoc, Class, Data, Doc, DocumentUpdate, + DOMAIN_TX, + IndexKind, Mixin, MixinUpdate, PropertyType, @@ -34,8 +36,7 @@ import type { TxRemoveDoc, TxUpdateDoc } from '@anticrm/core' -import { DOMAIN_TX } from '@anticrm/core' -import { Model } from '@anticrm/model' +import { Index, Model } from '@anticrm/model' import core from './component' import { TDoc } from './core' @@ -48,7 +49,9 @@ export class TTx extends TDoc implements Tx { @Model(core.class.TxCUD, core.class.Tx) export class TTxCUD extends TTx implements TxCUD { + @Index(IndexKind.Indexed) objectId!: Ref + objectClass!: Ref> } diff --git a/models/recruit/src/review-model.ts b/models/recruit/src/review-model.ts index 480be11083..fa7c9885a5 100644 --- a/models/recruit/src/review-model.ts +++ b/models/recruit/src/review-model.ts @@ -24,6 +24,9 @@ export class TReview extends TEvent implements Review { @Prop(TypeRef(recruit.mixin.Candidate), recruit.string.Candidate) declare attachedTo: Ref + @Prop(TypeString(), recruit.string.Review) + number!: number + @Prop(TypeString(), recruit.string.Verdict) @Index(IndexKind.FullText) verdict!: string diff --git a/packages/core/src/memdb.ts b/packages/core/src/memdb.ts index bb5817446b..9ff4007917 100644 --- a/packages/core/src/memdb.ts +++ b/packages/core/src/memdb.ts @@ -140,7 +140,7 @@ export abstract class MemDb extends TxProcessor { result = this.getObjectsByClass(baseClass) } - result = matchQuery(result, query) + result = matchQuery(result, query, _class, this.hierarchy) if (baseClass !== _class) { // We need to filter instances without mixin was set diff --git a/packages/core/src/query.ts b/packages/core/src/query.ts index dcf24f12c7..6c2b1df292 100644 --- a/packages/core/src/query.ts +++ b/packages/core/src/query.ts @@ -1,5 +1,6 @@ import { DocumentQuery } from '.' -import { Doc } from './classes' +import { Class, Doc, Ref } from './classes' +import { Hierarchy } from './hierarchy' import { getObjectValue } from './objvalue' import { createPredicates, isPredicate } from './predicate' import { SortingOrder, SortingQuery } from './storage' @@ -71,15 +72,31 @@ function getValue (key: string, obj: any): any { /** * @public */ -export function matchQuery (docs: Doc[], query: DocumentQuery): Doc[] { +export function matchQuery (docs: Doc[], query: DocumentQuery, clazz: Ref>, hierarchy: Hierarchy): Doc[] { let result = [...docs] for (const key in query) { if (key === '_id' && ((query._id as any)?.$like === undefined || query._id === undefined)) continue const value = (query as any)[key] - result = findProperty(result, key, value) + const tkey = checkMixinKey(key, clazz, hierarchy) + result = findProperty(result, tkey, value) if (result.length === 0) { break } } return result } + +function checkMixinKey (key: string, clazz: Ref>, hierarchy: Hierarchy): string { + if (!key.includes('.')) { + try { + const attr = hierarchy.getAttribute(clazz, key) + if (hierarchy.isMixin(attr.attributeOf)) { + // It is mixin + key = attr.attributeOf + '.' + key + } + } catch (err: any) { + // ignore, if + } + } + return key +} diff --git a/packages/panel/package.json b/packages/panel/package.json index e6e4886507..646d97a3b2 100644 --- a/packages/panel/package.json +++ b/packages/panel/package.json @@ -39,6 +39,7 @@ "@anticrm/chunter": "~0.6.1", "@anticrm/presentation": "~0.6.2", "@anticrm/activity": "~0.6.0", + "@anticrm/calendar": "~0.6.0", "@anticrm/notification": "~0.6.0" } } diff --git a/packages/panel/src/components/Panel.svelte b/packages/panel/src/components/Panel.svelte index bec297b2bc..3271f521ba 100644 --- a/packages/panel/src/components/Panel.svelte +++ b/packages/panel/src/components/Panel.svelte @@ -17,6 +17,7 @@ import activity from '@anticrm/activity' import type { Doc } from '@anticrm/core' import notification from '@anticrm/notification' + import calendar from '@anticrm/calendar' import type { Asset } from '@anticrm/platform' import { ActionIcon,AnyComponent,AnySvelteComponent,Component,Icon,IconClose,IconExpand,IconMoreH,Scroller } from '@anticrm/ui' import { createEventDispatcher } from 'svelte' @@ -43,7 +44,12 @@ {#if subtitle }{subtitle}{/if} - +
+ +
+ +
+
{#if $$slots.subtitle}
diff --git a/packages/presentation/src/components/Card.svelte b/packages/presentation/src/components/Card.svelte index 75de843e88..6b77319c83 100644 --- a/packages/presentation/src/components/Card.svelte +++ b/packages/presentation/src/components/Card.svelte @@ -25,7 +25,7 @@ import presentation from '..' export let spaceClass: Ref> | undefined = undefined - export let space: Ref + export let space: Ref | undefined = undefined export let spaceQuery: DocumentQuery | undefined = { archived: false } export let spaceLabel: IntlString | undefined = undefined export let spacePlaceholder: IntlString | undefined = undefined diff --git a/packages/presentation/src/components/SpaceSelect.svelte b/packages/presentation/src/components/SpaceSelect.svelte index 64f4d15a2b..2e4834ca85 100644 --- a/packages/presentation/src/components/SpaceSelect.svelte +++ b/packages/presentation/src/components/SpaceSelect.svelte @@ -26,7 +26,7 @@ export let spaceQuery: DocumentQuery | undefined = { archived: false } export let label: IntlString export let placeholder: IntlString - export let value: Ref + export let value: Ref | undefined export let show: boolean = false let selected: Space | undefined @@ -34,8 +34,8 @@ const client = getClient() - async function updateSelected (value: Ref) { - selected = await client.findOne(_class, { ...(spaceQuery ?? {}), _id: value }) + async function updateSelected (value: Ref | undefined) { + selected = value !== undefined ? await client.findOne(_class, { ...(spaceQuery ?? {}), _id: value }) : undefined } $: updateSelected(value) diff --git a/packages/text-editor/src/components/StyledTextBox.svelte b/packages/text-editor/src/components/StyledTextBox.svelte index 0120e56043..418054b05b 100644 --- a/packages/text-editor/src/components/StyledTextBox.svelte +++ b/packages/text-editor/src/components/StyledTextBox.svelte @@ -57,6 +57,10 @@ }} on:blur={() => { focused = false + if (alwaysEdit) { + dispatch('value', rawValue) + content = rawValue + } }} on:value={(evt) => { rawValue = evt.detail diff --git a/packages/ui/lang/en.json b/packages/ui/lang/en.json index 566353e06c..9050d5a498 100644 --- a/packages/ui/lang/en.json +++ b/packages/ui/lang/en.json @@ -17,7 +17,11 @@ "Today": "Today", "English": "English", "Russian": "Russian", - "CalendarLeft": "<", - "CalendarRight": ">" + "MinutesBefore": "{minutes, plural, =1 {a minute before} other {# minutes before}}", + "HoursBefore": "{hours, plural, =1 {an hour before} other {# hours before}}", + "DaysBefore": "{days, plural, =1 {a day before} other {# days before}}", + "MinutesAfter": "{minutes, plural, =1 {in a minute} other {in # minutes}}", + "HoursAfter": "{hours, plural, =1 {in an hour} other {in # hours}}", + "DaysAfter": "{days, plural, =1 {in a day} other {in # days}}" } } diff --git a/packages/ui/lang/ru.json b/packages/ui/lang/ru.json index d9608362bc..e6fd4fefcb 100644 --- a/packages/ui/lang/ru.json +++ b/packages/ui/lang/ru.json @@ -17,7 +17,11 @@ "Today": "Сегодня", "English": "Английский", "Russian": "Русский", - "CalendarLeft": "<", - "CalendarRight": ">" + "MinutesBefore": "{minutes, plural, =1 {за минуту} other {за # минут}}", + "HoursBefore": "{hours, plural, =1 {за час} other {за # часа}}", + "DaysBefore": "{days, plural, =1 {за день} =3 {за # дня} other {за # дней}}", + "MinutesAfter": "{minutes, plural, =1 {через минуту} other {через # минут}}", + "HoursAfter": "{hours, plural, =1 {через час} other {через # часа}}", + "DaysAfter": "{days, plural, =1 {через день} other {через # дней}}" } } diff --git a/packages/ui/src/components/ActionIcon.svelte b/packages/ui/src/components/ActionIcon.svelte index e5780f23fc..373d8262f3 100644 --- a/packages/ui/src/components/ActionIcon.svelte +++ b/packages/ui/src/components/ActionIcon.svelte @@ -25,7 +25,7 @@ export let direction: TooltipAligment | undefined = undefined export let icon: Asset | AnySvelteComponent export let size: 'small' | 'medium' | 'large' - export let action: (ev?: Event) => Promise | void = async () => { } + export let action: (ev: Event) => Promise | void = async () => { } export let invisible: boolean = false diff --git a/packages/ui/src/components/TimeShiftPicker.svelte b/packages/ui/src/components/TimeShiftPicker.svelte new file mode 100644 index 0000000000..75ab0c4e0f --- /dev/null +++ b/packages/ui/src/components/TimeShiftPicker.svelte @@ -0,0 +1,79 @@ + + + +
{ + btn.focus() + if (!opened) { + opened = true + showPopup(TimeShiftPopup, { title, value, direction }, container, (ev) => { + console.log('picker close handle') + console.log(ev) + changeValue(ev) + opened = false + }, changeValue) + } + }} +> + + +
+ + +
+
diff --git a/packages/ui/src/components/TimeShiftPopup.svelte b/packages/ui/src/components/TimeShiftPopup.svelte new file mode 100644 index 0000000000..995b4d5ce8 --- /dev/null +++ b/packages/ui/src/components/TimeShiftPopup.svelte @@ -0,0 +1,40 @@ + + + +
+ {#each values as value} +
+ { dispatch('close', value) }} /> +
+ {/each} +
\ No newline at end of file diff --git a/packages/ui/src/components/TimeShiftPresenter.svelte b/packages/ui/src/components/TimeShiftPresenter.svelte new file mode 100644 index 0000000000..205bd5af20 --- /dev/null +++ b/packages/ui/src/components/TimeShiftPresenter.svelte @@ -0,0 +1,55 @@ + + + +{time} \ No newline at end of file diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index e550a7bf72..caa671ff1c 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -66,6 +66,7 @@ export { default as DropdownPopup } from './components/DropdownPopup.svelte' export { default as DropdownLabels } from './components/DropdownLabels.svelte' export { default as ShowMore } from './components/ShowMore.svelte' export { default as Menu } from './components/Menu.svelte' +export { default as TimeShiftPicker } from './components/TimeShiftPicker.svelte' export { default as ErrorPresenter } from './components/ErrorPresenter.svelte' export { default as Scroller } from './components/Scroller.svelte' diff --git a/packages/ui/src/plugin.ts b/packages/ui/src/plugin.ts index c0f57fd3a8..bc96135bec 100644 --- a/packages/ui/src/plugin.ts +++ b/packages/ui/src/plugin.ts @@ -41,7 +41,13 @@ export default plugin(uiId, { NotSelected: '' as IntlString, Today: '' as IntlString, English: '' as IntlString, - Russian: '' as IntlString + Russian: '' as IntlString, + MinutesBefore: '' as IntlString, + HoursBefore: '' as IntlString, + DaysBefore: '' as IntlString, + MinutesAfter: '' as IntlString, + HoursAfter: '' as IntlString, + DaysAfter: '' as IntlString }, metadata: { DefaultApplication: '' as Metadata diff --git a/plugins/activity-resources/src/components/utils.ts b/plugins/activity-resources/src/components/utils.ts index 989f1f74d4..a66f4a5c64 100644 --- a/plugins/activity-resources/src/components/utils.ts +++ b/plugins/activity-resources/src/components/utils.ts @@ -50,6 +50,16 @@ export function getDTxProps (dtx: DisplayTx): any { return { tx: dtx.tx, value: dtx.doc, dtx } } +function getViewlet (viewlets: Map, dtx: DisplayTx): TxDisplayViewlet | undefined { + let key: string + if (dtx.mixinTx?.mixin !== undefined && dtx.tx._id === dtx.mixinTx._id) { + key = activityKey(dtx.mixinTx.mixin, dtx.tx._class) + } else { + key = activityKey(dtx.tx.objectClass, dtx.tx._class) + } + return viewlets.get(key) +} + export async function updateViewlet ( client: TxOperations, viewlets: Map, @@ -61,8 +71,7 @@ export async function updateViewlet ( props: any modelIcon: Asset | undefined }> { - const key = activityKey(dtx.tx.objectClass, dtx.tx._class) - let viewlet: TxDisplayViewlet = viewlets.get(key) + let viewlet = getViewlet(viewlets, dtx) const props = getDTxProps(dtx) let model: AttributeModel[] = [] diff --git a/plugins/calendar-assets/assets/icons.svg b/plugins/calendar-assets/assets/icons.svg index 3a8b7a69d4..41c0f0143d 100644 --- a/plugins/calendar-assets/assets/icons.svg +++ b/plugins/calendar-assets/assets/icons.svg @@ -6,4 +6,7 @@ + + + diff --git a/plugins/calendar-assets/lang/en.json b/plugins/calendar-assets/lang/en.json index c590a3dbbb..4eda6db8d0 100644 --- a/plugins/calendar-assets/lang/en.json +++ b/plugins/calendar-assets/lang/en.json @@ -25,6 +25,13 @@ "TableView": "Table", "DueMinutes": "{minutes, plural, =0 {less than a minute} =1 {a minute} other {# minutes}}", "DueHours": "{hours, plural, =0 {less than an hour} =1 {1 hour} other {# hours}}", - "DueDays": "{days, plural, =0 {today} =1 {1 day} other {# days}}" + "DueDays": "{days, plural, =0 {today} =1 {1 day} other {# days}}", + "Reminder": "Reminder", + "ReminderTime": "Reminder time", + "RemindMeAt": "Remind me at", + "EditReminder": "Edit reminder", + "CreateReminder": "Create reminder", + "CreatedReminder": "Created a reminder", + "Reminders": "Reminders" } } \ No newline at end of file diff --git a/plugins/calendar-assets/lang/ru.json b/plugins/calendar-assets/lang/ru.json index a0eae53111..ab2274b50d 100644 --- a/plugins/calendar-assets/lang/ru.json +++ b/plugins/calendar-assets/lang/ru.json @@ -25,6 +25,13 @@ "TableView": "Таблица", "DueMinutes": "{minutes, plural, =0 {меньше минуты} =1 {минута} other {# минут}}", "DueHours": "{hours, plural, =0 {меньше часа} =1 {1 час} other {# часы}}", - "DueDays": "{days, plural, =0 {сегодня} =1 {1 день} other {# дня}}" + "DueDays": "{days, plural, =0 {сегодня} =1 {1 день} other {# дня}}", + "Reminder": "Напоминание", + "RemindMeAt": "Напомнить мне", + "ReminderTime": "Время напоминания", + "EditReminder": "Редактировать напоминание", + "CreateReminder": "Создать напоминание", + "CreatedReminder": "Создал напоминание", + "Reminders": "Напоминания" } } \ No newline at end of file diff --git a/plugins/calendar-assets/src/index.ts b/plugins/calendar-assets/src/index.ts index 808bcb35dd..3af46ab086 100644 --- a/plugins/calendar-assets/src/index.ts +++ b/plugins/calendar-assets/src/index.ts @@ -19,6 +19,7 @@ import calendar, { calendarId } from '@anticrm/calendar' const icons = require('../assets/icons.svg') as string // eslint-disable-line loadMetadata(calendar.icon, { Calendar: `${icons}#calendar`, + Reminder: `${icons}#reminder`, Location: `${icons}#location` }) diff --git a/plugins/calendar-resources/src/components/CreateReminder.svelte b/plugins/calendar-resources/src/components/CreateReminder.svelte new file mode 100644 index 0000000000..ad1b70f428 --- /dev/null +++ b/plugins/calendar-resources/src/components/CreateReminder.svelte @@ -0,0 +1,91 @@ + + + + 0 && participants.length > 0} + {space} + on:close={() => { + dispatch('close') + }} +> + + +
+ +
+ { + participants.push(evt.detail._id) + participants = participants + }} + on:delete={(evt) => { + const _id = evt.detail._id + const index = participants.findIndex((p) => p === _id) + if (index !== -1) { + participants.splice(index, 1) + participants = participants + } + }} + noItems={calendar.string.NoParticipants} + /> +
+
diff --git a/plugins/calendar-resources/src/components/DocReminder.svelte b/plugins/calendar-resources/src/components/DocReminder.svelte new file mode 100644 index 0000000000..2a4a880cae --- /dev/null +++ b/plugins/calendar-resources/src/components/DocReminder.svelte @@ -0,0 +1,52 @@ + + + +{#if isEvent} + click(e)} /> +{:else} + click(e)} /> +{/if} \ No newline at end of file diff --git a/plugins/calendar-resources/src/components/DocRemindersPopup.svelte b/plugins/calendar-resources/src/components/DocRemindersPopup.svelte new file mode 100644 index 0000000000..0fb42cd68b --- /dev/null +++ b/plugins/calendar-resources/src/components/DocRemindersPopup.svelte @@ -0,0 +1,50 @@ + + + + +
+