slick-table 1.2.2 → 1.2.3

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 (153) hide show
  1. package/dist/index.cjs.js +98 -98
  2. package/dist/index.es.js +7040 -6843
  3. package/dist/styles/icons.scss +1 -1
  4. package/dist/types/entities/drawer-run-query/index.d.ts +2 -0
  5. package/dist/types/entities/drawer-run-query/index.d.ts.map +1 -0
  6. package/dist/types/entities/drawer-run-query/lib/grouping/getGroupLabel.d.ts +8 -0
  7. package/dist/types/entities/drawer-run-query/lib/grouping/getGroupLabel.d.ts.map +1 -0
  8. package/dist/types/entities/drawer-run-query/lib/grouping/groupQueriesByDate.d.ts +4 -0
  9. package/dist/types/entities/drawer-run-query/lib/grouping/groupQueriesByDate.d.ts.map +1 -0
  10. package/dist/types/entities/drawer-run-query/lib/grouping/index.d.ts +2 -0
  11. package/dist/types/entities/drawer-run-query/lib/grouping/index.d.ts.map +1 -0
  12. package/dist/types/entities/drawer-run-query/lib/hooks/index.d.ts +3 -0
  13. package/dist/types/entities/drawer-run-query/lib/hooks/index.d.ts.map +1 -0
  14. package/dist/types/entities/drawer-run-query/lib/hooks/useResizeCanvas.d.ts +2 -0
  15. package/dist/types/entities/drawer-run-query/lib/hooks/useResizeCanvas.d.ts.map +1 -0
  16. package/dist/types/entities/drawer-run-query/lib/hooks/useSubscribeToEvent.d.ts.map +1 -0
  17. package/dist/types/entities/drawer-run-query/lib/index.d.ts +4 -0
  18. package/dist/types/entities/drawer-run-query/lib/index.d.ts.map +1 -0
  19. package/dist/types/entities/drawer-run-query/lib/table/getColumsHash.d.ts +3 -0
  20. package/dist/types/entities/drawer-run-query/lib/table/getColumsHash.d.ts.map +1 -0
  21. package/dist/types/entities/drawer-run-query/lib/table/index.d.ts +3 -0
  22. package/dist/types/entities/drawer-run-query/lib/table/index.d.ts.map +1 -0
  23. package/dist/types/entities/drawer-run-query/lib/table/tableQuery.d.ts.map +1 -0
  24. package/dist/types/entities/drawer-run-query/model/consts/consts.d.ts +3 -0
  25. package/dist/types/entities/drawer-run-query/model/consts/consts.d.ts.map +1 -0
  26. package/dist/types/entities/drawer-run-query/model/consts/index.d.ts +2 -0
  27. package/dist/types/entities/drawer-run-query/model/consts/index.d.ts.map +1 -0
  28. package/dist/types/entities/drawer-run-query/model/index.d.ts +3 -0
  29. package/dist/types/entities/drawer-run-query/model/index.d.ts.map +1 -0
  30. package/dist/types/entities/drawer-run-query/model/types/IQueryGroup.d.ts +6 -0
  31. package/dist/types/entities/drawer-run-query/model/types/IQueryGroup.d.ts.map +1 -0
  32. package/dist/types/entities/drawer-run-query/model/types/index.d.ts +2 -0
  33. package/dist/types/entities/drawer-run-query/model/types/index.d.ts.map +1 -0
  34. package/dist/types/entities/drawer-run-query/ui/DrawerRunQuery.d.ts +7 -0
  35. package/dist/types/entities/drawer-run-query/ui/DrawerRunQuery.d.ts.map +1 -0
  36. package/dist/types/entities/{popup-query/ui/PopupQuery.style.d.ts → drawer-run-query/ui/DrawerRunQuery.style.d.ts} +14 -6
  37. package/dist/types/entities/drawer-run-query/ui/DrawerRunQuery.style.d.ts.map +1 -0
  38. package/dist/types/entities/drawer-run-query/ui/QueryHistory/QueryHistory.d.ts +9 -0
  39. package/dist/types/entities/drawer-run-query/ui/QueryHistory/QueryHistory.d.ts.map +1 -0
  40. package/dist/types/entities/drawer-run-query/ui/QueryHistory/QueryHistory.style.d.ts +23 -0
  41. package/dist/types/entities/drawer-run-query/ui/QueryHistory/QueryHistory.style.d.ts.map +1 -0
  42. package/dist/types/entities/drawer-run-query/ui/QueryHistory/index.d.ts +2 -0
  43. package/dist/types/entities/drawer-run-query/ui/QueryHistory/index.d.ts.map +1 -0
  44. package/dist/types/entities/drawer-run-query/ui/index.d.ts +2 -0
  45. package/dist/types/entities/drawer-run-query/ui/index.d.ts.map +1 -0
  46. package/dist/types/entities/popup-summary/ui/PopupSummary.style.d.ts +1 -1
  47. package/dist/types/features/column-filters/ui/ButtonReset/ButtonReset.style.d.ts +1 -1
  48. package/dist/types/features/context-menu/ui/ButtonQuery/ui/ButtonQuery.d.ts.map +1 -1
  49. package/dist/types/features/header-context-menu/lib/visibility/getHidableColumnIds.d.ts.map +1 -1
  50. package/dist/types/features/header-context-menu/ui/Item/Item.style.d.ts +1 -1
  51. package/dist/types/shared/lib/localStrore/model/classes/Queries.d.ts +7 -0
  52. package/dist/types/shared/lib/localStrore/model/classes/Queries.d.ts.map +1 -0
  53. package/dist/types/shared/lib/localStrore/model/classes/index.d.ts +1 -0
  54. package/dist/types/shared/lib/localStrore/model/classes/index.d.ts.map +1 -1
  55. package/dist/types/shared/lib/localStrore/model/enums/EStorageKey.d.ts +2 -1
  56. package/dist/types/shared/lib/localStrore/model/enums/EStorageKey.d.ts.map +1 -1
  57. package/dist/types/shared/lib/localStrore/model/localStore.d.ts +2 -1
  58. package/dist/types/shared/lib/localStrore/model/localStore.d.ts.map +1 -1
  59. package/dist/types/shared/lib/slickgrid/index.d.ts +1 -1
  60. package/dist/types/shared/lib/slickgrid/index.d.ts.map +1 -1
  61. package/dist/types/shared/lib/slickgrid/model/events/{eventQuery.d.ts → eventRunQuery.d.ts} +3 -5
  62. package/dist/types/shared/lib/slickgrid/model/events/eventRunQuery.d.ts.map +1 -0
  63. package/dist/types/shared/lib/slickgrid/model/events/index.d.ts +1 -1
  64. package/dist/types/shared/lib/slickgrid/model/events/index.d.ts.map +1 -1
  65. package/dist/types/shared/lib/slickgrid/model/index.d.ts +1 -1
  66. package/dist/types/shared/lib/slickgrid/model/index.d.ts.map +1 -1
  67. package/dist/types/shared/lib/slickgrid/ui/columns/columnIsEdited/ui/columnIsEdited.d.ts.map +1 -1
  68. package/dist/types/shared/model/consts/columnId.d.ts +1 -0
  69. package/dist/types/shared/model/consts/columnId.d.ts.map +1 -1
  70. package/dist/types/shared/model/consts/index.d.ts +1 -1
  71. package/dist/types/shared/model/consts/index.d.ts.map +1 -1
  72. package/dist/types/shared/model/types/IRecentQuery.d.ts +5 -0
  73. package/dist/types/shared/model/types/IRecentQuery.d.ts.map +1 -0
  74. package/dist/types/shared/model/types/index.d.ts +1 -0
  75. package/dist/types/shared/model/types/index.d.ts.map +1 -1
  76. package/package.json +1 -1
  77. package/src/app/styles/icons.scss +1 -1
  78. package/src/entities/drawer-run-query/index.ts +1 -0
  79. package/src/entities/drawer-run-query/lib/grouping/getGroupLabel.spec.ts +46 -0
  80. package/src/entities/drawer-run-query/lib/grouping/getGroupLabel.ts +26 -0
  81. package/src/entities/drawer-run-query/lib/grouping/groupQueriesByDate.spec.ts +54 -0
  82. package/src/entities/drawer-run-query/lib/grouping/groupQueriesByDate.ts +37 -0
  83. package/src/entities/drawer-run-query/lib/grouping/index.ts +1 -0
  84. package/src/entities/{popup-query → drawer-run-query}/lib/hooks/index.ts +1 -0
  85. package/src/entities/drawer-run-query/lib/hooks/useResizeCanvas.ts +13 -0
  86. package/src/entities/{popup-query → drawer-run-query}/lib/hooks/useSubscribeToEvent.ts +4 -8
  87. package/src/entities/drawer-run-query/lib/index.ts +3 -0
  88. package/src/entities/drawer-run-query/lib/table/getColumsHash.ts +18 -0
  89. package/src/entities/drawer-run-query/lib/table/index.ts +2 -0
  90. package/src/entities/{popup-query/model/consts/id.ts → drawer-run-query/model/consts/consts.ts} +2 -1
  91. package/src/entities/drawer-run-query/model/consts/index.ts +1 -0
  92. package/src/entities/drawer-run-query/model/index.ts +2 -0
  93. package/src/entities/drawer-run-query/model/types/IQueryGroup.ts +6 -0
  94. package/src/entities/drawer-run-query/model/types/index.ts +1 -0
  95. package/src/entities/{popup-query/ui/PopupQuery.style.ts → drawer-run-query/ui/DrawerRunQuery.style.ts} +43 -9
  96. package/src/entities/{popup-query/ui/PopupQuery.tsx → drawer-run-query/ui/DrawerRunQuery.tsx} +86 -51
  97. package/src/entities/drawer-run-query/ui/QueryHistory/QueryHistory.style.ts +53 -0
  98. package/src/entities/drawer-run-query/ui/QueryHistory/QueryHistory.tsx +62 -0
  99. package/src/entities/drawer-run-query/ui/QueryHistory/index.ts +1 -0
  100. package/src/entities/drawer-run-query/ui/index.ts +1 -0
  101. package/src/features/context-menu/ui/ButtonQuery/ui/ButtonQuery.tsx +3 -5
  102. package/src/features/header-context-menu/lib/visibility/getHidableColumnIds.ts +2 -1
  103. package/src/shared/lib/localStrore/model/classes/Queries.ts +40 -0
  104. package/src/shared/lib/localStrore/model/classes/index.ts +1 -0
  105. package/src/shared/lib/localStrore/model/enums/EStorageKey.ts +1 -0
  106. package/src/shared/lib/localStrore/model/localStore.ts +8 -1
  107. package/src/shared/lib/slickgrid/index.ts +1 -1
  108. package/src/shared/lib/slickgrid/model/events/{eventQuery.ts → eventRunQuery.ts} +2 -4
  109. package/src/shared/lib/slickgrid/model/events/index.ts +1 -1
  110. package/src/shared/lib/slickgrid/model/index.ts +1 -1
  111. package/src/shared/lib/slickgrid/ui/SlickgridTable/ui/SlickgridTable.tsx +2 -2
  112. package/src/shared/lib/slickgrid/ui/columns/columnIsEdited/ui/columnIsEdited.ts +3 -2
  113. package/src/shared/model/consts/columnId.ts +1 -0
  114. package/src/shared/model/consts/index.ts +1 -1
  115. package/src/shared/model/types/IRecentQuery.ts +4 -0
  116. package/src/shared/model/types/index.ts +1 -0
  117. package/dist/types/entities/popup-query/index.d.ts +0 -2
  118. package/dist/types/entities/popup-query/index.d.ts.map +0 -1
  119. package/dist/types/entities/popup-query/lib/hooks/index.d.ts +0 -2
  120. package/dist/types/entities/popup-query/lib/hooks/index.d.ts.map +0 -1
  121. package/dist/types/entities/popup-query/lib/hooks/useSubscribeToEvent.d.ts.map +0 -1
  122. package/dist/types/entities/popup-query/lib/index.d.ts +0 -3
  123. package/dist/types/entities/popup-query/lib/index.d.ts.map +0 -1
  124. package/dist/types/entities/popup-query/lib/table/index.d.ts +0 -2
  125. package/dist/types/entities/popup-query/lib/table/index.d.ts.map +0 -1
  126. package/dist/types/entities/popup-query/lib/table/tableQuery.d.ts.map +0 -1
  127. package/dist/types/entities/popup-query/model/consts/id.d.ts +0 -2
  128. package/dist/types/entities/popup-query/model/consts/id.d.ts.map +0 -1
  129. package/dist/types/entities/popup-query/model/consts/index.d.ts +0 -2
  130. package/dist/types/entities/popup-query/model/consts/index.d.ts.map +0 -1
  131. package/dist/types/entities/popup-query/model/index.d.ts +0 -3
  132. package/dist/types/entities/popup-query/model/index.d.ts.map +0 -1
  133. package/dist/types/entities/popup-query/model/types/ITotal.d.ts +0 -10
  134. package/dist/types/entities/popup-query/model/types/ITotal.d.ts.map +0 -1
  135. package/dist/types/entities/popup-query/model/types/index.d.ts +0 -2
  136. package/dist/types/entities/popup-query/model/types/index.d.ts.map +0 -1
  137. package/dist/types/entities/popup-query/ui/PopupQuery.d.ts +0 -7
  138. package/dist/types/entities/popup-query/ui/PopupQuery.d.ts.map +0 -1
  139. package/dist/types/entities/popup-query/ui/PopupQuery.style.d.ts.map +0 -1
  140. package/dist/types/entities/popup-query/ui/index.d.ts +0 -2
  141. package/dist/types/entities/popup-query/ui/index.d.ts.map +0 -1
  142. package/dist/types/shared/lib/slickgrid/model/events/eventQuery.d.ts.map +0 -1
  143. package/src/entities/popup-query/index.ts +0 -1
  144. package/src/entities/popup-query/lib/index.ts +0 -2
  145. package/src/entities/popup-query/lib/table/index.ts +0 -1
  146. package/src/entities/popup-query/model/consts/index.ts +0 -1
  147. package/src/entities/popup-query/model/index.ts +0 -2
  148. package/src/entities/popup-query/model/types/ITotal.ts +0 -23
  149. package/src/entities/popup-query/model/types/index.ts +0 -1
  150. package/src/entities/popup-query/ui/index.ts +0 -1
  151. /package/dist/types/entities/{popup-query → drawer-run-query}/lib/hooks/useSubscribeToEvent.d.ts +0 -0
  152. /package/dist/types/entities/{popup-query → drawer-run-query}/lib/table/tableQuery.d.ts +0 -0
  153. /package/src/entities/{popup-query → drawer-run-query}/lib/table/tableQuery.ts +0 -0
