@things-factory/code-ui 8.0.0-beta.1 → 8.0.0-beta.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/code-ui",
3
- "version": "8.0.0-beta.1",
3
+ "version": "8.0.0-beta.2",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -34,10 +34,10 @@
34
34
  "@operato/layout": "^8.0.0-beta",
35
35
  "@operato/shell": "^8.0.0-beta",
36
36
  "@operato/styles": "^8.0.0-beta",
37
- "@things-factory/code-base": "^8.0.0-beta.1",
38
- "@things-factory/form-ui": "^8.0.0-beta.1",
39
- "@things-factory/i18n-base": "^8.0.0-beta.1",
40
- "@things-factory/shell": "^8.0.0-beta.1"
37
+ "@things-factory/code-base": "^8.0.0-beta.2",
38
+ "@things-factory/form-ui": "^8.0.0-beta.2",
39
+ "@things-factory/i18n-base": "^8.0.0-beta.2",
40
+ "@things-factory/shell": "^8.0.0-beta.2"
41
41
  },
42
- "gitHead": "36c494e587640c1490318ef7b95adab02606e0c2"
42
+ "gitHead": "f03431a09435511b2595515658f9cb8f78ba4ebb"
43
43
  }
@@ -1,6 +0,0 @@
1
- import { registerEditor as registerGristEditor } from '@operato/data-grist'
2
- import { OxGristEditorI18nLabel } from '@operato/grist-editor/ox-grist-editor-i18n-label.js'
3
-
4
- export default function bootstrap() {
5
- registerGristEditor('i18n-label', OxGristEditorI18nLabel)
6
- }
package/client/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './pages/code-management'
2
- export * from './pages/code-management-detail'
@@ -1,261 +0,0 @@
1
- import '@operato/data-grist/ox-grist.js'
2
- import '@operato/data-grist/ox-filters-form.js'
3
- import '@operato/data-grist/ox-sorters-control.js'
4
- import '@operato/data-grist/ox-record-creator.js'
5
-
6
- import gql from 'graphql-tag'
7
- import { css, html, LitElement } from 'lit'
8
- import { customElement, property, query, state } from 'lit/decorators.js'
9
-
10
- import { i18next, localize } from '@operato/i18n'
11
- import { client } from '@operato/graphql'
12
- import { ButtonContainerStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
13
- import { isMobileDevice, adjustFilters } from '@operato/utils'
14
- import { OxPrompt } from '@operato/popup/ox-prompt.js'
15
- import { DataGrist, FetchOption, QueryFilter } from '@operato/data-grist'
16
-
17
- import { getLanguages } from '@things-factory/auth-base/dist-client'
18
-
19
- @customElement('code-management-detail')
20
- export class CodeManagementDetail extends localize(i18next)(LitElement) {
21
- static styles = [
22
- ScrollbarStyles,
23
- ButtonContainerStyles,
24
- CommonGristStyles,
25
- CommonHeaderStyles,
26
- css`
27
- :host {
28
- display: flex;
29
- flex-direction: column;
30
- overflow: hidden;
31
- background-color: var(--md-sys-color-surface);
32
- }
33
-
34
- ox-grist {
35
- flex: 1;
36
- }
37
- `
38
- ]
39
-
40
- @property({ type: String }) codeId?: string
41
- @property({ type: Object }) config: any
42
-
43
- @state() mode: 'LIST' | 'GRID' = isMobileDevice() ? 'LIST' : 'GRID'
44
-
45
- @query('ox-grist') grist!: DataGrist
46
-
47
- render() {
48
- let mode = this.mode
49
-
50
- return html`
51
- <ox-grist .mode=${mode} auto-fetch .config=${this.config} .fetchHandler=${this.fetchHandler.bind(this)}>
52
- <div slot="headroom" class="header">
53
- <div class="filters">
54
- <ox-filters-form></ox-filters-form>
55
- </div>
56
- </div>
57
- </ox-grist>
58
-
59
- <div class="footer">
60
- <div filler></div>
61
- <button @click=${this.delete} danger><md-icon>delete</md-icon>${String(i18next.t('button.delete'))}</button>
62
- <button @click=${this.save} done><md-icon>save</md-icon>${String(i18next.t('button.save'))}</button>
63
- </div>
64
- `
65
- }
66
-
67
- async firstUpdated() {
68
- this.config = {
69
- rows: { selectable: { multiple: true } },
70
- pagination: { pages: [100, 200, 500] },
71
- columns: [
72
- { type: 'gutter', gutterName: 'dirty' },
73
- { type: 'gutter', gutterName: 'sequence' },
74
- { type: 'gutter', gutterName: 'row-selector', multiple: true },
75
- {
76
- type: 'integer',
77
- name: 'rank',
78
- record: { align: 'left', editable: true, format: '#,###' },
79
- header: i18next.t('field.rank'),
80
- sortable: true,
81
- width: 60
82
- },
83
- {
84
- type: 'string',
85
- name: 'name',
86
- record: { align: 'left', editable: true },
87
- header: i18next.t('field.code'),
88
- sortable: true,
89
- filter: 'search',
90
- width: 320
91
- },
92
- {
93
- type: 'i18n-label',
94
- name: 'labels',
95
- record: {
96
- align: 'left',
97
- editable: true,
98
- renderer: (value, column, record, rowIndex, field) =>
99
- html`<span>${value && typeof value == 'object' ? value[i18next.language] : record['description']}</span>`,
100
- options: {
101
- objectified: true,
102
- languages: await getLanguages(),
103
- displayColumn: 'description'
104
- }
105
- },
106
- header: i18next.t('field.i18n-label'),
107
- sortable: true,
108
- filter: 'search',
109
- width: 370
110
- },
111
- {
112
- type: 'object',
113
- name: 'updater',
114
- record: { align: 'left', editable: false },
115
- header: i18next.t('field.updater'),
116
- sortable: true,
117
- width: 90
118
- },
119
- {
120
- type: 'datetime',
121
- name: 'updatedAt',
122
- header: i18next.t('field.updated_at'),
123
- record: { editable: false },
124
- sortable: true,
125
- width: 180
126
- }
127
- ]
128
- }
129
-
130
- await this.updateComplete
131
- this.grist.fetch()
132
- }
133
-
134
- async fetchHandler({ filters, page, limit, sorters = [{ name: 'rank' }] }: FetchOption) {
135
- if (this.codeId) {
136
- filters = adjustFilters(filters || [], [
137
- {
138
- name: 'commonCodeId',
139
- operator: 'eq',
140
- value: this.codeId
141
- }
142
- ]) as QueryFilter[]
143
- }
144
-
145
- const response = await client.query({
146
- query: gql`
147
- query CommonCodeDetails($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
148
- commonCodeDetails(filters: $filters, pagination: $pagination, sortings: $sortings) {
149
- items {
150
- id
151
- name
152
- description
153
- rank
154
- labels
155
- updatedAt
156
- updater {
157
- name
158
- description
159
- }
160
- }
161
- total
162
- }
163
- }
164
- `,
165
- variables: {
166
- filters,
167
- pagination: { page, limit },
168
- sorters
169
- }
170
- })
171
-
172
- if (!response.errors) {
173
- return {
174
- total: response.data.commonCodeDetails.total || 0,
175
- records: response.data.commonCodeDetails.items || []
176
- }
177
- }
178
- }
179
-
180
- async save() {
181
- const patches = this.getPatches()
182
- if (!patches?.length) {
183
- return this.showToast(i18next.t('text.nothing_changed'))
184
- }
185
-
186
- const response = await client.mutate({
187
- mutation: gql`
188
- mutation updateMultipleCommonCodeDetail($patches: [CommonCodeDetailPatch!]!) {
189
- updateMultipleCommonCodeDetail(patches: $patches) {
190
- name
191
- }
192
- }
193
- `,
194
- variables: { patches }
195
- })
196
-
197
- if (!response.errors) this.grist.fetch()
198
- }
199
-
200
- async delete() {
201
- const ids = this.grist.selected.map(record => record.id)
202
- if (!ids?.length) {
203
- return this.showToast(i18next.t('text.there_is_nothing_to_delete'))
204
- }
205
-
206
- if (
207
- await OxPrompt.open({
208
- type: 'warning',
209
- title: i18next.t('button.delete'),
210
- text: i18next.t('text.are_you_sure'),
211
- confirmButton: { text: i18next.t('button.delete') },
212
- cancelButton: { text: i18next.t('button.cancel') }
213
- })
214
- ) {
215
- const response = await client.mutate({
216
- mutation: gql`
217
- mutation DeleteCommonCodeDetails($ids: [String!]!) {
218
- deleteCommonCodeDetails(ids: $ids)
219
- }
220
- `,
221
- variables: {
222
- ids
223
- }
224
- })
225
-
226
- if (!response.errors) {
227
- OxPrompt.open({
228
- type: 'success',
229
- title: i18next.t('text.completed'),
230
- text: i18next.t('text.data_deleted_successfully'),
231
- confirmButton: { text: i18next.t('button.confirm') }
232
- })
233
-
234
- this.grist.fetch()
235
- }
236
- }
237
- }
238
-
239
- getPatches() {
240
- let patches = this.grist.dirtyRecords
241
- if (patches && patches.length) {
242
- patches = patches.map(code => {
243
- let patchField: any = code.id ? { id: code.id } : {}
244
- const dirtyFields = code.__dirtyfields__
245
- for (let key in dirtyFields) {
246
- patchField[key] = dirtyFields[key].after
247
- }
248
- patchField.commonCode = { id: this.codeId }
249
- patchField.cuFlag = code.__dirty__
250
-
251
- return patchField
252
- })
253
- }
254
-
255
- return patches
256
- }
257
-
258
- showToast(message) {
259
- document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
260
- }
261
- }
@@ -1,288 +0,0 @@
1
- import './code-management-detail'
2
- import '@operato/data-grist/ox-grist.js'
3
- import '@operato/data-grist/ox-filters-form.js'
4
- import '@operato/data-grist/ox-sorters-control.js'
5
- import '@operato/data-grist/ox-record-creator.js'
6
- import '@operato/context/ox-context-page-toolbar.js'
7
-
8
- import gql from 'graphql-tag'
9
- import { css, html } from 'lit'
10
- import { customElement, property, query, state } from 'lit/decorators.js'
11
-
12
- import { openPopup } from '@operato/layout'
13
- import { i18next, localize } from '@operato/i18n'
14
- import { client } from '@operato/graphql'
15
- import { PageView } from '@operato/shell'
16
- import { CommonButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles } from '@operato/styles'
17
- import { isMobileDevice } from '@operato/utils'
18
- import { DataGrist, FetchOption } from '@operato/data-grist'
19
-
20
- import { OxPrompt } from '@operato/popup/ox-prompt.js'
21
-
22
- @customElement('code-management')
23
- export class CodeManagement extends localize(i18next)(PageView) {
24
- static styles = [
25
- ScrollbarStyles,
26
- CommonGristStyles,
27
- CommonHeaderStyles,
28
- css`
29
- :host {
30
- display: flex;
31
-
32
- width: 100%;
33
-
34
- --grid-record-emphasized-background-color: #8b0000;
35
- --grid-record-emphasized-color: #ff6b6b;
36
- }
37
-
38
- ox-grist {
39
- overflow-y: auto;
40
- flex: 1;
41
- }
42
-
43
- .header {
44
- grid-template-areas: 'filters actions';
45
- }
46
- `
47
- ]
48
-
49
- @state() config?: any
50
- @state() data?: any
51
- @state() mode: 'LIST' | 'GRID' = isMobileDevice() ? 'LIST' : 'GRID'
52
-
53
- @query('ox-grist') grist!: DataGrist
54
-
55
- render() {
56
- let mode = this.mode
57
-
58
- return html`
59
- <ox-grist .mode=${mode} auto-fetch .config=${this.config} .fetchHandler=${this.fetchHandler.bind(this)}>
60
- <div slot="headroom" class="header">
61
- <div class="filters">
62
- <ox-filters-form autofocus without-search></ox-filters-form>
63
- </div>
64
-
65
- <ox-context-page-toolbar class="actions" .context=${this.context}> </ox-context-page-toolbar>
66
- </div>
67
- </ox-grist>
68
- `
69
- }
70
-
71
- get context() {
72
- return {
73
- title: i18next.t('title.code-management'),
74
- search: {
75
- handler: (search: string) => {
76
- this.grist.searchText = search
77
- },
78
- value: this.grist?.searchText || ''
79
- },
80
- filter: {
81
- handler: () => {
82
- this.grist.toggleHeadroom()
83
- }
84
- },
85
- actions: [
86
- {
87
- title: i18next.t('button.save'),
88
- action: this.save.bind(this),
89
- ...CommonButtonStyles.save
90
- },
91
- {
92
- title: i18next.t('button.delete'),
93
- action: this.delete.bind(this),
94
- ...CommonButtonStyles.delete
95
- }
96
- ],
97
- help: 'code/code-management',
98
- toolbar: false
99
- }
100
- }
101
-
102
- pageUpdated(_changed, _lifecycle) {
103
- if (this.active) {
104
- this.grist.fetch()
105
- }
106
- }
107
-
108
- pageInitialized() {
109
- this.config = {
110
- rows: { selectable: { multiple: true } },
111
- pagination: { pages: [50, 100, 200] },
112
- columns: [
113
- { type: 'gutter', gutterName: 'dirty' },
114
- { type: 'gutter', gutterName: 'sequence' },
115
- { type: 'gutter', gutterName: 'row-selector', multiple: true },
116
- {
117
- type: 'gutter',
118
- gutterName: 'button',
119
- icon: 'reorder',
120
- handlers: {
121
- click: (_columns, _data, _column, record, _rowIndex) => {
122
- if (record.id && record.name) this.openCodeDetail(record.id, record.name)
123
- }
124
- }
125
- },
126
- {
127
- type: 'string',
128
- name: 'name',
129
- header: i18next.t('field.common-code'),
130
- record: { editable: true, align: 'left' },
131
- sortable: true,
132
- filter: 'search',
133
- width: 375
134
- },
135
- {
136
- type: 'string',
137
- name: 'description',
138
- header: i18next.t('field.description'),
139
- record: { editable: true, align: 'left' },
140
- sortable: true,
141
- filter: 'search',
142
- width: 500
143
- },
144
- {
145
- type: 'object',
146
- name: 'updater',
147
- header: i18next.t('field.updater'),
148
- record: { editable: false },
149
- sortable: true,
150
- width: 90
151
- },
152
- {
153
- type: 'datetime',
154
- name: 'updatedAt',
155
- header: i18next.t('field.updated_at'),
156
- record: { editable: false },
157
- sortable: true,
158
- width: 180
159
- }
160
- ]
161
- }
162
- }
163
-
164
- async fetchHandler({ filters, page, limit, sorters = [{ name: 'name' }, { name: 'updatedAt' }] }: FetchOption) {
165
- const response = await client.query({
166
- query: gql`
167
- query CommonCodes($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
168
- commonCodes(filters: $filters, pagination: $pagination, sortings: $sortings) {
169
- items {
170
- id
171
- name
172
- description
173
- updatedAt
174
- updater {
175
- id
176
- name
177
- description
178
- }
179
- }
180
- total
181
- }
182
- }
183
- `,
184
- variables: {
185
- filters,
186
- pagination: { page, limit },
187
- sorters
188
- }
189
- })
190
-
191
- return {
192
- total: response.data.commonCodes.total || 0,
193
- records: response.data.commonCodes.items || []
194
- }
195
- }
196
-
197
- async save() {
198
- const patches = this.getPatches()
199
- if (!patches?.length) {
200
- return this.showToast(i18next.t('text.nothing_changed'))
201
- }
202
-
203
- const response = await client.mutate({
204
- mutation: gql`
205
- mutation UpdateMultipleCommonCode($patches: [CommonCodePatch!]!) {
206
- updateMultipleCommonCode(patches: $patches) {
207
- name
208
- }
209
- }
210
- `,
211
- variables: { patches }
212
- })
213
-
214
- if (!response.errors) {
215
- this.showToast(i18next.t('text.data_updated_successfully'))
216
- this.grist.fetch()
217
- }
218
- }
219
-
220
- async delete() {
221
- const ids = this.grist.selected.map(record => record.id)
222
- if (!ids?.length) {
223
- return this.showToast(i18next.t('text.there_is_nothing_to_delete'))
224
- }
225
-
226
- if (
227
- await OxPrompt.open({
228
- type: 'warning',
229
- title: i18next.t('button.delete'),
230
- text: i18next.t('text.are_you_sure'),
231
- confirmButton: { text: i18next.t('button.delete') },
232
- cancelButton: { text: i18next.t('button.cancel') }
233
- })
234
- ) {
235
- const response = await client.mutate({
236
- mutation: gql`
237
- mutation DeleteCommonCodes($ids: [String!]!) {
238
- deleteCommonCodes(ids: $ids)
239
- }
240
- `,
241
- variables: {
242
- ids
243
- }
244
- })
245
-
246
- if (!response.errors) {
247
- OxPrompt.open({
248
- type: 'success',
249
- title: i18next.t('text.completed'),
250
- text: i18next.t('text.data_deleted_successfully'),
251
- confirmButton: { text: i18next.t('button.confirm') }
252
- })
253
-
254
- this.grist.fetch()
255
- }
256
- }
257
- }
258
-
259
- getPatches() {
260
- let patches = this.grist.dirtyRecords
261
- if (patches && patches.length) {
262
- patches = patches.map(code => {
263
- let patchField: any = code.id ? { id: code.id } : {}
264
- const dirtyFields = code.__dirtyfields__
265
- for (let key in dirtyFields) {
266
- patchField[key] = dirtyFields[key].after
267
- }
268
- patchField.cuFlag = code.__dirty__
269
-
270
- return patchField
271
- })
272
- }
273
-
274
- return patches
275
- }
276
-
277
- openCodeDetail(codeId, codeName) {
278
- openPopup(html` <code-management-detail .codeId="${codeId}"></code-management-detail> `, {
279
- backdrop: true,
280
- size: 'large',
281
- title: `${i18next.t('title.code-management-detail')} - ${codeName}`
282
- })
283
- }
284
-
285
- showToast(message) {
286
- document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
287
- }
288
- }
package/client/route.ts DELETED
@@ -1,7 +0,0 @@
1
- export default function route(page) {
2
- switch (page) {
3
- case 'codes':
4
- import('./pages/code-management')
5
- return page
6
- }
7
- }
package/server/index.ts DELETED
File without changes