@things-factory/notification 6.1.18 → 6.1.22

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.
Files changed (108) hide show
  1. package/client/{bootstrap.js → bootstrap.ts} +13 -9
  2. package/client/pages/notification/notification-list-page.ts +267 -0
  3. package/client/pages/notification-rule/notification-rule-importer.ts +93 -0
  4. package/client/pages/notification-rule/notification-rule-list-page.ts +395 -0
  5. package/client/route.ts +10 -0
  6. package/client/tsconfig.json +13 -0
  7. package/client/viewparts/notification-badge.ts +58 -0
  8. package/client/viewparts/notification-item.ts +242 -0
  9. package/client/viewparts/notification-list.ts +171 -0
  10. package/client/viewparts/notification-sender.ts +126 -0
  11. package/client/viewparts/{notification-setting-let.js → notification-setting-let.ts} +48 -52
  12. package/dist-client/actions/notification-fcm.d.ts +7 -0
  13. package/dist-client/actions/notification-fcm.js +125 -0
  14. package/dist-client/actions/notification-fcm.js.map +1 -0
  15. package/dist-client/bootstrap.d.ts +1 -0
  16. package/dist-client/bootstrap.js +112 -0
  17. package/dist-client/bootstrap.js.map +1 -0
  18. package/dist-client/index.d.ts +5 -0
  19. package/dist-client/index.js +6 -0
  20. package/dist-client/index.js.map +1 -0
  21. package/dist-client/pages/notification/notification-list-page.d.ts +49 -0
  22. package/dist-client/pages/notification/notification-list-page.js +262 -0
  23. package/dist-client/pages/notification/notification-list-page.js.map +1 -0
  24. package/dist-client/pages/notification-rule/notification-rule-importer.d.ts +22 -0
  25. package/dist-client/pages/notification-rule/notification-rule-importer.js +100 -0
  26. package/dist-client/pages/notification-rule/notification-rule-importer.js.map +1 -0
  27. package/dist-client/pages/notification-rule/notification-rule-list-page.d.ts +62 -0
  28. package/dist-client/pages/notification-rule/notification-rule-list-page.js +380 -0
  29. package/dist-client/pages/notification-rule/notification-rule-list-page.js.map +1 -0
  30. package/dist-client/reducers/notification.d.ts +8 -0
  31. package/dist-client/reducers/notification.js +22 -0
  32. package/dist-client/reducers/notification.js.map +1 -0
  33. package/dist-client/route.d.ts +1 -0
  34. package/dist-client/route.js +11 -0
  35. package/dist-client/route.js.map +1 -0
  36. package/dist-client/tsconfig.tsbuildinfo +1 -0
  37. package/dist-client/viewparts/notification-badge.d.ts +15 -0
  38. package/dist-client/viewparts/notification-badge.js +61 -0
  39. package/dist-client/viewparts/notification-badge.js.map +1 -0
  40. package/dist-client/viewparts/notification-item.d.ts +16 -0
  41. package/dist-client/viewparts/notification-item.js +249 -0
  42. package/dist-client/viewparts/notification-item.js.map +1 -0
  43. package/dist-client/viewparts/notification-list.d.ts +20 -0
  44. package/dist-client/viewparts/notification-list.js +160 -0
  45. package/dist-client/viewparts/notification-list.js.map +1 -0
  46. package/dist-client/viewparts/notification-sender.d.ts +13 -0
  47. package/dist-client/viewparts/notification-sender.js +122 -0
  48. package/dist-client/viewparts/notification-sender.js.map +1 -0
  49. package/dist-client/viewparts/notification-setting-let.d.ts +20 -0
  50. package/dist-client/viewparts/notification-setting-let.js +193 -0
  51. package/dist-client/viewparts/notification-setting-let.js.map +1 -0
  52. package/dist-server/service/index.js +10 -1
  53. package/dist-server/service/index.js.map +1 -1
  54. package/dist-server/service/notification/index.js +6 -3
  55. package/dist-server/service/notification/index.js.map +1 -1
  56. package/dist-server/service/notification/notification-mutation.js +110 -0
  57. package/dist-server/service/notification/notification-mutation.js.map +1 -0
  58. package/dist-server/service/notification/notification-query.js +109 -0
  59. package/dist-server/service/notification/notification-query.js.map +1 -0
  60. package/dist-server/service/notification/notification-subscription.js +45 -0
  61. package/dist-server/service/notification/notification-subscription.js.map +1 -0
  62. package/dist-server/service/notification/notification-type.js +82 -0
  63. package/dist-server/service/notification/notification-type.js.map +1 -0
  64. package/dist-server/service/notification/notification.js +81 -8
  65. package/dist-server/service/notification/notification.js.map +1 -1
  66. package/dist-server/service/notification-rule/event-subscriber.js +21 -0
  67. package/dist-server/service/notification-rule/event-subscriber.js.map +1 -0
  68. package/dist-server/service/notification-rule/index.js +12 -0
  69. package/dist-server/service/notification-rule/index.js.map +1 -0
  70. package/dist-server/service/notification-rule/notification-rule-history.js +146 -0
  71. package/dist-server/service/notification-rule/notification-rule-history.js.map +1 -0
  72. package/dist-server/service/notification-rule/notification-rule-mutation.js +170 -0
  73. package/dist-server/service/notification-rule/notification-rule-mutation.js.map +1 -0
  74. package/dist-server/service/notification-rule/notification-rule-query.js +97 -0
  75. package/dist-server/service/notification-rule/notification-rule-query.js.map +1 -0
  76. package/dist-server/service/notification-rule/notification-rule-type.js +102 -0
  77. package/dist-server/service/notification-rule/notification-rule-type.js.map +1 -0
  78. package/dist-server/service/notification-rule/notification-rule.js +146 -0
  79. package/dist-server/service/notification-rule/notification-rule.js.map +1 -0
  80. package/dist-server/tsconfig.tsbuildinfo +1 -1
  81. package/helps/notification/noti-box.md +160 -0
  82. package/helps/notification/noti-rule.md +160 -0
  83. package/helps/notification/notibox.md +160 -0
  84. package/package.json +15 -12
  85. package/server/service/index.ts +14 -0
  86. package/server/service/notification/index.ts +6 -3
  87. package/server/service/notification/notification-mutation.ts +119 -0
  88. package/server/service/notification/notification-query.ts +70 -0
  89. package/server/service/notification/{notification-resolver.ts → notification-subscription.ts} +4 -4
  90. package/server/service/notification/notification-type.ts +55 -0
  91. package/server/service/notification/notification.ts +87 -14
  92. package/server/service/notification-rule/event-subscriber.ts +20 -0
  93. package/server/service/notification-rule/index.ts +9 -0
  94. package/server/service/notification-rule/notification-rule-history.ts +130 -0
  95. package/server/service/notification-rule/notification-rule-mutation.ts +203 -0
  96. package/server/service/notification-rule/notification-rule-query.ts +62 -0
  97. package/server/service/notification-rule/notification-rule-type.ts +71 -0
  98. package/server/service/notification-rule/notification-rule.ts +125 -0
  99. package/server/tsconfig.json +9 -0
  100. package/things-factory.config.js +7 -1
  101. package/client/viewparts/notification-badge.js +0 -63
  102. package/client/viewparts/notification-item.js +0 -250
  103. package/client/viewparts/notification-list.js +0 -177
  104. package/client/viewparts/notification-sender.js +0 -128
  105. package/tsconfig.json +0 -9
  106. /package/client/actions/{notification-fcm.js → notification-fcm.ts} +0 -0
  107. /package/client/{index.js → index.ts} +0 -0
  108. /package/client/reducers/{notification.js → notification.ts} +0 -0
