@processmaker/screen-builder 2.90.0 → 2.92.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.
Files changed (37) hide show
  1. package/README.md +5 -4
  2. package/dist/vue-form-builder.css +1 -1
  3. package/dist/vue-form-builder.es.js +7897 -7488
  4. package/dist/vue-form-builder.es.js.map +1 -1
  5. package/dist/vue-form-builder.umd.js +76 -59
  6. package/dist/vue-form-builder.umd.js.map +1 -1
  7. package/package.json +3 -3
  8. package/src/DataProvider.js +31 -11
  9. package/src/assets/icons/Bypass.svg +5 -0
  10. package/src/assets/icons/Unbypass.svg +5 -0
  11. package/src/components/accordions.js +1 -0
  12. package/src/components/computed-properties.vue +211 -110
  13. package/src/components/index.js +2 -0
  14. package/src/components/inspector/options-list.vue +1 -1
  15. package/src/components/renderer/form-list-table.vue +11 -2
  16. package/src/components/renderer/form-requests.vue +13 -26
  17. package/src/components/renderer/form-tasks.vue +5 -3
  18. package/src/components/renderer/index.js +1 -0
  19. package/src/components/renderer/link-button.vue +30 -0
  20. package/src/components/sortable/Sortable.vue +95 -13
  21. package/src/components/sortable/sortable.scss +5 -0
  22. package/src/components/sortable/sortableList/SortableList.vue +103 -36
  23. package/src/components/sortable/sortableList/sortableList.scss +63 -22
  24. package/src/components/task.vue +256 -59
  25. package/src/components/vue-form-builder.vue +19 -10
  26. package/src/components/watchers-form.vue +4 -3
  27. package/src/components/watchers-list.vue +46 -100
  28. package/src/components/watchers-popup.vue +89 -16
  29. package/src/customLogs.js +26 -0
  30. package/src/form-builder-controls.js +42 -0
  31. package/src/main.js +26 -1
  32. package/src/mixins/Json2Vue.js +5 -3
  33. package/src/mixins/computedFields.js +25 -7
  34. package/src/mixins/extensions/ComputedFields.js +26 -5
  35. package/src/mixins/extensions/Watchers.js +4 -0
  36. package/src/mixins/watchers.js +5 -2
  37. package/src/stories/Sortable.stories.js +58 -11
@@ -1,15 +1,13 @@
1
1
  <template>
2
2
  <div v-if="showTable">
3
3
  <filter-table
4
+ table-name="form-cases"
4
5
  :headers="tableHeaders"
5
6
  :data="tableData"
6
7
  :unread="unreadColumnName"
7
8
  :loading="shouldShowLoader"
8
9
  >
9
- <template
10
- v-for="(row, rowIndex) in data.data"
11
- v-slot:[`row-${rowIndex}`]
12
- >
10
+ <template v-for="(row, rowIndex) in data.data" #[`row-${rowIndex}`]>
13
11
  <td
14
12
  v-for="(header, colIndex) in tableHeaders"
15
13
  :key="`${rowIndex}-${colIndex}`"
@@ -98,7 +96,7 @@ export default {
98
96
  },
99
97
  computed: {
100
98
  noDataUrl() {
101
- return `${window.ProcessMaker?.app?.url}/requests`;
99
+ return `${window.ProcessMaker?.app?.url}/cases`;
102
100
  }
103
101
  },
104
102
  mounted() {
@@ -167,11 +165,12 @@ export default {
167
165
  variant: "primary",
168
166
  textColor: "text-primary",
169
167
  colorText: "color: #1572C2",
170
- url: "/requests",
168
+ url: "/cases",
171
169
  dropdownShow: "requests"
172
170
  };
173
171
  const tasksDropdown = [];
174
172
  this.$emit("requestsCount", { dataControls, tasksDropdown });
173
+ this.$refs["form-case"].resetToOriginalWidths();
175
174
  })
