polarvo-layout 1.0.63 → 1.0.65
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
|
@@ -43,8 +43,9 @@
|
|
|
43
43
|
:rootId="item.id"
|
|
44
44
|
:ref="setRef"
|
|
45
45
|
v-bind="item"
|
|
46
|
+
:isHovable="isHovable"
|
|
46
47
|
class="hover:opacity-80"
|
|
47
|
-
:class="activeEditMode ? `pointer-events-auto ` : `pointer-events-none`"
|
|
48
|
+
:class="activeEditMode || isHovable ? `pointer-events-auto ` : `pointer-events-none`"
|
|
48
49
|
@set:defaultStyle="setDefaultStyle"
|
|
49
50
|
/>
|
|
50
51
|
</div>
|
|
@@ -59,6 +60,7 @@ const props = defineProps({
|
|
|
59
60
|
item: { type: Object, required: true },
|
|
60
61
|
polarvo: { type: Object, required: true },
|
|
61
62
|
sectionKey: { type: String, required: true },
|
|
63
|
+
isHovable: { type: Boolean, required: true },
|
|
62
64
|
});
|
|
63
65
|
|
|
64
66
|
const { activeId, handles, activeElement } = toRefs(props.polarvo.freeDrop.state);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:item="item"
|
|
7
7
|
:polarvo="props.polarvo"
|
|
8
8
|
:sectionKey="props.sectionKey"
|
|
9
|
+
:isHovable="isHovable(item)"
|
|
9
10
|
></FreeItem>
|
|
10
11
|
|
|
11
12
|
<!-- 오버레이 -->
|
|
@@ -68,6 +69,11 @@ const filteredElements = computed(() => {
|
|
|
68
69
|
const selectedElement = inject('selectedElement');
|
|
69
70
|
const activeEditMode = inject('activeEditMode');
|
|
70
71
|
|
|
72
|
+
const isHovable = (item) => {
|
|
73
|
+
if (!item || props.preview) return true;
|
|
74
|
+
return activeElement.value?.id === item.id && ['chart'].includes(item.type);
|
|
75
|
+
};
|
|
76
|
+
|
|
71
77
|
let _isElementSwitching = false;
|
|
72
78
|
import { omit, cloneDeep } from 'lodash-es';
|
|
73
79
|
|
|
@@ -79,7 +85,7 @@ watch(
|
|
|
79
85
|
if (newId && activeElement.value?.section !== props.sectionKey) return;
|
|
80
86
|
|
|
81
87
|
if (!newId) {
|
|
82
|
-
console.l
|
|
88
|
+
console.l;
|
|
83
89
|
setActiveDesign(null);
|
|
84
90
|
setActiveMenu(null);
|
|
85
91
|
}
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
:rootId="item.id"
|
|
42
42
|
:ref="setRef"
|
|
43
43
|
v-bind="item"
|
|
44
|
+
:isHovable="isHovable"
|
|
44
45
|
class="hover:opacity-80"
|
|
45
|
-
:class="activeEditMode ? `pointer-events-auto ` : `pointer-events-none`"
|
|
46
|
-
|
|
46
|
+
:class="activeEditMode || isHovable ? `pointer-events-auto ` : `pointer-events-none`"
|
|
47
|
+
@set:defaultStyle="setDefaultStyle"
|
|
47
48
|
/>
|
|
48
|
-
|
|
49
49
|
<!-- 오버레이 -->
|
|
50
50
|
<div v-if="activeEditMode && item.id !== activeId" class="absolute inset-0 bg-black opacity-50 z-30"></div>
|
|
51
51
|
</template>
|
|
@@ -69,6 +69,7 @@ const props = defineProps({
|
|
|
69
69
|
item: { type: Object, required: true },
|
|
70
70
|
polarvo: { type: Object, required: true },
|
|
71
71
|
sectionKey: { type: String, required: true },
|
|
72
|
+
isHovable: { type: Boolean, required: true },
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
const { activeId } = toRefs(props.polarvo.gridDrop.state);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:item="item"
|
|
7
7
|
:polarvo="props.polarvo"
|
|
8
8
|
:sectionKey="props.sectionKey"
|
|
9
|
+
:isHovable="isHovable(item)"
|
|
9
10
|
></GridItem>
|
|
10
11
|
|
|
11
12
|
<!-- 행 크기 조절 -->
|
|
@@ -107,6 +108,11 @@ const { activeDesign } = toRefs(props.polarvo.display.state);
|
|
|
107
108
|
const selectedElement = inject('selectedElement');
|
|
108
109
|
const activeEditMode = inject('activeEditMode');
|
|
109
110
|
|
|
111
|
+
const isHovable = (item) => {
|
|
112
|
+
if (!item || props.preview) return true;
|
|
113
|
+
return activeElement.value?.id === item.id && ['chart'].includes(item.type);
|
|
114
|
+
};
|
|
115
|
+
|
|
110
116
|
import { omit, cloneDeep, debounce } from 'lodash-es';
|
|
111
117
|
|
|
112
118
|
const gridColumns = ref(3); // 동적으로 계산
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="gap-4 space-y-4">
|
|
3
3
|
<div
|
|
4
|
-
v-for="(item, index) in
|
|
4
|
+
v-for="(item, index) in currentElements"
|
|
5
5
|
:key="index"
|
|
6
6
|
class="flex flex-col items-center justify-center border border-gray-200 rounded-lg p-2 hover:bg-gray-50 transition-colors cursor-pointer active:scale-95"
|
|
7
7
|
@mousedown.stop="sectionMode == 'free' ? addElementToFree($event, item) : addElementToGrid(item)"
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
</div>
|
|
13
13
|
</template>
|
|
14
14
|
|
|
15
|
+
<script>
|
|
16
|
+
let cachedDefaultElements = null;
|
|
17
|
+
let cachedCustomElements = null;
|
|
18
|
+
</script>
|
|
19
|
+
|
|
15
20
|
<script setup>
|
|
16
21
|
import { ref, onBeforeMount, toRefs, computed } from 'vue';
|
|
17
22
|
|
|
@@ -25,14 +30,32 @@ const props = defineProps({
|
|
|
25
30
|
required: false,
|
|
26
31
|
default: '',
|
|
27
32
|
},
|
|
33
|
+
elType: {
|
|
34
|
+
type: String,
|
|
35
|
+
required: false,
|
|
36
|
+
default: 'default',
|
|
37
|
+
},
|
|
38
|
+
customElements: {
|
|
39
|
+
type: Array,
|
|
40
|
+
required: false,
|
|
41
|
+
default: () => [],
|
|
42
|
+
},
|
|
28
43
|
});
|
|
44
|
+
|
|
29
45
|
const { addElement: addElementToFree } = props.polarvo.freeDrop;
|
|
30
46
|
const { addElement: addElementToGrid } = props.polarvo.gridDrop;
|
|
31
47
|
|
|
32
48
|
const { activeMode } = toRefs(props.polarvo.layout.state);
|
|
33
49
|
const sectionMode = computed(() => activeMode.value);
|
|
34
50
|
|
|
35
|
-
const allElements = ref(
|
|
51
|
+
const allElements = ref({
|
|
52
|
+
default: [],
|
|
53
|
+
custom: props.customElements || [],
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const currentElements = computed(() => {
|
|
57
|
+
return allElements.value[props.elType] || [];
|
|
58
|
+
});
|
|
36
59
|
|
|
37
60
|
/** 프로젝트 폴더에서 요소 컴포넌트 주소를 맞춰줘야 정상 작동합니다.
|
|
38
61
|
* (현재 /src/components/elements/ 내부에 모든 요소 컴포넌트가 있어야 함) */
|
|
@@ -42,56 +65,77 @@ const imageModules = import.meta.glob('@/assets/el_img/*.{png,gif}', { eager: tr
|
|
|
42
65
|
function getPropsDefaults(props) {
|
|
43
66
|
if (!props) return {};
|
|
44
67
|
|
|
45
|
-
return Object.fromEntries(
|
|
46
|
-
|
|
68
|
+
return Object.fromEntries(
|
|
69
|
+
Object.entries(props)
|
|
70
|
+
.map(([key, prop]) => {
|
|
71
|
+
if (['size', 'preview'].includes(key)) return null;
|
|
47
72
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
73
|
+
if (prop.default !== undefined) {
|
|
74
|
+
return [key, typeof prop.default === 'function' ? prop.default() : prop.default];
|
|
75
|
+
}
|
|
76
|
+
return null; // 기본값이 없는 경우 null 반환
|
|
77
|
+
})
|
|
78
|
+
.filter((entry) => entry !== null),
|
|
79
|
+
);
|
|
53
80
|
}
|
|
54
81
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
})
|
|
75
|
-
.map((path) => {
|
|
76
|
-
const elName = path.split('/').pop().replace('.vue', '');
|
|
77
|
-
const propDefaults = getPropsDefaults(modules[path].default?.props);
|
|
78
|
-
|
|
79
|
-
// 확장자 조건 설정
|
|
82
|
+
// 기본 요소 목록에서 제외할 컴포넌트
|
|
83
|
+
const EXCLUDED_ELEMENTS = [
|
|
84
|
+
'button',
|
|
85
|
+
'labelInput',
|
|
86
|
+
'labelSelect',
|
|
87
|
+
'dataList',
|
|
88
|
+
'multiCheckRadio',
|
|
89
|
+
'labelInputRows',
|
|
90
|
+
'refLabel',
|
|
91
|
+
'labelTextarea',
|
|
92
|
+
'loginForm',
|
|
93
|
+
'searchAddress',
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
function buildDefaultElements() {
|
|
97
|
+
if (cachedDefaultElements) return cachedDefaultElements;
|
|
98
|
+
|
|
99
|
+
cachedDefaultElements = Object.keys(modules)
|
|
100
|
+
.map((path) => ({ path, elName: path.split('/').pop().replace('.vue', '') }))
|
|
101
|
+
.filter(({ elName }) => !EXCLUDED_ELEMENTS.includes(elName))
|
|
102
|
+
.map(({ path, elName }) => {
|
|
80
103
|
const ext = elName === 'dataList' ? 'gif' : 'png';
|
|
81
104
|
const imgKey = `/src/assets/el_img/${elName}.${ext}`;
|
|
82
105
|
|
|
83
|
-
|
|
106
|
+
return {
|
|
107
|
+
elType: 'default',
|
|
84
108
|
elName,
|
|
85
|
-
propDefaults:
|
|
86
|
-
// imgurl: new URL(`../../assets/el_img/${elName}.${ext}`, props.urlBase),
|
|
109
|
+
propDefaults: getPropsDefaults(modules[path].default?.props),
|
|
87
110
|
imgurl: imageModules[imgKey]?.default ?? '',
|
|
88
|
-
// component: markRaw(defineAsyncComponent(modules[path]))
|
|
89
111
|
};
|
|
90
|
-
|
|
91
|
-
return result;
|
|
92
112
|
});
|
|
93
113
|
|
|
94
|
-
|
|
114
|
+
return cachedDefaultElements;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function buildCustomElements() {
|
|
118
|
+
if (cachedCustomElements) return cachedCustomElements;
|
|
119
|
+
|
|
120
|
+
const imgurl = imageModules['/src/assets/el_img/customDefault.png']?.default ?? '';
|
|
121
|
+
|
|
122
|
+
cachedCustomElements = props.customElements.map((el) => {
|
|
123
|
+
const { elName, mode, position, size, section, isLocked, ...propDefaults } = el;
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
elType: 'custom',
|
|
127
|
+
elName,
|
|
128
|
+
propDefaults,
|
|
129
|
+
imgurl,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return cachedCustomElements;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function getElements() {
|
|
137
|
+
allElements.value.default = buildDefaultElements();
|
|
138
|
+
allElements.value.custom = buildCustomElements();
|
|
95
139
|
}
|
|
96
140
|
|
|
97
141
|
onBeforeMount(() => {
|