ts-glitter 13.3.4 → 13.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-blog.js +2 -7
  4. package/lowcode/backend-manager/bg-blog.ts +8 -13
  5. package/lowcode/backend-manager/bg-customer-message.js +4 -2
  6. package/lowcode/backend-manager/bg-customer-message.ts +4 -2
  7. package/lowcode/backend-manager/bg-graph-api.js +6 -11
  8. package/lowcode/backend-manager/bg-graph-api.ts +14 -20
  9. package/lowcode/backend-manager/bg-line.js +526 -1002
  10. package/lowcode/backend-manager/bg-line.ts +1815 -2354
  11. package/lowcode/backend-manager/bg-notify.js +392 -746
  12. package/lowcode/backend-manager/bg-notify.ts +436 -835
  13. package/lowcode/backend-manager/bg-project.js +176 -293
  14. package/lowcode/backend-manager/bg-project.ts +214 -344
  15. package/lowcode/backend-manager/bg-recommend.js +39 -148
  16. package/lowcode/backend-manager/bg-recommend.ts +43 -162
  17. package/lowcode/backend-manager/bg-sns.js +489 -814
  18. package/lowcode/backend-manager/bg-sns.ts +1876 -2238
  19. package/lowcode/backend-manager/bg-widget.js +301 -171
  20. package/lowcode/backend-manager/bg-widget.ts +324 -193
  21. package/lowcode/cms-plugin/ai-points.js +84 -67
  22. package/lowcode/cms-plugin/ai-points.ts +280 -247
  23. package/lowcode/cms-plugin/auto-reply.js +6 -7
  24. package/lowcode/cms-plugin/auto-reply.ts +6 -7
  25. package/lowcode/cms-plugin/data-analyze.js +5 -6
  26. package/lowcode/cms-plugin/data-analyze.ts +5 -6
  27. package/lowcode/cms-plugin/form-setting.js +122 -220
  28. package/lowcode/cms-plugin/form-setting.ts +124 -240
  29. package/lowcode/cms-plugin/line-auto-reply.js +17 -18
  30. package/lowcode/cms-plugin/line-auto-reply.ts +29 -36
  31. package/lowcode/cms-plugin/member-group-list.js +5 -2
  32. package/lowcode/cms-plugin/member-group-list.ts +5 -2
  33. package/lowcode/cms-plugin/member-type-list.js +36 -84
  34. package/lowcode/cms-plugin/member-type-list.ts +39 -92
  35. package/lowcode/cms-plugin/menus-setting.js +8 -73
  36. package/lowcode/cms-plugin/menus-setting.ts +8 -78
  37. package/lowcode/cms-plugin/permission-setting.js +73 -106
  38. package/lowcode/cms-plugin/permission-setting.ts +236 -278
  39. package/lowcode/cms-plugin/shopping-collections.js +95 -137
  40. package/lowcode/cms-plugin/shopping-collections.ts +103 -147
  41. package/lowcode/cms-plugin/shopping-discount-setting.js +310 -416
  42. package/lowcode/cms-plugin/shopping-discount-setting.ts +1269 -1386
  43. package/lowcode/cms-plugin/shopping-finance-setting.js +1 -0
  44. package/lowcode/cms-plugin/shopping-finance-setting.ts +1 -0
  45. package/lowcode/cms-plugin/shopping-order-manager.js +742 -973
  46. package/lowcode/cms-plugin/shopping-order-manager.ts +1928 -2164
  47. package/lowcode/cms-plugin/shopping-order-return.js +147 -267
  48. package/lowcode/cms-plugin/shopping-order-return.ts +154 -292
  49. package/lowcode/cms-plugin/shopping-product-setting.js +6 -2
  50. package/lowcode/cms-plugin/shopping-product-setting.ts +8 -4
  51. package/lowcode/cms-plugin/shopping-product-stock.js +12 -92
  52. package/lowcode/cms-plugin/shopping-product-stock.ts +14 -94
  53. package/lowcode/cms-plugin/shopping-product-text.js +0 -3
  54. package/lowcode/cms-plugin/shopping-product-text.ts +0 -3
  55. package/lowcode/cms-plugin/shopping-rebate.js +95 -151
  56. package/lowcode/cms-plugin/shopping-rebate.ts +101 -159
  57. package/lowcode/cms-plugin/sms-points.js +83 -67
  58. package/lowcode/cms-plugin/sms-points.ts +281 -241
  59. package/lowcode/cms-plugin/sns-auto-reply.js +18 -18
  60. package/lowcode/cms-plugin/sns-auto-reply.ts +34 -40
  61. package/lowcode/cms-plugin/user-list.js +71 -90
  62. package/lowcode/cms-plugin/user-list.ts +76 -95
  63. package/lowcode/cms-plugin/web-config-setting.js +61 -111
  64. package/lowcode/cms-plugin/web-config-setting.ts +65 -124
  65. package/lowcode/css/editor.css +5 -2
  66. package/lowcode/glitter-base/route/shopping.js +1 -1
  67. package/lowcode/glitter-base/route/shopping.ts +19 -19
  68. package/lowcode/jspage/editor.js +1 -1
  69. package/lowcode/jspage/editor.ts +1 -1
  70. package/lowcode/jspage/main.js +3 -0
  71. package/lowcode/jspage/main.ts +3 -0
  72. package/package.json +1 -2
  73. package/src/api-public/controllers/ai-chat.js.map +5 -1
  74. package/src/api-public/controllers/article.js.map +1 -1
  75. package/src/api-public/controllers/chat.js.map +1 -1
  76. package/src/api-public/controllers/fb-message.js.map +1 -1
  77. package/src/api-public/controllers/index.js.map +1 -1
  78. package/src/api-public/controllers/line-message.js.map +1 -1
  79. package/src/api-public/controllers/rebate.js.map +1 -1
  80. package/src/api-public/controllers/shop.js.map +1 -1
  81. package/src/api-public/controllers/user.js.map +1 -1
  82. package/src/api-public/services/auto-send-email.js.map +1 -1
  83. package/src/api-public/services/chat.js +3 -3
  84. package/src/api-public/services/chat.js.map +1 -1
  85. package/src/api-public/services/chat.ts +3 -4
  86. package/src/api-public/services/fb-message.js.map +5 -1
  87. package/src/api-public/services/filter-protect-data.js.map +1 -1
  88. package/src/api-public/services/line-message.js.map +1 -1
  89. package/src/api-public/services/monitor.js.map +1 -1
  90. package/src/api-public/services/notify.js.map +1 -1
  91. package/src/api-public/services/rebate.js.map +1 -1
  92. package/src/api-public/services/schedule.js.map +1 -1
  93. package/src/api-public/services/share-permission.js.map +1 -1
  94. package/src/api-public/services/shopping.js.map +1 -1
  95. package/src/api-public/services/user.js +67 -66
  96. package/src/api-public/services/user.js.map +1 -1
  97. package/src/api-public/services/user.ts +212 -182
  98. package/src/helper/glitter-util.js.map +1 -1
  99. package/src/modules/firebase.d.ts +1 -0
  100. package/src/modules/firebase.js +1 -1
  101. package/src/modules/firebase.js.map +1 -1
