evui 3.4.9 → 3.4.10

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.
@@ -54,7 +54,10 @@
54
54
  <li
55
55
  v-if="useCheckbox.use"
56
56
  :class="headerCheckboxClass"
57
- :style="`width: ${minWidth}px;`"
57
+ :style="{
58
+ width: `${minWidth}px`,
59
+ 'border-right': '1px solid #CFCFCF',
60
+ }"
58
61
  >
59
62
  <ev-checkbox
60
63
  v-if="isHeaderCheckbox"
@@ -92,6 +95,21 @@
92
95
  />
93
96
  </li>
94
97
  </template>
98
+ <!-- Row Contextmenu Column -->
99
+ <li
100
+ v-if="$props.option.customContextMenu?.length"
101
+ :class="{
102
+ column: true,
103
+ 'non-border': !!borderStyle,
104
+ }"
105
+ :style="{
106
+ width: '30px',
107
+ 'min-width': '30px',
108
+ 'margin-right': (hasVerticalScrollBar || hasHorizontalScrollBar)
109
+ ? `${scrollWidth}px` : '0px',
110
+ }"
111
+ >
112
+ </li>
95
113
  </ul>
96
114
  </div>
97
115
  <!-- Body -->
@@ -120,6 +138,8 @@
120
138
  :collapse-icon="option.collapseIcon"
121
139
  :parent-icon="option.parentIcon"
122
140
  :child-icon="option.childIcon"
141
+ :custom-context-menu="customContextMenu"
142
+ :menu-ref="menu"
123
143
  :is-resize="isResize"
124
144
  :row-height="rowHeight"
125
145
  :min-width="minWidth"
@@ -129,6 +149,7 @@
129
149
  @expand-tree-data="handleExpand"
130
150
  @click-tree-data="onRowClick"
131
151
  @dbl-click-tree-data="onRowDblClick"
152
+ @context-menu="onContextMenu"
132
153
  >
133
154
  <!-- Cell Renderer -->
134
155
  <template
@@ -152,6 +173,14 @@
152
173
  </span>
153
174
  </template>
154
175
  </template>
176
+ <template
177
+ v-if="$slots.contextmenuIcon"
178
+ #contextmenuIconNode
179
+ >
180
+ <slot
181
+ name="contextmenuIcon"
182
+ />
183
+ </template>
155
184
  </tree-grid-node>
156
185
  <tr v-if="!viewStore.length">
157
186
  <td class="is-empty">No records</td>
@@ -469,6 +498,7 @@ export default {
469
498
  isRenderer,
470
499
  updateVScroll,
471
500
  updateHScroll,
501
+ contextInfo,
472
502
  });
473
503
 
474
504
  const {
@@ -768,6 +798,7 @@ export default {
768
798
  'margin-right': (stores.orderedColumns.length - 1 === index
769
799
  && scrollInfo.hasVerticalScrollBar
770
800
  && scrollInfo.hasHorizontalScrollBar) ? `${resizeInfo.scrollWidth}px` : '0px',
801
+ 'border-right': stores.orderedColumns.length - 1 === index ? 'none' : '1px solid #CFCFCF',
771
802
  };
772
803
  };
773
804
  const getSlotName = column => `${column}Node`;
@@ -8,9 +8,11 @@
8
8
  <td
9
9
  v-if="useCheckbox.use"
10
10
  :class="checkboxClass"
