Procházet zdrojové kódy

提出为组件,不能排序和筛选

qdy před 1 měsícem
rodič
revize
842eb22e82

+ 33
- 6
projects/base-core/src/lib/components/sticky-header/sticky-header.component.scss Zobrazit soubor

@@ -119,22 +119,49 @@
119 119
       background: #f8fafc; /* 恢复默认背景色,与普通状态一致 */
120 120
       border: 1px solid #e2e8f0;
121 121
       border-top: none; /* 移除顶部边框,实现无缝衔接 */
122
-      height: 100%; /* 填充父容器高度 */
123
-      min-height: 100%; /* 确保填充最小高度 */
124
-      flex: 1; /* 填充可用空间 */
122
+      height: auto; /* 改为自适应高度 */
123
+      min-height: auto; /* 移除最小高度限制 */
124
+      flex: none; /* 取消flex扩展 */
125 125
       
126 126
       > div:first-child {
127
-        padding-top: 1px; /* 减少上下空白,从6px改为1px */
128
-        padding-bottom: 1px; /* 减少上下空白,从6px改为1px */
127
+        padding-top: 0; /* 移除上下空白 */
128
+        padding-bottom: 0;
129
+        min-height: 40px; /* 设置为单行高度 */
130
+        display: flex;
131
+        align-items: center; /* 垂直居中 */
129 132
       }
130 133
     }
131 134
 
132 135
     .header-title {
133
-      font-size: 1.125rem; /* 更小一点 */
136
+      font-size: 1rem; /* 进一步缩小字体 */
137
+      line-height: 1.2; /* 减少行高 */
134 138
       font-weight: 800;
135 139
       color: #0f172a; /* 更深的文字颜色,增强可读性 */
136 140
       text-shadow: 0 1px 2px rgba(255, 255, 255, 0.9); /* 保持文字阴影 */
137 141
       letter-spacing: -0.025em; /* 紧凑的字母间距 */
142
+      margin: 0;
143
+      white-space: nowrap; /* 防止标题换行 */
144
+      overflow: hidden;
145
+      text-overflow: ellipsis;
146
+    }
147
+
148
+    // 优化按钮尺寸
149
+    ::ng-deep .header-content > div:first-child {
150
+      button {
151
+        min-height: 32px !important; /* 覆盖Material默认高度 */
152
+        padding: 0 12px !important; /* 减少左右内边距 */
153
+        height: 32px !important;
154
+        
155
+        .mat-icon, .mat-mdc-progress-spinner {
156
+          width: 18px;
157
+          height: 18px;
158
+          font-size: 18px;
159
+        }
160
+        
161
+        span {
162
+          font-size: 0.875rem; /* 按钮文字稍微缩小 */
163
+        }
164
+      }
138 165
     }
139 166
 
