@operato/app 1.0.0-beta.1 → 1.0.0-beta.4

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 (40) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/src/filter-renderer/filter-resource-select.d.ts +4 -0
  3. package/dist/src/filter-renderer/filter-resource-select.js +79 -0
  4. package/dist/src/filter-renderer/filter-resource-select.js.map +1 -0
  5. package/dist/src/filter-renderer/index.d.ts +1 -0
  6. package/dist/src/filter-renderer/index.js +5 -0
  7. package/dist/src/filter-renderer/index.js.map +1 -0
  8. package/dist/src/grist-editor/ox-grist-editor-code.js +5 -8
  9. package/dist/src/grist-editor/ox-grist-editor-code.js.map +1 -1
  10. package/dist/src/grist-editor/ox-grist-editor-partition-keys.js +3 -3
  11. package/dist/src/grist-editor/ox-grist-editor-partition-keys.js.map +1 -1
  12. package/dist/src/grist-editor/ox-grist-editor-resource-id.d.ts +1 -2
  13. package/dist/src/grist-editor/ox-grist-editor-resource-id.js +9 -7
  14. package/dist/src/grist-editor/ox-grist-editor-resource-id.js.map +1 -1
  15. package/dist/src/grist-editor/ox-grist-editor-resource-object.js +17 -15
  16. package/dist/src/grist-editor/ox-grist-editor-resource-object.js.map +1 -1
  17. package/dist/src/grist-editor/ox-selector-resource-id.d.ts +3 -2
  18. package/dist/src/grist-editor/ox-selector-resource-id.js +8 -3
  19. package/dist/src/grist-editor/ox-selector-resource-id.js.map +1 -1
  20. package/dist/src/grist-editor/ox-selector-resource-object.d.ts +3 -2
  21. package/dist/src/grist-editor/ox-selector-resource-object.js +8 -3
  22. package/dist/src/grist-editor/ox-selector-resource-object.js.map +1 -1
  23. package/dist/src/index.d.ts +2 -1
  24. package/dist/src/index.js +2 -1
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/input/ox-input-resource.d.ts +36 -0
  27. package/dist/src/input/ox-input-resource.js +161 -0
  28. package/dist/src/input/ox-input-resource.js.map +1 -0
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +16 -15
  31. package/src/filter-renderer/filter-resource-select.ts +95 -0
  32. package/src/filter-renderer/index.ts +6 -0
  33. package/src/grist-editor/ox-grist-editor-code.ts +6 -8
  34. package/src/grist-editor/ox-grist-editor-partition-keys.ts +4 -4
  35. package/src/grist-editor/ox-grist-editor-resource-id.ts +12 -10
  36. package/src/grist-editor/ox-grist-editor-resource-object.ts +19 -17
  37. package/src/grist-editor/ox-selector-resource-id.ts +10 -4
  38. package/src/grist-editor/ox-selector-resource-object.ts +11 -5
  39. package/src/index.ts +2 -1
  40. package/src/input/ox-input-resource.ts +169 -0
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.1",
6
+ "version": "1.0.0-beta.4",
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.1",
62
- "@operato/data-grist": "^1.0.0-beta.1",
63
- "@operato/font": "^1.0.0-beta.1",
64
- "@operato/form": "^1.0.0-beta.1",
65
- "@operato/graphql": "^1.0.0-beta.1",
66
- "@operato/i18n": "^1.0.0-beta.1",
67
- "@operato/input": "^1.0.0-beta.1",
68
- "@operato/layout": "^1.0.0-beta.1",
69
- "@operato/property-editor": "^1.0.0-beta.1",
70
- "@operato/shell": "^1.0.0-beta.1",
71
- "@operato/styles": "^1.0.0-beta.1",
72
- "@operato/utils": "^1.0.0-beta.1",
62
+ "@operato/attachment": "^1.0.0-beta.4",
63
+ "@operato/data-grist": "^1.0.0-beta.4",
64
+ "@operato/font": "^1.0.0-beta.4",
65
+ "@operato/form": "^1.0.0-beta.4",
66
+ "@operato/graphql": "^1.0.0-beta.4",
67
+ "@operato/i18n": "^1.0.0-beta.4",
68
+ "@operato/input": "^1.0.0-beta.4",
69
+ "@operato/layout": "^1.0.0-beta.4",
70
+ "@operato/property-editor": "^1.0.0-beta.4",
71
+ "@operato/shell": "^1.0.0-beta.4",
72
+ "@operato/styles": "^1.0.0-beta.4",
73
+ "@operato/utils": "^1.0.0-beta.4",
73
74
  "codemirror": "^5.59.1",
