@teselagen/ui 0.9.6 → 0.9.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 (61) hide show
  1. package/DataTable/EditabelCell.d.ts +7 -0
  2. package/DataTable/ReactTable.d.ts +78 -0
  3. package/DataTable/defaultProps.d.ts +43 -0
  4. package/DataTable/index.d.ts +3 -3
  5. package/DataTable/utils/computePresets.d.ts +1 -0
  6. package/DataTable/utils/types/Entity.d.ts +9 -0
  7. package/DataTable/utils/types/Field.d.ts +4 -0
  8. package/DataTable/utils/types/OrderBy.d.ts +11 -0
  9. package/DataTable/utils/types/Schema.d.ts +4 -0
  10. package/DataTable/utils/useDeepEqualMemo.d.ts +1 -0
  11. package/DataTable/utils/useHotKeysWrapper.d.ts +29 -0
  12. package/DataTable/utils/useTableParams.d.ts +49 -0
  13. package/index.cjs.js +22410 -22287
  14. package/index.es.js +22462 -22339
  15. package/package.json +1 -2
  16. package/src/DataTable/Columns.jsx +945 -0
  17. package/src/DataTable/EditabelCell.js +44 -0
  18. package/src/DataTable/EditabelCell.jsx +44 -0
  19. package/src/DataTable/PagingTool.js +2 -2
  20. package/src/DataTable/ReactTable.js +738 -0
  21. package/src/DataTable/RenderCell.jsx +191 -0
  22. package/src/DataTable/defaultProps.js +45 -0
  23. package/src/DataTable/index.js +217 -1203
  24. package/src/DataTable/utils/computePresets.js +42 -0
  25. package/src/DataTable/utils/convertSchema.ts +79 -0
  26. package/src/DataTable/utils/formatPasteData.ts +34 -0
  27. package/src/DataTable/utils/getAllRows.ts +11 -0
  28. package/src/DataTable/utils/getCellCopyText.ts +7 -0
  29. package/src/DataTable/utils/getCellInfo.ts +46 -0
  30. package/src/DataTable/utils/getFieldPathToField.ts +10 -0
  31. package/src/DataTable/utils/getIdOrCodeOrIndex.ts +14 -0
  32. package/src/DataTable/utils/getLastSelectedEntity.ts +15 -0
  33. package/src/DataTable/utils/getNewEntToSelect.ts +32 -0
  34. package/src/DataTable/utils/initializeHasuraWhereAndFilter.ts +35 -0
  35. package/src/DataTable/utils/isBottomRightCornerOfRectangle.ts +27 -0
  36. package/src/DataTable/utils/isEntityClean.ts +15 -0
  37. package/src/DataTable/utils/primarySelectedValue.ts +1 -0
  38. package/src/DataTable/utils/removeCleanRows.ts +26 -0
  39. package/src/DataTable/utils/selection.ts +11 -0
  40. package/src/DataTable/utils/types/Entity.ts +13 -0
  41. package/src/DataTable/utils/types/Field.ts +4 -0
  42. package/src/DataTable/utils/types/OrderBy.ts +15 -0
  43. package/src/DataTable/utils/types/Schema.ts +5 -0
  44. package/src/DataTable/utils/useDeepEqualMemo.js +10 -0
  45. package/src/DataTable/utils/useHotKeysWrapper.js +395 -0
  46. package/src/DataTable/utils/useTableEntities.ts +60 -0
  47. package/src/DataTable/utils/useTableParams.js +361 -0
  48. package/src/DataTable/utils/utils.ts +39 -0
  49. package/src/DataTable/utils/withTableParams.js +1 -1
  50. package/src/Timeline/TimelineEvent.tsx +36 -0
  51. package/src/Timeline/index.tsx +21 -0
  52. package/src/utils/browserUtils.ts +3 -0
  53. package/src/utils/determineBlackOrWhiteTextColor.ts +11 -0
  54. package/src/utils/getTextFromEl.ts +45 -0
  55. package/src/utils/handlerHelpers.ts +32 -0
  56. package/src/utils/hooks/index.ts +1 -0
  57. package/src/utils/hooks/useDeepEqualMemo.ts +10 -0
  58. package/src/utils/hooks/useStableReference.ts +9 -0
  59. package/src/utils/hotkeyUtils.tsx +155 -0
  60. package/src/utils/isBeingCalledExcessively.ts +37 -0
  61. package/style.css +10537 -0
