@operato/app 1.0.0-beta.2 → 1.0.0-beta.22

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +413 -0
  2. package/demo/data-grist-test.html +1 -1
  3. package/dist/src/filter-renderer/filter-resource-select.d.ts +4 -0
  4. package/dist/src/filter-renderer/filter-resource-select.js +79 -0
  5. package/dist/src/filter-renderer/filter-resource-select.js.map +1 -0
  6. package/dist/src/filter-renderer/index.d.ts +1 -0
  7. package/dist/src/filter-renderer/index.js +5 -0
  8. package/dist/src/filter-renderer/index.js.map +1 -0
  9. package/dist/src/filters-form/filter-resource-select.d.ts +4 -0
  10. package/dist/src/filters-form/filter-resource-select.js +78 -0
  11. package/dist/src/filters-form/filter-resource-select.js.map +1 -0
  12. package/dist/src/filters-form/index.d.ts +1 -0
  13. package/dist/src/filters-form/index.js +5 -0
  14. package/dist/src/filters-form/index.js.map +1 -0
  15. package/dist/src/grist-editor/ox-grist-renderer-crontab.js +3 -3
  16. package/dist/src/grist-editor/ox-grist-renderer-crontab.js.map +1 -1
  17. package/dist/src/grist-editor/ox-grist-renderer-resource-id.js +5 -2
  18. package/dist/src/grist-editor/ox-grist-renderer-resource-id.js.map +1 -1
  19. package/dist/src/grist-editor/ox-popup-partition-keys-input.js +3 -2
  20. package/dist/src/grist-editor/ox-popup-partition-keys-input.js.map +1 -1
  21. package/dist/src/index.d.ts +2 -1
  22. package/dist/src/index.js +2 -1
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/input/ox-input-resource.d.ts +36 -0
  25. package/dist/src/input/ox-input-resource.js +161 -0
  26. package/dist/src/input/ox-input-resource.js.map +1 -0
  27. package/dist/src/property-editor/index.d.ts +2 -1
  28. package/dist/src/property-editor/index.js +5 -2
  29. package/dist/src/property-editor/index.js.map +1 -1
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +18 -17
  32. package/src/filter-renderer/filter-resource-select.ts +95 -0
  33. package/src/filter-renderer/index.ts +6 -0
  34. package/src/filters-form/filter-resource-select.ts +94 -0
  35. package/src/filters-form/index.ts +6 -0
  36. package/src/grist-editor/ox-grist-renderer-crontab.ts +5 -4
  37. package/src/grist-editor/ox-grist-renderer-resource-id.ts +6 -2
  38. package/src/grist-editor/ox-popup-partition-keys-input.ts +3 -2
  39. package/src/index.ts +2 -1
  40. package/src/input/ox-input-resource.ts +169 -0
  41. package/src/property-editor/index.ts +5 -2
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "WebApplication production supporting components following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "heartyoh",
6
- "version": "1.0.0-beta.2",
6
+ "version": "1.0.0-beta.22",
7
7
  "main": "dist/src/index.js",
8
8
  "module": "dist/src/index.js",
9
9
  "exports": {
@@ -28,7 +28,8 @@
28
28
  "./grist-editor/ox-grist-editor-resource-code.js": "./dist/src/grist-editor/ox-grist-editor-resource-code.js",
29
29
  "./grist-editor/ox-grist-editor-parameters.js": "./dist/src/grist-editor/ox-grist-editor-parameters.js",
30
30
  "./grist-editor/ox-grist-editor-value-map.js": "./dist/src/grist-editor/ox-grist-editor-value-map.js",
31
- "./grist-editor/ox-grist-editor-partition-keys.js": "./dist/src/grist-editor/ox-grist-editor-partition-keys.js"
31
+ "./grist-editor/ox-grist-editor-partition-keys.js": "./dist/src/grist-editor/ox-grist-editor-partition-keys.js",
32
+ "./filter-renderer.js": "./dist/src/filter-renderer/index.js"
32
33
  },
