quasar-ui-sellmate-ui-kit 3.9.6 → 3.9.7

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": "quasar-ui-sellmate-ui-kit",
3
- "version": "3.9.6",
3
+ "version": "3.9.7",
4
4
  "author": "Sellmate Dev Team <dev@sellmate.co.kr>",
5
5
  "description": "Sellmate UI Kit",
6
6
  "license": "MIT",
@@ -31,10 +31,6 @@ export const searchIcon = 'M9.16634 3.33325C12.388 3.33325 14.9997 5.94492 14.99
31
31
  export const imageUploadFilledIcon = 'M0.5 15V3C0.5 1.61929 1.61929 0.5 3 0.5H15C16.3807 0.5 17.5 1.61929 17.5 3V15C17.5 16.3807 16.3807 17.5 15 17.5H3C1.61929 17.5 0.5 16.3807 0.5 15Z@@fill:#222222&&M11.125 5.28125C11.125 6.16145 11.8385 6.875 12.7188 6.875C13.599 6.875 14.3125 6.16145 14.3125 5.28125C14.3125 4.40105 13.599 3.6875 12.7188 3.6875C11.8385 3.6875 11.125 4.40105 11.125 5.28125Z@@fill:white&&M17.5 9.3993V11.4342L14.4626 14.2184C13.7719 14.8516 12.7052 14.8284 12.0426 14.1659L4.92678 7.05C4.82914 6.95237 4.67085 6.95237 4.57322 7.05L0.5 11.1232V9.0019L3.51256 5.98934C4.19598 5.30592 5.30402 5.30592 5.98744 5.98934L13.1033 13.1052C13.1979 13.1998 13.3503 13.2032 13.449 13.1127L17.5 9.3993Z@@fill:white|0 0 18 18';
32
32
  export const clockIcon = 'M12 7V12H17@@fill:none;stroke:currentColor;stroke-width:1.5;&&M12 21C16.9707 21 21 16.9707 21 12C21 7.0293 16.9707 3 12 3C7.0293 3 3 7.0293 3 12C3 16.9707 7.0293 21 12 21Z@@fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round|0 0 24 24';
33
33
 
