@processmaker/screen-builder 2.87.1 → 2.89.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.
@@ -1,54 +1,67 @@
1
1
  <template>
2
2
  <div v-if="showTable">
3
- <vuetable
4
- ref="vuetable"
5
- :data-manager="dataManager"
6
- :sort-order="sortOrder"
7
- :api-mode="false"
8
- :fields="fields"
3
+ <filter-table
4
+ :headers="tableHeaders"
9
5
  :data="tableData"
10
- :css="css"
11
- data-path="data"
12
- pagination-path="meta"
6
+ :unread="unreadColumnName"
7
+ :loading="shouldShowLoader"
13
8
  >
14
- <template slot="ids" slot-scope="props">
15
- <b-link
16
- class="text-nowrap"
17
- :href="openRequest(props.rowData, props.rowIndex)"
9
+ <template
10
+ v-for="(row, rowIndex) in data.data"
11
+ v-slot:[`row-${rowIndex}`]
12
+ >
13
+ <td
14
+ v-for="(header, colIndex) in tableHeaders"
15
+ :key="`${rowIndex}-${colIndex}`"
18
16
  >
19
- #{{ props.rowData.id }}
20
- </b-link>
21
- </template>
22
- <template slot="name" slot-scope="props">
23
- <span v-uni-id="props.rowData.id.toString()">{{
24
- props.rowData.name
25
- }}</span>
26
- </template>
27
- <template slot="status" slot-scope="props">
28
- <span>
29
- <i :class="`fas fa-circle text-${props.rowData.status.color}`" />
30
- {{ props.rowData.status.label }}
31
- </span>
32
- </template>
33
- <template slot="actions" slot-scope="props">
34
- <div class="actions">
35
- <div class="popout">
36
- <b-btn
37
- v-b-tooltip.hover
38
- v-uni-aria-describedby="props.rowData.id.toString()"
39
- variant="link"
40
- :href="openRequest(props.rowData, props.rowIndex)"
41
- :title="$t('Open Request')"
17
+ <template v-if="containsHTML(getNestedPropertyValue(row, header))">
18
+ <div
19
+ :id="`element-${rowIndex}-${colIndex}`"
20
+ :class="{ 'pm-table-truncate': header.truncate }"
21
+ :style="{ maxWidth: header.width + 'px' }"
42
22
  >
43
- <i class="fas fa-caret-square-right fa-lg fa-fw" />
44
- </b-btn>
45
- </div>
46
- </div>
23
+ <span v-html="sanitize(getNestedPropertyValue(row, header))"></span>
24
+ </div>
25
+ <b-tooltip
26
+ v-if="header.truncate"
27
+ :target="`element-${rowIndex}-${colIndex}`"
28
+ custom-class="pm-table-tooltip"
29
+ @show="checkIfTooltipIsNeeded"
30
+ >
31
+ {{ sanitizeTooltip(getNestedPropertyValue(row, header)) }}
32
+ </b-tooltip>
33
+ </template>
34
+ <template v-else>
35
+ <template v-if="isComponent(row[header.field])">
36
+ <component
37
+ :is="row[header.field].component"
38
+ v-bind="row[header.field].props"
39
+ />
40
+ </template>
41
+ <template v-else>
42
+ <div
43
+ :id="`element-${rowIndex}-${colIndex}`"
44
+ :class="{ 'pm-table-truncate': header.truncate }"
45
+ :style="{ maxWidth: header.width + 'px' }"
46
+ >
47
+ {{ getNestedPropertyValue(row, header) }}
48
+ <b-tooltip
49
+ v-if="header.truncate"
50
+ :target="`element-${rowIndex}-${colIndex}`"
51
+ custom-class="pm-table-tooltip"
52
+ @show="checkIfTooltipIsNeeded"
53
+ >
54
+ {{ getNestedPropertyValue(row, header) }}
55
+ </b-tooltip>
56
+ </div>
57
+ </template>
58
+ </template>
59
+ </td>
47
60
  </template>