33
34
  "publishConfig": {
34
35
  "access": "public",
@@ -58,18 +59,18 @@
58
59
  "@material/mwc-button": "^0.25.3",
59
60
  "@material/mwc-icon": "^0.25.3",
60
61
  "@material/mwc-icon-button": "^0.25.3",
61
- "@operato/attachment": "^1.0.0-beta.2",
62
- "@operato/data-grist": "^1.0.0-beta.2",
63
- "@operato/font": "^1.0.0-beta.2",
64
- "@operato/form": "^1.0.0-beta.2",
65
- "@operato/graphql": "^1.0.0-beta.2",
66
- "@operato/i18n": "^1.0.0-beta.2",
67
- "@operato/input": "^1.0.0-beta.2",
68
- "@operato/layout": "^1.0.0-beta.2",
69
- "@operato/property-editor": "^1.0.0-beta.2",
70
- "@operato/shell": "^1.0.0-beta.2",
71
- "@operato/styles": "^1.0.0-beta.2",
72
- "@operato/utils": "^1.0.0-beta.2",
62
+ "@operato/attachment": "^1.0.0-beta.22",
63
+ "@operato/data-grist": "^1.0.0-beta.22",
64
+ "@operato/font": "^1.0.0-beta.22",
65
+ "@operato/form": "^1.0.0-beta.22",
66
+ "@operato/graphql": "^1.0.0-beta.22",
67
+ "@operato/i18n": "^1.0.0-beta.22",
68
+ "@operato/input": "^1.0.0-beta.22",
69
+ "@operato/layout": "^1.0.0-beta.22",
70
+ "@operato/property-editor": "^1.0.0-beta.22",
71
+ "@operato/shell": "^1.0.0-beta.22",
72
+ "@operato/styles": "^1.0.0-beta.22",
73
+ "@operato/utils": "^1.0.0-beta.22",
73
74
  "codemirror": "^5.59.1",
74
75
  "codemirror-graphql": "^0.15.2",
75
76
  "cronstrue": "^2.2.0",
@@ -86,12 +87,12 @@
86
87
  "@typescript-eslint/eslint-plugin": "^4.33.0",
87
88
  "@typescript-eslint/parser": "^4.33.0",
88
89
  "@web/dev-server": "^0.1.29",
89
- "@web/dev-server-storybook": "next",
90
+ "@web/dev-server-storybook": "^0.5.0",
90
91
  "@web/test-runner": "next",
91
92
  "concurrently": "^5.3.0",
92
93
  "eslint": "^7.32.0",
93
94
  "eslint-config-prettier": "^8.3.0",
94
- "husky": "^4.3.8",
95
+ "husky": "^7.0.2",
95
96
  "lint-staged": "^10.5.4",
96
97
  "prettier": "^2.4.1",
97
98
  "tslib": "^2.3.1",
@@ -110,5 +111,5 @@
110
111
  "prettier --write"
111
112
  ]
112
113
  },
113
- "gitHead": "514a836d3f5e959695701ba41913aee18a1efe66"
114
+ "gitHead": "deb882c6a8d7ed82e8d881ca281e421ec757abee"
114
115
  }
