@things-factory/reference-app 3.7.1 → 3.7.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,23 +1,23 @@
1
1
  import '@things-factory/auth-ui' /* for domain-switch */
2
2
  import '@things-factory/barcode-base' /* for <default-label-printer-setting-let> */
3
3
  import '@things-factory/notification' /* for notification-badge */
4
+ import './components/ocr-viewpart'
4
5
 
5
- import { html } from 'lit-html'
6
-
7
- import { APPEND_APP_TOOL } from '@things-factory/apptool-base'
8
- import { auth } from '@things-factory/auth-base'
9
- import { setAuthManagementMenus } from '@things-factory/auth-ui'
10
- import { getEditor, registerEditor, registerRenderer } from '@things-factory/grist-ui'
11
- import { appendViewpart, toggleOverlay, TOOL_POSITION, VIEWPART_POSITION } from '@things-factory/layout-base'
6
+ import { TOOL_POSITION, VIEWPART_POSITION, appendViewpart, toggleOverlay } from '@things-factory/layout-base'
7
+ import { getEditor, registerEditor, registerRenderer } from '@operato/data-grist'
8
+ import { navigate, store } from '@things-factory/shell'
12
9
  import { setupMenuPart, updateMenuTemplate } from '@things-factory/lite-menu'
10
+
13
11
  import { ADD_MORENDA } from '@things-factory/more-base'
14
12
  import { ADD_SETTING } from '@things-factory/setting-base'
15
- import { navigate, store } from '@things-factory/shell'
16
-
17
- import { IdEditor } from './editors/id-editor'
18
- import { getMenuTemplate } from './menu'
13
+ import { APPEND_APP_TOOL } from '@things-factory/apptool-base'
19
14
  import { BarcodeRenderer } from './renderers/barcode-renderer'
15
+ import { IdEditor } from './editors/id-editor'
20
16
  import { IdRenderer } from './renderers/id-renderer'
17
+ import { auth } from '@things-factory/auth-base'
18
+ import { getMenuTemplate } from './menu'
19
+ import { html } from 'lit-html'
20
+ import { setAuthManagementMenus } from '@things-factory/auth-ui'
21
21
 
