@kine-design/crud 0.0.1-beta.7 → 0.0.1-beta.8

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.
@@ -9,6 +9,7 @@
9
9
  * 一个配置出一整个页面:标题 + 筛选 + 表格 + 分页 + 状态标签。
10
10
  */
11
11
  import { defineComponent, type PropType } from 'vue';
12
+ import { useRouter } from 'vue-router';
12
13
  import KTableColumn from 'kine-ui/components/tableColumn/KTableColumn.tsx';
13
14
  import KTag from 'kine-ui/components/tag/KTag.tsx';
14
15
  import KPageHeader from '../pageHeader/KPageHeader.tsx';
@@ -28,6 +29,7 @@ export default defineComponent({
28
29
  },
29
30
 
30
31
  setup(props, { slots }) {
32
+ const router = useRouter();
31
33
  const {
32
34
  page, pageSize, total, list, loading,
33
35
  filters, onPageChange, onSearch, onReset,
@@ -67,6 +69,28 @@ export default defineComponent({
67
69
  }
68
70
  };
69
71
 
72
+ /** 行点击 → 跳转详情 */
73
+ const onRowClick = (e: MouseEvent) => {
74
+ const detailPath = props.config.detailPath;
75
+ if (!detailPath) return;
76
+
77
+ const tr = (e.target as HTMLElement).closest?.('tr');
78
+ if (!tr) return;
79
+ const tbody = tr.closest('tbody');
80
+ if (!tbody || tbody.classList.contains('k-table-empty')) return;
81
+
82
+ const rows = Array.from(tbody.querySelectorAll('tr'));
83
+ const index = rows.indexOf(tr as HTMLTableRowElement);
84
+ if (index < 0 || index >= list.value.length) return;
85
+
86
+ const row = list.value[index];
87
+ const key = props.config.rowKey ?? 'id';
88
+ const id = row[key];
89
+ if (id != null) {
90
+ router.push(`${detailPath}/${id}`);
91
+ }
92
+ };
93
+
70
94
  /** 渲染筛选区表单项 */
71
95
  const renderFilters = () => {
72
96
  if (!props.config.filters?.length) return null;
@@ -102,47 +126,49 @@ export default defineComponent({
102
126
  };
103
127
 
104
128
  return () => (
105
- <div class="k-crud-page">
129
+ <div class={['k-crud-page', props.config.detailPath ? 'k-crud-page--clickable' : '']}>
106
130
  <KPageHeader title={props.config.title}>
107
131
  {{ extra: slots.headerExtra }}
108
132
  </KPageHeader>
109
133
 
110
- <KSearchTable
111
- data={list.value}
112
- loading={loading.value}
113
- total={total.value}
114
- page={page.value}
115
- pageSize={pageSize.value}
116
- searchable={!!props.config.filters?.length}
117
- onUpdate:page={onPageChange}
118
- onSearch={onSearch}
119
- onReset={onReset}
120
- >
121
- {{
122
- search: renderFilters,
123
- toolbar: slots.toolbar,
124
- default: () => props.config.columns.map(col => {
125
- const customSlot = slots[`column-${col.param}`];
126
- return (
127
- <KTableColumn
128
- key={col.param}
129
- param={col.param}
130
- label={col.label}
131
- width={col.width ?? ''}
132
- >
133
- {{
134
- default: customSlot
135
- ? (scope: { row: Record<string, unknown>; index: number }) => customSlot(scope)
136
- : col.type
137
- ? (scope: { row: Record<string, unknown> }) => renderCell(col, scope.row)
138
- : undefined,
139
- }}
140
- </KTableColumn>
141
- );
142
- }),
143
- empty: slots.empty,
144
- }}
145
- </KSearchTable>
134
+ <div onClick={onRowClick}>
135
+ <KSearchTable
136
+ data={list.value}
137
+ loading={loading.value}
138
+ total={total.value}
139
+ page={page.value}
140
+ pageSize={pageSize.value}
141
+ searchable={!!props.config.filters?.length}
142
+ onUpdate:page={onPageChange}
143
+ onSearch={onSearch}
144
+ onReset={onReset}
145
+ >
146
+ {{
147
+ search: renderFilters,
148
+ toolbar: slots.toolbar,
149
+ default: () => props.config.columns.map(col => {
150
+ const customSlot = slots[`column-${col.param}`];
151
+ return (
152
+ <KTableColumn
153
+ key={col.param}
154
+ param={col.param}
155
+ label={col.label}
156
+ width={col.width ?? ''}
157
+ >
158
+ {{
159
+ default: customSlot
160
+ ? (scope: { row: Record<string, unknown>; index: number }) => customSlot(scope)
161
+ : col.type
162
+ ? (scope: { row: Record<string, unknown> }) => renderCell(col, scope.row)
163
+ : undefined,
164
+ }}
165
+ </KTableColumn>
166
+ );
167
+ }),
168
+ empty: slots.empty,
169
+ }}
170
+ </KSearchTable>
171
+ </div>
146
172
  </div>
147
173
  );
148
174
  },
@@ -46,3 +46,8 @@
46
46
  .k-crud-page-filter-control:focus {
47
47
  border-color: var(--kine-color-accent-default);
48
48
  }
49
+
50
+ /* ===== 行可点击 ===== */
51
+ .k-crud-page--clickable .k-tbody .k-tr {
52
+ cursor: pointer;
53
+ }
@@ -55,4 +55,6 @@ export interface CrudPageConfig {
55
55
  pageSize?: number;
56
56
  /** 行主键字段,默认 'id' */
57
57
  rowKey?: string;
58
+ /** 详情页路由前缀,设置后点击行自动跳转到 `${detailPath}/${row[rowKey]}` */
59
+ detailPath?: string;
58
60
  }
@@ -54,4 +54,6 @@ export interface CrudPageConfig {
54
54
  pageSize?: number;
55
55
  /** 行主键字段,默认 'id' */
56
56
  rowKey?: string;
57
+ /** 详情页路由前缀,设置后点击行自动跳转到 `${detailPath}/${row[rowKey]}` */
58
+ detailPath?: string;
57
59
  }
package/dist/crud.css CHANGED
@@ -743,6 +743,11 @@
743
743
  .k-crud-page-filter-control:focus {
744
744
  border-color: var(--kine-color-accent-default);
745
745
  }
746
+
747
+ /* ===== 行可点击 ===== */
748
+ .k-crud-page--clickable .k-tbody .k-tr {
749
+ cursor: pointer;
750
+ }
746
751
  /**
747
752
  * @description KLoginPage 登录页样式 — Phosphor 主题
748
753
  * @author 阿怪
package/dist/crud.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Comment, Fragment, computed, createApp, createTextVNode, createVNode, defineComponent, h, inject, isRef, mergeProps, onBeforeUnmount, onMounted, onUnmounted, provide, reactive, ref, resolveComponent, shallowRef, toRef, triggerRef, watch } from "vue";
2
+ import { useRoute, useRouter } from "vue-router";
2
3
  import { QueryClient, VueQueryPlugin, useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
3
4
  import { createPinia, defineStore } from "pinia";
4
- import { useRoute, useRouter } from "vue-router";
5
5
  //#region \0rolldown/runtime.js
6
6
  var __create = Object.create;
7
7
  var __defProp = Object.defineProperty;
@@ -6527,6 +6527,7 @@ var KCrudPage_default = /* @__PURE__ */ defineComponent({
6527
6527
  required: true
6528
6528
  } },
6529
6529
  setup(props, { slots }) {
6530
+ const router = useRouter();
6530
6531
  const { page, pageSize, total, list, loading, filters, onPageChange, onSearch, onReset } = useCrudPage(props.config);
6531
6532
  /** 格式化日期 */
6532
6533
  const formatDate = (val) => {
@@ -6561,6 +6562,19 @@ var KCrudPage_default = /* @__PURE__ */ defineComponent({
6561
6562
  default: return val != null ? String(val) : "";
6562
6563
  }
6563
6564
  };
6565
+ /** 行点击 → 跳转详情 */
6566
+ const onRowClick = (e) => {
6567
+ const detailPath = props.config.detailPath;
6568
+ if (!detailPath) return;
6569
+ const tr = e.target.closest?.("tr");
6570
+ if (!tr) return;
6571
+ const tbody = tr.closest("tbody");
6572
+ if (!tbody || tbody.classList.contains("k-table-empty")) return;
6573
+ const index = Array.from(tbody.querySelectorAll("tr")).indexOf(tr);
6574
+ if (index < 0 || index >= list.value.length) return;
6575
+ const id = list.value[index][props.config.rowKey ?? "id"];
6576
+ if (id != null) router.push(`${detailPath}/${id}`);
6577
+ };
6564
6578
  /** 渲染筛选区表单项 */
6565
6579
  const renderFilters = () => {
6566
6580
  if (!props.config.filters?.length) return null;
@@ -6586,7 +6600,7 @@ var KCrudPage_default = /* @__PURE__ */ defineComponent({
6586
6600
  }
6587
6601
  }, null)]));
6588
6602
  };
6589
- return () => createVNode("div", { "class": "k-crud-page" }, [createVNode(KPageHeader_default, { "title": props.config.title }, { extra: slots.headerExtra }), createVNode(KSearchTable_default, {
6603
+ return () => createVNode("div", { "class": ["k-crud-page", props.config.detailPath ? "k-crud-page--clickable" : ""] }, [createVNode(KPageHeader_default, { "title": props.config.title }, { extra: slots.headerExtra }), createVNode("div", { "onClick": onRowClick }, [createVNode(KSearchTable_default, {
6590
6604
  "data": list.value,
6591
6605
  "loading": loading.value,
6592
6606
  "total": total.value,
@@ -6609,7 +6623,7 @@ var KCrudPage_default = /* @__PURE__ */ defineComponent({
6609
6623
  }, { default: customSlot ? (scope) => customSlot(scope) : col.type ? (scope) => renderCell(col, scope.row) : void 0 });
6610
6624
  }),
6611
6625
  empty: slots.empty
6612
- })]);
6626
+ })])]);
6613
6627
  }
6614
6628
  });
6615
6629
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kine-design/crud",
3
- "version": "0.0.1-beta.7",
3
+ "version": "0.0.1-beta.8",
4
4
  "type": "module",
5
5
  "main": "./dist/crud.js",
6
6
  "types": "./dist/index.d.ts",