11
- :style="`
12
- width: ${minWidth}px;
13
- height: ${rowHeight}px;`"
11
+ :style="{
12
+ width: `${minWidth}px`,
13
+ height: `${rowHeight}px`,
14
+ 'border-right': '1px solid #CFCFCF',
15
+ }"
14
16
  >
15
17
  <ev-checkbox
16
18
  v-model="node.checked"
@@ -28,9 +30,9 @@
28
30
  :data-name="column.field"
29
31
  :data-index="node.index"
30
32
  :class="getColumnClass(column, cellIndex)"
31
- :style="getColumnStyle(column)"
33
+ :style="getColumnStyle(column, cellIndex)"
32
34
  >
33
- <div class="td-content">
35
+ <div class="td-content__wrapper">
34
36
  <!--Level Depth-->
35
37
  <span
36
38
  v-if="cellIndex === expandColumnIdx"
@@ -76,7 +78,7 @@
76
78
  <i></i>
77
79
  </span>
78
80
  </span>
79
- <div class="slot-wrapper">
81
+ <div class="td-content">
80
82
  <!-- cell renderer -->
81
83
  <template v-if="!!$slots[column.field + 'Node']">
82
84
  <slot
@@ -90,14 +92,52 @@
90
92
  </div>
91
93
  </td>
92
94
  </template>
95
+ <!-- Row Contextmenu Button -->
96
+ <td
97
+ v-if="customContextMenu?.length"
98
+ :class="{
99
+ 'row-contextmenu': true,
100
+ 'non-border': !!borderStyle,
101
+ }"
102
+ :style="{
103
+ position: 'sticky',
104
+ right: 0,
105
+ width: '30px',
106
+ height: `${rowHeight}px`,
107
+ 'min-width': '30px',
108
+ 'line-height': `${rowHeight}px`,
109
+ }"
110
+ >
111
+ <template v-if="$slots.contextmenuIconNode">
112
+ <span
113
+ class="row-contextmenu__btn"
114
+ @click="onContextMenu($event)"
115
+ @click.prevent="menuRef.show"
116
+ >
117
+ <slot
118
+ name="contextmenuIconNode"
119
+ />
120
+ </span>
121
+ </template>
122
+ <template v-else>
123
+ <grid-option-button
124
+ icon="ev-icon-warning2"
125
+ class="row-contextmenu__btn"
126
+ @click="onContextMenu($event)"
127
+ @click.prevent="menuRef.show"
128
+ />
129
+ </template>
130
+ </td>
93
131
  </tr>
94
132
  </template>
95
133
 
96
134
  <script>
97
135
  import { computed } from 'vue';
136
+ import GridOptionButton from '@/components/grid/grid.optionButton.vue';
98
137
 
99
138
  export default {
100
139
  name: 'TreeGridNode',
140
+ components: { GridOptionButton },
101
141
  props: {
102
142
  dataIndex: {
103
143
  type: Number,
@@ -135,6 +175,14 @@ export default {
135
175
  type: String,
136
176
  default: '',
137
177
  },
178
+ customContextMenu: {
179
+ type: [Array],
180
+ default: () => [],
181
+ },
182
+ menuRef: {
183
+ type: Object,
184
+ default: null,
185
+ },
138
186
  rowHeight: {
139
187
  type: Number,
140
188
  default: 35,
@@ -157,6 +205,7 @@ export default {
157
205
  'expand-tree-data': null,
158
206
  'click-tree-data': null,
159
207
  'dbl-click-tree-data': null,
208
+ 'context-menu': null,
160
209
  },
161
210
  setup(props, { emit }) {
162
211
  const onCheck = ($event, data) => {
@@ -171,6 +220,9 @@ export default {
171
220
  const onDblClick = ($event, data) => {
172
221
  emit('dbl-click-tree-data', $event, data);
173
222
  };
223
+ const onContextMenu = ($event) => {
224
+ emit('context-menu', $event);
225
+ };
174
226
  const expandIconClasses = (node) => {
175
227
  const expandIcon = props.expandIcon ? props.expandIcon : '';
176
228
  const collapseIcon = props.expandIcon ? props.collapseIcon : '';
@@ -205,11 +257,13 @@ export default {
205
257
  [column.align]: column.align,
206
258
  'non-border': !!props.borderStyle,
207
259
  });
208
- const getColumnStyle = column => ({
260
+ const getColumnStyle = (column, cellIndex) => ({
209
261
  width: `${column.width}px`,
210
262
  height: `${props.rowHeight}px`,
211
263
  'line-height': `${props.rowHeight}px`,
212
264
  'min-width': `${props.minWidth}px`,
265
+ 'border-right': props.orderedColumns.length - 1 === cellIndex
266
+ ? 'none' : '1px solid #CFCFCF',
213
267
  });
214
268
  const getDepthStyle = (nodeLevel) => {
215
269
  const depthSize = nodeLevel * 13;
@@ -228,6 +282,7 @@ export default {
228
282
  onExpand,
229
283
  onClick,
230
284
  onDblClick,
285
+ onContextMenu,
231
286
  expandIconClasses,
232
287
  getRowClass,
233
288
  getColumnClass,
@@ -279,7 +334,7 @@ export default {
279
334
  background: url('./tree_icon.png') no-repeat -14px -35px;
280
335
  }
281
336
  }
282
- .slot-wrapper {
337
+ .td-content {
283
338
  position: relative;
284
339
  flex: 1;
285
340
  }
@@ -28,6 +28,10 @@
28
28
  border-bottom: 1px solid evThemed('grid-bottom-border');
29
29
  }
30
30
  }
31
+ .row-contextmenu__btn {
32
+ display: none;
33
+ vertical-align: middle;
34
+ }
31
35
  }
32
36
 
33
37
  .column-list {
@@ -134,6 +138,15 @@
134
138
  background: #5AB7FF;
135
139
  color: #FFFFFF;
136
140
  }
141
+ &:hover {
142
+ .row-contextmenu__btn {
143
+ display: grid;
144
+ &:hover {
145
+ cursor: pointer;
146
+ opacity: 0.6;
147
+ }
148
+ }
149
+ }
137
150
  }
138
151
 
139
152
  .cell {
@@ -184,7 +197,7 @@
184
197
  }
185
198
  &.tree-td {
186
199
  text-align: left !important;
187
- .td-content {
200
+ .td-content__wrapper {
188
201
  display: flex;
189
202
  position: relative;
190
203
  align-items: center;
@@ -178,6 +178,7 @@ export const resizeEvent = (params) => {
178
178
  isRenderer,
179
179
  updateVScroll,
180
180
  updateHScroll,
181
+ contextInfo,
181
182
  } = params;
182
183
  /**
183
184
  * 고정 너비, 스크롤 유무 등에 따른 컬럼 너비를 계산한다.
@@ -207,7 +208,7 @@ export const resizeEvent = (params) => {
207
208
  }
208
209
 
209
210
  return acc;
210
- }, { totalWidth: 0, emptyCount: 0 });
211
+ }, { totalWidth: contextInfo.customContextMenu.length ? 30 : 0, emptyCount: 0 });
211
212
 
212
213
  if (resizeInfo.rowHeight * store.length > elHeight - resizeInfo.scrollWidth) {
213
214
  elWidth -= resizeInfo.scrollWidth;
@@ -373,7 +374,8 @@ export const clickEvent = (params) => {
373
374
  let timer = null;
374
375
  const onRowClick = (event, row) => {
375
376
  if (event.target && event.target.parentElement
376
- && event.target.parentElement.classList.contains('row-checkbox-input')) {
377
+ && (event.target.parentElement.classList.contains('row-checkbox-input')
378
+ || event.target.closest('td')?.classList?.contains('row-contextmenu'))) {
377
379
  return false;
378
380
  }
379
381
  clearTimeout(timer);