22
22
  console.log(
23
23
  `%c
@@ -135,6 +135,24 @@ export default function bootstrap() {
135
135
  })
136
136
 
137
137
  /* setting app-tools */
138
+ store.dispatch({
139
+ type: APPEND_APP_TOOL,
140
+ tool: {
141
+ name: 'ocr-toggler',
142
+ template: html`
143
+ <mwc-icon
144
+ @click=${e => {
145
+ toggleOverlay('ocr-viewpart', {
146
+ backdrop: false
147
+ })
148
+ }}
149
+ >camera_enhance
150
+ </mwc-icon>
151
+ `,
152
+ position: TOOL_POSITION.REAR
153
+ }
154
+ })
155
+
138
156
  store.dispatch({
139
157
  type: APPEND_APP_TOOL,
140
158
  tool: {
@@ -163,6 +181,17 @@ export default function bootstrap() {
163
181
  position: VIEWPART_POSITION.HEADERBAR
164
182
  })
165
183
 
184
+ appendViewpart({
185
+ name: 'ocr-viewpart',
186
+ viewpart: {
187
+ show: false,
188
+ hovering: false,
189
+ resizable: true,
190
+ template: html` <ocr-viewpart style="min-width: 300px; height: 100%; width: 50vw;"></ocr-viewpart> `
191
+ },
192
+ position: VIEWPART_POSITION.ASIDEBAR
193
+ })
194
+
166
195
  appendViewpart({
167
196
  name: 'notification',
168
197
  viewpart: {
@@ -1,4 +1,4 @@
1
- import { LitElement, css, html } from 'lit-element'
1
+ import { css, html, LitElement } from 'lit-element'
2
2
 
3
3
  import { FileDropHelper } from '@things-factory/utils'
4
4
 
@@ -90,7 +90,7 @@ export class CameraCapturer extends LitElement {
90
90
  accept=${this.accept}
91
91
  ?multiple=${this.multiple}
92
92
  hidden
93
- capture="camera"
93
+ capture="environment"
94
94
  @change=${e => {
95
95
  const fileInput = e.currentTarget
96
96
 
@@ -119,8 +119,16 @@ export class CameraCapturer extends LitElement {
119
119
  - ${file.name}
120
120
  <mwc-icon
121
121
  @click=${e => {
122
- this._files.splice(this._files.indexOf(file), 1)
123
- this.requestUpdate()
122
+ this._files = [...this._files.splice(this._files.indexOf(file), 1)]
123
+ this.dispatchEvent(
124
+ new CustomEvent('files-change', {
125
+ bubbles: true,
126
+ composed: true,
127
+ detail: {
128
+ files: this._files
129
+ }
130
+ })
131
+ )
124
132
  }}
125
133
  >delete_outline</mwc-icon
126
134
  >
@@ -137,6 +145,15 @@ export class CameraCapturer extends LitElement {
137
145
 
138
146
  this.addEventListener('file-drop', e => {
139
147
  this._files = this.multiple ? e.detail : e.detail[0] ? [e.detail[0]] : []
148
+ this.dispatchEvent(
149
+ new CustomEvent('files-change', {
150
+ bubbles: true,
151
+ composed: true,
152
+ detail: {
153
+ files: this._files
154
+ }
155
+ })
156
+ )
140
157
  })
141
158
  }
142
159
 
@@ -151,6 +168,16 @@ export class CameraCapturer extends LitElement {
151
168
  reset() {
152
169
  this.fileInput.value = ''
153
170
  this._files = []
171
+
172
+ this.dispatchEvent(
173
+ new CustomEvent('files-change', {
174
+ bubbles: true,
175
+ composed: true,
176
+ detail: {
177
+ files: this._files
178
+ }
179
+ })
180
+ )
154
181
  }
155
182
  }
156
183
 
@@ -0,0 +1,150 @@
1
+ import './camera-capturer'
2
+ import '@material/mwc-button'
3
+
4
+ import { LitElement, css, html } from 'lit-element'
5
+
6
+ import { client } from '@things-factory/shell'
7
+ import { gql } from 'graphql-tag'
8
+
9
+ class OCRViewPart extends LitElement {
10
+ static get styles() {
11
+ return [
12
+ css`
13
+ :host {
14
+ display: flex;
15
+ flex-direction: column;
16
+ min-width: 240px;
17
+ }
18
+
19
+ [buttons] {
20
+ display: flex;
21
+ flex-direction: row-reverse;
22
+ }
23
+
24
+ #images {
25
+ flex: 1;
26
+ background-color: black;
27
+ color: white;
28
+
29
+ display: flex;
30
+ flex-direction: column;
31
+ }
32
+
33
+ [tab] {
34
+ display: flex;
35
+ flex-direction: row;
36
+ }
37
+
38
+ [i] {
39
+ min-width: 50px;
40
+ background-color: black;
41
+ text-align: center;
42
+ }
43
+
44
+ [i][active] {
45
+ background-color: red;
46
+ }
47
+
48
+ [image] {
49
+ flex: 1;
50
+
51
+ display: flex;
52
+ flex-direction: column;
53
+ justify-content: center;
54
+ }
55
+
56
+ img {
57
+ style=width: 100%;
58
+ }
59
+ `
60
+ ]
61
+ }
62
+
63
+ static get properties() {
64
+ return {
65
+ _files: Array,
66
+ index: Number
67
+ }
68
+ }
69
+
70
+ render() {
71
+ const files = this._files || []
72
+ const index = this.index || 0
73
+ const file = files[index]
74
+ const image = file && URL.createObjectURL(file)
75
+ if (image) {
76
+ requestAnimationFrame(() => URL.revokeObjectURL(image))
77
+ }
78
+
79
+ return html`
80
+ <div attachment-wrap>
81
+ <camera-capturer
82
+ name="scanner"
83
+ id="capturer"
84
+ label="Capture Images"
85
+ accept="image/*"
86
+ multiple="true"
87
+ ?hidden=${false}
88
+ custom-input
89
+ @files-change=${e => this.fileschange(e)}
90
+ ></camera-capturer>
91
+ </div>
92
+ <div buttons>
93
+ <mwc-button @click=${e => this.upload()}>submit</mwc-button>
94
+ <mwc-button @click=${e => this.reset()}>reset</mwc-button>
95
+ </div>
96
+ <div id="images">
97
+ <div
98
+ tab
99
+ @click=${e => {
100
+ const item = e.target.closest('[i]')
101
+ const children = e.currentTarget.querySelectorAll('[i]')
102
+ this.index = Array.from(children).indexOf(item)
103
+ }}
104
+ >
105
+ ${files.map((file, idx) => html`<div i ?active=${idx === index}>${idx}</div>`)}
106
+ </div>
107
+ <div image>${file ? html` <img src=${URL.createObjectURL(file)} /> ` : html``}</div>
108
+ </div>
109
+ <div id="result"></div>
110
+ `
111
+ }
112
+
113
+ fileschange(e) {
114
+ const fileUploader = this.shadowRoot.querySelector('#capturer')
115
+ this._files = fileUploader.files
116
+ }
117
+
118
+ reset() {
119
+ const fileUploader = this.shadowRoot.querySelector('#capturer')
120
+ const result = this.shadowRoot.querySelector('#result')
121
+
122
+ fileUploader.reset()
123
+ result.textContent = ''
124
+ }
125
+
126
+ async upload() {
127
+ const fileUploader = this.shadowRoot.querySelector('#capturer')
128
+ const result = this.shadowRoot.querySelector('#result')
129
+
130
+ const response = await client.query({
131
+ query: gql`
132
+ query ocrRequest($images: [Upload!]!) {
133
+ ocrRequest(images: $images)
134
+ }
135
+ `,
136
+ variables: {
137
+ images: fileUploader?.files
138
+ },
139
+ context: { hasUpload: true }
140
+ })
141
+
142
+ if (!response.errors) {
143
+ result.textContent = response.data.ocrRequest
144
+ } else {
145
+ result.textContent = 'error'
146
+ }
147
+ }
148
+ }
149
+
150
+ customElements.define('ocr-viewpart', OCRViewPart)
@@ -1,6 +1,6 @@
1
- import '@things-factory/grist-ui'
1
+ import '@operato/data-grist'
2
2
 
3
- import { css, html, LitElement } from 'lit-element'
3
+ import { LitElement, css, html } from 'lit-element'
4
4
 
5
5
  import { MultiColumnFormStyles } from '@things-factory/form-ui'
6
6
  import { i18next } from '@things-factory/i18n-base'
@@ -33,7 +33,7 @@ export class IdSelector extends LitElement {
33
33
  height: var(--overlay-center-normal-height, 50%);
34
34
  }
35
35
 
36
- data-grist {
36
+ ox-grist {
37
37
  flex: 1;
38
38
  }
39
39
 
@@ -88,12 +88,12 @@ export class IdSelector extends LitElement {
88
88
  >
89
89
  </form>
90
90
 
91
- <data-grist
91
+ <ox-grist
92
92
  .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
93
93
  .config=${this.config}
94
94
  .fetchHandler=${this.fetchHandler.bind(this)}
95
95
  .selectedRecords=${this.selectedRecords}
96
- ></data-grist>
96
+ ></ox-grist>
97
97
 
98
98
  <div class="button-container">
99
99
  <mwc-button @click=${this.oncancel.bind(this)}>${i18next.t('button.cancel')}</mwc-button>
@@ -168,7 +168,7 @@ export class IdSelector extends LitElement {
168
168
  /* TODO config가 설정될 때, fetch() 가 동작하므로, fetch 완료 이벤트를 받아서, selected를 설정해주는 것이 좋겠다.
169
169
  현재는 fetch() 가 두번 일어난다.
170
170
  */
171
- var grist = this.shadowRoot.querySelector('data-grist')
171
+ var grist = this.shadowRoot.querySelector('ox-grist')
172
172
  await grist.fetch()
173
173
 
174
174
  var selected = grist.data.records.find(item => this.value == item.id)
@@ -219,7 +219,7 @@ export class IdSelector extends LitElement {
219
219
  }
220
220
 
221
221
  get selected() {
222
- var grist = this.shadowRoot.querySelector('data-grist')
222
+ var grist = this.shadowRoot.querySelector('ox-grist')
223
223
 
224
224
  var selected = grist.selected
225
225
 
package/client/menu.js CHANGED
@@ -37,8 +37,8 @@ export function getMenuTemplate() {
37
37
  path: 'bizplace-register'
38
38
  },
39
39
  {
40
- name: 'List Sample',
41
- path: 'bizplace-register'
40
+ name: 'List/Card Sample',
41
+ path: 'grist-mode-page'
42
42
  },
43
43
  {
44
44
  name: 'Headroom Style',
@@ -80,7 +80,7 @@ export function getMenuTemplate() {
80
80
  },
81
81
  {
82
82
  name: 'Label Scan',
83
- path: 'bizplace-register'
83
+ path: 'label-scan-page'
84
84
  },
85
85
  {
86
86
  name: 'Ghost Print',
@@ -1,5 +1,5 @@
1
1
  import '@material/mwc-icon'
2
- import '@operato/mini-popup'
2
+ import '@operato/popup'
3
3
 
4
4
  import { css, html } from 'lit-element'
5
5
  import { connect } from 'pwa-helpers/connect-mixin.js'
@@ -40,86 +40,108 @@ class ContextMenuPage extends connect(store)(PageView) {
40
40
  위치에서든 마우스 우측버튼을 클릭하고, 모바일 디바이스에서는 탭을 오래누르면(longpress) 팝업메뉴가 동작합니다.
41
41
  </p>
42
42
 
43
- <popup-menu>
44
- <popup-menuitem label="article">
43
+ <ox-popup-menu>
44
+ <ox-popup-menuitem
45
+ label="article - click me"
46
+ @selected=${function (e) {
47
+ console.log('first level article selected')
48
+ }}
49
+ >
45
50
  <mwc-icon slot="icon">article</mwc-icon>
46
- </popup-menuitem>
51
+ </ox-popup-menuitem>
47
52
 
48
- <popup-menuitem label="home">
53
+ <ox-popup-menuitem label="home">
49
54
  <mwc-icon slot="icon">home</mwc-icon>
50
- </popup-menuitem>
55
+ </ox-popup-menuitem>
51
56
 
52
- <popup-menuitem label="empty"> </popup-menuitem>
57
+ <ox-popup-menuitem label="empty"> </ox-popup-menuitem>
53
58
 
54
- <popup-menuitem
59
+ <ox-popup-menuitem
55
60
  label="click me to toggle"
56
- @click=${function (e) {
57
- const target = e.currentTarget
58
- const icon = target.querySelector('mwc-icon')
61
+ @selected=${function (e) {
62
+ const icon = e.currentTarget.querySelector('mwc-icon')
59
63
  icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
60
64
  }}
65
+ alive-on-select
61
66
  >
62
67
  <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
63
- </popup-menuitem>
68
+ </ox-popup-menuitem>
64
69
 
65
- <popup-menuitem label="verified">
70
+ <ox-popup-menuitem label="verified" @selected=${e => console.log('selected verified')}>
66
71
  <mwc-icon slot="icon">verified</mwc-icon>
67
- <popup-menu>
68
- <popup-menuitem label="article">
72
+ <ox-popup-menu>
73
+ <ox-popup-menuitem
74
+ label="article"
75
+ @selected=${function (e) {
76
+ console.log('article selected')
77
+ }}
78
+ alive-on-select
79
+ >
69
80
  <mwc-icon slot="icon">article</mwc-icon>
70
- </popup-menuitem>
81
+ </ox-popup-menuitem>
71
82
 
72
- <popup-menuitem label="home">
83
+ <ox-popup-menuitem label="home">
73
84
  <mwc-icon slot="icon">home</mwc-icon>
74
- </popup-menuitem>
85
+ </ox-popup-menuitem>
75
86
 
76
- <popup-menuitem label="verified">
87
+ <ox-popup-menuitem label="verified">
77
88
  <mwc-icon slot="icon">verified</mwc-icon>
78
- <popup-menu>
79
- <popup-menuitem label="article">
89
+ <ox-popup-menu>
90
+ <ox-popup-menuitem label="article">
80
91
  <mwc-icon slot="icon">article</mwc-icon>
81
- </popup-menuitem>
92
+ </ox-popup-menuitem>
82
93
 
83
- <popup-menuitem label="home">
94
+ <ox-popup-menuitem label="home">
84
95
  <mwc-icon slot="icon">home</mwc-icon>
85
- </popup-menuitem>
96
+ </ox-popup-menuitem>
86
97
 
87
- <popup-menuitem label="verified">
98
+ <ox-popup-menuitem label="verified">
88
99
  <mwc-icon slot="icon">verified</mwc-icon>
89
- </popup-menuitem>
100
+ </ox-popup-menuitem>
90
101
 
91
- <popup-menuitem label="checkbox">
102
+ <ox-popup-menuitem label="checkbox">
92
103
  <input type="checkbox" slot="icon" />
93
- </popup-menuitem>
104
+ </ox-popup-menuitem>
94
105
 
95
106
  <div separator></div>
96
- </popup-menu>
97
- </popup-menuitem>
107
+ </ox-popup-menu>
108
+ </ox-popup-menuitem>
98
109
 
99
110
  <div separator></div>
100
111
 
101
- <popup-menuitem label="checkbox">
112
+ <ox-popup-menuitem label="checkbox">
102
113
  <input type="checkbox" slot="icon" />
103
- </popup-menuitem>
104
- </popup-menu>
105
- </popup-menuitem>
114
+ </ox-popup-menuitem>
115
+ </ox-popup-menu>
116
+ </ox-popup-menuitem>
106
117
 
107
- <popup-menuitem label="checkbox">
118
+ <ox-popup-menuitem label="checkbox in icon area" alive-on-select>
108
119
  <input type="checkbox" slot="icon" />
109
- </popup-menuitem>
120
+ </ox-popup-menuitem>
110
121
 
111
122
  <div separator></div>
112
123
 
113
- <div menu>Plain DIV</div>
114
- <input type="checkbox" menu />
115
- <input type="text" menu value="Plain text input" />
116
- </popup-menu>
124
+ <div menu>Plain Text</div>
125
+
126
+ <div menu alive-on-select>
127
+ <ox-checkbox label="checkbox" slot="icon" checked />checkbox</ox-checkbox>
128
+ </div>
129
+
130
+ <div menu alive-on-select>
131
+ <input id="checkbox-01" type="checkbox" />
132
+ <label for="checkbox-01">custom menu</label>
133
+ </div>
134
+ <div menu alive-on-select>
135
+ <label for="text-01">value</label>
136
+ <input id="text-01" type="text" value="Plain text input" />
137
+ </div>
138
+ </ox-popup-menu>
117
139
  `