@@ -32,8 +32,6 @@ type TableV3 = {
32
32
  tableData: {
33
33
  key: string;
34
34
  value: string;
35
- width?: number;
36
- position?: string;
37
35
  }[][];
38
36
  originalData: any;
39
37
  callback: () => void;
@@ -68,8 +66,11 @@ export class BgWidget {
68
66
  static greenNote(text: string, event: string = '', style: string = ''): string {
69
67
  return html`<span style="color: #006621; font-size: 14px; font-weight: 400; cursor:pointer; overflow-wrap: break-word; text-decoration: underline; ${style}" onclick="${event}">${text}</span>`;
70
68
  }
69
+
71
70
  static dangerNote(text: string, event: string = '', style: string = ''): string {
72
- return html`<span style="color: #ef4444 !important; font-size: 14px; font-weight: 400; cursor:pointer; overflow-wrap: break-word; text-decoration: underline; ${style}" onclick="${event}">${text}</span>`;
71
+ return html`<span style="color: #ef4444 !important; font-size: 14px; font-weight: 400; cursor:pointer; overflow-wrap: break-word; text-decoration: underline; ${style}" onclick="${event}"
72
+ >${text}</span
73
+ >`;
73
74
  }
74
75
 
75
76
  static taiwanPhoneAlert(str: string = '請輸入正確的市話或手機號碼格式') {
@@ -286,6 +287,18 @@ export class BgWidget {
286
287
  </div>`;
287
288
  }
288
289
 
290
+ static aiChatButton(obj: { gvc: GVC; select: 'writer' | 'order_analysis' | 'operation_guide'; title: string }) {
291
+ return html`<div
292
+ class="bt_orange_lin"
293
+ onclick="${obj.gvc.event(() => {
294
+ (window.parent as any).glitter.share.ai_message.vm.select_bt = obj.select;
295
+ (window.parent as any).glitter.share.ai_message.toggle(true);
296
+ })}"
297
+ >
298
+ <img src="https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/size1440_s*px$_sas0s9s0s1sesas0_1697354801736-Glitterlogo.png" class="me-1" style="width: 24px; height: 24px;" />${obj.title}
299
+ </div>`;
300
+ }
301
+
289
302
  // 標籤
290
303
  static primaryInsignia(text: string) {
291
304
  return html` <div class="insignia insignia-primary">${text}</div>`;
@@ -328,10 +341,12 @@ export class BgWidget {
328
341
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
329
342
  return emailRegex.test(email);
330
343
  }
344
+
331
345
  static isValidNumbers(str: string) {
332
346
  const numberRegex = /^\d+$/;
333
347
  return numberRegex.test(str);
334
348
  }
349
+
335
350
  static editeInput(obj: {
336
351
  gvc: GVC;
337
352
  title: string;
@@ -402,11 +417,17 @@ ${obj.default ?? ''}</textarea
402
417
  </div>`;
403
418
  }
