@multiplatform.one/backoffice 7.23.2 → 7.24.0

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 (205) hide show
  1. package/dist/cjs/chrome/awesomebar-data.cjs +4 -2
  2. package/dist/cjs/chrome/awesomebar-data.native.js +7 -4
  3. package/dist/cjs/chrome/awesomebar-data.native.js.map +1 -1
  4. package/dist/cjs/chrome/help-about-dialog.cjs +2 -2
  5. package/dist/cjs/chrome/help-about-dialog.native.js +2 -2
  6. package/dist/cjs/chrome/help-shortcuts-dialog.cjs +2 -2
  7. package/dist/cjs/chrome/help-shortcuts-dialog.native.js +2 -2
  8. package/dist/cjs/chrome/notifications-panel.cjs +8 -6
  9. package/dist/cjs/chrome/notifications-panel.native.js +8 -6
  10. package/dist/cjs/chrome/notifications-panel.native.js.map +1 -1
  11. package/dist/cjs/form/DocFormScreen.cjs +43 -43
  12. package/dist/cjs/form/DocFormScreen.native.js +43 -43
  13. package/dist/cjs/form/DocFormScreen.native.js.map +1 -1
  14. package/dist/cjs/form/sidebar-people.cjs +5 -2
  15. package/dist/cjs/form/sidebar-people.native.js +5 -2
  16. package/dist/cjs/form/sidebar-people.native.js.map +1 -1
  17. package/dist/cjs/i18n/en.cjs +1 -1
  18. package/dist/cjs/i18n/en.native.js +1 -1
  19. package/dist/cjs/i18n/en.native.js.map +1 -1
  20. package/dist/cjs/list/ListBulkActionsBar.cjs +1 -1
  21. package/dist/cjs/list/ListBulkActionsBar.native.js +1 -2
  22. package/dist/cjs/list/ListBulkActionsBar.native.js.map +1 -1
  23. package/dist/cjs/shell/WorkspaceSidebar.cjs +9 -7
  24. package/dist/cjs/shell/WorkspaceSidebar.native.js +9 -7
  25. package/dist/cjs/shell/WorkspaceSidebar.native.js.map +1 -1
  26. package/dist/cjs/views/CalendarView.cjs +5 -1
  27. package/dist/cjs/views/CalendarView.native.js +7 -2
  28. package/dist/cjs/views/CalendarView.native.js.map +1 -1
  29. package/dist/cjs/views/DashboardView.cjs +9 -3
  30. package/dist/cjs/views/DashboardView.native.js +9 -3
  31. package/dist/cjs/views/DashboardView.native.js.map +1 -1
  32. package/dist/cjs/views/KanbanView.cjs +5 -2
  33. package/dist/cjs/views/KanbanView.native.js +7 -3
  34. package/dist/cjs/views/KanbanView.native.js.map +1 -1
  35. package/dist/cjs/views/ReportView.cjs +8 -5
  36. package/dist/cjs/views/ReportView.native.js +11 -6
  37. package/dist/cjs/views/ReportView.native.js.map +1 -1
  38. package/dist/cjs/views/ViewHeader.cjs +8 -1
  39. package/dist/cjs/views/ViewHeader.native.js +8 -1
  40. package/dist/cjs/views/ViewHeader.native.js.map +1 -1
  41. package/dist/cjs/views/dashboard-data.cjs +17 -11
  42. package/dist/cjs/views/dashboard-data.native.js +20 -13
  43. package/dist/cjs/views/dashboard-data.native.js.map +1 -1
  44. package/dist/esm/chrome/awesomebar-data.mjs +4 -2
  45. package/dist/esm/chrome/awesomebar-data.mjs.map +1 -1
  46. package/dist/esm/chrome/awesomebar-data.native.js +7 -4
  47. package/dist/esm/chrome/awesomebar-data.native.js.map +1 -1
  48. package/dist/esm/chrome/help-about-dialog.mjs +2 -2
  49. package/dist/esm/chrome/help-about-dialog.mjs.map +1 -1
  50. package/dist/esm/chrome/help-about-dialog.native.js +2 -2
  51. package/dist/esm/chrome/help-about-dialog.native.js.map +1 -1
  52. package/dist/esm/chrome/help-shortcuts-dialog.mjs +2 -2
  53. package/dist/esm/chrome/help-shortcuts-dialog.mjs.map +1 -1
  54. package/dist/esm/chrome/help-shortcuts-dialog.native.js +2 -2
  55. package/dist/esm/chrome/notifications-panel.mjs +8 -6
  56. package/dist/esm/chrome/notifications-panel.mjs.map +1 -1
  57. package/dist/esm/chrome/notifications-panel.native.js +8 -6
  58. package/dist/esm/chrome/notifications-panel.native.js.map +1 -1
  59. package/dist/esm/form/DocFormScreen.mjs +43 -43
  60. package/dist/esm/form/DocFormScreen.mjs.map +1 -1
  61. package/dist/esm/form/DocFormScreen.native.js +43 -43
  62. package/dist/esm/form/DocFormScreen.native.js.map +1 -1
  63. package/dist/esm/form/sidebar-people.mjs +6 -3
  64. package/dist/esm/form/sidebar-people.mjs.map +1 -1
  65. package/dist/esm/form/sidebar-people.native.js +6 -3
  66. package/dist/esm/form/sidebar-people.native.js.map +1 -1
  67. package/dist/esm/i18n/en.mjs +1 -1
  68. package/dist/esm/i18n/en.native.js +1 -1
  69. package/dist/esm/list/ListBulkActionsBar.mjs +2 -2
  70. package/dist/esm/list/ListBulkActionsBar.mjs.map +1 -1
  71. package/dist/esm/list/ListBulkActionsBar.native.js +2 -3
  72. package/dist/esm/list/ListBulkActionsBar.native.js.map +1 -1
  73. package/dist/esm/shell/WorkspaceSidebar.mjs +9 -7
  74. package/dist/esm/shell/WorkspaceSidebar.mjs.map +1 -1
  75. package/dist/esm/shell/WorkspaceSidebar.native.js +9 -7
  76. package/dist/esm/shell/WorkspaceSidebar.native.js.map +1 -1
  77. package/dist/esm/views/CalendarView.mjs +6 -2
  78. package/dist/esm/views/CalendarView.mjs.map +1 -1
  79. package/dist/esm/views/CalendarView.native.js +8 -3
  80. package/dist/esm/views/CalendarView.native.js.map +1 -1
  81. package/dist/esm/views/DashboardView.mjs +9 -3
  82. package/dist/esm/views/DashboardView.mjs.map +1 -1
  83. package/dist/esm/views/DashboardView.native.js +9 -3
  84. package/dist/esm/views/DashboardView.native.js.map +1 -1
  85. package/dist/esm/views/KanbanView.mjs +6 -3
  86. package/dist/esm/views/KanbanView.mjs.map +1 -1
  87. package/dist/esm/views/KanbanView.native.js +8 -4
  88. package/dist/esm/views/KanbanView.native.js.map +1 -1
  89. package/dist/esm/views/ReportView.mjs +8 -5
  90. package/dist/esm/views/ReportView.mjs.map +1 -1
  91. package/dist/esm/views/ReportView.native.js +11 -6
  92. package/dist/esm/views/ReportView.native.js.map +1 -1
  93. package/dist/esm/views/ViewHeader.mjs +8 -1
  94. package/dist/esm/views/ViewHeader.mjs.map +1 -1
  95. package/dist/esm/views/ViewHeader.native.js +8 -1
  96. package/dist/esm/views/ViewHeader.native.js.map +1 -1
  97. package/dist/esm/views/dashboard-data.mjs +17 -11
  98. package/dist/esm/views/dashboard-data.mjs.map +1 -1
  99. package/dist/esm/views/dashboard-data.native.js +20 -13
  100. package/dist/esm/views/dashboard-data.native.js.map +1 -1
  101. package/dist/jsx/chrome/awesomebar-data.mjs +4 -2
  102. package/dist/jsx/chrome/awesomebar-data.mjs.map +1 -1
  103. package/dist/jsx/chrome/awesomebar-data.native.js +7 -4
  104. package/dist/jsx/chrome/awesomebar-data.native.js.map +1 -1
  105. package/dist/jsx/chrome/help-about-dialog.mjs +2 -2
  106. package/dist/jsx/chrome/help-about-dialog.mjs.map +1 -1
  107. package/dist/jsx/chrome/help-about-dialog.native.js +2 -2
  108. package/dist/jsx/chrome/help-shortcuts-dialog.mjs +2 -2
  109. package/dist/jsx/chrome/help-shortcuts-dialog.mjs.map +1 -1
  110. package/dist/jsx/chrome/help-shortcuts-dialog.native.js +2 -2
  111. package/dist/jsx/chrome/help-shortcuts-dialog.native.js.map +1 -1
  112. package/dist/jsx/chrome/notifications-panel.mjs +8 -6
  113. package/dist/jsx/chrome/notifications-panel.mjs.map +1 -1
  114. package/dist/jsx/chrome/notifications-panel.native.js +8 -6
  115. package/dist/jsx/chrome/notifications-panel.native.js.map +1 -1
  116. package/dist/jsx/form/DocFormScreen.mjs +43 -43
  117. package/dist/jsx/form/DocFormScreen.mjs.map +1 -1
  118. package/dist/jsx/form/DocFormScreen.native.js +43 -43
  119. package/dist/jsx/form/DocFormScreen.native.js.map +1 -1
  120. package/dist/jsx/form/sidebar-people.mjs +6 -3
  121. package/dist/jsx/form/sidebar-people.mjs.map +1 -1
  122. package/dist/jsx/form/sidebar-people.native.js +5 -2
  123. package/dist/jsx/form/sidebar-people.native.js.map +1 -1
  124. package/dist/jsx/i18n/en.mjs +1 -1
  125. package/dist/jsx/i18n/en.native.js +1 -1
  126. package/dist/jsx/i18n/en.native.js.map +1 -1
  127. package/dist/jsx/list/ListBulkActionsBar.mjs +2 -2
  128. package/dist/jsx/list/ListBulkActionsBar.mjs.map +1 -1
  129. package/dist/jsx/list/ListBulkActionsBar.native.js +1 -2
  130. package/dist/jsx/list/ListBulkActionsBar.native.js.map +1 -1
  131. package/dist/jsx/shell/WorkspaceSidebar.mjs +9 -7
  132. package/dist/jsx/shell/WorkspaceSidebar.mjs.map +1 -1
  133. package/dist/jsx/shell/WorkspaceSidebar.native.js +9 -7
  134. package/dist/jsx/shell/WorkspaceSidebar.native.js.map +1 -1
  135. package/dist/jsx/views/CalendarView.mjs +6 -2
  136. package/dist/jsx/views/CalendarView.mjs.map +1 -1
  137. package/dist/jsx/views/CalendarView.native.js +7 -2
  138. package/dist/jsx/views/CalendarView.native.js.map +1 -1
  139. package/dist/jsx/views/DashboardView.mjs +9 -3
  140. package/dist/jsx/views/DashboardView.mjs.map +1 -1
  141. package/dist/jsx/views/DashboardView.native.js +9 -3
  142. package/dist/jsx/views/DashboardView.native.js.map +1 -1
  143. package/dist/jsx/views/KanbanView.mjs +6 -3
  144. package/dist/jsx/views/KanbanView.mjs.map +1 -1
  145. package/dist/jsx/views/KanbanView.native.js +7 -3
  146. package/dist/jsx/views/KanbanView.native.js.map +1 -1
  147. package/dist/jsx/views/ReportView.mjs +8 -5
  148. package/dist/jsx/views/ReportView.mjs.map +1 -1
  149. package/dist/jsx/views/ReportView.native.js +11 -6
  150. package/dist/jsx/views/ReportView.native.js.map +1 -1
  151. package/dist/jsx/views/ViewHeader.mjs +8 -1
  152. package/dist/jsx/views/ViewHeader.mjs.map +1 -1
  153. package/dist/jsx/views/ViewHeader.native.js +8 -1
  154. package/dist/jsx/views/ViewHeader.native.js.map +1 -1
  155. package/dist/jsx/views/dashboard-data.mjs +17 -11
  156. package/dist/jsx/views/dashboard-data.mjs.map +1 -1
  157. package/dist/jsx/views/dashboard-data.native.js +20 -13
  158. package/dist/jsx/views/dashboard-data.native.js.map +1 -1
  159. package/package.json +12 -12
  160. package/src/chrome/NotificationsButton.screen.spec.tsx +162 -0
  161. package/src/chrome/UserMenu.screen.spec.tsx +107 -0
  162. package/src/chrome/awesomebar-data.auth.spec.ts +56 -0
  163. package/src/chrome/awesomebar-data.tsx +4 -2
  164. package/src/chrome/help-about-dialog.tsx +2 -2
  165. package/src/chrome/help-shortcuts-dialog.tsx +2 -2
  166. package/src/chrome/notifications-panel.tsx +8 -9
  167. package/src/form/DocFormScreen.tsx +54 -45
  168. package/src/form/FormConnections.screen.spec.tsx +153 -0
  169. package/src/form/FormDialogs.screen.spec.tsx +119 -0
  170. package/src/form/FormToolbar.screen.spec.tsx +147 -0
  171. package/src/form/sidebar-people.tsx +7 -5
  172. package/src/i18n/en.ts +1 -1
  173. package/src/list/ListBulkActionsBar.screen.spec.tsx +181 -0
  174. package/src/list/ListBulkActionsBar.tsx +6 -2
  175. package/src/list/ListFilterBar.screen.spec.tsx +176 -0
  176. package/src/list/ListSidebar.screen.spec.tsx +202 -0
  177. package/src/quickEntry/QuickEntryDialog.screen.spec.tsx +143 -0
  178. package/src/report/DoctypeReportView.screen.spec.tsx +154 -0
  179. package/src/shell/WorkspaceSidebar.tsx +10 -9
  180. package/src/views/CalendarView.screen.spec.tsx +241 -0
  181. package/src/views/CalendarView.tsx +11 -3
  182. package/src/views/DashboardView.screen.spec.tsx +144 -0
  183. package/src/views/DashboardView.tsx +7 -3
  184. package/src/views/ImageView.screen.spec.tsx +108 -0
  185. package/src/views/KanbanView.screen.spec.tsx +282 -0
  186. package/src/views/KanbanView.tsx +7 -3
  187. package/src/views/ReportView.screen.spec.tsx +108 -0
  188. package/src/views/ReportView.tsx +10 -5
  189. package/src/views/ViewHeader.screen.spec.tsx +185 -0
  190. package/src/views/ViewHeader.tsx +4 -1
  191. package/src/views/dashboard-data.tsx +21 -12
  192. package/types/chrome/awesomebar-data.d.ts.map +1 -1
  193. package/types/chrome/notifications-panel.d.ts.map +1 -1
  194. package/types/form/DocFormScreen.d.ts.map +1 -1
  195. package/types/form/sidebar-people.d.ts.map +1 -1
  196. package/types/i18n/en.d.ts +1 -1
  197. package/types/list/ListBulkActionsBar.d.ts.map +1 -1
  198. package/types/shell/WorkspaceSidebar.d.ts.map +1 -1
  199. package/types/views/CalendarView.d.ts.map +1 -1
  200. package/types/views/DashboardView.d.ts.map +1 -1
  201. package/types/views/KanbanView.d.ts.map +1 -1
  202. package/types/views/ReportView.d.ts.map +1 -1
  203. package/types/views/ViewHeader.d.ts.map +1 -1
  204. package/types/views/dashboard-data.d.ts +4 -2
  205. package/types/views/dashboard-data.d.ts.map +1 -1
