@operato/app 1.0.0 → 1.0.6

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.
@@ -1,54 +1,46 @@
1
1
  import '@operato/data-grist'
2
- import '@operato/form/ox-search-form.js'
3
2
 
4
3
  import gql from 'graphql-tag'
5
4
  import { css, html, LitElement } from 'lit'
6
5
  import { customElement, property, query } from 'lit/decorators.js'
7
6
 
8
- import {
9
- ColumnConfig,
10
- DataGrist,
11
- FetchHandler,
12
- FetchOption,
13
- GristData,
14
- GristEventHandler,
15
- GristRecord,
16
- ZERO_DATA
17
- } from '@operato/data-grist'
18
- import { MultiColumnFormStyles, SearchForm } from '@operato/form'
19
- import { buildArgs, client, gqlContext } from '@operato/graphql'
7
+ import { DataGrist, FetchHandler, GristData, GristEventHandler, GristRecord, ZERO_DATA } from '@operato/data-grist'
8
+ import { client, gqlContext } from '@operato/graphql'
20
9
  import { i18next } from '@operato/i18n'
21
10
  import { closePopup } from '@operato/popup'
22
- import { isMobileDevice } from '@operato/utils'
11
+ import { adjustFilters, isMobileDevice } from '@operato/utils'
23
12
 
24
13
  @customElement('ox-selector-resource-object')
