@things-factory/announcement 10.1.269 → 10.1.271
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/announcement/announcement-resolver.js +4 -0
- package/dist-server/service/announcement/announcement-resolver.js.map +1 -1
- package/dist-server/service/announcement/announcement-service.d.ts +2 -0
- package/dist-server/service/announcement/announcement-service.js +6 -1
- package/dist-server/service/announcement/announcement-service.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/server/service/announcement/announcement-resolver.ts +4 -0
- package/server/service/announcement/announcement-service.ts +5 -0
- package/test/announcement-persistence.test.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/announcement",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.271",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "dist-client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -36,18 +36,18 @@
|
|
|
36
36
|
"@operato/shell": "^10.29.69",
|
|
37
37
|
"@operato/styles": "^10.29.1",
|
|
38
38
|
"@operato/utils": "^10.0.0",
|
|
39
|
-
"@things-factory/ai-assistant": "^10.1.
|
|
40
|
-
"@things-factory/attachment-base": "^10.1.
|
|
41
|
-
"@things-factory/auth-base": "^10.1.
|
|
39
|
+
"@things-factory/ai-assistant": "^10.1.271",
|
|
40
|
+
"@things-factory/attachment-base": "^10.1.271",
|
|
41
|
+
"@things-factory/auth-base": "^10.1.271",
|
|
42
42
|
"@things-factory/env": "^10.1.149",
|
|
43
|
-
"@things-factory/i18n-base": "^10.1.
|
|
44
|
-
"@things-factory/notification": "^10.1.
|
|
45
|
-
"@things-factory/organization": "^10.1.
|
|
46
|
-
"@things-factory/shell": "^10.1.
|
|
43
|
+
"@things-factory/i18n-base": "^10.1.271",
|
|
44
|
+
"@things-factory/notification": "^10.1.271",
|
|
45
|
+
"@things-factory/organization": "^10.1.271",
|
|
46
|
+
"@things-factory/shell": "^10.1.270",
|
|
47
47
|
"graphql-scalars": "^1.22.0",
|
|
48
48
|
"graphql-tag": "^2.12.6",
|
|
49
49
|
"graphql-upload": "^15.0.2",
|
|
50
50
|
"lit": "^3.1.2"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "843bc2608d8c89348ced871777535966758927db"
|
|
53
53
|
}
|
|
@@ -19,6 +19,7 @@ import { Announcement, AnnouncementAudience, AnnouncementImportance, Announcemen
|
|
|
19
19
|
import { inputRefusal, isCurrent, owedReminder, periodOf, popupDue, publishedStatusOf, publishRefusal, rankOf, readerNarrowingOf, readerStateOf } from './announcement-rules'
|
|
20
20
|
import {
|
|
21
21
|
alignRoster,
|
|
22
|
+
announcementNoticeKey,
|
|
22
23
|
ANNOUNCEMENT_REF_TYPE,
|
|
23
24
|
audiencesOf,
|
|
24
25
|
isWriter,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
AnnouncementReceiptRow,
|
|
40
41
|
AnnouncementSummary
|
|
41
42
|
} from './announcement-types'
|
|
43
|
+
import { closeNotices } from '@things-factory/notification'
|
|
42
44
|
|
|
43
45
|
const WRITE = '@privilege(category: "announcement", privilege: "mutation", domainOwnerGranted: true)'
|
|
44
46
|
|
|
@@ -247,6 +249,8 @@ export class AnnouncementResolver {
|
|
|
247
249
|
if (!Object.keys(patch).length) return visible.announcement
|
|
248
250
|
if (!receipt) await repository.save({ domain, announcement: { id }, user: { id: user.id }, listed: false, ...patch, creator: user, updater: user } as any)
|
|
249
251
|
else await repository.update(receipt.id, { ...patch, updater: user })
|
|
252
|
+
/* Read: its notice is read too, on every device and screen (ADR-0164 amendment 1) - one reading, not two. */
|
|
253
|
+
if (patch.readAt) await closeNotices(tx, domain, 'announcement', announcementNoticeKey(id), [user.id])
|
|
250
254
|
/* The reader's other windows - their badge asks again. */
|
|
251
255
|
tellChange(context as any, { kind: 'announcement', id, userIds: [user.id] })
|
|
252
256
|
return visible.announcement
|
|
@@ -147,6 +147,9 @@ async function receiversOf(userIds: string[], tx?: EntityManager) {
|
|
|
147
147
|
return people.filter(one => one.status === UserStatus.ACTIVATED).map(one => ({ id: one.id, email: one.email, locale: (one as any).locale }))
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/** What an announcement's notices tell of - a reader's are closed once they read it. */
|
|
151
|
+
export const announcementNoticeKey = (id: string) => `announcement:${id}`
|
|
152
|
+
|
|
150
153
|
/**
|
|
151
154
|
* The notice of an announcement (notification ADR-0164): in the app and by web push always - the `announcement` type is
|
|
152
155
|
* what pops it up - and by mail when the announcement asks for it and the domain has mail on.
|
|
@@ -159,6 +162,8 @@ function noticeOf(one: Announcement, kind: NoticeKind, receivers: Notice['receiv
|
|
|
159
162
|
words: lng => noticeWordsOf(one, kind, sayIn(lng)),
|
|
160
163
|
address: viewAddressOf(one.id),
|
|
161
164
|
link,
|
|
165
|
+
/* closed for a person once they read it (`readAnnouncement`) */
|
|
166
|
+
key: announcementNoticeKey(one.id),
|
|
162
167
|
label: `announcement ${kind} ${one.id}`,
|
|
163
168
|
/* The mail carries the whole body, drawn from its Markdown; the inbox and push show the summary. */
|
|
164
169
|
format: 'markdown',
|
|
@@ -16,6 +16,9 @@ const { DataSource } = require('typeorm')
|
|
|
16
16
|
const told: { domain: any; notice: any }[] = []
|
|
17
17
|
jest.mock('@things-factory/notification', () => ({
|
|
18
18
|
...jest.requireActual('@things-factory/notification/dist-server/controllers/notice/notice-delivery-record.js'),
|
|
19
|
+
/* a reader's notice is closed as they read (ADR-0164 amendment 1) - the real closing, on the kept notices */
|
|
20
|
+
closeNotices: jest.requireActual('@things-factory/notification/dist-server/service/notification/notice-service.js').closeNotices,
|
|
21
|
+
Notification: jest.requireActual('@things-factory/notification/dist-server/service/notification/notification.js').Notification,
|
|
19
22
|
sendNotice: async (domain: any, notice: any) => {
|
|
20
23
|
told.push({ domain, notice })
|
|
21
24
|
return { receivers: notice.receivers.length, email: { sent: notice.channels?.email ? notice.receivers.length : 0, failed: 0 }, teams: { sent: 0, failed: 0 } }
|
|
@@ -26,6 +29,7 @@ jest.mock('@things-factory/notification', () => ({
|
|
|
26
29
|
|
|
27
30
|
const shell = require('@things-factory/shell')
|
|
28
31
|
const authBase = require('@things-factory/auth-base')
|
|
32
|
+
const notification = require('@things-factory/notification')
|
|
29
33
|
const contact = require('@things-factory/contact')
|
|
30
34
|
const bizBase = require('@things-factory/biz-base')
|
|
31
35
|
const attachmentBase = require('@things-factory/attachment-base')
|
|
@@ -55,7 +59,7 @@ beforeAll(async () => {
|
|
|
55
59
|
synchronize: true,
|
|
56
60
|
dropSchema: true,
|
|
57
61
|
namingStrategy: new shell.NamingStrategy(),
|
|
58
|
-
entities: [...shell.entities, ...authBase.entities, ...bizBase.entities, ...contact.entities, ...organization.entities, ...attachmentBase.entities, Announcement, AnnouncementAudience, AnnouncementReceipt, AnnouncementRevision],
|
|
62
|
+
entities: [...shell.entities, ...authBase.entities, ...bizBase.entities, ...contact.entities, ...organization.entities, ...attachmentBase.entities, Announcement, AnnouncementAudience, AnnouncementReceipt, AnnouncementRevision, notification.Notification],
|
|
59
63
|
logging: false
|
|
60
64
|
})
|
|
61
65
|
await dataSource.initialize()
|