@operato/data-grist 7.1.31 → 7.1.33
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 +19 -0
- package/dist/src/data-grid/data-grid-field.js +4 -1
- package/dist/src/data-grid/data-grid-field.js.map +1 -1
- package/dist/src/record-view/record-view-body.js +8 -4
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/demo/data-grist-test.html +0 -468
- package/demo/favicon.ico +0 -0
- package/demo/index.html +0 -541
- package/demo/report-test.html +0 -249
- package/src/accumulator/accumulator.ts +0 -63
- package/src/configure/column-builder.ts +0 -114
- package/src/configure/config-builder.ts +0 -40
- package/src/configure/filters-option-builder.ts +0 -8
- package/src/configure/imex-option-builder.ts +0 -5
- package/src/configure/list-option-builder.ts +0 -9
- package/src/configure/rows-option-builder.ts +0 -38
- package/src/configure/tree-option-builder.ts +0 -22
- package/src/configure/zero-config.ts +0 -83
- package/src/const.ts +0 -1
- package/src/data-card/data-card-field.ts +0 -94
- package/src/data-card/data-card-gutter-menu.ts +0 -94
- package/src/data-card/data-card-gutter.ts +0 -103
- package/src/data-card/data-card.ts +0 -154
- package/src/data-card/event-handlers/record-card-click-handler.ts +0 -34
- package/src/data-card/event-handlers/record-card-dblclick-handler.ts +0 -34
- package/src/data-card/record-card.ts +0 -289
- package/src/data-consumer.ts +0 -11
- package/src/data-grid/data-grid-accum-field.ts +0 -109
- package/src/data-grid/data-grid-body-style.ts +0 -99
- package/src/data-grid/data-grid-body.ts +0 -753
- package/src/data-grid/data-grid-field.ts +0 -236
- package/src/data-grid/data-grid-footer.ts +0 -117
- package/src/data-grid/data-grid-header.ts +0 -574
- package/src/data-grid/data-grid.ts +0 -293
- package/src/data-grid/event-handlers/data-grid-body-click-handler.ts +0 -69
- package/src/data-grid/event-handlers/data-grid-body-contextmenu-handler.ts +0 -32
- package/src/data-grid/event-handlers/data-grid-body-dblclick-handler.ts +0 -42
- package/src/data-grid/event-handlers/data-grid-body-focus-change-handler.ts +0 -24
- package/src/data-grid/event-handlers/data-grid-body-keydown-handler.ts +0 -234
- package/src/data-grist.ts +0 -1233
- package/src/data-list/data-list-field.ts +0 -82
- package/src/data-list/data-list-gutter.ts +0 -108
- package/src/data-list/data-list.ts +0 -145
- package/src/data-list/event-handlers/record-partial-click-handler.ts +0 -34
- package/src/data-list/event-handlers/record-partial-dblclick-handler.ts +0 -33
- package/src/data-list/event-handlers/record-partial-long-press-handler.ts +0 -33
- package/src/data-list/record-partial.ts +0 -255
- package/src/data-manipulator.ts +0 -426
- package/src/data-provider.ts +0 -271
- package/src/data-report/data-report-body-style.ts +0 -58
- package/src/data-report/data-report-body.ts +0 -189
- package/src/data-report/data-report-component.ts +0 -138
- package/src/data-report/data-report-field.ts +0 -83
- package/src/data-report/data-report-header.ts +0 -242
- package/src/data-report/event-handlers/data-report-body-click-handler.ts +0 -38
- package/src/data-report/event-handlers/data-report-body-dblclick-handler.ts +0 -25
- package/src/data-report/event-handlers/data-report-body-keydown-handler.ts +0 -68
- package/src/data-report.ts +0 -424
- package/src/editors/index.ts +0 -4
- package/src/editors/ox-grist-editor-checkbox.ts +0 -28
- package/src/editors/ox-grist-editor-color.ts +0 -10
- package/src/editors/ox-grist-editor-date.ts +0 -10
- package/src/editors/ox-grist-editor-datetime.ts +0 -27
- package/src/editors/ox-grist-editor-email.ts +0 -10
- package/src/editors/ox-grist-editor-file.ts +0 -28
- package/src/editors/ox-grist-editor-image.ts +0 -31
- package/src/editors/ox-grist-editor-month.ts +0 -10
- package/src/editors/ox-grist-editor-multiple-select.ts +0 -57
- package/src/editors/ox-grist-editor-number.ts +0 -27
- package/src/editors/ox-grist-editor-password.ts +0 -10
- package/src/editors/ox-grist-editor-select.ts +0 -55
- package/src/editors/ox-grist-editor-tel.ts +0 -10
- package/src/editors/ox-grist-editor-text.ts +0 -14
- package/src/editors/ox-grist-editor-textarea.ts +0 -16
- package/src/editors/ox-grist-editor-time.ts +0 -10
- package/src/editors/ox-grist-editor-tree.ts +0 -27
- package/src/editors/ox-grist-editor-varname.ts +0 -36
- package/src/editors/ox-grist-editor-week.ts +0 -10
- package/src/editors/ox-grist-editor.ts +0 -207
- package/src/editors/ox-input-tree.ts +0 -226
- package/src/editors/registry.ts +0 -82
- package/src/empty-note.ts +0 -46
- package/src/filters/filter-checkbox.ts +0 -49
- package/src/filters/filter-input-barcode.ts +0 -34
- package/src/filters/filter-input.ts +0 -30
- package/src/filters/filter-range-date.ts +0 -81
- package/src/filters/filter-range-number.ts +0 -64
- package/src/filters/filter-select-buttons.ts +0 -60
- package/src/filters/filter-select.ts +0 -68
- package/src/filters/filter-styles.ts +0 -119
- package/src/filters/filters-form.ts +0 -476
- package/src/filters/index.ts +0 -10
- package/src/filters/registry.ts +0 -56
- package/src/formatters/date-formatter.ts +0 -3
- package/src/formatters/index.ts +0 -1
- package/src/formatters/number-formatter.ts +0 -3
- package/src/formatters/registry.ts +0 -30
- package/src/formatters/text-formatter.ts +0 -3
- package/src/gutters/gutter-button.ts +0 -51
- package/src/gutters/gutter-dirty.ts +0 -96
- package/src/gutters/gutter-row-selector.ts +0 -89
- package/src/gutters/gutter-sequence.ts +0 -54
- package/src/gutters/index.ts +0 -1
- package/src/gutters/registry.ts +0 -32
- package/src/handlers/contextmenu-tree-mutation.ts +0 -80
- package/src/handlers/index.ts +0 -1
- package/src/handlers/move-down.ts +0 -44
- package/src/handlers/move-up.ts +0 -44
- package/src/handlers/record-copy.ts +0 -38
- package/src/handlers/record-delete.ts +0 -30
- package/src/handlers/record-view-handler.ts +0 -27
- package/src/handlers/registry.ts +0 -42
- package/src/handlers/select-row-toggle.ts +0 -30
- package/src/handlers/select-row.ts +0 -27
- package/src/index.ts +0 -17
- package/src/personalizer/index.ts +0 -1
- package/src/personalizer/ox-grist-filter-personalizer.ts +0 -192
- package/src/personalizer/ox-grist-personalizer.ts +0 -226
- package/src/record-view/event-handlers/record-view-body-click-handler.ts +0 -33
- package/src/record-view/event-handlers/record-view-body-keydown-handler.ts +0 -26
- package/src/record-view/index.ts +0 -2
- package/src/record-view/ox-record-creator.ts +0 -289
- package/src/record-view/record-view-body.ts +0 -250
- package/src/record-view/record-view-handler.ts +0 -86
- package/src/record-view/record-view.ts +0 -122
- package/src/renderers/index.ts +0 -14
- package/src/renderers/ox-grist-renderer-boolean.ts +0 -43
- package/src/renderers/ox-grist-renderer-color.ts +0 -15
- package/src/renderers/ox-grist-renderer-date.ts +0 -62
- package/src/renderers/ox-grist-renderer-file.ts +0 -31
- package/src/renderers/ox-grist-renderer-image.ts +0 -27
- package/src/renderers/ox-grist-renderer-json5.ts +0 -36
- package/src/renderers/ox-grist-renderer-link.ts +0 -17
- package/src/renderers/ox-grist-renderer-password.ts +0 -7
- package/src/renderers/ox-grist-renderer-progress.ts +0 -45
- package/src/renderers/ox-grist-renderer-select.ts +0 -58
- package/src/renderers/ox-grist-renderer-text.ts +0 -16
- package/src/renderers/ox-grist-renderer-textarea.ts +0 -7
- package/src/renderers/ox-grist-renderer-tree.ts +0 -189
- package/src/renderers/ox-grist-renderer.ts +0 -35
- package/src/renderers/registry.ts +0 -111
- package/src/sorters/sorters-control.ts +0 -143
- package/src/types.ts +0 -813
- package/src/utils/index.ts +0 -2
- package/src/utils/list-param.ts +0 -72
- package/src/utils/supports-passive.ts +0 -13
- package/stories/accumulator-format.stories.ts +0 -276
- package/stories/barcode-input-filter.stories.ts +0 -216
- package/stories/bounded-select-filters.stories.ts +0 -333
- package/stories/bounded-select-record.stories.ts +0 -336
- package/stories/click-event-custom.stories.ts +0 -288
- package/stories/click-event.stories.ts +0 -283
- package/stories/creatable-only-column.stories.ts +0 -253
- package/stories/default-filters.stories.ts +0 -241
- package/stories/dynamic-editable.stories.ts +0 -313
- package/stories/empty-sorters.stories.ts +0 -180
- package/stories/explicit-fetch.stories.ts +0 -186
- package/stories/fixed-column.stories.ts +0 -416
- package/stories/grid-setting.stories.ts +0 -501
- package/stories/grist-modes.stories.ts +0 -451
- package/stories/group-header.stories.ts +0 -442
- package/stories/record-view.stories.ts +0 -143
- package/stories/textarea.stories.ts +0 -261
- package/stories/tree-column-with-checkbox.stories.ts +0 -297
- package/stories/tree-column.stories.ts +0 -296
- package/tsconfig.json +0 -26
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -45
@@ -1,38 +0,0 @@
|
|
1
|
-
import { DataReportBody } from '../data-report-body'
|
2
|
-
import { DataReportField } from '../data-report-field'
|
3
|
-
|
4
|
-
/**
|
5
|
-
* ox-report-body 의 click handler
|
6
|
-
*/
|
7
|
-
export function dataReportBodyClickHandler(this: DataReportBody, e: Event) {
|
8
|
-
e.stopPropagation()
|
9
|
-
|
10
|
-
var target = e.target as DataReportField
|
11
|
-
var { column, record, rowIndex, columnIndex } = target
|
12
|
-
|
13
|
-
if (!column) {
|
14
|
-
/* 여백 컬럼이 클릭된 경우 */
|
15
|
-
return
|
16
|
-
}
|
17
|
-
|
18
|
-
if (!isNaN(rowIndex) && !isNaN(columnIndex)) {
|
19
|
-
if (!this.focused || rowIndex !== this.focused.row || columnIndex !== this.focused.column) {
|
20
|
-
this.focused = {
|
21
|
-
row: rowIndex,
|
22
|
-
column: columnIndex
|
23
|
-
}
|
24
|
-
} else {
|
25
|
-
this.requestUpdate()
|
26
|
-
}
|
27
|
-
} else {
|
28
|
-
console.error('should not be here.')
|
29
|
-
}
|
30
|
-
|
31
|
-
/* do column click handler */
|
32
|
-
var { click } = column.handlers
|
33
|
-
click && click(this.columns, this.data, column, record, rowIndex, target)
|
34
|
-
|
35
|
-
/* do rows click handler */
|
36
|
-
var { click: rowsClick } = this.config.rows.handlers
|
37
|
-
rowsClick && rowsClick(this.columns, this.data, column, record, rowIndex, target)
|
38
|
-
}
|
@@ -1,25 +0,0 @@
|
|
1
|
-
import { DataReportBody } from '../data-report-body'
|
2
|
-
import { DataReportField } from '../data-report-field'
|
3
|
-
|
4
|
-
/**
|
5
|
-
* ox-report-body 의 dblclick handler
|
6
|
-
*/
|
7
|
-
export async function dataReportBodyDblclickHandler(this: DataReportBody, e: Event) {
|
8
|
-
e.stopPropagation()
|
9
|
-
|
10
|
-
var target = e.target as DataReportField
|
11
|
-
var { record, rowIndex, column } = target
|
12
|
-
|
13
|
-
if (!column) {
|
14
|
-
/* 여백 컬럼이 클릭된 경우 */
|
15
|
-
return
|
16
|
-
}
|
17
|
-
|
18
|
-
/* do column dblclick handler */
|
19
|
-
var { dblclick } = column.handlers
|
20
|
-
dblclick && dblclick(this.columns, this.data, column, record, rowIndex, target)
|
21
|
-
|
22
|
-
/* do rows dblclick handler */
|
23
|
-
var { dblclick: rowsDblclick } = this.config.rows.handlers
|
24
|
-
rowsDblclick && rowsDblclick(this.columns, this.data, column, record, rowIndex, target)
|
25
|
-
}
|
@@ -1,68 +0,0 @@
|
|
1
|
-
import { DataReportBody } from '../data-report-body'
|
2
|
-
|
3
|
-
/**
|
4
|
-
* ox-report-body 의 keydown handler
|
5
|
-
*/
|
6
|
-
export function dataReportBodyKeydownHandler(this: DataReportBody, e: KeyboardEvent): void {
|
7
|
-
// arrow-key
|
8
|
-
const key = e.key
|
9
|
-
var { row = 0, column = 0 } = this.focused || {}
|
10
|
-
var { records = [] } = this.data || {}
|
11
|
-
var maxrow = this.config.rows?.appendable ? records.length : records.length - 1
|
12
|
-
var maxcolumn = (this.columns || []).filter(column => !column.hidden).length - 1
|
13
|
-
|
14
|
-
switch (key) {
|
15
|
-
case 'Up':
|
16
|
-
case 'ArrowUp':
|
17
|
-
row = Math.max(0, row - 1)
|
18
|
-
break
|
19
|
-
|
20
|
-
case 'Down':
|
21
|
-
case 'ArrowDown':
|
22
|
-
row = Math.min(maxrow, row + 1)
|
23
|
-
break
|
24
|
-
|
25
|
-
case 'Enter':
|
26
|
-
if (maxcolumn > column) {
|
27
|
-
column++
|
28
|
-
} else if (maxrow > row) {
|
29
|
-
row++
|
30
|
-
}
|
31
|
-
break
|
32
|
-
|
33
|
-
case 'Left':
|
34
|
-
case 'ArrowLeft':
|
35
|
-
case 'Backspace':
|
36
|
-
column = Math.max(0, column - 1)
|
37
|
-
break
|
38
|
-
|
39
|
-
case 'Right':
|
40
|
-
case 'ArrowRight':
|
41
|
-
case 'Tab':
|
42
|
-
column = Math.min(maxcolumn, column + 1)
|
43
|
-
break
|
44
|
-
|
45
|
-
case 'PageUp':
|
46
|
-
/* TODO 페이지당 레코드의 수를 계산해서 증감시켜야 한다. */
|
47
|
-
row = Math.max(0, row - 10)
|
48
|
-
break
|
49
|
-
|
50
|
-
case 'PageDown':
|
51
|
-
row = Math.min(maxrow, row + 10)
|
52
|
-
break
|
53
|
-
|
54
|
-
case 'Esc':
|
55
|
-
case 'Escape':
|
56
|
-
return
|
57
|
-
|
58
|
-
default:
|
59
|
-
return
|
60
|
-
}
|
61
|
-
|
62
|
-
if (!this.focused || this.focused.row !== row || this.focused.column !== column) {
|
63
|
-
this.focused = { row, column }
|
64
|
-
}
|
65
|
-
|
66
|
-
/* arrow key에 의한 scrollbar의 자동 움직임을 하지 못하도록 한다. */
|
67
|
-
e.preventDefault()
|
68
|
-
}
|
package/src/data-report.ts
DELETED
@@ -1,424 +0,0 @@
|
|
1
|
-
import './data-report/data-report-component'
|
2
|
-
|
3
|
-
import { GristConfig, GristData, GristRecord, GroupConfig } from './types'
|
4
|
-
import { LitElement, PropertyValues, css, html } from 'lit'
|
5
|
-
import { ScrollbarStyles, SpinnerStyles } from '@operato/styles'
|
6
|
-
import { ZERO_CONFIG, ZERO_DATA, ZERO_PAGINATION } from './configure/zero-config'
|
7
|
-
import { customElement, property, query, queryAsync, state } from 'lit/decorators.js'
|
8
|
-
|
9
|
-
import { DataConsumer } from './data-consumer'
|
10
|
-
import { DataProvider } from './data-provider'
|
11
|
-
import { DataReportComponent } from './data-report/data-report-component'
|
12
|
-
import { buildColumn } from './configure/column-builder'
|
13
|
-
import { buildConfig } from './configure/config-builder'
|
14
|
-
import i18next from 'i18next'
|
15
|
-
import { pulltorefresh } from '@operato/pull-to-refresh'
|
16
|
-
|
17
|
-
@customElement('ox-report')
|
18
|
-
export class DataReport extends LitElement implements DataConsumer {
|
19
|
-
static styles = [
|
20
|
-
ScrollbarStyles,
|
21
|
-
SpinnerStyles,
|
22
|
-
css`
|
23
|
-
:host {
|
24
|
-
display: flex;
|
25
|
-
flex-direction: column;
|
26
|
-
box-sizing: border-box;
|
27
|
-
background-color: var(--report-background-color);
|
28
|
-
padding: var(--report-padding);
|
29
|
-
min-height: 120px;
|
30
|
-
|
31
|
-
overflow: hidden;
|
32
|
-
|
33
|
-
/* for pulltorefresh controller */
|
34
|
-
position: relative;
|
35
|
-
}
|
36
|
-
|
37
|
-
#wrap {
|
38
|
-
flex: 1;
|
39
|
-
display: flex;
|
40
|
-
flex-direction: column;
|
41
|
-
overflow: auto;
|
42
|
-
}
|
43
|
-
|
44
|
-
ox-report-component {
|
45
|
-
flex: 1;
|
46
|
-
}
|
47
|
-
|
48
|
-
ox-empty-note {
|
49
|
-
display: block;
|
50
|
-
position: absolute;
|
51
|
-
left: 50%;
|
52
|
-
top: 50%;
|
53
|
-
transform: translate(-50%, -50%);
|
54
|
-
}
|
55
|
-
`
|
56
|
-
]
|
57
|
-
|
58
|
-
@property() config: any
|
59
|
-
@property() data: GristData = ZERO_DATA
|
60
|
-
@property() fetchHandler: any
|
61
|
-
@property() fetchOptions: any
|
62
|
-
@property({ type: Boolean, attribute: 'auto-fetch' }) autoFetch: boolean = false
|
63
|
-
|
64
|
-
@state() _data: GristData = ZERO_DATA
|
65
|
-
@state() _config: GristConfig = ZERO_CONFIG
|
66
|
-
@state() private _showSpinner: boolean = false
|
67
|
-
|
68
|
-
private dataProvider?: DataProvider
|
69
|
-
private pulltorefreshHandle?: any
|
70
|
-
|
71
|
-
@query('#report') report!: DataReportComponent
|
72
|
-
@queryAsync('#wrap') private wrap!: Promise<HTMLElement>
|
73
|
-
|
74
|
-
get mode(): 'REPORT' {
|
75
|
-
return 'REPORT'
|
76
|
-
}
|
77
|
-
|
78
|
-
connectedCallback() {
|
79
|
-
super.connectedCallback()
|
80
|
-
|
81
|
-
this.dataProvider = new DataProvider(this)
|
82
|
-
}
|
83
|
-
|
84
|
-
disconnectedCallback() {
|
85
|
-
super.disconnectedCallback()
|
86
|
-
|
87
|
-
this.resetPullToRefresh()
|
88
|
-
this.dataProvider?.dispose()
|
89
|
-
}
|
90
|
-
|
91
|
-
private resetPullToRefresh() {
|
92
|
-
if (this.pulltorefreshHandle) {
|
93
|
-
this.pulltorefreshHandle()
|
94
|
-
delete this.pulltorefreshHandle
|
95
|
-
}
|
96
|
-
}
|
97
|
-
|
98
|
-
private async setPullToRefresh() {
|
99
|
-
this.resetPullToRefresh()
|
100
|
-
if (this.fetchHandler) {
|
101
|
-
this.pulltorefreshHandle = pulltorefresh({
|
102
|
-
container: await this.wrap,
|
103
|
-
scrollable: this.report.pullToRefreshTarget,
|
104
|
-
refresh: () => {
|
105
|
-
return this.fetch(true)
|
106
|
-
}
|
107
|
-
})
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
async firstUpdated() {
|
112
|
-
if (this.fetchHandler && this.autoFetch) {
|
113
|
-
await this.requestUpdate()
|
114
|
-
this.fetch(true)
|
115
|
-
}
|
116
|
-
}
|
117
|
-
|
118
|
-
render() {
|
119
|
-
var oops = !this._showSpinner && (!this._data || !this._data.records || this._data.records.length == 0)
|
120
|
-
|
121
|
-
return html`
|
122
|
-
${oops ? html` <ox-empty-note title="NO RECORDS"></ox-empty-note> ` : html``}
|
123
|
-
|
124
|
-
<div id="wrap">
|
125
|
-
<ox-report-component id="report" .config=${this._config} .data=${this._data}> </ox-report-component>
|
126
|
-
</div>
|
127
|
-
|
128
|
-
<div id="spinner" ?show=${this._showSpinner}></div>
|
129
|
-
`
|
130
|
-
}
|
131
|
-
|
132
|
-
async fetch(reset = true) {
|
133
|
-
if (!this._config) {
|
134
|
-
/* avoid to be here */
|
135
|
-
console.warn('report is not configured yet.')
|
136
|
-
return
|
137
|
-
}
|
138
|
-
|
139
|
-
if (reset) {
|
140
|
-
/*
|
141
|
-
* scroll 의 현재위치에 의해서 scroll 이벤트가 발생할 수 있으므로, 이를 방지하기 위해서 스크롤의 위치를 TOP으로 옮긴다.
|
142
|
-
* (scroll 이 첫페이지 크기 이상으로 내려가 있는 경우, 첫페이지부터 다시 표시하는 경우에, scroll 이벤트가 발생한다.)
|
143
|
-
*/
|
144
|
-
this.report.scrollTop = 0
|
145
|
-
}
|
146
|
-
|
147
|
-
if (this.dataProvider) {
|
148
|
-
await this.dataProvider.attach(reset)
|
149
|
-
}
|
150
|
-
}
|
151
|
-
|
152
|
-
async updated(changes: PropertyValues<this>) {
|
153
|
-
if (changes.has('config')) {
|
154
|
-
this._config = buildConfig({
|
155
|
-
...this.config
|
156
|
-
})
|
157
|
-
|
158
|
-
this.dataProvider && (this.dataProvider.sorters = this._config.sorters)
|
159
|
-
this.fetch()
|
160
|
-
}
|
161
|
-
|
162
|
-
if (changes.has('fetchHandler')) {
|
163
|
-
this.dataProvider && (this.dataProvider.fetchHandler = this.fetchHandler)
|
164
|
-
await this.setPullToRefresh()
|
165
|
-
}
|
166
|
-
|
167
|
-
if (changes.has('fetchOptions')) {
|
168
|
-
this.dataProvider && (this.dataProvider.fetchOptions = this.fetchOptions)
|
169
|
-
}
|
170
|
-
|
171
|
-
if (changes.has('data')) {
|
172
|
-
this.reset()
|
173
|
-
}
|
174
|
-
}
|
175
|
-
|
176
|
-
get dirtyData() {
|
177
|
-
return (this.report as any)?.data || {}
|
178
|
-
}
|
179
|
-
|
180
|
-
showSpinner() {
|
181
|
-
this._showSpinner = true
|
182
|
-
}
|
183
|
-
|
184
|
-
hideSpinner() {
|
185
|
-
this._showSpinner = false
|
186
|
-
}
|
187
|
-
|
188
|
-
focus() {
|
189
|
-
super.focus()
|
190
|
-
|
191
|
-
this.report?.focus()
|
192
|
-
}
|
193
|
-
|
194
|
-
/**
|
195
|
-
* Forced internal data to be reflected on the screen
|
196
|
-
* 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.
|
197
|
-
Therefore, it will be deprecated.
|
198
|
-
* @deprecated
|
199
|
-
* @method
|
200
|
-
*/
|
201
|
-
refresh() {
|
202
|
-
this.requestUpdate()
|
203
|
-
}
|
204
|
-
|
205
|
-
reset() {
|
206
|
-
var {
|
207
|
-
limit = ZERO_PAGINATION.limit,
|
208
|
-
page = ZERO_PAGINATION.page,
|
209
|
-
total = ZERO_PAGINATION.total,
|
210
|
-
records = []
|
211
|
-
} = this.data
|
212
|
-
|
213
|
-
this._data = {
|
214
|
-
limit,
|
215
|
-
page,
|
216
|
-
total,
|
217
|
-
records: this.sortByGroups(records).map((record, idx) => {
|
218
|
-
return {
|
219
|
-
...record,
|
220
|
-
__seq__: (page - 1) * limit + idx + 1
|
221
|
-
}
|
222
|
-
})
|
223
|
-
}
|
224
|
-
}
|
225
|
-
|
226
|
-
sortByGroups(sortedRecords: GristRecord[]) {
|
227
|
-
var { groups, totals } = this._config.rows
|
228
|
-
var { columns } = this._config
|
229
|
-
|
230
|
-
var getColumnIndex = (name: string | number) =>
|
231
|
-
columns.filter(column => !column.hidden).findIndex(column => column.name == name)
|
232
|
-
|
233
|
-
var groupFieldsForTotalRecord: GroupConfig[] = [
|
234
|
-
/* add a group total record to the front. */
|
235
|
-
{
|
236
|
-
column: '*',
|
237
|
-
title: i18next.exists('text.ox-data-report-grand-total')
|
238
|
-
? i18next.t('text.ox-data-report-grand-total')
|
239
|
-
: 'grand total',
|
240
|
-
align: 'right',
|
241
|
-
rowspan: 1
|
242
|
-
},
|
243
|
-
...groups
|
244
|
-
].map(group => {
|
245
|
-
return {
|
246
|
-
...group,
|
247
|
-
titleColumn: buildColumn({
|
248
|
-
record: {
|
249
|
-
align: group.align || 'right'
|
250
|
-
}
|
251
|
-
})
|
252
|
-
}
|
253
|
-
})
|
254
|
-
let lastGroupValues
|
255
|
-
let reportRecords = []
|
256
|
-
let totalicRecords: { [idx: string]: GroupConfig }[] = sortedRecords[0]
|
257
|
-
? (() => {
|
258
|
-
/* 처음 만드는 total records */
|
259
|
-
let record = sortedRecords[0]
|
260
|
-
let totalBase = totals.reduce((base, field) => {
|
261
|
-
base[field] =
|
262
|
-
columns.find(col => col.name == field)?.rowCount && (record[field] === 0 || record[field])
|
263
|
-
? 1
|
264
|
-
: record[field]
|
265
|
-
return base
|
266
|
-
}, {} as { [totalField: string]: number })
|
267
|
-
let groupBase = {} as { [idx: string]: GroupConfig }
|
268
|
-
|
269
|
-
return groupFieldsForTotalRecord.map((group, idx) => {
|
270
|
-
groupBase[group.column] = record[group.column]
|
271
|
-
|
272
|
-
return {
|
273
|
-
...totalBase,
|
274
|
-
...groupBase,
|
275
|
-
[group.column]: record[group.column],
|
276
|
-
'*': {
|
277
|
-
titleColumn: group.titleColumn,
|
278
|
-
value: group.title,
|
279
|
-
groupName: group.column,
|
280
|
-
/* 이 레코드 그룹에 해당하는 첫번째 레코드의 행 번호(1 부터 시작하는 번호임.) - grid layout의 row 지정에 사용됨. */
|
281
|
-
row: 1,
|
282
|
-
rowspan: 1,
|
283
|
-
/* 이 레코드 그룹의 컬럼에 해당하는 열 번호(1 부터 시작하는 번호임.) - grid layout의 column 지정에 사용됨. */
|
284
|
-
column:
|
285
|
-
group.column !== '*'
|
286
|
-
? getColumnIndex(group.column) + 1
|
287
|
-
: getColumnIndex(groups[0].column) + 1 /* grand total 은 첫번째 그룹 컬럼을 사용한다. */,
|
288
|
-
colspan:
|
289
|
-
group.column !== '*' ? groupFieldsForTotalRecord.length - idx : groupFieldsForTotalRecord.length - 1
|
290
|
-
}
|
291
|
-
}
|
292
|
-
})
|
293
|
-
})()
|
294
|
-
: [
|
295
|
-
{
|
296
|
-
'*': {
|
297
|
-
titleColumn: groupFieldsForTotalRecord[0].titleColumn,
|
298
|
-
value: i18next.exists('text.ox-data-report-grand-total')
|
299
|
-
? i18next.t('text.ox-data-report-grand-total')
|
300
|
-
: 'grand total',
|
301
|
-
groupName: '*',
|
302
|
-
row: 1,
|
303
|
-
rowspan: 1,
|
304
|
-
column: 1,
|
305
|
-
colspan: 0
|
306
|
-
} as GroupConfig
|
307
|
-
}
|
308
|
-
]
|
309
|
-
|
310
|
-
var row = 0
|
311
|
-
|
312
|
-
for (let record of sortedRecords) {
|
313
|
-
let groupValues = groups.reduce((base, group) => {
|
314
|
-
base[group.column] = record[group.column]
|
315
|
-
return base
|
316
|
-
}, {} as { [groupColumn: string]: string | number })
|
317
|
-
let isSameGroupRecord = true
|
318
|
-
let totalsStack = [] as { idx: string; record: any }[]
|
319
|
-
let groupBase = {} as { [idx: string]: any }
|
320
|
-
|
321
|
-
row++
|
322
|
-
|
323
|
-
if (lastGroupValues) {
|
324
|
-
for (let idx in groupFieldsForTotalRecord) {
|
325
|
-
let group = groupFieldsForTotalRecord[idx]
|
326
|
-
let totalRecord: {
|
327
|
-
[idx: string]: GroupConfig | number
|
328
|
-
} = totalicRecords[idx]
|
329
|
-
|
330
|
-
groupBase[group.column] = record[group.column]
|
331
|
-
|
332
|
-
if (
|
333
|
-
group.column == '*' ||
|
334
|
-
(isSameGroupRecord && groupValues[group.column] === lastGroupValues[group.column])
|
335
|
-
) {
|
336
|
-
for (let field of totals) {
|
337
|
-
totalRecord[field] +=
|
338
|
-
columns.find(col => col.name == field)?.rowCount && (record[field] === 0 || record[field])
|
339
|
-
? 1
|
340
|
-
: record[field]
|
341
|
-
}
|
342
|
-
|
343
|
-
;(totalRecord['*'] as GroupConfig).rowspan++
|
344
|
-
|
345
|
-
continue
|
346
|
-
}
|
347
|
-
|
348
|
-
/* to avoid from floating point calculation problem */
|
349
|
-
totals.forEach(field => {
|
350
|
-
totalRecord[field] = Math.round((totalRecord[field] as number) * 100) / 100
|
351
|
-
})
|
352
|
-
|
353
|
-
isSameGroupRecord = false
|
354
|
-
|
355
|
-
totalsStack.push({
|
356
|
-
idx,
|
357
|
-
record: totals.reduce(
|
358
|
-
(sum, field) => {
|
359
|
-
sum[field] =
|
360
|
-
columns.find(col => col.name == field)?.rowCount && (record[field] === 0 || record[field])
|
361
|
-
? 1
|
362
|
-
: record[field]
|
363
|
-
return sum
|
364
|
-
},
|
365
|
-
{
|
366
|
-
...groupBase,
|
367
|
-
[group.column]: record[group.column],
|
368
|
-
'*': {
|
369
|
-
titleColumn: group.titleColumn,
|
370
|
-
groupName: group.column,
|
371
|
-
value: group.title,
|
372
|
-
row,
|
373
|
-
rowspan: 1,
|
374
|
-
column: getColumnIndex(group.column) + 1,
|
375
|
-
colspan: totalicRecords[idx]['*'].colspan
|
376
|
-
}
|
377
|
-
}
|
378
|
-
)
|
379
|
-
})
|
380
|
-
}
|
381
|
-
|
382
|
-
totalsStack
|
383
|
-
.reverse()
|
384
|
-
.map(({ record, idx }) => {
|
385
|
-
reportRecords.push(totalicRecords[Number(idx)])
|
386
|
-
totalicRecords[Number(idx)] = {}
|
387
|
-
|
388
|
-
if (record['*'].value) {
|
389
|
-
totalicRecords.forEach(record => record['*'] && record['*'].rowspan++)
|
390
|
-
row++
|
391
|
-
}
|
392
|
-
|
393
|
-
return { record, idx }
|
394
|
-
})
|
395
|
-
.forEach(({ record, idx }) => {
|
396
|
-
record['*'].row = row
|
397
|
-
totalicRecords[Number(idx)] = record
|
398
|
-
})
|
399
|
-
}
|
400
|
-
|
401
|
-
reportRecords.push(record)
|
402
|
-
|
403
|
-
lastGroupValues = groupValues
|
404
|
-
}
|
405
|
-
|
406
|
-
/* 마지막 남은 토탈 레코드들을 추가한다. */
|
407
|
-
var poped: any
|
408
|
-
while ((poped = totalicRecords.pop())) {
|
409
|
-
/* to avoid from floating point calculation problem */
|
410
|
-
totals.forEach(field => {
|
411
|
-
poped[field] = Math.round(poped[field] * 100) / 100
|
412
|
-
})
|
413
|
-
|
414
|
-
reportRecords.push(poped)
|
415
|
-
if (poped['*'].value) {
|
416
|
-
totalicRecords.forEach(record => record['*'].rowspan++)
|
417
|
-
}
|
418
|
-
}
|
419
|
-
|
420
|
-
return reportRecords
|
421
|
-
}
|
422
|
-
|
423
|
-
checkDirties() {}
|
424
|
-
}
|
package/src/editors/index.ts
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
import { OxGristEditor } from './ox-grist-editor.js'
|
2
|
-
import { customElement } from 'lit/decorators.js'
|
3
|
-
import { html } from 'lit'
|
4
|
-
|
5
|
-
@customElement('ox-grist-editor-checkbox')
|
6
|
-
export class OxGristEditorCheckbox extends OxGristEditor {
|
7
|
-
_onchange(e: Event) {
|
8
|
-
e.stopPropagation()
|
9
|
-
|
10
|
-
const input = e.target as HTMLInputElement
|
11
|
-
|
12
|
-
this._dirtyValue = this.formatFromEditor(input.checked)
|
13
|
-
}
|
14
|
-
|
15
|
-
formatFromEditor(value: any) {
|
16
|
-
if (typeof value == 'boolean') {
|
17
|
-
return value
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
formatForEditor(value: any): any {
|
22
|
-
return value == !!value && !!String(value).match(/true/i)
|
23
|
-
}
|
24
|
-
|
25
|
-
get editorTemplate() {
|
26
|
-
return html` <input type="checkbox" .checked=${!!this.value && !!String(this.value).match(/true/i)} /> `
|
27
|
-
}
|
28
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { OxGristEditor } from './ox-grist-editor.js'
|
2
|
-
import { customElement } from 'lit/decorators.js'
|
3
|
-
import { html } from 'lit'
|
4
|
-
|
5
|
-
@customElement('ox-grist-editor-color')
|
6
|
-
export class OxGristEditorColor extends OxGristEditor {
|
7
|
-
get editorTemplate() {
|
8
|
-
return html` <input type="color" .value=${this.value} /> `
|
9
|
-
}
|
10
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { OxGristEditor } from './ox-grist-editor.js'
|
2
|
-
import { customElement } from 'lit/decorators.js'
|
3
|
-
import { html } from 'lit'
|
4
|
-
|
5
|
-
@customElement('ox-grist-editor-date')
|
6
|
-
export class OxGristEditorDate extends OxGristEditor {
|
7
|
-
get editorTemplate() {
|
8
|
-
return html` <input type="date" .value=${this.value} max="9999-12-31" /> `
|
9
|
-
}
|
10
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { OxGristEditor } from './ox-grist-editor.js'
|
2
|
-
import { customElement } from 'lit/decorators.js'
|
3
|
-
import { html } from 'lit'
|
4
|
-
|
5
|
-
@customElement('ox-grist-editor-datetime')
|
6
|
-
export class OxGristEditorDateTime extends OxGristEditor {
|
7
|
-
formatForEditor(timestamp: any) {
|
8
|
-
if (!timestamp) {
|
9
|
-
timestamp = Date.now()
|
10
|
-
}
|
11
|
-
var datetime = new Date(timestamp)
|
12
|
-
|
13
|
-
var tzoffset = datetime.getTimezoneOffset() * 60000 //offset in milliseconds
|
14
|
-
|
15
|
-
return new Date(timestamp - tzoffset).toISOString().slice(0, -1)
|
16
|
-
}
|
17
|
-
|
18
|
-
formatFromEditor(value: any) {
|
19
|
-
var datetime = new Date(value)
|
20
|
-
|
21
|
-
return datetime.getTime()
|
22
|
-
}
|
23
|
-
|
24
|
-
get editorTemplate() {
|
25
|
-
return html` <input type="datetime-local" .value=${this.value} max="9999-12-31T23:59" /> `
|
26
|
-
}
|
27
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { OxGristEditor } from './ox-grist-editor.js'
|
2
|
-
import { customElement } from 'lit/decorators.js'
|
3
|
-
import { html } from 'lit'
|
4
|
-
|
5
|
-
@customElement('ox-grist-editor-email')
|
6
|
-
export class OxGristEditorEmail extends OxGristEditor {
|
7
|
-
get editorTemplate() {
|
8
|
-
return html` <input type="email" .value=${this.value} /> `
|
9
|
-
}
|
10
|
-
}
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import { html } from 'lit'
|
2
|
-
import { customElement } from 'lit/decorators.js'
|
3
|
-
|
4
|
-
import { OxGristEditor } from './ox-grist-editor.js'
|
5
|
-
|
6
|
-
@customElement('ox-grist-editor-file')
|
7
|
-
export class OxGristEditorFile extends OxGristEditor {
|
8
|
-
_onchange(e: Event) {
|
9
|
-
e.stopPropagation()
|
10
|
-
|
11
|
-
const input = e.target as HTMLInputElement
|
12
|
-
|
13
|
-
this._dirtyValue = this.formatFromEditor(input.files)
|
14
|
-
|
15
|
-
this._onfocusout()
|
16
|
-
}
|
17
|
-
|
18
|
-
formatFromEditor(value: any): any {
|
19
|
-
return value
|
20
|
-
}
|
21
|
-
|
22
|
-
get editorTemplate() {
|
23
|
-
var value = typeof this.value === 'string' ? null : this.value
|
24
|
-
var { multiple = false } = this.column.record || {}
|
25
|
-
|
26
|
-
return html` <input style="opacity: 1" type="file" ?multiple=${multiple} /> `
|
27
|
-
}
|
28
|
-
}
|