404
419
 
405
- static searchPlace(event: string, vale: string, placeholder: string, margin: string = '16px 0 0 0') {
406
- return html` <div class="w-100 position-relative" style="margin: ${margin};">
407
- <i class=" fa-regular fa-magnifying-glass" style="font-size: 18px;color: #A0A0A0;position: absolute;left:20px;top:50%;transform: translateY(-50%);" aria-hidden="true"></i>
408
- <input class="form-control h-100 " style="border-radius: 10px; border: 1px solid #DDD; padding-left: 50px;" placeholder="${placeholder}" onchange="${event}" value="${vale}" />
409
- </div>`;
420
+ static searchPlace(event: string, vale: string, placeholder: string, margin?: string, padding?: string) {
421
+ const defMargin = document.body.clientWidth > 768 ? '16px 0' : '8px 0';
422
+ const defPadding = document.body.clientWidth > 768 ? '0 16px' : '0';
423
+ return html`
424
+ <div style="margin: ${margin ?? defMargin}; padding: ${padding ?? defPadding}">
425
+ <div class="w-100 position-relative">
426
+ <i class=" fa-regular fa-magnifying-glass" style="font-size: 18px;color: #A0A0A0;position: absolute;left:20px;top:50%;transform: translateY(-50%);" aria-hidden="true"></i>
427
+ <input class="form-control h-100 " style="border-radius: 10px; border: 1px solid #DDD; padding-left: 50px;" placeholder="${placeholder}" onchange="${event}" value="${vale}" />
428
+ </div>
429
+ </div>
430
+ `;
410
431
  }
411
432
 
412
433
  static linkList(obj: {
@@ -1240,27 +1261,43 @@ ${obj.default ?? ''}</textarea
1240
1261
  rowClick: (data: any, index: number) => void;
1241
1262
  filter: {
1242
1263
  name: string;
1264
+ option?: boolean;
1243
1265
  event: (data: any) => void;
1244
- option: boolean;
1245
1266
  }[];
1246
- tableMinWidth?: number;
1247
- tableMaxWidth?: number;
1248
1267
  hiddenPageSplit?: boolean;
1249
1268
  }) {
1250
1269
  const gvc = obj.gvc;
1251
1270
  const glitter = gvc.glitter;
1252
1271
  const ps = new PageSplit(gvc);
1253
- const isPhone = document.body.clientWidth < 768;
1254
- const tableMinWidth = obj.tableMinWidth ?? 800;
1255
- const maxWidth = obj.tableMaxWidth ?? 1500;
1256
- const tableMaxWidth = maxWidth > tableMinWidth ? maxWidth : tableMinWidth;
1272
+
1273
+ const widthList: number[] = [];
1274
+ let defWidth = 0;
1275
+ let fullWidth = 0;
1257
1276
 
1258
1277
  const ids = {
1259
1278
  container: glitter.getUUID(),
1260
1279
  filter: glitter.getUUID(),
1261
1280
  pencil: gvc.glitter.getUUID(),
1281
+ header: Tool.randomString(6),
1282
+ headerCell: Tool.randomString(6),
1283
+ tr: Tool.randomString(6),
1284
+ textClass: Tool.randomString(6),
1285
+ };
1286
+
1287
+ const created = {
1288
+ checkbox: false,
1289
+ header: false,
1290
+ table: false,
1262
1291
  };
1263
1292
 
1293
+ gvc.addStyle(`
1294
+ .${ids.textClass} {
1295
+ text-align: left !important;
1296
+ padding-right: 0.25rem !important;
1297
+ padding-left: 0.25rem !important;
1298
+ }
1299
+ `);
1300
+
1264
1301
  return gvc.bindView(() => {
1265
1302
  const vm: TableV3 = {
1266
1303
  loading: true,
@@ -1269,8 +1306,10 @@ ${obj.default ?? ''}</textarea
1269
1306
  tableData: [],
1270
1307
  originalData: [],
1271
1308
  callback: () => {
1272
- vm.loading = false;
1273
- gvc.notifyDataChange(ids.container);
1309
+ setTimeout(() => {
1310
+ vm.loading = false;
1311
+ gvc.notifyDataChange(ids.container);
1312
+ }, 50);
1274
1313
  },
1275
1314
  };
1276
1315
 
@@ -1284,12 +1323,8 @@ ${obj.default ?? ''}</textarea
1284
1323
  return html` <div style="text-align: center; padding: 24px; font-size: 24px; font-weight: 700;">暫無資料</div>`;
1285
1324
  }
1286
1325
 
1287
- let widthList: number[] = [];
1288
- let viewWidth = 100;
1289
- let noneWidthElement = 0;
1290
-
1291
1326
  // 表頭行爲全選按鈕
1292
- const checkAllBox = (changeView: boolean) => {
1327
+ function checkAllBox(changeView: boolean) {
1293
1328
  return EditorElem.checkBoxOnly({
1294
1329
  gvc: gvc,
1295
1330
  def: vm.originalData.every((item: any) => item.checked),
@@ -1304,128 +1339,161 @@ ${obj.default ?? ''}</textarea
1304
1339
  }
1305
1340
  });
1306
1341
  gvc.notifyDataChange(ids.filter);
1342
+ changeHeaderStyle();
1307
1343
  },
1308
1344
  stopChangeView: changeView,
1309
1345
  });
1310
- };
1346
+ }
1311
1347
 