140 167
     .hint-section {

+ 0
- 390
projects/base-core/src/lib/components/tabulator-grid/README.md Zobrazit soubor

@@ -1,390 +0,0 @@
1
-# TabulatorGrid 组件
2
-
3
-极简配置的服务端数据表格组件,只需提供API URL和列定义即可自动实现:
4
-- 服务端分页
5
-- 服务端排序  
6
-- 服务端筛选
7
-- 主题切换
8
-- 响应式设计
9
-
10
-## 安装依赖
11
-
12
-确保项目中已安装 `tabulator-tables`:
13
-
14
-```bash
15
-npm install tabulator-tables@^6.3.1
16
-```
17
-
18
-## 基本使用
19
-
20
-### 1. 在模块中导入组件
21
-
22
-```typescript
23
-import { TabulatorGridComponent } from 'base-core';
24
-
25
-@NgModule({
26
-  imports: [
27
-    TabulatorGridComponent
28
-  ]
29
-})
30
-export class YourModule { }
31
-```
32
-
33
-### 2. 在组件中定义列配置
34
-
35
-```typescript
36
-import { TabulatorGridColumn } from 'base-core';
37
-
38
-@Component({
39
-  // ...
40
-})
41
-export class YourComponent {
42
-  // 列定义
43
-  columns: TabulatorGridColumn[] = [
44
-    { title: 'ID', field: 'id', width: 80, sorter: 'number' },
45
-    { title: '姓名', field: 'name', sorter: 'string', headerFilter: true },
46
-    { title: '年龄', field: 'age', sorter: 'number', headerFilter: 'number' },
47
-    { title: '邮箱', field: 'email', sorter: 'string', headerFilter: true },
48
-    { title: '状态', field: 'status', formatter: 'tickCross', hozAlign: 'center' }
49
-  ];
50
-
51
-  // API地址
52
-  apiUrl = '/api/config/meta/list';
53
-
54
-  // 事件处理
55
-  onSort(event: any) {
56
-    console.log('排序变化:', event);
57
-  }
58
-
59
-  onFilter(event: any) {
60
-    console.log('筛选变化:', event);
61
-  }
62
-
63
-  onRowClick(event: any) {
64
-    console.log('行点击:', event);
65
-  }
66
-}
67
-```
68
-
69
-### 3. 在模板中使用
70
-
71
-```html
72
-<lib-tabulator-grid
73
-  [dataSource]="apiUrl"
74
-  [columns]="columns"
75
-  [pageSize]="20"
76
-  theme="bootstrap4"
77
-  [showHeaderFilters]="true"
78
-  (sortChanged)="onSort($event)"
79
-  (filterChanged)="onFilter($event)"
80
-  (rowClicked)="onRowClick($event)">
81
-</lib-tabulator-grid>
82
-```
83
-
84
-## 高级配置
85
-
86
-### 使用对象数据源
87
-
88
-```typescript
89
-dataSource = {
90
-  url: '/api/config/meta/list',
91
-  method: 'POST', // 默认POST
92
-  headers: {
93
-    'Authorization': 'Bearer token'
94
-  },
95
-  params: {
96
-    tenantId: '123'
97
-  },
98
-  // 自定义请求映射
99
-  requestMapper: (params) => {
100
-    return {
101
-      ...params,
102
-      extraParam: 'value'
103
-    };
104
-  },
105
-  // 自定义响应映射
106
-  responseMapper: (response) => {
107
-    return {
108
-      data: response.data,
109
-      total: response.totalCount,
110
-      last_page: Math.ceil(response.totalCount / 20)
111
-    };
112
-  }
113
-};
114
-```
115
-
116
-### 字段映射和操作符映射
117
-
118
-```typescript
119
-config = {
120
-  fieldMapping: {
121
-    'name': 'user_name',
122
-    'age': 'user_age',
123
-    'email': 'user_email'
124
-  },
125
-  operatorMapping: {
126
-    'contains': 'like',
127
-    'startsWith': 'like',
128
-    'endsWith': 'like'
129
-  }
130
-};
131
-```
132
-
133
-### 完整配置示例
134
-
135
-```typescript
136
-import { TabulatorGridConfig } from 'base-core';
137
-
138
-@Component({
139
-  // ...
140
-})
141
-export class YourComponent {
142
-  columns = [
143
-    { title: 'ID', field: 'id', width: 80, sorter: 'number' },
144
-    { title: '配置名称', field: 'configName', sorter: 'string', headerFilter: true },
145
-    { title: '字段名', field: 'fieldName', sorter: 'string', headerFilter: true },
146
-    { title: '字段类型', field: 'fieldType', sorter: 'string', headerFilter: 'select' },
147
-    { title: 'YAML标签', field: 'yamlName', sorter: 'string', headerFilter: true },
148
-    { title: '创建时间', field: 'createdAt', sorter: 'date', formatter: 'datetime' }
149
-  ];
150
-
151
-  dataSource = {
152
-    url: '/api/tabulator/config/meta/list',
153
-    method: 'POST'
154
-  };
155
-
156
-  config: TabulatorGridConfig = {
157
-    height: '600px',
158
-    layout: 'fitData',
159
-    placeholder: '暂无配置数据',
160
-    fieldMapping: {
161
-      'configName': 'config_name',
162
-      'fieldName': 'field_name', 
163
-      'fieldType': 'field_type',
164
-      'yamlName': 'yaml_name',
165
-      'createdAt': 'created_at'
166
-    },
167
-    operatorMapping: {
168
-      '=': '=',
169
-      'like': 'like',
170
-      '>': 'gt',
171
-      '<': 'lt'
172
-    }
173
-  };
174
-
175
-  pageSize = 20;
176
-  theme = 'bootstrap5';
177
-  showHeaderFilters = true;
178
-}
179
-```
180
-
181
-## 支持的Tabulator主题
182
-
183
-- `default` - 默认主题
184
-- `bootstrap` - Bootstrap 3
185
-- `bootstrap4` - Bootstrap 4 (默认)
186
-- `bootstrap5` - Bootstrap 5
187
-- `materialize` - Materialize
188
-- `semanticui` - Semantic UI
189
-- `bulma` - Bulma
190
-- `simple` - 简约主题
191
-- `midnight` - 深色主题
192
-- `modern` - 现代主题
193
-
194
-## 事件API
195
-
196
-| 事件 | 描述 | 事件数据 |
197
-|------|------|----------|
198
-| `sortChanged` | 排序变化时触发 | `{ sorters: Array<{field, dir}> }` |
199
-| `filterChanged` | 筛选变化时触发 | `{ filters: Array<{field, type, value}> }` |
200
-| `pageChanged` | 分页变化时触发 | `{ page: number, pageSize: number }` |
201
-| `rowClicked` | 行点击时触发 | `{ row: any, event?: Event }` |
202
-| `dataLoaded` | 数据加载完成时触发 | `data: any[]` |
203
-| `loadingStateChanged` | 加载状态变化时触发 | `loading: boolean` |
204
-| `error` | 发生错误时触发 | `error: any` |
205
-
206
-## 公共API方法
207
-
208
-| 方法 | 描述 | 参数 |
209
-|------|------|------|
210
-| `reloadData()` | 重新加载数据 | 无 |
211
-| `loadData()` | 加载数据 | 无 |
212
-| `setFilters(filters)` | 设置筛选器 | `filters: Array<{field, type, value}>` |
213
-| `setSort(sorters)` | 设置排序 | `sorters: Array<{field, dir}>` |
214
-| `getData()` | 获取当前数据 | 无 |
215
-| `getSelectedData()` | 获取选中的数据 | 无 |
216
-| `getCurrentPage()` | 获取当前页码 | 无 |
217
-| `setPage(page)` | 跳转到指定页码 | `page: number` |
218
-| `getTotalPages()` | 获取总页数 | 无 |
219
-
220
-## 后端API要求
221
-
222
-组件期望后端API支持以下格式:
223
-
224
-### 请求格式
225
-```json
226
-{
227
-  "page": 1,
228
-  "size": 20,
229
-  "sorters": [
230
-    { "field": "field_name", "dir": "asc" }
231
-  ],
232
-  "filters": [
233
-    { "field": "config_name", "type": "like", "value": "search" }
234
-  ]
235
-}
236
-```
237
-
238
-### 响应格式
239
-```json
240
-{
241
-  "last_page": 5,
242
-  "data": [
243
-    { "id": 1, "config_name": "database", "field_name": "host", "field_type": "string" }
244
-  ],
245
-  "total": 100
246
-}
247
-```
248
-
249
-## 适配现有后端API
250
-
251
-如果后端API格式不同,可以使用 `requestMapper` 和 `responseMapper` 进行适配:
252
-
253
-```typescript
254
-dataSource = {
255
-  url: '/api/config/meta/list',
256
-  requestMapper: (params) => {
257
-    // 转换为后端需要的格式
258
-    return {
259
-      page: params.page,
260
-      pageSize: params.size,
261
-      sortField: params.sorters[0]?.field,
262
-      sortOrder: params.sorters[0]?.dir,
263
-      filters: params.filters
264
-    };
265
-  },
266
-  responseMapper: (response) => {
267
-    // 转换为Tabulator需要的格式
268
-    return {
269
-      last_page: Math.ceil(response.totalCount / response.pageSize),
270
-      data: response.data,
271
-      total: response.totalCount
272
-    };
273
-  }
274
-};
275
-```
276
-
277
-## 样式定制
278
-
279
-组件提供了一些CSS类用于样式定制:
280
-
281
-```css
282
-/* 紧凑模式 */
283
-.tabulator-grid-compact .tabulator-grid-wrapper { /* ... */ }
284
-
285
-/* 边框模式 */
286
-.tabulator-grid-bordered .tabulator-grid-wrapper { /* ... */ }
287
-
288
-/* 深色主题适配 */
289
-:host-context(.dark-theme) .tabulator-grid-wrapper { /* ... */ }
290
-```
291
-
292
-## 响应式设计
293
-
294
-组件在不同屏幕尺寸下自动适配:
295
-- 在大屏幕上显示完整分页控件
296
-- 在移动设备上简化分页布局
297
-- 自动调整列宽和布局
298
-
299
-## 常见问题
300
-
301
-### 1. 表格不显示数据?
302
-- 检查API地址是否正确
303
-- 检查网络请求是否成功
304
-- 查看浏览器控制台错误信息
305
-- 确认后端API返回正确的格式
306
-
307
-### 2. 排序/筛选不工作?
308
-- 确认后端API支持排序和筛选
309
-- 检查字段映射是否正确
310
-- 查看请求参数格式
311
-
312
-### 3. 样式不正确?
313
-- 确认已导入Tabulator的CSS文件
314
-- 检查主题名称是否正确
315
-- 查看是否有CSS冲突
316
-
317
-### 4. 如何自定义列样式?
318
-- 在列定义中使用 `cssClass` 属性
319
-- 使用Tabulator原生的格式化器
320
-- 通过CSS选择器覆盖样式
321
-
322
-## 示例:配置元数据表格
323
-
324
-这是一个完整的配置元数据表格示例:
325
-
326
-```typescript
327
-import { Component } from '@angular/core';
328
-import { TabulatorGridComponent, TabulatorGridColumn } from 'base-core';
329
-
330
-@Component({
331
-  selector: 'app-config-meta-grid',
332
-  template: `
333
-    <lib-tabulator-grid
334
-      [dataSource]="dataSource"
335
-      [columns]="columns"
336
-      [pageSize]="15"
337
-      [config]="config"
338
-      theme="bootstrap5"
339
-      (rowClicked)="onRowClick($event)">
340
-    </lib-tabulator-grid>
341
-  `,
342
-  imports: [TabulatorGridComponent]
343
-})
344
-export class ConfigMetaGridComponent {
345
-  columns: TabulatorGridColumn[] = [
346
-    { title: 'ID', field: 'id', width: 80, sorter: 'number' },
347
-    { title: '配置名称', field: 'configName', width: 150, sorter: 'string', headerFilter: true },
348
-    { title: '字段名', field: 'fieldName', width: 150, sorter: 'string', headerFilter: true },
349
-    { title: '字段类型', field: 'fieldType', width: 120, sorter: 'string', headerFilter: 'select' },
350
-    { title: 'YAML标签', field: 'yamlName', width: 150, sorter: 'string', headerFilter: true },
351
-    { title: '字段描述', field: 'fieldDesc', width: 200, formatter: 'textarea' },
352
-    { title: '创建者', field: 'creator', width: 120, sorter: 'string' },
353
-    { title: '创建时间', field: 'createdAt', width: 180, sorter: 'date', formatter: 'datetime' }
354
-  ];
355
-
356
-  dataSource = {
357
-    url: '/api/tabulator/config/meta/list',
358
-    method: 'POST'
359
-  };
360
-
361
-  config = {
362
-    height: 'calc(100vh - 200px)',
363
-    layout: 'fitData',
364
-    fieldMapping: {
365
-      'configName': 'config_name',
366
-      'fieldName': 'field_name',
367
-      'fieldType': 'field_type',
368
-      'yamlName': 'yaml_name',
369
-      'fieldDesc': 'field_desc',
370
-      'createdAt': 'created_at'
371
-    }
372
-  };
373
-
374
-  onRowClick(event: any) {
375
-    console.log('选中行:', event.row);
376
-    // 可以在这里打开详情对话框等
377
-  }
378
-}
379
-```
380
-
381
-## 支持的后端框架
382
-
383
-组件已与以下后端框架集成:
384
-
385
-1. **Go (svc-configure)** - 使用 `TabulatorRequest` 和 `CreateTabulatorResponse`
386
-2. **Node.js/Express** - 参考请求/响应格式
387
-3. **Java/Spring Boot** - 参考请求/响应格式
388
-4. **Python/Django/Flask** - 参考请求/响应格式
389
-
390
-具体集成代码请参考项目中的 `svc-configure` 服务实现。

+ 0
- 1
projects/base-core/src/lib/components/tabulator-grid/index.ts Zobrazit soubor

@@ -1 +0,0 @@
1
-export * from './tabulator-grid.component';

+ 1
- 25
projects/base-core/src/lib/components/tabulator-grid/tabulator-grid.component.html Zobrazit soubor

@@ -1,25 +1 @@
1
-<div class="tabulator-grid-wrapper">
2
-  <!-- 加载状态指示器 -->
3
-  <div class="tabulator-grid-loading" *ngIf="isDataLoading">
4
-    <div class="loading-spinner">
5
-      <div class="spinner"></div>
6
-      <div class="loading-text">{{ loadingText }}</div>
7
-    </div>
8
-  </div>
9
-
10
-  <!-- 表格容器 -->
11
-  <div #tableContainer class="tabulator-grid-container"></div>
12
-
13
-  <!-- 空状态提示 -->
14
-  <div class="tabulator-grid-empty" *ngIf="!isDataLoading && (dataCount === 0)">
15
-    <div class="empty-icon">
16
-      <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
17
-        <path d="M3 3h18v18H3zM9 9h6M9 13h6M9 17h4"/>
18
-      </svg>
19
-    </div>
20
-    <div class="empty-text">
21
-      <h3>暂无数据</h3>
22
-      <p>当前表格没有数据,请检查数据源或筛选条件</p>
23
-    </div>
24
-  </div>
25
-</div>
1
+<div [id]="containerId" class="tabulator-grid-container"></div>

+ 5
- 303
projects/base-core/src/lib/components/tabulator-grid/tabulator-grid.component.scss Zobrazit soubor

@@ -1,307 +1,9 @@
1
-@use 'sass:math';
2
-
3
-.tabulator-grid-wrapper {
4
-  position: relative;
1
+.tabulator-grid-container {
5 2
   width: 100%;
6 3
   height: 100%;
7
-  min-height: 300px;
8
-
9
-  .tabulator-grid-loading {
10
-    position: absolute;
11
-    top: 0;
12
-    left: 0;
13
-    right: 0;
14
-    bottom: 0;
15
-    background: rgba(255, 255, 255, 0.8);
16
-    z-index: 1000;
17
-    display: flex;
18
-    align-items: center;
19
-    justify-content: center;
20
-    backdrop-filter: blur(2px);
21
-
22
-    .loading-spinner {
23
-      text-align: center;
24
-      padding: 2rem;
25
-      background: white;
26
-      border-radius: 8px;
27
-      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
28
-
29
-      .spinner {
30
-        width: 40px;
31
-        height: 40px;
32
-        border: 3px solid #f3f3f3;
33
-        border-top: 3px solid #3498db;
34
-        border-radius: 50%;
35
-        animation: spin 1s linear infinite;
36
-        margin: 0 auto 1rem;
37
-      }
38
-
39
-      .loading-text {
40
-        color: #666;
41
-        font-size: 0.875rem;
42
-      }
43
-    }
44
-  }
45
-
46
-  .tabulator-grid-container {
47
-    width: 100%;
48
-    height: 100%;
49
-    min-height: 300px;
50
-
51
-    // 覆盖Tabulator默认样式
52
-    .tabulator {
53
-      border: 1px solid #dee2e6;
54
-      border-radius: 4px;
55
-      overflow: hidden;
56
-
57
-      // 表头样式
58
-      .tabulator-header {
59
-        background-color: #f8f9fa;
60
-        border-bottom: 1px solid #dee2e6;
61
-
62
-        .tabulator-col {
63
-          background-color: transparent;
64
-          border-right: 1px solid #dee2e6;
65
-          font-weight: 600;
66
-          color: #495057;
67
-
68
-          &:hover {
69
-            background-color: #e9ecef;
70
-          }
71
-
72
-          .tabulator-col-content {
73
-            padding: 0.75rem 0.5rem;
74
-          }
75
-        }
76
-      }
77
-
78
-      // 表体样式
79
-      .tabulator-tableholder {
80
-        background-color: white;
81
-
82
-        .tabulator-table {
83
-          .tabulator-row {
84
-            border-bottom: 1px solid #dee2e6;
85
-
86
-            &:hover {
87
-              background-color: #f8f9fa;
88
-            }
89
-
90
-            &.tabulator-selected {
91
-              background-color: #e3f2fd;
92
-            }
93
-
94
-            .tabulator-cell {
95
-              padding: 0.5rem;
96
-              border-right: 1px solid #dee2e6;
97
-              color: #212529;
98
-
99
-              &:last-child {
100
-                border-right: none;
101
-              }
102
-            }
103
-          }
104
-        }
105
-      }
106
-
107
-      // 分页样式
108
-      .tabulator-footer {
109
-        background-color: #f8f9fa;
110
-        border-top: 1px solid #dee2e6;
111
-        padding: 0.5rem;
112
-
113
-        .tabulator-paginator {
114
-          display: flex;
115
-          align-items: center;
116
-          justify-content: space-between;
117
-          gap: 1rem;
118
-
119
-          .tabulator-page-size {
120
-            select {
121
-              padding: 0.25rem 0.5rem;
122
-              border: 1px solid #ced4da;
123
-              border-radius: 4px;
124
-              background-color: white;
125
-              color: #495057;
126
-            }
127
-          }
128
-
129
-          .tabulator-pages {
130
-            display: flex;
131
-            align-items: center;
132
-            gap: 0.25rem;
133
-
134
-            .tabulator-page {
135
-              min-width: 2rem;
136
-              height: 2rem;
137
-              display: flex;
138
-              align-items: center;
139
-              justify-content: center;
140
-              border: 1px solid #ced4da;
141
-              border-radius: 4px;
142
-              background-color: white;
143
-              color: #495057;
144
-              cursor: pointer;
145
-              font-size: 0.875rem;
146
-
147
-              &:hover:not(.disabled):not(.active) {
148
-                background-color: #e9ecef;
149
-                border-color: #adb5bd;
150
-              }
151
-
152
-              &.active {
153
-                background-color: #007bff;
154
-                border-color: #007bff;
155
-                color: white;
156
-              }
157
-
158
-              &.disabled {
159
-                opacity: 0.5;
160
-                cursor: not-allowed;
161
-              }
162
-            }
163
-          }
164
-        }
165
-      }
166
-    }
167
-  }
168
-
169
-  .tabulator-grid-empty {
170
-    position: absolute;
171
-    top: 50%;
172
-    left: 50%;
173
-    transform: translate(-50%, -50%);
174
-    text-align: center;
175
-    padding: 3rem;
176
-    max-width: 400px;
177
-    color: #6c757d;
178
-
179
-    .empty-icon {
180
-      margin-bottom: 1.5rem;
181
-
182
-      svg {
183
-        color: #adb5bd;
184
-        margin: 0 auto;
185
-      }
186
-    }
187
-
188
-    .empty-text {
189
-      h3 {
190
-        font-size: 1.25rem;
191
-        font-weight: 600;
192
-        margin-bottom: 0.5rem;
193
-        color: #495057;
194
-      }
195
-
196
-      p {
197
-        font-size: 0.875rem;
198
-        line-height: 1.5;
199
-        margin: 0;
200
-      }
201
-    }
202
-  }
203
-}
204
-
205
-// 主题适配
206
-:host-context(.dark-theme) {
207
-  .tabulator-grid-wrapper {
208
-    .tabulator-grid-loading {
209
-      background: rgba(0, 0, 0, 0.7);
210
-
211
-      .loading-spinner {
212
-        background: #2d3748;
213
-        color: #e2e8f0;
214
-
215
-        .spinner {
216
-          border-color: #4a5568;
217
-          border-top-color: #63b3ed;
218
-        }
219
-
220
-        .loading-text {
221
-          color: #a0aec0;
222
-        }
223
-      }
224
-    }
225
-
226
-    .tabulator-grid-empty {
227
-      color: #a0aec0;
228
-
229
-      .empty-icon svg {
230
-        color: #718096;
231
-      }
232
-
233
-      .empty-text h3 {
234
-        color: #e2e8f0;
235
-      }
236
-    }
237
-  }
238
-}
239
-
240
-// 响应式设计
241
-@media (max-width: 768px) {
242
-  .tabulator-grid-wrapper {
243
-    .tabulator-grid-container {
244
-      .tabulator {
245
-        .tabulator-footer {
246
-          .tabulator-paginator {
247
-            flex-direction: column;
248
-            align-items: stretch;
249
-            gap: 0.75rem;
250
-
251
-            .tabulator-pages {
252
-              justify-content: center;
253
-            }
254
-          }
255
-        }
256
-      }
257
-    }
258
-  }
259
-}
260
-
261
-// 动画
262
-@keyframes spin {
263
-  0% { transform: rotate(0deg); }
264
-  100% { transform: rotate(360deg); }
265
-}
266
-
267
-// 工具类
268
-.tabulator-grid-compact {
269
-  .tabulator-grid-wrapper {
270
-    .tabulator-grid-container {
271
-      .tabulator {
272
-        .tabulator-header {
273
-          .tabulator-col {
274
-            .tabulator-col-content {
275
-              padding: 0.5rem 0.25rem;
276
-            }
277
-          }
278
-        }
279
-
280
-        .tabulator-table {
281
-          .tabulator-row {
282
-            .tabulator-cell {
283
-              padding: 0.375rem;
284
-            }
285
-          }
286
-        }
287
-      }
288
-    }
289
-  }
290
-}
291
-
292
-.tabulator-grid-bordered {
293
-  .tabulator-grid-wrapper {
294
-    .tabulator-grid-container {
295
-      .tabulator {
296
-        border: 1px solid #dee2e6;
297
-        border-radius: 8px;
298
-
299
-        .tabulator-header,
300
-        .tabulator-tableholder,
301
-        .tabulator-footer {
302
-          border: none;
303
-        }
304
-      }
305
-    }
4
+  
5
+  // 确保 Tabulator 表格正确显示
6
+  :deep(.tabulator) {
7
+    font-family: inherit;
306 8
   }
307 9
 }

+ 0
- 73
projects/base-core/src/lib/components/tabulator-grid/tabulator-grid.component.spec.ts Zobrazit soubor

@@ -1,73 +0,0 @@
1
-import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-import { TabulatorGridComponent } from './tabulator-grid.component';
3
-import { provideHttpClientTesting } from '@angular/common/http/testing';
4
-import { provideHttpClient } from '@angular/common/http';
5
-
6
-describe('TabulatorGridComponent', () => {
7
-  let component: TabulatorGridComponent;
8
-  let fixture: ComponentFixture<TabulatorGridComponent>;
9
-
10
-  beforeEach(async () => {
11
-    await TestBed.configureTestingModule({
12
-      imports: [TabulatorGridComponent],
13
-      providers: [
14
-        provideHttpClient(),
15
-        provideHttpClientTesting()
16
-      ]
17
-    }).compileComponents();
18
-
19
-    fixture = TestBed.createComponent(TabulatorGridComponent);
20
-    component = fixture.componentInstance;
21
-    fixture.detectChanges();
22
-  });
23
-
24
-  it('should create', () => {
25
-    expect(component).toBeTruthy();
26
-  });
27
-
28
-  it('should have default properties', () => {
29
-    expect(component.pageSize).toBe(10);
30
-    expect(component.theme).toBe('bootstrap4');
31
-    expect(component.showHeaderFilters).toBe(true);
32
-    expect(component.autoLoad).toBe(true);
33
-    expect(component.loadingText).toBe('加载中...');
34
-    expect(component.columns).toEqual([]);
35
-    expect(component.config).toEqual({});
36
-  });
37
-
38
-  it('should emit loading state changes', () => {
39
-    let loadingState = false;
40
-    component.loadingStateChanged.subscribe(state => {
41
-      loadingState = state;
42
-    });
43
-
44
-    // Note: We can't directly test the private setLoading method
45
-    // This is more of an integration test
46
-    expect(loadingState).toBe(false);
47
-  });
48
-
49
-  it('should handle data source as string', () => {
50
-    component.dataSource = '/api/test';
51
-    expect(component).toBeTruthy();
52
-  });
53
-
54
-  it('should handle data source as object', () => {
55
-    component.dataSource = {
56
-      url: '/api/test',
57
-      method: 'GET'
58
-    };
59
-    expect(component).toBeTruthy();
60
-  });
61
-
62
-  it('should have public API methods', () => {
63
-    expect(component.reloadData).toBeDefined();
64
-    expect(component.setFilters).toBeDefined();
65
-    expect(component.setSort).toBeDefined();
66
-    expect(component.getData).toBeDefined();
67
-    expect(component.getSelectedData).toBeDefined();
68
-    expect(component.loadData).toBeDefined();
69
-    expect(component.getCurrentPage).toBeDefined();
70
-    expect(component.setPage).toBeDefined();
71
-    expect(component.getTotalPages).toBeDefined();
72
-  });
73
-});

+ 378
- 566
projects/base-core/src/lib/components/tabulator-grid/tabulator-grid.component.ts
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1
- 1
projects/base-core/src/lib/services/config.service.ts Zobrazit soubor

@@ -5,7 +5,7 @@ import { Injectable } from '@angular/core';
5 5
 })
6 6
 export class ConfigService {
7 7
    private _useMockData = true; // 默认使用模拟数据,便于开发测试
8
-  private _apiBaseUrl = '/api'; // 默认API基础URL,通过代理转发
8
+   private _apiBaseUrl = '/api'; // 通过代理连接到后端API
9 9
 
10 10
   get useMockData(): boolean {
11 11
     return this._useMockData;

Loading…
Zrušit
Uložit