@things-factory/id-rule-base 8.0.0-beta.9 → 8.0.0

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.
@@ -0,0 +1,8 @@
1
+ import { registerEditor } from '@operato/data-grist'
2
+
3
+ import { GristCodeInput } from './editors/grist-code-input'
4
+
5
+ export default function bootstrap() {
6
+ /* id-rule 의 GristRenderer는 텍스트와 같으므로, 별도로 정의하지 않음. */
7
+ registerEditor('id-rule', GristCodeInput)
8
+ }
@@ -0,0 +1,196 @@
1
+ import '@material/web/button/elevated-button.js'
2
+ import '@operato/i18n/ox-i18n.js'
3
+ import '@operato/input/ox-input-code.js'
4
+
5
+ import gql from 'graphql-tag'
6
+ import { css, html, LitElement } from 'lit'
7
+ import { customElement, property, query, state } from 'lit/decorators.js'
8
+
9
+ import { i18next } from '@operato/i18n'
10
+ import { client } from '@operato/graphql'
11
+ import { ColumnConfig, GristRecord } from '@operato/data-grist'
12
+ import { OxInputCode } from '@operato/input'
13
+
14
+ const FETCH_ID_RULE_GQL = type => {
15
+ return gql`
16
+ {
17
+ idRule(type:"${type}") {
18
+ id,
19
+ type,
20
+ rule
21
+ }
22
+ }
23
+ `
24
+ }
25
+
26
+ @customElement('grist-code-input-popup')
27
+ export class GristCodeInputPopup extends LitElement {
28
+ static styles = [
29
+ css`
30
+ :host {
31
+ display: flex;
32
+ flex-direction: column;
33
+ padding: 0;
34
+ align-items: center;
35
+ box-sizing: border-box;
36
+ width: 100%;
37
+ border: 0;
38
+ color: var(--popup-content-color);
39
+ background-color: var(--popup-content-background-color);
40
+
41
+ font: var(--grist-object-editor-font);
42
+
43
+ justify-content: inherit;
44
+ }
45
+
46
+ :host * {
47
+ box-sizing: border-box;
48
+ }
49
+
50
+ #wrapper {
51
+ flex: 1;
52
+ width: 100%;
53
+ display: flex;
54
+ flex-direction: column;
55
+ padding: 5px;
56
+ }
57
+
58
+ #wrapper > h4 {
59
+ margin: 0;
60
+ }
61
+
62
+ #wrapper > ul {
63
+ width: 100%;
64
+ }
65
+
66
+ #wrapper > ul > li {
67
+ display: flex;
68
+ }
69
+ #wrapper > ul > li > span {
70
+ font-weight: bold;
71
+ flex-basis: 200px;
72
+ }
73
+
74
+ #wrapper > ul > li > ox-i18n {
75
+ flex: 1;
76
+ }
77
+
78
+ ox-input-code {
79
+ width: 100%;
80
+ flex: 1;
81
+ }
82
+
83
+ #footer {
84
+ display: flex;
85
+ justify-content: flex-end;
86
+ }
87
+ `
88
+ ]
89
+
90
+ @property({ type: String }) value?: string
91
+ @property({ type: Object }) column?: ColumnConfig
92
+ @property({ type: Object }) record?: GristRecord
93
+ @property({ type: Number }) row?: number
94
+ @property({ type: Object }) field?: any
95
+ @property({ type: Object }) _idRule?: any
96
+ @property({ type: Object }) headers?: { [header: string]: string }
97
+
98
+ @query('ox-input-code') ruleEditor!: OxInputCode
99
+
100
+ render() {
101
+ return html`
102
+ <div id="wrapper">
103
+ <h4><ox-i18n msgid="label.arguments"></ox-i18n></h4>
104
+ <ul>
105
+ <li><span>domain</span><ox-i18n msgid="label.argument domain description"></ox-i18n></li>
106
+ <li><span>seed</span><ox-i18n msgid="label.argument seed description"></ox-i18n></li>
107
+ </ul>
108
+ <ox-input-code id="rule-editor" type="text" .value=${(this._idRule || {}).rule}></ox-input-code>
109
+
110
+ <div id="footer">
111
+ <md-elevated-button
112
+ label=${String(i18next.t('button.save'))}
113
+ @click=${(e: Event) => {
114
+ this.updateIdRule()
115
+ }}
116
+ ></md-elevated-button>
117
+ </div>
118
+ </div>
119
+ `
120
+ }
121
+
122
+ updated(changed) {
123
+ if (changed.has('value')) {
124
+ if (this.value && typeof this.value === 'string') {
125
+ this.getRule()
126
+ }
127
+ }
128
+ }
129
+
130
+ async getRule() {
131
+ var response = await client.query({
132
+ query: FETCH_ID_RULE_GQL(this.value)
133
+ })
134
+
135
+ let idRule = response.data.idRule
136
+ if (!idRule) {
137
+ idRule = await this.createIdRule()
138
+ }
139
+
140
+ this._idRule = idRule
141
+ this.requestUpdate()
142
+ }
143
+
144
+ async createIdRule() {
145
+ var idRule = {
146
+ type: this.value,
147
+ rule: `return ''`
148
+ }
149
+
150
+ return (
151
+ await client.mutate({
152
+ mutation: gql`
153
+ mutation createIdRule($idRule: NewIdRule!) {
154
+ createIdRule(idRule: $idRule) {
155
+ type
156
+ rule
157
+ }
158
+ }
159
+ `,
160
+ variables: { idRule }
161
+ })
162
+ ).data?.createIdRule
163
+ }
164
+
165
+ async updateIdRule() {
166
+ if (!this._idRule) console.error('ID Rule not found')
167
+
168
+ const rule = this.ruleEditor.value
169
+
170
+ const type = this._idRule.type
171
+
172
+ const patch = {
173
+ ...this._idRule,
174
+ rule
175
+ }
176
+
177
+ await client.mutate({
178
+ mutation: gql`
179
+ mutation updateIdRule($type: String!, $patch: IdRulePatch!) {
180
+ updateIdRule(type: $type, patch: $patch) {
181
+ type
182
+ rule
183
+ }
184
+ }
185
+ `,
186
+ variables: { type, patch }
187
+ })
188
+
189
+ this.dispatchEvent(
190
+ new CustomEvent('close-popup', {
191
+ bubbles: true,
192
+ composed: true
193
+ })
194
+ )
195
+ }
196
+ }
@@ -0,0 +1,121 @@
1
+ import '@material/web/icon/icon.js'
2
+
3
+ import { css, html } from 'lit'
4
+ import { customElement, property } from 'lit/decorators.js'
5
+ import { OxGristEditor } from '@operato/data-grist'
6
+ import { i18next } from '@operato/i18n'
7
+ import { OxPopup } from '@operato/popup'
8
+
9
+ import './grist-code-input-popup'
10
+
11
+ @customElement('grist-code-input')
12
+ export class GristCodeInput extends OxGristEditor {
13
+ static styles = [
14
+ css`
15
+ :host {
16
+ display: flex;
17
+ flex-flow: row nowrap;
18
+ align-items: center;
19
+
20
+ padding: 7px 0px;
21
+ box-sizing: border-box;
22
+
23
+ width: 100%;
24
+ height: 100%;
25
+
26
+ border: 0;
27
+ background-color: transparent;
28
+
29
+ font: var(--grist-object-editor-font);
30
+ color: var(--grist-object-editor-color);
31
+
32
+ justify-content: inherit;
33
+ }
34
+
35
+ md-icon {
36
+ width: 20px;
37
+ font-size: 1.5em;
38
+ }
39
+
40
+ #popup {
41
+ display: flex;
42
+ overflow: hidden;
43
+ }
44
+
45
+ input {
46
+ border: none;
47
+ background-color: transparent;
48
+ }
49
+
50
+ input:focus {
51
+ outline: none;
52
+ border: none;
53
+ }
54
+ `
55
+ ]
56
+
57
+ @property({ type: Object }) headers?: Object
58
+ @property({ type: Object }) popup?: OxPopup | null
59
+
60
+ render() {
61
+ return html`
62
+ <input
63
+ type="text"
64
+ .value=${this.value}
65
+ .record=${this.record}
66
+ .column=${this.column}
67
+ .field=${this.column}
68
+ .row=${this.row}
69
+ ></input>
70
+
71
+ <md-icon id="more" @click=${e => this.openPopup()}>more_vert</md-icon>
72
+ `
73
+ }
74
+
75
+ async firstUpdated() {
76
+ await this.updateComplete
77
+ await super.firstUpdated()
78
+ }
79
+
80
+ openPopup() {
81
+ if (this.record.__dirty__) {
82
+ document.dispatchEvent(
83
+ new CustomEvent('notify', {
84
+ detail: {
85
+ level: 'error',
86
+ message: i18next.t('text.please_save_your_modifications_first')
87
+ }
88
+ })
89
+ )
90
+
91
+ return
92
+ }
93
+
94
+ document.dispatchEvent(
95
+ new CustomEvent('open-popup', {
96
+ detail: {
97
+ template: html`
98
+ <grist-code-input-popup
99
+ .value=${this.value}
100
+ .column=${this.column}
101
+ .record=${this.record}
102
+ .row=${this.row}
103
+ .field=${this.field}
104
+ .headers=${this.headers}
105
+ @close-popup=${e => {
106
+ this.popup?.close()
107
+ this.popup = null
108
+ }}
109
+ ></grist-code-input-popup>
110
+ `,
111
+ options: {
112
+ title: i18next.t('title.ID Rule Editor')
113
+ },
114
+ callback: popup => {
115
+ this.popup = popup
116
+ }
117
+ }
118
+ })
119
+ )
120
+ }
121
+ }
File without changes