@things-factory/board-ui 8.0.0 → 9.0.0-beta.3

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 (59) hide show
  1. package/dist-client/tsconfig.tsbuildinfo +1 -1
  2. package/package.json +19 -19
  3. package/translations/en.json +31 -29
  4. package/translations/ja.json +33 -31
  5. package/translations/ko.json +33 -31
  6. package/translations/ms.json +28 -25
  7. package/translations/zh.json +31 -29
  8. package/client/apptools/favorite-tool.ts +0 -124
  9. package/client/board-list/board-tile-list.ts +0 -272
  10. package/client/board-list/group-bar-styles.ts +0 -63
  11. package/client/board-list/group-bar.ts +0 -99
  12. package/client/board-list/play-group-bar.ts +0 -88
  13. package/client/board-provider.ts +0 -92
  14. package/client/bootstrap.ts +0 -39
  15. package/client/data-grist/board-editor.ts +0 -113
  16. package/client/data-grist/board-renderer.ts +0 -134
  17. package/client/data-grist/color-map-editor.ts +0 -17
  18. package/client/data-grist/color-ranges-editor.ts +0 -17
  19. package/client/graphql/board-template.ts +0 -141
  20. package/client/graphql/board.ts +0 -273
  21. package/client/graphql/favorite-board.ts +0 -25
  22. package/client/graphql/group.ts +0 -138
  23. package/client/graphql/index.ts +0 -6
  24. package/client/graphql/my-board.ts +0 -25
  25. package/client/graphql/play-group.ts +0 -189
  26. package/client/index.ts +0 -10
  27. package/client/pages/attachment-list-page.ts +0 -142
  28. package/client/pages/board-list-page.ts +0 -603
  29. package/client/pages/board-modeller-page.ts +0 -288
  30. package/client/pages/board-player-by-name-page.ts +0 -29
  31. package/client/pages/board-player-page.ts +0 -241
  32. package/client/pages/board-template/board-template-list-page.ts +0 -248
  33. package/client/pages/board-viewer-by-name-page.ts +0 -24
  34. package/client/pages/board-viewer-page.ts +0 -271
  35. package/client/pages/font-list-page.ts +0 -31
  36. package/client/pages/play-list-page.ts +0 -400
  37. package/client/pages/printable-board-viewer-page.ts +0 -54
  38. package/client/pages/theme/theme-editors.ts +0 -56
  39. package/client/pages/theme/theme-list-page.ts +0 -313
  40. package/client/pages/things-scene-components-with-tools.import +0 -0
  41. package/client/pages/things-scene-components.import +0 -0
  42. package/client/route.ts +0 -51
  43. package/client/setting-let/board-view-setting-let.ts +0 -68
  44. package/client/themes/board-theme.css +0 -77
  45. package/client/things-scene-import.d.ts +0 -4
  46. package/client/viewparts/board-basic-info.ts +0 -646
  47. package/client/viewparts/board-info-link.ts +0 -56
  48. package/client/viewparts/board-info.ts +0 -85
  49. package/client/viewparts/board-template-builder.ts +0 -134
  50. package/client/viewparts/board-versions.ts +0 -172
  51. package/client/viewparts/group-info-basic.ts +0 -267
  52. package/client/viewparts/group-info-import.ts +0 -132
  53. package/client/viewparts/group-info.ts +0 -87
  54. package/client/viewparts/index.ts +0 -3
  55. package/client/viewparts/link-builder.ts +0 -210
  56. package/client/viewparts/play-group-info-basic.ts +0 -268
  57. package/client/viewparts/play-group-info-link.ts +0 -46
  58. package/client/viewparts/play-group-info.ts +0 -81
  59. package/server/index.ts +0 -0
