@operato/app 10.9.0 → 10.10.1
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 +29 -0
- package/dist/src/relation/ox-relation-view.d.ts +39 -0
- package/dist/src/relation/ox-relation-view.js +70 -13
- package/dist/src/relation/ox-relation-view.js.map +1 -1
- package/dist/src/relation/relation-groups.d.ts +1 -1
- package/dist/src/relation/relation-groups.js +77 -22
- package/dist/src/relation/relation-groups.js.map +1 -1
- package/dist/src/selector/ox-selector-resource-object-legacy.js +1 -1
- package/dist/src/selector/ox-selector-resource-object-legacy.js.map +1 -1
- package/dist/src/selector/ox-selector-resource-object.js +3 -3
- package/dist/src/selector/ox-selector-resource-object.js.map +1 -1
- package/dist/test/selector-confirm-keeps-value.test.js +2 -2
- package/dist/test/selector-confirm-keeps-value.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/test/selector-confirm-keeps-value.test.ts +2 -2
- package/translations/en.json +6 -0
- package/translations/es.json +7 -1
- package/translations/ja.json +7 -1
- package/translations/ko.json +6 -0
- package/translations/ms.json +6 -0
- package/translations/zh.json +6 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-selector-resource-object-legacy.js","sourceRoot":"","sources":["../../../src/selector/ox-selector-resource-object-legacy.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\nimport '@operato/form/ox-search-form.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport {\n ColumnConfig,\n DataGrist,\n FetchHandler,\n FetchOption,\n GristData,\n GristEventHandler,\n GristRecord,\n InheritedValueType,\n ZERO_DATA\n} from '@operato/data-grist'\nimport { MultiColumnFormStyles, OxSearchForm } from '@operato/form'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { isMobileDevice } from '@operato/utils'\nimport { CommonHeaderStyles } from '@operato/styles'\n\n@customElement('ox-selector-resource-object-legacy')\nexport class OxSelectorResourceObjectLegacy extends LitElement {\n static styles = [\n CommonHeaderStyles,\n MultiColumnFormStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n }\n\n ox-grist {\n flex: 1;\n }\n\n form {\n position: relative;\n }\n\n [search] {\n position: absolute;\n right: 0;\n }\n `\n ]\n\n @property({ type: String }) value?: string\n @property({ type: Object }) config: any\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: String }) queryName!: string\n @property({ type: Object }) basicArgs: any\n @property({ type: String }) inherited?: InheritedValueType = InheritedValueType.Include\n @property({ type: Object }) confirmCallback?: (record?: GristRecord | null) => void\n @property({ type: Array }) selectedRecords: GristRecord[] = []\n\n @property({ type: Array }) searchFields: any\n @property({ type: Array }) select: {\n type: string\n name: string\n header: string\n subFields?: string[]\n hidden: boolean\n ignoreCondition: boolean\n queryName: string\n width: number\n }[] = []\n @property({ type: Object }) list: any\n @property({ type: String }) valueField: string | ((item: any) => any) = 'id'\n\n @query('ox-grist') grist!: DataGrist\n @query('ox-search-form') searchForm!: OxSearchForm\n\n render() {\n return html`\n <ox-search-form\n id=\"search-form\"\n @keypress=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n this.grist.fetch()\n }\n }}\n @submit=${(e: SubmitEvent) => this.grist.fetch()}\n .fields=${this.searchFields}\n autofocus\n ></ox-search-form>\n\n <!--\n .data 를 넘기지 않는다 — 목록은 fetchHandler 가 채운다.\n\n 그 값은 늘 ZERO_DATA(빈 것)였다. 이 부품에 data 를 주는 부르는 쪽이 없다. 그리스트는\n data 가 설정되면 reset() 하므로(data-grist 의 updated), 이 부품이 **다시 그려지는 순간\n 목록이 통째로 사라진다.**\n\n 오늘은 안 터진다 — 이 부품에 다시 그릴 상태가 없다. 그러나 새 부품(ox-selector-resource-object)\n 에 바닥 단추를 고른 상태에 묶자마자 바로 터졌다. 넘길 값이 없으면서 넘기고 있던 것이므로\n 여기서도 걷는다. 남겨 두면 다음 사람이 같은 곳에 빠진다.\n\n [재봤음] 2026-09-05 · 새 부품에서 라디오 클릭 → reset() 1회 → 20건 → 0건\n -->\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .selectedRecords=${this.selectedRecords}\n >\n <div slot=\"headroom\" id=\"headroom\">\n <div id=\"filters\">\n <ox-filters-form></ox-filters-form>\n </div>\n </div>\n </ox-grist>\n\n <div class=\"footer\">\n <button @click=${this.onEmpty.bind(this)}>\n <md-icon>check_box_outline_blank</md-icon>${i18next.t('button.empty')}\n </button>\n <div filler></div>\n <button @click=${this.onCancel.bind(this)}><md-icon>cancel</md-icon>${i18next.t('button.cancel')}</button>\n <button @click=${this.onConfirm.bind(this)}><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>\n </div>\n `\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback()\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.selected)\n closePopup(this)\n }\n\n fetchHandler: FetchHandler = async ({ filters, page, limit, sorters = [], inherited }) => {\n const response = await client.query({\n query: gql`\n query($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $inherited: InheritedValueType) {\n fetch: ${\n this.queryName\n } (filters: $filters, pagination: $pagination, sortings: $sortings, inherited: $inherited)\n {\n ${this.getSelectFields()}\n }\n }\n `,\n variables: await this._buildConditions({ filters, page, limit, sorters, inherited: inherited || this.inherited })\n })\n\n if (!response.errors) {\n const records = response.data.fetch.items.map((item: any) => {\n let rowValue\n\n if (this.valueField && typeof this.valueField === 'function') {\n rowValue = this.valueField(item)\n } else if (this.valueField) {\n rowValue = item[this.valueField]\n } else {\n rowValue = item.id\n }\n\n if (this.value && this.value === rowValue) {\n this.selectedRecords = [item]\n item['__selected__'] = true\n }\n\n return item\n })\n const total = response.data.fetch.total\n\n return {\n records,\n total,\n limit,\n page\n }\n }\n }\n\n async firstUpdated() {\n this.config = {\n columns: [\n {\n type: 'gutter',\n gutterName: 'sequence'\n },\n {\n type: 'gutter',\n gutterName: 'row-selector',\n multiple: false\n }\n ],\n rows: {\n selectable: {\n multiple: false\n },\n handlers: {\n click: 'select-row',\n dblclick: ((columns, data, column, record, rowIndex, field) => {\n this.onConfirm()\n }) as GristEventHandler\n },\n appendable: false\n }\n }\n\n if (this.select && this.select.length > 0) {\n let _searchFields = this.select.filter(selectField => !selectField.hidden && !selectField.ignoreCondition)\n if (this.list && this.list.fields && this.list.fields.length > 0) {\n _searchFields = _searchFields.filter(searchField => this.list.fields.indexOf(searchField.name) >= 0)\n } else {\n _searchFields = _searchFields.slice(0, 4)\n }\n\n this.searchFields = _searchFields.map(selectField => {\n const fieldType = (selectField.type && selectField.type.toLowerCase()) || 'string'\n const numberTypes = ['integer', 'float']\n return {\n label: selectField.header || i18next.t(`field.${selectField.name}`),\n name: selectField.name,\n type:\n fieldType === 'string'\n ? 'text'\n : numberTypes.indexOf(fieldType) >= 0\n ? 'number'\n : fieldType === 'boolean'\n ? 'checkbox'\n : fieldType,\n queryName: selectField.queryName,\n props:\n fieldType === 'string'\n ? { searchOper: 'i_like' }\n : fieldType === 'object'\n ? { searchOper: 'in' }\n : { searchOper: 'eq' },\n attrs: fieldType === 'boolean' ? ['indeterminated'] : []\n }\n })\n this.config = {\n ...this.config,\n columns: [\n ...this.config.columns,\n ...this.select.map(selectField => {\n return {\n ...selectField,\n type: selectField.type || 'string',\n width: selectField.width || 160,\n header: selectField.header || i18next.t(`field.${selectField.name}`)\n }\n })\n ]\n }\n } else {\n this.searchFields = [\n {\n label: i18next.t('field.name'),\n name: 'name',\n type: 'text',\n props: { searchOper: 'i_like' }\n },\n {\n label: i18next.t('field.description'),\n name: 'description',\n type: 'text',\n props: { searchOper: 'i_like' }\n }\n ]\n\n this.config = {\n ...this.config,\n columns: [\n ...this.config.columns,\n {\n type: 'string',\n name: 'id',\n header: i18next.t('field.id'),\n hidden: true\n },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n align: 'left'\n },\n sortable: true,\n width: 160\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: {\n align: 'left'\n },\n sortable: true,\n width: 300\n }\n ]\n }\n }\n\n this.config = {\n ...this.config,\n list: {\n ...this.list,\n fields:\n this.list && this.list.fields && this.list.fields.length > 0\n ? this.list.fields\n : (this.config.columns as ColumnConfig[])\n .filter(column => column.type !== 'gutter')\n .slice(0, 3)\n .map(column => column.name)\n }\n }\n\n await this.updateComplete\n this.grist && this.grist.focus()\n }\n\n getSelectFields() {\n if (this.select && this.select.length > 0) {\n return `items {\n ${this.select.map(selectField => {\n return selectField.type === 'object'\n ? `${selectField.name} { ${\n selectField.subFields && selectField.subFields.length > 0\n ? selectField.subFields.join(' ')\n : `id name description`\n } }`\n : `${selectField.name}`\n })}\n }\n total`\n } else {\n return `\n items {\n id\n name\n description\n }\n total\n `\n }\n }\n\n async _buildConditions({ filters, page, limit, sorters, inherited }: FetchOption) {\n const queryConditions = {\n filters: [],\n ...this.basicArgs\n }\n\n queryConditions.filters = [...queryConditions.filters, ...(await this.searchForm.getQueryFilters())]\n queryConditions.pagination = { page, limit }\n queryConditions.sortings = sorters\n queryConditions.inherited = inherited\n\n return queryConditions\n }\n\n get selected() {\n var grist = this.renderRoot.querySelector('ox-grist') as DataGrist\n\n var selected = grist.selected\n\n return selected && selected.length > 0 ? selected[0] : undefined\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-selector-resource-object-legacy.js","sourceRoot":"","sources":["../../../src/selector/ox-selector-resource-object-legacy.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\nimport '@operato/form/ox-search-form.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport {\n ColumnConfig,\n DataGrist,\n FetchHandler,\n FetchOption,\n GristData,\n GristEventHandler,\n GristRecord,\n InheritedValueType,\n ZERO_DATA\n} from '@operato/data-grist'\nimport { MultiColumnFormStyles, OxSearchForm } from '@operato/form'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { isMobileDevice } from '@operato/utils'\nimport { CommonHeaderStyles } from '@operato/styles'\n\n@customElement('ox-selector-resource-object-legacy')\nexport class OxSelectorResourceObjectLegacy extends LitElement {\n static styles = [\n CommonHeaderStyles,\n MultiColumnFormStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n }\n\n ox-grist {\n flex: 1;\n }\n\n form {\n position: relative;\n }\n\n [search] {\n position: absolute;\n right: 0;\n }\n `\n ]\n\n @property({ type: String }) value?: string\n @property({ type: Object }) config: any\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: String }) queryName!: string\n @property({ type: Object }) basicArgs: any\n @property({ type: String }) inherited?: InheritedValueType = InheritedValueType.Include\n @property({ type: Object }) confirmCallback?: (record?: GristRecord | null) => void\n @property({ type: Array }) selectedRecords: GristRecord[] = []\n\n @property({ type: Array }) searchFields: any\n @property({ type: Array }) select: {\n type: string\n name: string\n header: string\n subFields?: string[]\n hidden: boolean\n ignoreCondition: boolean\n queryName: string\n width: number\n }[] = []\n @property({ type: Object }) list: any\n @property({ type: String }) valueField: string | ((item: any) => any) = 'id'\n\n @query('ox-grist') grist!: DataGrist\n @query('ox-search-form') searchForm!: OxSearchForm\n\n render() {\n return html`\n <ox-search-form\n id=\"search-form\"\n @keypress=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n this.grist.fetch()\n }\n }}\n @submit=${(e: SubmitEvent) => this.grist.fetch()}\n .fields=${this.searchFields}\n autofocus\n ></ox-search-form>\n\n <!--\n .data 를 넘기지 않는다 — 목록은 fetchHandler 가 채운다.\n\n 그 값은 늘 ZERO_DATA(빈 것)였다. 이 부품에 data 를 주는 부르는 쪽이 없다. 그리스트는\n data 가 설정되면 reset() 하므로(data-grist 의 updated), 이 부품이 **다시 그려지는 순간\n 목록이 통째로 사라진다.**\n\n 오늘은 안 터진다 — 이 부품에 다시 그릴 상태가 없다. 그러나 새 부품(ox-selector-resource-object)\n 에 바닥 단추를 고른 상태에 묶자마자 바로 터졌다. 넘길 값이 없으면서 넘기고 있던 것이므로\n 여기서도 걷는다. 남겨 두면 다음 사람이 같은 곳에 빠진다.\n\n [확인함] 2026-09-05 · 새 부품에서 라디오 클릭 → reset() 1회 → 20건 → 0건\n -->\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .selectedRecords=${this.selectedRecords}\n >\n <div slot=\"headroom\" id=\"headroom\">\n <div id=\"filters\">\n <ox-filters-form></ox-filters-form>\n </div>\n </div>\n </ox-grist>\n\n <div class=\"footer\">\n <button @click=${this.onEmpty.bind(this)}>\n <md-icon>check_box_outline_blank</md-icon>${i18next.t('button.empty')}\n </button>\n <div filler></div>\n <button @click=${this.onCancel.bind(this)}><md-icon>cancel</md-icon>${i18next.t('button.cancel')}</button>\n <button @click=${this.onConfirm.bind(this)}><md-icon>done</md-icon>${i18next.t('button.confirm')}</button>\n </div>\n `\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback()\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n this.confirmCallback && this.confirmCallback(this.selected)\n closePopup(this)\n }\n\n fetchHandler: FetchHandler = async ({ filters, page, limit, sorters = [], inherited }) => {\n const response = await client.query({\n query: gql`\n query($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $inherited: InheritedValueType) {\n fetch: ${\n this.queryName\n } (filters: $filters, pagination: $pagination, sortings: $sortings, inherited: $inherited)\n {\n ${this.getSelectFields()}\n }\n }\n `,\n variables: await this._buildConditions({ filters, page, limit, sorters, inherited: inherited || this.inherited })\n })\n\n if (!response.errors) {\n const records = response.data.fetch.items.map((item: any) => {\n let rowValue\n\n if (this.valueField && typeof this.valueField === 'function') {\n rowValue = this.valueField(item)\n } else if (this.valueField) {\n rowValue = item[this.valueField]\n } else {\n rowValue = item.id\n }\n\n if (this.value && this.value === rowValue) {\n this.selectedRecords = [item]\n item['__selected__'] = true\n }\n\n return item\n })\n const total = response.data.fetch.total\n\n return {\n records,\n total,\n limit,\n page\n }\n }\n }\n\n async firstUpdated() {\n this.config = {\n columns: [\n {\n type: 'gutter',\n gutterName: 'sequence'\n },\n {\n type: 'gutter',\n gutterName: 'row-selector',\n multiple: false\n }\n ],\n rows: {\n selectable: {\n multiple: false\n },\n handlers: {\n click: 'select-row',\n dblclick: ((columns, data, column, record, rowIndex, field) => {\n this.onConfirm()\n }) as GristEventHandler\n },\n appendable: false\n }\n }\n\n if (this.select && this.select.length > 0) {\n let _searchFields = this.select.filter(selectField => !selectField.hidden && !selectField.ignoreCondition)\n if (this.list && this.list.fields && this.list.fields.length > 0) {\n _searchFields = _searchFields.filter(searchField => this.list.fields.indexOf(searchField.name) >= 0)\n } else {\n _searchFields = _searchFields.slice(0, 4)\n }\n\n this.searchFields = _searchFields.map(selectField => {\n const fieldType = (selectField.type && selectField.type.toLowerCase()) || 'string'\n const numberTypes = ['integer', 'float']\n return {\n label: selectField.header || i18next.t(`field.${selectField.name}`),\n name: selectField.name,\n type:\n fieldType === 'string'\n ? 'text'\n : numberTypes.indexOf(fieldType) >= 0\n ? 'number'\n : fieldType === 'boolean'\n ? 'checkbox'\n : fieldType,\n queryName: selectField.queryName,\n props:\n fieldType === 'string'\n ? { searchOper: 'i_like' }\n : fieldType === 'object'\n ? { searchOper: 'in' }\n : { searchOper: 'eq' },\n attrs: fieldType === 'boolean' ? ['indeterminated'] : []\n }\n })\n this.config = {\n ...this.config,\n columns: [\n ...this.config.columns,\n ...this.select.map(selectField => {\n return {\n ...selectField,\n type: selectField.type || 'string',\n width: selectField.width || 160,\n header: selectField.header || i18next.t(`field.${selectField.name}`)\n }\n })\n ]\n }\n } else {\n this.searchFields = [\n {\n label: i18next.t('field.name'),\n name: 'name',\n type: 'text',\n props: { searchOper: 'i_like' }\n },\n {\n label: i18next.t('field.description'),\n name: 'description',\n type: 'text',\n props: { searchOper: 'i_like' }\n }\n ]\n\n this.config = {\n ...this.config,\n columns: [\n ...this.config.columns,\n {\n type: 'string',\n name: 'id',\n header: i18next.t('field.id'),\n hidden: true\n },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n align: 'left'\n },\n sortable: true,\n width: 160\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: {\n align: 'left'\n },\n sortable: true,\n width: 300\n }\n ]\n }\n }\n\n this.config = {\n ...this.config,\n list: {\n ...this.list,\n fields:\n this.list && this.list.fields && this.list.fields.length > 0\n ? this.list.fields\n : (this.config.columns as ColumnConfig[])\n .filter(column => column.type !== 'gutter')\n .slice(0, 3)\n .map(column => column.name)\n }\n }\n\n await this.updateComplete\n this.grist && this.grist.focus()\n }\n\n getSelectFields() {\n if (this.select && this.select.length > 0) {\n return `items {\n ${this.select.map(selectField => {\n return selectField.type === 'object'\n ? `${selectField.name} { ${\n selectField.subFields && selectField.subFields.length > 0\n ? selectField.subFields.join(' ')\n : `id name description`\n } }`\n : `${selectField.name}`\n })}\n }\n total`\n } else {\n return `\n items {\n id\n name\n description\n }\n total\n `\n }\n }\n\n async _buildConditions({ filters, page, limit, sorters, inherited }: FetchOption) {\n const queryConditions = {\n filters: [],\n ...this.basicArgs\n }\n\n queryConditions.filters = [...queryConditions.filters, ...(await this.searchForm.getQueryFilters())]\n queryConditions.pagination = { page, limit }\n queryConditions.sortings = sorters\n queryConditions.inherited = inherited\n\n return queryConditions\n }\n\n get selected() {\n var grist = this.renderRoot.querySelector('ox-grist') as DataGrist\n\n var selected = grist.selected\n\n return selected && selected.length > 0 ? selected[0] : undefined\n }\n}\n"]}
|
|
@@ -125,7 +125,7 @@ let OxSelectorResourceObject = class OxSelectorResourceObject extends LitElement
|
|
|
125
125
|
단추를 고른 상태에 묶으면서(hasSelection) 비로소 다시 그려지게 되었고, 그때 줄을
|
|
126
126
|
누르면 목록이 비었다.
|
|
127
127
|
|
|
128
|
-
[
|
|
128
|
+
[확인함] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건
|
|
129
129
|
|
|
130
130
|
고른 상태를 되돌리는 것이 아니라 **이 바인딩을 걷는다.** 넘길 값이 없으면서 넘기고
|
|
131
131
|
있던 것이고, 남겨 두면 다음 사람이 같은 곳에 빠진다.
|
|
@@ -237,7 +237,7 @@ let OxSelectorResourceObject = class OxSelectorResourceObject extends LitElement
|
|
|
237
237
|
* 이것이 조용한 데이터 손실로 이어졌다. 고른 표시는 목록을 받아올 때 **그 쪽에서 값을 찾으면**
|
|
238
238
|
* 켜지므로(아래 fetchHandler), 값이 2쪽에 있으면 1쪽만 받은 상태에서는 빈 채다.
|
|
239
239
|
*
|
|
240
|
-
* [
|
|
240
|
+
* [확인함] 2026-09-05 · 제조법 · 만드는 품목 · 총 106건
|
|
241
241
|
* value=MT10097283 은 1쪽에 없다 → selectedRecords = []
|
|
242
242
|
* 팝업을 열고 아무것도 만지지 않고 확인 → 칸이 빈 값이 되었다
|
|
243
243
|
*
|
|
@@ -474,7 +474,7 @@ OxSelectorResourceObject.styles = [
|
|
|
474
474
|
* 강조가 되지 않았다. 강조 잉크는 --ui-accent 이고, 그 색은 **작은 글자를 담을 수 있도록
|
|
475
475
|
* 톤을 낮춰 둔** 것이다.
|
|
476
476
|
*
|
|
477
|
-
* [
|
|
477
|
+
* [확인함] 2026-09-05 · --ui-accent #0c7a4c · 팝업 면 #f0f2f4 · 대비 4.79
|
|
478
478
|
* 작은 글자 기준 4.5 를 넘는다
|
|
479
479
|
*
|
|
480
480
|
* accent 가 없는 앱에서는 primary 로 떨어진다.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-selector-resource-object.js","sourceRoot":"","sources":["../../../src/selector/ox-selector-resource-object.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport {\n DataGrist,\n FetchHandler,\n GristData,\n GristEventHandler,\n GristRecord,\n ZERO_DATA,\n InheritedValueType\n} from '@operato/data-grist'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { adjustFilters, isMobileDevice } from '@operato/utils'\nimport { ButtonContainerStyles, CommonHeaderStyles } from '@operato/styles'\n\n@customElement('ox-selector-resource-object')\nexport class OxSelectorResourceObject extends LitElement {\n static styles = [\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n\n width: var(--overlay-center-normal-width, 50%);\n height: var(--overlay-center-normal-height, 50%);\n }\n\n ox-grist {\n flex: 1;\n }\n\n .header {\n grid-template-areas: 'filters actions';\n }\n\n [filler] {\n margin-left: auto;\n }\n\n /*\n * 꺼진 단추가 왜 꺼졌는지 말하는 한 줄. **단추 바로 앞에 선다** — 멀리 두면 그 단추의\n * 이야기로 읽히지 않는다.\n *\n * ── 색만 조금 세운다 ──────────────────────────────────────────────────\n * on-surface-variant 로 두었더니 너무 조용했다. 꺼진 단추 옆의 흐린 글자는 그 단추의\n * 일부처럼 보여서, 확인이 왜 꺼졌는지 찾는 눈에 걸리지 않았다.\n *\n * 크기와 배치는 그대로 두고 **잉크만** 바꾼다. 붉은색은 오류이고, 이것은 오류가 아니라\n * 남은 일이다.\n *\n * primary 를 먼저 써 봤는데 이 제품에서는 **흑연**이다(#262e38) — 틀 자체가 무채색이라\n * 강조가 되지 않았다. 강조 잉크는 --ui-accent 이고, 그 색은 **작은 글자를 담을 수 있도록\n * 톤을 낮춰 둔** 것이다.\n *\n * [재봤음] 2026-09-05 · --ui-accent #0c7a4c · 팝업 면 #f0f2f4 · 대비 4.79\n * 작은 글자 기준 4.5 를 넘는다\n *\n * accent 가 없는 앱에서는 primary 로 떨어진다.\n */\n [hint] {\n color: var(--ui-accent, var(--md-sys-color-primary));\n font-size: var(--md-sys-typescale-label-medium-size, 0.75rem);\n margin-right: var(--spacing-small, 4px);\n }\n `\n ]\n\n /**\n * 지금 들어 있는 값. **여럿 고르기에서는 배열이다.**\n *\n * 목록을 받아올 때 이 값과 같은 줄을 골라 둔다(fetchHandler). 그래서 팝업을 열면 지금 값이\n * 이미 고른 상태로 보인다.\n */\n @property({ type: Object }) value?: string | string[]\n\n /**\n * 여럿을 고를 수 있나. **부르는 쪽이 켠다.**\n *\n * ── 왜 필요한가 (2026-09-05) ────────────────────────────────────────────\n * 마스터 화면의 관계 칸 다섯이 여러 값을 든다 — 상위 등급(baseIds) · 요구 검사\n * (testSpecificationIds) · 공정의 차례(steps). 이 선택기가 하나만 내주어서 그 칸들이\n * **자유 텍스트로 남아 있었다.**\n *\n * 자유 텍스트는 조용히 틀린다. GUNSAN 을 GUNSAM 이라고 쳐도 저장되고, 그 뒤로 그 참조는\n * 어디에서도 안 걸린다 — 화면에는 값이 있는데.\n *\n * ── 켜면 무엇이 달라지나 ────────────────────────────────────────────────\n * 고르기 줄을 눌러 켜고 끈다(select-row-toggle). 겹쳐 고를 수 있다\n * 두 번 누르기 확정하지 않는다 — 한 줄만 넘기게 되므로\n * confirmCallback 고른 것들의 배열을 넘긴다\n *\n * 켠 쪽이 그 모양을 아니까 콜백을 둘로 나누지 않는다.\n */\n @property({ type: Boolean }) multiple: boolean = false\n @property({ type: Object }) config: any\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: String }) queryName!: string\n @property({ type: Object }) basicArgs: any\n @property({ type: String }) inherited?: InheritedValueType = InheritedValueType.Include\n @property({ type: Object }) confirmCallback?: (record?: Partial<GristRecord>) => void\n @property({ type: Array }) selectedRecords: GristRecord[] = []\n\n @property({ type: Array }) searchFields: any\n @property({ type: Array }) columns: {\n type: string\n name: string\n header: string\n subFields?: string[]\n hidden: boolean\n queryName: string\n width: number\n }[] = []\n @property({ type: Object }) pagination?: {\n limit: number\n pages: number[]\n }\n @property({ type: Object }) list: any\n @property({ type: String }) valueField: string | ((item: any) => any) = 'id'\n\n /** 설정을 한 번 세웠나 — 열·질의가 바뀔 때만 다시 세운다. */\n private _configured = false\n\n /**\n * 지금 고른 것이 있나 — **바닥 단추가 이 값을 본다.**\n *\n * `selected` 게터는 그리스트를 그때그때 읽으므로 반응형이 아니다. 그래서 단추의 disabled 를\n * 그것으로 묶으면 골라도 다시 그려지지 않는다. 그리스트가 내는 select-record-change 를 듣고\n * 이 상태를 갱신한다.\n */\n @state() private hasSelection = false\n\n @query('ox-grist') grist!: DataGrist\n\n render() {\n return html`\n <!--\n ── .data 를 넘기지 않는다 ────────────────────────────────────────────────\n\n 목록은 아래 fetchHandler 가 채운다. 그런데 .data 로 this.data 를 함께 넘기고\n 있었고, 그 값은 늘 ZERO_DATA(빈 것)였다 — 이 부품에 data 를 주는 부르는 쪽이 없다.\n\n 그리스트는 data 가 설정되면 **reset() 한다**(data-grist 의 updated). 그래서 이 부품이\n 다시 그려지는 순간 빈 값이 다시 내려가 **목록이 통째로 사라진다.**\n\n 여태 안 드러난 이유는 이 부품이 첫 렌더 뒤로 다시 그려질 일이 없었기 때문이다. 바닥\n 단추를 고른 상태에 묶으면서(hasSelection) 비로소 다시 그려지게 되었고, 그때 줄을\n 누르면 목록이 비었다.\n\n [재봤음] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건\n\n 고른 상태를 되돌리는 것이 아니라 **이 바인딩을 걷는다.** 넘길 값이 없으면서 넘기고\n 있던 것이고, 남겨 두면 다음 사람이 같은 곳에 빠진다.\n -->\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .selectedRecords=${this.selectedRecords}\n @select-record-change=${() => {\n this.hasSelection = (this.grist?.selected || []).length > 0\n }}\n >\n <div class=\"header\" slot=\"headroom\">\n <div class=\"filters\">\n <!--\n **검색은 이 영역이 그리지 않는다.**\n 찾기는 화면의 제목줄이 든다(페이지의 표준이 그렇다 — 제목 왼쪽, 찾기 오른쪽 끝).\n 여기서도 그리면 검색창이 둘이 된다. 실제로 한 번 그렇게 됐다.\n\n 이 영역은 **찾기가 아닌 필터**의 자리다. 그것이 하나도 없으면 아래 hideHeadroom 이\n 영역째 감춘다 — 열 것이 없는 문을 두지 않는다.\n -->\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </div>\n </ox-grist>\n\n <!--\n 바닥 — **세 동작의 무게가 다르다.**\n\n 지정 안 함 이 칸에 아무것도 넣지 않는다. 왼쪽 끝에 따로 선다 — 확정과 나란히 두면 잘못 누른다\n 닫기 아무것도 하지 않고 나간다. 글자만\n 확인 이 팝업이 하러 온 일. 하나만 채운다\n\n 아이콘을 떼었다. 「비우기」에는 체크박스 글리프가 붙어 있었는데, 그것은 **입력칸의\n 글리프**여서 동작이 아니라 「끄고 켜는 것」으로 읽혔다. 닫기의 ⊗ 와 확인의 ✓ 도 걷는다 —\n 낱말이 이미 그 일을 말하고, 곁 단추에 아이콘이 붙으면 무게가 주 동작과 비슷해진다.\n -->\n <div class=\"footer\">\n <!--\n 「비우기」였다. **무엇을** 비우는지 말하지 않는다 — 팝업 안에 목록도 검색창도 있어서\n 「목록을 비우나」로도 읽힌다. 이 단추가 하는 일은 그 칸을 빈 값으로 두고 닫는 것이다.\n\n button.empty 를 그대로 쓰지 않는 이유: 그 문자열은 여러 개를 고르는 팝업들도 함께 쓴다\n (결재자 · 수신자 편집기). 거기서는 「고른 것 전부 지우기」이고, 그것은 「지정 안 함」과\n 다른 말이다. 한 문자열이 두 뜻을 겸하고 있었다.\n -->\n <button @click=${this.onEmpty.bind(this)} clear>${i18next.t('button.unset')}</button>\n\n <div filler></div>\n\n <!--\n 힌트는 **단추 두 개 앞**에 선다. 닫기와 확인은 한 쌍이라, 그 사이에 글자가 끼면\n 쌍이 갈라져 보인다.\n -->\n ${!this.hasSelection\n ? html`<span hint\n >${i18next.t(this.multiple ? 'text.pick-from-the-list' : 'text.pick-one-from-the-list')}</span\n >`\n : ''}\n <button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</button>\n <!--\n ── 고른 것이 없으면 **확인을 끄고, 왜 껐는지 말한다** ─────────────────\n\n 꺼진 단추만 두면 막다른 길이다. 누른 사람은 「왜 안 되나」를 알 길이 없고, 특히 이\n 팝업은 목록이 여러 쪽이라 자기가 무엇을 안 했는지 스스로 떠올리기 어렵다.\n\n 그래서 한 줄을 함께 둔다. **고르면 사라진다** — 할 일이 남아 있는 동안만 보인다.\n\n ── 그 앞에는 더 나빴다 ────────────────────────────────────────────────\n 고른 것이 없을 때 확인이 **값을 지웠다**. 확인이 「지정 안 함」과 같은 일을 했다\n (onConfirm 주석 참조).\n -->\n <button\n @click=${this.onConfirm.bind(this)}\n ?disabled=${!this.hasSelection}\n title=${!this.hasSelection ? i18next.t('text.pick-one-from-the-list') : ''}\n done\n >\n ${i18next.t('button.confirm')}\n </button>\n </div>\n `\n }\n\n searchText(value: string) {\n this.grist.searchText = value\n }\n\n toggleFilter() {\n this.grist.toggleHeadroom()\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback()\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n const selected = this.selected\n\n /*\n * ── 고른 것이 없으면 **아무 일도 하지 않는다** ────────────────────────────\n *\n * 전에는 `confirmCallback(this.selected)` 를 그냥 불렀다. 고른 것이 없으면 `selected` 가\n * undefined 이고, 그것은 **아래 onEmpty 가 넘기는 것과 똑같다** — 즉 확인이 「지정 안 함」과\n * 같은 일을 했다. 값을 지우는 단추가 둘이었고, 그중 하나가 주 동작(채운 단추)이었다.\n *\n * 이것이 조용한 데이터 손실로 이어졌다. 고른 표시는 목록을 받아올 때 **그 쪽에서 값을 찾으면**\n * 켜지므로(아래 fetchHandler), 값이 2쪽에 있으면 1쪽만 받은 상태에서는 빈 채다.\n *\n * [재봤음] 2026-09-05 · 제조법 · 만드는 품목 · 총 106건\n * value=MT10097283 은 1쪽에 없다 → selectedRecords = []\n * 팝업을 열고 아무것도 만지지 않고 확인 → 칸이 빈 값이 되었다\n *\n * 확인의 뜻은 「이 고른 것으로 한다」다. 고른 것이 없으면 확인할 것이 없으므로 닫기와 같다.\n * **값을 지우는 길은 「지정 안 함」 하나다.**\n */\n if (!selected || (Array.isArray(selected) && selected.length === 0)) {\n closePopup(this)\n return\n }\n\n this.confirmCallback && this.confirmCallback(selected)\n closePopup(this)\n }\n\n fetchHandler: FetchHandler = async ({ filters = [], page, limit, sortings = [], inherited }) => {\n if (this.basicArgs?.filters) {\n filters = adjustFilters(filters, this.basicArgs.filters)\n }\n // basicArgs.sorters가 있으면 기본 정렬로 병합\n if (this.basicArgs?.sorters && sortings.length === 0) {\n sortings = [...this.basicArgs.sorters]\n }\n const pagination = { page, limit }\n\n const response = await client.query({\n query: gql`\n query($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $inherited: InheritedValueType) {\n fetch: ${\n this.queryName\n } (filters: $filters, pagination: $pagination, sortings: $sortings, inherited: $inherited) {\n ${this.getQueryFields()}\n }\n }\n `,\n variables: {\n filters,\n pagination,\n sortings,\n inherited: inherited || this.inherited\n },\n context: gqlContext()\n })\n\n if (!response.errors) {\n const records = response.data.fetch.items.map((item: any) => {\n let rowValue\n\n if (this.valueField && typeof this.valueField === 'function') {\n rowValue = this.valueField(item)\n } else if (this.valueField) {\n rowValue = item[this.valueField]\n } else {\n rowValue = item.id\n }\n\n /*\n * 지금 값과 같은 줄을 골라 둔다. 여럿 고르기에서는 값이 배열이므로 그 안에 있는지 본다.\n *\n * 값이 이 쪽에 없으면 골라지지 않는다 — 그것이 이 부품의 한계다. 부르는 쪽이 지금 값을\n * 글자로 함께 보여 주는 이유가 그것이다(ops-master 의 참조 팝업).\n */\n const wanted = Array.isArray(this.value) ? this.value : this.value ? [this.value] : []\n\n if (wanted.length && wanted.includes(rowValue)) {\n this.selectedRecords = this.multiple ? [...this.selectedRecords, item] : [item]\n item['__selected__'] = true\n /* 받아온 쪽에서 값을 찾았다 — 바닥 단추도 그것을 알아야 한다. */\n this.hasSelection = true\n }\n\n return item\n })\n const total = response.data.fetch.total\n\n return {\n records,\n total,\n limit,\n page\n }\n }\n }\n\n /**\n * 표의 설정을 **첫 렌더 전에** 세운다.\n *\n * ── 왜 firstUpdated 가 아닌가 ──────────────────────────────────────────────\n * 여기 있던 것을 `firstUpdated` 에서 만들고 있었다. 그러면 `<ox-grist>` 와 그 안의 필터 폼이\n * **먼저 붙고** 설정이 나중에 온다. 필터 폼은 붙는 순간의 설정을 한 번 읽어 두므로, 그 스냅숏이\n * 병합 전 것이었다 — 열 일곱 개 중 넷만 든 설정이라 필터가 하나도 없었고, 그래서 필터 영역이\n * 빈 채로 32px 만 서 있었다.\n *\n * `willUpdate` 는 렌더 전에 돈다. 폼이 붙을 때 이미 완성된 설정을 읽는다.\n */\n willUpdate(changed: PropertyValues<this>) {\n /* 열·질의가 바뀌면 다시 세운다. 그 밖의 변화에는 손대지 않는다. */\n /* multiple 이 바뀌면 거터와 고르기 규칙이 달라지므로 설정을 다시 세운다. */\n if (\n this._configured &&\n !changed.has('columns') &&\n !changed.has('queryName') &&\n !changed.has('list') &&\n !changed.has('multiple')\n ) {\n return\n }\n\n this._configured = true\n\n const config = {\n list: this.list,\n columns: [\n {\n type: 'gutter',\n gutterName: 'sequence'\n },\n {\n type: 'gutter',\n gutterName: 'row-selector',\n multiple: this.multiple\n }\n ],\n rows: {\n selectable: {\n multiple: this.multiple\n },\n handlers: {\n /*\n * 하나만 고를 때는 누르면 그 줄로 바뀐다. 여럿일 때는 눌러 켜고 끈다 — 앞의 것을\n * 풀면서 고르면 여러 개를 담을 수 없다.\n */\n click: this.multiple ? 'select-row-toggle' : 'select-row',\n /*\n * 두 번 눌러 확정하는 것은 하나만 고를 때다. 여럿일 때 그렇게 두면 **그 한 줄만**\n * 넘어가고 앞서 고른 것이 사라진다.\n */\n ...(this.multiple\n ? {}\n : {\n dblclick: ((columns, data, column, record, rowIndex, field) => {\n this.onConfirm()\n }) as GristEventHandler\n })\n },\n appendable: false\n },\n pagination: this.pagination\n }\n\n const columns = this.columns || [\n {\n type: 'string',\n name: 'id',\n header: i18next.t('field.id'),\n hidden: true\n },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n align: 'left'\n },\n sortable: true,\n filter: 'search',\n width: 160\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: {\n align: 'left'\n },\n sortable: true,\n filter: 'search',\n /*\n * 남는 폭을 이 열이 채운다.\n *\n * 열 폭은 grid-template-columns 에 그대로 들어가므로 문자열도 된다(data-grist 의\n * setGridTemplateColumns). 고정 300px 이었을 때는 오른쪽에 200px 가까운 죽은 자리와\n * 세로선 하나가 남았다 — 목록이 상자 한쪽에 몰려 보인다.\n */\n width: 'minmax(240px, 1fr)'\n }\n ]\n\n /*\n * **밖에서 준 설정을 덮어쓰지 않는다.**\n *\n * 여기서 `this.config` 를 통째로 갈아 끼우고 있었다. 그래서 부르는 쪽이 `config` 를 주어도\n * 사라졌다 — 빈 목록에 무슨 말을 할지(`emptyNote`)를 밖에서 정할 길이 없었다.\n *\n * 빈 목록은 **두 가지 다른 사실**을 말해야 하는 자리다. 「이 표에 아직 아무것도 없다」와\n * 「검색에 걸린 것이 없다」는 다르고, 하나로 합치면 결함이 「고를 게 없다」로 보인다. 실제로\n * 그런 일이 있었다(배열 모양이 달라 목록이 비었는데 아무도 결함인 줄 몰랐다).\n */\n const given = this.config || {}\n\n this.config = {\n ...config,\n ...given,\n columns: [\n ...config.columns,\n ...columns.map(selectField => {\n return {\n ...selectField,\n type: selectField.type || 'string',\n width: selectField.width || 160,\n header: selectField.header || i18next.t(`field.${selectField.name}`)\n }\n })\n ]\n }\n\n /*\n * 걸러 볼 것이 하나도 없으면 그 영역을 감춘다.\n *\n * **병합된 설정으로 판단한다.** 전에는 밖에서 받은 `columns` 만 보았는데, 기본 열(이름·설명)이\n * 이미 검색 필터를 갖고 있어서 그 판단이 실제와 달랐다.\n */\n requestAnimationFrame(() => {\n /*\n * **찾기가 아닌 필터**가 하나라도 있나로 판단한다. 찾기는 이 영역이 안 그리므로(위 주석),\n * `search` 형 필터만 있는 표에서는 여기 그릴 것이 없다.\n */\n const filterable = this.config.columns.some((column: any) => {\n const filter = column.filter\n return filter && filter !== 'search' && filter?.operator !== 'search'\n })\n\n if (!filterable) {\n this.grist?.hideHeadroom()\n }\n })\n }\n\n getQueryFields() {\n if (this.columns && this.columns.length > 0) {\n return `items {\n ${this.columns.map(selectField => {\n return selectField.type === 'object'\n ? `${selectField.name} { ${\n selectField.subFields && selectField.subFields.length > 0\n ? selectField.subFields.join(' ')\n : `id name description`\n } }`\n : `${selectField.name}`\n })}\n }\n total`\n } else {\n return `\n items {\n id\n name\n description\n }\n total\n `\n }\n }\n\n /**\n * 고른 것. **여럿 고르기에서는 배열이고, 아니면 하나다.**\n *\n * 켠 쪽이 그 모양을 아니까 두 가지를 한 자리에서 낸다.\n */\n get selected(): any {\n var grist = this.renderRoot.querySelector('ox-grist') as DataGrist\n\n var selected = grist.selected || []\n\n if (this.multiple) {\n return selected\n }\n\n return selected.length > 0 ? selected[0] : undefined\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-selector-resource-object.js","sourceRoot":"","sources":["../../../src/selector/ox-selector-resource-object.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/data-grist'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport {\n DataGrist,\n FetchHandler,\n GristData,\n GristEventHandler,\n GristRecord,\n ZERO_DATA,\n InheritedValueType\n} from '@operato/data-grist'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { closePopup } from '@operato/popup'\nimport { adjustFilters, isMobileDevice } from '@operato/utils'\nimport { ButtonContainerStyles, CommonHeaderStyles } from '@operato/styles'\n\n@customElement('ox-selector-resource-object')\nexport class OxSelectorResourceObject extends LitElement {\n static styles = [\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: var(--md-sys-color-surface);\n\n width: var(--overlay-center-normal-width, 50%);\n height: var(--overlay-center-normal-height, 50%);\n }\n\n ox-grist {\n flex: 1;\n }\n\n .header {\n grid-template-areas: 'filters actions';\n }\n\n [filler] {\n margin-left: auto;\n }\n\n /*\n * 꺼진 단추가 왜 꺼졌는지 말하는 한 줄. **단추 바로 앞에 선다** — 멀리 두면 그 단추의\n * 이야기로 읽히지 않는다.\n *\n * ── 색만 조금 세운다 ──────────────────────────────────────────────────\n * on-surface-variant 로 두었더니 너무 조용했다. 꺼진 단추 옆의 흐린 글자는 그 단추의\n * 일부처럼 보여서, 확인이 왜 꺼졌는지 찾는 눈에 걸리지 않았다.\n *\n * 크기와 배치는 그대로 두고 **잉크만** 바꾼다. 붉은색은 오류이고, 이것은 오류가 아니라\n * 남은 일이다.\n *\n * primary 를 먼저 써 봤는데 이 제품에서는 **흑연**이다(#262e38) — 틀 자체가 무채색이라\n * 강조가 되지 않았다. 강조 잉크는 --ui-accent 이고, 그 색은 **작은 글자를 담을 수 있도록\n * 톤을 낮춰 둔** 것이다.\n *\n * [확인함] 2026-09-05 · --ui-accent #0c7a4c · 팝업 면 #f0f2f4 · 대비 4.79\n * 작은 글자 기준 4.5 를 넘는다\n *\n * accent 가 없는 앱에서는 primary 로 떨어진다.\n */\n [hint] {\n color: var(--ui-accent, var(--md-sys-color-primary));\n font-size: var(--md-sys-typescale-label-medium-size, 0.75rem);\n margin-right: var(--spacing-small, 4px);\n }\n `\n ]\n\n /**\n * 지금 들어 있는 값. **여럿 고르기에서는 배열이다.**\n *\n * 목록을 받아올 때 이 값과 같은 줄을 골라 둔다(fetchHandler). 그래서 팝업을 열면 지금 값이\n * 이미 고른 상태로 보인다.\n */\n @property({ type: Object }) value?: string | string[]\n\n /**\n * 여럿을 고를 수 있나. **부르는 쪽이 켠다.**\n *\n * ── 왜 필요한가 (2026-09-05) ────────────────────────────────────────────\n * 마스터 화면의 관계 칸 다섯이 여러 값을 든다 — 상위 등급(baseIds) · 요구 검사\n * (testSpecificationIds) · 공정의 차례(steps). 이 선택기가 하나만 내주어서 그 칸들이\n * **자유 텍스트로 남아 있었다.**\n *\n * 자유 텍스트는 조용히 틀린다. GUNSAN 을 GUNSAM 이라고 쳐도 저장되고, 그 뒤로 그 참조는\n * 어디에서도 안 걸린다 — 화면에는 값이 있는데.\n *\n * ── 켜면 무엇이 달라지나 ────────────────────────────────────────────────\n * 고르기 줄을 눌러 켜고 끈다(select-row-toggle). 겹쳐 고를 수 있다\n * 두 번 누르기 확정하지 않는다 — 한 줄만 넘기게 되므로\n * confirmCallback 고른 것들의 배열을 넘긴다\n *\n * 켠 쪽이 그 모양을 아니까 콜백을 둘로 나누지 않는다.\n */\n @property({ type: Boolean }) multiple: boolean = false\n @property({ type: Object }) config: any\n @property({ type: Object }) data: GristData = ZERO_DATA\n @property({ type: String }) queryName!: string\n @property({ type: Object }) basicArgs: any\n @property({ type: String }) inherited?: InheritedValueType = InheritedValueType.Include\n @property({ type: Object }) confirmCallback?: (record?: Partial<GristRecord>) => void\n @property({ type: Array }) selectedRecords: GristRecord[] = []\n\n @property({ type: Array }) searchFields: any\n @property({ type: Array }) columns: {\n type: string\n name: string\n header: string\n subFields?: string[]\n hidden: boolean\n queryName: string\n width: number\n }[] = []\n @property({ type: Object }) pagination?: {\n limit: number\n pages: number[]\n }\n @property({ type: Object }) list: any\n @property({ type: String }) valueField: string | ((item: any) => any) = 'id'\n\n /** 설정을 한 번 세웠나 — 열·질의가 바뀔 때만 다시 세운다. */\n private _configured = false\n\n /**\n * 지금 고른 것이 있나 — **바닥 단추가 이 값을 본다.**\n *\n * `selected` 게터는 그리스트를 그때그때 읽으므로 반응형이 아니다. 그래서 단추의 disabled 를\n * 그것으로 묶으면 골라도 다시 그려지지 않는다. 그리스트가 내는 select-record-change 를 듣고\n * 이 상태를 갱신한다.\n */\n @state() private hasSelection = false\n\n @query('ox-grist') grist!: DataGrist\n\n render() {\n return html`\n <!--\n ── .data 를 넘기지 않는다 ────────────────────────────────────────────────\n\n 목록은 아래 fetchHandler 가 채운다. 그런데 .data 로 this.data 를 함께 넘기고\n 있었고, 그 값은 늘 ZERO_DATA(빈 것)였다 — 이 부품에 data 를 주는 부르는 쪽이 없다.\n\n 그리스트는 data 가 설정되면 **reset() 한다**(data-grist 의 updated). 그래서 이 부품이\n 다시 그려지는 순간 빈 값이 다시 내려가 **목록이 통째로 사라진다.**\n\n 여태 안 드러난 이유는 이 부품이 첫 렌더 뒤로 다시 그려질 일이 없었기 때문이다. 바닥\n 단추를 고른 상태에 묶으면서(hasSelection) 비로소 다시 그려지게 되었고, 그때 줄을\n 누르면 목록이 비었다.\n\n [확인함] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건\n\n 고른 상태를 되돌리는 것이 아니라 **이 바인딩을 걷는다.** 넘길 값이 없으면서 넘기고\n 있던 것이고, 남겨 두면 다음 사람이 같은 곳에 빠진다.\n -->\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .selectedRecords=${this.selectedRecords}\n @select-record-change=${() => {\n this.hasSelection = (this.grist?.selected || []).length > 0\n }}\n >\n <div class=\"header\" slot=\"headroom\">\n <div class=\"filters\">\n <!--\n **검색은 이 영역이 그리지 않는다.**\n 찾기는 화면의 제목줄이 든다(페이지의 표준이 그렇다 — 제목 왼쪽, 찾기 오른쪽 끝).\n 여기서도 그리면 검색창이 둘이 된다. 실제로 한 번 그렇게 됐다.\n\n 이 영역은 **찾기가 아닌 필터**의 자리다. 그것이 하나도 없으면 아래 hideHeadroom 이\n 영역째 감춘다 — 열 것이 없는 문을 두지 않는다.\n -->\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </div>\n </ox-grist>\n\n <!--\n 바닥 — **세 동작의 무게가 다르다.**\n\n 지정 안 함 이 칸에 아무것도 넣지 않는다. 왼쪽 끝에 따로 선다 — 확정과 나란히 두면 잘못 누른다\n 닫기 아무것도 하지 않고 나간다. 글자만\n 확인 이 팝업이 하러 온 일. 하나만 채운다\n\n 아이콘을 떼었다. 「비우기」에는 체크박스 글리프가 붙어 있었는데, 그것은 **입력칸의\n 글리프**여서 동작이 아니라 「끄고 켜는 것」으로 읽혔다. 닫기의 ⊗ 와 확인의 ✓ 도 걷는다 —\n 낱말이 이미 그 일을 말하고, 곁 단추에 아이콘이 붙으면 무게가 주 동작과 비슷해진다.\n -->\n <div class=\"footer\">\n <!--\n 「비우기」였다. **무엇을** 비우는지 말하지 않는다 — 팝업 안에 목록도 검색창도 있어서\n 「목록을 비우나」로도 읽힌다. 이 단추가 하는 일은 그 칸을 빈 값으로 두고 닫는 것이다.\n\n button.empty 를 그대로 쓰지 않는 이유: 그 문자열은 여러 개를 고르는 팝업들도 함께 쓴다\n (결재자 · 수신자 편집기). 거기서는 「고른 것 전부 지우기」이고, 그것은 「지정 안 함」과\n 다른 말이다. 한 문자열이 두 뜻을 겸하고 있었다.\n -->\n <button @click=${this.onEmpty.bind(this)} clear>${i18next.t('button.unset')}</button>\n\n <div filler></div>\n\n <!--\n 힌트는 **단추 두 개 앞**에 선다. 닫기와 확인은 한 쌍이라, 그 사이에 글자가 끼면\n 쌍이 갈라져 보인다.\n -->\n ${!this.hasSelection\n ? html`<span hint\n >${i18next.t(this.multiple ? 'text.pick-from-the-list' : 'text.pick-one-from-the-list')}</span\n >`\n : ''}\n <button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</button>\n <!--\n ── 고른 것이 없으면 **확인을 끄고, 왜 껐는지 말한다** ─────────────────\n\n 꺼진 단추만 두면 막다른 길이다. 누른 사람은 「왜 안 되나」를 알 길이 없고, 특히 이\n 팝업은 목록이 여러 쪽이라 자기가 무엇을 안 했는지 스스로 떠올리기 어렵다.\n\n 그래서 한 줄을 함께 둔다. **고르면 사라진다** — 할 일이 남아 있는 동안만 보인다.\n\n ── 그 앞에는 더 나빴다 ────────────────────────────────────────────────\n 고른 것이 없을 때 확인이 **값을 지웠다**. 확인이 「지정 안 함」과 같은 일을 했다\n (onConfirm 주석 참조).\n -->\n <button\n @click=${this.onConfirm.bind(this)}\n ?disabled=${!this.hasSelection}\n title=${!this.hasSelection ? i18next.t('text.pick-one-from-the-list') : ''}\n done\n >\n ${i18next.t('button.confirm')}\n </button>\n </div>\n `\n }\n\n searchText(value: string) {\n this.grist.searchText = value\n }\n\n toggleFilter() {\n this.grist.toggleHeadroom()\n }\n\n onEmpty() {\n this.confirmCallback && this.confirmCallback()\n closePopup(this)\n }\n\n onCancel() {\n closePopup(this)\n }\n\n onConfirm() {\n const selected = this.selected\n\n /*\n * ── 고른 것이 없으면 **아무 일도 하지 않는다** ────────────────────────────\n *\n * 전에는 `confirmCallback(this.selected)` 를 그냥 불렀다. 고른 것이 없으면 `selected` 가\n * undefined 이고, 그것은 **아래 onEmpty 가 넘기는 것과 똑같다** — 즉 확인이 「지정 안 함」과\n * 같은 일을 했다. 값을 지우는 단추가 둘이었고, 그중 하나가 주 동작(채운 단추)이었다.\n *\n * 이것이 조용한 데이터 손실로 이어졌다. 고른 표시는 목록을 받아올 때 **그 쪽에서 값을 찾으면**\n * 켜지므로(아래 fetchHandler), 값이 2쪽에 있으면 1쪽만 받은 상태에서는 빈 채다.\n *\n * [확인함] 2026-09-05 · 제조법 · 만드는 품목 · 총 106건\n * value=MT10097283 은 1쪽에 없다 → selectedRecords = []\n * 팝업을 열고 아무것도 만지지 않고 확인 → 칸이 빈 값이 되었다\n *\n * 확인의 뜻은 「이 고른 것으로 한다」다. 고른 것이 없으면 확인할 것이 없으므로 닫기와 같다.\n * **값을 지우는 길은 「지정 안 함」 하나다.**\n */\n if (!selected || (Array.isArray(selected) && selected.length === 0)) {\n closePopup(this)\n return\n }\n\n this.confirmCallback && this.confirmCallback(selected)\n closePopup(this)\n }\n\n fetchHandler: FetchHandler = async ({ filters = [], page, limit, sortings = [], inherited }) => {\n if (this.basicArgs?.filters) {\n filters = adjustFilters(filters, this.basicArgs.filters)\n }\n // basicArgs.sorters가 있으면 기본 정렬로 병합\n if (this.basicArgs?.sorters && sortings.length === 0) {\n sortings = [...this.basicArgs.sorters]\n }\n const pagination = { page, limit }\n\n const response = await client.query({\n query: gql`\n query($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $inherited: InheritedValueType) {\n fetch: ${\n this.queryName\n } (filters: $filters, pagination: $pagination, sortings: $sortings, inherited: $inherited) {\n ${this.getQueryFields()}\n }\n }\n `,\n variables: {\n filters,\n pagination,\n sortings,\n inherited: inherited || this.inherited\n },\n context: gqlContext()\n })\n\n if (!response.errors) {\n const records = response.data.fetch.items.map((item: any) => {\n let rowValue\n\n if (this.valueField && typeof this.valueField === 'function') {\n rowValue = this.valueField(item)\n } else if (this.valueField) {\n rowValue = item[this.valueField]\n } else {\n rowValue = item.id\n }\n\n /*\n * 지금 값과 같은 줄을 골라 둔다. 여럿 고르기에서는 값이 배열이므로 그 안에 있는지 본다.\n *\n * 값이 이 쪽에 없으면 골라지지 않는다 — 그것이 이 부품의 한계다. 부르는 쪽이 지금 값을\n * 글자로 함께 보여 주는 이유가 그것이다(ops-master 의 참조 팝업).\n */\n const wanted = Array.isArray(this.value) ? this.value : this.value ? [this.value] : []\n\n if (wanted.length && wanted.includes(rowValue)) {\n this.selectedRecords = this.multiple ? [...this.selectedRecords, item] : [item]\n item['__selected__'] = true\n /* 받아온 쪽에서 값을 찾았다 — 바닥 단추도 그것을 알아야 한다. */\n this.hasSelection = true\n }\n\n return item\n })\n const total = response.data.fetch.total\n\n return {\n records,\n total,\n limit,\n page\n }\n }\n }\n\n /**\n * 표의 설정을 **첫 렌더 전에** 세운다.\n *\n * ── 왜 firstUpdated 가 아닌가 ──────────────────────────────────────────────\n * 여기 있던 것을 `firstUpdated` 에서 만들고 있었다. 그러면 `<ox-grist>` 와 그 안의 필터 폼이\n * **먼저 붙고** 설정이 나중에 온다. 필터 폼은 붙는 순간의 설정을 한 번 읽어 두므로, 그 스냅숏이\n * 병합 전 것이었다 — 열 일곱 개 중 넷만 든 설정이라 필터가 하나도 없었고, 그래서 필터 영역이\n * 빈 채로 32px 만 서 있었다.\n *\n * `willUpdate` 는 렌더 전에 돈다. 폼이 붙을 때 이미 완성된 설정을 읽는다.\n */\n willUpdate(changed: PropertyValues<this>) {\n /* 열·질의가 바뀌면 다시 세운다. 그 밖의 변화에는 손대지 않는다. */\n /* multiple 이 바뀌면 거터와 고르기 규칙이 달라지므로 설정을 다시 세운다. */\n if (\n this._configured &&\n !changed.has('columns') &&\n !changed.has('queryName') &&\n !changed.has('list') &&\n !changed.has('multiple')\n ) {\n return\n }\n\n this._configured = true\n\n const config = {\n list: this.list,\n columns: [\n {\n type: 'gutter',\n gutterName: 'sequence'\n },\n {\n type: 'gutter',\n gutterName: 'row-selector',\n multiple: this.multiple\n }\n ],\n rows: {\n selectable: {\n multiple: this.multiple\n },\n handlers: {\n /*\n * 하나만 고를 때는 누르면 그 줄로 바뀐다. 여럿일 때는 눌러 켜고 끈다 — 앞의 것을\n * 풀면서 고르면 여러 개를 담을 수 없다.\n */\n click: this.multiple ? 'select-row-toggle' : 'select-row',\n /*\n * 두 번 눌러 확정하는 것은 하나만 고를 때다. 여럿일 때 그렇게 두면 **그 한 줄만**\n * 넘어가고 앞서 고른 것이 사라진다.\n */\n ...(this.multiple\n ? {}\n : {\n dblclick: ((columns, data, column, record, rowIndex, field) => {\n this.onConfirm()\n }) as GristEventHandler\n })\n },\n appendable: false\n },\n pagination: this.pagination\n }\n\n const columns = this.columns || [\n {\n type: 'string',\n name: 'id',\n header: i18next.t('field.id'),\n hidden: true\n },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: {\n align: 'left'\n },\n sortable: true,\n filter: 'search',\n width: 160\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: {\n align: 'left'\n },\n sortable: true,\n filter: 'search',\n /*\n * 남는 폭을 이 열이 채운다.\n *\n * 열 폭은 grid-template-columns 에 그대로 들어가므로 문자열도 된다(data-grist 의\n * setGridTemplateColumns). 고정 300px 이었을 때는 오른쪽에 200px 가까운 죽은 자리와\n * 세로선 하나가 남았다 — 목록이 상자 한쪽에 몰려 보인다.\n */\n width: 'minmax(240px, 1fr)'\n }\n ]\n\n /*\n * **밖에서 준 설정을 덮어쓰지 않는다.**\n *\n * 여기서 `this.config` 를 통째로 갈아 끼우고 있었다. 그래서 부르는 쪽이 `config` 를 주어도\n * 사라졌다 — 빈 목록에 무슨 말을 할지(`emptyNote`)를 밖에서 정할 길이 없었다.\n *\n * 빈 목록은 **두 가지 다른 사실**을 말해야 하는 자리다. 「이 표에 아직 아무것도 없다」와\n * 「검색에 걸린 것이 없다」는 다르고, 하나로 합치면 결함이 「고를 게 없다」로 보인다. 실제로\n * 그런 일이 있었다(배열 모양이 달라 목록이 비었는데 아무도 결함인 줄 몰랐다).\n */\n const given = this.config || {}\n\n this.config = {\n ...config,\n ...given,\n columns: [\n ...config.columns,\n ...columns.map(selectField => {\n return {\n ...selectField,\n type: selectField.type || 'string',\n width: selectField.width || 160,\n header: selectField.header || i18next.t(`field.${selectField.name}`)\n }\n })\n ]\n }\n\n /*\n * 걸러 볼 것이 하나도 없으면 그 영역을 감춘다.\n *\n * **병합된 설정으로 판단한다.** 전에는 밖에서 받은 `columns` 만 보았는데, 기본 열(이름·설명)이\n * 이미 검색 필터를 갖고 있어서 그 판단이 실제와 달랐다.\n */\n requestAnimationFrame(() => {\n /*\n * **찾기가 아닌 필터**가 하나라도 있나로 판단한다. 찾기는 이 영역이 안 그리므로(위 주석),\n * `search` 형 필터만 있는 표에서는 여기 그릴 것이 없다.\n */\n const filterable = this.config.columns.some((column: any) => {\n const filter = column.filter\n return filter && filter !== 'search' && filter?.operator !== 'search'\n })\n\n if (!filterable) {\n this.grist?.hideHeadroom()\n }\n })\n }\n\n getQueryFields() {\n if (this.columns && this.columns.length > 0) {\n return `items {\n ${this.columns.map(selectField => {\n return selectField.type === 'object'\n ? `${selectField.name} { ${\n selectField.subFields && selectField.subFields.length > 0\n ? selectField.subFields.join(' ')\n : `id name description`\n } }`\n : `${selectField.name}`\n })}\n }\n total`\n } else {\n return `\n items {\n id\n name\n description\n }\n total\n `\n }\n }\n\n /**\n * 고른 것. **여럿 고르기에서는 배열이고, 아니면 하나다.**\n *\n * 켠 쪽이 그 모양을 아니까 두 가지를 한 자리에서 낸다.\n */\n get selected(): any {\n var grist = this.renderRoot.querySelector('ox-grist') as DataGrist\n\n var selected = grist.selected || []\n\n if (this.multiple) {\n return selected\n }\n\n return selected.length > 0 ? selected[0] : undefined\n }\n}\n"]}
|
|
@@ -17,7 +17,7 @@ import { expect } from '@open-wc/testing';
|
|
|
17
17
|
* 표에서는 안 드러났고, 여러 쪽이면 값이 2쪽에 있을 때 빈 채였다.
|
|
18
18
|
*
|
|
19
19
|
* ```
|
|
20
|
-
* [
|
|
20
|
+
* [확인함] 제조법 · 만드는 품목 · 총 106건 · value=MT10097283 은 1쪽에 없다
|
|
21
21
|
* 팝업을 열고 아무것도 만지지 않고 확인 → 칸이 빈 값이 되었다
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
@@ -82,7 +82,7 @@ describe('참조 선택기 · 확인은 값을 지우지 않는다', () => {
|
|
|
82
82
|
* 내려가 목록이 통째로 사라졌다.
|
|
83
83
|
*
|
|
84
84
|
* ```
|
|
85
|
-
* [
|
|
85
|
+
* [확인함] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건
|
|
86
86
|
* ```
|
|
87
87
|
*
|
|
88
88
|
* 첫 렌더 뒤로 다시 그릴 일이 없어서 여태 안 드러났다. 바닥 단추를 고른 상태에 묶으면서
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selector-confirm-keeps-value.test.js","sourceRoot":"","sources":["../../test/selector-confirm-keeps-value.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing'\n\n/**\n * 참조 팝업의 **확인이 값을 지우지 않는다.**\n *\n * ## 무엇을 지키나\n *\n * `ox-selector-resource-object` 의 확인은 「이 고른 것으로 한다」다. 고른 것이 없으면 확인할 것이\n * 없으므로 닫기와 같아야 한다. **값을 지우는 길은 「지정 안 함」 하나다.**\n *\n * ## 왜 이 시험이 있나 (2026-09-05)\n *\n * 전에는 `confirmCallback(this.selected)` 를 조건 없이 불렀다. 고른 것이 없으면 `selected` 가\n * undefined 이고, 그것은 `onEmpty` 가 넘기는 것과 **똑같다** — 확인이 「지정 안 함」과 같은 일을\n * 했다. 값을 지우는 단추가 둘이었고 그중 하나가 주 동작(채운 단추)이었다.\n *\n * 고른 표시는 목록을 받아올 때 그 쪽에서 값을 찾으면 켜진다. 그래서 목록이 한 쪽에 다 들어가는\n * 표에서는 안 드러났고, 여러 쪽이면 값이 2쪽에 있을 때 빈 채였다.\n *\n * ```\n * [
|
|
1
|
+
{"version":3,"file":"selector-confirm-keeps-value.test.js","sourceRoot":"","sources":["../../test/selector-confirm-keeps-value.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing'\n\n/**\n * 참조 팝업의 **확인이 값을 지우지 않는다.**\n *\n * ## 무엇을 지키나\n *\n * `ox-selector-resource-object` 의 확인은 「이 고른 것으로 한다」다. 고른 것이 없으면 확인할 것이\n * 없으므로 닫기와 같아야 한다. **값을 지우는 길은 「지정 안 함」 하나다.**\n *\n * ## 왜 이 시험이 있나 (2026-09-05)\n *\n * 전에는 `confirmCallback(this.selected)` 를 조건 없이 불렀다. 고른 것이 없으면 `selected` 가\n * undefined 이고, 그것은 `onEmpty` 가 넘기는 것과 **똑같다** — 확인이 「지정 안 함」과 같은 일을\n * 했다. 값을 지우는 단추가 둘이었고 그중 하나가 주 동작(채운 단추)이었다.\n *\n * 고른 표시는 목록을 받아올 때 그 쪽에서 값을 찾으면 켜진다. 그래서 목록이 한 쪽에 다 들어가는\n * 표에서는 안 드러났고, 여러 쪽이면 값이 2쪽에 있을 때 빈 채였다.\n *\n * ```\n * [확인함] 제조법 · 만드는 품목 · 총 106건 · value=MT10097283 은 1쪽에 없다\n * 팝업을 열고 아무것도 만지지 않고 확인 → 칸이 빈 값이 되었다\n * ```\n *\n * ## 왜 부품을 세우지 않고 원문을 보나\n *\n * 이 부품은 `@operato/graphql` 의 클라이언트를 모듈 적재 시점에 끌어온다. 시험 안에서 그것을 세우면\n * 서버가 필요하고, 그 무거움이 이 한 줄의 규칙을 지키는 값보다 크다.\n *\n * 대신 **그 규칙이 코드에 남아 있는지**를 본다. 조건 없이 부르는 모양으로 되돌아가면 빨갛게 난다.\n * 부품을 세우는 시험은 그래프가 가벼워지면 그때 더한다.\n */\n/**\n * `onConfirm` 의 본문만 떼어 낸다.\n *\n * 처음에 `indexOf('fetchHandler')` 를 끝 경계로 썼다가 빈 문자열이 나왔다 — 그 낱말은 render 의\n * 템플릿(`.fetchHandler=…`)에 **먼저** 나온다. 메서드 선언을 경계로 삼는다.\n */\nfunction onConfirmBody(source: string): string {\n const start = source.indexOf(' onConfirm() {')\n if (start < 0) return ''\n const rest = source.slice(start)\n const end = rest.indexOf('\\n }')\n return end < 0 ? rest : rest.slice(0, end + 4)\n}\n\ndescribe('참조 선택기 · 확인은 값을 지우지 않는다', () => {\n let source: string\n\n before(async () => {\n const response = await fetch('/src/selector/ox-selector-resource-object.ts')\n expect(response.ok, '원문을 읽을 수 있어야 한다').to.be.true\n source = await response.text()\n })\n\n it('확인은 고른 것이 없으면 콜백을 부르지 않는다', () => {\n const body = onConfirmBody(source)\n\n expect(body, 'onConfirm 을 찾아야 한다').to.include('onConfirm')\n\n /*\n * 고른 것이 없을 때 빠져나가는 길이 있어야 한다.\n *\n * 조건 안에 다른 절이 더 붙어도 통과시킨다 — 여럿 고르기가 들어오면서 빈 배열도 함께 봐야\n * 했다. 지키려는 것은 「!selected 를 보고 닫고 끝낸다」이지 조건의 글자 수가 아니다.\n */\n expect(body.replace(/\\s+/g, ' '), '고른 것이 없으면 닫고 끝낸다').to.match(\n /if\\s*\\([^)]*!\\s*selected[^{]*\\)\\s*\\{\\s*closePopup\\(this\\)\\s*;?\\s*return/\n )\n })\n\n it('확인이 넘기는 것은 고른 것 하나다 — this.selected 를 조건 없이 넘기지 않는다', () => {\n const body = onConfirmBody(source).replace(/\\s+/g, ' ')\n\n /*\n * 되돌아간 모양을 직접 막는다. 주석 안에 같은 글자가 있어도 걸리지 않도록 앞의 주석을 걷는다.\n */\n const code = body.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n\n expect(code, '조건 없이 this.selected 를 넘기는 모양으로 돌아가면 안 된다').to.not.include(\n 'confirmCallback(this.selected)'\n )\n })\n\n it('값을 지우는 길은 지정 안 함 하나다', () => {\n const empty = source.slice(source.indexOf('onEmpty()'), source.indexOf('onCancel()')).replace(/\\s+/g, ' ')\n\n /* 인자 없이 부르는 것이 「지우기」의 뜻이다. */\n expect(empty, '지정 안 함은 빈 값을 넘긴다').to.include('confirmCallback()')\n })\n\n /**\n * 그리스트에 **빈 data 를 넘기지 않는다.**\n *\n * data-grist 는 data 가 설정되면 reset() 한다. 이 부품은 fetchHandler 로 목록을 채우면서\n * `.data` 로 늘 ZERO_DATA 를 함께 넘기고 있었다. 그래서 이 부품이 다시 그려지는 순간 빈 값이\n * 내려가 목록이 통째로 사라졌다.\n *\n * ```\n * [확인함] 2026-09-05 · 라디오 클릭 → reset() 1회(DataGrist.updated) → 20건 → 0건\n * ```\n *\n * 첫 렌더 뒤로 다시 그릴 일이 없어서 여태 안 드러났다. 바닥 단추를 고른 상태에 묶으면서\n * 드러났고, 그것을 되돌리는 대신 이 바인딩을 걷었다.\n */\n it('ox-grist 에 .data 를 넘기지 않는다', () => {\n const template = source.slice(source.indexOf('<ox-grist'), source.indexOf('</ox-grist>'))\n\n expect(template, 'ox-grist 를 찾아야 한다').to.include('.fetchHandler=')\n expect(template.replace(/<!--[\\s\\S]*?-->/g, ''), '.data 를 다시 넘기면 목록이 사라진다').to.not.include(\n '.data='\n )\n })\n\n /**\n * **여럿 고르기에서 빈 배열도 막는다.**\n *\n * multiple 을 켜면 `selected` 가 배열이다. 아무것도 안 고른 상태는 undefined 가 아니라 `[]` 이고,\n * 그것은 truthy 다 — `!selected` 만으로는 빠져나가지 못하고 빈 배열이 그대로 넘어간다. 받는 쪽이\n * 그것을 「전부 지워라」로 읽으면 하나만 고르기 때와 같은 데이터 손실이 난다.\n */\n it('여럿 고르기에서 빈 배열을 넘기지 않는다', () => {\n const body = onConfirmBody(source).replace(/\\s+/g, ' ')\n\n expect(body, '빈 배열도 걸러야 한다').to.match(/Array\\.isArray\\(selected\\)\\s*&&\\s*selected\\.length\\s*===?\\s*0/)\n })\n})\n"]}
|