@operato/data-grist 8.0.0-alpha.3 → 8.0.0-alpha.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 +111 -0
- package/dist/src/data-card/record-card.js +10 -1
- package/dist/src/data-card/record-card.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.js +15 -6
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-footer.js +2 -0
- package/dist/src/data-grid/data-grid-footer.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.d.ts +1 -1
- package/dist/src/data-grid/data-grid-header.js +13 -9
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grist.d.ts +16 -1
- package/dist/src/data-grist.js +53 -20
- package/dist/src/data-grist.js.map +1 -1
- package/dist/src/data-list/record-partial.js +10 -1
- package/dist/src/data-list/record-partial.js.map +1 -1
- package/dist/src/editors/ox-grist-editor-file.js +2 -1
- package/dist/src/editors/ox-grist-editor-file.js.map +1 -1
- package/dist/src/editors/ox-grist-editor.js +3 -3
- package/dist/src/editors/ox-grist-editor.js.map +1 -1
- package/dist/src/record-view/record-creator.d.ts +5 -0
- package/dist/src/record-view/record-creator.js +47 -4
- package/dist/src/record-view/record-creator.js.map +1 -1
- package/dist/src/record-view/record-view-body.d.ts +6 -1
- package/dist/src/record-view/record-view-body.js +43 -5
- package/dist/src/record-view/record-view-body.js.map +1 -1
- package/dist/src/record-view/record-view.d.ts +7 -1
- package/dist/src/record-view/record-view.js +7 -1
- package/dist/src/record-view/record-view.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-boolean.js +1 -1
- package/dist/src/renderers/ox-grist-renderer-boolean.js.map +1 -1
- package/dist/src/renderers/ox-grist-renderer-file.js +17 -5
- package/dist/src/renderers/ox-grist-renderer-file.js.map +1 -1
- package/dist/src/types.d.ts +6 -0
- package/dist/src/types.js +7 -0
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/data-card/record-card.ts +10 -1
- package/src/data-grid/data-grid-body.ts +18 -6
- package/src/data-grid/data-grid-footer.ts +2 -0
- package/src/data-grid/data-grid-header.ts +13 -9
- package/src/data-grist.ts +60 -24
- package/src/data-list/record-partial.ts +10 -1
- package/src/editors/ox-grist-editor-file.ts +3 -1
- package/src/editors/ox-grist-editor.ts +3 -3
- package/src/record-view/record-creator.ts +50 -4
- package/src/record-view/record-view-body.ts +49 -5
- package/src/record-view/record-view.ts +10 -2
- package/src/renderers/ox-grist-renderer-boolean.ts +1 -1
- package/src/renderers/ox-grist-renderer-file.ts +20 -6
- package/src/types.ts +8 -0
- package/themes/calendar-theme.css +3 -1
- package/translations/en.json +5 -1
- package/translations/ja.json +5 -1
- package/translations/ko.json +5 -1
- package/translations/ms.json +5 -1
- package/translations/zh.json +5 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"record-partial.js","sourceRoot":"","sources":["../../../src/data-list/record-partial.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport './data-list-gutter'\nimport './data-list-field'\nimport '../record-view'\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ZERO_CONFIG, ZERO_DATA, ZERO_RECORD } from '../configure/zero-config'\nimport { RecordViewHandler } from '../record-view/record-view-handler'\nimport { GristConfig, GristData, GristRecord } from '../types'\nimport { recordPartialClickHandler } from './event-handlers/record-partial-click-handler'\nimport { recordPartialDblClickHandler } from './event-handlers/record-partial-dblclick-handler'\n\n// import { recordPartialLongPressHandler } from './event-handlers/record-partial-long-press-handler'\n\n// TODO 로케일 설정에 따라서 포맷이 바뀌도록 해야한다.\nconst OPTIONS: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n hour12: false\n // timeZone: 'America/Los_Angeles'\n}\n\nconst formatter = new Intl.DateTimeFormat(navigator.language, OPTIONS)\n\n@customElement('ox-record-partial')\nexport class RecordPartial extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: var(--data-list-item-border-bottom);\n position: relative;\n min-height: 42px;\n padding-left: var(--spacing-medium);\n }\n\n :host([dirty])::before {\n content: '';\n position: absolute;\n left: var(--spacing-none);\n top: var(--spacing-none);\n\n width: var(--spacing-none);\n height: var(--spacing-none);\n border-top: var(--grid-record-dirty-border-top);\n border-right: var(--grid-record-dirty-border-left);\n }\n\n :host[emphasized-row] {\n background-color: var(--grid-record-emphasized-background-color);\n color: var(--grid-record-emphasized-color);\n }\n\n :host [dirty] {\n position: absolute;\n margin: var(--spacing-none);\n height: 20px;\n font: var(--grid-record-dirty-icon-font);\n text-indent: 1px;\n left: var(--spacing-none);\n top: var(--spacing-none);\n color: var(--grid-record-dirty-color, var(--md-sys-color-error));\n }\n\n [content] {\n flex: auto;\n display: block;\n zoom: 1;\n }\n\n div[tail] {\n margin: var(--spacing-none);\n width: 100px;\n aspect-ratio: 1 / 1;\n\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n }\n\n div[tail] > ox-list-field {\n flex: 1;\n }\n\n ox-list-field {\n font: var(--data-list-item-etc-font);\n color: var(--data-list-item-etc-color, var(--md-sys-color-on-surface));\n }\n\n ox-list-field[name] {\n font: var(--data-list-item-name-font);\n color: var(--data-list-item-name-color, var(--md-sys-color-secondary));\n }\n\n ox-list-field[desc] {\n font: var(--data-list-item-disc-font);\n color: var(--data-list-item-disc-color, var(--md-sys-color-on-tertiary-container));\n }\n `\n ]\n\n @property({ type: Object }) config: GristConfig = ZERO_CONFIG\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: Object }) record: GristRecord = ZERO_RECORD\n @property({ type: Number }) rowIndex: number = -1\n /*\n * row-selector를 사용자가 변경할 때, record-partial의 update를 유도하기 위해 selected-row attribute를 property에 추가함.\n * (이를 해주지 않으면, 리스트 refresh 경우에 selected-row checkbox가 클리어되지 않는 현상이 발생함.)\n */\n @property({ type: Boolean, attribute: 'selected-row' }) selectedRow: boolean = false\n @property({ attribute: false }) emphasized: any = false\n\n private _recordView: any\n\n attributeChangedCallback(name: string, oldval: any, newval: any) {\n super.attributeChangedCallback(name, oldval, newval)\n }\n\n firstUpdated() {\n /*\n long-press\n TODO. performance를 확인한 후에 활성화하자.\n */\n // longpressable(this.renderRoot.querySelector('[content]'))\n\n // this.renderRoot.addEventListener('long-press', recordPartialLongPressHandler.bind(this))\n this.renderRoot.addEventListener('click', recordPartialClickHandler.bind(this) as EventListener)\n this.renderRoot.addEventListener('dblclick', recordPartialDblClickHandler.bind(this) as EventListener)\n\n this.addEventListener('show-record-view', () => this.popupRecordView())\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('record') && this._recordView) {\n this._recordView.record = this.record\n }\n\n const emphasized = this.emphasized\n\n if (!!emphasized) {\n this.setAttribute('emphasized-row', '')\n\n if (Symbol.iterator in Object(emphasized)) {\n const [backgroundColor, foregroundColor] = emphasized as string[]\n backgroundColor && this.style.setProperty('--grid-record-emphasized-background-color', backgroundColor)\n foregroundColor && this.style.setProperty('--grid-record-emphasized-color', foregroundColor)\n }\n } else {\n this.removeAttribute('emphasized-row')\n }\n }\n\n render() {\n var record = this.record\n var rowIndex = this.rowIndex\n var { columns, list } = this.config\n var { thumbnail, fields, details } = list || {}\n\n var displayColumns =\n [...fields, ...details].map(field => columns.find(column => column.name == field)).filter(column => column) || []\n var gutters = (columns || []).filter(column => column.type == 'gutter' && column.forList)\n\n const thumbnailColumn = thumbnail ? columns.find(column => column.name == thumbnail) : undefined\n\n if (this.hasAttribute('dirty')) {\n var dirtyIcon\n\n switch (this.record['__dirty__']) {\n case 'M':\n dirtyIcon = 'done'\n break\n case '+':\n dirtyIcon = 'add'\n break\n case '-':\n dirtyIcon = 'remove'\n break\n }\n }\n\n return html`\n ${dirtyIcon ? html` <md-icon dirty>${dirtyIcon}</md-icon> ` : html``}\n ${gutters.map(\n gutter => html`\n <ox-list-gutter\n class=${gutter.name === 'detail' ? 'expand' : ''}\n .rowIndex=${rowIndex}\n .column=${gutter}\n .record=${record}\n .value=${record[gutter.name]}\n ></ox-list-gutter>\n `\n )}\n\n <div content>\n ${displayColumns.map(\n (column, idx) => html`\n <ox-list-field\n .rowIndex=${rowIndex}\n .column=${column}\n .record=${record}\n .value=${record[column?.name || '']}\n ?name=${idx == 0}\n ?desc=${idx == 1}\n ></ox-list-field>\n `\n )}\n </div>\n ${thumbnail\n ? html`<div tail>\n <ox-list-field\n thumbnail\n .rowIndex=${rowIndex}\n .column=${thumbnailColumn}\n .record=${record}\n .value=${record[thumbnailColumn?.name || '']}\n ></ox-list-field>\n </div>`\n : html``}\n `\n }\n\n popupRecordView() {\n var titleField = this.config.list.fields[0] || 'name'\n var title = this.record[titleField]\n\n /* field가 오브젝트형인 경우에는 렌더러를 타이틀로 사용한다. */\n if (typeof title == 'object') {\n var column = this.config.columns.find(column => column.name == titleField)\n title = column?.record.renderer(title, column, this.record, this.rowIndex, this /* cautious */)\n }\n\n this._recordView = RecordViewHandler(\n this.config.columns,\n this.record,\n this.rowIndex,\n this,\n {\n title\n },\n () => {\n delete this._recordView\n }\n )\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"record-partial.js","sourceRoot":"","sources":["../../../src/data-list/record-partial.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport './data-list-gutter'\nimport './data-list-field'\nimport '../record-view'\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ZERO_CONFIG, ZERO_DATA, ZERO_RECORD } from '../configure/zero-config'\nimport { RecordViewHandler } from '../record-view/record-view-handler'\nimport { GristConfig, GristData, GristRecord } from '../types'\nimport { recordPartialClickHandler } from './event-handlers/record-partial-click-handler'\nimport { recordPartialDblClickHandler } from './event-handlers/record-partial-dblclick-handler'\n\n// import { recordPartialLongPressHandler } from './event-handlers/record-partial-long-press-handler'\n\n// TODO 로케일 설정에 따라서 포맷이 바뀌도록 해야한다.\nconst OPTIONS: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n hour12: false\n // timeZone: 'America/Los_Angeles'\n}\n\nfunction getSafeFormatter(locale: string, options: Intl.DateTimeFormatOptions) {\n try {\n const safeLocale = locale || 'en-US'\n return new Intl.DateTimeFormat(safeLocale, options)\n } catch (e) {\n return new Intl.DateTimeFormat('en-US', options)\n }\n}\n\nconst formatter = getSafeFormatter(navigator.language, OPTIONS)\n\n@customElement('ox-record-partial')\nexport class RecordPartial extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: var(--data-list-item-border-bottom);\n position: relative;\n min-height: 42px;\n padding-left: var(--spacing-medium);\n }\n\n :host([dirty])::before {\n content: '';\n position: absolute;\n left: var(--spacing-none);\n top: var(--spacing-none);\n\n width: var(--spacing-none);\n height: var(--spacing-none);\n border-top: var(--grid-record-dirty-border-top);\n border-right: var(--grid-record-dirty-border-left);\n }\n\n :host[emphasized-row] {\n background-color: var(--grid-record-emphasized-background-color);\n color: var(--grid-record-emphasized-color);\n }\n\n :host [dirty] {\n position: absolute;\n margin: var(--spacing-none);\n height: 20px;\n font: var(--grid-record-dirty-icon-font);\n text-indent: 1px;\n left: var(--spacing-none);\n top: var(--spacing-none);\n color: var(--grid-record-dirty-color, var(--md-sys-color-error));\n }\n\n [content] {\n flex: auto;\n display: block;\n zoom: 1;\n }\n\n div[tail] {\n margin: var(--spacing-none);\n width: 100px;\n aspect-ratio: 1 / 1;\n\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n }\n\n div[tail] > ox-list-field {\n flex: 1;\n }\n\n ox-list-field {\n font: var(--data-list-item-etc-font);\n color: var(--data-list-item-etc-color, var(--md-sys-color-on-surface));\n }\n\n ox-list-field[name] {\n font: var(--data-list-item-name-font);\n color: var(--data-list-item-name-color, var(--md-sys-color-secondary));\n }\n\n ox-list-field[desc] {\n font: var(--data-list-item-disc-font);\n color: var(--data-list-item-disc-color, var(--md-sys-color-on-tertiary-container));\n }\n `\n ]\n\n @property({ type: Object }) config: GristConfig = ZERO_CONFIG\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: Object }) record: GristRecord = ZERO_RECORD\n @property({ type: Number }) rowIndex: number = -1\n /*\n * row-selector를 사용자가 변경할 때, record-partial의 update를 유도하기 위해 selected-row attribute를 property에 추가함.\n * (이를 해주지 않으면, 리스트 refresh 경우에 selected-row checkbox가 클리어되지 않는 현상이 발생함.)\n */\n @property({ type: Boolean, attribute: 'selected-row' }) selectedRow: boolean = false\n @property({ attribute: false }) emphasized: any = false\n\n private _recordView: any\n\n attributeChangedCallback(name: string, oldval: any, newval: any) {\n super.attributeChangedCallback(name, oldval, newval)\n }\n\n firstUpdated() {\n /*\n long-press\n TODO. performance를 확인한 후에 활성화하자.\n */\n // longpressable(this.renderRoot.querySelector('[content]'))\n\n // this.renderRoot.addEventListener('long-press', recordPartialLongPressHandler.bind(this))\n this.renderRoot.addEventListener('click', recordPartialClickHandler.bind(this) as EventListener)\n this.renderRoot.addEventListener('dblclick', recordPartialDblClickHandler.bind(this) as EventListener)\n\n this.addEventListener('show-record-view', () => this.popupRecordView())\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('record') && this._recordView) {\n this._recordView.record = this.record\n }\n\n const emphasized = this.emphasized\n\n if (!!emphasized) {\n this.setAttribute('emphasized-row', '')\n\n if (Symbol.iterator in Object(emphasized)) {\n const [backgroundColor, foregroundColor] = emphasized as string[]\n backgroundColor && this.style.setProperty('--grid-record-emphasized-background-color', backgroundColor)\n foregroundColor && this.style.setProperty('--grid-record-emphasized-color', foregroundColor)\n }\n } else {\n this.removeAttribute('emphasized-row')\n }\n }\n\n render() {\n var record = this.record\n var rowIndex = this.rowIndex\n var { columns, list } = this.config\n var { thumbnail, fields, details } = list || {}\n\n var displayColumns =\n [...fields, ...details].map(field => columns.find(column => column.name == field)).filter(column => column) || []\n var gutters = (columns || []).filter(column => column.type == 'gutter' && column.forList)\n\n const thumbnailColumn = thumbnail ? columns.find(column => column.name == thumbnail) : undefined\n\n if (this.hasAttribute('dirty')) {\n var dirtyIcon\n\n switch (this.record['__dirty__']) {\n case 'M':\n dirtyIcon = 'done'\n break\n case '+':\n dirtyIcon = 'add'\n break\n case '-':\n dirtyIcon = 'remove'\n break\n }\n }\n\n return html`\n ${dirtyIcon ? html` <md-icon dirty>${dirtyIcon}</md-icon> ` : html``}\n ${gutters.map(\n gutter => html`\n <ox-list-gutter\n class=${gutter.name === 'detail' ? 'expand' : ''}\n .rowIndex=${rowIndex}\n .column=${gutter}\n .record=${record}\n .value=${record[gutter.name]}\n ></ox-list-gutter>\n `\n )}\n\n <div content>\n ${displayColumns.map(\n (column, idx) => html`\n <ox-list-field\n .rowIndex=${rowIndex}\n .column=${column}\n .record=${record}\n .value=${record[column?.name || '']}\n ?name=${idx == 0}\n ?desc=${idx == 1}\n ></ox-list-field>\n `\n )}\n </div>\n ${thumbnail\n ? html`<div tail>\n <ox-list-field\n thumbnail\n .rowIndex=${rowIndex}\n .column=${thumbnailColumn}\n .record=${record}\n .value=${record[thumbnailColumn?.name || '']}\n ></ox-list-field>\n </div>`\n : html``}\n `\n }\n\n popupRecordView() {\n var titleField = this.config.list.fields[0] || 'name'\n var title = this.record[titleField]\n\n /* field가 오브젝트형인 경우에는 렌더러를 타이틀로 사용한다. */\n if (typeof title == 'object') {\n var column = this.config.columns.find(column => column.name == titleField)\n title = column?.record.renderer(title, column, this.record, this.rowIndex, this /* cautious */)\n }\n\n this._recordView = RecordViewHandler(\n this.config.columns,\n this.record,\n this.rowIndex,\n this,\n {\n title\n },\n () => {\n delete this._recordView\n }\n )\n }\n}\n"]}
|
@@ -14,7 +14,8 @@ let OxGristEditorFile = class OxGristEditorFile extends OxGristEditor {
|
|
14
14
|
}
|
15
15
|
get editorTemplate() {
|
16
16
|
var value = typeof this.value === 'string' ? null : this.value;
|
17
|
-
|
17
|
+
var { multiple = false } = this.column.record || {};
|
18
|
+
return html ` <input style="opacity: 1" type="file" ?multiple=${multiple} /> `;
|
18
19
|
}
|
19
20
|
};
|
20
21
|
OxGristEditorFile = __decorate([
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ox-grist-editor-file.js","sourceRoot":"","sources":["../../../src/editors/ox-grist-editor-file.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAG7C,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,aAAa;IAClD,SAAS,CAAC,CAAQ;QAChB,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,MAAM,KAAK,GAAG,CAAC,CAAC,MAA0B,CAAA;QAE1C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAErD,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC;IAED,gBAAgB,CAAC,KAAU;QACzB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,cAAc;QAChB,IAAI,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAA;QAC9D,OAAO,IAAI,CAAA,
|
1
|
+
{"version":3,"file":"ox-grist-editor-file.js","sourceRoot":"","sources":["../../../src/editors/ox-grist-editor-file.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAG7C,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,aAAa;IAClD,SAAS,CAAC,CAAQ;QAChB,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,MAAM,KAAK,GAAG,CAAC,CAAC,MAA0B,CAAA;QAE1C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAErD,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC;IAED,gBAAgB,CAAC,KAAU;QACzB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,cAAc;QAChB,IAAI,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAA;QAC9D,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;QAEnD,OAAO,IAAI,CAAA,oDAAoD,QAAQ,MAAM,CAAA;IAC/E,CAAC;CACF,CAAA;AArBY,iBAAiB;IAD7B,aAAa,CAAC,sBAAsB,CAAC;GACzB,iBAAiB,CAqB7B","sourcesContent":["import { html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { OxGristEditor } from './ox-grist-editor.js'\n\n@customElement('ox-grist-editor-file')\nexport class OxGristEditorFile extends OxGristEditor {\n _onchange(e: Event) {\n e.stopPropagation()\n\n const input = e.target as HTMLInputElement\n\n this._dirtyValue = this.formatFromEditor(input.files)\n\n this._onfocusout()\n }\n\n formatFromEditor(value: any): any {\n return value\n }\n\n get editorTemplate() {\n var value = typeof this.value === 'string' ? null : this.value\n var { multiple = false } = this.column.record || {}\n\n return html` <input style=\"opacity: 1\" type=\"file\" ?multiple=${multiple} /> `\n }\n}\n"]}
|
@@ -93,9 +93,9 @@ let OxGristEditor = class OxGristEditor extends LitElement {
|
|
93
93
|
this.addEventListener('dblclick', this._ondblclick.bind(this));
|
94
94
|
this.addEventListener('keydown', this._onkeydown.bind(this));
|
95
95
|
/* editor mode 인 경우의 마우스 움직임이, grist-body의 이벤트 처리에 의해서 에디터를 리셋시킬 수 있으므로, 이벤트 전파를 막는다. */
|
96
|
-
this.addEventListener('
|
97
|
-
this.addEventListener('
|
98
|
-
this.addEventListener('
|
96
|
+
this.addEventListener('pointerdown', (e) => e.stopPropagation());
|
97
|
+
this.addEventListener('pointermove', (e) => e.stopPropagation());
|
98
|
+
this.addEventListener('pointerup', (e) => e.stopPropagation());
|
99
99
|
const { name = '' } = this.column;
|
100
100
|
const { align, defaultValue } = this.column.record;
|
101
101
|
if (align) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ox-grist-editor.js","sourceRoot":"","sources":["../../../src/editors/ox-grist-editor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkEhB,CAAA;AAGM,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,UAAU;IAAtC;;QAIuB,WAAM,GAAiB,WAAW,CAAA;QAClC,WAAM,GAAgB,WAAW,CAAA;IA4H/D,CAAC;IArHC,MAAM;QACJ,OAAO,IAAI,CAAC,cAAc,CAAA;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,UAAU,CAAC,iBAAgC,CAAA;IACzD,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,CAAC,YAAY;;QAChB,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACrE,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACzE,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACxD,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAE5D,wFAAwF;QACxF,IAAI,CAAC,gBAAgB,CAAC,
|
1
|
+
{"version":3,"file":"ox-grist-editor.js","sourceRoot":"","sources":["../../../src/editors/ox-grist-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ZERO_COLUMN, ZERO_RECORD } from '../configure/zero-config'\nimport { DataGridField } from '../data-grid/data-grid-field'\nimport { ColumnConfig, GristRecord } from '../types'\nimport { getDefaultValue } from '@operato/time-calculator'\n\nconst STYLE = css`\n :host {\n display: flex;\n\n align-items: center;\n\n width: 100%;\n height: 100%;\n\n border: 0;\n background-color: transparent;\n\n overflow: hidden;\n justify-content: var(--data-grid-field-justify-content, flex-start);\n }\n\n :host > * {\n display: flex;\n\n width: 100%;\n height: 100%;\n\n border: 0;\n background-color: transparent;\n\n box-sizing: border-box;\n\n align-items: center;\n }\n\n :host > style {\n display: none;\n }\n\n :host > input {\n color: var(--md-sys-color-on-background);\n }\n\n :host > input[type='checkbox'] {\n width: initial;\n margin: 0;\n }\n *:focus {\n outline: none;\n }\n\n input[type='file'] {\n opacity: 0%;\n }\n\n @media screen and (max-width: 460px) {\n :host > * {\n border: initial;\n background-color: initial;\n }\n\n *:focus {\n outline: none;\n }\n\n input,\n select,\n textarea {\n font-size: 16px;\n }\n }\n`\n\n@customElement('ox-grist-editor')\nexport class OxGristEditor extends LitElement {\n static styles = [STYLE]\n\n @property({ type: Object }) value?: any\n @property({ type: Object }) column: ColumnConfig = ZERO_COLUMN\n @property({ type: Object }) record: GristRecord = ZERO_RECORD\n @property({ type: Number }) rowIndex?: number\n @property({ type: Object }) field?: DataGridField\n @property({ type: Number }) row?: number\n\n protected _dirtyValue?: any\n\n render() {\n return this.editorTemplate\n }\n\n get editor(): HTMLElement | null {\n return this.renderRoot.firstElementChild as HTMLElement\n }\n\n get inlineEditable() {\n return false\n }\n\n async firstUpdated() {\n this.renderRoot.addEventListener('change', this._onchange.bind(this))\n this.renderRoot.addEventListener('focusout', this._onfocusout.bind(this))\n this.addEventListener('click', this._onclick.bind(this))\n this.addEventListener('dblclick', this._ondblclick.bind(this))\n this.addEventListener('keydown', this._onkeydown.bind(this))\n\n /* editor mode 인 경우의 마우스 움직임이, grist-body의 이벤트 처리에 의해서 에디터를 리셋시킬 수 있으므로, 이벤트 전파를 막는다. */\n this.addEventListener('pointerdown', (e: Event) => e.stopPropagation())\n this.addEventListener('pointermove', (e: Event) => e.stopPropagation())\n this.addEventListener('pointerup', (e: Event) => e.stopPropagation())\n\n const { name = '' } = this.column\n const { align, defaultValue } = this.column.record\n\n if (align) {\n this.style.textAlign = align\n this.style.textAlignLast = align /* for select */\n }\n\n var currentValue = this.record[name]\n\n if (typeof currentValue == 'undefined' && defaultValue) {\n currentValue = getDefaultValue(defaultValue, this.record)\n }\n\n this.value = this._dirtyValue = this.formatForEditor(currentValue)\n\n // 입력을 위한 키를 누르면서 편집모드가 될때는 누른 키가 처음에 입력되도록, enter 같은 것을 눌러서 편집모드가 되면 현재 값으로 편집모드 전환\n const valueWith = this.inlineEditable && this.field?.valueWith\n this.value = this._dirtyValue = valueWith ? this.formatFromEditor(valueWith) : this.formatForEditor(currentValue)\n\n requestAnimationFrame(() => {\n this.focus()\n !valueWith && this.select()\n })\n }\n\n select() {\n const editor = this.editor\n if ((editor as HTMLInputElement)?.select) {\n return (editor as HTMLInputElement).select()\n }\n }\n\n focus() {\n const editor = this.editor\n if (editor) {\n editor.focus()\n }\n }\n\n formatForEditor(value: any): any {\n return value == null ? '' : value\n }\n\n formatFromEditor(value: any): any {\n return value\n }\n\n _onfocusout() {\n // paste시 field-change는 Body에서 하므로 X\n if (this.field?.isWorking === true) return\n\n const { name = '' } = this.column\n var currentValue = this.record[name] || ''\n\n if (this._dirtyValue !== currentValue) {\n this.dispatchEvent(\n new CustomEvent('field-change', {\n bubbles: true,\n composed: true,\n detail: {\n before: currentValue,\n after: this._dirtyValue,\n column: this.column,\n record: this.record,\n row: this.row\n }\n })\n )\n }\n }\n\n _onchange(e: Event): void {\n e.stopPropagation()\n\n const value = (e.target as any)?.value\n\n this._dirtyValue = this.formatFromEditor(value)\n }\n\n _onkeydown(e: Event): void {}\n\n _onclick(e: Event): void {\n e.stopPropagation()\n }\n\n _ondblclick(e: Event): void {\n e.stopPropagation()\n }\n\n get editorTemplate() {\n return html``\n }\n}\n"]}
|
@@ -2,6 +2,7 @@ import '@material/web/icon/icon.js';
|
|
2
2
|
import './record-view';
|
3
3
|
import { LitElement } from 'lit';
|
4
4
|
import { DataGrist } from '../data-grist';
|
5
|
+
import { GristRecord, ValidationReason } from '../types';
|
5
6
|
export declare class RecordCreator extends LitElement {
|
6
7
|
grist?: DataGrist;
|
7
8
|
callback?: (operation: {
|
@@ -12,6 +13,10 @@ export declare class RecordCreator extends LitElement {
|
|
12
13
|
constructor();
|
13
14
|
connectedCallback(): void;
|
14
15
|
render(): import("lit-html").TemplateResult<1>;
|
16
|
+
validateRecord(record: GristRecord): {
|
17
|
+
field: string;
|
18
|
+
reason: ValidationReason;
|
19
|
+
}[];
|
15
20
|
lightPopupRecordView(): void;
|
16
21
|
popupRecordView(): void;
|
17
22
|
}
|
@@ -4,6 +4,7 @@ import './record-view';
|
|
4
4
|
import { html, LitElement } from 'lit';
|
5
5
|
import { customElement, property, state } from 'lit/decorators.js';
|
6
6
|
import { OxPopup } from '@operato/popup';
|
7
|
+
import { ValidationReason } from '../types';
|
7
8
|
let RecordCreator = class RecordCreator extends LitElement {
|
8
9
|
constructor() {
|
9
10
|
super();
|
@@ -27,6 +28,21 @@ let RecordCreator = class RecordCreator extends LitElement {
|
|
27
28
|
render() {
|
28
29
|
return html `<slot></slot>`;
|
29
30
|
}
|
31
|
+
validateRecord(record) {
|
32
|
+
const columns = this.grist.compiledConfig.columns;
|
33
|
+
const invalidFields = [];
|
34
|
+
columns.forEach(column => {
|
35
|
+
var _a;
|
36
|
+
if (((_a = column.record) === null || _a === void 0 ? void 0 : _a.mandatory) && (record[column.name] === undefined || record[column.name] === null || record[column.name] === '')) {
|
37
|
+
invalidFields.push({
|
38
|
+
field: column.name,
|
39
|
+
reason: ValidationReason.MANDATORY
|
40
|
+
});
|
41
|
+
}
|
42
|
+
// 여기에 추가적인 유효성 검사 규칙을 구현할 수 있습니다.
|
43
|
+
});
|
44
|
+
return invalidFields;
|
45
|
+
}
|
30
46
|
lightPopupRecordView() {
|
31
47
|
const config = this.grist.compiledConfig;
|
32
48
|
var title = 'create';
|
@@ -61,9 +77,19 @@ let RecordCreator = class RecordCreator extends LitElement {
|
|
61
77
|
@cancel=${(e) => {
|
62
78
|
popup.close();
|
63
79
|
}}
|
64
|
-
@ok=${(e) => {
|
65
|
-
popup.close();
|
80
|
+
@ok=${async (e) => {
|
66
81
|
const view = e.currentTarget;
|
82
|
+
// 레코드 밸리데이션 체크
|
83
|
+
const invalidFields = await this.validateRecord(view.record);
|
84
|
+
if (invalidFields.length > 0) {
|
85
|
+
// const firstInvalidField = invalidFields[0];
|
86
|
+
// if (firstInvalidField) {
|
87
|
+
// view.setFocus(firstInvalidField.field)
|
88
|
+
// }
|
89
|
+
view.setFocusOnInvalid(invalidFields);
|
90
|
+
return false;
|
91
|
+
}
|
92
|
+
popup.close();
|
67
93
|
this.dispatchEvent(new CustomEvent('ok', {
|
68
94
|
bubbles: true,
|
69
95
|
composed: true,
|
@@ -103,11 +129,28 @@ let RecordCreator = class RecordCreator extends LitElement {
|
|
103
129
|
popup.close();
|
104
130
|
});
|
105
131
|
recordView.addEventListener('ok', async (e) => {
|
106
|
-
var _a;
|
132
|
+
var _a, _b;
|
107
133
|
const view = e.currentTarget;
|
108
|
-
|
134
|
+
// 레코드 밸리데이션 체크
|
135
|
+
const invalidFields = await this.validateRecord(view.record);
|
136
|
+
if (invalidFields.length > 0) {
|
137
|
+
const firstInvalidField = invalidFields[0];
|
138
|
+
if (firstInvalidField) {
|
139
|
+
const fieldElement = (_a = view.renderRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[name="${firstInvalidField}"]`);
|
140
|
+
if (fieldElement) {
|
141
|
+
fieldElement.focus();
|
142
|
+
}
|
143
|
+
}
|
144
|
+
return false;
|
145
|
+
}
|
146
|
+
if (await ((_b = this.callback) === null || _b === void 0 ? void 0 : _b.call(this, view.record))) {
|
109
147
|
popup.close();
|
110
148
|
}
|
149
|
+
else {
|
150
|
+
// 밸리데이션 실패 시 처리
|
151
|
+
console.error('레코드 밸리데이션 실패');
|
152
|
+
// 여기에 사용자에게 오류 메시지를 표시하는 로직을 추가할 수 있습니다.
|
153
|
+
}
|
111
154
|
});
|
112
155
|
recordView.addEventListener('field-change', async (e) => {
|
113
156
|
const view = e.currentTarget;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"record-creator.js","sourceRoot":"","sources":["../../../src/record-view/record-creator.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport './record-view'\n\nimport { html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxPopup } from '@operato/popup'\n\nimport { DataGrist } from '../data-grist'\nimport { ColumnConfig, GristRecord } from '../types'\nimport { RecordView } from './record-view'\n\n@customElement('ox-record-creator')\nexport class RecordCreator extends LitElement {\n @state() grist?: DataGrist\n\n @property({ type: Object }) callback?: (operation: { [key: string]: any }) => boolean\n @property({ type: Boolean, attribute: 'light-popup' }) lightPopup: boolean = false\n @property({ type: Boolean, attribute: 'prevent-close-on-blur' }) preventCloseOnBlur = false\n\n constructor() {\n super()\n\n this.addEventListener('click', (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n\n if (this.lightPopup) {\n this.lightPopupRecordView()\n } else {\n this.popupRecordView()\n }\n })\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.grist = this.closest('ox-grist') as DataGrist\n }\n\n render() {\n return html`<slot></slot>`\n }\n\n lightPopupRecordView() {\n const config = this.grist!.compiledConfig\n var title = 'create'\n const rowIndex = -1\n var record: GristRecord = {}\n const columns = config.columns\n\n var popup = OxPopup.open({\n template: html`\n <div title>${title}</div>\n <ox-record-view\n @field-change=${(e: CustomEvent) => {\n const view = e.currentTarget as RecordView\n\n var { after, before, column, record, row } = (e as CustomEvent).detail as {\n after: any\n before: any\n column: ColumnConfig\n record: GristRecord\n row: number\n }\n\n var validation = column.validation\n if (validation && typeof validation == 'function') {\n if (!validation.call(this, after, before, record, column)) {\n return\n }\n }\n\n view.record = {\n ...record,\n [column.name]: after\n }\n }}\n .columns=${columns}\n .record=${record}\n .rowIndex=${rowIndex}\n @reset=${(e: Event) => {\n const view = e.currentTarget as RecordView\n view.record = {}\n }}\n @cancel=${(e: Event) => {\n popup.close()\n }}\n @ok=${(e: Event) => {\n popup.close()\n\n const view = e.currentTarget as RecordView\n\n this.dispatchEvent(\n new CustomEvent('ok', {\n bubbles: true,\n composed: true,\n detail: view.record\n })\n )\n }}\n ></ox-record-view>\n `,\n parent: document.body,\n preventCloseOnBlur: this.preventCloseOnBlur\n })\n }\n\n popupRecordView() {\n const config = this.grist!.compiledConfig\n const rowIndex = -1\n var record: GristRecord = {}\n const columns = config.columns\n\n var title = 'create'\n\n var recordView = document.createElement('ox-record-view') as RecordView\n\n recordView.columns = columns\n recordView.record = record\n recordView.rowIndex = rowIndex\n\n document.dispatchEvent(\n new CustomEvent('open-popup', {\n detail: {\n template: recordView,\n options: {\n backdrop: true,\n size: 'large',\n title\n },\n callback: (popup: any) => {\n recordView.addEventListener('reset', (e: Event) => {\n const view = e.currentTarget as RecordView\n view.record = {}\n })\n\n recordView.addEventListener('cancel', (e: Event) => {\n popup.close()\n })\n\n recordView.addEventListener('ok', async (e: Event) => {\n const view = e.currentTarget as RecordView\n if (await this.callback?.(view.record)) {\n popup.close()\n }\n })\n\n recordView.addEventListener('field-change', async (e: Event) => {\n const view = e.currentTarget as RecordView\n\n var { after, before, column, record, row } = (e as CustomEvent).detail as {\n after: any\n before: any\n column: ColumnConfig\n record: GristRecord\n row: number\n }\n\n var validation = column.validation\n if (validation && typeof validation == 'function') {\n if (!(await validation.call(this, after, before, record, column))) {\n return\n }\n }\n\n view.record = {\n ...record,\n [column.name]: after\n }\n })\n\n popup.onclosed = () => {}\n }\n }\n })\n )\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"record-creator.js","sourceRoot":"","sources":["../../../src/record-view/record-creator.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport './record-view'\n\nimport { html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxPopup } from '@operato/popup'\n\nimport { DataGrist } from '../data-grist'\nimport { ColumnConfig, GristRecord, ValidationReason } from '../types'\nimport { RecordView } from './record-view'\n\n@customElement('ox-record-creator')\nexport class RecordCreator extends LitElement {\n @state() grist?: DataGrist\n\n @property({ type: Object }) callback?: (operation: { [key: string]: any }) => boolean\n @property({ type: Boolean, attribute: 'light-popup' }) lightPopup: boolean = false\n @property({ type: Boolean, attribute: 'prevent-close-on-blur' }) preventCloseOnBlur = false\n\n constructor() {\n super()\n\n this.addEventListener('click', (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n\n if (this.lightPopup) {\n this.lightPopupRecordView()\n } else {\n this.popupRecordView()\n }\n })\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.grist = this.closest('ox-grist') as DataGrist\n }\n\n render() {\n return html`<slot></slot>`\n }\n\n validateRecord(record: GristRecord): { field: string; reason: ValidationReason }[] {\n const columns = this.grist!.compiledConfig.columns;\n const invalidFields: { field: string; reason: ValidationReason }[] = [];\n\n columns.forEach(column => {\n if (column.record?.mandatory && (record[column.name] === undefined || record[column.name] === null || record[column.name] === '')) {\n invalidFields.push({\n field: column.name,\n reason: ValidationReason.MANDATORY\n });\n }\n // 여기에 추가적인 유효성 검사 규칙을 구현할 수 있습니다.\n });\n\n return invalidFields\n }\n\n lightPopupRecordView() {\n const config = this.grist!.compiledConfig\n var title = 'create'\n const rowIndex = -1\n var record: GristRecord = {}\n const columns = config.columns\n\n var popup = OxPopup.open({\n template: html`\n <div title>${title}</div>\n <ox-record-view\n @field-change=${(e: CustomEvent) => {\n const view = e.currentTarget as RecordView\n\n var { after, before, column, record, row } = (e as CustomEvent).detail as {\n after: any\n before: any\n column: ColumnConfig\n record: GristRecord\n row: number\n }\n\n var validation = column.validation\n if (validation && typeof validation == 'function') {\n if (!validation.call(this, after, before, record, column)) {\n return\n }\n }\n\n view.record = {\n ...record,\n [column.name]: after\n }\n }}\n .columns=${columns}\n .record=${record}\n .rowIndex=${rowIndex}\n @reset=${(e: Event) => {\n const view = e.currentTarget as RecordView\n view.record = {}\n }}\n @cancel=${(e: Event) => {\n popup.close()\n }}\n @ok=${async (e: Event) => {\n const view = e.currentTarget as RecordView\n\n // 레코드 밸리데이션 체크\n const invalidFields = await this.validateRecord(view.record);\n if (invalidFields.length > 0) {\n // const firstInvalidField = invalidFields[0];\n // if (firstInvalidField) {\n // view.setFocus(firstInvalidField.field)\n // }\n view.setFocusOnInvalid(invalidFields);\n return false;\n }\n\n popup.close()\n\n this.dispatchEvent(\n new CustomEvent('ok', {\n bubbles: true,\n composed: true,\n detail: view.record\n })\n )\n }}\n ></ox-record-view>\n `,\n parent: document.body,\n preventCloseOnBlur: this.preventCloseOnBlur\n })\n }\n\n popupRecordView() {\n const config = this.grist!.compiledConfig\n const rowIndex = -1\n var record: GristRecord = {}\n const columns = config.columns\n\n var title = 'create'\n\n var recordView = document.createElement('ox-record-view') as RecordView\n\n recordView.columns = columns\n recordView.record = record\n recordView.rowIndex = rowIndex\n\n document.dispatchEvent(\n new CustomEvent('open-popup', {\n detail: {\n template: recordView,\n options: {\n backdrop: true,\n size: 'large',\n title\n },\n callback: (popup: any) => {\n recordView.addEventListener('reset', (e: Event) => {\n const view = e.currentTarget as RecordView\n view.record = {}\n })\n\n recordView.addEventListener('cancel', (e: Event) => {\n popup.close()\n })\n\n recordView.addEventListener('ok', async (e: Event) => {\n const view = e.currentTarget as RecordView\n\n // 레코드 밸리데이션 체크\n const invalidFields = await this.validateRecord(view.record);\n if (invalidFields.length > 0) {\n const firstInvalidField = invalidFields[0];\n if (firstInvalidField) {\n const fieldElement = view.renderRoot?.querySelector(`[name=\"${firstInvalidField}\"]`);\n if (fieldElement) {\n (fieldElement as HTMLElement).focus();\n }\n }\n return false;\n }\n \n if (await this.callback?.(view.record)) {\n popup.close()\n } else {\n // 밸리데이션 실패 시 처리\n console.error('레코드 밸리데이션 실패');\n // 여기에 사용자에게 오류 메시지를 표시하는 로직을 추가할 수 있습니다.\n }\n })\n\n recordView.addEventListener('field-change', async (e: Event) => {\n const view = e.currentTarget as RecordView\n\n var { after, before, column, record, row } = (e as CustomEvent).detail as {\n after: any\n before: any\n column: ColumnConfig\n record: GristRecord\n row: number\n }\n\n var validation = column.validation\n if (validation && typeof validation == 'function') {\n if (!(await validation.call(this, after, before, record, column))) {\n return\n }\n }\n\n view.record = {\n ...record,\n [column.name]: after\n }\n })\n\n popup.onclosed = () => {}\n }\n }\n })\n )\n }\n}\n"]}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import '@material/web/icon/icon.js';
|
2
2
|
import '../data-grid/data-grid-field';
|
3
3
|
import { LitElement } from 'lit';
|
4
|
-
import { ColumnConfig, GristRecord } from '../types';
|
4
|
+
import { ColumnConfig, GristRecord, ValidationReason } from '../types';
|
5
5
|
export declare class RecordViewBody extends LitElement {
|
6
6
|
static styles: import("lit").CSSResult[];
|
7
7
|
columns: ColumnConfig[];
|
@@ -10,6 +10,11 @@ export declare class RecordViewBody extends LitElement {
|
|
10
10
|
currentTarget: any;
|
11
11
|
connectedCallback(): void;
|
12
12
|
disconnectedCallback(): void;
|
13
|
+
setFocus(fieldElement: HTMLElement): void;
|
14
|
+
setFocusOnInvalid(invalidFields: {
|
15
|
+
field: string;
|
16
|
+
reason: ValidationReason;
|
17
|
+
}[]): void;
|
13
18
|
_onKeyDown(event: KeyboardEvent): void;
|
14
19
|
render(): import("lit-html").TemplateResult<1>;
|
15
20
|
_renderLabel(column: ColumnConfig): import("lit-html").TemplateResult<1>;
|
@@ -5,6 +5,7 @@ import { css, html, LitElement } from 'lit';
|
|
5
5
|
import { customElement, property } from 'lit/decorators.js';
|
6
6
|
import { ZERO_RECORD } from '../configure/zero-config';
|
7
7
|
import { recordViewBodyClickHandler } from './event-handlers/record-view-body-click-handler';
|
8
|
+
import i18next from 'i18next';
|
8
9
|
let RecordViewBody = class RecordViewBody extends LitElement {
|
9
10
|
constructor() {
|
10
11
|
super(...arguments);
|
@@ -22,8 +23,31 @@ let RecordViewBody = class RecordViewBody extends LitElement {
|
|
22
23
|
super.disconnectedCallback();
|
23
24
|
this.removeEventListener('keydown', this._onKeyDown);
|
24
25
|
}
|
26
|
+
setFocus(fieldElement) {
|
27
|
+
fieldElement === null || fieldElement === void 0 ? void 0 : fieldElement.dispatchEvent(new CustomEvent('click', { bubbles: true, composed: true }));
|
28
|
+
}
|
29
|
+
setFocusOnInvalid(invalidFields) {
|
30
|
+
const allLabels = this.renderRoot.querySelectorAll('label');
|
31
|
+
allLabels.forEach((label) => {
|
32
|
+
label.classList.remove('highlight-invalid');
|
33
|
+
label.removeAttribute('data-reason');
|
34
|
+
});
|
35
|
+
// 유효성 검사를 통과하지 못한 필드에 대해 처리
|
36
|
+
invalidFields.forEach(({ field, reason }, index) => {
|
37
|
+
const labelElement = this.renderRoot.querySelector(`[data-name="${field}"]`);
|
38
|
+
const fieldElement = this.renderRoot.querySelector(`[data-name="${field}"] + ox-grid-field`);
|
39
|
+
// 동적으로 data-reason 속성을 설정하여 메시지를 변경
|
40
|
+
if (labelElement) {
|
41
|
+
labelElement.classList.add('highlight-invalid');
|
42
|
+
labelElement.setAttribute('data-reason', '(' + i18next.t(`text.validation-reason.${reason}`) + ')');
|
43
|
+
}
|
44
|
+
// 첫 번째 필드에 포커스 설정
|
45
|
+
if (index === 0 && fieldElement) {
|
46
|
+
this.setFocus(fieldElement);
|
47
|
+
}
|
48
|
+
});
|
49
|
+
}
|
25
50
|
_onKeyDown(event) {
|
26
|
-
var _a;
|
27
51
|
if (event.key === 'Tab') {
|
28
52
|
const fields = Array.from(this.renderRoot.querySelectorAll('ox-grid-field[tabstop]'));
|
29
53
|
const focused = this.renderRoot.querySelector('ox-grid-field[editing]');
|
@@ -33,7 +57,8 @@ let RecordViewBody = class RecordViewBody extends LitElement {
|
|
33
57
|
return; // Let the default behavior happen if it's the last or first element
|
34
58
|
}
|
35
59
|
event.preventDefault();
|
36
|
-
|
60
|
+
const nextField = fields[nextIndex];
|
61
|
+
nextField && this.setFocus(nextField);
|
37
62
|
}
|
38
63
|
}
|
39
64
|
render() {
|
@@ -49,7 +74,7 @@ let RecordViewBody = class RecordViewBody extends LitElement {
|
|
49
74
|
}
|
50
75
|
let dirtyFields = record['__dirtyfields__'] || {};
|
51
76
|
return html `
|
52
|
-
<label ?editable=${editable} ?wide=${wide}>
|
77
|
+
<label ?editable=${editable} ?wide=${wide} data-name=${column.name}>
|
53
78
|
<span>${mandatory ? '*' : ''}${this._renderLabel(column)}</span>
|
54
79
|
<md-icon>edit</md-icon>
|
55
80
|
</label>
|
@@ -86,7 +111,7 @@ RecordViewBody.styles = [
|
|
86
111
|
}
|
87
112
|
|
88
113
|
div[content] {
|
89
|
-
align-self:
|
114
|
+
align-self: center;
|
90
115
|
|
91
116
|
display: grid;
|
92
117
|
grid-template-columns: 2fr 3fr 2fr 3fr;
|
@@ -132,7 +157,6 @@ RecordViewBody.styles = [
|
|
132
157
|
}
|
133
158
|
|
134
159
|
ox-grid-field {
|
135
|
-
justify-content: var();
|
136
160
|
background-color: var(--record-view-grid-field-background-color, var(--md-sys-color-surface-container-lowest));
|
137
161
|
border: var(--record-view-grid-field-border);
|
138
162
|
border-radius: var(--md-sys-shape-corner-small);
|
@@ -159,6 +183,20 @@ RecordViewBody.styles = [
|
|
159
183
|
font-weight: bold;
|
160
184
|
}
|
161
185
|
|
186
|
+
.highlight-invalid {
|
187
|
+
position: relative;
|
188
|
+
padding: var(--spacing-tiny) var(--spacing-small);
|
189
|
+
}
|
190
|
+
|
191
|
+
.highlight-invalid::after {
|
192
|
+
content: attr(data-reason); /* 콘텐츠를 동적으로 변경하기 위해 data-reason 속성을 사용 */
|
193
|
+
color: red;
|
194
|
+
font-size: 12px;
|
195
|
+
position: absolute;
|
196
|
+
left: 0;
|
197
|
+
bottom: -8px; /* 라벨 아래쪽에 메시지를 표시 */
|
198
|
+
}
|
199
|
+
|
162
200
|
@media only screen and (max-width: 1000px) {
|
163
201
|
div[content] {
|
164
202
|
grid-template-columns: 2fr 3fr;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"record-view-body.js","sourceRoot":"","sources":["../../../src/record-view/record-view-body.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '../data-grid/data-grid-field'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ZERO_RECORD } from '../configure/zero-config'\nimport { ColumnConfig, GristRecord } from '../types'\nimport { recordViewBodyClickHandler } from './event-handlers/record-view-body-click-handler'\n\n@customElement('ox-record-view-body')\nexport class RecordViewBody extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n align-content: center;\n }\n\n :host > * {\n align-self: stretch;\n }\n\n div[content] {\n align-self: auto;\n\n display: grid;\n grid-template-columns: 2fr 3fr 2fr 3fr;\n grid-auto-rows: min-content;\n grid-gap: var(--spacing-large) 0;\n\n padding: var(--spacing-large) var(--spacing-huge);\n font-size: 16px; /* for ios safari */\n flex: 1;\n width: 100%;\n max-width: 1300px;\n box-sizing: border-box;\n }\n\n label {\n display: flex;\n align-items: center;\n position: relative;\n text-transform: capitalize;\n padding: var(--record-view-item-padding);\n font: var(--record-view-label-font);\n color: var(--record-view-label-color);\n text-align: right;\n padding-right: var(--spacing-large);\n }\n\n label[wide] {\n grid-column: 1 / 2;\n }\n\n label md-icon {\n display: none;\n }\n\n label > span {\n margin-left: auto;\n }\n\n label[editable] md-icon {\n display: inline-block;\n font-size: var(--record-view-label-icon-size);\n opacity: 0.5;\n }\n\n ox-grid-field {\n justify-content: var();\n background-color: var(--record-view-grid-field-background-color, var(--md-sys-color-surface-container-lowest));\n border: var(--record-view-grid-field-border);\n border-radius: var(--md-sys-shape-corner-small);\n padding: var(--spacing-tiny) var(--spacing-small);\n\n font: var(--record-view-font);\n color: var(--record-view-color);\n\n max-width: 360px;\n }\n\n ox-grid-field[editing='true'] {\n border: var(--record-view-edit-border);\n }\n\n ox-grid-field[wide] {\n grid-column: 2 / 5;\n width: 100%;\n max-width: 986px;\n }\n\n :first-child + ox-grid-field {\n color: var(--record-view-focus-color);\n font-weight: bold;\n }\n\n @media only screen and (max-width: 1000px) {\n div[content] {\n grid-template-columns: 2fr 3fr;\n padding: var(--spacing-medium);\n }\n\n label[wide] {\n grid-column: 1 / 2;\n }\n\n ox-grid-field[wide] {\n grid-column: 2 / 3;\n width: 100%;\n max-width: 360px;\n }\n }\n\n @media only screen and (max-width: 600px) {\n div[content] {\n grid-template-columns: 2fr 3fr;\n padding: var(--spacing-medium);\n }\n\n label[wide] {\n grid-column: 1 / 2;\n }\n\n ox-grid-field[wide] {\n grid-column: 1 / 3;\n width: 100%;\n max-width: unset;\n }\n }\n `\n ]\n\n @property({ type: Array }) columns: ColumnConfig[] = []\n @property({ type: Object }) record: GristRecord = ZERO_RECORD\n @property({ type: Number }) rowIndex: number = -1\n\n public currentTarget: any\n\n connectedCallback() {\n super.connectedCallback()\n\n this.setAttribute('tabindex', '0')\n\n this.addEventListener('keydown', this._onKeyDown)\n this.renderRoot.addEventListener('click', recordViewBodyClickHandler.bind(this))\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.removeEventListener('keydown', this._onKeyDown)\n }\n\n _onKeyDown(event: KeyboardEvent) {\n if (event.key === 'Tab') {\n const fields = Array.from(this.renderRoot.querySelectorAll('ox-grid-field[tabstop]'))\n const focused = this.renderRoot.querySelector('ox-grid-field[editing]')\n const focusedIndex = fields.findIndex(field => field === focused)\n\n let nextIndex = focusedIndex + (event.shiftKey ? -1 : 1)\n\n if (nextIndex >= fields.length || nextIndex < 0) {\n return // Let the default behavior happen if it's the last or first element\n }\n\n event.preventDefault()\n fields[nextIndex]?.dispatchEvent(new CustomEvent('click', { bubbles: true, composed: true }))\n }\n }\n\n render() {\n var columns = this.columns.filter(column => !column.hidden && column.type !== 'gutter')\n var record = this.record\n var rowIndex = this.rowIndex\n\n return html`\n <div content>\n ${columns.map((column, index) => {\n let { editable, mandatory, wide } = column.record\n if (typeof editable === 'function') {\n editable = editable.call(this, record[column.name], column, record, rowIndex, this)\n }\n\n let dirtyFields = record['__dirtyfields__'] || {}\n\n return html`\n <label ?editable=${editable} ?wide=${wide}>\n <span>${mandatory ? '*' : ''}${this._renderLabel(column)}</span>\n <md-icon>edit</md-icon>\n </label>\n <ox-grid-field\n .rowIndex=${rowIndex}\n .column=${column}\n .record=${record}\n .value=${record[column.name]}\n ?dirty=${!!dirtyFields[column.name]}\n ?tabstop=${!!editable}\n ?wide=${wide}\n ></ox-grid-field>\n `\n })}\n </div>\n `\n }\n\n _renderLabel(column: ColumnConfig) {\n var { renderer } = column.header\n var title = renderer.call(this, column)\n\n return html` ${title} `\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"record-view-body.js","sourceRoot":"","sources":["../../../src/record-view/record-view-body.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '../data-grid/data-grid-field'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { ZERO_RECORD } from '../configure/zero-config'\nimport { ColumnConfig, GristRecord, ValidationReason } from '../types'\nimport { recordViewBodyClickHandler } from './event-handlers/record-view-body-click-handler'\nimport i18next from 'i18next'\n\n@customElement('ox-record-view-body')\nexport class RecordViewBody extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n align-content: center;\n }\n\n :host > * {\n align-self: stretch;\n }\n\n div[content] {\n align-self: center;\n\n display: grid;\n grid-template-columns: 2fr 3fr 2fr 3fr;\n grid-auto-rows: min-content;\n grid-gap: var(--spacing-large) 0;\n\n padding: var(--spacing-large) var(--spacing-huge);\n font-size: 16px; /* for ios safari */\n flex: 1;\n width: 100%;\n max-width: 1300px;\n box-sizing: border-box;\n }\n\n label {\n display: flex;\n align-items: center;\n position: relative;\n text-transform: capitalize;\n padding: var(--record-view-item-padding);\n font: var(--record-view-label-font);\n color: var(--record-view-label-color);\n text-align: right;\n padding-right: var(--spacing-large);\n }\n\n label[wide] {\n grid-column: 1 / 2;\n }\n\n label md-icon {\n display: none;\n }\n\n label > span {\n margin-left: auto;\n }\n\n label[editable] md-icon {\n display: inline-block;\n font-size: var(--record-view-label-icon-size);\n opacity: 0.5;\n }\n\n ox-grid-field {\n background-color: var(--record-view-grid-field-background-color, var(--md-sys-color-surface-container-lowest));\n border: var(--record-view-grid-field-border);\n border-radius: var(--md-sys-shape-corner-small);\n padding: var(--spacing-tiny) var(--spacing-small);\n\n font: var(--record-view-font);\n color: var(--record-view-color);\n\n max-width: 360px;\n }\n\n ox-grid-field[editing='true'] {\n border: var(--record-view-edit-border);\n }\n\n ox-grid-field[wide] {\n grid-column: 2 / 5;\n width: 100%;\n max-width: 986px;\n }\n\n :first-child + ox-grid-field {\n color: var(--record-view-focus-color);\n font-weight: bold;\n }\n\n .highlight-invalid {\n position: relative;\n padding: var(--spacing-tiny) var(--spacing-small);\n }\n\n .highlight-invalid::after {\n content: attr(data-reason); /* 콘텐츠를 동적으로 변경하기 위해 data-reason 속성을 사용 */\n color: red;\n font-size: 12px;\n position: absolute;\n left: 0;\n bottom: -8px; /* 라벨 아래쪽에 메시지를 표시 */\n }\n\n @media only screen and (max-width: 1000px) {\n div[content] {\n grid-template-columns: 2fr 3fr;\n padding: var(--spacing-medium);\n }\n\n label[wide] {\n grid-column: 1 / 2;\n }\n\n ox-grid-field[wide] {\n grid-column: 2 / 3;\n width: 100%;\n max-width: 360px;\n }\n }\n\n @media only screen and (max-width: 600px) {\n div[content] {\n grid-template-columns: 2fr 3fr;\n padding: var(--spacing-medium);\n }\n\n label[wide] {\n grid-column: 1 / 2;\n }\n\n ox-grid-field[wide] {\n grid-column: 1 / 3;\n width: 100%;\n max-width: unset;\n }\n }\n `\n ]\n\n @property({ type: Array }) columns: ColumnConfig[] = []\n @property({ type: Object }) record: GristRecord = ZERO_RECORD\n @property({ type: Number }) rowIndex: number = -1\n\n public currentTarget: any\n\n connectedCallback() {\n super.connectedCallback()\n\n this.setAttribute('tabindex', '0')\n\n this.addEventListener('keydown', this._onKeyDown)\n this.renderRoot.addEventListener('click', recordViewBodyClickHandler.bind(this))\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.removeEventListener('keydown', this._onKeyDown)\n }\n\n setFocus(fieldElement: HTMLElement) {\n fieldElement?.dispatchEvent(new CustomEvent('click', { bubbles: true, composed: true }))\n }\n\n setFocusOnInvalid(invalidFields: { field: string; reason: ValidationReason }[]) {\n const allLabels = this.renderRoot.querySelectorAll('label')\n allLabels.forEach((label: HTMLLabelElement) => {\n label.classList.remove('highlight-invalid')\n label.removeAttribute('data-reason')\n })\n\n // 유효성 검사를 통과하지 못한 필드에 대해 처리\n invalidFields.forEach(({ field, reason }, index) => {\n const labelElement = this.renderRoot.querySelector(`[data-name=\"${field}\"]`) as HTMLLabelElement\n const fieldElement = this.renderRoot.querySelector(`[data-name=\"${field}\"] + ox-grid-field`) as HTMLInputElement\n\n // 동적으로 data-reason 속성을 설정하여 메시지를 변경\n if (labelElement) {\n labelElement.classList.add('highlight-invalid')\n labelElement.setAttribute('data-reason', '(' + i18next.t(`text.validation-reason.${reason}`) + ')')\n }\n\n // 첫 번째 필드에 포커스 설정\n if (index === 0 && fieldElement) {\n this.setFocus(fieldElement)\n }\n })\n }\n\n _onKeyDown(event: KeyboardEvent) {\n if (event.key === 'Tab') {\n const fields = Array.from(this.renderRoot.querySelectorAll('ox-grid-field[tabstop]'))\n const focused = this.renderRoot.querySelector('ox-grid-field[editing]')\n const focusedIndex = fields.findIndex(field => field === focused)\n\n let nextIndex = focusedIndex + (event.shiftKey ? -1 : 1)\n\n if (nextIndex >= fields.length || nextIndex < 0) {\n return // Let the default behavior happen if it's the last or first element\n }\n\n event.preventDefault()\n const nextField = fields[nextIndex] as HTMLInputElement\n nextField && this.setFocus(nextField)\n }\n }\n\n render() {\n var columns = this.columns.filter(column => !column.hidden && column.type !== 'gutter')\n var record = this.record\n var rowIndex = this.rowIndex\n\n return html`\n <div content>\n ${columns.map((column, index) => {\n let { editable, mandatory, wide } = column.record\n if (typeof editable === 'function') {\n editable = editable.call(this, record[column.name], column, record, rowIndex, this)\n }\n\n let dirtyFields = record['__dirtyfields__'] || {}\n\n return html`\n <label ?editable=${editable} ?wide=${wide} data-name=${column.name}>\n <span>${mandatory ? '*' : ''}${this._renderLabel(column)}</span>\n <md-icon>edit</md-icon>\n </label>\n <ox-grid-field\n .rowIndex=${rowIndex}\n .column=${column}\n .record=${record}\n .value=${record[column.name]}\n ?dirty=${!!dirtyFields[column.name]}\n ?tabstop=${!!editable}\n ?wide=${wide}\n ></ox-grid-field>\n `\n })}\n </div>\n `\n }\n\n _renderLabel(column: ColumnConfig) {\n var { renderer } = column.header\n var title = renderer.call(this, column)\n\n return html` ${title} `\n }\n}\n"]}
|
@@ -3,14 +3,20 @@ import './record-view-body';
|
|
3
3
|
import '@operato/input/ox-input-file.js';
|
4
4
|
import '../data-grid/data-grid-field';
|
5
5
|
import { LitElement } from 'lit';
|
6
|
-
import { ColumnConfig, GristRecord } from '../types';
|
6
|
+
import { ColumnConfig, GristRecord, ValidationReason } from '../types';
|
7
|
+
import { RecordViewBody } from './record-view-body';
|
7
8
|
export declare class RecordView extends LitElement {
|
8
9
|
static styles: import("lit").CSSResult[];
|
9
10
|
columns: ColumnConfig[];
|
10
11
|
record: GristRecord;
|
11
12
|
rowIndex: number;
|
13
|
+
body: RecordViewBody;
|
12
14
|
render(): import("lit-html").TemplateResult<1>;
|
13
15
|
firstUpdated(): void;
|
16
|
+
setFocusOnInvalid(invalidFields: {
|
17
|
+
field: string;
|
18
|
+
reason: ValidationReason;
|
19
|
+
}[]): void;
|
14
20
|
onReset(): void;
|
15
21
|
onCancel(): void;
|
16
22
|
onOK(): void;
|
@@ -4,7 +4,7 @@ import './record-view-body';
|
|
4
4
|
import '@operato/input/ox-input-file.js';
|
5
5
|
import '../data-grid/data-grid-field';
|
6
6
|
import { css, html, LitElement } from 'lit';
|
7
|
-
import { customElement, property } from 'lit/decorators.js';
|
7
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
8
8
|
import { ScrollbarStyles } from '@operato/styles';
|
9
9
|
import { ZERO_RECORD } from '../configure/zero-config';
|
10
10
|
let RecordView = class RecordView extends LitElement {
|
@@ -28,6 +28,9 @@ let RecordView = class RecordView extends LitElement {
|
|
28
28
|
firstUpdated() {
|
29
29
|
this.setAttribute('tabindex', '0');
|
30
30
|
}
|
31
|
+
setFocusOnInvalid(invalidFields) {
|
32
|
+
this.body.setFocusOnInvalid(invalidFields);
|
33
|
+
}
|
31
34
|
onReset() {
|
32
35
|
this.focus();
|
33
36
|
this.dispatchEvent(new CustomEvent('reset', {
|
@@ -104,6 +107,9 @@ __decorate([
|
|
104
107
|
__decorate([
|
105
108
|
property({ type: Number })
|
106
109
|
], RecordView.prototype, "rowIndex", void 0);
|
110
|
+
__decorate([
|
111
|
+
query('ox-record-view-body')
|
112
|
+
], RecordView.prototype, "body", void 0);
|
107
113
|
RecordView = __decorate([
|
108
114
|
customElement('ox-record-view')
|
109
115
|
], RecordView);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"record-view.js","sourceRoot":"","sources":["../../../src/record-view/record-view.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,oBAAoB,CAAA;AAC3B,OAAO,iCAAiC,CAAA;AACxC,OAAO,8BAA8B,CAAA;AAErC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;
|
1
|
+
{"version":3,"file":"record-view.js","sourceRoot":"","sources":["../../../src/record-view/record-view.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,oBAAoB,CAAA;AAC3B,OAAO,iCAAiC,CAAA;AACxC,OAAO,8BAA8B,CAAA;AAErC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAM/C,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;QAkDsB,YAAO,GAAmB,EAAE,CAAA;QAC3B,WAAM,GAAgB,WAAW,CAAA;QACjC,aAAQ,GAAW,CAAC,CAAC,CAAA;IAqDnD,CAAC;IAjDC,MAAM;QACJ,OAAO,IAAI,CAAA;sCACuB,IAAI,CAAC,OAAO,YAAY,IAAI,CAAC,MAAM,cAAc,IAAI,CAAC,QAAQ;;;yBAG3E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;yBACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;yBACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;;KAExC,CAAA;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,iBAAiB,CAAC,aAA4D;QAC5E,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAA;IAC5C,CAAC;IAED,OAAO;QACL,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,OAAO,EAAE;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CACH,CAAA;IACH,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CACH,CAAA;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,IAAI,EAAE;YACpB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CACH,CAAA;IACH,CAAC;;AAvGM,iBAAM,GAAG;IACd,eAAe;IACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4CF;CACF,AA/CY,CA+CZ;AAE0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2CAA6B;AAC3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAAkC;AACjC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAsB;AAEnB;IAA7B,KAAK,CAAC,qBAAqB,CAAC;wCAAsB;AAtDxC,UAAU;IADtB,aAAa,CAAC,gBAAgB,CAAC;GACnB,UAAU,CAyGtB","sourcesContent":["import '@material/web/icon/icon.js'\nimport './record-view-body'\nimport '@operato/input/ox-input-file.js'\nimport '../data-grid/data-grid-field'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { ZERO_RECORD } from '../configure/zero-config'\nimport { ColumnConfig, GristRecord, ValidationReason } from '../types'\n\nimport { RecordViewBody } from './record-view-body'\n\n@customElement('ox-record-view')\nexport class RecordView extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n background-color: var(--record-view-background-color);\n }\n\n ox-record-view-body {\n flex: 1;\n overflow-y: auto;\n }\n\n [footer] {\n text-align: right;\n background-color: var(--record-view-footer-background);\n box-shadow: var(--context-toolbar-shadow-line);\n }\n\n [footer] button {\n display: inline-block;\n align-items: center;\n justify-content: center;\n\n background-color: transparent;\n border: var(--record-view-footer-button-border);\n border-width: var(--record-view-footer-button-border-width);\n padding: var(--spacing-tiny) var(--spacing-medium);\n color: var(--record-view-footer-button-color);\n font-size: var(--md-sys-typescale-title-medium-size, 1rem);\n line-height: 2;\n }\n\n [footer] button * {\n vertical-align: middle;\n }\n\n [footer] button md-icon {\n --md-icon-size: var(--icon-size-small);\n margin-right: var(--spacing-small, 4px);\n }\n\n [footer] button[ok] {\n background-color: var(--record-view-footer-focus-background);\n }\n `\n ]\n\n @property({ type: Array }) columns: ColumnConfig[] = []\n @property({ type: Object }) record: GristRecord = ZERO_RECORD\n @property({ type: Number }) rowIndex: number = -1\n\n @query('ox-record-view-body') body!: RecordViewBody\n\n render() {\n return html`\n <ox-record-view-body .columns=${this.columns} .record=${this.record} .rowIndex=${this.rowIndex}>\n </ox-record-view-body>\n <div footer>\n <button @click=${this.onReset.bind(this)}><md-icon>refresh</md-icon><span>Reset</span></button>\n <button @click=${this.onCancel.bind(this)}><md-icon>clear</md-icon><span>Cancel</span></button>\n <button @click=${this.onOK.bind(this)} ok><md-icon>task_alt</md-icon><span>OK</span></button>\n </div>\n `\n }\n\n firstUpdated() {\n this.setAttribute('tabindex', '0')\n }\n\n setFocusOnInvalid(invalidFields: { field: string; reason: ValidationReason }[]) {\n this.body.setFocusOnInvalid(invalidFields)\n }\n\n onReset() {\n this.focus()\n\n this.dispatchEvent(\n new CustomEvent('reset', {\n detail: this.record\n })\n )\n }\n\n onCancel() {\n this.focus()\n\n this.dispatchEvent(\n new CustomEvent('cancel', {\n detail: this.record\n })\n )\n }\n\n onOK() {\n this.focus()\n\n this.dispatchEvent(\n new CustomEvent('ok', {\n detail: this.record\n })\n )\n }\n}\n"]}
|
@@ -9,7 +9,7 @@ export const OxGristRendererBoolean = (value, column, record, rowIndex, field) =
|
|
9
9
|
type="checkbox"
|
10
10
|
.checked=${!!value && !!String(value).match(/true/i)}
|
11
11
|
?disabled=${!editable}
|
12
|
-
@
|
12
|
+
@pointerdown=${(e) => {
|
13
13
|
/* edit mode로 전환되지 않도록 차단함. 체크박스인풋은 렌더러 모드에서도 처리가능하므로. */
|
14
14
|
e.stopPropagation();
|
15
15
|
}}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ox-grist-renderer-boolean.js","sourceRoot":"","sources":["../../../src/renderers/ox-grist-renderer-boolean.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,MAAM,CAAC,MAAM,sBAAsB,GAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAC9F,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,CAAA;IAChC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;IACzE,CAAC;IAED,OAAO,IAAI,CAAA;;;iBAGI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;kBACxC,CAAC,QAAQ;
|
1
|
+
{"version":3,"file":"ox-grist-renderer-boolean.js","sourceRoot":"","sources":["../../../src/renderers/ox-grist-renderer-boolean.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,MAAM,CAAC,MAAM,sBAAsB,GAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAC9F,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,CAAA;IAChC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;IACzE,CAAC;IAED,OAAO,IAAI,CAAA;;;iBAGI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;kBACxC,CAAC,QAAQ;qBACN,CAAC,CAAQ,EAAE,EAAE;QAC1B,yDAAyD;QACzD,CAAC,CAAC,eAAe,EAAE,CAAA;IACrB,CAAC;eACQ,CAAC,CAAQ,EAAE,EAAE;QACpB,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB;;;;;WAKG;QACH,KAAK,CAAC,aAAa,CACjB,IAAI,WAAW,CAAC,cAAc,EAAE;YAC9B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,MAAM,EAAE,KAAK;gBACb,KAAK,EAAG,CAAC,CAAC,MAA2B,CAAC,OAAO;gBAC7C,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,QAAQ;aACd;SACF,CAAC,CACH,CAAA;IACH,CAAC;;GAEJ,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { FieldRenderer } from '../types'\nimport { html } from 'lit'\n\nexport const OxGristRendererBoolean: FieldRenderer = (value, column, record, rowIndex, field) => {\n let { editable } = column.record\n if (typeof editable === 'function') {\n editable = editable.call(field, value, column, record, rowIndex, field)\n }\n\n return html`\n <input\n type=\"checkbox\"\n .checked=${!!value && !!String(value).match(/true/i)}\n ?disabled=${!editable}\n @pointerdown=${(e: Event) => {\n /* edit mode로 전환되지 않도록 차단함. 체크박스인풋은 렌더러 모드에서도 처리가능하므로. */\n e.stopPropagation()\n }}\n @click=${(e: Event) => {\n e.stopPropagation()\n /*\n * 특별하게, checkbox인 경우에, editor가 활성화되지 않아도, renderer에서 값을 변경할 수 있게 함.\n * checkbox가 클릭되면, 클릭에 의해 변경된 값을 레코드에 반영하기 위해서 value-changed 이벤트를 발생시킨다.\n *\n * 만일, readonly인 경우에는 click 이벤트가 발생하지 않으므로, 클릭으로 에디트할 수 없게 됨.\n */\n field.dispatchEvent(\n new CustomEvent('field-change', {\n bubbles: true,\n composed: true,\n detail: {\n before: value,\n after: (e.target as HTMLInputElement).checked,\n column: column,\n record: record,\n row: rowIndex\n }\n })\n )\n }}\n />\n `\n}\n"]}
|