@operato/process 1.5.25 → 1.5.27

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/process",
3
- "version": "1.5.25",
3
+ "version": "1.5.27",
4
4
  "description": "Webcomponent for business process modeling following open-wc recommendations",
5
5
  "author": "heartyoh",
6
6
  "main": "dist/src/index.js",
@@ -68,16 +68,16 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@open-wc/scoped-elements": "^2.1.3",
71
- "@operato/app": "^1.5.25",
72
- "@operato/board": "^1.5.25",
73
- "@operato/data-grist": "^1.5.25",
74
- "@operato/font": "^1.5.25",
71
+ "@operato/app": "^1.5.27",
72
+ "@operato/board": "^1.5.27",
73
+ "@operato/data-grist": "^1.5.27",
74
+ "@operato/font": "^1.5.27",
75
75
  "@operato/graphql": "^1.4.76",
76
76
  "@operato/i18n": "^1.5.14",
77
- "@operato/input": "^1.5.25",
77
+ "@operato/input": "^1.5.27",
78
78
  "@operato/markdown": "^1.4.64",
79
- "@operato/popup": "^1.5.13",
80
- "@operato/property-editor": "^1.5.25",
79
+ "@operato/popup": "^1.5.27",
80
+ "@operato/property-editor": "^1.5.27",
81
81
  "@operato/styles": "^1.4.64",
82
82
  "@operato/utils": "^1.4.64",
83
83
  "@polymer/paper-dropdown-menu": "^3.2.0",
@@ -128,5 +128,5 @@
128
128
  "prettier --write"
129
129
  ]
130
130
  },
131
- "gitHead": "c00ba4544ea5bfbd329520f0b7a865d6a6ee038d"
131
+ "gitHead": "014457ceb1f2671743226ac18423ead229c8b571"
132
132
  }
