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()
}
}
}
}