@@ -0,0 +1,46 @@
1
+ import moment from "moment";
2
+
3
+ import { getGroupLabel } from "./getGroupLabel";
4
+
5
+ const toDateString = (date: Date): string => moment(date).format("YYYY-MM-DD");
6
+
7
+ const daysAgo = (days: number): Date => moment().subtract(days, "day").toDate();
8
+
9
+ describe("pages | chat-with-ai | lib | getGroupLabel", () => {
10
+ it('returns "Today" for the current date', () => {
11
+ expect(getGroupLabel(new Date())).toBe("Today");
12
+ });
13
+
14
+ it('returns "Yesterday" for the previous calendar day', () => {
15
+ expect(getGroupLabel(daysAgo(1))).toBe("Yesterday");
16
+ });
17
+
18
+ it("returns a relative label for dates within the relative limit", () => {
19
+ expect(getGroupLabel(daysAgo(2))).toBe("2 days");
20
+ expect(getGroupLabel(daysAgo(15))).toBe("15 days");
21
+ });
22
+
23
+ it('returns "30 days" on the last day of the relative limit', () => {
24
+ expect(getGroupLabel(daysAgo(30))).toBe("30 days");
25
+ });
26
+
27
+ it("returns the formatted date for dates beyond the relative limit", () => {
28
+ const lastMonth = daysAgo(31);
29
+ const lastYear = daysAgo(365);
30
+
31
+ expect(getGroupLabel(lastMonth)).toBe(toDateString(lastMonth));
32
+ expect(getGroupLabel(lastYear)).toBe(toDateString(lastYear));
33
+ expect(getGroupLabel(lastMonth)).toMatch(/^\d{4}-\d{2}-\d{2}$/);
34
+ });
35
+
36
+ it("uses calendar days and ignores the time of day", () => {
37
+ const yesterdayEvening = daysAgo(1);
38
+ yesterdayEvening.setHours(23, 59, 59, 999);
39
+
40
+ const thirtyDaysAgoEvening = daysAgo(30);
41
+ thirtyDaysAgoEvening.setHours(23, 59, 59, 999);
42
+
43
+ expect(getGroupLabel(yesterdayEvening)).toBe("Yesterday");
44
+ expect(getGroupLabel(thirtyDaysAgoEvening)).toBe("30 days");
45
+ });
46
+ });
@@ -0,0 +1,26 @@
1
+ import moment from "moment";
2
+
3
+ import { EDateFormat } from "shared/model/enums";
4
+
5
+ const RELATIVE_DAY_LIMIT = 30;
6
+
7
+ /**
8
+ * Builds a human readable label for the day a query was run on.
9
+ * The label is relative ("Today", "Yesterday", "N days") within the limit
10
+ * and an absolute date after it. Days are calendar days, the time of day
11
+ * is ignored.
12
+ * */
13
+ export const getGroupLabel = (date: Date): string => {
14
+ const value = moment(date);
15
+
16
+ if (value.isSame(moment(), "day")) return "Today";
17
+ if (value.isSame(moment().subtract(1, "day"), "day")) return "Yesterday";
18
+
19
+ const daysAgo = moment()
20
+ .startOf("day")
21
+ .diff(value.clone().startOf("day"), "days");
22
+
23
+ if (daysAgo <= RELATIVE_DAY_LIMIT) return `${daysAgo} days`;
24
+
25
+ return value.format(EDateFormat.db);
26
+ };
@@ -0,0 +1,54 @@
1
+ import moment from "moment";
2
+
3
+ import { IRecentQuery } from "shared/model/types";
4
+
5
+ import { groupQueriesByDate } from "./groupQueriesByDate";
6
+
7
+ const toTime = (daysAgo: number, time = "12:00:00"): string =>
8
+ moment().subtract(daysAgo, "day").format(`YYYY-MM-DD ${time}`);
9
+
10
+ const makeQuery = (query: string, time: string): IRecentQuery => ({
11
+ query,
12
+ time,
13
+ });
14
+
15
+ describe("pages | chat-with-ai | lib | groupConversationsByDate", () => {
16
+ it("groups conversations into today, yesterday, N days and dated buckets", () => {
17
+ const conversations = [
18
+ makeQuery("older", toTime(31)),
19
+ makeQuery("30d", toTime(30)),
20
+ makeQuery("2d", toTime(2)),
21
+ makeQuery("yesterday", toTime(1)),
22
+ makeQuery("today-late", toTime(0, "15:00:00")),
23
+ makeQuery("today-early", toTime(0, "09:00:00")),
24
+ ];
25
+
26
+ const groups = groupQueriesByDate(conversations);
27
+
28
+ expect(groups.map((group) => group.label)).toEqual([
29
+ "Today",
30
+ "Yesterday",
31
+ "2 days",
32
+ "30 days",
33
+ toTime(31).slice(0, 10),
34
+ ]);
35
+ });
36
+
37
+ it("sorts conversations within a group by time descending", () => {
38
+ const conversations = [
39
+ makeQuery("early", toTime(0, "09:00:00")),
40
+ makeQuery("late", toTime(0, "15:00:00")),
41
+ ];
42
+
43
+ const groups = groupQueriesByDate(conversations);
44
+
45
+ expect(groups[0].queries.map(({ query }) => query)).toEqual([
46
+ "late",
47
+ "early",
48
+ ]);
49
+ });
50
+
51
+ it("returns an empty array for empty input", () => {
52
+ expect(groupQueriesByDate([])).toEqual([]);
53
+ });
54
+ });
@@ -0,0 +1,37 @@
1
+ import moment from "moment";
2
+
3
+ import { dateFormats } from "shared/model/consts";
4
+ import { EDateFormat } from "shared/model/enums";
5
+ import { IRecentQuery } from "shared/model/types";
6
+
7
+ import { IQueryGroup } from "../../model";
8
+ import { getGroupLabel } from "./getGroupLabel";
9
+
10
+ export const groupQueriesByDate = (
11
+ recentQueries: IRecentQuery[],
12
+ ): IQueryGroup[] => {
13
+ const sorted = [...recentQueries].sort(
14
+ (a, b) =>
15
+ moment(b.time, dateFormats).valueOf() -
16
+ moment(a.time, dateFormats).valueOf(),
17
+ );
18
+
19
+ const groups = new Map<string, IQueryGroup>();
20
+
21
+ for (const query of sorted) {
22
+ const date = moment(query.time, dateFormats).startOf("day");
23
+ const key = date.format(EDateFormat.db);
24
+
25
+ const group = groups.get(key);
26
+ if (group) {
27
+ group.queries.push(query);
28
+ } else {
29
+ groups.set(key, {
30
+ label: getGroupLabel(date.toDate()),
31
+ queries: [query],
32
+ });
33
+ }
34
+ }
35
+
36
+ return Array.from(groups.values());
37
+ };
@@ -0,0 +1 @@
1
+ export { groupQueriesByDate } from "./groupQueriesByDate";
@@ -1 +1,2 @@
1
+ export { useResizeCanvas } from "./useResizeCanvas";
1
2
  export { useSubscribeToEvent } from "./useSubscribeToEvent";
