@keqi.gress/plugin-ui 1.0.0 → 1.3.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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ref, computed, onMounted, onUnmounted, defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString, createCommentVNode, renderSlot } from "vue";
1
+ import { ref, computed, onMounted, onUnmounted, defineComponent, openBlock, createElementBlock, renderSlot, createElementVNode, toDisplayString, createCommentVNode, normalizeClass, Fragment, renderList, watch, nextTick, createTextVNode, withDirectives, createStaticVNode, vModelSelect, withKeys, createVNode, Transition, withCtx, normalizeStyle, useSlots, createBlock, withModifiers } from "vue";
2
2
  function useLoadingState(options = {}) {
3
3
  const { initialLoading = false, onError } = options;
4
4
  const loading = ref(initialLoading);
@@ -172,6 +172,946 @@ function useResponsive() {
172
172
  breakpoints
173
173
  };
174
174
  }
175
+ const _hoisted_1$9 = { class: "page-container" };
176
+ const _sfc_main$a = /* @__PURE__ */ defineComponent({
177
+ __name: "PageContainer",
178
+ setup(__props) {
179
+ return (_ctx, _cache) => {
180
+ return openBlock(), createElementBlock("div", _hoisted_1$9, [
181
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
182
+ ]);
183
+ };
184
+ }
185
+ });
186
+ const _export_sfc = (sfc, props) => {
187
+ const target = sfc.__vccOpts || sfc;
188
+ for (const [key, val] of props) {
189
+ target[key] = val;
190
+ }
191
+ return target;
192
+ };
193
+ const PageContainer = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-65bd80d8"]]);
194
+ const _hoisted_1$8 = { class: "page-content" };
195
+ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
196
+ __name: "PageContent",
197
+ setup(__props) {
198
+ return (_ctx, _cache) => {
199
+ return openBlock(), createElementBlock("div", _hoisted_1$8, [
200
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
201
+ ]);
202
+ };
203
+ }
204
+ });
205
+ const PageContent = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-7bbf9d25"]]);
206
+ const _hoisted_1$7 = { class: "page-header" };
207
+ const _hoisted_2$7 = { class: "page-header__content" };
208
+ const _hoisted_3$6 = {
209
+ key: 0,
210
+ class: "page-header__prefix"
211
+ };
212
+ const _hoisted_4$6 = {
213
+ key: 1,
214
+ class: "page-header__left"
215
+ };
216
+ const _hoisted_5$6 = { class: "page-header__breadcrumb" };
217
+ const _hoisted_6$4 = {
218
+ key: 0,
219
+ class: "breadcrumb-item"
220
+ };
221
+ const _hoisted_7$4 = {
222
+ key: 1,
223
+ class: "breadcrumb-separator"
224
+ };
225
+ const _hoisted_8$3 = { class: "breadcrumb-item breadcrumb-item--current" };
226
+ const _hoisted_9$2 = {
227
+ key: 2,
228
+ class: "page-header__actions"
229
+ };
230
+ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
231
+ __name: "PageHeader",
232
+ props: {
233
+ title: {},
234
+ breadcrumb: {}
235
+ },
236
+ setup(__props) {
237
+ return (_ctx, _cache) => {
238
+ return openBlock(), createElementBlock("div", _hoisted_1$7, [
239
+ createElementVNode("div", _hoisted_2$7, [
240
+ _ctx.$slots.prefix ? (openBlock(), createElementBlock("div", _hoisted_3$6, [
241
+ renderSlot(_ctx.$slots, "prefix", {}, void 0, true)
242
+ ])) : (openBlock(), createElementBlock("div", _hoisted_4$6, [
243
+ createElementVNode("div", _hoisted_5$6, [
244
+ __props.breadcrumb ? (openBlock(), createElementBlock("div", _hoisted_6$4, [
245
+ createElementVNode("span", null, toDisplayString(__props.breadcrumb), 1)
246
+ ])) : createCommentVNode("", true),
247
+ __props.breadcrumb ? (openBlock(), createElementBlock("span", _hoisted_7$4, "/")) : createCommentVNode("", true),
248
+ createElementVNode("div", _hoisted_8$3, [
249
+ createElementVNode("span", null, toDisplayString(__props.title), 1)
250
+ ])
251
+ ])
252
+ ])),
253
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_9$2, [
254
+ renderSlot(_ctx.$slots, "actions", {}, void 0, true)
255
+ ])) : createCommentVNode("", true)
256
+ ])
257
+ ]);
258
+ };
259
+ }
260
+ });
261
+ const PageHeader = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-4d82a654"]]);
262
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
263
+ __name: "CardList",
264
+ props: {
265
+ size: { default: "medium" },
266
+ minWidth: { default: "380px" }
267
+ },
268
+ setup(__props) {
269
+ return (_ctx, _cache) => {
270
+ return openBlock(), createElementBlock("div", {
271
+ class: normalizeClass(["card-list", { [`card-list--${__props.size}`]: __props.size }])
272
+ }, [
273
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
274
+ ], 2);
275
+ };
276
+ }
277
+ });
278
+ const CardList = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-f199a048"]]);
279
+ const _hoisted_1$6 = {
280
+ key: 0,
281
+ class: "page-pagination"
282
+ };
283
+ const _hoisted_2$6 = { class: "pagination-controls" };
284
+ const _hoisted_3$5 = ["disabled"];
285
+ const _hoisted_4$5 = { class: "pagination-info" };
286
+ const _hoisted_5$5 = ["disabled"];
287
+ const _hoisted_6$3 = ["value"];
288
+ const _hoisted_7$3 = ["value"];
289
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
290
+ __name: "PagePagination",
291
+ props: {
292
+ page: {},
293
+ pageSize: {},
294
+ total: {},
295
+ pageSizes: { default: () => [10, 20, 50, 100] },
296
+ showSizePicker: { type: Boolean, default: true }
297
+ },
298
+ emits: ["update:page", "update:pageSize"],
299
+ setup(__props, { emit: __emit }) {
300
+ const props = __props;
301
+ const emit = __emit;
302
+ const pageCount = computed(() => Math.ceil(props.total / props.pageSize));
303
+ function handlePageChange(page) {
304
+ if (page >= 1 && page <= pageCount.value) {
305
+ emit("update:page", page);
306
+ }
307
+ }
308
+ function handlePageSizeChange(pageSize) {
309
+ emit("update:pageSize", pageSize);
310
+ if (props.page > 1) {
311
+ emit("update:page", 1);
312
+ }
313
+ }
314
+ return (_ctx, _cache) => {
315
+ return __props.total > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
316
+ renderSlot(_ctx.$slots, "default", {
317
+ page: __props.page,
318
+ pageSize: __props.pageSize,
319
+ pageCount: pageCount.value,
320
+ total: __props.total,
321
+ onPageChange: handlePageChange,
322
+ onPageSizeChange: handlePageSizeChange
323
+ }, () => [
324
+ createElementVNode("div", _hoisted_2$6, [
325
+ createElementVNode("button", {
326
+ class: "pagination-btn",
327
+ disabled: __props.page === 1,
328
+ onClick: _cache[0] || (_cache[0] = ($event) => handlePageChange(__props.page - 1))
329
+ }, " 上一页 ", 8, _hoisted_3$5),
330
+ createElementVNode("span", _hoisted_4$5, " 第 " + toDisplayString(__props.page) + " / " + toDisplayString(pageCount.value) + " 页,共 " + toDisplayString(__props.total) + " 条 ", 1),
331
+ createElementVNode("button", {
332
+ class: "pagination-btn",
333
+ disabled: __props.page === pageCount.value,
334
+ onClick: _cache[1] || (_cache[1] = ($event) => handlePageChange(__props.page + 1))
335
+ }, " 下一页 ", 8, _hoisted_5$5),
336
+ __props.showSizePicker ? (openBlock(), createElementBlock("select", {
337
+ key: 0,
338
+ class: "pagination-select",
339
+ value: __props.pageSize,
340
+ onChange: _cache[2] || (_cache[2] = ($event) => handlePageSizeChange(Number($event.target.value)))
341
+ }, [
342
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.pageSizes, (size) => {
343
+ return openBlock(), createElementBlock("option", {
344
+ key: size,
345
+ value: size
346
+ }, toDisplayString(size) + " 条/页 ", 9, _hoisted_7$3);
347
+ }), 128))
348
+ ], 40, _hoisted_6$3)) : createCommentVNode("", true)
349
+ ])
350
+ ], true)
351
+ ])) : createCommentVNode("", true);
352
+ };
353
+ }
354
+ });
355
+ const PagePagination = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-bf918fa3"]]);
356
+ const _hoisted_1$5 = { class: "log-toolbar" };
357
+ const _hoisted_2$5 = { class: "toolbar-group" };
358
+ const _hoisted_3$4 = { class: "btn-icon" };
359
+ const _hoisted_4$4 = {
360
+ key: 0,
361
+ class: "log-loading"
362
+ };
363
+ const _hoisted_5$4 = {
364
+ key: 1,
365
+ class: "log-list"
366
+ };
367
+ const _hoisted_6$2 = { class: "log-timestamp" };
368
+ const _hoisted_7$2 = {
369
+ key: 0,
370
+ class: "log-thread"
371
+ };
372
+ const _hoisted_8$2 = { class: "log-level" };
373
+ const _hoisted_9$1 = {
374
+ key: 1,
375
+ class: "log-class"
376
+ };
377
+ const _hoisted_10$1 = { class: "log-message" };
378
+ const _hoisted_11 = {
379
+ key: 2,
380
+ class: "log-error-detail"
381
+ };
382
+ const _hoisted_12 = { class: "log-error-message" };
383
+ const _hoisted_13 = {
384
+ key: 2,
385
+ class: "log-empty"
386
+ };
387
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
388
+ __name: "LogViewer",
389
+ props: {
390
+ logs: { default: () => [] },
391
+ loading: { type: Boolean, default: false },
392
+ autoScroll: { type: Boolean, default: true },
393
+ defaultTheme: { default: "light" }
394
+ },
395
+ emits: ["refresh", "clear"],
396
+ setup(__props, { emit: __emit }) {
397
+ const props = __props;
398
+ const emit = __emit;
399
+ const scrollbarRef = ref();
400
+ const filterLevel = ref("");
401
+ const theme = ref(props.defaultTheme);
402
+ const filteredLogs = computed(() => {
403
+ if (!filterLevel.value || filterLevel.value === "") {
404
+ return props.logs;
405
+ }
406
+ return props.logs.filter((log) => {
407
+ const logLevel = getLogLevel(log);
408
+ return logLevel === filterLevel.value;
409
+ });
410
+ });
411
+ watch(
412
+ () => props.logs.length,
413
+ () => {
414
+ if (props.autoScroll) {
415
+ nextTick(() => {
416
+ if (scrollbarRef.value) {
417
+ scrollbarRef.value.scrollTop = scrollbarRef.value.scrollHeight;
418
+ }
419
+ });
420
+ }
421
+ }
422
+ );
423
+ function handleRefresh() {
424
+ emit("refresh");
425
+ }
426
+ function handleClear() {
427
+ emit("clear");
428
+ }
429
+ function toggleTheme() {
430
+ theme.value = theme.value === "dark" ? "light" : "dark";
431
+ }
432
+ function getLogLevel(log) {
433
+ var _a;
434
+ if (log.level) return log.level.toUpperCase();
435
+ if ((_a = log.body) == null ? void 0 : _a.level) return String(log.body.level).toUpperCase();
436
+ const content = log.message || log.logContent || "";
437
+ const levelMatch = content.match(/\b(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)\b/);
438
+ if (levelMatch) return levelMatch[1];
439
+ return "INFO";
440
+ }
441
+ function getThreadName(log) {
442
+ var _a;
443
+ if ((_a = log.body) == null ? void 0 : _a.threadName) return String(log.body.threadName);
444
+ if (log.threadName) return log.threadName;
445
+ return "";
446
+ }
447
+ function getLoggerName(log) {
448
+ var _a, _b;
449
+ if (log.logger) return log.logger;
450
+ if ((_a = log.body) == null ? void 0 : _a.logger) return String(log.body.logger);
451
+ if (log.className) return log.className;
452
+ if ((_b = log.body) == null ? void 0 : _b.className) return String(log.body.className);
453
+ return "";
454
+ }
455
+ function formatTimestamp(time) {
456
+ if (!time) return "--";
457
+ try {
458
+ const date = new Date(time);
459
+ const year = date.getFullYear();
460
+ const month = String(date.getMonth() + 1).padStart(2, "0");
461
+ const day = String(date.getDate()).padStart(2, "0");
462
+ const hours = String(date.getHours()).padStart(2, "0");
463
+ const minutes = String(date.getMinutes()).padStart(2, "0");
464
+ const seconds = String(date.getSeconds()).padStart(2, "0");
465
+ const ms = String(date.getMilliseconds()).padStart(3, "0");
466
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;
467
+ } catch (error) {
468
+ return time;
469
+ }
470
+ }
471
+ return (_ctx, _cache) => {
472
+ return openBlock(), createElementBlock("div", {
473
+ class: normalizeClass(["log-viewer", { "log-viewer--dark": theme.value === "dark" }])
474
+ }, [
475
+ createElementVNode("div", _hoisted_1$5, [
476
+ createElementVNode("div", _hoisted_2$5, [
477
+ createElementVNode("button", {
478
+ class: "toolbar-btn",
479
+ onClick: handleRefresh
480
+ }, [..._cache[1] || (_cache[1] = [
481
+ createElementVNode("span", { class: "btn-icon" }, "↻", -1),
482
+ createTextVNode(" 刷新 ", -1)
483
+ ])]),
484
+ createElementVNode("button", {
485
+ class: "toolbar-btn",
486
+ onClick: handleClear
487
+ }, [..._cache[2] || (_cache[2] = [
488
+ createElementVNode("span", { class: "btn-icon" }, "🗑", -1),
489
+ createTextVNode(" 清空 ", -1)
490
+ ])]),
491
+ withDirectives(createElementVNode("select", {
492
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => filterLevel.value = $event),
493
+ class: "toolbar-select"
494
+ }, [..._cache[3] || (_cache[3] = [
495
+ createStaticVNode('<option value="" data-v-c4c4657a>全部级别</option><option value="TRACE" data-v-c4c4657a>TRACE</option><option value="DEBUG" data-v-c4c4657a>DEBUG</option><option value="INFO" data-v-c4c4657a>INFO</option><option value="WARN" data-v-c4c4657a>WARN</option><option value="ERROR" data-v-c4c4657a>ERROR</option><option value="FATAL" data-v-c4c4657a>FATAL</option>', 7)
496
+ ])], 512), [
497
+ [vModelSelect, filterLevel.value]
498
+ ]),
499
+ createElementVNode("button", {
500
+ class: "toolbar-btn",
501
+ onClick: toggleTheme
502
+ }, [
503
+ createElementVNode("span", _hoisted_3$4, toDisplayString(theme.value === "dark" ? "☀" : "🌙"), 1),
504
+ createTextVNode(" " + toDisplayString(theme.value === "dark" ? "浅色" : "深色"), 1)
505
+ ])
506
+ ])
507
+ ]),
508
+ createElementVNode("div", {
509
+ class: "log-content",
510
+ ref_key: "scrollbarRef",
511
+ ref: scrollbarRef
512
+ }, [
513
+ __props.loading ? (openBlock(), createElementBlock("div", _hoisted_4$4, [..._cache[4] || (_cache[4] = [
514
+ createElementVNode("div", { class: "loading-spinner" }, null, -1),
515
+ createElementVNode("span", null, "加载中...", -1)
516
+ ])])) : filteredLogs.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_5$4, [
517
+ (openBlock(true), createElementBlock(Fragment, null, renderList(filteredLogs.value, (log) => {
518
+ var _a, _b, _c;
519
+ return openBlock(), createElementBlock("div", {
520
+ key: log.id,
521
+ class: normalizeClass(["log-line", [`log-level-${(_a = getLogLevel(log)) == null ? void 0 : _a.toLowerCase()}`]])
522
+ }, [
523
+ createElementVNode("span", _hoisted_6$2, toDisplayString(formatTimestamp(log.timestamp || log.createTime)), 1),
524
+ getThreadName(log) ? (openBlock(), createElementBlock("span", _hoisted_7$2, "[" + toDisplayString(getThreadName(log)) + "]", 1)) : createCommentVNode("", true),
525
+ createElementVNode("span", _hoisted_8$2, toDisplayString(getLogLevel(log)), 1),
526
+ getLoggerName(log) ? (openBlock(), createElementBlock("span", _hoisted_9$1, toDisplayString(getLoggerName(log)), 1)) : createCommentVNode("", true),
527
+ _cache[6] || (_cache[6] = createElementVNode("span", { class: "log-separator" }, "-", -1)),
528
+ createElementVNode("span", _hoisted_10$1, toDisplayString(log.message || log.logContent), 1),
529
+ log.errorMessage || ((_b = log.body) == null ? void 0 : _b.errorMessage) ? (openBlock(), createElementBlock("div", _hoisted_11, [
530
+ _cache[5] || (_cache[5] = createElementVNode("span", { class: "log-error-label" }, "错误:", -1)),
531
+ createElementVNode("span", _hoisted_12, toDisplayString(log.errorMessage || ((_c = log.body) == null ? void 0 : _c.errorMessage)), 1)
532
+ ])) : createCommentVNode("", true)
533
+ ], 2);
534
+ }), 128))
535
+ ])) : (openBlock(), createElementBlock("div", _hoisted_13, [..._cache[7] || (_cache[7] = [
536
+ createElementVNode("div", { class: "empty-icon" }, "📋", -1),
537
+ createElementVNode("div", { class: "empty-text" }, "暂无日志", -1)
538
+ ])]))
539
+ ], 512)
540
+ ], 2);
541
+ };
542
+ }
543
+ });
544
+ const LogViewer = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-c4c4657a"]]);
545
+ const _hoisted_1$4 = { class: "filter-card" };
546
+ const _hoisted_2$4 = { class: "filter-inline" };
547
+ const _hoisted_3$3 = { class: "filter-inline__fields" };
548
+ const _hoisted_4$3 = {
549
+ key: 0,
550
+ class: "field-label"
551
+ };
552
+ const _hoisted_5$3 = ["value", "placeholder", "onInput"];
553
+ const _hoisted_6$1 = { class: "toggle-icon" };
554
+ const _hoisted_7$1 = {
555
+ key: 0,
556
+ class: "filter-grid"
557
+ };
558
+ const _hoisted_8$1 = {
559
+ key: 0,
560
+ class: "field-label"
561
+ };
562
+ const _hoisted_9 = ["value", "placeholder", "onInput"];
563
+ const _hoisted_10 = {
564
+ key: 0,
565
+ class: "filter-grid__hint"
566
+ };
567
+ const TRANSITION_DURATION = 220;
568
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
569
+ __name: "FilterPanel",
570
+ props: {
571
+ filters: {},
572
+ basicFields: {},
573
+ advancedFields: { default: () => [] },
574
+ showAdvanced: { type: Boolean, default: false },
575
+ searchText: { default: "查询" },
576
+ resetText: { default: "重置" },
577
+ expandText: { default: "展开" },
578
+ collapseText: { default: "收起" },
579
+ actionAlign: { default: "right" }
580
+ },
581
+ emits: ["update:filters", "update:showAdvanced", "search", "reset"],
582
+ setup(__props, { emit: __emit }) {
583
+ const props = __props;
584
+ const emit = __emit;
585
+ const hasAdvancedFields = computed(
586
+ () => {
587
+ var _a;
588
+ return (((_a = props.advancedFields) == null ? void 0 : _a.length) ?? 0) > 0;
589
+ }
590
+ );
591
+ const showAdvanced = computed(() => props.showAdvanced ?? false);
592
+ const actionAlign = computed(() => props.actionAlign ?? "right");
593
+ function getValue(key) {
594
+ var _a;
595
+ return (_a = props.filters) == null ? void 0 : _a[key];
596
+ }
597
+ function updateField(key, value) {
598
+ emit("update:filters", {
599
+ ...props.filters,
600
+ [key]: value
601
+ });
602
+ }
603
+ function slotUpdater(key) {
604
+ return (value) => updateField(key, value);
605
+ }
606
+ function toggleAdvanced() {
607
+ emit("update:showAdvanced", !showAdvanced.value);
608
+ }
609
+ function emitSearch() {
610
+ emit("search");
611
+ }
612
+ function emitReset() {
613
+ emit("reset");
614
+ }
615
+ function beforeExpand(el) {
616
+ const element = el;
617
+ element.style.height = "0";
618
+ element.style.opacity = "0";
619
+ }
620
+ function onExpand(el) {
621
+ const element = el;
622
+ requestAnimationFrame(() => {
623
+ element.style.transition = `height ${TRANSITION_DURATION}ms ease, opacity ${TRANSITION_DURATION}ms ease`;
624
+ element.style.height = `${element.scrollHeight}px`;
625
+ element.style.opacity = "1";
626
+ });
627
+ }
628
+ function afterExpand(el) {
629
+ const element = el;
630
+ element.style.height = "";
631
+ element.style.opacity = "";
632
+ element.style.transition = "";
633
+ }
634
+ function beforeCollapse(el) {
635
+ const element = el;
636
+ element.style.height = `${element.scrollHeight}px`;
637
+ element.style.opacity = "1";
638
+ }
639
+ function onCollapse(el, done) {
640
+ const element = el;
641
+ requestAnimationFrame(() => {
642
+ element.style.transition = `height ${TRANSITION_DURATION}ms ease, opacity ${TRANSITION_DURATION}ms ease`;
643
+ element.style.height = "0";
644
+ element.style.opacity = "0";
645
+ setTimeout(done, TRANSITION_DURATION);
646
+ });
647
+ }
648
+ function afterCollapse(el) {
649
+ const element = el;
650
+ element.style.height = "";
651
+ element.style.opacity = "";
652
+ element.style.transition = "";
653
+ }
654
+ return (_ctx, _cache) => {
655
+ return openBlock(), createElementBlock("div", _hoisted_1$4, [
656
+ createElementVNode("div", _hoisted_2$4, [
657
+ createElementVNode("div", _hoisted_3$3, [
658
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.basicFields, (field) => {
659
+ return openBlock(), createElementBlock("div", {
660
+ key: field.key,
661
+ class: "filter-inline__field"
662
+ }, [
663
+ field.label ? (openBlock(), createElementBlock("span", _hoisted_4$3, toDisplayString(field.label) + ":", 1)) : createCommentVNode("", true),
664
+ renderSlot(_ctx.$slots, field.slotName || `field-${field.key}`, {
665
+ field,
666
+ value: getValue(field.key),
667
+ update: slotUpdater(field.key)
668
+ }, () => [
669
+ !field.type || field.type === "input" ? (openBlock(), createElementBlock("input", {
670
+ key: 0,
671
+ value: getValue(field.key) ?? "",
672
+ placeholder: field.placeholder,
673
+ class: "filter-input",
674
+ onInput: ($event) => updateField(field.key, $event.target.value),
675
+ onKeyup: withKeys(emitSearch, ["enter"])
676
+ }, null, 40, _hoisted_5$3)) : createCommentVNode("", true)
677
+ ], true)
678
+ ]);
679
+ }), 128))
680
+ ]),
681
+ createElementVNode("div", {
682
+ class: normalizeClass(["filter-inline__actions", `align-${actionAlign.value}`])
683
+ }, [
684
+ renderSlot(_ctx.$slots, "actions", {
685
+ onReset: emitReset,
686
+ onSearch: emitSearch
687
+ }, () => [
688
+ createElementVNode("button", {
689
+ class: "filter-btn filter-btn--secondary",
690
+ onClick: emitReset
691
+ }, toDisplayString(__props.resetText), 1),
692
+ createElementVNode("button", {
693
+ class: "filter-btn filter-btn--primary",
694
+ onClick: emitSearch
695
+ }, toDisplayString(__props.searchText), 1)
696
+ ], true),
697
+ hasAdvancedFields.value ? (openBlock(), createElementBlock("button", {
698
+ key: 0,
699
+ class: "inline-toggle",
700
+ onClick: toggleAdvanced
701
+ }, [
702
+ createTextVNode(toDisplayString(showAdvanced.value ? __props.collapseText : __props.expandText) + " ", 1),
703
+ createElementVNode("span", _hoisted_6$1, toDisplayString(showAdvanced.value ? "▲" : "▼"), 1)
704
+ ])) : createCommentVNode("", true)
705
+ ], 2)
706
+ ]),
707
+ createVNode(Transition, {
708
+ onBeforeEnter: beforeExpand,
709
+ onEnter: onExpand,
710
+ onAfterEnter: afterExpand,
711
+ onBeforeLeave: beforeCollapse,
712
+ onLeave: onCollapse,
713
+ onAfterLeave: afterCollapse
714
+ }, {
715
+ default: withCtx(() => [
716
+ showAdvanced.value && hasAdvancedFields.value ? (openBlock(), createElementBlock("div", _hoisted_7$1, [
717
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.advancedFields, (field) => {
718
+ return openBlock(), createElementBlock("div", {
719
+ key: field.key,
720
+ class: "filter-grid__field",
721
+ style: normalizeStyle(field.span ? { gridColumn: `span ${field.span}` } : void 0)
722
+ }, [
723
+ field.label ? (openBlock(), createElementBlock("span", _hoisted_8$1, toDisplayString(field.label) + ":", 1)) : createCommentVNode("", true),
724
+ renderSlot(_ctx.$slots, field.slotName || `field-${field.key}`, {
725
+ field,
726
+ value: getValue(field.key),
727
+ update: slotUpdater(field.key)
728
+ }, () => [
729
+ !field.type || field.type === "input" ? (openBlock(), createElementBlock("input", {
730
+ key: 0,
731
+ value: getValue(field.key) ?? "",
732
+ placeholder: field.placeholder,
733
+ class: "filter-input",
734
+ onInput: ($event) => updateField(field.key, $event.target.value)
735
+ }, null, 40, _hoisted_9)) : createCommentVNode("", true)
736
+ ], true)
737
+ ], 4);
738
+ }), 128)),
739
+ _ctx.$slots["advanced-hint"] ? (openBlock(), createElementBlock("div", _hoisted_10, [
740
+ renderSlot(_ctx.$slots, "advanced-hint", {}, void 0, true)
741
+ ])) : createCommentVNode("", true)
742
+ ])) : createCommentVNode("", true)
743
+ ]),
744
+ _: 3
745
+ })
746
+ ]);
747
+ };
748
+ }
749
+ });
750
+ const FilterPanel = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-8db9aa68"]]);
751
+ const _hoisted_1$3 = { class: "header-content" };
752
+ const _hoisted_2$3 = {
753
+ key: 0,
754
+ class: "header-icon"
755
+ };
756
+ const _hoisted_3$2 = ["src"];
757
+ const _hoisted_4$2 = { class: "header-info" };
758
+ const _hoisted_5$2 = {
759
+ key: 0,
760
+ class: "header-subtitle"
761
+ };
762
+ const _hoisted_6 = { class: "header-title" };
763
+ const _hoisted_7 = {
764
+ key: 0,
765
+ class: "header-actions"
766
+ };
767
+ const _hoisted_8 = {
768
+ key: 0,
769
+ class: "footer-actions"
770
+ };
771
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
772
+ __name: "UniversalModal",
773
+ props: {
774
+ show: { type: Boolean },
775
+ title: { default: "" },
776
+ subtitle: { default: "" },
777
+ iconUrl: {},
778
+ iconSize: {},
779
+ width: { default: "500px" },
780
+ height: { default: "auto" },
781
+ maxWidth: { default: "90vw" },
782
+ maxHeight: { default: "90vh" },
783
+ position: { default: "right" },
784
+ top: { default: "24px" },
785
+ bottom: { default: "24px" },
786
+ left: { default: "24px" },
787
+ right: { default: "24px" },
788
+ showMask: { type: Boolean, default: false },
789
+ maskClosable: { type: Boolean, default: true },
790
+ hideHeader: { type: Boolean, default: false },
791
+ hideFooter: { type: Boolean, default: true },
792
+ hideClose: { type: Boolean, default: false },
793
+ showCancel: { type: Boolean, default: false },
794
+ showConfirm: { type: Boolean, default: false },
795
+ showFullscreen: { type: Boolean, default: true },
796
+ resizable: { type: Boolean, default: true },
797
+ cancelText: { default: "取消" },
798
+ confirmText: { default: "确定" },
799
+ headerClass: {},
800
+ bodyClass: {},
801
+ footerClass: {},
802
+ customClass: {},
803
+ zIndex: { default: 9999 },
804
+ fullscreen: { type: Boolean, default: false }
805
+ },
806
+ emits: ["update:show", "close", "cancel", "confirm"],
807
+ setup(__props, { emit: __emit }) {
808
+ const props = __props;
809
+ const emit = __emit;
810
+ const slots = useSlots();
811
+ const isFullscreen = ref(false);
812
+ const modalRef = ref(null);
813
+ const resizing = ref(false);
814
+ const resizeDirection = ref("");
815
+ const modalSize = ref({
816
+ width: 0,
817
+ height: 0,
818
+ top: 0,
819
+ left: 0,
820
+ right: 0,
821
+ bottom: 0
822
+ });
823
+ const shouldShowFooter = computed(() => {
824
+ if (props.hideFooter) return false;
825
+ if (slots.footer) return true;
826
+ if (props.showCancel || props.showConfirm) return true;
827
+ return false;
828
+ });
829
+ const transitionName = computed(() => {
830
+ switch (props.position) {
831
+ case "left":
832
+ return "slide-left";
833
+ case "right":
834
+ return "slide-right";
835
+ case "top":
836
+ return "slide-top";
837
+ case "bottom":
838
+ return "slide-bottom";
839
+ case "center":
840
+ default:
841
+ return "fade-scale";
842
+ }
843
+ });
844
+ const wrapperClass = computed(() => {
845
+ return [
846
+ `position-${props.position}`,
847
+ props.fullscreen ? "fullscreen" : "",
848
+ props.showMask ? "with-mask" : "no-mask"
849
+ ];
850
+ });
851
+ const wrapperStyle = computed(() => {
852
+ const style = {};
853
+ if (!props.showMask) {
854
+ style.background = "transparent";
855
+ style.pointerEvents = "none";
856
+ }
857
+ return style;
858
+ });
859
+ const modalClass = computed(() => {
860
+ return [
861
+ `modal-${props.position}`,
862
+ props.customClass,
863
+ props.fullscreen ? "modal-fullscreen" : ""
864
+ ];
865
+ });
866
+ const modalStyle = computed(() => {
867
+ const style = {
868
+ zIndex: String(props.zIndex)
869
+ };
870
+ if (props.fullscreen) return style;
871
+ if (props.width) {
872
+ style.width = typeof props.width === "number" ? `${props.width}px` : props.width;
873
+ }
874
+ if (props.height && props.height !== "auto") {
875
+ style.height = typeof props.height === "number" ? `${props.height}px` : props.height;
876
+ }
877
+ if (props.maxWidth) {
878
+ style.maxWidth = typeof props.maxWidth === "number" ? `${props.maxWidth}px` : props.maxWidth;
879
+ }
880
+ if (props.maxHeight) {
881
+ style.maxHeight = typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight;
882
+ }
883
+ if (props.position !== "center") {
884
+ if (props.top) style.top = typeof props.top === "number" ? `${props.top}px` : props.top;
885
+ if (props.bottom) style.bottom = typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom;
886
+ if (props.left && props.position === "left") style.left = typeof props.left === "number" ? `${props.left}px` : props.left;
887
+ if (props.right && props.position === "right") style.right = typeof props.right === "number" ? `${props.right}px` : props.right;
888
+ }
889
+ return style;
890
+ });
891
+ const bodyStyle = computed(() => {
892
+ const style = {};
893
+ if (props.height && props.height !== "auto") {
894
+ style.overflowY = "auto";
895
+ }
896
+ return style;
897
+ });
898
+ const computedModalStyle = computed(() => {
899
+ const style = { ...modalStyle.value };
900
+ if (isFullscreen.value) {
901
+ return {
902
+ ...style,
903
+ width: "100vw !important",
904
+ height: "100vh !important",
905
+ maxWidth: "100vw !important",
906
+ maxHeight: "100vh !important",
907
+ top: "0 !important",
908
+ left: "0 !important",
909
+ right: "0 !important",
910
+ bottom: "0 !important"
911
+ };
912
+ }
913
+ if (resizing.value || modalSize.value.width > 0) {
914
+ if (modalSize.value.width > 0) style.width = `${modalSize.value.width}px`;
915
+ if (modalSize.value.height > 0) style.height = `${modalSize.value.height}px`;
916
+ if (props.position === "right" && modalSize.value.right >= 0) style.right = `${modalSize.value.right}px`;
917
+ if (props.position === "left" && modalSize.value.left >= 0) style.left = `${modalSize.value.left}px`;
918
+ if (modalSize.value.top >= 0) style.top = `${modalSize.value.top}px`;
919
+ if (modalSize.value.bottom >= 0) style.bottom = `${modalSize.value.bottom}px`;
920
+ }
921
+ return style;
922
+ });
923
+ function handleClose() {
924
+ emit("update:show", false);
925
+ emit("close");
926
+ }
927
+ function handleCancel() {
928
+ emit("cancel");
929
+ handleClose();
930
+ }
931
+ function handleConfirm() {
932
+ emit("confirm");
933
+ }
934
+ function handleMaskClick() {
935
+ if (props.maskClosable) {
936
+ handleClose();
937
+ }
938
+ }
939
+ function toggleFullscreen() {
940
+ isFullscreen.value = !isFullscreen.value;
941
+ }
942
+ function startResize(direction) {
943
+ if (!modalRef.value) return;
944
+ resizing.value = true;
945
+ resizeDirection.value = direction;
946
+ const rect = modalRef.value.getBoundingClientRect();
947
+ modalSize.value = {
948
+ width: rect.width,
949
+ height: rect.height,
950
+ top: rect.top,
951
+ left: rect.left,
952
+ right: window.innerWidth - rect.right,
953
+ bottom: window.innerHeight - rect.bottom
954
+ };
955
+ document.addEventListener("mousemove", handleResize);
956
+ document.addEventListener("mouseup", stopResize);
957
+ document.body.style.cursor = getCursor(direction);
958
+ document.body.style.userSelect = "none";
959
+ }
960
+ function handleResize(e) {
961
+ if (!resizing.value || !modalRef.value) return;
962
+ const direction = resizeDirection.value;
963
+ if (direction === "right") {
964
+ if (props.position === "right") {
965
+ const newRight = window.innerWidth - e.clientX;
966
+ modalSize.value.right = Math.max(0, newRight);
967
+ modalSize.value.width = e.clientX - modalSize.value.left;
968
+ } else {
969
+ modalSize.value.width = e.clientX - modalSize.value.left;
970
+ }
971
+ } else if (direction === "left") {
972
+ if (props.position === "left") {
973
+ modalSize.value.left = e.clientX;
974
+ modalSize.value.width = window.innerWidth - e.clientX - modalSize.value.right;
975
+ } else {
976
+ const newWidth = modalSize.value.width + (modalSize.value.left - e.clientX);
977
+ modalSize.value.width = newWidth;
978
+ modalSize.value.left = e.clientX;
979
+ }
980
+ } else if (direction === "top") {
981
+ const newHeight = modalSize.value.height + (modalSize.value.top - e.clientY);
982
+ modalSize.value.height = Math.max(200, newHeight);
983
+ modalSize.value.top = e.clientY;
984
+ } else if (direction === "bottom") {
985
+ modalSize.value.height = e.clientY - modalSize.value.top;
986
+ modalSize.value.bottom = window.innerHeight - e.clientY;
987
+ }
988
+ }
989
+ function stopResize() {
990
+ resizing.value = false;
991
+ resizeDirection.value = "";
992
+ document.removeEventListener("mousemove", handleResize);
993
+ document.removeEventListener("mouseup", stopResize);
994
+ document.body.style.cursor = "";
995
+ document.body.style.userSelect = "";
996
+ }
997
+ function getCursor(direction) {
998
+ switch (direction) {
999
+ case "top":
1000
+ case "bottom":
1001
+ return "ns-resize";
1002
+ case "left":
1003
+ case "right":
1004
+ return "ew-resize";
1005
+ default:
1006
+ return "default";
1007
+ }
1008
+ }
1009
+ onUnmounted(() => {
1010
+ if (resizing.value) {
1011
+ stopResize();
1012
+ }
1013
+ });
1014
+ return (_ctx, _cache) => {
1015
+ return openBlock(), createBlock(Transition, { name: transitionName.value }, {
1016
+ default: withCtx(() => [
1017
+ __props.show ? (openBlock(), createElementBlock("div", {
1018
+ key: 0,
1019
+ class: normalizeClass(["universal-modal-wrapper", wrapperClass.value]),
1020
+ style: normalizeStyle(wrapperStyle.value),
1021
+ onClick: withModifiers(handleMaskClick, ["self"])
1022
+ }, [
1023
+ createElementVNode("div", {
1024
+ ref_key: "modalRef",
1025
+ ref: modalRef,
1026
+ class: normalizeClass(["universal-modal", modalClass.value]),
1027
+ style: normalizeStyle(computedModalStyle.value)
1028
+ }, [
1029
+ !isFullscreen.value && __props.resizable && (__props.position === "right" || __props.position === "left") ? (openBlock(), createElementBlock("div", {
1030
+ key: 0,
1031
+ class: "resize-handle resize-handle-left",
1032
+ onMousedown: _cache[0] || (_cache[0] = ($event) => startResize("left"))
1033
+ }, null, 32)) : createCommentVNode("", true),
1034
+ !isFullscreen.value && __props.resizable && (__props.position === "right" || __props.position === "left") ? (openBlock(), createElementBlock("div", {
1035
+ key: 1,
1036
+ class: "resize-handle resize-handle-right",
1037
+ onMousedown: _cache[1] || (_cache[1] = ($event) => startResize("right"))
1038
+ }, null, 32)) : createCommentVNode("", true),
1039
+ !isFullscreen.value && __props.resizable ? (openBlock(), createElementBlock("div", {
1040
+ key: 2,
1041
+ class: "resize-handle resize-handle-top",
1042
+ onMousedown: _cache[2] || (_cache[2] = ($event) => startResize("top"))
1043
+ }, null, 32)) : createCommentVNode("", true),
1044
+ !isFullscreen.value && __props.resizable ? (openBlock(), createElementBlock("div", {
1045
+ key: 3,
1046
+ class: "resize-handle resize-handle-bottom",
1047
+ onMousedown: _cache[3] || (_cache[3] = ($event) => startResize("bottom"))
1048
+ }, null, 32)) : createCommentVNode("", true),
1049
+ !__props.hideHeader ? (openBlock(), createElementBlock("div", {
1050
+ key: 4,
1051
+ class: normalizeClass(["modal-header", __props.headerClass])
1052
+ }, [
1053
+ renderSlot(_ctx.$slots, "header", {}, () => [
1054
+ createElementVNode("div", _hoisted_1$3, [
1055
+ __props.iconUrl ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
1056
+ createElementVNode("img", {
1057
+ src: __props.iconUrl,
1058
+ class: "header-icon-img",
1059
+ alt: "icon"
1060
+ }, null, 8, _hoisted_3$2)
1061
+ ])) : createCommentVNode("", true),
1062
+ createElementVNode("div", _hoisted_4$2, [
1063
+ __props.subtitle ? (openBlock(), createElementBlock("div", _hoisted_5$2, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true),
1064
+ createElementVNode("div", _hoisted_6, toDisplayString(__props.title), 1)
1065
+ ])
1066
+ ])
1067
+ ], true),
1068
+ !__props.hideClose ? (openBlock(), createElementBlock("div", _hoisted_7, [
1069
+ renderSlot(_ctx.$slots, "header-actions", {}, void 0, true),
1070
+ __props.showFullscreen ? (openBlock(), createElementBlock("button", {
1071
+ key: 0,
1072
+ class: "header-btn",
1073
+ onClick: toggleFullscreen
1074
+ }, toDisplayString(isFullscreen.value ? "⊡" : "⊞"), 1)) : createCommentVNode("", true),
1075
+ createElementVNode("button", {
1076
+ class: "header-btn",
1077
+ onClick: handleClose
1078
+ }, " ✕ ")
1079
+ ])) : createCommentVNode("", true)
1080
+ ], 2)) : createCommentVNode("", true),
1081
+ createElementVNode("div", {
1082
+ class: normalizeClass(["modal-body", __props.bodyClass]),
1083
+ style: normalizeStyle(bodyStyle.value)
1084
+ }, [
1085
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
1086
+ ], 6),
1087
+ shouldShowFooter.value ? (openBlock(), createElementBlock("div", {
1088
+ key: 5,
1089
+ class: normalizeClass(["modal-footer", __props.footerClass])
1090
+ }, [
1091
+ renderSlot(_ctx.$slots, "footer", {}, () => [
1092
+ __props.showCancel || __props.showConfirm ? (openBlock(), createElementBlock("div", _hoisted_8, [
1093
+ __props.showCancel ? (openBlock(), createElementBlock("button", {
1094
+ key: 0,
1095
+ class: "footer-btn footer-btn--cancel",
1096
+ onClick: handleCancel
1097
+ }, toDisplayString(__props.cancelText), 1)) : createCommentVNode("", true),
1098
+ __props.showConfirm ? (openBlock(), createElementBlock("button", {
1099
+ key: 1,
1100
+ class: "footer-btn footer-btn--confirm",
1101
+ onClick: handleConfirm
1102
+ }, toDisplayString(__props.confirmText), 1)) : createCommentVNode("", true)
1103
+ ])) : createCommentVNode("", true)
1104
+ ], true)
1105
+ ], 2)) : createCommentVNode("", true)
1106
+ ], 6)
1107
+ ], 6)) : createCommentVNode("", true)
1108
+ ]),
1109
+ _: 3
1110
+ }, 8, ["name"]);
1111
+ };
1112
+ }
1113
+ });
1114
+ const UniversalModal = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-c1a551dc"]]);
175
1115
  const _hoisted_1$2 = { class: "loading-container" };