@@ -409,15 +409,17 @@ class ProcessList extends LitElement {
409
409
  .groups=${this.groups}
410
410
  @create-process=${async (e: CustomEvent) => {
411
411
  try {
412
- var { name, description, groupId } = e.detail
412
+ var { name, description, groupId, model, thumbnail } = e.detail
413
+
413
414
  var process: Process = {
414
415
  name,
415
416
  description,
416
417
  groupId,
417
- model: {
418
+ model: model || {
418
419
  width: 1200,
419
420
  height: 800
420
- }
421
+ },
422
+ thumbnail
421
423
  }
422
424
 
423
425
  const { createProcess: created } = await createProcess(process)
@@ -0,0 +1,265 @@
1
+ import '@operato/data-grist'
2
+ import '@operato/input/ox-input-file.js'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html, LitElement } from 'lit'
6
+ import { customElement, property, query, state } from 'lit/decorators.js'
7
+
8
+ import {
9
+ ColumnConfig,
10
+ DataGrist,
11
+ FetchOption,
12
+ FilterValue,
13
+ GristData,
14
+ GristRecord,
15
+ PaginationConfig,
16
+ SortersConfig
17
+ } from '@operato/data-grist'
18
+ import { buildArgs, client } from '@operato/graphql'
19
+ import { ScrollbarStyles, TooltipStyles } from '@operato/styles'
20
+
21
+ const FETCH_PROCESS_TEMPLATE_LIST_GQL = (listParam: any) => {
22
+ return gql`
23
+ {
24
+ processTemplates(${buildArgs(listParam)}) {
25
+ items {
26
+ id
27
+ name
28
+ description
29
+ visibility
30
+ thumbnail
31
+ }
32
+ total
33
+ }
34
+ }
35
+ `
36
+ }
37
+
38
+ const FETCH_PROCESS_TEMPLATE_GQL = (id: string) => {
39
+ return gql`
40
+ {
41
+ processTemplate(id: "${id}") {
42
+ id
43
+ name
44
+ description
45
+ visibility
46
+ model
47
+ thumbnail
48
+ }
49
+ }
50
+ `
51
+ }
52
+
53
+ @customElement('ox-process-template-list')
54
+ export class OxProcessTemplateList extends LitElement {
55
+ static styles = [
56
+ ScrollbarStyles,
57
+ TooltipStyles,
58
+ css`
59
+ :host {
60
+ display: flex;
61
+
62
+ width: 100%;
63
+
64
+ --grid-record-emphasized-background-color: red;
65
+ --grid-record-emphasized-color: yellow;
66
+ }
67
+
68
+ ox-grist {
69
+ flex: 1;
70
+ overflow-y: auto;
71
+
72
+ --grid-record-emphasized-background-color: red;
73
+ --grid-record-emphasized-color: yellow;
74
+ }
75
+
76
+ #headroom {
77
+ align-items: center;
78
+ padding: var(--padding-default) var(--padding-wide);
79
+ border-top: 2px solid rgba(0, 0, 0, 0.2);
80
+ background-color: var(--theme-white-color);
81
+ box-shadow: var(--box-shadow);
82
+ }
83
+
84
+ #filters {
85
+ display: flex;
86
+ flex-direction: row;
87
+ place-content: space-between;
88
+ margin: var(--margin-default) 0;
89
+ }
90
+
91
+ select {
92
+ border: 0;
93
+ outline: none;
94
+ text-align: right;
95
+ }
96
+
97
+ @media only screen and (max-width: 460px) {
98
+ #filters {
99
+ flex-direction: column;
100
+ }
101
+ }
102
+ `
103
+ ]
104
+
105
+ @property({ type: Boolean, attribute: 'without-search' }) withoutSearch: boolean = false
106
+
107
+ @query('ox-grist') grist!: DataGrist
108
+
109
+ render() {
110
+ return html`
111
+ <ox-grist .config=${this.gristConfig} .mode=${'CARD'} auto-fetch .fetchHandler=${this.fetchHandler.bind(this)}>
112
+ <div slot="headroom" id="headroom">
113
+ <div id="filters">
114
+ <ox-filters-form autofocus .withoutSearch=${this.withoutSearch}></ox-filters-form>
115
+ </div>
116
+ </div>
117
+ </ox-grist>
118
+ `
119
+ }
120
+
121
+ async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {
122
+ const { items: records, total } = await this.getProcessTemplates({ page, limit, filters, sortings })
123
+
124
+ return {
125
+ total,
126
+ records
127
+ }
128
+ }
129
+
130
+ get gristConfig() {
131
+ return {
132
+ list: {
133
+ thumbnail: 'thumbnail',
134
+ fields: ['name'],
135
+ details: ['description']
136
+ },
137
+ columns: [
138
+ {
139
+ type: 'string',
140
+ name: 'id',
141
+ hidden: true
142
+ },
143
+ {
144
+ type: 'string',
145
+ name: 'name',
146
+ header: 'name',
147
+ record: {
148
+ editable: true,
149
+ align: 'left'
150
+ },
151
+ width: 200,
152
+ filter: 'search',
153
+ sortable: true
154
+ },
155
+ {
156
+ type: 'string',
157
+ name: 'description',
158
+ header: 'description',
159
+ record: {
160
+ editable: true,
161
+ align: 'left'
162
+ },
163
+ width: 200,
164
+ filter: 'search'
165
+ },
166
+ {
167
+ type: 'select-buttons',
168
+ name: 'visibility',
169
+ header: 'visibility',
170
+ record: {
171
+ editable: false
172
+ },
173
+ hidden: true,
174
+ filter: {
175
+ operator: 'in',
176
+ options: ['private', 'domain', 'public'],
177
+ label: ''
178
+ }
179
+ },
180
+ {
181
+ type: 'image',
182
+ name: 'thumbnail',
183
+ hidden: true,
184
+ record: {
185
+ editable: false
186
+ }
187
+ }
188
+ ],
189
+ rows: {
190
+ appendable: false,
191
+ selectable: {
192
+ multiple: false
193
+ },
194
+ handlers: {
195
+ click: 'select-row-toggle'
196
+ }
197
+ },
198
+ sorters: [
199
+ {
200
+ name: 'name',
201
+ desc: false
202
+ }
203
+ ],
204
+ pagination: {
205
+ pages: [20, 30, 50, 100, 200]
206
+ }
207
+ }
208
+ }
209
+
210
+ async firstUpdated() {
211
+ this.refreshProcessTemplates()
212
+ }
213
+
214
+ async getSelected() {
215
+ const selected = this.grist.selected
216
+ const templateId = selected && selected[0]?.id
217
+
218
+ if (!templateId) {
219
+ return
220
+ }
221
+
222
+ var processTemplateResponse = await client.query({
223
+ query: FETCH_PROCESS_TEMPLATE_GQL(templateId)
224
+ })
225
+
226
+ var template = processTemplateResponse.data?.processTemplate
227
+
228
+ if (template) {
229
+ template = {
230
+ ...template,
231
+ model: JSON.parse(template.model)
232
+ }
233
+ }
234
+
235
+ return template
236
+ }
237
+
238
+ async refreshProcessTemplates() {
239
+ this.grist.fetch()
240
+ }
241
+
242
+ async getProcessTemplates({
243
+ page = 1,
244
+ limit = 30,
245
+ filters = [],
246
+ sortings = []
247
+ }: { page?: number; limit?: number; filters?: FilterValue[]; sortings?: SortersConfig } = {}) {
248
+ var pagination: PaginationConfig = {
249
+ limit,
250
+ page
251
+ }
252
+
253
+ var params = {
254
+ filters,
255
+ sortings,
256
+ pagination
257
+ }
258
+
259
+ var processTemplateListResponse = await client.query({
260
+ query: FETCH_PROCESS_TEMPLATE_LIST_GQL(params)
261
+ })
262
+
263
+ return processTemplateListResponse?.data?.processTemplates || {}
264
+ }
265
+ }
@@ -66,14 +66,16 @@ export class ProcessCreationCard extends localize(i18next)(LitElement) {
66
66
  .defaultGroup=${this.defaultGroup}
67
67
  .groups=${this.groups}
68
68
  @create-process=${async (e: CustomEvent) => {
69
- var { name, description, groupId } = e.detail
69
+ var { name, description, groupId, model, thumbnail } = e.detail
70
70
 
71
71
  this.dispatchEvent(
72
72
  new CustomEvent('create-process', {
73
73
  detail: {
74
74
  name,
75
75
  description,
76
- groupId
76
+ groupId,
77
+ model,
78
+ thumbnail
77
79
  }
78
80
  })
79
81
  )
@@ -229,9 +229,9 @@ export class ProcessSelector extends InfiniteScrollable(localize(i18next)(LitEle
229
229
  }
230
230
 
231
231
  async onCreateProcess(e: CustomEvent) {
232
- var { name, description, groupId } = e.detail
232
+ var { name, description, groupId, model, thumbnail } = e.detail
233
233
 
234
- await this.createProcess(name, description, groupId)
234
+ await this.createProcess(name, description, groupId, model, thumbnail)
235
235
  this.refreshProcesses()
236
236
  }
237
237
 
@@ -296,12 +296,14 @@ export class ProcessSelector extends InfiniteScrollable(localize(i18next)(LitEle
296
296
  return processListResponse.data.processes.items
297
297
  }
298
298
 
299
- async createProcess(name: string, description: string, groupId: string) {
300
- var model = JSON.stringify({
301
- width: 1200,
302
- height: 800,
303
- fillStyle: 'white'
304
- })
299
+ async createProcess(name: string, description: string, groupId: string, modelTemplate: any, thumbnail: string) {
300
+ var model = JSON.stringify(
301
+ modelTemplate || {
302
+ width: 1200,
303
+ height: 800,
304
+ fillStyle: 'white'
305
+ }
306
+ )
305
307
 
306
308
  const response = await client.mutate({
307
309
  mutation: CREATE_PROCESS_GQL,
@@ -3,11 +3,13 @@ import '@material/mwc-textarea'
3
3
  import '@material/mwc-select'
4
4
  import '@material/mwc-list/mwc-list-item'
5
5
  import '@material/mwc-button'
6
+ import '../ox-process-template-list'
6
7
 
7
8
  import { css, html, LitElement } from 'lit'
8
- import { customElement, property } from 'lit/decorators.js'
9
+ import { customElement, property, query } from 'lit/decorators.js'
9
10
 
10
11
  import { i18next, localize } from '@operato/i18n'
12
+ import { OxProcessTemplateList } from '../ox-process-template-list'
11
13
 
12
14
  @customElement('process-creation-popup')
13
15
  export class ProcessCreationPopup extends localize(i18next)(LitElement) {
@@ -17,24 +19,46 @@ export class ProcessCreationPopup extends localize(i18next)(LitElement) {
17
19
  :host {
18
20
  display: flex;
19
21
  flex-direction: column;
20
-
22
+ gap: 10px;
21
23
  padding: 10px;
24
+
22
25
  background-color: white;
23
26
  }
24
27
 
25
- :host > * {
26
- margin: 10px;
28
+ [body] {
29
+ flex: 1;
30
+
31
+ display: flex;
32
+ flex-direction: row;
33
+ gap: 10px;
34
+
35
+ overflow: hidden;
27
36
  }
28
37
 
29
38
  [content] {
30
39
  flex: 1;
40
+
31
41
  display: flex;
32
42
  flex-direction: column;
43
+ gap: 10px;
44
+
33
45
  overflow: auto;
34
46
  }
35
47
 
36
- [content] > * {
37
- margin: 10px 0;
48
+ [content] > mwc-textarea {
49
+ flex: 1;
50
+ }
51
+
52
+ [templates] {
53
+ flex: 2;
54
+ display: flex;
55
+ flex-direction: column;
56
+ overflow: hidden;
57
+ }
58
+
59
+ [templates] > ox-process-template-list {
60
+ flex: 1;
61
+ overflow: hidden;
38
62
  }
39
63
  `
40
64
  ]
@@ -43,28 +67,39 @@ export class ProcessCreationPopup extends localize(i18next)(LitElement) {
43
67
  @property({ type: String }) defaultGroup?: string
44
68
  @property({ type: Array }) groups?: { id: string; name: string }[]
45
69
 
70
+ @query('ox-process-template-list') processTemplateList!: OxProcessTemplateList
71
+
46
72
  render() {
47
73
  var groups = this.groups || []
48
74
 
49
75
  return html`
50
- <div content>
51
- <mwc-textfield label=${String(i18next.t('label.name'))} name="name" required field-name></mwc-textfield>
52
- <mwc-textarea
53
- label=${String(i18next.t('label.description'))}
54
- name="description"
55
- field-description
56
- ></mwc-textarea>
57
- <mwc-select
58
- label=${String(i18next.t('label.group'))}
59
- field-group
60
- helper="If there is no group to choose, you can leave it empty."
61
- >
62
- ${groups.map(
63
- group => html`
64
- <mwc-list-item value=${group.id} ?selected=${this.defaultGroup == group.id}>${group.name}</mwc-list-item>
65
- `
66
- )}
67
- </mwc-select>
76
+ <div body>
77
+ <div content>
78
+ <mwc-textfield label=${String(i18next.t('label.name'))} name="name" required field-name></mwc-textfield>
79
+ <mwc-textarea
80
+ label=${String(i18next.t('label.description'))}
81
+ name="description"
82
+ field-description
83
+ ></mwc-textarea>
84
+ <mwc-select
85
+ label=${String(i18next.t('label.group'))}
86
+ field-group
87
+ helper="If there is no group to choose, you can leave it empty."
88
+ >
89
+ ${groups.map(
90
+ group => html`
91
+ <mwc-list-item value=${group.id} ?selected=${this.defaultGroup == group.id}
92
+ >${group.name}</mwc-list-item
93
+ >
94
+ `
95
+ )}
96
+ </mwc-select>
97
+ </div>
98
+
99
+ <div templates>
100
+ <div>${i18next.t('label.process-template')}</div>
101
+ <ox-process-template-list></ox-process-template-list>
102
+ </div>
68
103
  </div>
69
104
 
70
105
  <mwc-button
@@ -81,7 +116,7 @@ export class ProcessCreationPopup extends localize(i18next)(LitElement) {
81
116
  }, 100)
82
117
  }
83
118
 
84
- onClickSubmit() {
119
+ async onClickSubmit() {
85
120
  var [name, description, groupId] = ['name', 'description', 'group'].map(attr => {
86
121
  return (this.renderRoot.querySelector(`[field-${attr}]`) as any)?.value
87
122
  })
@@ -90,12 +125,16 @@ export class ProcessCreationPopup extends localize(i18next)(LitElement) {
90
125
  return
91
126
  }
92
127
 
128
+ const template = await this.processTemplateList.getSelected()
129
+
93
130
  this.dispatchEvent(
94
131
  new CustomEvent('create-process', {
95
132
  detail: {
96
133
  name,
97
134
  description,
98
- groupId
135
+ groupId,
136
+ model: template?.model,
137
+ thumbnail: template?.thumbnail
99
138
  }
100
139
  })
101
140
  )
package/src/types.ts CHANGED
@@ -47,6 +47,7 @@ export type Process = {
47
47
  description?: string
48
48
  model?: any
49
49
  groupId?: string
50
+ thumbnail?: string
50
51
  }
51
52
 
52
53
  export type ProcessGroup = {