@operato/data-grist 0.2.27 → 0.2.28

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/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ### [0.2.28](https://github.com/hatiolab/operato/compare/v0.2.27...v0.2.28) (2021-11-29)
7
+
8
+
9
+ ### :bug: Bug Fix
10
+
11
+ * support i18next for @operato/data-grist/data-report ([8ee763d](https://github.com/hatiolab/operato/commit/8ee763d194e3ce7eed5d96868ada068e8a854743))
12
+
13
+
14
+
6
15
  ### [0.2.27](https://github.com/hatiolab/operato/compare/v0.2.26...v0.2.27) (2021-11-29)
7
16
 
8
17
 
@@ -0,0 +1,464 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en-GB">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" />
6
+ <style>
7
+ body {
8
+ /* box-sizing: border-box; */
9
+ margin: 0;
10
+ padding: 0;
11
+ overflow: hidden;
12
+
13
+ /* This is a font-stack that tries to use the system-default sans-serifs first */
14
+ font-family: Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
15
+ line-height: 1.5;
16
+ -webkit-font-smoothing: antialiased;
17
+ }
18
+
19
+ #app {
20
+ width: 100vw;
21
+ height: 100vh;
22
+
23
+ display: flex;
24
+ flex-direction: column;
25
+ }
26
+
27
+ #demo {
28
+ flex: 1;
29
+
30
+ display: flex;
31
+ flex-direction: column;
32
+ overflow: hidden;
33
+ }
34
+
35
+ grist-demo {
36
+ flex: 1;
37
+ overflow: auto;
38
+ }
39
+ </style>
40
+ <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" />
41
+ <link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
42
+
43
+ <link href="/themes/app-theme.css" rel="stylesheet" />
44
+ <link href="/themes/oops-theme.css" rel="stylesheet" />
45
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
46
+ </head>
47
+ <body>
48
+ <script type="module">
49
+ import { LitElement, html, css, render } from 'lit'
50
+ import '../dist/index.js'
51
+ import '@operato/popup'
52
+ import '@material/mwc-icon'
53
+
54
+ const fetchHandler = async ({ page, limit, sorters = [] }) => {
55
+ var total = 120993
56
+ var start = (page - 1) * limit
57
+
58
+ await new Promise(resolve => setTimeout(resolve, 500))
59
+
60
+ return {
61
+ total,
62
+ records: Array(limit * page > total ? total % limit : limit)
63
+ .fill()
64
+ .map((item, idx) => {
65
+ return {
66
+ id: idx,
67
+ name: idx % 2 ? `shnam-${start + idx + 1}` : `heartyoh-${start + idx + 1}`,
68
+ description: idx % 2 ? `hatiolab manager-${start + idx + 1}` : `hatiosea manager-${start + idx + 1}`,
69
+ email: idx % 2 ? `shnam-${start + idx + 1}@gmail.com` : `heartyoh-${start + idx + 1}@gmail.com`,
70
+ active: Math.round(Math.random() * 2) % 2 ? true : false,
71
+ barcode: idx % 2 ? `1234567890${start + idx + 1}` : `0987654321${start + idx + 1}`,
72
+ company:
73
+ idx % 2
74
+ ? {
75
+ id: '2',
76
+ name: 'HatioLAB',
77
+ description: `경기도 성남시-${start + idx + 1}`
78
+ }
79
+ : {
80
+ id: '3',
81
+ name: 'HatioSEA',
82
+ description: `말레이시아 세티아알람-${start + idx + 1}`
83
+ },
84
+ image:
85
+ idx % 2
86
+ ? `http://www.hatiolab.com/assets/img/operato-biz3.png`
87
+ : `http://www.hatiolab.com/assets/img/thingsboard-30.png`,
88
+ role: ['admin', 'worker', 'tester'][idx % 3],
89
+ color: idx % 2 ? `#87f018` : `#180f87`,
90
+ rate: Math.round(Math.random() * 100),
91
+ dynamicType: ['text', 'email', 'checkbox', 'color', 'progress', 'barcode'][idx % 5],
92
+ dynamicValue: ['abcdefghijkl', 'heartyoh@hatiolab.com', 'true', 'orange', '50', '1234567890'][idx % 5],
93
+ homepage:
94
+ idx % 2
95
+ ? `http://hatiolab.com/${start + idx + 1}`
96
+ : `http://deadpool.hatiolab.com/${start + idx + 1}`,
97
+ json5: {
98
+ abc: 'abc',
99
+ value: 123
100
+ },
101
+ createdAt: Date.now(),
102
+ updatedAt: Date.now()
103
+ }
104
+ })
105
+ }
106
+ }
107
+
108
+ const config = {
109
+ list: {
110
+ thumbnail: function (record, rowIndex) {
111
+ return html` <img src=${record.image} style="width: 100%; height: 100%;" /> `
112
+ },
113
+ fields: ['name', 'description'],
114
+ details: ['role', 'email']
115
+ },
116
+ columns: [
117
+ {
118
+ type: 'gutter',
119
+ gutterName: 'dirty'
120
+ },
121
+ {
122
+ type: 'gutter',
123
+ gutterName: 'sequence'
124
+ },
125
+ {
126
+ type: 'gutter',
127
+ gutterName: 'row-selector',
128
+ multiple: true
129
+ },
130
+ {
131
+ type: 'gutter',
132
+ gutterName: 'button',
133
+ icon: 'edit',
134
+ handlers: {
135
+ click: function () {
136
+ console.log('clicked')
137
+ }
138
+ }
139
+ },
140
+ {
141
+ type: 'string',
142
+ name: 'id',
143
+ hidden: true
144
+ },
145
+ {
146
+ type: 'link',
147
+ name: 'name',
148
+ label: true,
149
+ header: 'name',
150
+ record: {
151
+ editable: true,
152
+ options: {
153
+ // href: 'http://hatiolab.com',
154
+ href: function (column, record, rowIndex) {
155
+ return record['homepage']
156
+ }
157
+ // target: '_blank'
158
+ }
159
+ },
160
+ sortable: true,
161
+ width: 120
162
+ },
163
+ {
164
+ type: 'string',
165
+ name: 'description',
166
+ header: 'description',
167
+ record: {
168
+ editable: true,
169
+ align: 'left'
170
+ },
171
+ width: 200,
172
+ handlers: {
173
+ dblclick: (columns, data, column, record, rowIndex) => {
174
+ alert(`${column.name} ${record[column.name]}, row : ${rowIndex}`)
175
+ }
176
+ }
177
+ },
178
+ {
179
+ type: 'email',
180
+ name: 'email',
181
+ label: true,
182
+ header: 'email',
183
+ record: {
184
+ editable: true
185
+ },
186
+ sortable: true,
187
+ width: 130,
188
+ validation: function (after, before, record, column) {
189
+ if (after.indexOf('@') == -1) {
190
+ document.dispatchEvent(
191
+ new CustomEvent('notify', {
192
+ detail: {
193
+ type: 'error',
194
+ message: `invalid value - ${after}`
195
+ }
196
+ })
197
+ )
198
+ return false
199
+ }
200
+ return true
201
+ }
202
+ },
203
+ {
204
+ type: 'boolean',
205
+ name: 'active',
206
+ header: 'active',
207
+ record: {
208
+ editable: true
209
+ },
210
+ handlers: {
211
+ dblclick: () => {
212
+ const grist = document.querySelector('ox-grist')
213
+ console.log(grist.dirtyRecords)
214
+ }
215
+ },
216
+ sortable: true,
217
+ width: 60
218
+ },
219
+ {
220
+ type: 'select',
221
+ name: 'role',
222
+ label: true,
223
+ header: 'role',
224
+ record: {
225
+ options: ['admin', 'worker', 'tester'],
226
+ editable: true
227
+ },
228
+ sortable: true,
229
+ width: 120
230
+ },
231
+ {
232
+ type: 'color',
233
+ name: 'color',
234
+ header: 'color',
235
+ record: {
236
+ editable: true
237
+ },
238
+ sortable: true,
239
+ width: 50
240
+ },
241
+ {
242
+ type: 'float',
243
+ name: 'rate',
244
+ header: 'rate',
245
+ record: {
246
+ align: 'right',
247
+ editable: true
248
+ },
249
+ sortable: true,
250
+ width: 50
251
+ },
252
+ {
253
+ type: 'json5',
254
+ name: 'json5',
255
+ header: 'JSON5',
256
+ width: 200
257
+ },
258
+ {
259
+ type: 'datetime',
260
+ name: 'updatedAt',
261
+ header: 'updated at',
262
+ record: {
263
+ editable: true
264
+ },
265
+ sortable: true,
266
+ width: 180
267
+ },
268
+ {
269
+ type: 'datetime',
270
+ name: 'createdAt',
271
+ header: 'created at',
272
+ record: {
273
+ editable: true
274
+ },
275
+ sortable: true,
276
+ width: 180
277
+ }
278
+ ],
279
+ rows: {
280
+ selectable: {
281
+ multiple: true
282
+ },
283
+ handlers: {
284
+ click: 'select-row-toggle'
285
+ },
286
+ classifier: function (record, rowIndex) {
287
+ const rate = record['rate']
288
+ const emphasized =
289
+ rate < 10 ? ['black', 'white'] : rate < 25 ? ['yellow', 'blue'] : rate < 40 ? ['cyan', 'red'] : undefined
290
+ return {
291
+ emphasized
292
+ }
293
+ }
294
+ },
295
+ sorters: [
296
+ {
297
+ name: 'name',
298
+ desc: true
299
+ },
300
+ {
301
+ name: 'email'
302
+ }
303
+ ],
304
+ pagination: {
305
+ pages: [20, 30, 50, 100, 200]
306
+ }
307
+ }
308
+
309
+ class GristDemo extends LitElement {
310
+ static styles = [
311
+ css`
312
+ :host {
313
+ display: flex;
314
+ }
315
+
316
+ ox-grist {
317
+ flex: 1;
318
+ overflow-y: auto;
319
+
320
+ --grid-record-emphasized-background-color: red;
321
+ --grid-record-emphasized-color: yellow;
322
+ }
323
+
324
+ #headroom {
325
+ display: flex;
326
+ flex-direction: column;
327
+ background-color: var(--primary-color);
328
+ height: 200px;
329
+ align-items: center;
330
+ justify-content: center;
331
+ color: var(--theme-white-color);
332
+ }
333
+
334
+ #modes > * {
335
+ padding: var(--padding-narrow);
336
+ font-size: 1.5em;
337
+ opacity: 0.7;
338
+ }
339
+
340
+ #modes > mwc-icon[active] {
341
+ border: 1px solid var(--status-warning-color);
342
+ border-radius: 9px;
343
+ background-color: rgba(0, 0, 0, 0.3);
344
+ opacity: 1;
345
+ }
346
+
347
+ #filters {
348
+ position: absolute;
349
+ left: 10px;
350
+ bottom: 10px;
351
+ width: calc(100% - 20px);
352
+ }
353
+ `
354
+ ]
355
+
356
+ static get properties() {
357
+ return {
358
+ mode: String
359
+ }
360
+ }
361
+
362
+ render() {
363
+ const mode = this.mode || 'CARD'
364
+
365
+ return html`
366
+ <ox-grist .config=${config} .mode=${mode} auto-fetch .fetchHandler=${fetchHandler}>
367
+ <div slot="headroom" id="headroom">
368
+ <h1>HEAD ROOM AREA</h1>
369
+ <div id="modes">
370
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>view_list</mwc-icon>
371
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>menu</mwc-icon>
372
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
373
+ </div>
374
+ <div id="tailer">
375
+ <a href="./report-test.html">Report Test</a>|
376
+ <a
377
+ href="#"
378
+ @click=${() => {
379
+ this.renderRoot.querySelector('ox-grist').reset()
380
+ }}
381
+ >Reset</a
382
+ >|
383
+ <a
384
+ href="#"
385
+ @click=${() => {
386
+ this.renderRoot.querySelector('ox-grist').fetch(true)
387
+ }}
388
+ >Fetch</a
389
+ >
390
+ </div>
391
+
392
+ <div id="filters">
393
+ <mwc-icon
394
+ @click=${e => {
395
+ const target = e.currentTarget
396
+ this.renderRoot.querySelector('ox-popup-list').open({
397
+ left: target.offsetLeft,
398
+ top: target.offsetTop + target.offsetHeight
399
+ })
400
+ }}
401
+ >sort</mwc-icon
402
+ >
403
+ <mwc-icon
404
+ @click=${e => {
405
+ const target = e.currentTarget
406
+ this.renderRoot.querySelector('ox-popup-list').open({
407
+ left: target.offsetLeft,
408
+ top: target.offsetTop + target.offsetHeight
409
+ })
410
+ }}
411
+ >more_horiz</mwc-icon
412
+ >
413
+ <mwc-icon
414
+ @click=${e => {
415
+ const target = e.currentTarget
416
+ this.renderRoot.querySelector('ox-popup-list').open({
417
+ left: target.offsetLeft,
418
+ top: target.offsetTop + target.offsetHeight
419
+ })
420
+ }}
421
+ >sort</mwc-icon
422
+ >
423
+
424
+ <ox-popup-list alive-on-select>
425
+ <div
426
+ option
427
+ @click=${function (e) {
428
+ const icon = e.currentTarget.querySelector('mwc-icon')
429
+ icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
430
+ }}
431
+ >
432
+ <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
433
+ <span>click me to toggle</span>
434
+ </div>
435
+ <div
436
+ option
437
+ @click=${function (e) {
438
+ const icon = e.currentTarget.querySelector('mwc-icon')
439
+ icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
440
+ }}
441
+ >
442
+ <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
443
+ <span>click me to toggle</span>
444
+ </div>
445
+ </ox-popup-list>
446
+ </div>
447
+ </div>
448
+ </ox-grist>
449
+ `
450
+ }
451
+ }
452
+
453
+ customElements.define('grist-demo', GristDemo)
454
+
455
+ setTimeout(() => {
456
+ render(html` <grist-demo mode="LIST"></grist-demo> `, document.querySelector('#demo'))
457
+ })
458
+ </script>
459
+
460
+ <div id="app">
461
+ <div id="demo"></div>
462
+ </div>
463
+ </body>
464
+ </html>
@@ -1,13 +1,13 @@
1
1
  import { __decorate } from "tslib";
