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