@@ -1,19 +1,22 @@
1
1
  import gql from 'graphql-tag'
2
2
 
3
3
  import { notify } from '@operato/layout'
4
- import { auth } from '@things-factory/auth-base'
5
- import { i18next } from '@things-factory/i18n-base'
6
- import { notificationStore, route, store, subscribe as graphqlSubscribe } from '@things-factory/shell'
4
+ import { auth } from '@things-factory/auth-base/dist-client'
5
+ import { i18next } from '@operato/i18n'
6
+ import { notificationStore, route, store } from '@operato/shell'
7
+ import { subscribe as graphqlSubscribe } from '@operato/graphql'
7
8
 
8
9
  import { subscribe, unsubscribe, UPDATE_NOTIFICATION } from './actions/notification-fcm'
9
10
  import notification from './reducers/notification'
10
11
 
12
+ var graphqlSubscription: any
13
+
11
14
  export default async function bootstrap() {
12
15
  /* initialize reducers */
13
16
  store.addReducers({ notification })
14
17
 
15
- async function onnotification(notification) {
16
- store.dispatch(async dispatch => {
18
+ async function onnotification(notification?: any) {
19
+ store.dispatch((async dispatch => {
17
20
  if (notification) {
18
21
  await notificationStore.add(notification)
19
22
  await notificationStore.limit()
@@ -25,7 +28,7 @@ export default async function bootstrap() {
25
28
  type: UPDATE_NOTIFICATION,
26
29
  history: [...history]
27
30
  })
28
- })
31
+ }) as any)
29
32
  }
30
33
 
31
34
  auth.on('presignout', async () => {
@@ -60,7 +63,8 @@ export default async function bootstrap() {
60
63
  }
61
64
  }
62
65
  `
63
- this.graphqlSubscription = await graphqlSubscribe(
66
+
67
+ graphqlSubscription = await graphqlSubscribe(
64
68
  {
65
69
  query,
66
70
  variables: {
@@ -112,8 +116,8 @@ export default async function bootstrap() {
112
116
  }
113
117
  })
114
118
 
115
- document.addEventListener('notify', event => {
116
- let { message, level, ex = '', option = {} } = event.detail
119
+ document.addEventListener('notify', (event: Event) => {
120
+ let { message, level, ex = '', option = {} } = (event as CustomEvent).detail
117
121
  const title = message.split(' .\n')[0]
118
122
 
119
123
  if (level === 'error') {
@@ -0,0 +1,267 @@
1
+ import '@operato/data-grist'
2
+
3
+ import { CommonButtonStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
4
+ import { PageView, store } from '@operato/shell'
5
+ import { css, html } from 'lit'
6
+ import { customElement, property, query } from 'lit/decorators.js'
7
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements'
8
+ import { ColumnConfig, DataGrist, FetchOption, SortersControl } from '@operato/data-grist'
9
+ import { client } from '@operato/graphql'
10
+ import { i18next, localize } from '@operato/i18n'
11
+ import { notify } from '@operato/layout'
12
+ import { OxPopup } from '@operato/popup'
13
+ import { isMobileDevice } from '@operato/utils'
14
+
15
+ import { connect } from 'pwa-helpers/connect-mixin'
16
+ import gql from 'graphql-tag'
17
+
18
+ @customElement('notification-list-page')
19
+ export class NotificationListPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
20
+ static styles = [
21
+ ScrollbarStyles,
22
+ CommonGristStyles,
23
+ css`
24
+ :host {
25
+ display: flex;
26
+
27
+ width: 100%;
28
+
29
+ --grid-record-emphasized-background-color: red;
30
+ --grid-record-emphasized-color: yellow;
31
+ }
32
+ `
33
+ ]
34
+
35
+ @property({ type: Object }) gristConfig: any
36
+ @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
37
+
38
+ @query('ox-grist') private grist!: DataGrist
39
+ @query('#sorter-control') private sortersControl!: OxPopup
40
+
41
+ get context() {
42
+ return {
43
+ search: {
44
+ handler: (search: string) => {
45
+ this.grist.searchText = search
46
+ },
47
+ placeholder: i18next.t('title.notification list'),
48
+ value: this.grist.searchText
49
+ },
50
+ filter: {
51
+ handler: () => {
52
+ this.grist.toggleHeadroom()
53
+ }
54
+ },
55
+ help: 'notification/notification',
56
+ actions: [
57
+ {
58
+ title: i18next.t('button.save'),
59
+ action: this._updateNotification.bind(this),
60
+ ...CommonButtonStyles.save
61
+ },
62
+ {
63
+ title: i18next.t('button.delete'),
64
+ action: this._deleteNotification.bind(this),
65
+ ...CommonButtonStyles.delete
66
+ }
67
+ ]
68
+ }
69
+ }
70
+
71
+ render() {
72
+ const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')
73
+
74
+ return html`
75
+ <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
76
+ <div slot="headroom">
77
+ <div id="filters">
78
+ <ox-filters-form autofocus></ox-filters-form>
79
+ </div>
80
+
81
+ <div id="sorters">
82
+ Sort
83
+ <mwc-icon
84
+ @click=${e => {
85
+ const target = e.currentTarget
86
+ this.sortersControl.open({
87
+ right: 0,
88
+ top: target.offsetTop + target.offsetHeight
89
+ })
90
+ }}
91
+ >expand_more</mwc-icon
92
+ >
93
+ <ox-popup id="sorter-control">
94
+ <ox-sorters-control> </ox-sorters-control>
95
+ </ox-popup>
96
+ </div>
97
+
98
+ <div id="modes">
99
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</mwc-icon>
100
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</mwc-icon>
101
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
102
+ </div>
103
+ </div>
104
+ </ox-grist>
105
+ `
106
+ }
107
+
108
+ async pageInitialized(lifecycle: any) {
109
+ this.gristConfig = {
110
+ list: {
111
+ fields: ['title', 'body'],
112
+ details: ['state', 'updatedAt']
113
+ },
114
+ columns: [
115
+ { type: 'gutter', gutterName: 'sequence' },
116
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
117
+ {
118
+ type: 'string',
119
+ name: 'title',
120
+ header: i18next.t('field.title'),
121
+ record: {
122
+ editable: false
123
+ },
124
+ filter: 'search',
125
+ sortable: true,
126
+ width: 150
127
+ },
128
+ {
129
+ type: 'string',
130
+ name: 'body',
131
+ header: i18next.t('field.body'),
132
+ record: {
133
+ editable: false
134
+ },
135
+ filter: 'search',
136
+ width: 200
137
+ },
138
+ {
139
+ type: 'checkbox',
140
+ name: 'state',
141
+ label: true,
142
+ header: i18next.t('field.state'),
143
+ record: {
144
+ editable: true
145
+ },
146
+ filter: true,
147
+ sortable: true,
148
+ width: 60
149
+ },
150
+ {
151
+ type: 'datetime',
152
+ name: 'createdAt',
153
+ header: i18next.t('field.created_at'),
154
+ record: {
155
+ editable: false
156
+ },
157
+ sortable: true,
158
+ width: 180
159
+ }
160
+ ],
161
+ rows: {
162
+ selectable: {
163
+ multiple: true
164
+ }
165
+ },
166
+ sorters: [
167
+ {
168
+ name: 'createdAt',
169
+ desc: true
170
+ }
171
+ ]
172
+ }
173
+ }
174
+
175
+ async pageUpdated(changes: any, lifecycle: any) {
176
+ if (this.active) {
177
+ // do something here when this page just became as active
178
+ }
179
+ }
180
+
181
+ async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {
182
+ const response = await client.query({
183
+ query: gql`
184
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
185
+ responses: notiBoxes(filters: $filters, pagination: $pagination, sortings: $sortings) {
186
+ items {
187
+ id
188
+ title
189
+ body
190
+ state
191
+ createdAt
192
+ }
193
+ total
194
+ }
195
+ }
196
+ `,
197
+ variables: {
198
+ filters,
199
+ pagination: { page, limit },
200
+ sortings
201
+ }
202
+ })
203
+
204
+ return {
205
+ total: response.data.responses.total || 0,
206
+ records: response.data.responses.items || []
207
+ }
208
+ }
209
+
210
+ async _deleteNotification() {
211
+ if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
212
+ const ids = this.grist.selected.map(record => record.id)
213
+ if (ids && ids.length > 0) {
214
+ const response = await client.mutate({
215
+ mutation: gql`
216
+ mutation ($ids: [String!]!) {
217
+ deleteNotificationes(ids: $ids)
218
+ }
219
+ `,
220
+ variables: {
221
+ ids
222
+ }
223
+ })
224
+
225
+ if (!response.errors) {
226
+ this.grist.fetch()
227
+ notify({
228
+ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
229
+ })
230
+ }
231
+ }
232
+ }
233
+ }
234
+
235
+ async _updateNotification() {
236
+ let patches = this.grist.dirtyRecords
237
+ if (patches && patches.length) {
238
+ patches = patches.map(patch => {
239
+ let patchField: any = patch.id ? { id: patch.id } : {}
240
+ const dirtyFields = patch.__dirtyfields__
241
+ for (let key in dirtyFields) {
242
+ patchField[key] = dirtyFields[key].after
243
+ }
244
+ patchField.cuFlag = patch.__dirty__
245
+
246
+ return patchField
247
+ })
248
+
249
+ const response = await client.mutate({
250
+ mutation: gql`
251
+ mutation ($patches: [NotificationPatch!]!) {
252
+ updateMultipleNotification(patches: $patches) {
253
+ name
254
+ }
255
+ }
256
+ `,
257
+ variables: {
258
+ patches
259
+ }
260
+ })
261
+
262
+ if (!response.errors) {
263
+ this.grist.fetch()
264
+ }
265
+ }
266
+ }
267
+ }
@@ -0,0 +1,93 @@
1
+ import '@operato/data-grist'
2
+
3
+ import gql from 'graphql-tag'
4
+ import { css, html, LitElement } from 'lit'
5
+ import { property } from 'lit/decorators.js'
6
+
7
+ import { client } from '@operato/graphql'
8
+ import { i18next } from '@operato/i18n'
9
+ import { isMobileDevice } from '@operato/utils'
10
+
11
+ export class NotificationRuleImporter extends LitElement {
12
+ static styles = [
13
+ css`
14
+ :host {
15
+ display: flex;
16
+ flex-direction: column;
17
+
18
+ background-color: #fff;
19
+ }
20
+
21
+ ox-grist {
22
+ flex: 1;
23
+ }
24
+
25
+ .button-container {
26
+ display: flex;
27
+ margin-left: auto;
28
+ padding: var(--padding-default);
29
+ }
30
+
31
+ mwc-button {
32
+ margin-left: var(--margin-default);
33
+ }
34
+ `
35
+ ]
36
+
37
+ @property({ type: Array }) notificationRules: any[] = []
38
+ @property({ type: Object }) columns = {
39
+ list: { fields: ['name', 'description'] },
40
+ pagination: { infinite: true },
41
+ columns: [
42
+ {
43
+ type: 'string',
44
+ name: 'name',
45
+ header: i18next.t('field.name'),
46
+ width: 150
47
+ },
48
+ {
49
+ type: 'string',
50
+ name: 'description',
51
+ header: i18next.t('field.description'),
52
+ width: 200
53
+ },
54
+ {
55
+ type: 'checkbox',
56
+ name: 'active',
57
+ header: i18next.t('field.active'),
58
+ width: 60
59
+ }
60
+ ]
61
+ }
62
+
63
+ render() {
64
+ return html`
65
+ <ox-grist
66
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
67
+ .config=${this.columns}
68
+ .data=${{
69
+ records: this.notificationRules
70
+ }}
71
+ ></ox-grist>
72
+
73
+ <div class="button-container">
74
+ <mwc-button raised @click="${this.save.bind(this)}">${i18next.t('button.save')}</mwc-button>
75
+ </div>
76
+ `
77
+ }
78
+
79
+ async save() {
80
+ const response = await client.mutate({
81
+ mutation: gql`
82
+ mutation importNotificationRules($notificationRules: [NotificationRulePatch!]!) {
83
+ importNotificationRules(notificationRules: $notificationRules)
84
+ }
85
+ `,
86
+ variables: { notificationRules: this.notificationRules }
87
+ })
88
+
89
+ if (response.errors?.length) return
90
+
91
+ this.dispatchEvent(new CustomEvent('imported'))
92
+ }
93
+ }