@@ -0,0 +1,13 @@
1
+ import { useEffect } from "react";
2
+
3
+ import { TRANSITION_MS } from "../../model";
4
+ import { tableQuery } from "../table";
5
+
6
+ export function useResizeCanvas(isExpanded: boolean) {
7
+ useEffect(() => {
8
+ if (!isExpanded) return;
9
+ setTimeout(() => {
10
+ tableQuery.grid?.resizeCanvas();
11
+ }, TRANSITION_MS);
12
+ }, [isExpanded]);
13
+ }
@@ -1,6 +1,6 @@
1
1
  import { Dispatch, SetStateAction, useEffect } from "react";
2
2
 
3
- import { eventQuery } from "shared/lib/slickgrid";
3
+ import { eventRunQuery } from "shared/lib/slickgrid";
4
4
 
5
5
  export function useSubscribeToEvent(
6
6
  setIsOpened: Dispatch<SetStateAction<boolean>>,
@@ -8,17 +8,13 @@ export function useSubscribeToEvent(
8
8
  ) {
9
9
  useEffect(() => {
10
10
  function callback() {
11
- const { open, table } = eventQuery;
11
+ const { open, table } = eventRunQuery;
12
12
  if (table?.id !== tableId) return;
13
- if (open) {
14
- const table = eventQuery.table;
15
- const grid = table?.grid;
16
- }
17
13
  setIsOpened(open);
18
14
  }
19
- eventQuery.subscribe(callback);
15
+ eventRunQuery.subscribe(callback);
20
16
  return () => {
21
- eventQuery.unsubscribe(callback);
17
+ eventRunQuery.unsubscribe(callback);
22
18
  };
23
19
  }, [tableId]);
24
20
  }
@@ -0,0 +1,3 @@
1
+ export { groupQueriesByDate } from "./grouping";
2
+ export { useResizeCanvas, useSubscribeToEvent } from "./hooks";
3
+ export { tableQuery, getColumsHash } from "./table";
@@ -0,0 +1,18 @@
1
+ import { eventRunQuery } from "shared/lib/slickgrid";
2
+ import { IS_EDITED } from "shared/model/consts";
3
+ import { IColumn } from "shared/model/types";
4
+
5
+ export function getColumsHash(): Record<string, IColumn> {
6
+ const table = eventRunQuery.table;
7
+ if (!table) return {};
8
+ const grid = table.grid;
9
+ if (!grid) return {};
10
+ const columns: IColumn[] = grid.getColumns();
11
+ const result: Record<string, IColumn> = {};
12
+ for (const column of columns) {
13
+ if (column.id !== "_checkbox_selector" && column.id !== IS_EDITED) {
14
+ result[column.id] = column;
15
+ }
16
+ }
17
+ return result;
18
+ }
@@ -0,0 +1,2 @@
1
+ export { tableQuery } from "./tableQuery";
2
+ export { getColumsHash } from "./getColumsHash";
@@ -1 +1,2 @@
1
- export const QUERY_LANGUAGE = "QUERY_LANGUAGE";
1
+ export const TRANSITION_MS = 300;
2
+ export const QUERY_LANGUAGE = "QUERY_LANGUAGE";
@@ -0,0 +1 @@
1
+ export { QUERY_LANGUAGE, TRANSITION_MS } from "./consts";
@@ -0,0 +1,2 @@
1
+ export { QUERY_LANGUAGE, TRANSITION_MS } from "./consts";
2
+ export type { IQueryGroup } from "./types";
@@ -0,0 +1,6 @@
1
+ import { IRecentQuery } from "shared/model/types";
2
+
3
+ export interface IQueryGroup {
4
+ label: string;
5
+ queries: IRecentQuery[];
6
+ }
@@ -0,0 +1 @@
1
+ export type { IQueryGroup } from "./IQueryGroup";
@@ -2,6 +2,8 @@ import {
2
2
  Box,
3
3
  Button,
4
4
  Drawer,
5
+ IconButton,
6
+ InputAdornment,
5
7
  TextField,
6
8
  Typography,
7
9
  styled,
@@ -9,20 +11,31 @@ import {
9
11
 
10
12
  import { doNotForwardProps } from "shared/lib/dom";
11
13
 
12
- const StyledDrawer = styled(Drawer)({
14
+ import { TRANSITION_MS } from "../model";
15
+
16
+ const HEIGHT_EXPANDED = "90vh";
17
+ const HEIGHT_COLLAPSED_EM = 11;
18
+
19
+ const StyledDrawer = styled(Drawer, {
20
+ shouldForwardProp: doNotForwardProps(["isExpanded"]),
21
+ })<{ isExpanded: boolean }>(({ isExpanded }) => ({
13
22
  zIndex: 1300,
14
23
  "& .MuiDrawer-paper": {
15
- display: "flex",
16
- flexDirection: "column",
24
+ borderTopLeftRadius: "10px",
25
+ borderTopRightRadius: "10px",
26
+ columnGap: "1em",
27
+ display: "grid",
28
+ gridTemplateColumns: "25% 1fr",
29
+ transition: `${TRANSITION_MS / 1000}s`,
30
+ height: isExpanded ? HEIGHT_EXPANDED : `${HEIGHT_COLLAPSED_EM}em`,
17
31
  padding: "1em",
18
- maxHeight: "90vh",
19
32
  },
20
33
  "& div.MuiBackdrop-root": {
21
34
  opacity: "0 !important",
22
35
  },
23
- });
36
+ }));
24
37
 
25
- const Header = styled(Typography)({
38
+ const Header = styled(Box)({
26
39
  display: "flex",
27
40
  justifyContent: "space-between",
28
41
  });
@@ -49,6 +62,23 @@ const StyledTextField = styled(TextField)({
49
62
  },
50
63
  });
51
64
 
65
+ const EndAdornment = styled(InputAdornment)({
66
+ alignSelf: "flex-start",
67
+ marginTop: "-2px",
68
+ });
69
+
70
+ const ClearButton = styled(IconButton)({
71
+ color: "#808080",
72
+ padding: "4px",
73
+ "& .sgi": {
74
+ display: "block",
75
+ },
76
+ "&:hover": {
77
+ backgroundColor: "#E8F4FE",
78
+ color: "#235B95",
79
+ },
80
+ });
81
+
52
82
  const ContainerInput = styled(Box)({
53
83
  display: "flex",
54
84
  columnGap: "0.5em",
@@ -66,11 +96,13 @@ const ColumnName = styled("span")({
66
96
  });
67
97
 
68
98
  const ContainerTable = styled(Box, {
69
- shouldForwardProp: doNotForwardProps(["isRightScreenVisible"]),
99
+ shouldForwardProp: doNotForwardProps(["isExpanded"]),
70
100
  })<{ isExpanded: boolean }>(({ isExpanded }) => ({
71
101
  overflowY: "auto",
72
- // transition: "0.3s",
73
- height: isExpanded ? "90vh" : "0vh",
102
+ transition: `${TRANSITION_MS / 1000}s`,
103
+ height: isExpanded
104
+ ? `calc(${HEIGHT_EXPANDED} - ${HEIGHT_COLLAPSED_EM + 2}em)`
105
+ : "0vh",
74
106
  }));
75
107
 
76
108
  const StyledButton = styled(Button)({
@@ -84,10 +116,12 @@ const StyledButton = styled(Button)({
84
116
 
85
117
  export default {
86
118
  Button: StyledButton,
119
+ ClearButton,
87
120
  ColumnName,
88
121
  ContainerInput,
89
122
  ContainerTable,
90
123
  Drawer: StyledDrawer,
124
+ EndAdornment,
91
125
  Header,
92
126
  RowsNumber,
93
127
  TextField: StyledTextField,
@@ -1,47 +1,45 @@
1
- import { Box, IconButton } from "@mui/material";
1
+ import { Box, IconButton, Tooltip } from "@mui/material";
2
2
  import { GvizTable } from "myworkql";
3
3
  import { ChangeEvent, FC, MouseEvent, useRef, useState } from "react";
4
4
  import { SlickDataView } from "slickgrid";
5
5
 
6
- import { SlickgridTable, eventQuery } from "shared/lib/slickgrid";
7
- import { CHECKBOX_SELECTOR } from "shared/model/consts";
6
+ import { localStore } from "shared/lib/localStrore";
7
+ import { SlickgridTable, eventRunQuery } from "shared/lib/slickgrid";
8
8
  import { IColumn } from "shared/model/types";
9
9
 
10
- import { tableQuery, useSubscribeToEvent } from "../lib";
10
+ import {
11
+ getColumsHash,
12
+ tableQuery,
13
+ useResizeCanvas,
14
+ useSubscribeToEvent,
15
+ } from "../lib";
16
+ import { QueryHistory } from "./QueryHistory";
11
17
 
12
- import Styled from "./PopupQuery.style";
18
+ import Styled from "./DrawerRunQuery.style";
13
19
 
14
- export const PopupQuery: FC<Props> = ({ tableId }) => {
15
- const [query, setQuery] = useState(`select * where hours > 7`);
20
+ export const DrawerRunQuery: FC<Props> = ({ tableId }) => {
21
+ const [query, setQuery] = useState("");
16
22
  const [isOpened, setIsOpened] = useState(false);
17
23
  const [isExpanded, setIsExpanded] = useState(false);
18
24
  const [items, setItems] = useState<Record<string, any>[]>([]);
19
25
  const [columns, setColumns] = useState<IColumn[]>([]);
20
26
  const queryInputRef = useRef<HTMLTextAreaElement>(null);
27
+ const columnsHash = getColumsHash();
21
28
 
22
- function getColumNames(): IColumn[] {
23
- const table = eventQuery.table;
24
- if (!table) return [];
25
- const grid = table.grid;
26
- if (!grid) return [];
27
- return grid
28
- .getColumns()
29
- .filter(
30
- ({ id, name }) =>
31
- typeof name === "string" &&
32
- id !== CHECKBOX_SELECTOR &&
33
- id !== "isEdited",
34
- );
35
- }
36
-
37
- function onClose() {
38
- eventQuery.open = false;
29
+ function closeDrawer() {
30
+ eventRunQuery.open = false;
39
31
  }
40
32
 
41
33
  function updateQuery(event: ChangeEvent<HTMLTextAreaElement>) {
42
34
  setQuery(event.target.value);
43
35
  }
44
36
 
37
+ function clearQuery() {
38
+ const input = queryInputRef.current;
39
+ setQuery("");
40
+ requestAnimationFrame(() => input?.focus());
41
+ }
42
+
45
43
  function pasteColumnId(event: MouseEvent<HTMLSpanElement>) {
46
44
  const columnId = event.currentTarget.id;
47
45
  if (!columnId) return;
@@ -57,43 +55,59 @@ export const PopupQuery: FC<Props> = ({ tableId }) => {
57
55
  });
58
56
  }
59
57
 
60
- function executeQuery() {
61
- const table = eventQuery.table;
58
+ function executeQuery(query: string) {
59
+ const table = eventRunQuery.table;
62
60
  if (!table) return;
63
61
  const grid = table.grid;
64
62
  if (!grid) return;
65
63
  const dataView: SlickDataView = grid.getData();
66
64
  const items = dataView.getItems();
67
- const idPropertyName = dataView.getIdPropertyName();
68
- const itemsCopy = [...items];
69
- for (const item of itemsCopy) {
70
- delete item[idPropertyName];
65
+ const itemsCopy = [];
66
+ const fields = Object.keys(columnsHash);
67
+ for (const item of items) {
68
+ const newItem: Record<string, string | number | boolean> = {};
69
+ for (const field of fields) {
70
+ newItem[field] = item[field];
71
+ }
72
+ itemsCopy.push(newItem);
71
73
  }
72
74
  const gvizTable = new GvizTable(itemsCopy);
73
75
  const run = gvizTable.query(query);
74
76
  const newItems = run.toObjects();
75
77
  setItems(newItems);
76
78
  setColumns(
77
- Object.keys(newItems[0]).map(
79
+ Object.keys(newItems[0] || {}).map(
78
80
  (key): IColumn => ({
79
- id: key,
80
- field: key,
81
- name: key
82
- .split(" ")
83
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
84
- .join(" "),
81
+ id: columnsHash[key].id,
82
+ field: columnsHash[key].field,
83
+ name: columnsHash[key].name,
84
+ formatter: columnsHash[key].formatter,
85
+ cssClass: columnsHash[key].cssClass,
85
86
  }),
86
87
  ),
87
88
  );
88
89
  setIsExpanded(true);
90
+ localStore.queries.set(tableId, query);
89
91
  }
90
92
 
91
93
  useSubscribeToEvent(setIsOpened, tableId);
94
+ useResizeCanvas(isExpanded);
92
95
 
93
96
  if (!isOpened) return null;
94
97
 
95
98
  return (
96
- <Styled.Drawer anchor={"bottom"} open={isOpened} onClose={onClose}>
99
+ <Styled.Drawer
100
+ anchor={"bottom"}
101
+ open={isOpened}
102
+ onClose={closeDrawer}
103
+ disablePortal
104
+ isExpanded={isExpanded}
105
+ >
106
+ <QueryHistory
107
+ executeQuery={executeQuery}
108
+ query={query}
109
+ setQuery={setQuery}
110
+ />
97
111
  <Box>
98
112
  <Styled.Header>
99
113
  <Styled.Title variant={"h6"}>
@@ -110,7 +124,7 @@ export const PopupQuery: FC<Props> = ({ tableId }) => {
110
124
  <span className={"sgi sgi-arrow-expand"}></span>
111
125
  </IconButton>
112
126
  )}
113
- <IconButton onClick={onClose}>
127
+ <IconButton onClick={closeDrawer}>
114
128
  <span className={"sgi sgi-close"}></span>
115
129
  </IconButton>
116
130
  </Box>
@@ -123,14 +137,35 @@ export const PopupQuery: FC<Props> = ({ tableId }) => {
123
137
  multiline
124
138
  onChange={updateQuery}
125
139
  inputRef={queryInputRef}
140
+ slotProps={{
141
+ input: {
142
+ endAdornment: !!query && (
143
+ <Styled.EndAdornment position={"end"}>
144
+ <Tooltip title={"Clear query"}>
145
+ <Styled.ClearButton
146
+ aria-label={"Clear query"}
147
+ onClick={clearQuery}
148
+ size={"small"}
149
+ >
150
+ <span className={"sgi sgi-close"}></span>
151
+ </Styled.ClearButton>
152
+ </Tooltip>
153
+ </Styled.EndAdornment>
154
+ ),
155
+ },
156
+ }}
126
157
  value={query}
127
158
  />
128
- <Styled.Button variant={"contained"} onClick={executeQuery}>
159
+ <Styled.Button
160
+ disabled={!query.trim()}
161
+ onClick={() => executeQuery(query)}
162
+ variant={"contained"}
163
+ >
129
164
  Execute
130
165
  </Styled.Button>
131
166
  </Styled.ContainerInput>
132
167
  <Box sx={{ display: "flex", columnGap: "1em", marginBottom: "1em" }}>
133
- {getColumNames().map(({ id, name }) => (
168
+ {Object.values(columnsHash).map(({ id, name }) => (
134
169
  <Styled.ColumnName
135
170
  key={id}
136
171
  id={id as string}
@@ -140,17 +175,17 @@ export const PopupQuery: FC<Props> = ({ tableId }) => {
140
175
  </Styled.ColumnName>
141
176
  ))}
142
177
  </Box>
178
+ <Styled.ContainerTable isExpanded={isExpanded}>
179
+ {!!columns.length && (
180
+ <SlickgridTable
181
+ assignIds={true}
182
+ columns={columns}
183
+ items={items}
184
+ table={tableQuery}
185
+ />
186
+ )}
187
+ </Styled.ContainerTable>
143
188
  </Box>
144
- <Styled.ContainerTable isExpanded={isExpanded}>
145
- {!!columns.length && (
146
- <SlickgridTable
147
- assignIds={true}
148
- columns={columns}
149
- items={items}
150
- table={tableQuery}
151
- />
152
- )}
153
- </Styled.ContainerTable>
154
189
  </Styled.Drawer>
155
190
  );
156
191
  };
@@ -0,0 +1,53 @@
1
+ import styled from "@emotion/styled";
2
+ import { Box, Typography } from "@mui/material";
3
+
4
+ const Wrapper = styled(Box)({
5
+ backgroundColor: "#F8F8FA",
6
+ borderRadius: "10px",
7
+ padding: "10px",
8
+ overflowY: "auto",
9
+ });
10
+
11
+ const GroupLabel = styled(Typography)({
12
+ color: "#BBBDBF",
13
+ fontSize: "0.75rem",
14
+ fontWeight: 400,
15
+ letterSpacing: "-2%",
16
+ lineHeight: "100%",
17
+ margin: "1.5em 0 0.75em",
18
+ padding: "0 8px",
19
+ });
20
+
21
+ const Item = styled(Box)({
22
+ alignItems: "center",
23
+ borderRadius: "8px",
24
+ color: "#333333",
25
+ cursor: "pointer",
26
+ display: "flex",
27
+ justifyContent: "space-between",
28
+ marginBottom: "2px",
29
+ padding: "8px 10px",
30
+ textAlign: "left",
31
+ userSelect: "none",
32
+ width: "100%",
33
+ "&:hover": {
34
+ backgroundColor: "#E8F4FE",
35
+ },
36
+ "&.active": {
37
+ backgroundColor: "#E8F4FE",
38
+ color: "#235B95",
39
+ },
40
+ });
41
+
42
+ const Title = styled("span")({
43
+ display: "-webkit-box",
44
+ fontSize: "0.75rem",
45
+ fontWeight: 400,
46
+ letterSpacing: "-2%",
47
+ lineHeight: "100%",
48
+ overflow: "hidden",
49
+ WebkitBoxOrient: "vertical",
50
+ WebkitLineClamp: 3,
51
+ });
52
+
53
+ export default { Wrapper, GroupLabel, Item, Title };