34
- // TODO: icon 변경
35
- export const tableTreeArrowRight =
36
- 'M14.75 9.20096C15.75 9.77831 15.75 11.2217 14.75 11.799L8 15.6962C7 16.2735 5.75 15.5518 5.75 14.3971L5.75 6.60288C5.75 5.44818 7 4.7265 8 5.30385L14.75 9.20096Z@fill:currentColor|0 0 20 21';
37
- export const tableTreeArrowDown =
38
- 'M10.799 15.75C10.2217 16.75 8.77831 16.75 8.20096 15.75L4.30385 9C3.7265 8 4.44819 6.75 5.60289 6.75L13.3971 6.75C14.5518 6.75 15.2735 8 14.6962 9L10.799 15.75Z@fill:currentColor|0 0 20 21';
39
- export const path =
40
- 'M6 1.5V6V8.5C6 9.60457 6.89543 10.5 8 10.5H16@fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round|0 0 20 21';
34
+
35
+ export const addIcon10 = 'M1.16669 5H8.83335@@stroke:currentColor;stroke-width:0.8;stroke-linecap:round&&M5 1.16669L5 8.83335@@stroke:currentColor;stroke-width:0.8;stroke-linecap:round; | 0 0 10 10'
36
+ export const minusIcon10 = 'M1.16669 5H8.83335@@stroke:currentColor;stroke-width:0.8;stroke-linecap:round; | 0 0 10 10'
@@ -0,0 +1,468 @@
1
+ <template>
2
+ <div
3
+ class="s-table-tree"
4
+ :class="{
5
+ 'sticky-table-tree': isStickyFirstColumn,
6
+ 'loading-table-tree': loading,
7
+ 'no-data-table-tree': !rows.length,
8
+ }"
9
+ ref="sTableTreeRef"
10
+ >
11
+ <slot name="loading" v-if="loading">
12
+ <q-inner-loading showing color="positive" size="72px" />
13
+ </slot>
14
+
15
+ <div class="s-table-tree__inner" ref="scrollLocationRef" @scroll="handleScroll" >
16
+ <table>
17
+ <thead>
18
+ <tr>
19
+ <th
20
+ v-for="(column, idx) in columns"
21
+ :key="column.name"
22
+ :class="`td-${idx + 1} text-${column.align}`"
23
+ :style="`width: ${column.width}px`"
24
+ >
25
+ <slot :name="`header-cell-${column.name}`">
26
+ {{ column.label }}
27
+ </slot>
28
+ </th>
29
+ </tr>
30
+ </thead>
31
+
32
+ <tbody v-if="!rows.length">
33
+ <tr>
34
+ <td :colspan="columns.length">
35
+ <div>
36
+ <slot name="no-data">
37
+ {{ noDataLabel }}
38
+ </slot>
39
+ </div>
40
+ </td>
41
+ </tr>
42
+ </tbody>
43
+
44
+ <tbody v-else>
45
+ <slot name="body">
46
+ <tr v-if="rows.length > 0">
47
+ <td :colspan="columns.length" class="body-td">
48
+ <table-tree-node
49
+ v-for="(row, i) in treeDataSource"
50
+ :key="i"
51
+ :nodeName="`root_node_${i}`"
52
+ :row="row"
53
+ :columns="columns"
54
+ :colspan="columns.length"
55
+ :resizedWidths="resizedWidths"
56
+ ref="childTableNode"
57
+ @handlerExpand="handlerExpand"
58
+ >
59
+ <template
60
+ v-for="column in columns"
61
+ :key="column.name"
62
+ #[`body-cell-${column.name}`]="props"
63
+ >
64
+ <slot :name="`body-cell-${column.name}`" v-bind="props"></slot>
65
+ </template>
66
+ </table-tree-node>
67
+ </td>
68
+ </tr>
69
+ </slot>
70
+ </tbody>
71
+
72
+ <tfoot v-if="foots.length > 0 && rows.length > 0">
73
+ <slot name="tfoot">
74
+ <tr v-for="(f, i) in foots" :key="i" :class="`tr-${i + 1}`">
75
+ <td
76
+ v-for="(col, colIdx) in columns"
77
+ :key="col.name"
78
+ :class="`td-${colIdx + 1} text-${col.align}`"
79
+ >
80
+ <slot :name="`body-cell-${col.name}`">
81
+ <span v-if="col.prefix" class="q-mr-xs">{{ col.prefix }}</span>
82
+ {{ f[col.name] }}
83
+ <span v-if="col.suffix" class="q-ml-xs">{{ col.suffix }}</span>
84
+ </slot>
85
+ </td>
86
+ </tr>
87
+ </slot>
88
+ </tfoot>
89
+ </table>
90
+ </div>
91
+ </div>
92
+ </template>
93
+
94
+ <script>
95
+ import { defineComponent, ref, onMounted, nextTick } from 'vue';
96
+ import { QInnerLoading } from 'quasar';
97
+ import TableTreeNode from './TableTreeNode.vue';
98
+ import { useResizableTree } from '../composables/table/use-resizable-tree';
99
+
100
+ function setWidthForExpand(tableNodeRef, resizedWidths) {
101
+ const tableElements = tableNodeRef.querySelectorAll('table');
102
+
103
+ tableElements.forEach(tableElement => {
104
+ const rows = tableElement.querySelectorAll('tr');
105
+ rows.forEach(row => {
106
+ const cols = row.children;
107
+ for (let i = 0; i < cols.length; i++) {
108
+ if (resizedWidths[i] !== undefined) {
109
+ cols[i].style.minWidth = `${resizedWidths[i]}px`;
110
+ cols[i].style.width = `${resizedWidths[i]}px`;
111
+ }
112
+ }
113
+ });
114
+ });
115
+ }
116
+
117
+ export default defineComponent({
118
+ name: 'STableTree',
119
+ components: { TableTreeNode, QInnerLoading },
120
+ props: {
121
+ columns: {
122
+ type: Array,
123
+ default: () => [],
124
+ },
125
+ rows: {
126
+ type: Array,
127
+ default: () => [],
128
+ },
129
+ foots: {
130
+ type: Array,
131
+ default: () => [],
132
+ },
133
+ noDataLabel: {
134
+ type: String,
135
+ default: '데이터 조회가 필요합니다',
136
+ },
137
+ loading: {
138
+ type: Boolean,
139
+ default: false,
140
+ },
141
+ isStickyFirstColumn: {
142
+ tpye: Boolean,
143
+ default: true,
144
+ },
145
+ resizable: {
146
+ type: Boolean,
147
+ default: false,
148
+ },
149
+ stickyResizable: {
150
+ type: [Array, Number],
151
+ required: false,
152
+ },
153
+ },
154
+ setup(props) {
155
+ const treeDataSource = ref([]);
156
+ const sTableTreeRef = ref(null);
157
+ const resizedWidths = ref({});
158
+ const scrollLocationRef = ref(null)
159
+
160
+ function handleScroll() {
161
+ const { scrollLeft } = scrollLocationRef.value;
162
+
163
+ if (scrollLeft === 0) {
164
+ scrollLocationRef.value.classList.add('no-before');
165
+ } else {
166
+ scrollLocationRef.value.classList.remove('no-before');
167
+ }
168
+
169
+ }
170
+
171
+ function initTreeData() {
172
+ const tempData = JSON.parse(JSON.stringify(props.rows));
173
+ const reduceDataFunc = (data, level) => {
174
+ data.forEach(m => {
175
+ m.isExpand = m.isExpand || false;
176
+ m.children = m.children || [];
177
+ m.level = level;
178
+ m.leftPadding = level === 1 ? 20 : (level - 1) * 28 + 20;
179
+ if (m.children.length > 0) {
180
+ reduceDataFunc(m.children, level + 1);
181
+ }
182
+
183
+ nextTick(() => {
184
+ setWidthForExpand(sTableTreeRef.value, resizedWidths.value);
185
+ });
186
+ });
187
+ };
188
+ reduceDataFunc(tempData, 1);
189
+ treeDataSource.value = tempData;
190
+ }
191
+
192
+ function handlerExpand(row) {
193
+ row.isExpand = !row.isExpand;
194
+
195
+ nextTick(() => {
196
+ setWidthForExpand(sTableTreeRef.value, resizedWidths.value);
197
+ });
198
+ };
199
+
200
+ onMounted(() => {
201
+ const { addResizable } = useResizableTree();
202
+ if (props.resizable || props.isStickyFirstColumn) {
203
+ resizedWidths.value = addResizable(sTableTreeRef.value, props.columns);
204
+ }
205
+ scrollLocationRef.value.classList.add('no-before');
206
+ });
207
+
208
+ initTreeData();
209
+
210
+ return {
211
+ treeDataSource,
212
+ handlerExpand,
213
+ handleScroll,
214
+ sTableTreeRef,
215
+ scrollLocationRef,
216
+ resizedWidths,
217
+ };
218
+ },
219
+ });
220
+ </script>
221
+
222
+ <style scoped lang="scss">
223
+ @import '../css/quasar.variables.scss';
224
+ @import '../css/extends.scss';
225
+
226
+ .s-table-tree {
227
+ border: 1px solid $Grey_Lighten-2;
228
+ border-radius: 8px !important;
229
+ overflow: hidden;
230
+ position: relative;
231
+ box-sizing: border-box;
232
+ color: $Grey_Darken-5;
233
+ .q-inner-loading {
234
+ z-index: 1;
235
+ }
236
+ .s-table-tree__inner {
237
+ overflow: auto;
238
+ td, th {
239
+ width: 100%;
240
+ &:not(:first-of-type){
241
+ word-break: keep-all;
242
+ white-space: nowrap;
243
+ text-overflow: ellipsis;
244
+ overflow: hidden;
245
+ }
246
+ }
247
+ table {
248
+ width: 100%;
249
+ border-collapse: collapse;
250
+ border-spacing: 0;
251
+ table-layout: fixed;
252
+ thead {
253
+ background: $th-bg;
254
+ tr {
255
+ height: 36px;
256
+ th {
257
+ border-bottom: 1px solid $Grey-Lighten-3;
258
+ padding: 0 16px;
259
+ font-weight: 500;
260
+ color: rgba(34, 34, 34, 1);
261
+ }
262
+ }
263
+ }
264
+ tbody {
265
+ > tr {
266
+ td{
267
+ height: 44px;
268
+ }
269
+ > .body-td {
270
+ padding: 0;
271
+ }
272
+ }
273
+ }
274
+ tfoot {
275
+ border-top: 2px solid $Grey_Lighten-3 !important;
276
+ tr {
277
+ &:last-of-type{
278
+ background: rgba(245, 250, 255, 1);
279
+ .td-1{
280
+ color: $Blue_B_Lighten-2;
281
+ }
282
+ }
283
+ td {
284
+ border-top: 1px solid $Grey_Lighten-3 !important;
285
+ height: 52px;
286
+ padding: 0 16px;
287
+ &.td-1 {
288
+ padding: 0 20px;
289
+ font-weight: 700;
290
+ color: $Blue_C_Darken-1;
291
+ }
292
+ }
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ &.sticky-table-tree {
299
+ .s-table-tree__inner {
300
+ td, th {
301
+ width: 100%;
302
+ &:not(:first-of-type){
303
+ word-break: keep-all;
304
+ white-space: nowrap;
305
+ text-overflow: ellipsis;
306
+ overflow: hidden;
307
+ }
308
+ }
309
+ table {
310
+ border-collapse: collapse !important;
311
+ thead {
312
+ tr {
313
+ th {
314
+ &:first-of-type {
315
+ position: sticky;
316
+ left: 0;
317
+ background: $th-bg;
318
+ z-index: 10;
319
+ &:before {
320
+ content: '';
321
+ position: absolute;
322
+ width: 20px;
323
+ height: 100%;
324
+ right: -20px;
325
+ top: 0;
326
+ box-shadow: inset 17px 0 26px -29px rgba(0, 0, 0, 0.2);
327
+ background: none !important;
328
+ }
329
+ }
330
+ }
331
+ }
332
+ }
333
+ > tbody {
334
+ > tr {
335
+ > td {
336
+ :deep(.table-tree-node) {
337
+ table {
338
+ tr {
339
+ td {
340
+ &:first-of-type {
341
+ position: sticky;
342
+ left: 0;
343
+ &:before {
344
+ content: '';
345
+ position: absolute;
346
+ width: 20px;
347
+ height: 100%;
348
+ right: -20px;
349
+ top: 0;
350
+ box-shadow: inset 17px 0 26px -29px rgba(0, 0, 0, 0.3);
351
+ background: none !important;
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+ tfoot {
362
+ border-top: 2px solid $Grey_Lighten-3 !important;
363
+ tr {
364
+ td {
365
+ &:first-of-type {
366
+ position: sticky;
367
+ left: 0;
368
+ background: white;
369
+ &:before {
370
+ content: '';
371
+ position: absolute;
372
+ width: 20px;
373
+ height: 100%;
374
+ right: -20px;
375
+ top: 0;
376
+ box-shadow: inset 17px 0 26px -29px rgba(0, 0, 0, 0.3);
377
+ background: none !important;
378
+ }
379
+ }
380
+ }
381
+ &:last-of-type{
382
+ background: rgba(245, 250, 255, 1);
383
+ .td-1{
384
+ color: $Blue_B_Lighten-2;
385
+ background: rgba(245, 250, 255, 1);
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+ &.no-before {
392
+ table {
393
+ thead {
394
+ tr {
395
+ th {
396
+ &:first-of-type {
397
+ &::before {
398
+ display: none;
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
404
+ > tbody {
405
+ > tr {
406
+ > td {
407
+ :deep(.table-tree-node) {
408
+ table {
409
+ tr {
410
+ td {
411
+ &:first-of-type {
412
+ &::before{
413
+ display: none;
414
+ }
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+ tfoot {
424
+ tr {
425
+ td {
426
+ &:first-of-type {
427
+ &::before {
428
+ display: none;
429
+ }
430
+ }
431
+ }
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+
439
+ &.no-data-table-tree {
440
+ .s-table-tree__inner {
441
+ overflow: hidden;
442
+ table {
443
+ thead {
444
+ opacity: 0.4;
445
+ }
446
+ tbody {
447
+ tr {
448
+ td {
449
+ height: 240px;
450
+ padding: 0;
451
+ > div {
452
+ padding-top: 80px;
453
+ height: 240px;
454
+ text-align: center;
455
+ position: absolute;
456
+ width: 100%;
457
+ top: 36px;
458
+ left: 0;
459
+ color: $Grey_Default;
460
+ }
461
+ }
462
+ }
463
+ }
464
+ }
465
+ }
466
+ }
467
+ }
468
+ </style>
@@ -0,0 +1,182 @@
1
+ <template>
2
+ <div class="table-tree-node" :class="nodeName" ref="childTableNode">
3
+ <table>
4
+ <tbody>
5
+ <tr class="level" :class="levelClass">
6
+ <template v-for="(column, i) in columns" :key="i">
7
+ <td
8
+ :class="{
9
+ 'bg-white': i === 0 && hasChildren,
10
+ 'bg-Grey_Lighten-5': !hasChildren,
11
+ [`td-${i + 1} text-${column.align}`]: i >= 0,
12
+ }"
13
+ :style="[
14
+ i === 0 && `padding-left: ${row.leftPadding}px`,
15
+ `width: ${column.width}px`
16
+ ]"
17
+ >
18
+ <slot :name="`body-cell-${column.name}`">
19
+ <div>
20
+ <s-button
21
+ v-if="hasChildren && i === 0"
22
+ :icon="row.isExpand ? minusIcon10 : addIcon10"
23
+ outline
24
+ round
25
+ :color="row.isExpand ? 'Blue_C_Lighten-3' : 'Grey_Default'"
26
+ class="expand-btn q-mr-sm"
27
+ :class="{ 'not-expand-btn': !row.isExpand }"
28
+ @click="handlerExpand(row)"
29
+ />
30
+
31
+ <span
32
+ class="cell-content"
33
+ :class="{'is-root': isRoot}"
34
+ >
35
+ <span v-if="column.prefix" class="q-mr-xs">{{ column.prefix }}</span>
36
+ {{ row[column.name] }}
37
+ <span v-if="column.suffix" class="q-ml-xs">{{ column.suffix }}</span>
38
+ </span>
39
+ </div>
40
+ </slot>
41
+ </td>
42
+ </template>
43
+ </tr>
44
+ </tbody>
45
+ </table>
46
+
47
+ <div v-if="row.isExpand">
48
+ <table-tree-node
49
+ v-for="(childRow, childRowIdx) in row.children"
50
+ :key="`child_node${childRowIdx}`"
51
+ :nodeName="`child_node${childRowIdx}`"
52
+ :row="childRow"
53
+ :columns="columns"
54
+ :colspan="colspan"
55
+ :resizedWidths="resizedWidths"
56
+ @handlerExpand="handlerExpand"
57
+ :is-root="false"
58
+ >
59
+ <template
60
+ v-for="column in columns"
61
+ :key="column.name"
62
+ #[`body-cell-${column.name}`]="props"
63
+ >
64
+ <slot :name="`body-cell-${column.name}`" v-bind="props"></slot>
65
+ </template>
66
+ </table-tree-node>
67
+ </div>
68
+ </div>
69
+ </template>
70
+
71
+ <script>
72
+ import { defineComponent, computed, ref } from 'vue';
73
+ import { addIcon10, minusIcon10 } from '../assets/icons';
74
+
75
+ export default defineComponent({
76
+ name: 'TableTreeNode',
77
+ props: {
78
+ row: Object,
79
+ nodeName: String,
80
+ columns: {
81
+ type: Array,
82
+ default: () => [],
83
+ },
84
+ isRoot:{
85
+ type: Boolean,
86
+ default: true
87
+ },
88
+ colspan: Number,
89
+ resizedWidths: Object,
90
+ },
91
+ setup(props, { emit }) {
92
+ const levelClass = computed(() => `level-${props.row.level}` || '');
93
+ const hasChildren = computed(() => props.row.children && props.row.children.length > 0);
94
+ const childTableNode = ref(null);
95
+
96
+ function handlerExpand(row) {;
97
+ emit('handlerExpand', row);
98
+ }
99
+
100
+ return {
101
+ levelClass,
102
+ hasChildren,
103
+ handlerExpand,
104
+ childTableNode,
105
+ addIcon10,
106
+ minusIcon10
107
+ };
108
+ },
109
+ });
110
+ </script>
111
+
112
+ <style scoped lang="scss">
113
+ @import '../css/quasar.variables.scss';
114
+ @import '../css/extends.scss';
115
+
116
+ .table-tree-node {
117
+ border-top: 1px solid $Grey_Lighten-3 !important;
118
+ box-sizing: border-box;
119
+
120
+ &.root_node_0 {
121
+ border-top: 0 !important;
122
+ }
123
+ .tr {
124
+ vertical-align: middle;
125
+ td {
126
+ height: 48px;
127
+ padding: 0 16px;
128
+ }
129
+ }
130
+ td,th{
131
+ width: 100%;
132
+ &:not(:first-of-type){
133
+ word-break: keep-all;
134
+ white-space: nowrap;
135
+ overflow: hidden;
136
+ text-overflow: ellipsis;
137
+ }
138
+ }
139
+ table {
140
+ width: 100%;
141
+ table-layout: fixed;
142
+ border-collapse: collapse;
143
+ tbody {
144
+ tr {
145
+ td {
146
+ height: 44px;
147
+ padding: 0 16px;
148
+ font-weight: 400;
149
+
150
+ .expand-btn {
151
+ min-width: 20px;
152
+ min-height: 20px;
153
+ padding: 0 !important;
154
+ &.not-expand-btn {
155
+ &:before {
156
+ border-color: $Grey_Lighten-3;
157
+ }
158
+ }
159
+ &.s-button-sm.q-btn {
160
+ height: 20px;
161
+ }
162
+ :deep(.q-btn__content) {
163
+ .q-icon {
164
+ font-size: 12px;
165
+ }
166
+ }
167
+ }
168
+ .cell-content {
169
+ display: inline-block;
170
+ }
171
+ }
172
+ }
173
+ }
174
+ .td-1 .is-root {
175
+ font-weight: 700;
176
+ }
177
+ .td-1 :not(.is-root) {
178
+ font-weight: 400;
179
+ }
180
+ }
181
+ }
182
+ </style>