|
372 | 372 | import { useHelpers, useOrderBy } from "../../composables/utils";
|
373 | 373 | import useUUID from "../../composables/uuid";
|
374 | 374 |
|
375 |
| - export interface iTableProps<Ti extends Record<string, any>> extends iUseThemeProps { |
| 375 | + type tPropertyOrderFn = (a: [string, any], b: [string, any]) => -1 | 0 | 1; |
| 376 | +
|
| 377 | + interface iPropertyMeta extends iSelectOption { |
| 378 | + value: string; |
| 379 | + canSort: boolean; |
| 380 | + } |
| 381 | +
|
| 382 | + interface iTableProps<Ti extends Record<string, any>> extends iUseThemeProps { |
376 | 383 | /**
|
377 | 384 | * Table nodes
|
378 | 385 | * an array of nodes
|
|
387 | 394 | * @old columns
|
388 | 395 | */
|
389 | 396 | properties?: iProperty<Ti>[];
|
| 397 | + propertyOrder?: tPropertyOrderFn; |
390 | 398 | /**
|
391 | 399 | * read only table
|
392 | 400 | * @old editable(inverse)
|
|
504 | 512 | );
|
505 | 513 | });
|
506 | 514 |
|
507 |
| - interface iPropertyMeta extends iSelectOption { |
508 |
| - value: string; |
509 |
| - canSort: boolean; |
510 |
| - } |
511 |
| -
|
512 | 515 | /**
|
513 | 516 | * This one assumes all objects within nodes are all the same
|
514 | 517 | */
|
515 | 518 | const propertiesMeta = computed<iPropertyMeta[]>(() => {
|
516 | 519 | return Object.entries(props.nodes[0])
|
517 |
| - .sort(([a], [b]) => { |
518 |
| - // updatedAt, updatedBy, createdAt and createdBy to last position |
519 |
| - if (a.endsWith("At") || a.endsWith("By") || b.endsWith("At") || b.endsWith("By")) { |
520 |
| - if (a.endsWith("At") || a.endsWith("By")) return 1; |
521 |
| -
|
522 |
| - return -1; |
523 |
| - } else if (a > b) return 1; |
524 |
| - else if (a < b) return -1; |
525 |
| -
|
526 |
| - return 0; |
527 |
| - }) |
| 520 | + .sort(props.propertyOrder || defaultOrderProperty) |
528 | 521 | .map(([key, value]): iPropertyMeta => {
|
529 | 522 | const options = (props.properties || []).map(toOption);
|
530 | 523 | const property = toOption(options.find((p) => p.value === key) || key);
|
531 | 524 | const aliasKey = _.snakeCase(key);
|
532 |
| - const canSort = ["string", "number", "boolean"].includes(typeof value); |
533 | 525 |
|
534 | 526 | return {
|
535 | 527 | ...property,
|
536 | 528 | value: String(property.value),
|
537 | 529 | alias: _.capitalize(_.startCase(property.alias || tet(aliasKey))),
|
538 |
| - canSort: !!props.canSort && canSort, |
| 530 | + canSort: !!props.canSort && isPlainValue(value), |
539 | 531 | };
|
540 | 532 | })
|
541 | 533 | .filter((property) => property.value !== "id");
|
|
549 | 541 | return `table_${seed.replaceAll(" ", "") || randomId}`;
|
550 | 542 | });
|
551 | 543 |
|
| 544 | + const defaultOrderProperty: tPropertyOrderFn = ([a, aValue], [b, bValue]) => { |
| 545 | + const isDateOrAuthor = (k: string) => k.endsWith("At") || k.endsWith("By"); |
| 546 | +
|
| 547 | + // Move dates or authors backwards |
| 548 | + if (isDateOrAuthor(a) || isDateOrAuthor(b)) { |
| 549 | + // Respect whatever order they had |
| 550 | + if (isDateOrAuthor(a) && isDateOrAuthor(b)) return 0; |
| 551 | +
|
| 552 | + return isDateOrAuthor(a) ? 1 : -1; |
| 553 | + } |
| 554 | + // Move strings forward |
| 555 | + else if (isPlainValue(aValue) || isPlainValue(bValue)) { |
| 556 | + // Respect whatever order they had |
| 557 | + if (isPlainValue(aValue) && isPlainValue(bValue)) return 0; |
| 558 | +
|
| 559 | + return isPlainValue(aValue) ? -1 : 1; |
| 560 | + } |
| 561 | +
|
| 562 | + // Respect whatever order they had |
| 563 | + return 0; |
| 564 | + }; |
| 565 | +
|
| 566 | + function isPlainValue(value: any) { |
| 567 | + return ["string", "number", "boolean"].includes(typeof value); |
| 568 | + } |
552 | 569 | function reFillNodes(length: number): [boolean, boolean][] {
|
553 | 570 | return Array.from({ length }, () => [false, !!props.childrenVisibility]);
|
554 | 571 | }
|
|
0 commit comments