@@ -0,0 +1,108 @@
1
+ // The compatibility report view (MPO-414), still exported beside
2
+ // DoctypeReportView: it counts and totals the filtered result, opens a record
3
+ // from the footer or the grid, applies and clears the ?f= base filters, and
4
+ // ANDs the desk scope into its queries (GL-5).
5
+ import React from "react";
6
+ import { InMemoryFixtureProvider } from "@multiplatform.one/frappe";
7
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
8
+ import { fireEvent, screen, waitFor } from "@testing-library/react";
9
+ import { describe, expect, it } from "vitest";
10
+ import { BackofficeProvider } from "../config/BackofficeProvider";
11
+ import { DeskScopeProvider } from "../desk/scope";
12
+ import { createMemoryNavigator, type MemoryNavigator } from "../navigation/navigator";
13
+ import type { FrappeFilters } from "../shared/types";
14
+ import { ReportView } from "./ReportView";
15
+
16
+ const orderMeta = {
17
+ name: "QaLegacyOrder",
18
+ doctype: "DocType",
19
+ module: "QA",
20
+ title_field: "customer",
21
+ fields: [
22
+ { fieldname: "customer", fieldtype: "Data", label: "Customer", in_list_view: 1 },
23
+ { fieldname: "amount", fieldtype: "Int", label: "Amount", in_list_view: 1 },
24
+ {
25
+ fieldname: "status",
26
+ fieldtype: "Select",
27
+ label: "Status",
28
+ options: "Draft\nPaid",
29
+ in_list_view: 1,
30
+ },
31
+ ],
32
+ permissions: [{ role: "All", read: 1 }],
33
+ };
34
+
35
+ const orders = [
36
+ ["QLO-0001", "ACME Corp", "Paid", 100],
37
+ ["QLO-0002", "Globex", "Draft", 20],
38
+ ["QLO-0003", "Initech", "Draft", 3],
39
+ ].map(([name, customer, status, amount]) => ({
40
+ name: String(name),
41
+ doctype: "QaLegacyOrder",
42
+ customer,
43
+ status,
44
+ amount,
45
+ modified: "2026-08-01 09:00:00",
46
+ }));
47
+
48
+ let run = 0;
49
+
50
+ function renderReport(filtersParam?: string, scope?: FrappeFilters): MemoryNavigator {
51
+ run += 1;
52
+ const navigation = createMemoryNavigator("/backoffice/qalegacyorder/view/report");
53
+ renderWithProviders(
54
+ <BackofficeProvider
55
+ frappe={{
56
+ baseURL: `https://legacy-report-${run}.spec.test`,
57
+ fixtures: new InMemoryFixtureProvider({ DocType: [orderMeta], QaLegacyOrder: orders }),
58
+ }}
59
+ navigation={navigation}
60
+ >
61
+ <DeskScopeProvider scope={scope}>
62
+ <ReportView doctype="QaLegacyOrder" filtersParam={filtersParam} />
63
+ </DeskScopeProvider>
64
+ </BackofficeProvider>,
65
+ );
66
+ return navigation;
67
+ }
68
+
69
+ async function counted(count: number) {
70
+ expect(await screen.findByText(`${count} record(s)`, {}, { timeout: 5000 })).toBeTruthy();
71
+ }
72
+
73
+ describe("<ReportView />", () => {
74
+ it("counts and totals the result", async () => {
75
+ renderReport();
76
+ await counted(3);
77
+ const strips = screen
78
+ .getAllByText("Totals")
79
+ .map((label) => label.parentElement?.textContent ?? "");
80
+ expect(strips.some((text) => text.includes("Amount: 123"))).toBe(true);
81
+ });
82
+
83
+ it("opens a record from the footer's Open menu", async () => {
84
+ const navigation = renderReport();
85
+ await counted(3);
86
+ fireEvent.click(screen.getByRole("button", { name: "Open" }));
87
+ fireEvent.click(await screen.findByText("Globex", { selector: "[role=menuitem] *" }));
88
+ await waitFor(() =>
89
+ expect(navigation.getLocation().path).toBe("/backoffice/qalegacyorder/QLO-0002"),
90
+ );
91
+ });
92
+
93
+ it("applies the ?f= base filters and drops them from the address on clear", async () => {
94
+ const navigation = renderReport(encodeURIComponent(JSON.stringify([["status", "=", "Draft"]])));
95
+ await counted(2);
96
+ fireEvent.click(screen.getByRole("button", { name: "Clear filters" }));
97
+ await counted(3);
98
+ expect(navigation.getLocation().path).toBe("/backoffice/qalegacyorder/view/report");
99
+ });
100
+
101
+ it("ANDs the desk scope into the count and the grid", async () => {
102
+ renderReport(undefined, [["status", "=", "Paid"]]);
103
+ await counted(1);
104
+ expect(screen.queryByRole("button", { name: "Clear filters" })).toBeNull();
105
+ await waitFor(() => expect(screen.queryByText("Globex")).toBeNull());
106
+ expect(screen.getAllByText("ACME Corp").length).toBeGreaterThan(0);
107
+ });
108
+ });
@@ -42,6 +42,7 @@ import { useResolvedKnobs } from "@multiplatform.one/theme";
42
42
  import { useCallback, useEffect, useMemo, useState } from "react";