@@ -1,4 +1,5 @@
1
1
  {
2
+ "EDIT": "编辑",
2
3
  "button.accept": "同意",
3
4
  "button.account": "账户",
4
5
  "button.add": "添加",
@@ -79,45 +80,44 @@
79
80
  "button.view-short": "查看",
80
81
  "button.zoom-in": "放大",
81
82
  "button.zoom-out": "缩小",
83
+ "component.audio": "音频",
84
+ "component.both arrow": "双向箭头",
85
+ "component.color image": "彩色图像",
82
86
  "component.container": "容器",
83
- "component.popup": "弹出窗口",
84
- "component.info-window": "信息窗口",
85
- "component.local-ref": "本地引用",
87
+ "component.dash": "虚线",
88
+ "component.donut": "圆环",
89
+ "component.ellipse": "椭圆",
90
+ "component.embed": "嵌入",
91
+ "component.gif image": "GIF图像",
92
+ "component.gif-view": "GIF视图",
86
93
  "component.global-ref": "全球引用",
94
+ "component.gray image": "灰色图像",
87
95
  "component.group": "组",
96
+ "component.image-view": "图像视图",
97
+ "component.info-window": "信息窗口",
88
98
  "component.line": "线条",
89
- "component.dash": "虚线",
90
- "component.single arrow": "单箭头",
91
- "component.both arrow": "双向箭头",
92
- "component.polyline": "多段线",
99
+ "component.local-ref": "本地引用",
100
+ "component.model-layer": "画布",
93
101
  "component.ortholine": "正交线",
94
- "component.rect": "矩形",
95
- "component.ellipse": "椭圆",
96
- "component.donut": "圆环",
97
- "component.triangle": "三角形",
98
102
  "component.polygon": "多边形",
103
+ "component.polyline": "多段线",
104
+ "component.popup": "弹出窗口",
105
+ "component.rect": "矩形",
106
+ "component.single arrow": "单箭头",
99
107
  "component.star": "星形",
100
108
  "component.text": "文本",
101
- "component.color image": "彩色图像",
102
- "component.gray image": "灰色图像",
103
- "component.image-view": "图像视图",
104
- "component.gif image": "GIF图像",
105
- "component.gif-view": "GIF视图",
106
- "component.audio": "音频",
109
+ "component.triangle": "三角形",
107
110
  "component.video": "视频",
108
- "component.embed": "嵌入",
109
- "component.model-layer": "画布",
110
- "EDIT": "编辑",
111
+ "error.MAX_LENGTH_OF_X_IS_Y": "{name}的最大长度是 {value}。",
112
+ "error.SERVER-ERROR": "发生了服务端错误。({msg})",
113
+ "error.SHOULD_NOT_BE_EMPTY": "值'{value}'不能为空值。",
111
114
  "error.count over license limit": "您的看板或子域数量超过了许可证限制!",
112
115
  "error.invalid license key": "无效的许可证密钥!",
113
116
  "error.license expiration notice": "许可证到期提醒",
114
117
  "error.license key is empty": "许可证密钥为空!",
115
118
  "error.license key is not certified": "许可证密钥未通过认证!",
116
119
  "error.license token not valid": "您的数据密钥验证失败,系统许可无效!",
117
- "error.MAX_LENGTH_OF_X_IS_Y": "{name}的最大长度是 {value}。",
118
- "error.SERVER-ERROR": "发生了服务端错误。({msg})",
119
120
  "error.setting-error": "设置错误",
120
- "error.SHOULD_NOT_BE_EMPTY": "值'{value}'不能为空值。",
121
121
  "error.your license due date is x, please renewal your license!": "您的许可证到期日期为{x},请续订您的许可证!",
122
122
  "error.your license is expired! expired date is [x]": "您的许可证已过期! 过期日为[{x}]",
123
123
  "error.your license is not valid in this host": "您的许可证在此主机中无效!",
@@ -240,6 +240,7 @@
240
240
  "label.domain-url": "域地址",
241
241
  "label.domain_app": "域应用程序",
242
242
  "label.donut-style": "圆环样式",
243
+ "label.draggable": "可拖动",
243
244
  "label.duration": "持续期间",
244
245
  "label.email": "邮件",
245
246
  "label.email-id": "邮件ID",
@@ -351,6 +352,7 @@
351
352
  "label.min": "最小",
352
353
  "label.min-section": "最小段",
353
354
  "label.min-unit": "最小单位",
355
+ "label.minimizable": "可最小化",
354
356
  "label.minor": "次要",
355
357
  "label.minute-width": "分针厚度",
356
358
  "label.miter": "斜边",
@@ -603,6 +605,12 @@
603
605
  "menu.variables": "变量",
604
606
  "scene.scene-height": "标签高(Pixel)",
605
607
  "scene.scene-width": "标签宽(Pixel)",
608
+ "text.NOTHING_CHANGED": "没有新的更新。",
609
+ "text.New Alarm Message is Arrived.": "新报警到达!",
610
+ "text.Server Processing": "执行服务中..",
611
+ "text.Success to Process": "执行成功",
612
+ "text.Sure To Delete Important": "所有相关数据都会被删除,请确认是否删除?",
613
+ "text.Sure to X": "确定要{x}吗?",
606
614
  "text.add_files": "添加文件",
607
615
  "text.board cloned": "看板 '{board}' 已成功克隆",
608
616
  "text.board created": "看板 '{board}' 创建成功",
@@ -655,9 +663,7 @@
655
663
  "text.modeller-save-title": "保存:版本报警",
656
664
  "text.move-to-home": "将会移动到主页。",
657
665
  "text.name-and-group-required": "请指定仪表盘名称和仪表盘组!",
658
- "text.New Alarm Message is Arrived.": "新报警到达!",
659
666
  "text.no released version information available": "没有发布版本信息可用",
660
- "text.NOTHING_CHANGED": "没有新的更新。",
661
667
  "text.only-edit-status-label-can-be-deleted": "只有EDIT状态的标签才可以删除!",
662
668
  "text.only-edit-status-label-can-be-saved": "只有EDIT状态的标签才可以更改!",
663
669
  "text.password-missmatch": "新密码与确认密码不同",
@@ -680,13 +686,9 @@
680
686
  "text.saved": "已保存",
681
687
  "text.search with type, id or tag": "通过类型、ID或标签名搜索",
682
688
  "text.select_file": "选择文件",
683
- "text.Server Processing": "执行服务中..",
684
689
  "text.server_unavailable": "服务器无法链接",
685
690
  "text.settings-already-done": "已有设置。",
686
691
  "text.stalled": "停滞",
687
- "text.Success to Process": "执行成功",
688
- "text.Sure To Delete Important": "所有相关数据都会被删除,请确认是否删除?",
689
- "text.Sure to X": "确定要{x}吗?",
690
692
  "text.sure-delete-domain": "所有相关数据都会被删除,请确认是否删除?",
691
693
  "text.sure-delete-domain-final": "将会删除所有相关数据。是否继续进行删除?",
692
694
  "text.sure-to-delete": "是否执行删除操作?",
@@ -1,124 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
-
3
- import gql from 'graphql-tag'
4
- import { css, html, LitElement, nothing } from 'lit'
5
- import { customElement, property } from 'lit/decorators.js'
6
- import { connect } from 'pwa-helpers/connect-mixin.js'
7
-
8
- import { store } from '@operato/shell'
9
- import { client } from '@operato/graphql'
10
-
11
- import { UPDATE_FAVORITES } from '@things-factory/fav-base/client'
12
-
13
- @customElement('favorite-tool')
14
- export class FavoriteTool extends connect(store)(LitElement) {
15
- static styles = css`
16
- :host {
17
- display: inline-block;
18
- vertical-align: middle;
19
- line-height: 0;
20
- }
21
-
22
- [favorable] {
23
- opacity: 0.5;
24
- }
25
- `
26
-
27
- @property({ type: Array }) favorites: any[] = []
28
- @property({ type: Object }) user: any
29
- @property({ type: String }) resourceId?: string
30
- @property({ type: Boolean }) favored?: boolean
31
- @property({ type: Array }) acceptedPages: any[] = []
32
-
33
- page: any
34
-
35
- render() {
36
- var renderable = (this.acceptedPages || []).indexOf(this.page) !== -1
37
-
38
- return renderable
39
- ? html`
40
- <md-icon @click=${this.onClick.bind(this)} ?favorable=${!this.favored}
41
- >${this.favored ? 'star' : 'star_border'}</md-icon
42
- >
43
- `
44
- : nothing
45
- }
46
-
47
- updated(changes) {
48
- if (changes.has('user')) {
49
- this.refreshFavorites()
50
- }
51
-
52
- this.favored = (this.favorites || []).includes(this.resourceId)
53
- }
54
-
55
- stateChanged(state) {
56
- this.page = state.route.page
57
- this.favorites = state.favorite.favorites
58
- this.user = state.auth.user
59
- this.resourceId = state.route.resourceId
60
- }
61
-
62
- onClick(event) {
63
- if (!this.resourceId) {
64
- return
65
- }
66
-
67
- if (this.favored) {
68
- this.removeFavorite(this.resourceId)
69
- } else {
70
- this.addFavorite(this.resourceId)
71
- }
72
- }
73
-
74
- async refreshFavorites() {
75
- if (!this.user || !this.user.email) {
76
- return
77
- }
78
-
79
- const response = await client.query({
80
- query: gql`
81
- query {
82
- myFavorites {
83
- id
84
- routing
85
- }
86
- }
87
- `
88
- })
89
-
90
- store.dispatch({
91
- type: UPDATE_FAVORITES,
92
- favorites: response.data.myFavorites.map(favorite => favorite.routing)
93
- })
94
- }
95
-
96
- async removeFavorite(routing) {
97
- await client.query({
98
- query: gql`
99
- mutation {
100
- deleteFavorite(routing: "${routing}")
101
- }
102
- `
103
- })
104
-
105
- this.refreshFavorites()
106
- }
107
-
108
- async addFavorite(routing) {
109
- await client.query({
110
- query: gql`
111
- mutation {
112
- createFavorite(favorite: {
113
- routing: "${routing}"
114
- }) {
115
- id
116
- routing
117
- }
118
- }
119
- `
120
- })
121
-
122
- this.refreshFavorites()
123
- }
124
- }
@@ -1,272 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/board/ox-board-creation-card.js'
3
-
4
- import gql from 'graphql-tag'
5
- import { css, html, LitElement, PropertyValues, nothing } from 'lit'
6
- import { customElement, property, state, query } from 'lit/decorators.js'
7
- import { keyed } from 'lit/directives/keyed.js'
8
-
9
- import { client } from '@operato/graphql'
10
-
11
- import { privileged } from '@things-factory/auth-base/dist-client'
12
-
13
- @customElement('board-tile-list')
14
- export class BoardTileList extends LitElement {
15
- static styles = [
16
- css`
17
- :host {
18
- overflow: auto;
19
- padding: var(--popup-content-padding);
20
- display: grid;
21
- background-color: var(--md-sys-color-background);
22
-
23
- grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
24
- grid-auto-rows: var(--card-list-rows-height);
25
- grid-gap: 20px;
26
- }
27
-
28
- [card] {
29
- position: relative;
30
- align-items: center;
31
- overflow: hidden;
32
- }
33
-
34
- [card][create] {
35
- overflow: visible;
36
- background-color: initial;
37
- }
38
-
39
- [card] > a {
40
- display: flex;
41
- clip-path: border-box;
42
- }
43
-
44
- [card]:hover {
45
- cursor: pointer;
46
- }
47
-
48
- [name] {
49
- text-overflow: ellipsis;
50
- white-space: nowrap;
51
- overflow: hidden;
52
- margin-top: var(--spacing-small);
53
- width: calc(100% - 45px);
54
- color: var(--md-sys-color-on-background);
55
- font-weight: bolder;
56
- font-size: var(--fontsize-small);
57
- }
58
-
59
- img {
60
- flex: 1;
61
- object-fit: contain;
62
- }
63
-
64
- md-icon[iconBtn] {
65
- float: right;
66
- margin-top: -20px;
67
- margin-left: 2px;
68
- color: var(--board-list-star-color);
69
- font-size: 1.4em;
70
- }
71
- md-icon[info] {
72
- color: var(--md-sys-color-primary);
73
- }
74
-
75
- md-icon[iconBtn][favored],
76
- md-icon[info]:hover {
77
- color: var(--board-list-star-active-color);
78
- }
79
-
80
- a {
81
- display: block;
82
- border-radius: var(--card-list-border-radius);
83
- border: var(--border-dim-color);
84
- box-sizing: border-box;
85
- color: var(--card-list-color);
86
- background-color: var(--card-list-background-color);
87
- margin: 0px;
88
- height: calc(100% - 25px);
89
- }
90
-
91
- :host > *:hover [info] {
92
- opacity: 1;
93
- -webkit-transition: opacity 0.8s;
94
- -moz-transition: opacity 0.8s;
95
- -o-transition: opacity 0.8s;
96
- transition: opacity 0.8s;
97
- }
98
-
99
- [draggable='true'] {
100
- cursor: grab;
101
- }
102
-
103
- @media screen and (max-width: 800px), screen and (max-height: 600px) {
104
- ox-board-creation-card {
105
- display: none;
106
- }
107
- }
108
- `
109
- ]
110
-
111
- @property({ type: Array }) boards: any[] = []
112
- @property({ type: Array }) favorites: any[] = []
113
- @property({ type: Array }) groups: any[] = []
114
- @property({ type: String }) group?: string
115
- @property({ type: Boolean }) creatable?: boolean = false
116
- @property({ type: String, attribute: 'search-text' }) searchText?: string
117
- @property({ type: Boolean, attribute: 'reorderable' }) reorderable: boolean = false
118
-
119
- private draggedItem
120
-
121
- connectedCallback() {
122
- super.connectedCallback()
123
-
124
- if (this.reorderable) {
125
- this.renderRoot.addEventListener('dragstart', (e: Event) => {
126
- const target = e.target! as HTMLElement
127
- this.draggedItem = target.closest('[card]')
128
- ;(e as DragEvent).dataTransfer?.setData('text/plain', target.innerHTML)
129
- })
130
-
131
- this.renderRoot.addEventListener('dragover', (e: Event) => {
132
- e.preventDefault()
133
-
134
- const target = e.target! as HTMLElement
135
- const targetItem = target.closest('[card]')
136
- if (targetItem && targetItem !== this.draggedItem) {
137
- const targetRect = targetItem.getBoundingClientRect()
138
- const mousePos = (e as DragEvent).clientX - targetRect.left
139
-
140
- if (mousePos < targetRect.width / 2) {
141
- // 마우스 위치가 아이템 좌측 반절에 있을 때
142
- this.renderRoot.insertBefore(this.draggedItem, targetItem)
143
- } else {
144
- // 마우스 위치가 아이템 우측 반절에 있을 때
145
- this.renderRoot.insertBefore(this.draggedItem, targetItem.nextSibling)
146
- }
147
- }
148
- })
149
-
150
- this.renderRoot.addEventListener('drop', (e: Event) => {
151
- e.preventDefault()
152
-
153
- const boardIds = Array.from(this.renderRoot.querySelectorAll('[card]'))
154
- .map(board => board.getAttribute('id'))
155
- .filter(Boolean)
156
-
157
- this.dispatchEvent(
158
- new CustomEvent('reordered', {
159
- detail: {
160
- groupId: this.group,
161
- boardIds
162
- }
163
- })
164
- )
165
- })
166
- }
167
- }
168
-
169
- render() {
170
- var boards = this.boards || []
171
-
172
- return html`
173
- ${this.creatable
174
- ? privileged(
175
- { privilege: 'mutation', category: 'board' },
176
- html`
177
- <ox-board-creation-card
178
- .groups=${this.groups}
179
- .defaultGroup=${this.group}
180
- @create-board=${e => this.onCreateBoard(e)}
181
- card
182
- create
183
- ></ox-board-creation-card>
184
- `
185
- )
186
- : nothing}
187
- ${keyed(
188
- Date.now(),
189
- boards.map(
190
- board => html`
191
- <div card draggable="true" id=${board.id}>
192
- <a href="board-viewer/${board.id}"> <img src=${board.thumbnail} /> </a>
193
-
194
- <div name>${board.name}</div>
195
- <!-- <div description>${board.description}</div> -->
196
-
197
- <md-icon
198
- iconBtn
199
- info
200
- @click=${e => {
201
- this.infoBoard(board)
202
- e.preventDefault()
203
- }}
204
- >info</md-icon
205
- >
206
-
207
- ${(this.favorites || []).includes(board.id)
208
- ? html` <md-icon iconBtn favored @click=${e => this.removeFavorite(board.id)}>star</md-icon> `
209
- : html` <md-icon iconBtn @click=${e => this.addFavorite(board.id)}>star_border</md-icon> `}
210
- </div>
211
- `
212
- )
213
- )}
214
- `
215
- }
216
-
217
- updated(changes: PropertyValues<this>) {
218
- var creationCard = this.renderRoot.querySelector('ox-board-creation-card') as any
219
- if (creationCard) {
220
- creationCard.reset()
221
- }
222
- }
223
-
224
- onCreateBoard(e) {
225
- this.dispatchEvent(
226
- new CustomEvent('create-board', {
227
- detail: e.detail
228
- })
229
- )
230
- }
231
-
232
- infoBoard(board) {
233
- this.dispatchEvent(
234
- new CustomEvent('info-board', {
235
- detail: board
236
- })
237
- )
238
- }
239
-
240
- async removeFavorite(boardId) {
241
- await client.query({
242
- query: gql`
243
- mutation {
244
- deleteFavorite(routing: "${boardId}")
245
- }
246
- `
247
- })
248
-
249
- this.refreshFavorites()
250
- }
251
-
252
- async addFavorite(boardId) {
253
- await client.query({
254
- query: gql`
255
- mutation {
256
- createFavorite(favorite: {
257
- routing: "${boardId}"
258
- }) {
259
- id
260
- routing
261
- }
262
- }
263
- `
264
- })
265
-
266
- this.refreshFavorites()
267
- }
268
-
269
- async refreshFavorites() {
270
- this.dispatchEvent(new CustomEvent('refresh-favorites'))
271
- }
272
- }
@@ -1,63 +0,0 @@
1
- import { css } from 'lit'
2
-
3
- export const GroupBarStyles = css`
4
- :host {
5
- background-color: var(--group-bar-background-color);
6
-
7
- overflow-x: hidden;
8
- }
9
-
10
- ul {
11
- display: flex;
12
- flex-direction: row;
13
- box-sizing: border-box;
14
- list-style: none;
15
- margin: 0;
16
- padding: 0;
17
- white-space: nowrap;
18
- }
19
-
20
- li {
21
- display: flex;
22
- align-items: center;
23
-
24
- box-sizing: border-box;
25
- border-bottom: var(--group-bar-line);
26
- align-self: auto;
27
- min-height: 43px;
28
- padding: 4px 8px;
29
-
30
- * {
31
- vertical-align: middle;
32
- }
33
-
34
- a {
35
- display: block;
36
- text-decoration: none;
37
- font: var(--group-bar-textbutton);
38
- color: var(--md-sys-color-on-secondary-container);
39
- opacity: 0.8;
40
- }
41
-
42
- a md-icon {
43
- font-variation-settings: 'FILL' 1;
44
- }
45
-
46
- &[active] {
47
- border-color: var(--group-bar-active-line-color);
48
-
49
- a {
50
- font: var(--group-bar-textbutton-active);
51
- opacity: 1;
52
- }
53
- }
54
-
55
- &[padding] {
56
- flex: 1;
57
- }
58
-
59
- &[add] * {
60
- color: var(--md-sys-color-on-secondary-container);
61
- }
62
- }
63
- `
@@ -1,99 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
-
3
- import { html, LitElement } from 'lit'
4
- import { customElement, property } from 'lit/decorators.js'
5
- import ScrollBooster from 'scrollbooster'
6
-
7
- import { longpressable } from '@operato/utils'
8
- import { privileged } from '@things-factory/auth-base/dist-client'
9
- import { GroupBarStyles } from './group-bar-styles'
10
-
11
- @customElement('group-bar')
12
- export default class GroupBar extends LitElement {
13
- static styles = [GroupBarStyles]
14
-
15
- @property({ type: Array }) groups?: any[]
16
- @property({ type: String }) groupId?: string
17
- @property({ type: String }) targetPage?: string
18
-
19
- private __sb?: ScrollBooster
20
-
21
- render() {
22
- return html`
23
- <ul>
24
- <li ?active=${!this.groupId}>
25
- <a href=${this.targetPage || ''}><md-icon>dashboard</md-icon></a>
26
- </li>
27
-
28
- <li ?active=${this.groupId === 'favor'}>
29
- <a href="${this.targetPage}/favor"><md-icon>star</md-icon></a>
30
- </li>
31
-
32
- ${privileged(
33
- { privilege: 'mutation', category: 'board' },
34
- html`<li ?active=${this.groupId === 'mywork'}>
35
- <a href="${this.targetPage}/mywork"><md-icon>engineering</md-icon></a>
36
- </li>`
37
- )}
38
- ${(this.groups || []).map(
39
- group => html`
40
- <li ?active=${this.groupId === group.id} @long-press=${e => this.infoGroup(group.id)}>
41
- <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>
42
- </li>
43
- `
44
- )}
45
-
46
- <li padding></li>
47
-
48
- <li add>
49
- <md-icon @click=${e => this.infoGroup()}>add</md-icon>
50
- </li>
51
- </ul>
52
- `
53
- }
54
-
55
- infoGroup(groupId?: string) {
56
- this.dispatchEvent(
57
- new CustomEvent('info-group', {
58
- detail: groupId
59
- })
60
- )
61
- }
62
-
63
- onWheelEvent(e) {
64
- var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))
65
- this.scrollLeft -= delta * 40
66
-
67
- e.preventDefault()
68
- }
69
-
70
- updated(change) {
71
- if (change.has('groups')) {
72
- /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */
73
- this.__sb && this.__sb.updateMetrics()
74
- }
75
-
76
- if (change.has('groupId')) {
77
- var active = this.renderRoot.querySelector('li[active]')
78
- active && active.scrollIntoView()
79
- }
80
- }
81
-
82
- firstUpdated() {
83
- var scrollTarget = this.renderRoot.querySelector('ul')
84
-
85
- /* long-press */
86
- longpressable(scrollTarget!)
87
-
88
- scrollTarget!.addEventListener('mousewheel', this.onWheelEvent.bind(this), false)
89
-
90
- this.__sb = new ScrollBooster({
91
- viewport: this,
92
- content: scrollTarget,
93
- mode: 'x',
94
- onUpdate: data => {
95
- this.scrollLeft = data.position.x
96
- }
97
- })
98
- }
99
- }