@things-factory/announcement 10.1.259 → 10.1.260
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/index.ts +1 -0
- package/client/pages/announcement-list.ts +28 -43
- package/client/utils/announcement-list-query.ts +8 -0
- package/dist-client/index.d.ts +1 -0
- package/dist-client/index.js +1 -0
- package/dist-client/index.js.map +1 -1
- package/dist-client/pages/announcement-list.d.ts +0 -4
- package/dist-client/pages/announcement-list.js +28 -48
- package/dist-client/pages/announcement-list.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/announcement-list-query.d.ts +5 -0
- package/dist-client/utils/announcement-list-query.js +8 -0
- package/dist-client/utils/announcement-list-query.js.map +1 -0
- package/package.json +9 -9
- package/test/list-query-state.test.ts +25 -0
- package/translations/en.json +3 -3
- package/translations/es.json +3 -3
- package/translations/ja.json +3 -3
- package/translations/ko.json +3 -3
- package/translations/ms.json +3 -3
- package/translations/zh.json +3 -3
package/client/index.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import '@material/web/icon/icon.js'
|
|
2
2
|
import '@operato/data-grist/ox-grist.js'
|
|
3
3
|
import '@operato/data-grist/ox-filters-form.js'
|
|
4
|
-
import '@operato/input/ox-select.js'
|
|
5
|
-
import '@operato/popup/ox-popup-list.js'
|
|
6
4
|
|
|
7
5
|
import gql from 'graphql-tag'
|
|
8
|
-
import {
|
|
6
|
+
import { html } from 'lit'
|
|
9
7
|
import { customElement, query, state } from 'lit/decorators.js'
|
|
10
8
|
|
|
11
9
|
import { DataGrist, FetchOption } from '@operato/data-grist'
|
|
@@ -17,6 +15,7 @@ import { isMobileDevice } from '@operato/utils'
|
|
|
17
15
|
import { hasPrivilege } from '@things-factory/auth-base/dist-client'
|
|
18
16
|
|
|
19
17
|
import { LIST_FIELDS } from '../utils/announcement-api.js'
|
|
18
|
+
import { announcementPeriodOf } from '../utils/announcement-list-query.js'
|
|
20
19
|
import { CATEGORIES, categoryWord, importanceWord, readerStateWord, t, when } from '../utils/announcement-words.js'
|
|
21
20
|
|
|
22
21
|
/**
|
|
@@ -29,22 +28,10 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
29
28
|
WorkSurfacePageStyles,
|
|
30
29
|
CommonGristStyles,
|
|
31
30
|
CommonHeaderStyles,
|
|
32
|
-
ScrollbarStyles
|
|
33
|
-
css`
|
|
34
|
-
.filters {
|
|
35
|
-
display: flex;
|
|
36
|
-
flex-wrap: wrap;
|
|
37
|
-
align-items: center;
|
|
38
|
-
gap: var(--spacing-medium, 8px);
|
|
39
|
-
}
|
|
40
|
-
ox-select {
|
|
41
|
-
min-width: 140px;
|
|
42
|
-
}
|
|
43
|
-
`
|
|
31
|
+
ScrollbarStyles
|
|
44
32
|
]
|
|
45
33
|
|
|
46
34
|
@state() gristConfig: any
|
|
47
|
-
@state() period: 'current' | 'past' = 'current'
|
|
48
35
|
/* A writer manages and writes from here - the menu offers one entry, and a reader sees no group of one. */
|
|
49
36
|
@state() writer = false
|
|
50
37
|
@query('ox-grist') private grist!: DataGrist
|
|
@@ -74,29 +61,14 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
74
61
|
}
|
|
75
62
|
}
|
|
76
63
|
|
|
64
|
+
/*
|
|
65
|
+
* The period, the category, search and page are the grid's own, kept in the address (FOOTER-BUTTON-REVIEW G09): a
|
|
66
|
+
* shared link, coming back and reloading read the same list, and a change of them reads page 1 again.
|
|
67
|
+
*/
|
|
77
68
|
render() {
|
|
78
|
-
|
|
79
|
-
{ value: 'current', display: t('announcement.text.period-current') },
|
|
80
|
-
{ value: 'past', display: t('announcement.text.period-past') }
|
|
81
|
-
]
|
|
82
|
-
return html`<ox-grist class="page-fill" search-mode="term" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
|
|
69
|
+
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}>
|
|
83
70
|
<div slot="headroom" class="header">
|
|
84
|
-
<div class="filters">
|
|
85
|
-
<ox-select
|
|
86
|
-
.value=${this.period}
|
|
87
|
-
aria-label=${t('announcement.text.period')}
|
|
88
|
-
@change=${(e: CustomEvent) => {
|
|
89
|
-
const next = e.detail === 'past' ? 'past' : 'current'
|
|
90
|
-
if (next === this.period) return
|
|
91
|
-
this.period = next
|
|
92
|
-
this.grist.fetch()
|
|
93
|
-
}}
|
|
94
|
-
>
|
|
95
|
-
<span slot="label">${periods.find(one => one.value === this.period)?.display}</span>
|
|
96
|
-
<ox-popup-list align-left nowrap with-search>${periods.map(one => html`<div option value=${one.value}>${one.display}</div>`)}</ox-popup-list>
|
|
97
|
-
</ox-select>
|
|
98
|
-
<ox-filters-form without-search autofocus></ox-filters-form>
|
|
99
|
-
</div>
|
|
71
|
+
<div class="filters"><ox-filters-form without-search autofocus></ox-filters-form></div>
|
|
100
72
|
</div>
|
|
101
73
|
</ox-grist>`
|
|
102
74
|
}
|
|
@@ -111,10 +83,6 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
111
83
|
super.disconnectedCallback()
|
|
112
84
|
}
|
|
113
85
|
|
|
114
|
-
async pageUpdated(changes: any) {
|
|
115
|
-
if (this.active && changes.active && this.gristConfig) this.grist?.fetch()
|
|
116
|
-
}
|
|
117
|
-
|
|
118
86
|
async pageInitialized() {
|
|
119
87
|
hasPrivilege({ category: 'announcement', privilege: 'mutation', domainOwnerGranted: true }).then(writer => {
|
|
120
88
|
this.writer = !!writer
|
|
@@ -128,6 +96,23 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
128
96
|
emptyNote: { title: t('announcement.text.empty'), description: t('announcement.text.empty-description') },
|
|
129
97
|
list: { fields: ['title', 'readerState'], details: ['category', 'publishedAt'] },
|
|
130
98
|
columns: [
|
|
99
|
+
/* Current or past - a filter of its own, on no column shown; the list is always one of the two. */
|
|
100
|
+
{
|
|
101
|
+
type: 'string',
|
|
102
|
+
name: 'period',
|
|
103
|
+
header: t('announcement.text.period'),
|
|
104
|
+
hidden: true,
|
|
105
|
+
record: { editable: false },
|
|
106
|
+
filter: {
|
|
107
|
+
type: 'select',
|
|
108
|
+
operator: 'eq',
|
|
109
|
+
value: 'current',
|
|
110
|
+
options: [
|
|
111
|
+
{ value: 'current', display: t('announcement.text.period-current') },
|
|
112
|
+
{ value: 'past', display: t('announcement.text.period-past') }
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
},
|
|
131
116
|
{
|
|
132
117
|
type: 'string',
|
|
133
118
|
name: 'pinned',
|
|
@@ -177,7 +162,7 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
177
162
|
}
|
|
178
163
|
|
|
179
164
|
private isPast() {
|
|
180
|
-
return this.
|
|
165
|
+
return announcementPeriodOf(this.grist?.filters) === 'past'
|
|
181
166
|
}
|
|
182
167
|
|
|
183
168
|
async fetchHandler({ page = 1, limit = 50, filters = [], search }: FetchOption) {
|
|
@@ -191,7 +176,7 @@ export class AnnouncementList extends localize(i18next)(PageView) {
|
|
|
191
176
|
}
|
|
192
177
|
`,
|
|
193
178
|
/* The period is the reader's own filter - the assistant narrows the same list the same way. */
|
|
194
|
-
variables: { filters: [...filters, { name: 'period', operator: 'eq', value:
|
|
179
|
+
variables: { filters: [...filters.filter(one => one.name !== 'period'), { name: 'period', operator: 'eq', value: announcementPeriodOf(filters) }], pagination: { page, limit }, search: search?.trim() || undefined },
|
|
195
180
|
fetchPolicy: 'network-only'
|
|
196
181
|
})
|
|
197
182
|
if (response.errors?.length) throw response
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The announcement list's query as its grid keeps it (FOOTER-BUTTON-REVIEW G09). Pure - no imports, so a test holds it.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** The period the grid's `period` filter names - past, else current (a cleared choice is the current ones). Pure. */
|
|
6
|
+
export function announcementPeriodOf(filters: readonly { name: string; value?: any }[] | undefined): 'current' | 'past' {
|
|
7
|
+
return filters?.find(one => one.name === 'period')?.value === 'past' ? 'past' : 'current'
|
|
8
|
+
}
|
package/dist-client/index.d.ts
CHANGED
package/dist-client/index.js
CHANGED
package/dist-client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA","sourcesContent":["export { generateAnnouncementBadge, refreshAnnouncementBadge } from './utils/announcement-badge.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA","sourcesContent":["export { generateAnnouncementBadge, refreshAnnouncementBadge } from './utils/announcement-badge.js'\nexport { AudiencePicker } from './components/audience-picker.js'\n"]}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import '@material/web/icon/icon.js';
|
|
2
2
|
import '@operato/data-grist/ox-grist.js';
|
|
3
3
|
import '@operato/data-grist/ox-filters-form.js';
|
|
4
|
-
import '@operato/input/ox-select.js';
|
|
5
|
-
import '@operato/popup/ox-popup-list.js';
|
|
6
4
|
import { FetchOption } from '@operato/data-grist';
|
|
7
5
|
import { PageView } from '@operato/shell';
|
|
8
6
|
declare const AnnouncementList_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
|
|
@@ -13,7 +11,6 @@ declare const AnnouncementList_base: (new (...args: any[]) => import("lit").LitE
|
|
|
13
11
|
export declare class AnnouncementList extends AnnouncementList_base {
|
|
14
12
|
static styles: import("lit").CSSResult[];
|
|
15
13
|
gristConfig: any;
|
|
16
|
-
period: 'current' | 'past';
|
|
17
14
|
writer: boolean;
|
|
18
15
|
private grist;
|
|
19
16
|
private onChanged;
|
|
@@ -43,7 +40,6 @@ export declare class AnnouncementList extends AnnouncementList_base {
|
|
|
43
40
|
render(): import("lit-html").TemplateResult<1>;
|
|
44
41
|
connectedCallback(): void;
|
|
45
42
|
disconnectedCallback(): void;
|
|
46
|
-
pageUpdated(changes: any): Promise<void>;
|
|
47
43
|
pageInitialized(): Promise<void>;
|
|
48
44
|
private isPast;
|
|
49
45
|
fetchHandler({ page, limit, filters, search }: FetchOption): Promise<{
|
|
@@ -2,10 +2,8 @@ import { __decorate, __metadata } from "tslib";
|
|
|
2
2
|
import '@material/web/icon/icon.js';
|
|
3
3
|
import '@operato/data-grist/ox-grist.js';
|
|
4
4
|
import '@operato/data-grist/ox-filters-form.js';
|
|
5
|
-
import '@operato/input/ox-select.js';
|
|
6
|
-
import '@operato/popup/ox-popup-list.js';
|
|
7
5
|
import gql from 'graphql-tag';
|
|
8
|
-
import {
|
|
6
|
+
import { html } from 'lit';
|
|
9
7
|
import { customElement, query, state } from 'lit/decorators.js';
|
|
10
8
|
import { DataGrist } from '@operato/data-grist';
|
|
11
9
|
import { client } from '@operato/graphql';
|
|
@@ -15,6 +13,7 @@ import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePage
|
|
|
15
13
|
import { isMobileDevice } from '@operato/utils';
|
|
16
14
|
import { hasPrivilege } from '@things-factory/auth-base/dist-client';
|
|
17
15
|
import { LIST_FIELDS } from '../utils/announcement-api.js';
|
|
16
|
+
import { announcementPeriodOf } from '../utils/announcement-list-query.js';
|
|
18
17
|
import { CATEGORIES, categoryWord, importanceWord, readerStateWord, t, when } from '../utils/announcement-words.js';
|
|
19
18
|
/**
|
|
20
19
|
* 공지 — the announcements addressed to the person: the current ones, pinned, urgent and important first, or the past
|
|
@@ -23,7 +22,6 @@ import { CATEGORIES, categoryWord, importanceWord, readerStateWord, t, when } fr
|
|
|
23
22
|
let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView) {
|
|
24
23
|
constructor() {
|
|
25
24
|
super(...arguments);
|
|
26
|
-
this.period = 'current';
|
|
27
25
|
/* A writer manages and writes from here - the menu offers one entry, and a reader sees no group of one. */
|
|
28
26
|
this.writer = false;
|
|
29
27
|
this.onChanged = () => this.grist?.fetch();
|
|
@@ -32,18 +30,7 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
32
30
|
WorkSurfacePageStyles,
|
|
33
31
|
CommonGristStyles,
|
|
34
32
|
CommonHeaderStyles,
|
|
35
|
-
ScrollbarStyles
|
|
36
|
-
css `
|
|
37
|
-
.filters {
|
|
38
|
-
display: flex;
|
|
39
|
-
flex-wrap: wrap;
|
|
40
|
-
align-items: center;
|
|
41
|
-
gap: var(--spacing-medium, 8px);
|
|
42
|
-
}
|
|
43
|
-
ox-select {
|
|
44
|
-
min-width: 140px;
|
|
45
|
-
}
|
|
46
|
-
`
|
|
33
|
+
ScrollbarStyles
|
|
47
34
|
]; }
|
|
48
35
|
get context() {
|
|
49
36
|
return {
|
|
@@ -67,30 +54,14 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
67
54
|
: []
|
|
68
55
|
};
|
|
69
56
|
}
|
|
57
|
+
/*
|
|
58
|
+
* The period, the category, search and page are the grid's own, kept in the address (FOOTER-BUTTON-REVIEW G09): a
|
|
59
|
+
* shared link, coming back and reloading read the same list, and a change of them reads page 1 again.
|
|
60
|
+
*/
|
|
70
61
|
render() {
|
|
71
|
-
|
|
72
|
-
{ value: 'current', display: t('announcement.text.period-current') },
|
|
73
|
-
{ value: 'past', display: t('announcement.text.period-past') }
|
|
74
|
-
];
|
|
75
|
-
return html `<ox-grist class="page-fill" search-mode="term" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
|
|
62
|
+
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}>
|
|
76
63
|
<div slot="headroom" class="header">
|
|
77
|
-
<div class="filters">
|
|
78
|
-
<ox-select
|
|
79
|
-
.value=${this.period}
|
|
80
|
-
aria-label=${t('announcement.text.period')}
|
|
81
|
-
@change=${(e) => {
|
|
82
|
-
const next = e.detail === 'past' ? 'past' : 'current';
|
|
83
|
-
if (next === this.period)
|
|
84
|
-
return;
|
|
85
|
-
this.period = next;
|
|
86
|
-
this.grist.fetch();
|
|
87
|
-
}}
|
|
88
|
-
>
|
|
89
|
-
<span slot="label">${periods.find(one => one.value === this.period)?.display}</span>
|
|
90
|
-
<ox-popup-list align-left nowrap with-search>${periods.map(one => html `<div option value=${one.value}>${one.display}</div>`)}</ox-popup-list>
|
|
91
|
-
</ox-select>
|
|
92
|
-
<ox-filters-form without-search autofocus></ox-filters-form>
|
|
93
|
-
</div>
|
|
64
|
+
<div class="filters"><ox-filters-form without-search autofocus></ox-filters-form></div>
|
|
94
65
|
</div>
|
|
95
66
|
</ox-grist>`;
|
|
96
67
|
}
|
|
@@ -102,10 +73,6 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
102
73
|
window.removeEventListener('announcements-changed', this.onChanged);
|
|
103
74
|
super.disconnectedCallback();
|
|
104
75
|
}
|
|
105
|
-
async pageUpdated(changes) {
|
|
106
|
-
if (this.active && changes.active && this.gristConfig)
|
|
107
|
-
this.grist?.fetch();
|
|
108
|
-
}
|
|
109
76
|
async pageInitialized() {
|
|
110
77
|
hasPrivilege({ category: 'announcement', privilege: 'mutation', domainOwnerGranted: true }).then(writer => {
|
|
111
78
|
this.writer = !!writer;
|
|
@@ -119,6 +86,23 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
119
86
|
emptyNote: { title: t('announcement.text.empty'), description: t('announcement.text.empty-description') },
|
|
120
87
|
list: { fields: ['title', 'readerState'], details: ['category', 'publishedAt'] },
|
|
121
88
|
columns: [
|
|
89
|
+
/* Current or past - a filter of its own, on no column shown; the list is always one of the two. */
|
|
90
|
+
{
|
|
91
|
+
type: 'string',
|
|
92
|
+
name: 'period',
|
|
93
|
+
header: t('announcement.text.period'),
|
|
94
|
+
hidden: true,
|
|
95
|
+
record: { editable: false },
|
|
96
|
+
filter: {
|
|
97
|
+
type: 'select',
|
|
98
|
+
operator: 'eq',
|
|
99
|
+
value: 'current',
|
|
100
|
+
options: [
|
|
101
|
+
{ value: 'current', display: t('announcement.text.period-current') },
|
|
102
|
+
{ value: 'past', display: t('announcement.text.period-past') }
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
},
|
|
122
106
|
{
|
|
123
107
|
type: 'string',
|
|
124
108
|
name: 'pinned',
|
|
@@ -165,7 +149,7 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
165
149
|
};
|
|
166
150
|
}
|
|
167
151
|
isPast() {
|
|
168
|
-
return this.
|
|
152
|
+
return announcementPeriodOf(this.grist?.filters) === 'past';
|
|
169
153
|
}
|
|
170
154
|
async fetchHandler({ page = 1, limit = 50, filters = [], search }) {
|
|
171
155
|
const response = await client.query({
|
|
@@ -178,7 +162,7 @@ let AnnouncementList = class AnnouncementList extends localize(i18next)(PageView
|
|
|
178
162
|
}
|
|
179
163
|
`,
|
|
180
164
|
/* The period is the reader's own filter - the assistant narrows the same list the same way. */
|
|
181
|
-
variables: { filters: [...filters, { name: 'period', operator: 'eq', value:
|
|
165
|
+
variables: { filters: [...filters.filter(one => one.name !== 'period'), { name: 'period', operator: 'eq', value: announcementPeriodOf(filters) }], pagination: { page, limit }, search: search?.trim() || undefined },
|
|
182
166
|
fetchPolicy: 'network-only'
|
|
183
167
|
});
|
|
184
168
|
if (response.errors?.length)
|
|
@@ -190,10 +174,6 @@ __decorate([
|
|
|
190
174
|
state(),
|
|
191
175
|
__metadata("design:type", Object)
|
|
192
176
|
], AnnouncementList.prototype, "gristConfig", void 0);
|
|
193
|
-
__decorate([
|
|
194
|
-
state(),
|
|
195
|
-
__metadata("design:type", String)
|
|
196
|
-
], AnnouncementList.prototype, "period", void 0);
|
|
197
177
|
__decorate([
|
|
198
178
|
state(),
|
|
199
179
|
__metadata("design:type", Object)
|
|
@@ -1 +1 @@
|
|
|
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'\nimport '@operato/input/ox-select.js'\nimport '@operato/popup/ox-popup-list.js'\n\nimport gql from 'graphql-tag'\nimport { css, 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 { 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 css`\n .filters {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-medium, 8px);\n }\n ox-select {\n min-width: 140px;\n }\n `\n ]\n\n @state() gristConfig: any\n @state() period: 'current' | 'past' = 'current'\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 render() {\n const periods = [\n { value: 'current', display: t('announcement.text.period-current') },\n { value: 'past', display: t('announcement.text.period-past') }\n ]\n return html`<ox-grist class=\"page-fill\" search-mode=\"term\" .mode=${isMobileDevice() ? 'CARD' : 'GRID'} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-select\n .value=${this.period}\n aria-label=${t('announcement.text.period')}\n @change=${(e: CustomEvent) => {\n const next = e.detail === 'past' ? 'past' : 'current'\n if (next === this.period) return\n this.period = next\n this.grist.fetch()\n }}\n >\n <span slot=\"label\">${periods.find(one => one.value === this.period)?.display}</span>\n <ox-popup-list align-left nowrap with-search>${periods.map(one => html`<div option value=${one.value}>${one.display}</div>`)}</ox-popup-list>\n </ox-select>\n <ox-filters-form without-search autofocus></ox-filters-form>\n </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 pageUpdated(changes: any) {\n if (this.active && changes.active && this.gristConfig) this.grist?.fetch()\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 {\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 this.period === '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, { name: 'period', operator: 'eq', value: this.period }], 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 { 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"]}
|