43
43
  import { useTranslation } from "react-i18next";
44
44
  import { useBackofficeNavigator, useBackofficePaths } from "../config/BackofficeProvider";
45
+ import { useDeskScope } from "../desk/scope";
45
46
  import { BACKOFFICE_I18N_NAMESPACE } from "../i18n";
46
47
  import type { FrappeFilters } from "../shared/types";
47
48
  import { useViewConnection } from "./connection";
@@ -132,6 +133,7 @@ export function ReportView({ doctype, filtersParam, initialFilters }: ReportView
132
133
  const navigator = useBackofficeNavigator();
133
134
  const paths = useBackofficePaths();
134
135
  const { knobProps } = useResolvedKnobs();
136
+ const deskScope = useDeskScope();
135
137
  const connection = useViewConnection();
136
138
  const { meta, isLoading: isMetaLoading, error: metaError } = useViewMeta(doctype);
137
139
 
@@ -144,6 +146,9 @@ export function ReportView({ doctype, filtersParam, initialFilters }: ReportView
144
146
  const baseFilters = filtersCleared
145
147
  ? EMPTY_FILTERS
146
148
  : (urlFilters ?? initialFilters ?? EMPTY_FILTERS);
149
+ // Desk scope (GL-5) ANDs into both queries, invisible to the filter chips
150
+ // and not clearable by the user.
151
+ const queryFilters = useMemo(() => [...deskScope, ...baseFilters], [deskScope, baseFilters]);
147
152
  const handleClearFilters = useCallback(() => {
148
153
  setFiltersCleared(true);
149
154
  // Drop the ?f= param from the URL so the cleared state survives reloads.
@@ -217,7 +222,7 @@ export function ReportView({ doctype, filtersParam, initialFilters }: ReportView
217
222
  setPage(0);
218
223
  }, [doctype]);
219
224
 
220
- const filtersKey = useMemo(() => JSON.stringify(baseFilters), [baseFilters]);
225
+ const filtersKey = useMemo(() => JSON.stringify(queryFilters), [queryFilters]);
221
226
  useEffect(() => {
222
227
  setPage(0);
223
228
  }, [filtersKey, pageSize]);
@@ -256,7 +261,7 @@ export function ReportView({ doctype, filtersParam, initialFilters }: ReportView
256
261
  );
257
262
  const statsCollection = useFrappeCollection<StatsRow>(statsConfig, doctype, {
258
263
  fields: statsFields,
259
- filters: baseFilters,
264
+ filters: queryFilters,
260
265
  orderBy: { field: sortField, order: sortAscending ? Order.Asc : Order.Desc },
261
266
  onSyncError: handleStatsError,
262
267
  });
@@ -299,9 +304,9 @@ export function ReportView({ doctype, filtersParam, initialFilters }: ReportView
299
304
  );
300
305
 
301
306
  const builderFilters = useMemo<FrappeFilters>(() => {
302
- if (!needsWindow) return baseFilters;
303
- return [...baseFilters, ["name", "in", pageRows.map((row) => row.name)]];
304
- }, [needsWindow, baseFilters, pageRows]);
307
+ if (!needsWindow) return queryFilters;
308
+ return [...queryFilters, ["name", "in", pageRows.map((row) => row.name)]];
309
+ }, [needsWindow, queryFilters, pageRows]);
305
310
 
306
311
  // ---------------------------------------------------------------------
307
312
  // Footer inputs: open-record jump + totals over the FULL filtered result
@@ -0,0 +1,185 @@
1
+ // The alternate views' shared header (MPO-414): the switcher offers what the
2
+ // doctype's meta supports and navigates there, and New is offered only as far
3
+ // as the newDoc capability and the session's create right allow (MPO-390).
4
+ import React from "react";
5
+ import { InMemoryFixtureProvider } from "@multiplatform.one/frappe";
6
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
7
+ import { act, fireEvent, screen, waitFor } from "@testing-library/react";
8
+ import { afterEach, describe, expect, it, vi } from "vitest";
9
+ import { BackofficeProvider } from "../config/BackofficeProvider";
10
+ import type { BackofficeCapabilities } from "../config/capabilities";
11
+ import { createMemoryNavigator, type MemoryNavigator } from "../navigation/navigator";
12
+ import type { BackofficeView } from "../navigation/paths";
13
+ import { ViewHeader } from "./ViewHeader";
14
+
15
+ const plainMeta = {
16
+ name: "QaHeaderNote",
17
+ doctype: "DocType",
18
+ module: "QA",
19
+ fields: [{ fieldname: "subject", fieldtype: "Data", label: "Subject", in_list_view: 1 }],
20
+ permissions: [{ role: "All", read: 1 }],
21
+ };
22
+
23
+ const imageMeta = {
24
+ name: "QaHeaderProduct",
25
+ doctype: "DocType",
26
+ module: "QA",
27
+ title_field: "product_name",
28
+ image_field: "photo",
29
+ fields: [
30
+ { fieldname: "product_name", fieldtype: "Data", label: "Product Name", in_list_view: 1 },
31
+ { fieldname: "photo", fieldtype: "Attach Image", label: "Photo" },
32
+ ],
33
+ permissions: [{ role: "All", read: 1 }],
34
+ };
35
+
36
+ const moveMeta = {
37
+ name: "Poke Move",
38
+ doctype: "DocType",
39
+ title_field: "move_name",
40
+ fields: [{ fieldname: "move_name", fieldtype: "Data", label: "Move Name", in_list_view: 1 }],
41
+ permissions: [
42
+ { role: "Pokemon Editor", read: 1, write: 1, create: 1, delete: 1 },
43
+ { role: "Guest", read: 1 },
44
+ ],
45
+ };
46
+
47
+ let run = 0;
48
+
49
+ afterEach(() => {
50
+ vi.restoreAllMocks();
51
+ vi.unstubAllGlobals();
52
+ });
53
+
54
+ function renderFixtureHeader(
55
+ doctype: string,
56
+ view: BackofficeView,
57
+ capabilities?: BackofficeCapabilities,
58
+ ): MemoryNavigator {
59
+ run += 1;
60
+ const navigation = createMemoryNavigator("/backoffice");
61
+ renderWithProviders(
62
+ <BackofficeProvider
63
+ frappe={{
64
+ baseURL: `https://view-header-${run}.spec.test`,
65
+ fixtures: new InMemoryFixtureProvider({ DocType: [plainMeta, imageMeta] }),
66
+ }}
67
+ navigation={navigation}
68
+ capabilities={capabilities}
69
+ >
70
+ <ViewHeader doctype={doctype} view={view} />
71
+ </BackofficeProvider>,
72
+ );
73
+ return navigation;
74
+ }
75
+
76
+ function json(body: unknown) {
77
+ return new Response(JSON.stringify(body), {
78
+ status: 200,
79
+ headers: { "content-type": "application/json" },
80
+ });
81
+ }
82
+
83
+ function renderBenchHeader(roles: string[]) {
84
+ run += 1;
85
+ let rolesAnswered = false;
86
+ vi.stubGlobal("fetch", async (input: string | URL | Request) => {
87
+ const url = new URL(String(input instanceof Request ? input.url : input));
88
+ const method = url.pathname.replace(/^\/api\/method\//, "");
89
+ if (method === "frappe.auth.get_logged_user") return json({ message: "user@pokemon.test" });
90
+ if (method === "frappe.core.doctype.user.user.get_roles") {
91
+ rolesAnswered = true;
92
+ return json({ message: roles });
93
+ }
94
+ if (method === "frappe.desk.form.load.getdoctype") return json({ docs: [moveMeta] });
95
+ return json({ data: [], message: [] });
96
+ });
97
+ renderWithProviders(
98
+ <BackofficeProvider
99
+ frappe={{ baseURL: `https://view-header-bench-${run}.spec.test` }}
100
+ navigation={createMemoryNavigator("/backoffice")}
101
+ >
102
+ <ViewHeader doctype="Poke Move" view="report" />
103
+ </BackofficeProvider>,
104
+ );
105
+ return {
106
+ rolesAnswered: () => rolesAnswered,
107
+ settle: async () => {
108
+ await act(async () => {
109
+ await new Promise((resolve) => setTimeout(resolve, 300));
110
+ });
111
+ },
112
+ };
113
+ }
114
+
115
+ async function openSwitcher() {
116
+ fireEvent.click(await screen.findByTestId("list-view-switcher", {}, { timeout: 5000 }));
117
+ await screen.findByRole("menu", {}, { timeout: 5000 });
118
+ }
119
+
120
+ function offeredViews(): string[] {
121
+ return Array.from(
122
+ document.querySelectorAll('[role="menuitemcheckbox"]'),
123
+ (node) => node.textContent?.trim() ?? "",
124
+ );
125
+ }
126
+
127
+ describe("<ViewHeader />", () => {
128
+ it("titles the page with the doctype", async () => {
129
+ renderFixtureHeader("QaHeaderNote", "report");
130
+ expect(await screen.findByRole("heading", { name: "QaHeaderNote" })).toBeTruthy();
131
+ });
132
+
133
+ it("offers Image only when the doctype's meta has an image field", async () => {
134
+ renderFixtureHeader("QaHeaderProduct", "report");
135
+ await openSwitcher();
136
+ await waitFor(() => expect(offeredViews()).toContain("Image"));
137
+ });
138
+
139
+ it("leaves Image and Tree out for a plain doctype", async () => {
140
+ renderFixtureHeader("QaHeaderNote", "report");
141
+ await openSwitcher();
142
+ await waitFor(() => expect(offeredViews()).toContain("Report"));
143
+ expect(offeredViews()).not.toContain("Image");
144
+ expect(offeredViews()).not.toContain("Tree");
145
+ });
146
+
147
+ it("navigates to the view picked in the switcher", async () => {
148
+ const navigation = renderFixtureHeader("QaHeaderProduct", "report");
149
+ await openSwitcher();
150
+ const image = await waitFor(() => {
151
+ const item = Array.from(document.querySelectorAll('[role="menuitemcheckbox"]')).find(
152
+ (node) => node.textContent?.trim() === "Image",
153
+ );
154
+ expect(item).toBeTruthy();
155
+ return item as HTMLElement;
156
+ });
157
+ fireEvent.click(image);
158
+ await waitFor(() =>
159
+ expect(navigation.getLocation().path).toBe("/backoffice/qaheaderproduct/view/image"),
160
+ );
161
+ });
162
+
163
+ it("opens a new record from New, and hides New when the newDoc capability is off", async () => {
164
+ const navigation = renderFixtureHeader("QaHeaderNote", "report");
165
+ fireEvent.click(await screen.findByLabelText("New QaHeaderNote", {}, { timeout: 5000 }));
166
+ expect(navigation.getLocation().path).toBe("/backoffice/qaheadernote/new");
167
+
168
+ renderFixtureHeader("QaHeaderProduct", "report", { newDoc: false });
169
+ await screen.findByRole("heading", { name: "QaHeaderProduct" });
170
+ expect(screen.queryByLabelText("New QaHeaderProduct")).toBeNull();
171
+ });
172
+
173
+ it("offers an editor New on a live bench", async () => {
174
+ renderBenchHeader(["Pokemon Editor", "Guest"]);
175
+ expect(await screen.findByLabelText("New Poke Move", {}, { timeout: 5000 })).toBeTruthy();
176
+ });
177
+
178
+ it("offers a reader no New on a live bench", async () => {
179
+ const bench = renderBenchHeader(["Guest"]);
180
+ await screen.findByRole("heading", { name: "Poke Move" });
181
+ await bench.settle();
182
+ expect(screen.queryByLabelText("New Poke Move")).toBeNull();
183
+ expect(bench.rolesAnswered()).toBe(true);
184
+ });
185
+ });
@@ -5,6 +5,7 @@
5
5
  // PageHeader is the same primitive the list screen uses (LC-16).
6
6
  import { PageHeader, YStack } from "@multiplatform.one/components";
7
7
  import { Button } from "@multiplatform.one/forms";
8
+ import { useDocRights, useFrappeConfig } from "@multiplatform.one/frappe-ui";
8
9
  import { useResolvedKnobs } from "@multiplatform.one/theme";
9
10
  import { ArrowSquareOutIcon, PlusIcon } from "@phosphor-icons/react";
10
11
  import { useTranslation } from "react-i18next";
@@ -53,6 +54,8 @@ export function ViewHeader({ doctype, view }: ViewHeaderProps) {
53
54
  const { t } = useTranslation(BACKOFFICE_I18N_NAMESPACE);
54
55
  const { knobProps } = useResolvedKnobs();
55
56
  const availableViews = useAvailableViews(doctype, view);
57
+ const { meta } = useViewMeta(doctype);
58
+ const { rights } = useDocRights(useFrappeConfig(), meta);
56
59
  // Desk counterpart of this exact view (fixture mode has no desk).
57
60
  const deskHref =
58
61
  frappe?.baseURL && !frappe.fixtures ? deskViewUrl(frappe.baseURL, doctype, view) : undefined;
@@ -78,7 +81,7 @@ export function ViewHeader({ doctype, view }: ViewHeaderProps) {
78
81
  current={view}
79
82
  onViewChange={(next) => navigator.navigate(paths.view(doctype, next))}
80
83
  />
81
- {newDoc.enabled ? (
84
+ {newDoc.enabled && rights.create ? (
82
85
  <Button
83
86
  size={knobProps.sizeToken}
84
87
  accent
@@ -168,13 +168,14 @@ async function fetchLiveDayCounts(
168
168
  connection: ViewConnection,
169
169
  doctype: string,
170
170
  cutoff: string,
171
+ scope: FrappeFilters,
171
172
  ): Promise<Map<string, number>> {
172
173
  const db = new DbModule(new HttpClient(connection.baseURL, toAuthConfig(connection.auth)));
173
174
  try {
174
175
  // Server-side per-day aggregate: bounded payload regardless of doc count.
175
176
  const rows = await db.getDocList<DayAggregateRow>(doctype, {
176
177
  fields: ["date(creation) as _day", "count(name) as _aggregate_value"],
177
- filters: [["creation", ">=", cutoff]],
178
+ filters: [...scope, ["creation", ">=", cutoff]],
178
179
  groupBy: "date(creation)",
179
180
  limit: 0,
180
181
  });
@@ -190,7 +191,7 @@ async function fetchLiveDayCounts(
190
191
  // Grouped-by-function query rejected — fetch raw creation values instead.
191
192
  const rows = await db.getDocList<CreationRow>(doctype, {
192
193
  fields: ["creation"],
193
- filters: [["creation", ">=", cutoff]],
194
+ filters: [...scope, ["creation", ">=", cutoff]],
194
195
  limit: 0,
195
196
  });
196
197
  return bucketRowsByDay(rows);
@@ -200,25 +201,32 @@ async function fetchLiveDayCounts(
200
201
  async function fetchFixtureDayCounts(
201
202
  fixtures: FixtureProvider,
202
203
  doctype: string,
204
+ scope: FrappeFilters,
203
205
  ): Promise<Map<string, number>> {
204
- const rows = (await fixtures.getList(doctype, { fields: ["creation"] })) as Array<{
206
+ const rows = (await fixtures.getList(doctype, {
207
+ fields: ["creation"],
208
+ filters: scope,
209
+ })) as Array<{
205
210
  creation?: unknown;
206
211
  }>;
207
212
  return bucketRowsByDay(rows);
208
213
  }
209
214
 
210
215
  const REFETCH_DEBOUNCE_MS = 300;
216
+ const NO_SCOPE: FrappeFilters = [];
211
217
 
212
218
  /**
213
219
  * Docs created per week over the last {@link WEEKS_WINDOW} weeks (Monday
214
220
  * buckets, empty weeks included so the series is continuous), refetched on
215
221
  * doctype realtime events with a coalescing debounce — same recompute
216
- * contract as `useFrappeAggregate`.
222
+ * contract as `useFrappeAggregate`. `scope` (the desk scope, GL-5) ANDs
223
+ * into both the live and the fixture query.
217
224
  */
218
225
  export function useWeeklyCreated(
219
226
  connection: ViewConnection | undefined,
220
227
  doctype: string,
221
228
  weeks: number = WEEKS_WINDOW,
229
+ scope: FrappeFilters = NO_SCOPE,
222
230
  ): WeeklyCreatedState {
223
231
  const [data, setData] = useState<WeeklyCreatedPoint[] | undefined>(undefined);
224
232
  const [isLoading, setIsLoading] = useState(true);
@@ -228,20 +236,20 @@ export function useWeeklyCreated(
228
236
  const fetchSeq = useRef(0);
229
237
  const connectionRef = useRef(connection);
230
238
  connectionRef.current = connection;
231
- const specRef = useRef({ doctype, weeks });
232
- specRef.current = { doctype, weeks };
239
+ const specRef = useRef({ doctype, weeks, scope });
240
+ specRef.current = { doctype, weeks, scope };
233
241
 
234
242
  const runFetch = useCallback(async () => {
235
243
  const conn = connectionRef.current;
236
- const { doctype: currentDoctype, weeks: currentWeeks } = specRef.current;
244
+ const { doctype: currentDoctype, weeks: currentWeeks, scope: currentScope } = specRef.current;
237
245
  if (!conn || !currentDoctype) return;
238
246
  const seq = ++fetchSeq.current;
239
247
  try {
240
248
  const firstWeek = weekStart(new Date());
241
249
  firstWeek.setDate(firstWeek.getDate() - (currentWeeks - 1) * 7);
242
250
  const dayCounts = conn.fixtures
243
- ? await fetchFixtureDayCounts(conn.fixtures, currentDoctype)
244
- : await fetchLiveDayCounts(conn, currentDoctype, isoDate(firstWeek));
251
+ ? await fetchFixtureDayCounts(conn.fixtures, currentDoctype, currentScope)
252
+ : await fetchLiveDayCounts(conn, currentDoctype, isoDate(firstWeek), currentScope);
245
253
 
246
254
  const weekCounts = new Map<string, number>();
247
255
  for (const [day, count] of dayCounts) {
@@ -289,14 +297,15 @@ export function useWeeklyCreated(
289
297
 
290
298
  const baseURL = connection?.baseURL;
291
299
  const hasFixtures = !!connection?.fixtures;
300
+ const scopeKey = JSON.stringify(scope);
292
301
  useEffect(() => {
293
302
  if (!baseURL || !doctype) return;
294
303
  setIsLoading(true);
295
304
  setError(undefined);
296
305
  void runFetch();
297
- // Refetch on connection target / doctype change only — the connection
298
- // object identity churns with provider re-renders.
299
- }, [baseURL, hasFixtures, doctype, weeks, runFetch]);
306
+ // Refetch on connection target / doctype / scope change only — the
307
+ // connection object identity churns with provider re-renders.
308
+ }, [baseURL, hasFixtures, doctype, weeks, scopeKey, runFetch]);
300
309
 
301
310
  useFrappeDoctypeEvents(
302
311
  connection as Parameters<typeof useFrappeDoctypeEvents>[0],
@@ -1 +1 @@
1
- {"version":3,"file":"awesomebar-data.d.ts","sourceRoot":"","sources":["../../src/chrome/awesomebar-data.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AA0DD,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CA6B7D;AAMD,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,iBAAiB,CA4C5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAUzE;AAOD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAID,gEAAgE;AAChE,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAO7D;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAiB9E;AA2BD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAahG"}
1
+ {"version":3,"file":"awesomebar-data.d.ts","sourceRoot":"","sources":["../../src/chrome/awesomebar-data.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AA0DD,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CA6B7D;AAMD,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,iBAAiB,CA8C5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAUzE;AAOD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAID,gEAAgE;AAChE,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAO7D;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAiB9E;AA2BD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAahG"}
@@ -1 +1 @@
1
- {"version":3,"file":"notifications-panel.d.ts","sourceRoot":"","sources":["../../src/chrome/notifications-panel.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AA4FD,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,SAAS,EACT,KAAK,EACL,WAAW,EACX,aAAa,GACd,EAAE,uBAAuB,2CAgEzB"}
1
+ {"version":3,"file":"notifications-panel.d.ts","sourceRoot":"","sources":["../../src/chrome/notifications-panel.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AA2FD,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,SAAS,EACT,KAAK,EACL,WAAW,EACX,aAAa,GACd,EAAE,uBAAuB,2CAgEzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"DocFormScreen.d.ts","sourceRoot":"","sources":["../../src/form/DocFormScreen.tsx"],"names":[],"mappings":"AA0CA,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAqCtC,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wDAAwD;IACxD,eAAe,CAAC,EAAE,sBAAsB,CAAC;CAC1C;AAID,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,GAChB,EAAE,kBAAkB,2CA4/BpB"}
1
+ {"version":3,"file":"DocFormScreen.d.ts","sourceRoot":"","sources":["../../src/form/DocFormScreen.tsx"],"names":[],"mappings":"AA0CA,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAqCtC,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wDAAwD;IACxD,eAAe,CAAC,EAAE,sBAAsB,CAAC;CAC1C;AAID,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,GAChB,EAAE,kBAAkB,2CAqgCpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-people.d.ts","sourceRoot":"","sources":["../../src/form/sidebar-people.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,EAAE,sBAAsB,2CA+CxB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,uBAAuB,kDA0BzE"}
1
+ {"version":3,"file":"sidebar-people.d.ts","sourceRoot":"","sources":["../../src/form/sidebar-people.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,EAAE,sBAAsB,2CA+CxB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,uBAAuB,kDA0BzE"}
@@ -398,7 +398,7 @@ export declare const en: {
398
398
  readonly list: "List";
399
399
  readonly loadFailed: "Couldn't load this view";
400
400
  readonly loading: "Loading";
401
- readonly new: "New";
401
+ readonly new: "New {{doctype}}";
402
402
  readonly report: "Report";
403
403
  readonly switchView: "Switch view";
404
404
  readonly tree: "Tree";
@@ -1 +1 @@
1
- {"version":3,"file":"ListBulkActionsBar.d.ts","sourceRoot":"","sources":["../../src/list/ListBulkActionsBar.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAS5D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,IAAI,EACJ,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,uBAAuB,kDAuUzB"}
1
+ {"version":3,"file":"ListBulkActionsBar.d.ts","sourceRoot":"","sources":["../../src/list/ListBulkActionsBar.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAS5D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,IAAI,EACJ,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,uBAAuB,kDAuUzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceSidebar.d.ts","sourceRoot":"","sources":["../../src/shell/WorkspaceSidebar.tsx"],"names":[],"mappings":"AAyCA,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,MAAM,WAAW,qBAAqB;IACpC,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAsJD,wBAAgB,gBAAgB,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,qBAAqB,2CA2CjF"}
1
+ {"version":3,"file":"WorkspaceSidebar.d.ts","sourceRoot":"","sources":["../../src/shell/WorkspaceSidebar.tsx"],"names":[],"mappings":"AAyCA,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,MAAM,WAAW,qBAAqB;IACpC,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAuJD,wBAAgB,gBAAgB,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,qBAAqB,2CA2CjF"}
@@ -1 +1 @@
1
- {"version":3,"file":"CalendarView.d.ts","sourceRoot":"","sources":["../../src/views/CalendarView.tsx"],"names":[],"mappings":"AAwCA,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,YAAY,GACb,EAAE,iBAAiB,2CA6HnB"}
1
+ {"version":3,"file":"CalendarView.d.ts","sourceRoot":"","sources":["../../src/views/CalendarView.tsx"],"names":[],"mappings":"AA6CA,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,YAAY,GACb,EAAE,iBAAiB,2CAgInB"}
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardView.d.ts","sourceRoot":"","sources":["../../src/views/DashboardView.tsx"],"names":[],"mappings":"AAsEA,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE,kBAAkB,2CA2J5D"}
1
+ {"version":3,"file":"DashboardView.d.ts","sourceRoot":"","sources":["../../src/views/DashboardView.tsx"],"names":[],"mappings":"AAsEA,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE,kBAAkB,2CA+J5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"KanbanView.d.ts","sourceRoot":"","sources":["../../src/views/KanbanView.tsx"],"names":[],"mappings":"AA6FA,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EAAE,aAAa,EACpB,UAAU,EACV,QAAQ,GACT,EAAE,eAAe,2CA+TjB"}
1
+ {"version":3,"file":"KanbanView.d.ts","sourceRoot":"","sources":["../../src/views/KanbanView.tsx"],"names":[],"mappings":"AA+FA,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EAAE,aAAa,EACpB,UAAU,EACV,QAAQ,GACT,EAAE,eAAe,2CAiUjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReportView.d.ts","sourceRoot":"","sources":["../../src/views/ReportView.tsx"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAYrD,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,cAAc,CAAC,EAAE,aAAa,CAAC;CAChC;AAQD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CA8B/E;AAgBD,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,eAAe,2CAgTpF"}
1
+ {"version":3,"file":"ReportView.d.ts","sourceRoot":"","sources":["../../src/views/ReportView.tsx"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAYrD,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,cAAc,CAAC,EAAE,aAAa,CAAC;CAChC;AAQD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CA8B/E;AAgBD,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,eAAe,2CAoTpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ViewHeader.d.ts","sourceRoot":"","sources":["../../src/views/ViewHeader.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAI7F;AAED,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,eAAe,2CAoD5D"}
1
+ {"version":3,"file":"ViewHeader.d.ts","sourceRoot":"","sources":["../../src/views/ViewHeader.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAI7F;AAED,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,eAAe,2CAsD5D"}
@@ -1,4 +1,5 @@
1
1
  import { type BackofficePaths } from "../navigation/paths";
2
+ import type { FrappeFilters } from "../shared/types";
2
3
  import type { DocFieldMeta, DoctypeMeta } from "../shared/useDoctypeMeta";
3
4
  import type { ViewConnection } from "./connection";
4
5
  export declare const WEEKS_WINDOW = 12;
@@ -43,7 +44,8 @@ export interface WeeklyCreatedState {
43
44
  * Docs created per week over the last {@link WEEKS_WINDOW} weeks (Monday
44
45
  * buckets, empty weeks included so the series is continuous), refetched on
45
46
  * doctype realtime events with a coalescing debounce — same recompute
46
- * contract as `useFrappeAggregate`.
47
+ * contract as `useFrappeAggregate`. `scope` (the desk scope, GL-5) ANDs
48
+ * into both the live and the fixture query.
47
49
  */
48
- export declare function useWeeklyCreated(connection: ViewConnection | undefined, doctype: string, weeks?: number): WeeklyCreatedState;
50
+ export declare function useWeeklyCreated(connection: ViewConnection | undefined, doctype: string, weeks?: number, scope?: FrappeFilters): WeeklyCreatedState;
49
51
  //# sourceMappingURL=dashboard-data.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-data.d.ts","sourceRoot":"","sources":["../../src/views/dashboard-data.tsx"],"names":[],"mappings":"AA2BA,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAElF,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAanD,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAUtC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,CAG7E;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,eAA8B,GACpC,MAAM,CAGR;AAMD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE1C;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAK1C;AAqBD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,IAAI,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAoED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,GAAG,SAAS,EACtC,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAqB,GAC3B,kBAAkB,CAkGpB"}
1
+ {"version":3,"file":"dashboard-data.d.ts","sourceRoot":"","sources":["../../src/views/dashboard-data.tsx"],"names":[],"mappings":"AA2BA,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAanD,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAUtC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,CAG7E;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,eAA8B,GACpC,MAAM,CAGR;AAMD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE1C;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAK1C;AAqBD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,IAAI,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA0ED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,GAAG,SAAS,EACtC,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAqB,EAC5B,KAAK,GAAE,aAAwB,GAC9B,kBAAkB,CAmGpB"}