74
75
  "codemirror-graphql": "^0.15.2",
75
76
  "cronstrue": "^2.2.0",
@@ -110,5 +111,5 @@
110
111
  "prettier --write"
111
112
  ]
112
113
  },
113
- "gitHead": "cfa0be4c72d93b2bf3f851c09b5c62c6025edf0f"
114
+ "gitHead": "08201dc8c015c0d6ccceb846907dd9950363a553"
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])
@@ -1,8 +1,9 @@
1
1
  import './ox-popup-code-input.js'
2
2
 
3
- import { OxGristEditor } from '@operato/data-grist'
4
- import { customElement } from 'lit/decorators.js'
5
3
  import { html } from 'lit'
4
+ import { customElement } from 'lit/decorators.js'
5
+
6
+ import { OxGristEditor } from '@operato/data-grist'
6
7
  import { i18next } from '@operato/i18n'
7
8
  import { openPopup } from '@operato/layout'
8
9
 
@@ -29,7 +30,7 @@ export class OxGristEditorCode extends OxGristEditor {
29
30
 
30
31
  var change = (value: string) => {
31
32
  this.dispatchEvent(
32
- new CustomEvent('change', {
33
+ new CustomEvent('field-change', {
33
34
  bubbles: true,
34
35
  composed: true,
35
36
  detail: {
@@ -48,15 +49,12 @@ export class OxGristEditorCode extends OxGristEditor {
48
49
  <ox-popup-code-input
49
50
  .value=${this.value}
50
51
  mode=${mode}
51
- @change=${(e: CustomEvent) => {
52
- change(e.detail.value)
53
- popup.close()
54
- }}
52
+ .confirmCallback=${change.bind(this)}
55
53
  ></ox-popup-code-input>
56
54
  `,
57
55
  {
58
56
  backdrop: true,
59
- title: i18next.t('title.setting schedule'),
57
+ title: i18next.t('title.edit code'),
60
58
  help: 'data-grist/grist-editor/code'
61
59
  }
62
60
  )
@@ -4,13 +4,13 @@
4
4
 
5
5
  import './ox-popup-partition-keys-input.js'
6
6
 
7
- import { PopupHandle, openPopup } from '@operato/layout'
8
- import { customElement, property } from 'lit/decorators.js'
7
+ import { html } from 'lit'
8
+ import { customElement } from 'lit/decorators.js'
9
+ import { cloneDeep } from 'lodash-es'
9
10
 
10
11
  import { OxGristEditor } from '@operato/data-grist'
11
- import { cloneDeep } from 'lodash-es'
12
- import { html } from 'lit'
13
12
  import { i18next } from '@operato/i18n'
13
+ import { openPopup, PopupHandle } from '@operato/layout'
14
14
 
15
15
  @customElement('ox-grist-editor-partition-keys')
16
16
  export class OxGristEditorPartitionKeys extends OxGristEditor {
@@ -1,12 +1,12 @@
1
1
  import '@material/mwc-icon'
2
2
  import './ox-selector-resource-id.js'
3
3
 
4
- import { GristRecord, OxGristEditor } from '@operato/data-grist'
5
- import { PopupHandle, openPopup } from '@operato/layout'
6
- import { TemplateResult, html } from 'lit'
7
-
4
+ import { html } from 'lit'
8
5
  import { customElement } from 'lit/decorators.js'
9
6
 
7
+ import { GristRecord, OxGristEditor } from '@operato/data-grist'
8
+ import { openPopup, PopupHandle } from '@operato/layout'
9
+
10
10
  @customElement('ox-input-resource-id')
11
11
  export class OxGristEditorResourceId extends OxGristEditor {
12
12
  private popup?: PopupHandle
@@ -38,7 +38,7 @@ export class OxGristEditorResourceId extends OxGristEditor {
38
38
  delete this.popup
39
39
  }
40
40
 
41
- const confirmCallback: (record: GristRecord | undefined) => void = selected => {
41
+ const confirmCallback: (record?: GristRecord) => void = selected => {
42
42
  if (!selected) {
43
43
  return
44
44
  }
@@ -51,11 +51,13 @@ export class OxGristEditorResourceId extends OxGristEditor {
51
51
  composed: true,
52
52
  detail: {
53
53
  before: this.value,
54
- after: {
55
- [idField]: selected[idField],
56
- [nameField]: selected[nameField],
57
- [descriptionField]: selected[descriptionField]
58
- },
54
+ after: selected
55
+ ? {
56
+ [idField]: selected[idField],
57
+ [nameField]: selected[nameField],
58
+ [descriptionField]: selected[descriptionField]
59
+ }
60
+ : null,
59
61
  record: this.record,
60
62
  column: this.column,
61
63
  row: this.row
@@ -1,12 +1,12 @@
1
1
  import '@material/mwc-icon'
2
2
  import './ox-selector-resource-object.js'
3
3
 
4
- import { PopupHandle, openPopup } from '@operato/layout'
5
- import { TemplateResult, css, html } from 'lit'
4
+ import { html, TemplateResult } from 'lit'
5
+ import { customElement } from 'lit/decorators.js'
6
6
 
7
7
  import { OxGristEditor } from '@operato/data-grist'
8
- import { customElement } from 'lit/decorators.js'
9
8
  import { i18next } from '@operato/i18n'
9
+ import { openPopup, PopupHandle } from '@operato/layout'
10
10
 
11
11
  @customElement('ox-grist-editor-resource-object')
12
12
  export class OxGristEditorResourceObject extends OxGristEditor {
@@ -55,7 +55,7 @@ export class OxGristEditorResourceObject extends OxGristEditor {
55
55
  delete this.popup
56
56
  }
57
57
 
58
- const confirmCallback = (selected: { [field: string]: any }) => {
58
+ const confirmCallback = (selected?: { [field: string]: any }) => {
59
59
  var { idField = 'id', nameField = 'name', descriptionField = 'description' } = this.column.record.options || {}
60
60
 
61
61
  this.dispatchEvent(
@@ -64,19 +64,21 @@ export class OxGristEditorResourceObject extends OxGristEditor {
64
64
  composed: true,
65
65
  detail: {
66
66
  before: this.value,
67
- after: {
68
- ...(this.column.record.options.select || [])
69
- .map((field: any) => field.name)
70
- .reduce((obj: { [field: string]: any }, fieldName: string) => {
71
- return (obj = {
72
- ...obj,
73
- [fieldName]: selected[fieldName]
74
- })
75
- }, {} as { [field: string]: any }),
76
- [idField]: selected[idField],
77
- [nameField]: selected[nameField],
78
- [descriptionField]: selected[descriptionField]
79
- },
67
+ after: selected
68
+ ? {
69
+ ...(this.column.record.options.select || [])
70
+ .map((field: any) => field.name)
71
+ .reduce((obj: { [field: string]: any }, fieldName: string) => {
72
+ return (obj = {
73
+ ...obj,
74
+ [fieldName]: selected[fieldName]
75
+ })
76
+ }, {} as { [field: string]: any }),
77
+ [idField]: selected[idField],
78
+ [nameField]: selected[nameField],
79
+ [descriptionField]: selected[descriptionField]
80
+ }
81
+ : null,
80
82
  record: this.record,
81
83
  column: this.column,
82
84
  row: this.row
@@ -1,11 +1,11 @@
1
1
  import '@operato/data-grist'
2
2
 
3
- import { DataGrist, FetchOption, GristData, GristRecord, ZERO_DATA } from '@operato/data-grist'
4
- import { LitElement, css, html } from 'lit'
3
+ import gql from 'graphql-tag'
4
+ import { css, html, LitElement } from 'lit'
5
5
  import { customElement, property, query } from 'lit/decorators.js'
6
6
 
7
+ import { DataGrist, FetchOption, GristData, GristRecord, ZERO_DATA } from '@operato/data-grist'
7
8
  import { client } from '@operato/graphql'
8
- import gql from 'graphql-tag'
9
9
  import { i18next } from '@operato/i18n'
10
10
  import { isMobileDevice } from '@operato/utils'
11
11
 
@@ -47,7 +47,7 @@ export class OxSelectorResourceId extends LitElement {
47
47
  @property({ type: Object }) data: GristData = ZERO_DATA
48
48
  @property({ type: String }) queryName!: string
49
49
  @property({ type: Object }) basicArgs: any
50
- @property({ type: Object }) confirmCallback?: (record: GristRecord | undefined) => void
50
+ @property({ type: Object }) confirmCallback?: (record?: GristRecord) => void
51
51
  @property({ type: Array }) selectedRecords: GristRecord[] = []
52
52
 
53
53
  @query('ox-grist') grist!: DataGrist
@@ -66,12 +66,18 @@ export class OxSelectorResourceId extends LitElement {
66
66
  </ox-grist>
67
67
 
68
68
  <div class="button-container">
69
+ <mwc-button @click=${this.onempty.bind(this)}>${i18next.t('button.empty')}</mwc-button>
69
70
  <mwc-button @click=${this.oncancel.bind(this)}>${i18next.t('button.cancel')}</mwc-button>
70
71
  <mwc-button @click=${this.onconfirm.bind(this)}>${i18next.t('button.confirm')}</mwc-button>
71
72
  </div>
72
73
  `
73
74
  }
74
75
 
76
+ onempty() {
77
+ this.confirmCallback && this.confirmCallback()
78
+ history.back()
79
+ }
80
+
75
81
  oncancel() {
76
82
  history.back()
77
83
  }
@@ -1,6 +1,10 @@
1
1
  import '@operato/data-grist'
2
2
  import '@operato/form/ox-search-form.js'
3
3
 
4
+ import gql from 'graphql-tag'
5
+ import { css, html, LitElement } from 'lit'
6
+ import { customElement, property, query } from 'lit/decorators.js'
7
+
4
8
  import {
5
9
  ColumnConfig,
6
10
  DataGrist,
@@ -11,12 +15,8 @@ import {
11
15
  GristRecord,
12
16
  ZERO_DATA
13
17
  } from '@operato/data-grist'
14
- import { LitElement, css, html } from 'lit'
15
18
  import { MultiColumnFormStyles, SearchForm } from '@operato/form'
16
19
  import { buildArgs, client, gqlContext } from '@operato/graphql'
17
- import { customElement, property, query } from 'lit/decorators.js'
18
-
19
- import gql from 'graphql-tag'
20
20
  import { i18next } from '@operato/i18n'
21
21
  import { isMobileDevice } from '@operato/utils'
22
22
 
@@ -57,7 +57,7 @@ export class OxSelectorResourceObject extends LitElement {
57
57
  @property({ type: Object }) data: GristData = ZERO_DATA
58
58
  @property({ type: String }) queryName!: string
59
59
  @property({ type: Object }) basicArgs: any
60
- @property({ type: Object }) confirmCallback?: (record: GristRecord | undefined) => void
60
+ @property({ type: Object }) confirmCallback?: (record?: GristRecord | null) => void
61
61
  @property({ type: Array }) selectedRecords: GristRecord[] = []
62
62
 
63
63
  @property({ type: Array }) searchFields: any
@@ -99,12 +99,18 @@ export class OxSelectorResourceObject extends LitElement {
99
99
  ></ox-grist>
100
100
 
101
101
  <div class="button-container">
102
+ <mwc-button @click=${this.onempty.bind(this)}>${i18next.t('button.empty')}</mwc-button>
102
103
  <mwc-button @click=${this.oncancel.bind(this)}>${i18next.t('button.cancel')}</mwc-button>
103
104
  <mwc-button @click=${this.onconfirm.bind(this)}>${i18next.t('button.confirm')}</mwc-button>
104
105
  </div>
105
106
  `
106
107
  }
107
108
 
109
+ onempty() {
110
+ this.confirmCallback && this.confirmCallback()
111
+ history.back()
112
+ }
113
+
108
114
  oncancel() {
109
115
  history.back()
110
116
  }
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
+ }