@things-factory/announcement 10.1.261 → 10.1.263
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/client/pages/announcement-list.ts +14 -2
- package/dist-client/pages/announcement-list.js +14 -2
- package/dist-client/pages/announcement-list.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/test/list-query-state.test.ts +14 -0
|
@@ -12,6 +12,7 @@ import { i18next, localize } from '@operato/i18n'
|
|
|
12
12
|
import { navigate, PageView } from '@operato/shell'
|
|
13
13
|
import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'
|
|
14
14
|
import { isMobileDevice } from '@operato/utils'
|
|
15
|
+
import { SELECTION_ROW_PICKER } from '@things-factory/ai-assistant/dist-client/index.js'
|
|
15
16
|
import { hasPrivilege } from '@things-factory/auth-base/dist-client'
|
|
16
17
|
|
|
17
18
|
import { LIST_FIELDS } from '../utils/announcement-api.js'
|
|
@@ -66,7 +67,14 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
66
67
|
* shared link, coming back and reloading read the same list, and a change of them reads page 1 again.
|
|
67
68
|
*/
|
|
68
69
|
render() {
|
|
69
|
-
return html`<ox-
|
|
70
|
+
return html`<ox-assistant-selection-bar
|
|
71
|
+
.gridOf=${() => this.grist}
|
|
72
|
+
name=${t('announcement.title.list')}
|
|
73
|
+
list="announcements"
|
|
74
|
+
axis="list"
|
|
75
|
+
.labelOf=${(row: any) => row.title ?? ''}
|
|
76
|
+
></ox-assistant-selection-bar>
|
|
77
|
+
<ox-grist class="page-fill" search-mode="term" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)} ?url-params-sensitive=${this.active}>
|
|
70
78
|
<div slot="headroom" class="header">
|
|
71
79
|
<div class="filters"><ox-filters-form without-search autofocus></ox-filters-form></div>
|
|
72
80
|
</div>
|
|
@@ -91,11 +99,15 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
91
99
|
const open = (record: any) => record?.id && navigate(`announcement-view?id=${record.id}`)
|
|
92
100
|
const owed = (record: any) => record?.readerState === 'unread' || record?.readerState === 'to-acknowledge'
|
|
93
101
|
this.gristConfig = {
|
|
94
|
-
rows: { appendable: false, selectable:
|
|
102
|
+
rows: { appendable: false, selectable: { multiple: true } },
|
|
95
103
|
pagination: { limit: 50, pages: [50, 100] },
|
|
96
104
|
emptyNote: { title: t('announcement.text.empty'), description: t('announcement.text.empty-description') },
|
|
97
105
|
list: { fields: ['title', 'readerState'], details: ['category', 'publishedAt'] },
|
|
98
106
|
columns: [
|
|
107
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
108
|
+
SELECTION_ROW_PICKER,
|
|
109
|
+
/* Rows are picked for the assistant; an announcement opens from its own button, as the other lists do. */
|
|
110
|
+
{ type: 'gutter', gutterName: 'button', icon: 'edit_note', handlers: { click: (_c: any, _d: any, _col: any, record: any) => open(record) } },
|
|
99
111
|
/* Current or past - a filter of its own, on no column shown; the list is always one of the two. */
|
|
100
112
|
{
|
|
101
113
|
type: 'string',
|
|
@@ -11,6 +11,7 @@ import { i18next, localize } from '@operato/i18n';
|
|
|
11
11
|
import { navigate, PageView } from '@operato/shell';
|
|
12
12
|
import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
|
|
13
13
|
import { isMobileDevice } from '@operato/utils';
|
|
14
|
+
import { SELECTION_ROW_PICKER } from '@things-factory/ai-assistant/dist-client/index.js';
|
|
14
15
|
import { hasPrivilege } from '@things-factory/auth-base/dist-client';
|
|
15
16
|
import { LIST_FIELDS } from '../utils/announcement-api.js';
|
|
16
17
|
import { announcementPeriodOf } from '../utils/announcement-list-query.js';
|
|
@@ -59,7 +60,14 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
59
60
|
* shared link, coming back and reloading read the same list, and a change of them reads page 1 again.
|
|
60
61
|
*/
|
|
61
62
|
render() {
|
|
62
|
-
return html `<ox-
|
|
63
|
+
return html `<ox-assistant-selection-bar
|
|
64
|
+
.gridOf=${() => this.grist}
|
|
65
|
+
name=${t('announcement.title.list')}
|
|
66
|
+
list="announcements"
|
|
67
|
+
axis="list"
|
|
68
|
+
.labelOf=${(row) => row.title ?? ''}
|
|
69
|
+
></ox-assistant-selection-bar>
|
|
70
|
+
<ox-grist class="page-fill" search-mode="term" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)} ?url-params-sensitive=${this.active}>
|
|
63
71
|
<div slot="headroom" class="header">
|
|
64
72
|
<div class="filters"><ox-filters-form without-search autofocus></ox-filters-form></div>
|
|
65
73
|
</div>
|
|
@@ -81,11 +89,15 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
81
89
|
const open = (record) => record?.id && navigate(`announcement-view?id=${record.id}`);
|
|
82
90
|
const owed = (record) => record?.readerState === 'unread' || record?.readerState === 'to-acknowledge';
|
|
83
91
|
this.gristConfig = {
|
|
84
|
-
rows: { appendable: false, selectable:
|
|
92
|
+
rows: { appendable: false, selectable: { multiple: true } },
|
|
85
93
|
pagination: { limit: 50, pages: [50, 100] },
|
|
86
94
|
emptyNote: { title: t('announcement.text.empty'), description: t('announcement.text.empty-description') },
|
|
87
95
|
list: { fields: ['title', 'readerState'], details: ['category', 'publishedAt'] },
|
|
88
96
|
columns: [
|
|
97
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
98
|
+
SELECTION_ROW_PICKER,
|
|
99
|
+
/* Rows are picked for the assistant; an announcement opens from its own button, as the other lists do. */
|
|
100
|
+
{ type: 'gutter', gutterName: 'button', icon: 'edit_note', handlers: { click: (_c, _d, _col, record) => open(record) } },
|
|
89
101
|
/* Current or past - a filter of its own, on no column shown; the list is always one of the two. */
|
|
90
102
|
{
|
|
91
103
|
type: 'string',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announcement-list.js","sourceRoot":"","sources":["../../client/pages/announcement-list.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,iCAAiC,CAAA;AACxC,OAAO,wCAAwC,CAAA;AAE/C,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE/D,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAA;AAEnH;;;GAGG;AAEI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;IAA1D;;QASL,2GAA2G;QAClG,WAAM,GAAG,KAAK,CAAA;QAGf,cAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;IAkJ/C,CAAC;aA9JQ,WAAM,GAAG;QACd,qBAAqB;QACrB,iBAAiB;QACjB,kBAAkB;QAClB,eAAe;KAChB,AALY,CAKZ;IASD,IAAI,OAAO;QACT,OAAO;YACL,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC;YACnC,MAAM,EAAE;gBACN,OAAO,EAAE,CAAC,MAAc,EAAE,EAAE;oBAC1B,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAA;gBAChC,CAAC;gBACD,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,IAAI,EAAE;aACpC;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;gBAC7B,CAAC;aACF;YACD,OAAO,EAAE,IAAI,CAAC,MAAM;gBAClB,CAAC,CAAC;oBACE,EAAE,KAAK,EAAE,CAAC,CAAC,2BAA2B,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE;oBAChH,EAAE,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;iBAChI;gBACH,CAAC,CAAC,EAAE;SACP,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,OAAO,IAAI,CAAA,wDAAwD,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,YAAY,IAAI,CAAC,WAAW,kBAAkB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,MAAM;;;;gBAIxM,CAAA;IACd,CAAC;IAED,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QACzB,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IAClE,CAAC;IAED,oBAAoB;QAClB,MAAM,CAAC,mBAAmB,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACnE,KAAK,CAAC,oBAAoB,EAAE,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,YAAY,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACxG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;YACtB,IAAI,CAAC,aAAa,EAAE,CAAA;QACtB,CAAC,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,QAAQ,CAAC,wBAAwB,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;QACzF,MAAM,IAAI,GAAG,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,QAAQ,IAAI,MAAM,EAAE,WAAW,KAAK,gBAAgB,CAAA;QAC1G,IAAI,CAAC,WAAW,GAAG;YACjB,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAO,EAAE,EAAO,EAAE,IAAS,EAAE,MAAW,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;YAC/H,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE;YAC3C,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,qCAAqC,CAAC,EAAE;YACzG,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE;YAChF,OAAO,EAAE;gBACP,mGAAmG;gBACnG;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,CAAC,CAAC,0BAA0B,CAAC;oBACrC,MAAM,EAAE,IAAI;oBACZ,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC3B,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,IAAI;wBACd,KAAK,EAAE,SAAS;wBAChB,OAAO,EAAE;4BACP,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,kCAAkC,CAAC,EAAE;4BACpE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,+BAA+B,CAAC,EAAE;yBAC/D;qBACF;iBACF;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,EAAE;oBACV,KAAK,EAAE,EAAE;oBACT,MAAM,EAAE;wBACN,QAAQ,EAAE,KAAK;wBACf,QAAQ,EAAE,CAAC,EAAO,EAAE,EAAO,EAAE,MAAW,EAAE,EAAE,CAC1C,MAAM,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;4BAC9B,CAAC,CAAC,IAAI,CAAA,8CAA8C,CAAC,CAAC,2BAA2B,CAAC,qBAAqB;4BACvG,CAAC,CAAC,MAAM,EAAE,UAAU,KAAK,QAAQ;gCAC/B,CAAC,CAAC,IAAI,CAAA,8EAA8E,cAAc,CAAC,QAAQ,CAAC,0BAA0B;gCACtI,CAAC,CAAC,EAAE;qBACX;iBACF;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,CAAC,CAAC,6BAA6B,CAAC;oBACxC,KAAK,EAAE,EAAE;oBACT,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;oBAC7E,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;iBAC7J;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,CAAC,CAAC,0BAA0B,CAAC;oBACrC,KAAK,EAAE,GAAG;oBACV,MAAM,EAAE;wBACN,QAAQ,EAAE,KAAK;wBACf,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAO,EAAE,MAAW,EAAE,EAAE,CAChD,IAAI,CAAA,eAAe,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,IAAI,MAAM,EAAE,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,SAAS;qBAC7J;iBACF;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,aAAa;oBACnB,MAAM,EAAE,CAAC,CAAC,iCAAiC,CAAC;oBAC5C,KAAK,EAAE,GAAG;oBACV,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAA,eAAe,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,gBAAgB,CAAC,CAAC,CAAC,mDAAmD,CAAC,CAAC,CAAC,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,SAAS,EAAE;iBAC5N;gBACD,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,8BAA8B,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE;gBACtK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,iCAAiC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC/K,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,4BAA4B,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE;aACtK;SACF,CAAA;IACH,CAAC;IAEO,MAAM;QACZ,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IAC7D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,MAAM,EAAe;QAC5E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;sBAGM,WAAW;;;;OAI1B;YACD,+FAA+F;YAC/F,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE;YACrN,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAA;QACF,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM;YAAE,MAAM,QAAQ,CAAA;QAC3C,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;IACzF,CAAC;;AAtJQ;IAAR,KAAK,EAAE;;qDAAiB;AAEhB;IAAR,KAAK,EAAE;;gDAAe;AACI;IAA1B,KAAK,CAAC,UAAU,CAAC;8BAAiB,SAAS;+CAAA;AAXjC,gBAAgB;IAD5B,aAAa,CAAC,mBAAmB,CAAC;GACtB,gBAAgB,CA+J5B","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\n\nimport gql from 'graphql-tag'\nimport { html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { navigate, PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client'\n\nimport { LIST_FIELDS } from '../utils/announcement-api.js'\nimport { announcementPeriodOf } from '../utils/announcement-list-query.js'\nimport { CATEGORIES, categoryWord, importanceWord, readerStateWord, t, when } from '../utils/announcement-words.js'\n\n/**\n * 공지 — the announcements addressed to the person: the current ones, pinned, urgent and important first, or the past\n * ones (ADR-0163 decision 5). Those not read yet are bold; a row opens the announcement.\n */\n@customElement('announcement-list')\nexport class AnnouncementList extends localize(i18next)(PageView) {\n static styles = [\n WorkSurfacePageStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles\n ]\n\n @state() gristConfig: any\n /* A writer manages and writes from here - the menu offers one entry, and a reader sees no group of one. */\n @state() writer = false\n @query('ox-grist') private grist!: DataGrist\n\n private onChanged = () => this.grist?.fetch()\n\n get context() {\n return {\n title: t('announcement.title.list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n actions: this.writer\n ? [\n { title: t('announcement.title.manage'), icon: 'edit_note', action: () => navigate('announcement-manage-list') },\n { title: t('announcement.button.new'), icon: 'add', emphasis: { raised: true }, action: () => navigate('announcement-editor') }\n ]\n : []\n }\n }\n\n /*\n * The period, the category, search and page are the grid's own, kept in the address (FOOTER-BUTTON-REVIEW G09): a\n * shared link, coming back and reloading read the same list, and a change of them reads page 1 again.\n */\n render() {\n return html`<ox-grist class=\"page-fill\" search-mode=\"term\" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)} ?url-params-sensitive=${this.active}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\"><ox-filters-form without-search autofocus></ox-filters-form></div>\n </div>\n </ox-grist>`\n }\n\n connectedCallback() {\n super.connectedCallback()\n window.addEventListener('announcements-changed', this.onChanged)\n }\n\n disconnectedCallback() {\n window.removeEventListener('announcements-changed', this.onChanged)\n super.disconnectedCallback()\n }\n\n async pageInitialized() {\n hasPrivilege({ category: 'announcement', privilege: 'mutation', domainOwnerGranted: true }).then(writer => {\n this.writer = !!writer\n this.updateContext()\n })\n const open = (record: any) => record?.id && navigate(`announcement-view?id=${record.id}`)\n const owed = (record: any) => record?.readerState === 'unread' || record?.readerState === 'to-acknowledge'\n this.gristConfig = {\n rows: { appendable: false, selectable: false, handlers: { click: (_c: any, _d: any, _col: any, record: any) => open(record) } },\n pagination: { limit: 50, pages: [50, 100] },\n emptyNote: { title: t('announcement.text.empty'), description: t('announcement.text.empty-description') },\n list: { fields: ['title', 'readerState'], details: ['category', 'publishedAt'] },\n columns: [\n /* Current or past - a filter of its own, on no column shown; the list is always one of the two. */\n {\n type: 'string',\n name: 'period',\n header: t('announcement.text.period'),\n hidden: true,\n record: { editable: false },\n filter: {\n type: 'select',\n operator: 'eq',\n value: 'current',\n options: [\n { value: 'current', display: t('announcement.text.period-current') },\n { value: 'past', display: t('announcement.text.period-past') }\n ]\n }\n },\n {\n type: 'string',\n name: 'pinned',\n header: '',\n width: 34,\n record: {\n editable: false,\n renderer: (_v: any, _c: any, record: any) =>\n record?.pinned && !this.isPast()\n ? html`<md-icon style=\"--md-icon-size:16px\" title=${t('announcement.field.pinned')}>push_pin</md-icon>`\n : record?.importance === 'URGENT'\n ? html`<md-icon style=\"--md-icon-size:16px;color:var(--md-sys-color-error)\" title=${importanceWord('URGENT')}>priority_high</md-icon>`\n : ''\n }\n },\n {\n type: 'string',\n name: 'category',\n header: t('announcement.field.category'),\n width: 90,\n record: { editable: false, renderer: (value: string) => categoryWord(value) },\n filter: { type: 'select', operator: 'eq', options: [{ display: '', value: '' }, ...CATEGORIES.map(code => ({ display: categoryWord(code), value: code }))] }\n },\n {\n type: 'string',\n name: 'title',\n header: t('announcement.field.title'),\n width: 320,\n record: {\n editable: false,\n renderer: (value: string, _c: any, record: any) =>\n html`<span style=${owed(record) ? 'font-weight:600' : ''}>${record?.importance === 'IMPORTANT' ? `[${importanceWord('IMPORTANT')}] ` : ''}${value}</span>`\n }\n },\n {\n type: 'string',\n name: 'readerState',\n header: t('announcement.field.reader-state'),\n width: 100,\n record: { editable: false, renderer: (value: string) => html`<span style=${value === 'unread' || value === 'to-acknowledge' ? 'color:var(--md-sys-color-primary);font-weight:600' : ''}>${readerStateWord(value)}</span>` }\n },\n { type: 'string', name: 'publisher', header: t('announcement.field.publisher'), width: 110, record: { editable: false, renderer: (value: any) => value?.name ?? '' } },\n { type: 'string', name: 'publishedAt', header: t('announcement.field.published-at'), width: 110, record: { editable: false, renderer: (value: string) => when(value, false) } },\n { type: 'string', name: 'endsAt', header: t('announcement.field.ends-at'), width: 110, record: { editable: false, renderer: (value: string) => when(value, false) } }\n ]\n }\n }\n\n private isPast() {\n return announcementPeriodOf(this.grist?.filters) === 'past'\n }\n\n async fetchHandler({ page = 1, limit = 50, filters = [], search }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $search: String) {\n responses: announcements(filters: $filters, pagination: $pagination, search: $search) {\n items { ${LIST_FIELDS} }\n total\n }\n }\n `,\n /* The period is the reader's own filter - the assistant narrows the same list the same way. */\n variables: { filters: [...filters.filter(one => one.name !== 'period'), { name: 'period', operator: 'eq', value: announcementPeriodOf(filters) }], pagination: { page, limit }, search: search?.trim() || undefined },\n fetchPolicy: 'network-only'\n })\n if (response.errors?.length) throw response\n return { total: response.data.responses.total, records: response.data.responses.items }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"announcement-list.js","sourceRoot":"","sources":["../../client/pages/announcement-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.js'\n\nimport gql from 'graphql-tag'\nimport { html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { navigate, PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { SELECTION_ROW_PICKER } from '@things-factory/ai-assistant/dist-client/index.js'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client'\n\nimport { LIST_FIELDS } from '../utils/announcement-api.js'\nimport { announcementPeriodOf } from '../utils/announcement-list-query.js'\nimport { CATEGORIES, categoryWord, importanceWord, readerStateWord, t, when } from '../utils/announcement-words.js'\n\n/**\n * 공지 — the announcements addressed to the person: the current ones, pinned, urgent and important first, or the past\n * ones (ADR-0163 decision 5). Those not read yet are bold; a row opens the announcement.\n */\n@customElement('announcement-list')\nexport class AnnouncementList extends localize(i18next)(PageView) {\n static styles = [\n WorkSurfacePageStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles\n ]\n\n @state() gristConfig: any\n /* A writer manages and writes from here - the menu offers one entry, and a reader sees no group of one. */\n @state() writer = false\n @query('ox-grist') private grist!: DataGrist\n\n private onChanged = () => this.grist?.fetch()\n\n get context() {\n return {\n title: t('announcement.title.list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n actions: this.writer\n ? [\n { title: t('announcement.title.manage'), icon: 'edit_note', action: () => navigate('announcement-manage-list') },\n { title: t('announcement.button.new'), icon: 'add', emphasis: { raised: true }, action: () => navigate('announcement-editor') }\n ]\n : []\n }\n }\n\n /*\n * The period, the category, search and page are the grid's own, kept in the address (FOOTER-BUTTON-REVIEW G09): a\n * shared link, coming back and reloading read the same list, and a change of them reads page 1 again.\n */\n render() {\n return html`<ox-assistant-selection-bar\n .gridOf=${() => this.grist}\n name=${t('announcement.title.list')}\n list=\"announcements\"\n axis=\"list\"\n .labelOf=${(row: any) => row.title ?? ''}\n ></ox-assistant-selection-bar>\n <ox-grist class=\"page-fill\" search-mode=\"term\" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)} ?url-params-sensitive=${this.active}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\"><ox-filters-form without-search autofocus></ox-filters-form></div>\n </div>\n </ox-grist>`\n }\n\n connectedCallback() {\n super.connectedCallback()\n window.addEventListener('announcements-changed', this.onChanged)\n }\n\n disconnectedCallback() {\n window.removeEventListener('announcements-changed', this.onChanged)\n super.disconnectedCallback()\n }\n\n async pageInitialized() {\n hasPrivilege({ category: 'announcement', privilege: 'mutation', domainOwnerGranted: true }).then(writer => {\n this.writer = !!writer\n this.updateContext()\n })\n const open = (record: any) => record?.id && navigate(`announcement-view?id=${record.id}`)\n const owed = (record: any) => record?.readerState === 'unread' || record?.readerState === 'to-acknowledge'\n this.gristConfig = {\n rows: { appendable: false, selectable: { multiple: true } },\n pagination: { limit: 50, pages: [50, 100] },\n emptyNote: { title: t('announcement.text.empty'), description: t('announcement.text.empty-description') },\n list: { fields: ['title', 'readerState'], details: ['category', 'publishedAt'] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n SELECTION_ROW_PICKER,\n /* Rows are picked for the assistant; an announcement opens from its own button, as the other lists do. */\n { type: 'gutter', gutterName: 'button', icon: 'edit_note', handlers: { click: (_c: any, _d: any, _col: any, record: any) => open(record) } },\n /* Current or past - a filter of its own, on no column shown; the list is always one of the two. */\n {\n type: 'string',\n name: 'period',\n header: t('announcement.text.period'),\n hidden: true,\n record: { editable: false },\n filter: {\n type: 'select',\n operator: 'eq',\n value: 'current',\n options: [\n { value: 'current', display: t('announcement.text.period-current') },\n { value: 'past', display: t('announcement.text.period-past') }\n ]\n }\n },\n {\n type: 'string',\n name: 'pinned',\n header: '',\n width: 34,\n record: {\n editable: false,\n renderer: (_v: any, _c: any, record: any) =>\n record?.pinned && !this.isPast()\n ? html`<md-icon style=\"--md-icon-size:16px\" title=${t('announcement.field.pinned')}>push_pin</md-icon>`\n : record?.importance === 'URGENT'\n ? html`<md-icon style=\"--md-icon-size:16px;color:var(--md-sys-color-error)\" title=${importanceWord('URGENT')}>priority_high</md-icon>`\n : ''\n }\n },\n {\n type: 'string',\n name: 'category',\n header: t('announcement.field.category'),\n width: 90,\n record: { editable: false, renderer: (value: string) => categoryWord(value) },\n filter: { type: 'select', operator: 'eq', options: [{ display: '', value: '' }, ...CATEGORIES.map(code => ({ display: categoryWord(code), value: code }))] }\n },\n {\n type: 'string',\n name: 'title',\n header: t('announcement.field.title'),\n width: 320,\n record: {\n editable: false,\n renderer: (value: string, _c: any, record: any) =>\n html`<span style=${owed(record) ? 'font-weight:600' : ''}>${record?.importance === 'IMPORTANT' ? `[${importanceWord('IMPORTANT')}] ` : ''}${value}</span>`\n }\n },\n {\n type: 'string',\n name: 'readerState',\n header: t('announcement.field.reader-state'),\n width: 100,\n record: { editable: false, renderer: (value: string) => html`<span style=${value === 'unread' || value === 'to-acknowledge' ? 'color:var(--md-sys-color-primary);font-weight:600' : ''}>${readerStateWord(value)}</span>` }\n },\n { type: 'string', name: 'publisher', header: t('announcement.field.publisher'), width: 110, record: { editable: false, renderer: (value: any) => value?.name ?? '' } },\n { type: 'string', name: 'publishedAt', header: t('announcement.field.published-at'), width: 110, record: { editable: false, renderer: (value: string) => when(value, false) } },\n { type: 'string', name: 'endsAt', header: t('announcement.field.ends-at'), width: 110, record: { editable: false, renderer: (value: string) => when(value, false) } }\n ]\n }\n }\n\n private isPast() {\n return announcementPeriodOf(this.grist?.filters) === 'past'\n }\n\n async fetchHandler({ page = 1, limit = 50, filters = [], search }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $search: String) {\n responses: announcements(filters: $filters, pagination: $pagination, search: $search) {\n items { ${LIST_FIELDS} }\n total\n }\n }\n `,\n /* The period is the reader's own filter - the assistant narrows the same list the same way. */\n variables: { filters: [...filters.filter(one => one.name !== 'period'), { name: 'period', operator: 'eq', value: announcementPeriodOf(filters) }], pagination: { page, limit }, search: search?.trim() || undefined },\n fetchPolicy: 'network-only'\n })\n if (response.errors?.length) throw response\n return { total: response.data.responses.total, records: response.data.responses.items }\n }\n}\n"]}
|