176
1116
  const _hoisted_2$2 = {
177
1117
  key: 0,
@@ -191,14 +1131,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
191
1131
  };
192
1132
  }
193
1133
  });
194
- const _export_sfc = (sfc, props) => {
195
- const target = sfc.__vccOpts || sfc;
196
- for (const [key, val] of props) {
197
- target[key] = val;
198
- }
199
- return target;
200
- };
201
- const LoadingState = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-88be2f1a"]]);
1134
+ const LoadingState = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-d3a7a28f"]]);
202
1135
  const _hoisted_1$1 = { class: "empty-state" };
203
1136
  const _hoisted_2$1 = { class: "empty-icon" };
204
1137
  const _hoisted_3$1 = { class: "empty-title" };
@@ -249,7 +1182,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
249
1182
  };
250
1183
  }
251
1184
  });
252
- const EmptyState = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-12ee016f"]]);
1185
+ const EmptyState = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-a29f92b8"]]);
253
1186
  const _hoisted_1 = { class: "error-container" };
254
1187
  const _hoisted_2 = { class: "error-icon" };
255
1188
  const _hoisted_3 = { class: "error-title" };
@@ -315,11 +1248,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
315
1248
  };
316
1249
  }
317
1250
  });
318
- const ErrorState = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-9bbae138"]]);
1251
+ const ErrorState = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-c6d5c909"]]);
319
1252
  export {
1253
+ CardList,
320
1254
  EmptyState,
321
1255
  ErrorState,
322
- LoadingState as LoadingStateComponent,
1256
+ FilterPanel,
1257
+ LoadingState,
1258
+ LogViewer,
1259
+ PageContainer,
1260
+ PageContent,
1261
+ PageHeader,
1262
+ PagePagination,
1263
+ UniversalModal,
323
1264
  breakpoints,
324
1265
  useLoadingState,
325
1266
  useResponsive