118
140
  }
119
141
 
120
142
  firstUpdated() {
121
143
  this.addEventListener('contextmenu', e => {
122
- const popupMenu = this.renderRoot.querySelector('popup-menu')
144
+ const popupMenu = this.renderRoot.querySelector('ox-popup-menu')
123
145
 
124
146
  if (popupMenu) {
125
147
  e.preventDefault()
@@ -1,10 +1,9 @@
1
1
  import { css, html } from 'lit-element'
2
-
3
- import { getEditor, getRenderer } from '@things-factory/grist-ui'
2
+ import { getEditor, getRenderer } from '@operato/data-grist'
4
3
  import { i18next, localize } from '@things-factory/i18n-base'
4
+
5
5
  import { PageView } from '@things-factory/shell'
6
6
  import { isMobileDevice } from '@things-factory/utils'
7
-
8
7
  import { referencePageStyles } from './reference-page-styles'
9
8
 
10
9
  class GristColorizing extends localize(i18next)(PageView) {
@@ -27,7 +26,7 @@ class GristColorizing extends localize(i18next)(PageView) {
27
26
  overflow: auto;
28
27
  }
29
28
 
30
- data-grist {
29
+ ox-grist {
31
30
  flex: 1;
32
31
  }
33
32
  `
@@ -49,7 +48,7 @@ class GristColorizing extends localize(i18next)(PageView) {
49
48
  }
50
49
 
51
50
  get grist() {
52
- return this.shadowRoot.querySelector('data-grist')
51
+ return this.shadowRoot.querySelector('ox-grist')
53
52
  }
54
53
 
55
54
  render() {
@@ -97,11 +96,11 @@ class GristColorizing extends localize(i18next)(PageView) {
97
96
  </pre
98
97
  >
99
98
  </div>
100
- <data-grist
99
+ <ox-grist
101
100
  .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
102
101
  .config=${this.config}
103
102
  .fetchHandler=${this.fetchHandler}
104
- ></data-grist>
103
+ ></ox-grist>
105
104
  `
106
105
  }
107
106