25
14
  export class OxSelectorResourceObject extends LitElement {
26
15
  static styles = [
27
- MultiColumnFormStyles,
28
16
  css`
29
17
  :host {
30
18
  display: flex;
31
19
  flex-direction: column;
32
20
 
33
21
  background-color: #fff;
22
+
23
+ width: var(--overlay-center-normal-width, 50%);
24
+ height: var(--overlay-center-normal-height, 50%);
34
25
  }
35
26
 
36
27
  ox-grist {
37
28
  flex: 1;
38
29
  }
39
30
 
40
- .button-container {
31
+ #filters {
41
32
  display: flex;
42
- margin-left: auto;
33
+ flex-direction: row;
34
+ justify-content: space-between;
43
35
  }
44
36
 
45
- form {
46
- position: relative;
37
+ #filters > * {
38
+ padding: var(--padding-default) var(--padding-wide);
47
39
  }
48
40
 
49
- [search] {
50
- position: absolute;
51
- right: 0;
41
+ .button-container {
42
+ display: flex;
43
+ margin-left: auto;
52
44
  }
53
45
  `
54
46
  ]
@@ -62,13 +54,12 @@ export class OxSelectorResourceObject extends LitElement {
62
54
  @property({ type: Array }) selectedRecords: GristRecord[] = []
63
55
 
64
56
  @property({ type: Array }) searchFields: any
65
- @property({ type: Array }) select: {
57
+ @property({ type: Array }) columns: {
66
58
  type: string
67
59
  name: string
68
60
  header: string
69
61
  subFields?: string[]
70
62
  hidden: boolean
71
- ignoreCondition: boolean
72
63
  queryName: string
73
64
  width: number
74
65
  }[] = []
@@ -76,29 +67,20 @@ export class OxSelectorResourceObject extends LitElement {
76
67
  @property({ type: String }) valueField: string | ((item: any) => any) = 'id'
77
68
 
78
69
  @query('ox-grist') grist!: DataGrist
79
- @query('ox-search-form') searchForm!: SearchForm
80
70
 
81
71
  render() {
82
72
  return html`
83
- <ox-search-form
84
- id="search-form"
85
- @keypress=${(e: KeyboardEvent) => {
86
- if (e.key === 'Enter') {
87
- this.grist.fetch()
88
- }
89
- }}
90
- @submit=${(e: SubmitEvent) => this.grist.fetch()}
91
- .fields=${this.searchFields}
92
- autofocus
93
- ></ox-search-form>
94
-
95
73
  <ox-grist
96
74
  .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
97
75
  .config=${this.config}
98
76
  .data=${this.data}
99
77
  .fetchHandler=${this.fetchHandler.bind(this)}
100
78
  .selectedRecords=${this.selectedRecords}
101
- ></ox-grist>
79
+ >
80
+ <div id="filters" slot="headroom">
81
+ <ox-filters-form autofocus></ox-filters-form>
82
+ </div>
83
+ </ox-grist>
102
84
 
103
85
  <div class="button-container">
104
86
  <mwc-button @click=${this.onempty.bind(this)}>${i18next.t('button.empty')}</mwc-button>
@@ -122,15 +104,21 @@ export class OxSelectorResourceObject extends LitElement {
122
104
  closePopup(this)
123
105
  }
124
106
 
125
- fetchHandler: FetchHandler = async ({ filters, page, limit, sorters = [] }) => {
107
+ fetchHandler: FetchHandler = async ({ filters = [], page, limit, sortings = [] }) => {
108
+ if (this.basicArgs) {
109
+ filters = adjustFilters(filters, this.basicArgs)
110
+ }
111
+ const pagination = { page, limit }
112
+
126
113
  const response = await client.query({
127
114
  query: gql`
128
- query {
129
- fetch: ${this.queryName} (${buildArgs(await this._buildConditions({ filters, page, limit, sorters }))}) {
130
- ${this.getSelectFields()}
115
+ query($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
116
+ fetch: ${this.queryName} (filters: $filters, pagination: $pagination, sortings: $sortings) {
117
+ ${this.getQueryFields()}
131
118
  }
132
119
  }
133
120
  `,
121
+ variables: { filters, pagination, sortings },
134
122
  context: gqlContext()
135
123
  })
136
124
 
@@ -191,124 +179,57 @@ export class OxSelectorResourceObject extends LitElement {
191
179
  }
192
180
  }
193
181
 
194
- if (this.select && this.select.length > 0) {
195
- let _searchFields = this.select.filter(selectField => !selectField.hidden && !selectField.ignoreCondition)
196
- if (this.list && this.list.fields && this.list.fields.length > 0) {
197
- _searchFields = _searchFields.filter(searchField => this.list.fields.indexOf(searchField.name) >= 0)
198
- } else {
199
- _searchFields = _searchFields.slice(0, 4)
200
- }
201
-
202
- this.searchFields = _searchFields.map(selectField => {
203
- const fieldType = (selectField.type && selectField.type.toLowerCase()) || 'string'
204
- const numberTypes = ['integer', 'float']
205
- return {
206
- label: selectField.header || i18next.t(`field.${selectField.name}`),
207
- name: selectField.name,
208
- type:
209
- fieldType === 'string'
210
- ? 'text'
211
- : numberTypes.indexOf(fieldType) >= 0
212
- ? 'number'
213
- : fieldType === 'boolean'
214
- ? 'checkbox'
215
- : fieldType,
216
- queryName: selectField.queryName,
217
- props:
218
- fieldType === 'string'
219
- ? { searchOper: 'i_like' }
220
- : fieldType === 'object'
221
- ? { searchOper: 'in' }
222
- : { searchOper: 'eq' },
223
- attrs: fieldType === 'boolean' ? ['indeterminated'] : []
224
- }
225
- })
226
- this.config = {
227
- ...this.config,
228
- columns: [
229
- ...this.config.columns,
230
- ...this.select.map(selectField => {
231
- return {
232
- ...selectField,
233
- type: selectField.type || 'string',
234
- width: selectField.width || 160,
235
- header: selectField.header || i18next.t(`field.${selectField.name}`)
236
- }
237
- })
238
- ]
239
- }
240
- } else {
241
- this.searchFields = [
242
- {
243
- label: i18next.t('field.name'),
244
- name: 'name',
245
- type: 'text',
246
- props: { searchOper: 'i_like' }
182
+ const columns = this.columns || [
183
+ {
184
+ type: 'string',
185
+ name: 'id',
186
+ header: i18next.t('field.id'),
187
+ hidden: true
188
+ },
189
+ {
190
+ type: 'string',
191
+ name: 'name',
192
+ header: i18next.t('field.name'),
193
+ record: {
194
+ align: 'left'
247
195
  },
248
- {
249
- label: i18next.t('field.description'),
250
- name: 'description',
251
- type: 'text',
252
- props: { searchOper: 'i_like' }
253
- }
254
- ]
255
-
256
- this.config = {
257
- ...this.config,
258
- columns: [
259
- ...this.config.columns,
260
- {
261
- type: 'string',
262
- name: 'id',
263
- header: i18next.t('field.id'),
264
- hidden: true
265
- },
266
- {
267
- type: 'string',
268
- name: 'name',
269
- header: i18next.t('field.name'),
270
- record: {
271
- align: 'left'
272
- },
273
- sortable: true,
274
- width: 160
275
- },
276
- {
277
- type: 'string',
278
- name: 'description',
279
- header: i18next.t('field.description'),
280
- record: {
281
- align: 'left'
282
- },
283
- sortable: true,
284
- width: 300
285
- }
286
- ]
196
+ sortable: true,
197
+ filter: 'search',
198
+ width: 160
199
+ },
200
+ {
201
+ type: 'string',
202
+ name: 'description',
203
+ header: i18next.t('field.description'),
204
+ record: {
205
+ align: 'left'
206
+ },
207
+ sortable: true,
208
+ filter: 'search',
209
+ width: 300
287
210
  }
288
- }
211
+ ]
289
212
 
290
213
  this.config = {
291
214
  ...this.config,
292
- list: {
293
- ...this.list,
294
- fields:
295
- this.list && this.list.fields && this.list.fields.length > 0
296
- ? this.list.fields
297
- : (this.config.columns as ColumnConfig[])
298
- .filter(column => column.type !== 'gutter')
299
- .slice(0, 3)
300
- .map(column => column.name)
301
- }
215
+ columns: [
216
+ ...this.config.columns,
217
+ ...columns.map(selectField => {
218
+ return {
219
+ ...selectField,
220
+ type: selectField.type || 'string',
221
+ width: selectField.width || 160,
222
+ header: selectField.header || i18next.t(`field.${selectField.name}`)
223
+ }
224
+ })
225
+ ]
302
226
  }
303
-
304
- await this.updateComplete
305
- this.grist && this.grist.focus()
306
227
  }
307
228
 
308
- getSelectFields() {
309
- if (this.select && this.select.length > 0) {
229
+ getQueryFields() {
230
+ if (this.columns && this.columns.length > 0) {
310
231
  return `items {
311
- ${this.select.map(selectField => {
232
+ ${this.columns.map(selectField => {
312
233
  return selectField.type === 'object'
313
234
  ? `${selectField.name} { ${
314
235
  selectField.subFields && selectField.subFields.length > 0
@@ -331,19 +252,6 @@ export class OxSelectorResourceObject extends LitElement {
331
252
  }
332
253
  }
333
254
 
334
- async _buildConditions({ filters, page, limit, sorters }: FetchOption) {
335
- const queryConditions = {
336
- filters: [],
337
- ...this.basicArgs
338
- }
339
-
340
- queryConditions.filters = [...queryConditions.filters, ...(await this.searchForm.getQueryFilters())]
341
- queryConditions.pagination = { page, limit }
342
- queryConditions.sortings = sorters
343
-
344
- return queryConditions
345
- }
346
-
347
255
  get selected() {
348
256
  var grist = this.renderRoot.querySelector('ox-grist') as DataGrist
349
257