1312
- // 判斷是否添加行爲按鈕
1313
- vm.tableData = vm.tableData.map((item, index: number) => {
1314
- if (obj.filter.length > 0) {
1315
- return [
1316
- {
1317
- key: checkAllBox(true),
1318
- value: EditorElem.checkBoxOnly({
1319
- gvc: gvc,
1320
- def: false,
1321
- callback: (result) => {
1322
- vm.originalData[index].checked = result;
1323
- gvc.notifyDataChange(ids.filter);
1324
- },
1325
- }),
1326
- width: 5,
1327
- },
1328
- ...item,
1329
- ];
1348
+ // 表頭位置設定
1349
+ function changeHeaderStyle() {
1350
+ const target = document.querySelector(`[gvc-id="${gvc.id(ids.header)}"]`) as HTMLElement;
1351
+ if (target) {
1352
+ if (vm.originalData.find((dd: any) => dd.checked)) {
1353
+ target.style.position = 'sticky';
1354
+ target.style.top = '0';
1355
+ target.style.left = '0';
1356
+ } else {
1357
+ target.style.position = 'relative';
1358
+ target.style.top = '';
1359
+ target.style.left = '';
1360
+ }
1330
1361
  }
1331
- return item;
1332
- });
1362
+ }
1333
1363
 
1334
- // 判斷表頭項目是否有設定寬度
1335
- vm.tableData[0].map((item) => {
1336
- if (item.width) {
1337
- viewWidth -= item.width;
1338
- } else {
1339
- noneWidthElement++;
1340
- }
1341
- });
1364
+ // 判斷是否添加行爲按鈕
1365
+ if (!created.checkbox) {
1366
+ vm.tableData = vm.tableData.map((item, index: number) => {
1367
+ if (obj.filter.length > 0) {
1368
+ return [
1369
+ {
1370
+ key: checkAllBox(true),
1371
+ value: EditorElem.checkBoxOnly({
1372
+ gvc: gvc,
1373
+ def: false,
1374
+ callback: (result) => {
1375
+ vm.originalData[index].checked = result;
1376
+ gvc.notifyDataChange(ids.filter);
1377
+ changeHeaderStyle();
1378
+ },
1379
+ }),
1380
+ },
1381
+ ...item,
1382
+ ];
1383
+ }
1384
+ return item;
1385
+ });
1386
+ created.checkbox = !created.checkbox;
1387
+ }
1342
1388
 
1343
- // 設定表頭項目的寬度
1344
- vm.tableData[0].map((item) => {
1345
- if (!item.width) {
1346
- item.width = viewWidth / noneWidthElement;
1347
- }
1348
- widthList.push(item.width);
1349
- });
1389
+ return html`<div style="margin-top: 4px; overflow-x: scroll; position: relative; min-height: 350px">
1390
+ <div class="w-100 h-100 bg-white top-0" style="position: absolute; z-index: ${defWidth > 0 ? 0 : 2}; display: ${defWidth > 0 ? 'none' : 'block'};"></div>
1391
+ ${gvc.bindView({
1392
+ bind: ids.header,
1393
+ view: () => {
1394
+ return gvc.bindView({
1395
+ bind: ids.filter,
1396
+ view: () => {
1397
+ // 顯示行為列
1398
+ if (vm.originalData.find((dd: any) => dd.checked)) {
1399
+ const checkedData = vm.originalData.filter((dd: any) => dd.checked);
1400
+
1401
+ // 手機版
1402
+ if (document.body.clientWidth < 768) {
1403
+ return BgWidget.selNavbar({
1404
+ checkbox: checkAllBox(false),
1405
+ count: checkedData.length,
1406
+ buttonList: [
1407
+ BgWidget.selEventDropmenu({
1408
+ gvc: gvc,
1409
+ options: obj.filter.map((item) => {
1410
+ return {
1411
+ name: item.name,
1412
+ event: gvc.event(() => item.event(checkedData)),
1413
+ };
1414
+ }),
1415
+ text: '',
1416
+ }),
1417
+ ],
1418
+ });
1419
+ }
1350
1420
 
1351
- return html`<div style="margin-top: 4px; overflow-x: scroll; z-index: 1;">
1352
- ${gvc.bindView(() => {
1353
- // 表頭&行爲列
1354
- return {
1355
- bind: ids.filter,
1356
- view: () => {
1357
- // 顯示行為列
1358
- if (vm.originalData.find((dd: any) => dd.checked)) {
1359
- const checkedData = vm.originalData.filter((dd: any) => dd.checked);
1360
-
1361
- // 手機版
1362
- if (isPhone) {
1421
+ // 電腦版
1422
+ const inButtons = obj.filter.filter((item) => item.option);
1423
+ const outButtons = obj.filter.filter((item) => !item.option);
1424
+ const inList =
1425
+ inButtons.length > 0
1426
+ ? [
1427
+ BgWidget.selEventDropmenu({
1428
+ gvc: gvc,
1429
+ options: inButtons.map((item) => {
1430
+ return {
1431
+ name: item.name,
1432
+ event: gvc.event(() => item.event(checkedData)),
1433
+ };
1434
+ }),
1435
+ text: '更多操作',
1436
+ }),
1437
+ ]
1438
+ : [];
1439
+ const outList = outButtons.map((item) => {
1440
+ return BgWidget.selEventButton(
1441
+ item.name,
1442
+ gvc.event(() => item.event(checkedData))
1443
+ );
1444
+ });
1363
1445
  return BgWidget.selNavbar({
1364
1446
  checkbox: checkAllBox(false),
1365
1447
  count: checkedData.length,
1366
- buttonList: [
1367
- BgWidget.selEventDropmenu({
1368
- gvc: gvc,
1369
- options: obj.filter.map((item) => {
1370
- return {
1371
- name: item.name,
1372
- event: gvc.event(() => item.event(checkedData)),
1373
- };
1374
- }),
1375
- text: '',
1376
- }),
1377
- ],
1448
+ buttonList: [...inList, ...outList],
1378
1449
  });
1379
1450
  }
1380
-
1381
- // 電腦版
1382
- const inButtons = obj.filter.filter((item) => item.option);
1383
- const outButtons = obj.filter.filter((item) => !item.option);
1384
- const inList =
1385
- inButtons.length > 0
1386
- ? [
1387
- BgWidget.selEventDropmenu({
1388
- gvc: gvc,
1389
- options: inButtons.map((item) => {
1390
- return {
1391
- name: item.name,
1392
- event: gvc.event(() => item.event(checkedData)),
1393
- };
1394
- }),
1395
- text: '更多操作',
1396
- }),
1397
- ]
1398
- : [];
1399
- const outList = outButtons.map((item) => {
1400
- return BgWidget.selEventButton(
1401
- item.name,
1402
- gvc.event(() => item.event(checkedData))
1403
- );
1404
- });
1405
- return BgWidget.selNavbar({
1406
- checkbox: checkAllBox(false),
1407
- count: checkedData.length,
1408
- buttonList: [...inList, ...outList],
1409
- });
1410
- }
1411
- // 顯示表頭
1412
- return vm.tableData[0]
1413
- .map((dd, index: number) => {
1414
- return html` <th class="text-start tx_700 px-1" style="width: ${widthList[index]}%;">${dd.key}</th>`;
1415
- })
1416
- .join('');
1417
- },
1418
- divCreate: {
1419
- class: 'd-flex align-items-center mb-2',
1420
- style: `position: relative; height: 40px !important; ${isPhone ? `min-width: ${tableMinWidth}px; max-width: ${tableMaxWidth}px;` : ''}`,
1421
- },
1422
- };
1451
+ // 顯示表頭
1452
+ return vm.tableData[0]
1453
+ .map((dd, index: number) => {
1454
+ return html` <div class="${ids.headerCell} ${ids.textClass} tx_700" style="min-width: ${widthList[index]}px;">${dd.key}</div>`;
1455
+ })
1456
+ .join('');
1457
+ },
1458
+ divCreate: {
1459
+ class: `d-flex align-items-center mb-2 ${ids.header}`,
1460
+ style: `height: 40px !important;`,
1461
+ },
1462
+ onCreate: () => {
1463
+ if (!created.header) {
1464
+ let timer = 0;
1465
+ const si = setInterval(() => {
1466
+ timer++;
1467
+ const header = document.querySelector(`.${ids.header}`) as HTMLElement;
1468
+ if (!created.header && header && header.offsetWidth > 0) {
1469
+ let n = 0;
1470
+ const htmlTags = new RegExp(/<[^>]*>/);
1471
+ header?.querySelectorAll('div').forEach((div: any) => {
1472
+ if (div.classList.contains(ids.headerCell)) {
1473
+ const baseWidth = htmlTags.test(div.innerHTML) ? 0 : div.innerHTML.length * 24;
1474
+ widthList[n] = div.offsetWidth > baseWidth ? div.offsetWidth : baseWidth;
1475
+ n++;
1476
+ }
1477
+ });
1478
+ fullWidth = header.offsetWidth;
1479
+ created.header = !created.header;
1480
+ clearInterval(si);
1481
+ }
1482
+ if (timer > 500) {
1483
+ clearInterval(si);
1484
+ }
1485
+ }, 50);
1486
+ }
1487
+ },
1488
+ });
1489
+ },
1423
1490
  })}
