import '@operato/data-grist' import { css, html } from 'lit' import { customElement, property, query } from 'lit/decorators.js' import gql from 'graphql-tag' import { PageView } from '@operato/shell' import { CommonHeaderStyles, CommonGristStyles, CommonButtonStyles, ScrollbarStyles } from '@operato/styles' import { ColumnConfig, DataGrist, FetchOption, SortersControl } from '@operato/data-grist' import { client } from '@operato/graphql' import { i18next, localize } from '@operato/i18n' import { notify, openPopup } from '@operato/layout' import { OxPopup, OxPrompt } from '@operato/popup' import { isMobileDevice } from '@operato/utils' import { p13n } from '@operato/p13n' @customElement('state-register-page') export class StateRegisterListPage extends p13n(localize(i18next)(PageView)) { static styles = [ ScrollbarStyles, CommonGristStyles, CommonHeaderStyles, css` :host { display: flex; width: 100%; --grid-record-emphasized-background-color: #8b0000; --grid-record-emphasized-color: #ff6b6b; } ox-grist { overflow-y: auto; flex: 1; } ` ] @property({ type: Object }) gristConfig: any @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID' @query('ox-grist') private grist!: DataGrist get context() { return { title: i18next.t('title.state-register'), search: { handler: (search: string) => { this.grist.searchText = search }, value: this.grist.searchText }, help: 'integration/ui/state-register', actions: [ { title: i18next.t('button.save'), action: this._updateStateRegister.bind(this), ...CommonButtonStyles.save }, { title: i18next.t('button.delete'), action: this._deleteStateRegister.bind(this), ...CommonButtonStyles.delete } ] } } render() { const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID') return html` ` } async pageInitialized(lifecycle: any) { this.gristConfig = { list: { fields: ['name', 'description'], details: ['type', 'state', 'wroteAt'] }, columns: [ { type: 'gutter', gutterName: 'sequence' }, { type: 'gutter', gutterName: 'row-selector', multiple: true }, { type: 'string', name: 'name', header: i18next.t('field.name'), record: { editable: true }, filter: 'search', sortable: true, width: 150, description: i18next.t('field.name-publish-tag-desc') // name이 publish tag 역할을 한다는 설명 }, { type: 'string', name: 'description', header: i18next.t('field.description'), record: { editable: true }, filter: 'search', width: 200 }, { type: 'string', name: 'group', header: i18next.t('field.group'), record: { editable: true }, filter: 'search', sortable: true, width: 150 }, { type: 'boolean', name: 'autoPublish', header: i18next.t('field.auto-publish'), record: { editable: true }, width: 120 }, { type: 'select', name: 'type', header: i18next.t('field.type'), record: { editable: true, options: [ {}, { display: 'text', value: 'text' }, { display: 'number', value: 'number' }, { display: 'object', value: 'object' } ] }, filter: 'search', sortable: true, width: 150 }, { type: 'number', name: 'ttl', header: i18next.t('field.ttl-seconds'), record: { editable: true }, width: 100 }, { type: 'data', name: 'state', header: i18next.t('field.state-value'), record: { editable: true // 사용자가 state를 편집할 수 있도록 변경 }, width: 200 }, { type: 'datetime', name: 'wroteAt', header: i18next.t('field.wrote-at'), record: { editable: false }, sortable: true, width: 180 } ], rows: { selectable: { multiple: true } }, sorters: [ { name: 'name' } ] } } async pageUpdated(changes: any, lifecycle: any) { if (this.active) { // do something here when this page just became as active } } async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) { const response = await client.query({ query: gql` query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: stateRegisters(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id name description group type place unit ttl state autoPublish writer { id name } wroteAt } total } } `, variables: { filters, pagination: { page, limit }, sortings } }) return { total: response.data.responses.total || 0, records: response.data.responses.items || [] } } async _deleteStateRegister() { if ( await OxPrompt.open({ title: i18next.t('text.are_you_sure'), text: i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }), confirmButton: { text: i18next.t('button.confirm') }, cancelButton: { text: i18next.t('button.cancel') } }) ) { const ids = this.grist.selected.map(record => record.id) if (ids && ids.length > 0) { const response = await client.mutate({ mutation: gql` mutation ($ids: [String!]!) { deleteStateRegisters(ids: $ids) } `, variables: { ids } }) if (!response.errors) { this.grist.fetch() notify({ message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') }) }) } } } } async _updateStateRegister() { let patches = this.grist.dirtyRecords if (patches && patches.length) { patches = patches.map(patch => { let patchField: any = patch.id ? { id: patch.id } : {} const dirtyFields = patch.__dirtyfields__ for (let key in dirtyFields) { patchField[key] = dirtyFields[key].after } patchField.cuFlag = patch.__dirty__ return patchField }) const response = await client.mutate({ mutation: gql` mutation ($patches: [StateRegisterPatch!]!) { updateMultipleStateRegister(patches: $patches) { name } } `, variables: { patches } }) if (!response.errors) { this.grist.fetch() } } } }