adminforth 2.26.0-test.5 → 2.26.0-test.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/commands/createApp/templates/package.json.hbs +1 -1
- package/dist/dataConnectors/qdrant.d.ts +2 -10
- package/dist/dataConnectors/qdrant.d.ts.map +1 -1
- package/dist/dataConnectors/qdrant.js +12 -38
- package/dist/dataConnectors/qdrant.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -31
- package/dist/index.js.map +1 -1
- package/dist/modules/restApi.d.ts +1 -0
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js +33 -16
- package/dist/modules/restApi.js.map +1 -1
- package/dist/modules/utils.d.ts +6 -0
- package/dist/modules/utils.d.ts.map +1 -1
- package/dist/modules/utils.js +13 -0
- package/dist/modules/utils.js.map +1 -1
- package/dist/servers/express.d.ts.map +1 -1
- package/dist/servers/express.js +7 -1
- package/dist/servers/express.js.map +1 -1
- package/dist/spa/package-lock.json +44 -7
- package/dist/spa/package.json +1 -1
- package/dist/spa/pnpm-lock.yaml +301 -299
- package/dist/spa/src/adminforth.ts +17 -29
- package/dist/spa/src/afcl/Input.vue +1 -1
- package/dist/spa/src/afcl/Modal.vue +12 -1
- package/dist/spa/src/afcl/Select.vue +4 -2
- package/dist/spa/src/afcl/Table.vue +27 -13
- package/dist/spa/src/components/AcceptModal.vue +2 -0
- package/dist/spa/src/components/ColumnValueInputWrapper.vue +11 -3
- package/dist/spa/src/components/CustomRangePicker.vue +16 -67
- package/dist/spa/src/components/ListActionsThreeDots.vue +10 -9
- package/dist/spa/src/components/RangePicker.vue +236 -0
- package/dist/spa/src/components/ResourceListTable.vue +283 -136
- package/dist/spa/src/components/Sidebar.vue +1 -1
- package/dist/spa/src/components/ThreeDotsMenu.vue +10 -9
- package/dist/spa/src/i18n.ts +1 -1
- package/dist/spa/src/stores/core.ts +4 -2
- package/dist/spa/src/types/Back.ts +7 -3
- package/dist/spa/src/types/Common.ts +25 -5
- package/dist/spa/src/types/FrontendAPI.ts +6 -1
- package/dist/spa/src/utils/listUtils.ts +8 -2
- package/dist/spa/src/utils/utils.ts +29 -10
- package/dist/spa/src/views/CreateView.vue +8 -8
- package/dist/spa/src/views/EditView.vue +8 -7
- package/dist/spa/src/views/ListView.vue +14 -48
- package/dist/spa/src/views/LoginView.vue +13 -13
- package/dist/spa/src/views/ShowView.vue +10 -10
- package/dist/spa/tsconfig.app.json +0 -1
- package/dist/types/Back.d.ts +4 -4
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +20 -5
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js.map +1 -1
- package/dist/types/FrontendAPI.d.ts +13 -1
- package/dist/types/FrontendAPI.d.ts.map +1 -1
- package/dist/types/FrontendAPI.js.map +1 -1
- package/package.json +2 -2
- package/dist/spa/src/components/ResourceListTableVirtual.vue +0 -789
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="range-slider" ref="trackRef" @mousedown="onTrackMouseDown">
|
|
3
|
+
<div class="track"></div>
|
|
4
|
+
<div class="range bg-lightPrimary/30" :style="rangeStyle"></div>
|
|
5
|
+
|
|
6
|
+
<div
|
|
7
|
+
class="bg-lightPrimary thumb"
|
|
8
|
+
:style="minThumbStyle"
|
|
9
|
+
@mousedown.stop.prevent="startDrag('min', $event)"
|
|
10
|
+
@mouseenter="minHovered = true"
|
|
11
|
+
@mouseleave="minHovered = false"
|
|
12
|
+
></div>
|
|
13
|
+
<div v-if="minHovered || activeThumb === 'min'" class="thumb-tooltip" :style="minTooltipStyle">{{ minVal }}</div>
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
class="bg-lightPrimary thumb"
|
|
17
|
+
:style="maxThumbStyle"
|
|
18
|
+
@mousedown.stop.prevent="startDrag('max', $event)"
|
|
19
|
+
@mouseenter="maxHovered = true"
|
|
20
|
+
@mouseleave="maxHovered = false"
|
|
21
|
+
></div>
|
|
22
|
+
<div v-if="maxHovered || activeThumb === 'max'" class="thumb-tooltip" :style="maxTooltipStyle">{{ maxVal }}</div>
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
import { computed, ref, watch, onBeforeUnmount } from 'vue'
|
|
29
|
+
|
|
30
|
+
const props = defineProps({
|
|
31
|
+
modelValue: {
|
|
32
|
+
type: Array as unknown as () => [number, number],
|
|
33
|
+
default: () => [0, 100]
|
|
34
|
+
},
|
|
35
|
+
min: { type: Number, default: 0 },
|
|
36
|
+
max: { type: Number, default: 100 },
|
|
37
|
+
dotSize: { type: Number, default: 20 },
|
|
38
|
+
height: { type: String, default: '8px' }
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const emit = defineEmits(['update:modelValue'])
|
|
42
|
+
|
|
43
|
+
const trackRef = ref<HTMLElement | null>(null)
|
|
44
|
+
|
|
45
|
+
const minVal = ref(props.modelValue[0])
|
|
46
|
+
const maxVal = ref(props.modelValue[1])
|
|
47
|
+
|
|
48
|
+
watch(() => props.modelValue, (val) => {
|
|
49
|
+
if (!val) return
|
|
50
|
+
minVal.value = val[0]
|
|
51
|
+
maxVal.value = val[1]
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
function clamp(val: number) {
|
|
55
|
+
return Math.min(props.max, Math.max(props.min, val))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function valueToPercent(val: number) {
|
|
59
|
+
return ((val - props.min) / (props.max - props.min)) * 100
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function percentToValue(percent: number) {
|
|
63
|
+
return props.min + ((props.max - props.min) * percent) / 100
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const minPercent = computed(() => valueToPercent(minVal.value))
|
|
67
|
+
const maxPercent = computed(() => valueToPercent(maxVal.value))
|
|
68
|
+
|
|
69
|
+
const rangeStyle = computed(() => ({
|
|
70
|
+
left: `${minPercent.value}%`,
|
|
71
|
+
width: `${maxPercent.value - minPercent.value}%`,
|
|
72
|
+
transition: isAnimating.value ? 'left 0.18s ease, width 0.18s ease' : 'none'
|
|
73
|
+
}))
|
|
74
|
+
|
|
75
|
+
const minThumbStyle = computed(() => ({
|
|
76
|
+
left: `calc(${minPercent.value}% - ${props.dotSize / 2}px)`,
|
|
77
|
+
width: `${props.dotSize}px`,
|
|
78
|
+
height: `${props.dotSize}px`,
|
|
79
|
+
transition: isAnimating.value ? 'left 0.18s ease' : 'none',
|
|
80
|
+
zIndex: activeThumb.value === 'min' ? 3 : 2
|
|
81
|
+
}))
|
|
82
|
+
|
|
83
|
+
const maxThumbStyle = computed(() => ({
|
|
84
|
+
left: `calc(${maxPercent.value}% - ${props.dotSize / 2}px)`,
|
|
85
|
+
width: `${props.dotSize}px`,
|
|
86
|
+
height: `${props.dotSize}px`,
|
|
87
|
+
transition: isAnimating.value ? 'left 0.18s ease' : 'none',
|
|
88
|
+
zIndex: activeThumb.value === 'max' ? 3 : 2
|
|
89
|
+
}))
|
|
90
|
+
|
|
91
|
+
const minTooltipStyle = computed(() => ({
|
|
92
|
+
left: `${minPercent.value}%`,
|
|
93
|
+
transition: isAnimating.value ? 'left 0.18s ease' : 'none'
|
|
94
|
+
}))
|
|
95
|
+
|
|
96
|
+
const maxTooltipStyle = computed(() => ({
|
|
97
|
+
left: `${maxPercent.value}%`,
|
|
98
|
+
transition: isAnimating.value ? 'left 0.18s ease' : 'none'
|
|
99
|
+
}))
|
|
100
|
+
|
|
101
|
+
const activeThumb = ref<'min' | 'max' | null>(null)
|
|
102
|
+
const isAnimating = ref(false)
|
|
103
|
+
const minHovered = ref(false)
|
|
104
|
+
const maxHovered = ref(false)
|
|
105
|
+
|
|
106
|
+
function startDrag(type: 'min' | 'max', e: MouseEvent) {
|
|
107
|
+
activeThumb.value = type
|
|
108
|
+
document.addEventListener('mousemove', onMouseMove)
|
|
109
|
+
document.addEventListener('mouseup', stopDrag)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function onMouseMove(e: MouseEvent) {
|
|
113
|
+
if (!trackRef.value || !activeThumb.value) return
|
|
114
|
+
|
|
115
|
+
const rect = trackRef.value.getBoundingClientRect()
|
|
116
|
+
const percent = ((e.clientX - rect.left) / rect.width) * 100
|
|
117
|
+
const value = Math.round(clamp(percentToValue(percent)))
|
|
118
|
+
|
|
119
|
+
if (activeThumb.value === 'min') {
|
|
120
|
+
if (value > maxVal.value) {
|
|
121
|
+
// cross over: become the max thumb
|
|
122
|
+
minVal.value = maxVal.value
|
|
123
|
+
maxVal.value = value
|
|
124
|
+
activeThumb.value = 'max'
|
|
125
|
+
} else {
|
|
126
|
+
minVal.value = value
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
if (value < minVal.value) {
|
|
130
|
+
// cross over: become the min thumb
|
|
131
|
+
maxVal.value = minVal.value
|
|
132
|
+
minVal.value = value
|
|
133
|
+
activeThumb.value = 'min'
|
|
134
|
+
} else {
|
|
135
|
+
maxVal.value = value
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
emit('update:modelValue', [minVal.value, maxVal.value])
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function stopDrag() {
|
|
143
|
+
document.removeEventListener('mousemove', onMouseMove)
|
|
144
|
+
document.removeEventListener('mouseup', stopDrag)
|
|
145
|
+
activeThumb.value = null
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function onTrackMouseDown(e: MouseEvent) {
|
|
149
|
+
if (!trackRef.value) return
|
|
150
|
+
|
|
151
|
+
const rect = trackRef.value.getBoundingClientRect()
|
|
152
|
+
const percent = ((e.clientX - rect.left) / rect.width) * 100
|
|
153
|
+
const value = percentToValue(percent)
|
|
154
|
+
|
|
155
|
+
const distToMin = Math.abs(value - minVal.value)
|
|
156
|
+
const distToMax = Math.abs(value - maxVal.value)
|
|
157
|
+
|
|
158
|
+
isAnimating.value = true
|
|
159
|
+
if (distToMin < distToMax) {
|
|
160
|
+
minVal.value = Math.round(Math.min(clamp(value), maxVal.value))
|
|
161
|
+
} else {
|
|
162
|
+
maxVal.value = Math.round(Math.max(clamp(value), minVal.value))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
emit('update:modelValue', [minVal.value, maxVal.value])
|
|
166
|
+
|
|
167
|
+
setTimeout(() => { isAnimating.value = false }, 200)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
onBeforeUnmount(() => {
|
|
171
|
+
stopDrag()
|
|
172
|
+
})
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
<style scoped>
|
|
176
|
+
.range-slider {
|
|
177
|
+
position: relative;
|
|
178
|
+
width: 100%;
|
|
179
|
+
height: 20px;
|
|
180
|
+
display: flex;
|
|
181
|
+
align-items: center;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.track {
|
|
185
|
+
position: absolute;
|
|
186
|
+
width: 100%;
|
|
187
|
+
height: 8px;
|
|
188
|
+
background: #e5e7eb;
|
|
189
|
+
border-radius: 9999px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.range {
|
|
193
|
+
position: absolute;
|
|
194
|
+
height: 8px;
|
|
195
|
+
border-radius: 9999px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.thumb {
|
|
199
|
+
position: absolute;
|
|
200
|
+
top: 50%;
|
|
201
|
+
transform: translateY(-50%);
|
|
202
|
+
border-radius: 9999px;
|
|
203
|
+
cursor: pointer;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.thumb-tooltip {
|
|
207
|
+
position: absolute;
|
|
208
|
+
top: -28px;
|
|
209
|
+
transform: translateX(-50%);
|
|
210
|
+
background: rgba(0, 0, 0, 0.75);
|
|
211
|
+
color: #fff;
|
|
212
|
+
font-size: 14px;
|
|
213
|
+
font-weight: 500;
|
|
214
|
+
line-height: 1;
|
|
215
|
+
padding: 6px 6px;
|
|
216
|
+
border-radius: 4px;
|
|
217
|
+
white-space: nowrap;
|
|
218
|
+
pointer-events: none;
|
|
219
|
+
animation: tooltip-in 0.12s ease;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.thumb-tooltip::after {
|
|
223
|
+
content: '';
|
|
224
|
+
position: absolute;
|
|
225
|
+
top: 100%;
|
|
226
|
+
left: 50%;
|
|
227
|
+
transform: translateX(-50%);
|
|
228
|
+
border: 4px solid transparent;
|
|
229
|
+
border-top-color: rgba(0, 0, 0, 0.75);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@keyframes tooltip-in {
|
|
233
|
+
from { opacity: 0; transform: translateX(-50%) translateY(4px); }
|
|
234
|
+
to { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
235
|
+
}
|
|
236
|
+
</style>
|