@@ -0,0 +1,42 @@
1
+ import { omitBy, isNil } from "lodash-es";
2
+ //we use this to make adding preset prop groups simpler
3
+ export default function computePresets(props = {}) {
4
+ const { isSimple } = props;
5
+ let toReturn = omitBy(props, isNil);
6
+ toReturn.pageSize = toReturn.controlled_pageSize || toReturn.pageSize;
7
+ if (isSimple) {
8
+ //isSimplePreset
9
+ toReturn = {
10
+ noHeader: true,
11
+ noFooter: !props.withPaging,
12
+ noPadding: true,
13
+ noFullscreenButton: true,
14
+ hidePageSizeWhenPossible: !props.withPaging,
15
+ isInfinite: !props.withPaging,
16
+ hideSelectedCount: true,
17
+ withTitle: false,
18
+ withSearch: false,
19
+ compact: true,
20
+ withPaging: false,
21
+ withFilter: false,
22
+ ...toReturn
23
+ };
24
+ } else {
25
+ toReturn = {
26
+ // the usual defaults:
27
+ noFooter: false,
28
+ noPadding: false,
29
+ compact: true,
30
+ noFullscreenButton: false,
31
+ hidePageSizeWhenPossible: false,
32
+ isInfinite: false,
33
+ hideSelectedCount: false,
34
+ withTitle: true,
35
+ withSearch: true,
36
+ withPaging: true,
37
+ withFilter: true,
38
+ ...toReturn
39
+ };
40
+ }
41
+ return toReturn || {};
42
+ }
@@ -0,0 +1,79 @@
1
+ import { camelCase } from "lodash-es";
2
+ import { startCase, keyBy, map } from "lodash-es";
3
+
4
+ type Field = {
5
+ type?: string;
6
+ displayName?: string;
7
+ path?: string;
8
+ filterDisabled?: boolean;
9
+ sortDisabled?: boolean;
10
+ };
11
+
12
+ type Schema = { fields: (Field | string)[] };
13
+
14
+ type CompleteField = Field & {
15
+ type: string;
16
+ displayName: string;
17
+ path: string;
18
+ };
19
+
20
+ type CompleteSchema = {
21
+ fields: CompleteField[];
22
+ };
23
+
24
+ const convertSchema = (schema: Schema): CompleteSchema => {
25
+ let schemaToUse = schema;
26
+ if (!schemaToUse.fields && Array.isArray(schema)) {
27
+ schemaToUse = {
28
+ fields: schema
29
+ };
30
+ }
31
+ schemaToUse = {
32
+ ...schemaToUse
33
+ };
34
+ schemaToUse.fields = schemaToUse.fields.map((field, i) => {
35
+ if (typeof field === "string") {
36
+ return {
37
+ displayName: startCase(camelCase(field)),
38
+ path: field,
39
+ type: "string"
40
+ };
41
+ } else {
42
+ const fieldToUse = { ...(field as Field) };
43
+ fieldToUse.type = fieldToUse.type || "string";
44
+ fieldToUse.displayName =
45
+ fieldToUse.displayName || startCase(camelCase(fieldToUse.path || ""));
46
+ // paths are needed for column resizing
47
+ if (!fieldToUse.path) {
48
+ fieldToUse.filterDisabled = true;
49
+ fieldToUse.sortDisabled = true;
50
+ fieldToUse.path = "fake-path" + i;
51
+ }
52
+ return fieldToUse as CompleteField;
53
+ }
54
+ });
55
+ return schemaToUse as CompleteSchema;
56
+ };
57
+
58
+ export function mergeSchemas(_originalSchema: Schema, _overrideSchema: Schema) {
59
+ const originalSchema = convertSchema(_originalSchema);
60
+ const overrideSchema = convertSchema(_overrideSchema);
61
+
62
+ const overridesByKey = keyBy(overrideSchema.fields, "path");
63
+ return {
64
+ ...originalSchema,
65
+ ...overrideSchema,
66
+ fields: originalSchema.fields
67
+ .map(f => {
68
+ const override = overridesByKey[f.path];
69
+ if (override) {
70
+ delete overridesByKey[f.path];
71
+ return override;
72
+ }
73
+ return f;
74
+ })
75
+ .concat(map(overridesByKey))
76
+ };
77
+ }
78
+
79
+ export default convertSchema;
@@ -0,0 +1,34 @@
1
+ import { getFieldPathToField } from "./getFieldPathToField";
2
+ import type { Schema } from "./types/Schema";
3
+
4
+ type GenericSelectValue = {
5
+ __strVal: string;
6
+ __genSelCol: string;
7
+ };
8
+
9
+ export const formatPasteData = ({
10
+ schema,
11
+ newVal,
12
+ path
13
+ }: {
14
+ schema: Schema;
15
+ newVal: GenericSelectValue | string | number | boolean | null | undefined;
16
+ path: string;
17
+ }) => {
18
+ const pathToField = getFieldPathToField(schema);
19
+ const column = pathToField[path];
20
+ if (column.type === "genericSelect") {
21
+ const value = newVal as GenericSelectValue;
22
+ if (value.__genSelCol === path) {
23
+ newVal = value.__strVal;
24
+ } else {
25
+ newVal = undefined;
26
+ }
27
+ } else {
28
+ newVal =
29
+ typeof newVal === "object" && newVal !== null && "__strVal" in newVal
30
+ ? newVal.__strVal
31
+ : newVal;
32
+ }
33
+ return newVal;
34
+ };
@@ -0,0 +1,11 @@
1
+ import type { RefObject } from "react";
2
+
3
+ export const getAllRows = (
4
+ tableRef: RefObject<{ tableRef: HTMLDivElement }>
5
+ ) => {
6
+ const allRowEls = tableRef.current?.tableRef?.querySelectorAll(".rt-tr");
7
+ if (!allRowEls || !allRowEls.length) {
8
+ return;
9
+ }
10
+ return allRowEls;
11
+ };
@@ -0,0 +1,7 @@
1
+ export const getCellCopyText = (cellWrapper: HTMLElement | null) => {
2
+ const text = cellWrapper?.getAttribute("data-copy-text");
3
+ const jsonText = cellWrapper?.getAttribute("data-copy-json");
4
+
5
+ const textContent = text || cellWrapper?.textContent || "";
6
+ return [textContent, jsonText];
7
+ };
@@ -0,0 +1,46 @@
1
+ import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
2
+ import { Entity } from "./types/Entity";
3
+
4
+ export const getCellInfo = <T extends Entity>({
5
+ columnIndex,
6
+ columnPath,
7
+ rowId,
8
+ schema,
9
+ entities,
10
+ rowIndex,
11
+ isEntityDisabled,
12
+ entity
13
+ }: {
14
+ columnIndex: number;
15
+ columnPath: string;
16
+ rowId: string | number;
17
+ schema: { fields: { path: string }[] };
18
+ entities: T[];
19
+ rowIndex: number;
20
+ isEntityDisabled: (entity: T) => boolean;
21
+ entity: T;
22
+ }) => {
23
+ const leftpath = schema.fields[columnIndex - 1]?.path;
24
+ const rightpath = schema.fields[columnIndex + 1]?.path;
25
+ const cellIdToLeft = leftpath && `${rowId}:${leftpath}`;
26
+ const cellIdToRight = rightpath && `${rowId}:${rightpath}`;
27
+ const rowAboveId =
28
+ entities[rowIndex - 1] &&
29
+ getIdOrCodeOrIndex(entities[rowIndex - 1], rowIndex - 1);
30
+ const rowBelowId =
31
+ entities[rowIndex + 1] &&
32
+ getIdOrCodeOrIndex(entities[rowIndex + 1], rowIndex + 1);
33
+ const cellIdAbove = rowAboveId && `${rowAboveId}:${columnPath}`;
34
+ const cellIdBelow = rowBelowId && `${rowBelowId}:${columnPath}`;
35
+
36
+ const cellId = `${rowId}:${columnPath}`;
37
+ const rowDisabled = isEntityDisabled(entity);
38
+ return {
39
+ cellId,
40
+ cellIdAbove,
41
+ cellIdToRight,
42
+ cellIdBelow,
43
+ cellIdToLeft,
44
+ rowDisabled
45
+ };
46
+ };
@@ -0,0 +1,10 @@
1
+ import { Field } from "./types/Field";
2
+ import { Schema } from "./types/Schema";
3
+
4
+ export const getFieldPathToField = (schema: Schema) => {
5
+ const fieldPathToField: { [path: string]: Field } = {};
6
+ schema.fields.forEach(f => {
7
+ fieldPathToField[f.path] = f;
8
+ });
9
+ return fieldPathToField;
10
+ };
@@ -0,0 +1,14 @@
1
+ import type { Entity } from "./types/Entity";
2
+
3
+ export const getIdOrCodeOrIndex = (record: Entity, rowIndex?: number) => {
4
+ if ("id" in record && (record.id || record.id === 0)) {
5
+ return record.id;
6
+ } else if ("code" in record && record.code) {
7
+ return record.code;
8
+ } else {
9
+ if (rowIndex === undefined || rowIndex === null) {
10
+ throw new Error("id, code, or rowIndex must be provided");
11
+ }
12
+ return rowIndex;
13
+ }
14
+ };
@@ -0,0 +1,15 @@
1
+ import { Entity } from "./types/Entity";
2
+
3
+ export const getLastSelectedEntity = (idMap: {
4
+ [id: string]: { time: number; entity: Entity };
5
+ }) => {
6
+ let lastSelectedEnt;
7
+ let latestTime: number | null = null;
8
+ Object.values(idMap).forEach(({ time, entity }) => {
9
+ if (!latestTime || time > latestTime) {
10
+ lastSelectedEnt = entity;
11
+ latestTime = time;
12
+ }
13
+ });
14
+ return lastSelectedEnt;
15
+ };
@@ -0,0 +1,32 @@
1
+ import { Entity } from "./types/Entity";
2
+
3
+ export const getNewEntToSelect = ({
4
+ type,
5
+ lastSelectedIndex,
6
+ entities,
7
+ isEntityDisabled
8
+ }: {
9
+ type: "up" | "down";
10
+ lastSelectedIndex: number;
11
+ entities: Entity[];
12
+ isEntityDisabled?: (entity: Entity) => boolean;
13
+ }): Entity | undefined => {
14
+ let newIndexToSelect;
15
+ if (type === "up") {
16
+ newIndexToSelect = lastSelectedIndex - 1;
17
+ } else {
18
+ newIndexToSelect = lastSelectedIndex + 1;
19
+ }
20
+ const newEntToSelect = entities[newIndexToSelect];
21
+ if (!newEntToSelect) return;
22
+ if (isEntityDisabled && isEntityDisabled(newEntToSelect)) {
23
+ return getNewEntToSelect({
24
+ type,
25
+ lastSelectedIndex: newIndexToSelect,
26
+ entities,
27
+ isEntityDisabled
28
+ }) as Entity;
29
+ } else {
30
+ return newEntToSelect;
31
+ }
32
+ };
@@ -0,0 +1,35 @@
1
+ type Filter = {
2
+ [key: string]:
3
+ | { _eq: string | number | boolean }
4
+ | { _in: (string | number | boolean)[] }
5
+ | { _gt: number }
6
+ | { _lt: number }
7
+ | { _gte: number }
8
+ | { _lte: number };
9
+ };
10
+ type Where = { _and?: Filter[]; _or?: Filter[] };
11
+ type CurrentParams = object;
12
+
13
+ export function initializeHasuraWhereAndFilter(
14
+ additionalFilter:
15
+ | ((where: Where, currentParams: CurrentParams) => Filter | void)
16
+ | Filter
17
+ | undefined
18
+ | null,
19
+ where: Where = {},
20
+ currentParams: CurrentParams
21
+ ) {
22
+ where._and = where._and || [];
23
+ where._or = where._or || [];
24
+ if (typeof additionalFilter === "function") {
25
+ const newWhere = additionalFilter(where, currentParams);
26
+ if (newWhere) {
27
+ Object.assign(where, newWhere);
28
+ }
29
+ } else if (
30
+ typeof additionalFilter === "object" &&
31
+ additionalFilter !== null
32
+ ) {
33
+ where._and.push(additionalFilter);
34
+ }
35
+ }
@@ -0,0 +1,27 @@
1
+ export const isBottomRightCornerOfRectangle = ({
2
+ cellId,
3
+ selectionGrid,
4
+ lastRowIndex,
5
+ lastCellIndex,
6
+ entityMap,
7
+ pathToIndex
8
+ }: {
9
+ cellId: string;
10
+ selectionGrid: (string | undefined)[][];
11
+ lastRowIndex: number;
12
+ lastCellIndex: number;
13
+ entityMap: Record<string, { i: number }>;
14
+ pathToIndex: Record<string, number>;
15
+ }) => {
16
+ selectionGrid.forEach(row => {
17
+ // remove undefineds from start of row
18
+ while (row[0] === undefined && row.length) row.shift();
19
+ });
20
+ const [rowId, cellPath] = cellId.split(":");
21
+ const ent = entityMap[rowId];
22
+ if (!ent) return;
23
+ const { i } = ent;
24
+ const cellIndex = pathToIndex[cellPath];
25
+ const isBottomRight = i === lastRowIndex && cellIndex === lastCellIndex;
26
+ return isBottomRight;
27
+ };
@@ -0,0 +1,15 @@
1
+ export function isEntityClean(e: { [key: string]: unknown } | null): boolean {
2
+ if (typeof e !== "object" || e === null) {
3
+ return true; // or return false depending on what you want for non-object inputs
4
+ }
5
+ let isClean = true;
6
+ for (const [key, val] of Object.entries(e)) {
7
+ if (key === "id") continue;
8
+ if (key === "_isClean") continue;
9
+ if (val) {
10
+ isClean = false;
11
+ break;
12
+ }
13
+ }
14
+ return isClean;
15
+ }
@@ -0,0 +1 @@
1
+ export const PRIMARY_SELECTED_VAL = "main_cell";
@@ -0,0 +1,26 @@
1
+ import { isEntityClean } from "./isEntityClean";
2
+ import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
3
+ import { Entity } from "./types/Entity";
4
+
5
+ export const removeCleanRows = (
6
+ entities: Entity[],
7
+ cellValidation: Record<string, unknown>
8
+ ) => {
9
+ const toFilterOut: Record<string, boolean> = {};
10
+ const entsToUse = (entities || []).filter(e => {
11
+ if (!(e._isClean || isEntityClean(e))) return true;
12
+ else {
13
+ toFilterOut[getIdOrCodeOrIndex(e)] = true;
14
+ return false;
15
+ }
16
+ });
17
+
18
+ const validationToUse: Record<string, unknown> = {};
19
+ Object.entries(cellValidation || {}).forEach(([k, v]) => {
20
+ const [rowId] = k.split(":");
21
+ if (!toFilterOut[rowId]) {
22
+ validationToUse[k] = v;
23
+ }
24
+ });
25
+ return { entsToUse, validationToUse };
26
+ };
@@ -0,0 +1,11 @@
1
+ import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
2
+
3
+ export const getSelectedRowsFromEntities = (
4
+ entities: { [key: string]: unknown }[],
5
+ idMap: Record<string, boolean>
6
+ ) => {
7
+ if (!idMap) return [];
8
+ return entities.reduce((acc: number[], entity, i) => {
9
+ return idMap[getIdOrCodeOrIndex(entity, i)] ? acc.concat([i]) : acc;
10
+ }, []);
11
+ };
@@ -0,0 +1,13 @@
1
+ type SharedFields = {
2
+ _isClean?: boolean;
3
+ };
4
+
5
+ export type Entity = (
6
+ | {
7
+ id?: string | number;
8
+ }
9
+ | {
10
+ code?: string;
11
+ }
12
+ ) &
13
+ SharedFields;
@@ -0,0 +1,4 @@
1
+ export type Field = {
2
+ path: string;
3
+ type: "genericSelect" | string;
4
+ };
@@ -0,0 +1,15 @@
1
+ type OrderByClause<T = { id: string }> = {
2
+ path?: string;
3
+ direction?: "asc" | "desc";
4
+ type?: string;
5
+ sortFn?:
6
+ | ((record: T) => unknown)
7
+ | string
8
+ | Array<((record: T) => unknown) | string>;
9
+ getValueToFilterOn?: (record: T) => unknown;
10
+ };
11
+
12
+ export type OrderBy =
13
+ | OrderByClause
14
+ | OrderByClause[]
15
+ | Record<string, "asc" | "desc">;
@@ -0,0 +1,5 @@
1
+ import { Field } from "./Field";
2
+
3
+ export type Schema = {
4
+ fields: Field[];
5
+ };
@@ -0,0 +1,10 @@
1
+ import { isEqual } from "lodash-es";
2
+ import { useRef } from "react";
3
+
4
+ export const useDeepEqualMemo = value => {
5
+ const ref = useRef();
6
+ if (!isEqual(value, ref.current)) {
7
+ ref.current = value;
8
+ }
9
+ return ref.current;
10
+ };