1424
- <table class="table table-centered table-nowrap text-center table-hover" style="${isPhone ? `min-width: ${tableMinWidth}px; max-width: ${tableMaxWidth}px;` : ''}">
1491
+ <table class="table table-centered table-nowrap text-center table-hover" style="width: ${defWidth}px;">
1425
1492
  <tbody>
1426
1493
  ${vm.tableData
1427
1494
  .map((dd, trIndex: number) => {
1428
1495
  return html` <tr
1496
+ class="${trIndex === 0 ? ids.tr : ''}"
1429
1497
  onclick="${gvc.event(() => {
1430
1498
  obj.rowClick && obj.rowClick(dd, trIndex);
1431
1499
  })}"
@@ -1438,19 +1506,22 @@ ${obj.default ?? ''}</textarea
1438
1506
  >
1439
1507
  ${dd
1440
1508
  .map((d3, tdIndex: number) => {
1509
+ const tdClass = Tool.randomString(5);
1510
+ gvc.addStyle(`
1511
+ .${tdClass} {
1512
+ border: none;
1513
+ vertical-align: middle;
1514
+ width: ${widthList[tdIndex]}px;
1515
+ ${dd.length > 1 && tdIndex === 0 ? 'border-radius: 10px 0 0 10px;' : ''}
1516
+ ${dd.length > 1 && tdIndex === dd.length - 1 ? 'border-radius: 0 10px 10px 0;' : ''}
1517
+ ${dd.length === 1 ? 'border-radius: 10px;' : ''}
1518
+ }
1519
+ `);
1441
1520
  return html` <td
1442
- class="${d3.position ?? 'text-start'} tx_normal px-1"
1443
- style="
1444
- color:#393939 !important;
1445
- border: none;
1446
- vertical-align: middle;
1447
- width: ${widthList[tdIndex]}%;
1448
- ${tdIndex === 0 ? 'border-radius: 10px 0 0 10px;' : ''}
1449
- ${tdIndex === dd.length - 1 ? 'border-radius: 0 10px 10px 0;' : ''}
1450
- "
1451
- gvc-checkbox="${obj.filter.length !== 0 && tdIndex === 0 ? `checkbox${trIndex}` : ''}"
1521
+ class="${ids.textClass} ${tdClass} tx_normal"
1522
+ ${obj.filter.length !== 0 && tdIndex === 0 ? `gvc-checkbox="checkbox${trIndex}"` : ''}
1452
1523
  >
1453
- <div class="text-nowrap">${d3.value}</div>
1524
+ <div class="text-nowrap" style="color: #393939 !important;">${d3.value}</div>
1454
1525
  </td>`;
1455
1526
  })
1456
1527
  .join('')}
@@ -1480,6 +1551,43 @@ ${obj.default ?? ''}</textarea
1480
1551
  onCreate: () => {
1481
1552
  if (vm.loading) {
1482
1553
  obj.getData(vm);
1554
+ } else {
1555
+ if (!created.table) {
1556
+ let timer = 0;
1557
+ const si = setInterval(() => {
1558
+ timer++;
1559
+ if (created.header) {
1560
+ const checkbox = obj.filter.length > 0;
1561
+ const tr = document.querySelector(`.${ids.tr}`) as HTMLElement;
1562
+
1563
+ tr?.querySelectorAll('td').forEach((td: any, index: number) => {
1564
+ if (checkbox && index === 0) {
1565
+ widthList[index] = 60;
1566
+ } else {
1567
+ widthList[index] = td.offsetWidth > widthList[index] ? td.offsetWidth : widthList[index];
1568
+ }
1569
+ defWidth += widthList[index];
1570
+ });
1571
+
1572
+ if (fullWidth > defWidth) {
1573
+ const extraWidth = (fullWidth - defWidth) / (widthList.length - (checkbox ? 1 : 0));
1574
+ widthList.map((width, index) => {
1575
+ if (!(checkbox && index === 0)) {
1576
+ widthList[index] = width + extraWidth;
1577
+ }
1578
+ });
1579
+ defWidth = fullWidth;
1580
+ }
1581
+
1582
+ created.table = !created.table;
1583
+ gvc.notifyDataChange(ids.container);
1584
+ clearInterval(si);
1585
+ }
1586
+ if (timer > 500) {
1587
+ clearInterval(si);
1588
+ }
1589
+ }, 50);
1590
+ }
1483
1591
  }
1484
1592
  },
1485
1593
  };
@@ -1846,21 +1954,26 @@ ${obj.default ?? ''}</textarea
1846
1954
  }
1847
1955
 
1848
1956
  static selNavbar(data: { checkbox?: string; count: number; buttonList: string[] }): string {
1849
- const pd = document.body.clientWidth > 768 ? this.getContainerWidth() / 60 : 12;
1957
+ const navbarStyle = `
1958
+ display: flex;
1959
+ justify-content: space-between;
1960
+ align-items: center;
1961
+ height: 40px !important;
1962
+ border-radius: 10px;
1963
+ background: linear-gradient(0deg, #f7f7f7 0%, #f7f7f7 100%), #fff;
1964
+ padding: 0 22px;
1965
+ ${document.body.clientWidth > 768 ? `width: 100%;` : `width: calc(100vw - 24px); `}
1966
+ `;
1850
1967
  return html`
1851
1968
  <div
1852
- style="display: flex;
1853
- justify-content: space-between;
1854
- align-items: center;
1855
- height: 40px !important;
1856
- border-radius: 10px;
1857
- background: linear-gradient(0deg, #f7f7f7 0%, #f7f7f7 100%), #fff;
1858
- padding: 0 ${pd}px;
1859
- ${document.body.clientWidth > 768 ? `width: 100%;` : `width: calc(100vw - 8%); position: sticky; top: 0; left: 0;`}"
1969
+ style="${navbarStyle
1970
+ .replace(/;\s+/g, ';')
1971
+ .replace(/[\r\n]/g, '')
1972
+ .trim()}"
1860
1973
  >
1861
1974
  <div style="display: flex; align-items: center; font-size: 14px; color: #393939; font-weight: 700;">
1862
1975
  ${data.checkbox ?? ''}
1863
- <span class="ms-3">已選取${data.count}項</span>
1976
+ <span style="margin-left: 24px;">已選取${data.count}項</span>
1864
1977
  </div>
1865
1978
  <div style="display: flex; justify-content: flex-end; gap: 12px;">${data.buttonList.join('')}</div>
1866
1979
  </div>
@@ -1927,7 +2040,8 @@ ${obj.default ?? ''}</textarea
1927
2040
  .join(this.horizontalLine());
1928
2041
  }
1929
2042
 
1930
- static openBoxContainer(obj: { gvc: GVC; tag: string; title: string; insideHTML: string; height?: number; autoClose?: boolean; guideClass?: string }): string {
2043
+ static openBoxContainer(obj: { gvc: GVC; tag: string; title: string; insideHTML: string; height?: number; autoClose?: boolean; guideClass?: string; openOnInit?: boolean }): string {
2044
+ const bvid = Tool.randomString(5);
1931
2045
  const text = Tool.randomString(5);
1932
2046
  const height = obj.height ?? 500;
1933
2047
  const closeHeight = 56;
@@ -1986,55 +2100,72 @@ ${obj.default ?? ''}</textarea
1986
2100
  }
1987
2101
  `);
1988
2102
 
1989
- return html` <div class="box-tag-${obj.tag} box-container-${text}">
1990
- <div
1991
- class="box-navbar-${text} ${obj.guideClass ?? ''}"
1992
- onclick="${obj.gvc.event((e) => {
1993
- if (!obj.autoClose) {
1994
- const boxes = document.querySelectorAll(`.box-tag-${obj.tag}`);
1995
- boxes.forEach((box: any) => {
1996
- const isOpening = box.classList.contains('open-box');
1997
- const isSelf = box.classList.contains(`box-container-${text}`) || box.classList.contains(`arrow-icon-${text}`);
1998
- if (isOpening && !isSelf) {
1999
- box.classList.remove('open-box');
2000
- if (box.tagName === 'DIV') {
2001
- box.style.height = `${closeHeight}px`;
2002
- }
2103
+ return obj.gvc.bindView({
2104
+ bind: bvid,
2105
+ view: () => {
2106
+ return html` <div class="box-tag-${obj.tag} box-container-${text}">
2107
+ <div
2108
+ class="box-navbar-${text} ${obj.guideClass ?? ''}"
2109
+ onclick="${obj.gvc.event((e) => {
2110
+ if (!obj.autoClose) {
2111
+ const boxes = document.querySelectorAll(`.box-tag-${obj.tag}`);
2112
+ boxes.forEach((box: any) => {
2113
+ const isOpening = box.classList.contains('open-box');
2114
+ const isSelf = box.classList.contains(`box-container-${text}`) || box.classList.contains(`arrow-icon-${text}`);
2115
+ if (isOpening && !isSelf) {
2116
+ box.classList.remove('open-box');
2117
+ if (box.tagName === 'DIV') {
2118
+ box.style.height = `${closeHeight}px`;
2119
+ }
2120
+ }
2121
+ });
2003
2122
  }
2004
- });
2005
- }
2006
-
2007
- setTimeout(() => {
2008
- e.parentElement.classList.toggle('open-box');
2009
- e.parentElement.querySelector(`.arrow-icon-${text}`).classList.toggle('open-box');
2010
2123
 
2011
- const container = window.document.querySelector(`.box-container-${text}`) as any;
2012
- if (e.parentElement.classList.contains('open-box')) {
2013
- const si = setInterval(() => {
2014
- const inside = window.document.querySelector(`.box-inside-${text}`) as any;
2015
- if (inside) {
2016
- const insideHeight = inside.clientHeight;
2017
- if (insideHeight + closeHeight < height) {
2018
- container.style.height = `${insideHeight + closeHeight + 20}px`;
2019
- } else {
2020
- container.style.height = `${height}px`;
2021
- }
2022
- clearInterval(si);
2124
+ setTimeout(() => {
2125
+ e.parentElement.classList.toggle('open-box');
2126
+ e.parentElement.querySelector(`.arrow-icon-${text}`).classList.toggle('open-box');
2127
+
2128
+ const container = window.document.querySelector(`.box-container-${text}`) as any;
2129
+ if (e.parentElement.classList.contains('open-box')) {
2130
+ const si = setInterval(() => {
2131
+ const inside = window.document.querySelector(`.box-inside-${text}`) as any;
2132
+ if (inside) {
2133
+ const insideHeight = inside.clientHeight;
2134
+ if (insideHeight + closeHeight < height) {
2135
+ container.style.height = `${insideHeight + closeHeight + 20}px`;
2136
+ } else {
2137
+ container.style.height = `${height}px`;
2138
+ }
2139
+ clearInterval(si);
2140
+ }
2141
+ }, 100);
2142
+ } else {
2143
+ container.style.height = `${closeHeight}px`;
2023
2144
  }
2024
- }, 100);
2025
- } else {
2026
- container.style.height = `${closeHeight}px`;
2145
+ }, 50);
2146
+ })}"
2147
+ >
2148
+ <div class="d-flex tx_700">${obj.title}</div>
2149
+ <div class="d-flex">
2150
+ <button class="box-tag-${obj.tag} arrow-icon-${text}"></button>
2151
+ </div>
2152
+ </div>
2153
+ <div class="box-inside-${text} ${obj.guideClass ? `box-inside-${obj.guideClass}` : ''}">${obj.insideHTML}</div>
2154
+ </div>`;
2155
+ },
2156
+ divCreate: {},
2157
+ onCreate: () => {
2158
+ if (obj.openOnInit) {
2159
+ setTimeout(() => {
2160
+ const navs = document.getElementsByClassName(`box-navbar-${text}`) as any;
2161
+ if (navs.length > 0) {
2162
+ const nav = navs[0];
2163
+ nav.click();
2027
2164
  }
2028
- }, 50);
2029
- })}"
2030
- >
2031
- <div class="d-flex tx_700">${obj.title}</div>
2032
- <div class="d-flex">
2033
- <button class="box-tag-${obj.tag} arrow-icon-${text}"></button>
2034
- </div>
2035
- </div>
2036
- <div class="box-inside-${text} ${obj.guideClass ? `box-inside-${obj.guideClass}` : ''}">${obj.insideHTML}</div>
2037
- </div>`;
2165
+ }, 100);
2166
+ }
2167
+ },
2168
+ });
2038
2169
  }
2039
2170
 
2040
2171
  // 視窗