@@ -0,0 +1,95 @@
1
+ import '@operato/input/ox-checkbox.js'
2
+ import '../grist-editor/ox-selector-resource-id'
3
+
4
+ import { html } from 'lit-html'
5
+
6
+ import { ColumnConfig, FilterConfigObject, FilterSelectRenderer } from '@operato/data-grist'
7
+ import { i18next } from '@operato/i18n'
8
+ import { openPopup } from '@operato/layout'
9
+
10
+ type SelectedCallback = (value: { id: string; name: string; description: string }) => void
11
+
12
+ function openResourceSelector(column: ColumnConfig, value: any, confirmCallback: SelectedCallback) {
13
+ const { queryName, select, list, basicArgs, valueField = 'id' } = column.record.options
14
+
15
+ var actualValue
16
+ if (typeof valueField === 'function') {
17
+ actualValue = valueField(value)
18
+ } else {
19
+ actualValue = value?.[valueField]
20
+ }
21
+
22
+ var template = html`
23
+ <ox-selector-resource-id
24
+ .value=${actualValue}
25
+ .confirmCallback=${confirmCallback}
26
+ .queryName=${queryName}
27
+ .select=${select}
28
+ .list=${list}
29
+ .basicArgs=${basicArgs}
30
+ .valueField=${valueField}
31
+ ></ox-selector-resource-id>
32
+ `
33
+
34
+ const popup = openPopup(template, {
35
+ backdrop: true,
36
+ size: 'large',
37
+ title: i18next.t('title.select_item')
38
+ })
39
+ }
40
+
41
+ export const FilterResourceSelect: FilterSelectRenderer = (column, value, owner) => {
42
+ const filter = column.filter as FilterConfigObject
43
+ const { operator = 'like' } = filter
44
+
45
+ return operator === 'like'
46
+ ? html` <input
47
+ type="text"
48
+ name=${column.name}
49
+ .value=${value}
50
+ @change=${(e: CustomEvent) => {
51
+ const input = e.target as HTMLInputElement
52
+ input.dispatchEvent(
53
+ new CustomEvent('filter-change', {
54
+ bubbles: true,
55
+ composed: true,
56
+ detail: {
57
+ name: column.name,
58
+ operator,
59
+ value: input.value
60
+ }
61
+ })
62
+ )
63
+ }}
64
+ />`
65
+ : operator == 'in'
66
+ ? html``
67
+ : operator === 'eq'
68
+ ? html`
69
+ <input
70
+ style="min-width: 100px; min-height: 24px"
71
+ type="text"
72
+ name=${column.name}
73
+ .value=${value}
74
+ readonly
75
+ @click=${(e: Event) => {
76
+ e.stopPropagation()
77
+
78
+ const confirmCallback = (selected?: { [field: string]: any }) => {
79
+ var { idField = 'id', nameField = 'name', descriptionField = 'description' } = column.record.options || {}
80
+
81
+ owner.dispatchEvent(
82
+ new CustomEvent('filter-change', {
83
+ bubbles: true,
84
+ composed: true,
85
+ detail: selected ? selected[idField] : ''
86
+ })
87
+ )
88
+ }
89
+
90
+ openResourceSelector(column, value, confirmCallback)
91
+ }}
92
+ />
93
+ `
94
+ : html``
95
+ }
@@ -0,0 +1,6 @@
1
+ import { registerFilterRenderer } from '@operato/data-grist'
2
+
3
+ import { FilterResourceSelect } from './filter-resource-select.js'
4
+
5
+ registerFilterRenderer('resource-object', [FilterResourceSelect])
6
+ registerFilterRenderer('resource-id', [FilterResourceSelect])
@@ -0,0 +1,94 @@
1
+ import '@operato/input/ox-checkbox.js'
2
+ import '../grist-editor/ox-selector-resource-id'
3
+
4
+ import { html } from 'lit-html'
5
+
6
+ import { FilterConfig, FilterSelectRenderer } from '@operato/form'
7
+ import { i18next } from '@operato/i18n'
8
+ import { openPopup } from '@operato/layout'
9
+
10
+ type SelectedCallback = (value: { id: string; name: string; description: string }) => void
11
+
12
+ function openResourceSelector(filter: FilterConfig, value: any, confirmCallback: SelectedCallback) {
13
+ const { queryName, select, list, basicArgs, valueField = 'id' } = filter.options || {}
14
+
15
+ var actualValue
16
+ if (typeof valueField === 'function') {
17
+ actualValue = valueField(value)
18
+ } else {
19
+ actualValue = value?.[valueField]
20
+ }
21
+
22
+ var template = html`
23
+ <ox-selector-resource-id
24
+ .value=${actualValue}
25
+ .confirmCallback=${confirmCallback}
26
+ .queryName=${queryName}
27
+ .select=${select}
28
+ .list=${list}
29
+ .basicArgs=${basicArgs}
30
+ .valueField=${valueField}
31
+ ></ox-selector-resource-id>
32
+ `
33
+
34
+ const popup = openPopup(template, {
35
+ backdrop: true,
36
+ size: 'large',
37
+ title: i18next.t('title.select_item')
38
+ })
39
+ }
40
+
41
+ export const FilterResourceSelect: FilterSelectRenderer = (filter, value, owner) => {
42
+ const { name, operator = 'like' } = filter
43
+
44
+ return operator === 'like'
45
+ ? html` <input
46
+ type="text"
47
+ name=${name}
48
+ .value=${value}
49
+ @change=${(e: CustomEvent) => {
50
+ const input = e.target as HTMLInputElement
51
+ input.dispatchEvent(
52
+ new CustomEvent('filter-change', {
53
+ bubbles: true,
54
+ composed: true,
55
+ detail: {
56
+ name,
57
+ operator,
58
+ value: input.value
59
+ }
60
+ })
61
+ )
62
+ }}
63
+ />`
64
+ : operator == 'in'
65
+ ? html``
66
+ : operator === 'eq'
67
+ ? html`
68
+ <input
69
+ style="min-width: 100px; min-height: 24px"
70
+ type="text"
71
+ name=${name}
72
+ .value=${value}
73
+ readonly
74
+ @click=${(e: Event) => {
75
+ e.stopPropagation()
76
+
77
+ const confirmCallback = (selected?: { [field: string]: any }) => {
78
+ var { idField = 'id', nameField = 'name', descriptionField = 'description' } = filter.options || {}
79
+
80
+ owner.dispatchEvent(
81
+ new CustomEvent('filter-change', {
82
+ bubbles: true,
83
+ composed: true,
84
+ detail: selected ? selected[idField] : ''
85
+ })
86
+ )
87
+ }
88
+
89
+ openResourceSelector(filter, value, confirmCallback)
90
+ }}
91
+ />
92
+ `
93
+ : html``
94
+ }
@@ -0,0 +1,6 @@
1
+ import { registerFilterRenderer } from '@operato/form'
2
+
3
+ import { FilterResourceSelect } from './filter-resource-select.js'
4
+
5
+ registerFilterRenderer('resource-object', [FilterResourceSelect])
6
+ registerFilterRenderer('resource-id', [FilterResourceSelect])
@@ -1,8 +1,9 @@
1
- import { FieldRenderer } from '@operato/data-grist'
2
1
  import cronstrue from 'cronstrue/i18n'