2
2
  import './data-report/data-report-component';
3
3
  import { ZERO_CONFIG, ZERO_DATA, ZERO_PAGINATION } from './configure/config-types';
4
- import { ScrollbarStyles } from '@operato/styles';
5
4
  import { LitElement, css, html } from 'lit';
5
+ import { ScrollbarStyles, SpinnerStyles } from '@operato/styles';
6
6
  import { customElement, property, query, queryAsync, state } from 'lit/decorators.js';
7
7
  import { DataProvider } from './data-provider';
8
- import { SpinnerStyles } from '@operato/styles';
9
8
  import { buildColumn } from './configure/column-builder';
10
9
  import { buildConfig } from './configure/config-builder';
10
+ import i18next from 'i18next';
11
11
  import { pulltorefresh } from '@operato/pull-to-refresh';
12
12
  let DataReport = class DataReport extends LitElement {
13
13
  constructor() {
@@ -153,7 +153,14 @@ let DataReport = class DataReport extends LitElement {
153
153
  var getColumnIndex = (name) => columns.filter(column => !column.hidden).findIndex(column => column.name == name);
154
154
  var groupFieldsForTotalRecord = [
155
155
  /* add a group total record to the front. */
156
- { column: '*', title: 'grand total', align: 'right', rowspan: 1 },
156
+ {
157
+ column: '*',
158
+ title: i18next.exists('text.ox-data-report-grand-total')
159
+ ? i18next.t('text.ox-data-report-grand-total')
160
+ : 'grand total',
161
+ align: 'right',
162
+ rowspan: 1
163
+ },
157
164
  ...groups
158
165
  ].map(group => {
159
166
  return {
@@ -168,7 +175,7 @@ let DataReport = class DataReport extends LitElement {
168
175
  let lastGroupValues;
169
176
  let reportRecords = [];
170
177
  let totalicRecords = sortedRecords[0]
171
- ? (function () {
178
+ ? (() => {
172
179
  /* 처음 만드는 total records */
173
180
  let record = sortedRecords[0];
174
181
  let totalBase = totals.reduce((base, field) => {
@@ -202,7 +209,9 @@ let DataReport = class DataReport extends LitElement {
202
209
  {
203
210
  '*': {
204
211
  titleColumn: groupFieldsForTotalRecord[0].titleColumn,
205
- value: 'grand total',
212
+ value: i18next.exists('text.ox-data-report-grand-total')
213
+ ? i18next.t('text.ox-data-report-grand-total')
214
+ : 'grand total',
206
215
  groupName: '*',
207
216
  row: 1,
208
217
  rowspan: 1,
@@ -1 +1 @@
1
- {"version":3,"file":"data-report.js","sourceRoot":"","sources":["../../src/data-report.ts"],"names":[],"mappings":"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","sourcesContent":["import './data-report/data-report-component'\n\nimport {\n GristConfig,\n GristData,\n GristRecord,\n GroupConfig,\n ZERO_CONFIG,\n ZERO_DATA,\n ZERO_PAGINATION\n} from './configure/config-types'\nimport { HeadroomStyles, ScrollbarStyles } from '@operato/styles'\nimport { LitElement, PropertyValues, css, html } from 'lit'\nimport { customElement, property, query, queryAsync, state } from 'lit/decorators.js'\n\nimport { DataConsumer } from './data-consumer'\nimport { DataProvider } from './data-provider'\nimport { DataReportComponent } from './data-report/data-report-component'\nimport { SpinnerStyles } from '@operato/styles'\nimport { buildColumn } from './configure/column-builder'\nimport { buildConfig } from './configure/config-builder'\nimport { pulltorefresh } from '@operato/pull-to-refresh'\n\n@customElement('ox-report')\nexport class DataReport extends LitElement implements DataConsumer {\n static styles = [\n ScrollbarStyles,\n SpinnerStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n background-color: var(--report-background-color);\n padding: var(--report-padding);\n min-height: 120px;\n\n overflow: hidden;\n\n /* for pulltorefresh controller */\n position: relative;\n }\n\n #wrap {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n }\n\n ox-report-component {\n flex: 1;\n }\n\n ox-empty-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n `\n ]\n\n @property() config: any\n @property() data: GristData = ZERO_DATA\n @property() fetchHandler: any\n @property() fetchOptions: any\n @property({ type: Boolean, attribute: 'auto-fetch' }) autoFetch: boolean = false\n @state() _data: GristData = ZERO_DATA\n @state() _config: GristConfig = ZERO_CONFIG\n @state() private _showSpinner: boolean = false\n\n private dataProvider?: DataProvider\n private pulltorefreshHandle?: any\n\n @query('#report') report!: DataReportComponent\n @queryAsync('#wrap') private wrap!: Promise<HTMLElement>\n\n connectedCallback() {\n super.connectedCallback()\n\n this.dataProvider = new DataProvider(this)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.resetPullToRefresh()\n this.dataProvider?.dispose()\n }\n\n private resetPullToRefresh() {\n if (this.pulltorefreshHandle) {\n this.pulltorefreshHandle()\n delete this.pulltorefreshHandle\n }\n }\n\n private async setPullToRefresh() {\n this.resetPullToRefresh()\n if (this.fetchHandler) {\n this.pulltorefreshHandle = pulltorefresh({\n container: await this.wrap,\n scrollable: this.report.pullToRefreshTarget,\n refresh: () => {\n return this.fetch(true)\n }\n })\n }\n }\n\n async firstUpdated() {\n if (this.fetchHandler && this.autoFetch) {\n await this.requestUpdate()\n this.fetch(true)\n }\n }\n\n render() {\n var oops = !this._showSpinner && (!this._data || !this._data.records || this._data.records.length == 0)\n\n return html`\n ${oops\n ? html`\n <ox-empty-note\n icon=\"list\"\n title=\"EMPTY LIST\"\n description=\"There are no records to be shown\"\n ></ox-empty-note>\n `\n : html``}\n\n <div id=\"wrap\">\n <ox-report-component id=\"report\" .config=${this._config} .data=${this._data}> </ox-report-component>\n </div>\n\n <div id=\"spinner\" ?show=${this._showSpinner}></div>\n `\n }\n\n async fetch(reset = true) {\n if (!this._config) {\n /* avoid to be here */\n console.warn('report is not configured yet.')\n return\n }\n\n if (reset) {\n /*\n * scroll 의 현재위치에 의해서 scroll 이벤트가 발생할 수 있으므로, 이를 방지하기 위해서 스크롤의 위치를 TOP으로 옮긴다.\n * (scroll 이 첫페이지 크기 이상으로 내려가 있는 경우, 첫페이지부터 다시 표시하는 경우에, scroll 이벤트가 발생한다.)\n */\n this.report.scrollTop = 0\n }\n\n if (this.dataProvider) {\n await this.dataProvider.attach(reset)\n }\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('config')) {\n this._config = buildConfig({\n ...this.config\n })\n\n this.dataProvider && (this.dataProvider.sorters = this._config.sorters)\n this.fetch()\n }\n\n if (changes.has('fetchHandler')) {\n this.dataProvider && (this.dataProvider.fetchHandler = this.fetchHandler)\n await this.setPullToRefresh()\n }\n\n if (changes.has('fetchOptions')) {\n this.dataProvider && (this.dataProvider.fetchOptions = this.fetchOptions)\n }\n\n if (changes.has('data')) {\n this.reset()\n }\n }\n\n get dirtyData() {\n return (this.report as any)?.data || {}\n }\n\n showSpinner() {\n this._showSpinner = true\n }\n\n hideSpinner() {\n this._showSpinner = false\n }\n\n focus() {\n super.focus()\n\n this.report?.focus()\n }\n\n /**\n * Forced internal data to be reflected on the screen\n * Data changing through a normal method is automatically reflected on the screen, so it is a method that does not need to be used in general.\nTherefore, it will be deprecated.\n * @deprecated\n * @method\n */\n refresh() {\n this.requestUpdate()\n }\n\n reset() {\n var {\n limit = ZERO_PAGINATION.limit,\n page = ZERO_PAGINATION.page,\n total = ZERO_PAGINATION.total,\n records = []\n } = this.data\n\n this._data = {\n limit,\n page,\n total,\n records: this.sortByGroups(records).map((record, idx) => {\n return {\n ...record,\n __seq__: (page - 1) * limit + idx + 1\n }\n })\n }\n }\n\n sortByGroups(sortedRecords: GristRecord[]) {\n var { groups, totals } = this._config.rows\n var { columns } = this._config\n\n var getColumnIndex = (name: string | number) =>\n columns.filter(column => !column.hidden).findIndex(column => column.name == name)\n\n var groupFieldsForTotalRecord: GroupConfig[] = [\n /* add a group total record to the front. */\n { column: '*', title: 'grand total', align: 'right', rowspan: 1 },\n ...groups\n ].map(group => {\n return {\n ...group,\n titleColumn: buildColumn({\n record: {\n align: group.align || 'right'\n }\n })\n }\n })\n let lastGroupValues\n let reportRecords = []\n let totalicRecords: { [idx: string]: GroupConfig }[] = sortedRecords[0]\n ? (function () {\n /* 처음 만드는 total records */\n let record = sortedRecords[0]\n let totalBase = totals.reduce((base, field) => {\n base[field] = record[field]\n return base\n }, {} as { [totalField: string]: number })\n let groupBase = {} as { [idx: string]: GroupConfig }\n\n return groupFieldsForTotalRecord.map((group, idx) => {\n groupBase[group.column] = record[group.column]\n\n return {\n ...totalBase,\n ...groupBase,\n [group.column]: record[group.column],\n '*': {\n titleColumn: group.titleColumn,\n value: group.title,\n groupName: group.column,\n /* 이 레코드 그룹에 해당하는 첫번째 레코드의 행 번호(1 부터 시작하는 번호임.) - grid layout의 row 지정에 사용됨. */\n row: 1,\n rowspan: 1,\n /* 이 레코드 그룹의 컬럼에 해당하는 열 번호(1 부터 시작하는 번호임.) - grid layout의 column 지정에 사용됨. */\n column:\n group.column !== '*'\n ? getColumnIndex(group.column) + 1\n : getColumnIndex(groups[0].column) + 1 /* grand total 은 첫번째 그룹 컬럼을 사용한다. */,\n colspan:\n group.column !== '*' ? groupFieldsForTotalRecord.length - idx : groupFieldsForTotalRecord.length - 1\n }\n }\n })\n })()\n : [\n {\n '*': {\n titleColumn: groupFieldsForTotalRecord[0].titleColumn,\n value: 'grand total',\n groupName: '*',\n row: 1,\n rowspan: 1,\n column: 1,\n colspan: 0\n } as GroupConfig\n }\n ]\n\n var row = 0\n\n for (let record of sortedRecords) {\n let groupValues = groups.reduce((base, group) => {\n base[group.column] = record[group.column]\n return base\n }, {} as { [groupColumn: string]: string | number })\n let isSameGroupRecord = true\n let totalsStack = [] as { idx: string; record: any }[]\n let groupBase = {} as { [idx: string]: any }\n\n row++\n\n if (lastGroupValues) {\n for (let idx in groupFieldsForTotalRecord) {\n let group = groupFieldsForTotalRecord[idx]\n let totalRecord: {\n [idx: string]: GroupConfig | number\n } = totalicRecords[idx]\n\n groupBase[group.column] = record[group.column]\n\n if (\n group.column == '*' ||\n (isSameGroupRecord && groupValues[group.column] === lastGroupValues[group.column])\n ) {\n for (let field of totals) {\n totalRecord[field] += record[field]\n }\n\n ;(totalRecord['*'] as GroupConfig).rowspan++\n\n continue\n }\n\n /* to avoid from floating point calculation problem */\n totals.forEach(field => {\n totalRecord[field] = Math.round((totalRecord[field] as number) * 100) / 100\n })\n\n isSameGroupRecord = false\n\n totalsStack.push({\n idx,\n record: totals.reduce(\n (sum, field) => {\n sum[field] = record[field]\n return sum\n },\n {\n ...groupBase,\n [group.column]: record[group.column],\n '*': {\n titleColumn: group.titleColumn,\n groupName: group.column,\n value: group.title,\n row,\n rowspan: 1,\n column: getColumnIndex(group.column) + 1,\n colspan: totalicRecords[idx]['*'].colspan\n }\n }\n )\n })\n }\n\n totalsStack\n .reverse()\n .map(({ record, idx }) => {\n reportRecords.push(totalicRecords[Number(idx)])\n totalicRecords[Number(idx)] = {}\n\n if (record['*'].value) {\n totalicRecords.forEach(record => record['*'] && record['*'].rowspan++)\n row++\n }\n\n return { record, idx }\n })\n .forEach(({ record, idx }) => {\n record['*'].row = row\n totalicRecords[Number(idx)] = record\n })\n }\n\n reportRecords.push(record)\n\n lastGroupValues = groupValues\n }\n\n /* 마지막 남은 토탈 레코드들을 추가한다. */\n var poped: any\n while ((poped = totalicRecords.pop())) {\n /* to avoid from floating point calculation problem */\n totals.forEach(field => {\n poped[field] = Math.round(poped[field] * 100) / 100\n })\n\n reportRecords.push(poped)\n if (poped['*'].value) {\n totalicRecords.forEach(record => record['*'].rowspan++)\n }\n }\n\n return reportRecords\n }\n\n checkDirties() {}\n}\n"]}
1
+ {"version":3,"file":"data-report.js","sourceRoot":"","sources":["../../src/data-report.ts"],"names":[],"mappings":"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","sourcesContent":["import './data-report/data-report-component'\n\nimport {\n GristConfig,\n GristData,\n GristRecord,\n GroupConfig,\n ZERO_CONFIG,\n ZERO_DATA,\n ZERO_PAGINATION\n} from './configure/config-types'\nimport { LitElement, PropertyValues, css, html } from 'lit'\nimport { ScrollbarStyles, SpinnerStyles } from '@operato/styles'\nimport { customElement, property, query, queryAsync, state } from 'lit/decorators.js'\n\nimport { DataConsumer } from './data-consumer'\nimport { DataProvider } from './data-provider'\nimport { DataReportComponent } from './data-report/data-report-component'\nimport { buildColumn } from './configure/column-builder'\nimport { buildConfig } from './configure/config-builder'\nimport i18next from 'i18next'\nimport { pulltorefresh } from '@operato/pull-to-refresh'\n\n@customElement('ox-report')\nexport class DataReport extends LitElement implements DataConsumer {\n static styles = [\n ScrollbarStyles,\n SpinnerStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n background-color: var(--report-background-color);\n padding: var(--report-padding);\n min-height: 120px;\n\n overflow: hidden;\n\n /* for pulltorefresh controller */\n position: relative;\n }\n\n #wrap {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n }\n\n ox-report-component {\n flex: 1;\n }\n\n ox-empty-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n `\n ]\n\n @property() config: any\n @property() data: GristData = ZERO_DATA\n @property() fetchHandler: any\n @property() fetchOptions: any\n @property({ type: Boolean, attribute: 'auto-fetch' }) autoFetch: boolean = false\n\n @state() _data: GristData = ZERO_DATA\n @state() _config: GristConfig = ZERO_CONFIG\n @state() private _showSpinner: boolean = false\n\n private dataProvider?: DataProvider\n private pulltorefreshHandle?: any\n\n @query('#report') report!: DataReportComponent\n @queryAsync('#wrap') private wrap!: Promise<HTMLElement>\n\n connectedCallback() {\n super.connectedCallback()\n\n this.dataProvider = new DataProvider(this)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.resetPullToRefresh()\n this.dataProvider?.dispose()\n }\n\n private resetPullToRefresh() {\n if (this.pulltorefreshHandle) {\n this.pulltorefreshHandle()\n delete this.pulltorefreshHandle\n }\n }\n\n private async setPullToRefresh() {\n this.resetPullToRefresh()\n if (this.fetchHandler) {\n this.pulltorefreshHandle = pulltorefresh({\n container: await this.wrap,\n scrollable: this.report.pullToRefreshTarget,\n refresh: () => {\n return this.fetch(true)\n }\n })\n }\n }\n\n async firstUpdated() {\n if (this.fetchHandler && this.autoFetch) {\n await this.requestUpdate()\n this.fetch(true)\n }\n }\n\n render() {\n var oops = !this._showSpinner && (!this._data || !this._data.records || this._data.records.length == 0)\n\n return html`\n ${oops\n ? html`\n <ox-empty-note\n icon=\"list\"\n title=\"EMPTY LIST\"\n description=\"There are no records to be shown\"\n ></ox-empty-note>\n `\n : html``}\n\n <div id=\"wrap\">\n <ox-report-component id=\"report\" .config=${this._config} .data=${this._data}> </ox-report-component>\n </div>\n\n <div id=\"spinner\" ?show=${this._showSpinner}></div>\n `\n }\n\n async fetch(reset = true) {\n if (!this._config) {\n /* avoid to be here */\n console.warn('report is not configured yet.')\n return\n }\n\n if (reset) {\n /*\n * scroll 의 현재위치에 의해서 scroll 이벤트가 발생할 수 있으므로, 이를 방지하기 위해서 스크롤의 위치를 TOP으로 옮긴다.\n * (scroll 이 첫페이지 크기 이상으로 내려가 있는 경우, 첫페이지부터 다시 표시하는 경우에, scroll 이벤트가 발생한다.)\n */\n this.report.scrollTop = 0\n }\n\n if (this.dataProvider) {\n await this.dataProvider.attach(reset)\n }\n }\n\n async updated(changes: PropertyValues<this>) {\n if (changes.has('config')) {\n this._config = buildConfig({\n ...this.config\n })\n\n this.dataProvider && (this.dataProvider.sorters = this._config.sorters)\n this.fetch()\n }\n\n if (changes.has('fetchHandler')) {\n this.dataProvider && (this.dataProvider.fetchHandler = this.fetchHandler)\n await this.setPullToRefresh()\n }\n\n if (changes.has('fetchOptions')) {\n this.dataProvider && (this.dataProvider.fetchOptions = this.fetchOptions)\n }\n\n if (changes.has('data')) {\n this.reset()\n }\n }\n\n get dirtyData() {\n return (this.report as any)?.data || {}\n }\n\n showSpinner() {\n this._showSpinner = true\n }\n\n hideSpinner() {\n this._showSpinner = false\n }\n\n focus() {\n super.focus()\n\n this.report?.focus()\n }\n\n /**\n * Forced internal data to be reflected on the screen\n * Data changing through a normal method is automatically reflected on the screen, so it is a method that does not need to be used in general.\nTherefore, it will be deprecated.\n * @deprecated\n * @method\n */\n refresh() {\n this.requestUpdate()\n }\n\n reset() {\n var {\n limit = ZERO_PAGINATION.limit,\n page = ZERO_PAGINATION.page,\n total = ZERO_PAGINATION.total,\n records = []\n } = this.data\n\n this._data = {\n limit,\n page,\n total,\n records: this.sortByGroups(records).map((record, idx) => {\n return {\n ...record,\n __seq__: (page - 1) * limit + idx + 1\n }\n })\n }\n }\n\n sortByGroups(sortedRecords: GristRecord[]) {\n var { groups, totals } = this._config.rows\n var { columns } = this._config\n\n var getColumnIndex = (name: string | number) =>\n columns.filter(column => !column.hidden).findIndex(column => column.name == name)\n\n var groupFieldsForTotalRecord: GroupConfig[] = [\n /* add a group total record to the front. */\n {\n column: '*',\n title: i18next.exists('text.ox-data-report-grand-total')\n ? i18next.t('text.ox-data-report-grand-total')\n : 'grand total',\n align: 'right',\n rowspan: 1\n },\n ...groups\n ].map(group => {\n return {\n ...group,\n titleColumn: buildColumn({\n record: {\n align: group.align || 'right'\n }\n })\n }\n })\n let lastGroupValues\n let reportRecords = []\n let totalicRecords: { [idx: string]: GroupConfig }[] = sortedRecords[0]\n ? (() => {\n /* 처음 만드는 total records */\n let record = sortedRecords[0]\n let totalBase = totals.reduce((base, field) => {\n base[field] = record[field]\n return base\n }, {} as { [totalField: string]: number })\n let groupBase = {} as { [idx: string]: GroupConfig }\n\n return groupFieldsForTotalRecord.map((group, idx) => {\n groupBase[group.column] = record[group.column]\n\n return {\n ...totalBase,\n ...groupBase,\n [group.column]: record[group.column],\n '*': {\n titleColumn: group.titleColumn,\n value: group.title,\n groupName: group.column,\n /* 이 레코드 그룹에 해당하는 첫번째 레코드의 행 번호(1 부터 시작하는 번호임.) - grid layout의 row 지정에 사용됨. */\n row: 1,\n rowspan: 1,\n /* 이 레코드 그룹의 컬럼에 해당하는 열 번호(1 부터 시작하는 번호임.) - grid layout의 column 지정에 사용됨. */\n column:\n group.column !== '*'\n ? getColumnIndex(group.column) + 1\n : getColumnIndex(groups[0].column) + 1 /* grand total 은 첫번째 그룹 컬럼을 사용한다. */,\n colspan:\n group.column !== '*' ? groupFieldsForTotalRecord.length - idx : groupFieldsForTotalRecord.length - 1\n }\n }\n })\n })()\n : [\n {\n '*': {\n titleColumn: groupFieldsForTotalRecord[0].titleColumn,\n value: i18next.exists('text.ox-data-report-grand-total')\n ? i18next.t('text.ox-data-report-grand-total')\n : 'grand total',\n groupName: '*',\n row: 1,\n rowspan: 1,\n column: 1,\n colspan: 0\n } as GroupConfig\n }\n ]\n\n var row = 0\n\n for (let record of sortedRecords) {\n let groupValues = groups.reduce((base, group) => {\n base[group.column] = record[group.column]\n return base\n }, {} as { [groupColumn: string]: string | number })\n let isSameGroupRecord = true\n let totalsStack = [] as { idx: string; record: any }[]\n let groupBase = {} as { [idx: string]: any }\n\n row++\n\n if (lastGroupValues) {\n for (let idx in groupFieldsForTotalRecord) {\n let group = groupFieldsForTotalRecord[idx]\n let totalRecord: {\n [idx: string]: GroupConfig | number\n } = totalicRecords[idx]\n\n groupBase[group.column] = record[group.column]\n\n if (\n group.column == '*' ||\n (isSameGroupRecord && groupValues[group.column] === lastGroupValues[group.column])\n ) {\n for (let field of totals) {\n totalRecord[field] += record[field]\n }\n\n ;(totalRecord['*'] as GroupConfig).rowspan++\n\n continue\n }\n\n /* to avoid from floating point calculation problem */\n totals.forEach(field => {\n totalRecord[field] = Math.round((totalRecord[field] as number) * 100) / 100\n })\n\n isSameGroupRecord = false\n\n totalsStack.push({\n idx,\n record: totals.reduce(\n (sum, field) => {\n sum[field] = record[field]\n return sum\n },\n {\n ...groupBase,\n [group.column]: record[group.column],\n '*': {\n titleColumn: group.titleColumn,\n groupName: group.column,\n value: group.title,\n row,\n rowspan: 1,\n column: getColumnIndex(group.column) + 1,\n colspan: totalicRecords[idx]['*'].colspan\n }\n }\n )\n })\n }\n\n totalsStack\n .reverse()\n .map(({ record, idx }) => {\n reportRecords.push(totalicRecords[Number(idx)])\n totalicRecords[Number(idx)] = {}\n\n if (record['*'].value) {\n totalicRecords.forEach(record => record['*'] && record['*'].rowspan++)\n row++\n }\n\n return { record, idx }\n })\n .forEach(({ record, idx }) => {\n record['*'].row = row\n totalicRecords[Number(idx)] = record\n })\n }\n\n reportRecords.push(record)\n\n lastGroupValues = groupValues\n }\n\n /* 마지막 남은 토탈 레코드들을 추가한다. */\n var poped: any\n while ((poped = totalicRecords.pop())) {\n /* to avoid from floating point calculation problem */\n totals.forEach(field => {\n poped[field] = Math.round(poped[field] * 100) / 100\n })\n\n reportRecords.push(poped)\n if (poped['*'].value) {\n totalicRecords.forEach(record => record['*'].rowspan++)\n }\n }\n\n return reportRecords\n }\n\n checkDirties() {}\n}\n"]}