48
- </vuetable>
61
+ </filter-table>
49
62
  </div>
50
63
  <div v-else>
51
- <formEmpty link="Requests" title="No Requests to Show" :url="noDataUrl" />
64
+ <formEmpty link="Requests" title="No Cases to Show" :url="noDataUrl" />
52
65
  </div>
53
66
  </template>
54
67
 
@@ -72,13 +85,15 @@ export default {
72
85
  orderDirection: "DESC",
73
86
  additionalParams: "",
74
87
  showTable: true,
88
+ pmqlSearch: "",
75
89
  sortOrder: [
76
90
  {
77
91
  field: "id",
78
92
  sortField: "id",
79
93
  direction: "desc"
80
94
  }
81
- ]
95
+ ],
96
+ tableHeaders: [],
82
97
  };
83
98
  },
84
99
  computed: {
@@ -87,7 +102,7 @@ export default {
87
102
  }
88
103
  },
89
104
  mounted() {
90
- this.setFields();
105
+ this.setupColumns();
91
106
  this.pmql = `requester = "${Processmaker.user.username}"`;
92
107
  this.fetch();
93
108
  this.$root.$on("dropdownSelectionRequest", this.fetchData);
@@ -102,6 +117,10 @@ export default {
102
117
  pmql = this.pmql;
103
118
  }
104
119
 
120
+ if (this.pmqlSearch) {
121
+ pmql = pmql + "AND" + this.pmqlSearch;
122
+ }
123
+
105
124
  let { filter } = this;
106
125
 
107
126
  if (filter && filter.length) {
@@ -135,7 +154,8 @@ export default {
135
154
  .then((response) => {
136
155
  this.showTable = response.data.data.length !== 0;
137
156
  for (const record of response.data.data) {
138
- // format Status
157
+ record.case_number = this.formatOpenCase(record, "case_number");
158
+ record.case_title = this.formatOpenCase(record, "case_title");
139
159
  record.status = this.formatStatus(record.status);
140
160
  }
141
161
  this.tableData = response.data;
@@ -158,39 +178,6 @@ export default {
158
178
  });
159
179
  });
160
180
  },
161
- setFields() {
162
- this.fields.push({
163
- name: "__slot:ids",
164
- field: "id",
165
- sortField: "id",
166
- sortable: true,
167
- title: "#"
168
- });
169
-
170
- this.fields.push({
171
- name: "__slot:name",
172
- field: "name",
173
- sortField: "name",
174
- sortable: true,
175
- title: () => this.$t("Name")
176
- });
177
-
178
- this.fields.push({
179
- name: "__slot:status",
180
- field: "status",
181
- sortField: "status",
182
- sortable: true,
183
- title: () => this.$t("Status")
184
- });
185
-
186
- this.fields.push({
187
- name: "__slot:actions",
188
- title: ""
189
- });
190
- this.$nextTick(() => {
191
- this.$refs.vuetable.normalizeFields();
192
- });
193
- },
194
181
  formatStatus(status) {
195
182
  let color = "";
196
183
  let label = "";
@@ -215,9 +202,20 @@ export default {
215
202
  color = "success";
216
203
  label = "In Progress";
217
204
  }
218
- return { color, label };
205
+ return `<span class="badge badge-${color} status-${color}"> ${label} </span>`;
219
206
  },
220
- openRequest(data, index) {
207
+ /**
208
+ * Add the formart to column to open a case in other tab
209
+ */
210
+ formatOpenCase(value, option) {
211
+ const attr = value;
212
+ if (option === "case_title") {
213
+ attr[option] = value.case_title_formatted || value.case_title || "";
214
+ }
215
+ return `<a href="${this.openRequest(value)}" class="text-nowrap"
216
+ target="_blank">${attr[option]}</a>`;
217
+ },
218
+ openRequest(data) {
221
219
  return `/requests/${data.id}`;
222
220
  },
223
221
  classDueDate(value) {
@@ -231,25 +229,114 @@ export default {
231
229
  : "text-dark";
232
230
  },
233
231
  fetchData(selectedOptions) {
234
- if (selectedOptions[0] === "by_me" && selectedOptions[1] !== "all") {
232
+ if (selectedOptions[0] === "by_me" && selectedOptions[1] !== "View All") {
235
233
  this.pmql = `(user_id = ${ProcessMaker.user.id}) AND (status = "${selectedOptions[1]}")`;
236
234
  }
237
235
  if (
238
236
  selectedOptions[0] === "as_participant" &&
239
- selectedOptions[1] !== "all"
237
+ selectedOptions[1] !== "View All"
240
238
  ) {
241
239
  this.pmql = `(status = "${selectedOptions[1]}") AND (participant = "${Processmaker.user.username}")`;
242
240
  }
243
- if (selectedOptions[1] === "all") {
241
+ if (selectedOptions[1] === "View All") {
244
242
  this.pmql = `(user_id = ${ProcessMaker.user.id}) AND ((status = "In Progress") OR (status = "Completed"))`;
245
243
  }
246
244
  this.fetch();
247
245
  },
248
246
  fetchSearch(searchData) {
249
- this.pmql = "";
250
- this.pmql = searchData;
247
+ this.pmqlSearch = "";
248
+ this.pmqlSearch = searchData;
251
249
  this.fetch();
250
+ },
251
+ setupColumns() {
252
+ const columns = this.getColumns();
253
+ this.tableHeaders = this.getColumns();
254
+
255
+ columns.forEach((column) => {
256
+ const field = {
257
+ title: () => this.$t(column.label),
258
+ };
259
+
260
+ switch (column.field) {
261
+ case "id":
262
+ field.name = "__slot:ids";
263
+ field.title = "#";
264
+ break;
265
+ case "participants":
266
+ field.name = "__slot:participants";
267
+ break;
268
+ case "name":
269
+ field.name = "__slot:name";
270
+ break;
271
+ case "case_title":
272
+ field.name = "__slot:case_title";
273
+ break;
274
+ default:
275
+ field.name = column.name || column.field;
276
+ }
277
+
278
+ if (!field.field) {
279
+ field.field = column.field;
280
+ }
281
+
282
+ if (column.format === "datetime") {
283
+ field.callback = "formatDateUser|datetime";
284
+ }
285
+
286
+ if (column.format === "date") {
287
+ field.callback = "formatDateUser|date";
288
+ }
289
+
290
+ if (column.sortable === true && !field.sortField) {
291
+ field.sortField = column.field;
292
+ }
293
+
294
+ this.fields.push(field);
295
+ });
296
+
297
+ this.fields.push({
298
+ name: "__slot:actions",
299
+ title: ""
300
+ });
301
+ },
302
+ getColumns() {
303
+ return [
304
+ {
305
+ label: "Case #",
306
+ field: "case_number",
307
+ sortable: true,
308
+ default: true,
309
+ width: 96,
310
+ fixed_width: 96
311
+ },
312
+ {
313
+ label: "Case title",
314
+ field: "case_title",
315
+ sortable: true,
316
+ default: true,
317
+ truncate: true,
318
+ width: 314,
319
+ fixed_width: 314,
320
+ resizable: false
321
+ },
322
+ {
323
+ label: "Status",
324
+ field: "status",
325
+ sortable: true,
326
+ default: true,
327
+ width: 113,
328
+ fixed_width: 314,
329
+ resizable: false,
330
+ filter_subject: { type: "Status" }
331
+ }
332
+ ];
252
333
  }
253
334
  }
254
335
  };
255
336
  </script>
337
+
338
+ <style scoped>
339
+ .pm-table-container {
340
+ height: 300px;
341
+ }
342
+ </style>