3
- import { detectOverflow } from '@operato/utils'
4
- import { html } from 'lit'
5
2
  import i18next from 'i18next'
3
+ import { html } from 'lit'
4
+
5
+ import { FieldRenderer } from '@operato/data-grist'
6
+ import { detectOverflow } from '@operato/utils'
6
7
 
7
8
  function onmouseover(e: Event) {
8
9
  const element = e.target as HTMLSpanElement
@@ -21,7 +22,7 @@ export const OxGristRendererCrontab: FieldRenderer = (value, column, record, row
21
22
 
22
23
  try {
23
24
  const language = (i18next.language || 'en').substring(0, 2)
24
- text = value === undefined ? '' : cronstrue.toString(value, { locale: language || 'en' })
25
+ text = !value ? '' : cronstrue.toString(value, { locale: language || 'en' })
25
26
  } catch (e) {
26
27
  console.error(e)
27
28
  }
@@ -7,7 +7,11 @@ export const OxGristRendererResourceId: FieldRenderer = (value, column, record,
7
7
  return ''
8
8
  }
9
9
 
10
- var { nameField = 'name', descriptionField = 'description' } = column.record.options || {}
10
+ const { nameField = 'name', descriptionField = 'description' } = column.record.options || {}
11
11
 
12
- return html`<span>${value[nameField] || ''}(${value[descriptionField] || ''})</span> `
12
+ const name = value[nameField] || ''
13
+ const description = value[descriptionField] || ''
14
+ const suffix = description ? `(${description})` : ''
15
+
16
+ return html`<span>${name}${suffix}</span> `
13
17
  }
@@ -1,10 +1,10 @@
1
1
  import '@operato/input/ox-input-partition-keys.js'
2
2
 
3
- import { LitElement, css, html } from 'lit'
3
+ import { css, html, LitElement } from 'lit'
4
4
  import { customElement, property } from 'lit/decorators.js'
5
5
 
6
- import { ScrollbarStyles } from '@operato/styles'
7
6
  import { i18next } from '@operato/i18n'
7
+ import { ScrollbarStyles } from '@operato/styles'
8
8
 
9
9
  @customElement('ox-popup-partition-keys-input')
10
10
  export class OxPopupPartitionKeysInput extends LitElement {
@@ -24,6 +24,7 @@ export class OxPopupPartitionKeysInput extends LitElement {
24
24
  ox-input-partition-keys {
25
25
  flex: 1;
26
26
  overflow-y: auto;
27
+ padding: 10px;
27
28
  }
28
29
 
29
30
  span {
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './input/index.js'
2
- export * from './property-editor'
2
+ export * from './property-editor/index.js'
3
3
  export * from './grist-editor/index.js'
4
+ export * from './filter-renderer/index.js'
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import 'codemirror/addon/display/fullscreen'
6
+ import 'codemirror/addon/display/autorefresh'
7
+ import 'codemirror/addon/hint/show-hint'
8
+ import 'codemirror/addon/lint/lint'
9
+ import 'codemirror-graphql/hint'
10
+ import 'codemirror-graphql/lint'
11
+ import 'codemirror-graphql/mode'
12
+
13
+ import { GRAPHQL_URI, client } from '@operato/graphql'
14
+ import { LitElement, PropertyValues, css, html, unsafeCSS } from 'lit'
15
+ import { customElement, property, query } from 'lit/decorators.js'
16
+ import { introspectSchema, wrapSchema } from '@graphql-tools/wrap'
17
+
18
+ import CodeMirror from 'codemirror'
19
+ import CodeMirrorStyle from '!!text-loader!codemirror/lib/codemirror.css'
20
+ import FullScreenStyle from '!!text-loader!codemirror/addon/display/fullscreen.css'
21
+ import LintStyle from '!!text-loader!codemirror/addon/lint/lint.css'
22
+ import NightThemeStyle from '!!text-loader!codemirror/theme/night.css'
23
+ import ShowHintStyle from '!!text-loader!codemirror/addon/hint/show-hint.css'
24
+ import { fetch } from 'cross-fetch'
25
+ import { print } from 'graphql'
26
+
27
+ /**
28
+ WEB Component for code-mirror graphql editor.
29
+
30
+ Example:
31
+
32
+ <ox-input-graphql value=${text} link=${link}>
33
+ </ox-input-graphql>
34
+ */
35
+ @customElement('ox-input-graphql')
36
+ export default class OxInputGraphql extends LitElement {
37
+ static styles = [
38
+ css`
39
+ ${unsafeCSS(CodeMirrorStyle)}
40
+ ${unsafeCSS(FullScreenStyle)}
41
+ ${unsafeCSS(NightThemeStyle)}
42
+ ${unsafeCSS(LintStyle)}
43
+ ${unsafeCSS(ShowHintStyle)}
44
+ `,
45
+ css`
46
+ :host {
47
+ display: block;
48
+ position: relative;
49
+ }
50
+
51
+ textarea {
52
+ display: block;
53
+ height: 100%;
54
+ width: 100%;
55
+ resize: none;
56
+ font-size: 16px;
57
+ line-height: 20px;
58
+ border: 0px;
59
+ padding: 0px;
60
+ }
61
+ `
62
+ ]
63
+
64
+ /**
65
+ * `value`는 에디터에서 작성중인 contents이다.
66
+ */
67
+ @property({ type: String }) value?: string
68
+ @property({ type: String }) link?: string
69
+
70
+ @query('textarea') textarea!: HTMLTextAreaElement
71
+
72
+ private _self_changing: boolean = false
73
+ private _changed: boolean = false
74
+ private _editor?: CodeMirror.EditorFromTextArea
75
+
76
+ async updated(changes: PropertyValues<this>) {
77
+ if ((!this._editor || changes.has('value') || changes.has('link')) && !this._self_changing) {
78
+ if (changes.has('link')) {
79
+ this._editor = undefined
80
+ }
81
+ ;(await this.getEditor())!.setValue(this.value === undefined ? '' : String(this.value))
82
+ // ;(await this.getEditor()).refresh()
83
+ }
84
+ }
85
+
86
+ render() {
87
+ return html` <textarea></textarea> `
88
+ }
89
+
90
+ async getSchema() {
91
+ const executor = async ({ document, variables }: any) => {
92
+ const query = print(document)
93
+ const uri = this.link || GRAPHQL_URI
94
+
95
+ const fetchResult = await fetch(uri, {
96
+ method: 'POST',
97
+ headers: {
98
+ 'Content-Type': 'application/json'
99
+ },
100
+ body: JSON.stringify({ query, variables })
101
+ })
102
+ return fetchResult.json()
103
+ }
104
+
105
+ return await wrapSchema({
106
+ schema: await introspectSchema(executor),
107
+ executor
108
+ })
109
+ }
110
+
111
+ async getEditor() {
112
+ if (!this._editor) {
113
+ try {
114
+ var schema = await this.getSchema()
115
+ } catch (err) {
116
+ console.error(err)
117
+ }
118
+
119
+ if (this.textarea) {
120
+ this._editor = CodeMirror.fromTextArea(this.textarea, {
121
+ value: this.value,
122
+ mode: 'graphql',
123
+ lint: {
124
+ //@ts-ignore
125
+ schema
126
+ },
127
+ hintOptions: {
128
+ //@ts-ignore
129
+ schema
130
+ },
131
+ tabSize: 2,
132
+ lineNumbers: false,
133
+ showCursorWhenSelecting: true,
134
+ theme: 'night',
135
+ extraKeys: {
136
+ F11: function (cm) {
137
+ cm.setOption('fullScreen', !cm.getOption('fullScreen'))
138
+ },
139
+ Esc: function (cm) {
140
+ cm.setOption('fullScreen', !cm.getOption('fullScreen'))
141
+ }
142
+ },
143
+ autoRefresh: {
144
+ delay: 500
145
+ }
146
+ })
147
+
148
+ this._editor.on('blur', (editor: CodeMirror.Editor, e: FocusEvent) => {
149
+ if (!this._changed) return
150
+
151
+ this.value = editor.getValue()
152
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
153
+ })
154
+
155
+ this._editor.on('change', async (editor: CodeMirror.Editor, changeObj: CodeMirror.EditorChange) => {
156
+ this._self_changing = true
157
+
158
+ this._changed = true
159
+
160
+ await this.requestUpdate()
161
+
162
+ this._self_changing = false
163
+ })
164
+ }
165
+ }
166
+
167
+ return this._editor
168
+ }
169
+ }
@@ -13,9 +13,10 @@ import '@operato/property-editor/ox-property-editor-color.js'
13
13
  import '@operato/property-editor/ox-property-editor-multiple-colors.js'
14
14
  import '@operato/property-editor/ox-property-editor-solid-colorstops.js'
15
15
  import '@operato/property-editor/ox-property-editor-gradient-colorstops.js'
16
- import '@operato/property-editor/ox-property-editor-gradient-colorstops.js'
17
16
  import '@operato/property-editor/ox-property-editor-textarea.js'
18
17
  import '@operato/property-editor/ox-property-editor-table.js'
18
+ import '@operato/property-editor/ox-property-editor-key-values.js'
19
+ import '@operato/property-editor/ox-property-editor-partition-keys.js'
19
20
  import '@operato/property-editor/ox-property-editor-value-map.js'
20
21
  import '@operato/property-editor/ox-property-editor-value-ranges.js'
21
22
  import '@operato/attachment/ox-property-editor-attachment-selector.js'
@@ -55,5 +56,7 @@ OxPropertyEditor.register({
55
56
  graphql: 'ox-property-editor-graphql',
56
57
  'editor-table': 'ox-property-editor-table',
57
58
  'id-input': 'ox-property-editor-scene-component-id',
58
- 'font-selector': 'ox-property-editor-font-selector'
59
+ 'font-selector': 'ox-property-editor-font-selector',
60
+ 'partition-keys': 'ox-property-editor-partion-keys',
61
+ 'key-values': 'ox-property-editor-key-values'
59
62
  })