176
175
  .catch(() => {
177
176
  this.tableData = [];
@@ -249,24 +248,17 @@ export default {
249
248
  this.fetch();
250
249
  },
251
250
  setupColumns() {
252
- const columns = this.getColumns();
253
- this.tableHeaders = this.getColumns();
251
+ const columnsCases = this.getColumnsCases();
252
+ this.tableHeaders = this.getColumnsCases();
254
253
 
255
- columns.forEach((column) => {
254
+ columnsCases.forEach((column) => {
256
255
  const field = {
257
- title: () => this.$t(column.label),
256
+ title: () => this.$t(column.label)
258
257
  };
259
258
 
260
259
  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";
260
+ case "case_number":
261
+ field.name = "__slot:case_number";
270
262
  break;
271
263
  case "case_title":
272
264
  field.name = "__slot:case_title";
@@ -293,13 +285,8 @@ export default {
293
285
 
294
286
  this.fields.push(field);
295
287
  });
296
-
297
- this.fields.push({
298
- name: "__slot:actions",
299
- title: ""
300
- });
301
288
  },
302
- getColumns() {
289
+ getColumnsCases() {
303
290
  return [
304
291
  {
305
292
  label: "Case #",
@@ -325,7 +312,7 @@ export default {
325
312
  sortable: true,
326
313
  default: true,
327
314
  width: 113,
328
- fixed_width: 314,
315
+ fixed_width: 113,
329
316
  resizable: false,
330
317
  filter_subject: { type: "Status" }
331
318
  },
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div v-if="showTable">
3
3
  <filter-table
4
+ table-name="form-tasks"
4
5
  :headers="tableHeaders"
5
6
  :data="tableData"
6
7
  :unread="unreadColumnName"
@@ -270,6 +271,7 @@ export default {
270
271
  dropdownShow: "tasks"
271
272
  };
272
273
  this.$emit("tasksCount", { dataControls, tasksDropdown });
274
+ this.$refs["form-task"].resetToOriginalWidths();
273
275
  })
274
276
  .catch(() => {
275
277
  this.tableData = [];
@@ -308,7 +310,7 @@ export default {
308
310
  let draftBadge = "";
309
311
  if (record.draft && record.status !== "CLOSED") {
310
312
  draftBadge = `
311
- <span class ="badge badge-warning status-warnig">
313
+ <span class ="badge badge-warning status-warning">
312
314
  ${this.$t("Draft")}
313
315
  </span>
314
316
  `;
@@ -386,9 +388,9 @@ export default {
386
388
  },
387
389
  setupColumns() {
388
390
  this.tableHeaders = this.getColumns();
389
- const columns = this.getColumns();
391
+ const columnsTasks = this.getColumns();
390
392
 
391
- columns.forEach((column) => {
393
+ columnsTasks.forEach((column) => {
392
394
  const field = {
393
395
  title: () => this.$t(column.label)
394
396
  };
@@ -18,3 +18,4 @@ export { default as FormListTable } from "./form-list-table.vue";
18
18
  export { default as FormAnalyticsChart } from "./form-analytics-chart.vue";
19
19
  export { default as FormRequests } from "./form-requests.vue";
20
20
  export { default as FormTasks } from "./form-tasks.vue";
21
+ export { default as LinkButton } from "./link-button.vue";
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <div class="form-group">
3
+ <a :class="classColor" :href="inputUrlLink"> {{ label }} </a>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ props: [
10
+ "variant",
11
+ "label",
12
+ "event",
13
+ "eventData",
14
+ "name",
15
+ "fieldValue",
16
+ "value",
17
+ "inputUrlLink"
18
+ ],
19
+ computed: {
20
+ classColor() {
21
+ return `text-${this.variant}`;
22
+ }
23
+ }
24
+ };
25
+ </script>
26
+ <style scoped>
27
+ a {
28
+ text-decoration: underline;
29
+ }
30
+ </style>
@@ -15,6 +15,7 @@
15
15
  <button
16
16
  type="button"
17
17
  class="btn sortable-btn-new"
18
+ v-bind="testActions.btnNew"
18
19
  @click="$emit('add-page', $event)"
19
20
  >
20
21
  <i class="fa fa-plus"></i>
@@ -23,26 +24,47 @@
23
24
  </div>
24
25
 
25
26
  <SortableList
27
+ :fields="fields"
26
28
  :items="items"
27
29
  :filtered-items="filteredItems"
30
+ :inline-edit="inlineEdit"
31
+ :disable-key="disableKey"
32
+ :data-test-actions="testActions"
28
33
  @ordered="$emit('ordered', $event)"
29
34
  @item-edit="$emit('item-edit', $event)"
30
35
  @item-delete="$emit('item-delete', $event)"
31
- />
36
+ >
37
+ <template #options="{ item }">
38
+ <slot name="options" :item="item"></slot>
39
+ </template>
40
+ </SortableList>
32
41
  </div>
33
42
  </template>
34
43
 
35
44
  <script>
36
- import SortableList from './sortableList/SortableList.vue'
45
+ import SortableList from './sortableList/SortableList.vue';
37
46
 
38
47
  export default {
39
48
  name: 'Sortable',
40
49
  components: {
41
- SortableList
50
+ SortableList,
42
51
  },
43
52
  props: {
53
+ fields: { type: Array, required: true },
44
54
  items: { type: Array, required: true },
45
- filterKey: { type: String, required: true },
55
+ disableKey: { type: String, default: null },
56
+ inlineEdit: { type: Boolean, default: true },
57
+ dataTestActions: {
58
+ type: Object,
59
+ default: () => ({}),
60
+ },
61
+ searchProperties: {
62
+ type: Array,
63
+ required: false,
64
+ default() {
65
+ return []; // Return a new instance of the array
66
+ },
67
+ },
46
68
  },
47
69
  data() {
48
70
  return {
@@ -54,34 +76,94 @@ export default {
54
76
  this.$set(item, "order", index + 1);
55
77
  }
56
78
  return item;
57
- })
79
+ }),
80
+ defaultTestActions: {
81
+ tableBox: { 'data-test': 'sortable-table-box' },
82
+ btnNew: { 'data-test': 'sortable-btn-new' },
83
+ btnEdit: { 'data-test': 'sortable-btn-edit' },
84
+ btnDelete: { 'data-test': 'sortable-btn-remove' },
85
+ },
58
86
  };
59
87
  },
88
+ computed: {
89
+ testActions() {
90
+ return { ...this.defaultTestActions, ...this.dataTestActions };
91
+ },
92
+ },
60
93
  watch: {
61
94
  search(value) {
62
- this.filteredItems = this.filterItems(value, this.items);
95
+ this.filteredItems = this.filterItems(value, this.items, this.searchProperties);
63
96
  },
64
97
  items: {
65
98
  handler(newItems) {
66
99
  this.filteredItems = [...newItems];
67
100
 
68
101
  if (this.search.length > 0) {
69
- this.filteredItems = this.filterItems(this.search, newItems);
102
+ this.filteredItems = this.filterItems(this.search, newItems, this.searchProperties);
70
103
  }
71
104
  },
72
105
  deep: true,
73
106
  },
74
107
  },
75
108
  methods: {
76
- clearSearch(value) {
77
- return value.trim().toLowerCase();
109
+ /**
110
+ * Filters items by searching within specified properties, including nested properties, considering substrings.
111
+ *
112
+ * @param {string} searchValue - The value to search for within item properties.
113
+ * @param {Array} items - The collection of items to filter.
114
+ * @param {Array} searchProperties - The properties to search within each item.
115
+ * @returns {Array} - The filtered items.
116
+ */
117
+ filterItems(searchValue, items, searchProperties) {
118
+ const cleanSearch = this.clearSearch(searchValue).toLowerCase();
119
+
120
+ return items.filter((item) => {
121
+ return this.propertyMatchesSearch(item, searchProperties, cleanSearch);
122
+ });
78
123
  },
79
- filterItems(searchValue, items) {
80
- const cleanSearch = this.clearSearch(searchValue);
81
- return items.filter((item) => item[this.filterKey].toLowerCase().includes(cleanSearch));
124
+
125
+ /**
126
+ * Checks if any of the specified properties of an item match the cleaned search value as a substring.
127
+ *
128
+ * @param {Object} item - The item object to check.
129
+ * @param {Array} properties - The properties to search within each item.
130
+ * @param {string} cleanSearch - The cleaned and lowercase search value.
131
+ * @returns {boolean} - True if any property matches the search value, otherwise false.
132
+ */
133
+ propertyMatchesSearch(item, properties, cleanSearch) {
134
+ return properties.some((property) => {
135
+ const value = this.getPropertyValue(item, property);
136
+ if (value && typeof value === 'string') {
137
+ const normalizedValue = value.toLowerCase();
138
+ return normalizedValue.includes(cleanSearch);
139
+ }
140
+ return false;
141
+ });
142
+ },
143
+
144
+ /**
145
+ * Retrieves the value of a nested property within an object.
146
+ *
147
+ * @param {Object} obj - The object from which to retrieve the property value.
148
+ * @param {string} path - The path to the nested property, e.g., "item.title".
149
+ * @returns {*} - The value of the nested property if found, otherwise undefined.
150
+ */
151
+ getPropertyValue(obj, path) {
152
+ const parts = path.split('.');
153
+ return parts.reduce((acc, curr) => acc?.[curr], obj);
154
+ },
155
+
156
+ /**
157
+ * Cleans the search value by removing unwanted characters and trimming spaces.
158
+ *
159
+ * @param {string} searchValue - The value to be cleaned.
160
+ * @returns {string} - The cleaned search value.
161
+ */
162
+ clearSearch(searchValue) {
163
+ return searchValue.trim();
82
164
  },
83
165
  },
84
- }
166
+ };
85
167
  </script>
86
168
 
87
169
  <style lang="scss" scoped src="./sortable.scss"></style>
@@ -1,12 +1,17 @@
1
1
  .sortable {
2
2
  &-box {
3
3
  font-family: "Open Sans", sans-serif !important;
4
+ overflow-x: auto;
4
5
  }
5
6
 
6
7
  &-search-box {
7
8
  display: flex;
8
9
  align-items: center;
9
10
  border-color: #cdddee !important;
11
+
12
+ & > input.form-control:focus {
13
+ border: 0 none !important;
14
+ }
10
15
  }
11
16
 
12
17
  &-search-icon {
@@ -1,51 +1,90 @@
1
1
  <template>
2
2
  <div class="row mt-3">
3
- <div class="col p-0 border rounded-lg sortable-list">
4
- <div class="sortable-list-header">
5
- <div class="sortable-item-icon"></div>
6
- <div class="sortable-list-title">PAGE NAME</div>
7
- </div>
8
- <div class="sortable-container" @dragover="dragOver">
3
+ <div
4
+ class="p-0 border rounded-lg sortable-list"
5
+ v-bind="dataTestActions.tableBox"
6
+ @dragover="dragOver"
7
+ >
8
+ <div class="sortable-list-tr">
9
+ <div class="sortable-list-td"></div>
9
10
  <div
10
- v-for="(item, index) in sortedItems"
11
- :key="index"
12
- :data-order="item.order"
13
- :data-test="`item-${item.order}`"
14
- :title="item.name"
15
- draggable="true"
16
- @dragstart="(event) => dragStart(event, item.order)"
17
- @dragenter="(event) => dragEnter(event, item.order)"
18
- @dragend="dragEnd"
19
- class="sortable-item sortable-draggable"
11
+ v-for="field in fields"
12
+ :key="field.key"
13
+ class="sortable-list-td"
20
14
  >
15
+ <span class="sortable-list-separator">&nbsp;</span>
16
+ <span class="sortable-list-header">{{ field.label }}</span>
17
+ </div>
18
+ <div class="sortable-list-td">
19
+ <span class="sortable-list-separator">&nbsp;</span>
20
+ </div>
21
+ </div>
22
+ <div
23
+ v-for="(item, index) in sortedItems"
24
+ :key="`item-${index}`"
25
+ :data-order="item.order"
26
+ :data-test="`item-${item.order}`"
27
+ :title="item.name"
28
+ :class="[
29
+ 'sortable-list-tr',
30
+ 'sortable-item',
31
+ { 'sortable-item-disabled': isDisabled(item) },
32
+ ]"
33
+ draggable="true"
34
+ @dragstart="(event) => dragStart(event, item.order)"
35
+ @dragenter="(event) => dragEnter(event, item.order)"
36
+ @dragend="dragEnd"
37
+ >
38
+ <div class="sortable-list-td">
21
39
  <div class="sortable-item-icon">
22
40
  <i class="fas fa-bars"></i>
23
41
  </div>
24
- <div class="rounded sortable-item-name">
25
- <b-form-input
26
- v-if="editRowIndex === index"
27
- v-model="newName"
28
- type="text"
29
- autofocus
30
- required
31
- :state="validateState(newName, item)"
32
- :error="validateError(newName, item)"
33
- @blur.stop="onBlur(newName, item)"
34
- @keydown.enter.stop="onBlur(newName, item)"
35
- @keydown.esc.stop="onCancel(item)"
36
- @focus="onFocus(item)"
37
- />
38
- <span v-else>{{ item.name }}</span>
39
- </div>
42
+ </div>
43
+ <div
44
+ v-for="field in fields"
45
+ :key="field.key"
46
+ class="sortable-list-td sortable-item-prop"
47
+ >
48
+ <b-form-input
49
+ v-if="editRowIndex === index"
50
+ v-model="newName"
51
+ type="text"
52
+ autofocus
53
+ required
54
+ :state="validateState(newName, item)"
55
+ :error="validateError(newName, item)"
56
+ @blur.stop="onBlur(newName, item)"
57
+ @keydown.enter.stop="onBlur(newName, item)"
58
+ @keydown.esc.stop="onCancel(item)"
59
+ @focus="onFocus(item)"
60
+ />
61
+ <span v-else>{{ getItemValue(item, field.key, field.cb) }}</span>
62
+ </div>
63
+
64
+ <div class="sortable-list-td">
40
65
  <div class="border rounded-lg sortable-item-action">
41
66
  <button v-if="editRowIndex === index" class="btn">
42
67
  <i class="fas fa-check"></i>
43
68
  </button>
44
- <button v-else class="btn" @click.stop="onClick(item, index)">
69
+ <button
70
+ v-else
71
+ v-b-tooltip="{ customClass: 'sortable-item-action-btn-tooltip' }"
72
+ class="btn"
73
+ :title="$t('Edit')"
74
+ v-bind="dataTestActions.btnEdit"
75
+ @click.stop="onClick(item, index)"
76
+ >
45
77
  <i class="fas fa-edit"></i>
46
78
  </button>
47
79
  <div class="sortable-item-vr"></div>
48
- <button class="btn" @click="$emit('item-delete', item)">
80
+ <slot name="options" :item="item"></slot>
81
+ <button
82
+ v-b-tooltip="{ customClass: 'sortable-item-action-btn-tooltip' }"
83
+ class="btn"
84
+ :title="$t('Delete')"
85
+ v-bind="dataTestActions.btnDelete"
86
+ @click="$emit('item-delete', item)"
87
+ >
49
88
  <i class="fas fa-trash-alt"></i>
50
89
  </button>
51
90
  </div>
@@ -59,8 +98,12 @@
59
98
  export default {
60
99
  name: 'SortableList',
61
100
  props: {
101
+ fields: { type: Array, required: true },
62
102
  items: { type: Array, required: true },
63
103
  filteredItems: { type: Array, required: true },
104
+ inlineEdit: { type: Boolean, default: true },
105
+ disableKey: { type: String, default: null },
106
+ dataTestActions: { type: Object, required: true },
64
107
  },
65
108
  data() {
66
109
  return {
@@ -77,9 +120,22 @@ export default {
77
120
  this.refreshSort &&
78
121
  [...this.filteredItems].sort((a, b) => a.order - b.order);
79
122
  return sortedItems;
80
- }
123
+ },
81
124
  },
82
125
  methods: {
126
+ /** Get the value of a nested field in an object
127
+ * @param {Object} item - The object to get the value from
128
+ * @param {String} fieldKey - The key of the field to get the value from
129
+ * @param {Function} cb - Callback function to apply to the value
130
+ *
131
+ * @returns {String} The value of the field
132
+ */
133
+ getItemValue(item, fieldKey, cb = null) {
134
+ return fieldKey.split('.').reduce((obj, key) => {
135
+ if (!obj[key]) return '';
136
+ return cb instanceof Function ? cb(obj[key]) : obj[key];
137
+ }, item);
138
+ },
83
139
  validateState(name, item) {
84
140
  const isEmpty = !name?.trim();
85
141
  const isDuplicated = this.items
@@ -120,6 +176,11 @@ export default {
120
176
  this.editRowIndex = null;
121
177
  },
122
178
  onClick(item, index) {
179
+ if (!this.inlineEdit) {
180
+ this.$emit("item-edit", item);
181
+ return;
182
+ }
183
+
123
184
  this.editRowIndex = index;
124
185
  this.$emit("item-edit", item);
125
186
  },
@@ -129,6 +190,9 @@ export default {
129
190
  this.draggedItem = order;
130
191
  // add dragging class to the element
131
192
  event.target.classList.add('dragging');
193
+ if (event?.dataTransfer) {
194
+ event.dataTransfer.effectAllowed = 'move';
195
+ }
132
196
  },
133
197
  dragEnter(event, order) {
134
198
  this.draggedOverItem = order;
@@ -185,8 +249,11 @@ export default {
185
249
  dragOver(event) {
186
250
  event.preventDefault();
187
251
  },
252
+ isDisabled(item) {
253
+ return this.disableKey ? item[this.disableKey] : false;
254
+ },
188
255
  },
189
- }
256
+ };
190
257
  </script>
191
258
 
192
259
  <style lang="scss" scoped src="./sortableList.scss"></style>
@@ -2,44 +2,67 @@ $border-color: #cdddee;
2
2
 
3
3
  .sortable {
4
4
  &-list {
5
- display: flex;
5
+ display: table;
6
6
  flex-direction: column;
7
+ width: 100%;
7
8
  border: 1px solid $border-color !important;
8
9
 
9
- &-header {
10
- display: flex;
11
- align-items: center;
10
+ &-tr {
11
+ display: table-row;
12
+
13
+ &:last-child > .sortable-list-td {
14
+ border-bottom: none;
15
+ }
16
+ }
17
+
18
+ &-td {
19
+ display: table-cell;
12
20
  border-bottom: 1px solid $border-color;
21
+ white-space: nowrap;
22
+
23
+ &:first-child {
24
+ width: 60px;
25
+ }
26
+
27
+ &:nth-child(2) {
28
+ min-width: 30%;
29
+ width: auto;
30
+ }
31
+
32
+ &:not(:first-child):not(:nth-child(2)):not(:last-child) {
33
+ width: auto;
34
+ }
35
+
36
+ &:last-child {
37
+ width: 1%;
38
+ white-space: nowrap;
39
+ }
13
40
  }
14
41
 
15
- &-title {
16
- padding-left: 16px;
42
+ &-header {
43
+ padding: 16px 0 16px 16px;
17
44
  font-size: 14px;
18
- font-weight: bold;
45
+ font-weight: 700;
19
46
  color: #566877;
47
+ text-transform: uppercase;
48
+ display: inline-block;
49
+ white-space: normal;
50
+ }
51
+ &-separator {
52
+ border-left: 1px solid $border-color;
53
+ display: inline-block;
54
+ padding: 0.5rem 0rem;
55
+ width: 1px;
20
56
  }
21
- }
22
-
23
- &-container {
24
- display: flex;
25
- flex-direction: column;
26
- width: 100%;
27
- height: 340px;
28
- overflow-x: auto;
29
57
  }
30
58
 
31
59
  &-item {
32
- display: flex;
33
- align-items: center;
34
- height: 56px;
35
- border-bottom: 1px solid $border-color;
36
60
  cursor: move;
37
61
 
38
62
  &-icon {
39
63
  display: flex;
40
64
  justify-content: center;
41
65
  align-items: center;
42
- width: 64px;
43
66
  height: 56px;
44
67
  }
45
68
 
@@ -47,8 +70,7 @@ $border-color: #cdddee;
47
70
  color: #6A7888;
48
71
  }
49
72
 
50
- &-name {
51
- flex-grow: 1;
73
+ &-prop {
52
74
  padding: 8px 16px;
53
75
  font-size: 15px;
54
76
  color: #556271;
@@ -58,6 +80,18 @@ $border-color: #cdddee;
58
80
  display: flex;
59
81
  margin: 0 16px;
60
82
  border-color: $border-color !important;
83
+
84
+ &-btn-tooltip::v-deep {
85
+ & .tooltip-inner {
86
+ background-color: #EBEEF2 !important;
87
+ color: #444444 !important;
88
+ }
89
+
90
+ & .arrow:before {
91
+ border-top-color: #EBEEF2 !important;
92
+ border-bottom-color: #EBEEF2 !important;
93
+ }
94
+ }
61
95
  }
62
96
 
63
97
  &-vr {
@@ -65,9 +99,16 @@ $border-color: #cdddee;
65
99
  margin: 9px 0;
66
100
  border-right: 1px solid $border-color;
67
101
  }
102
+
103
+ &-disabled > .sortable-item-prop {
104
+ color: rgba(85, 98, 113, 0.5);
105
+ }
68
106
  }
69
107
  }
70
108
 
71
109
  .dragging {
72
110
  box-shadow: 0 1px 5px 0 rgba(86, 104, 119, 0.4);
111
+ cursor: move;
112
+ cursor: -webkit-grab;
113
+ cursor: -moz-grab;
73
114
  }