@activecollab/components 2.0.417 → 2.0.419

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 (71) hide show
  1. package/dist/cjs/components/Icons/collection/Portfolio.js +61 -0
  2. package/dist/cjs/components/Icons/collection/Portfolio.js.map +1 -0
  3. package/dist/cjs/components/Icons/collection/PortfolioPlus.js +62 -0
  4. package/dist/cjs/components/Icons/collection/PortfolioPlus.js.map +1 -0
  5. package/dist/cjs/components/Icons/collection/Target.js +65 -0
  6. package/dist/cjs/components/Icons/collection/Target.js.map +1 -0
  7. package/dist/cjs/components/Icons/collection/index.js +21 -0
  8. package/dist/cjs/components/Icons/collection/index.js.map +1 -1
  9. package/dist/cjs/presentation/shared/MessageDialog.js +62 -107
  10. package/dist/cjs/presentation/shared/MessageDialog.js.map +1 -1
  11. package/dist/cjs/presentation/shared/MessageFeedback.js +284 -0
  12. package/dist/cjs/presentation/shared/MessageFeedback.js.map +1 -0
  13. package/dist/cjs/presentation/shared/PortfolioOptionsMenu.js +64 -0
  14. package/dist/cjs/presentation/shared/PortfolioOptionsMenu.js.map +1 -0
  15. package/dist/cjs/presentation/shared/ProjectOptionsMenu.js +367 -0
  16. package/dist/cjs/presentation/shared/ProjectOptionsMenu.js.map +1 -0
  17. package/dist/cjs/presentation/shared/dashboardWidgets.js +726 -0
  18. package/dist/cjs/presentation/shared/dashboardWidgets.js.map +1 -0
  19. package/dist/cjs/presentation/shared/headers.js +25 -360
  20. package/dist/cjs/presentation/shared/headers.js.map +1 -1
  21. package/dist/cjs/presentation/shared/index.js +130 -0
  22. package/dist/cjs/presentation/shared/index.js.map +1 -1
  23. package/dist/esm/components/Icons/collection/Portfolio.d.ts +32 -0
  24. package/dist/esm/components/Icons/collection/Portfolio.d.ts.map +1 -0
  25. package/dist/esm/components/Icons/collection/Portfolio.js +54 -0
  26. package/dist/esm/components/Icons/collection/Portfolio.js.map +1 -0
  27. package/dist/esm/components/Icons/collection/PortfolioPlus.d.ts +32 -0
  28. package/dist/esm/components/Icons/collection/PortfolioPlus.d.ts.map +1 -0
  29. package/dist/esm/components/Icons/collection/PortfolioPlus.js +55 -0
  30. package/dist/esm/components/Icons/collection/PortfolioPlus.js.map +1 -0
  31. package/dist/esm/components/Icons/collection/Target.d.ts +32 -0
  32. package/dist/esm/components/Icons/collection/Target.d.ts.map +1 -0
  33. package/dist/esm/components/Icons/collection/Target.js +58 -0
  34. package/dist/esm/components/Icons/collection/Target.js.map +1 -0
  35. package/dist/esm/components/Icons/collection/index.d.ts +3 -0
  36. package/dist/esm/components/Icons/collection/index.d.ts.map +1 -1
  37. package/dist/esm/components/Icons/collection/index.js +3 -0
  38. package/dist/esm/components/Icons/collection/index.js.map +1 -1
  39. package/dist/esm/presentation/shared/MessageDialog.d.ts +8 -3
  40. package/dist/esm/presentation/shared/MessageDialog.d.ts.map +1 -1
  41. package/dist/esm/presentation/shared/MessageDialog.js +64 -98
  42. package/dist/esm/presentation/shared/MessageDialog.js.map +1 -1
  43. package/dist/esm/presentation/shared/MessageFeedback.d.ts +54 -0
  44. package/dist/esm/presentation/shared/MessageFeedback.d.ts.map +1 -0
  45. package/dist/esm/presentation/shared/MessageFeedback.js +252 -0
  46. package/dist/esm/presentation/shared/MessageFeedback.js.map +1 -0
  47. package/dist/esm/presentation/shared/PortfolioOptionsMenu.d.ts +12 -0
  48. package/dist/esm/presentation/shared/PortfolioOptionsMenu.d.ts.map +1 -0
  49. package/dist/esm/presentation/shared/PortfolioOptionsMenu.js +46 -0
  50. package/dist/esm/presentation/shared/PortfolioOptionsMenu.js.map +1 -0
  51. package/dist/esm/presentation/shared/ProjectOptionsMenu.d.ts +31 -0
  52. package/dist/esm/presentation/shared/ProjectOptionsMenu.d.ts.map +1 -0
  53. package/dist/esm/presentation/shared/ProjectOptionsMenu.js +311 -0
  54. package/dist/esm/presentation/shared/ProjectOptionsMenu.js.map +1 -0
  55. package/dist/esm/presentation/shared/dashboardWidgets.d.ts +203 -0
  56. package/dist/esm/presentation/shared/dashboardWidgets.d.ts.map +1 -0
  57. package/dist/esm/presentation/shared/dashboardWidgets.js +665 -0
  58. package/dist/esm/presentation/shared/dashboardWidgets.js.map +1 -0
  59. package/dist/esm/presentation/shared/headers.d.ts +0 -11
  60. package/dist/esm/presentation/shared/headers.d.ts.map +1 -1
  61. package/dist/esm/presentation/shared/headers.js +23 -315
  62. package/dist/esm/presentation/shared/headers.js.map +1 -1
  63. package/dist/esm/presentation/shared/index.d.ts +8 -0
  64. package/dist/esm/presentation/shared/index.d.ts.map +1 -1
  65. package/dist/esm/presentation/shared/index.js +4 -0
  66. package/dist/esm/presentation/shared/index.js.map +1 -1
  67. package/dist/index.js +666 -508
  68. package/dist/index.js.map +1 -1
  69. package/dist/index.min.js +1 -1
  70. package/dist/index.min.js.map +1 -1
  71. package/package.json +1 -1
@@ -0,0 +1,311 @@
1
+ import React, { useCallback, useState } from "react";
2
+ import styled, { createGlobalStyle } from "styled-components";
3
+ import { ConnectRepositoryDialog } from "./ConnectRepositoryDialog";
4
+ import { WEBHOOK_CONNECTIONS, WEBHOOK_REPOSITORIES, WebhookLogsDialog } from "./WebhookLogsDialog";
5
+ import { Badge } from "../../components/Badge";
6
+ import { Button } from "../../components/Button";
7
+ import { CompleteCheckbox } from "../../components/CompleteCheckbox";
8
+ import { Dialog } from "../../components/Dialog";
9
+ import { IconButton } from "../../components/IconButton";
10
+ import { AccessLogIcon, ArrowLeftIcon, CaretRightIcon, CheckboxBlankTogglerIcon, DownloadIcon, DuplicateIcon, EditIcon, GitHubIcon, GitIcon, GitLabIcon, GitRepositoryConnectIcon, GitRepositoryIcon, InsertLinkIcon, LabelsIcon, NotificationBellIcon, ProjectTemplateConvertIcon, ProjectTemplateIcon, StarIcon, TrashIcon, TreeDotsIcon } from "../../components/Icons";
11
+ import { List, ListItem, ListSeparator } from "../../components/List";
12
+ import { Menu, MenuHeader } from "../../components/Menu";
13
+ import { ToastMessage } from "../../components/ToastMessage";
14
+ import { ResizeTransition, SlideFromTop, SlideLeftRightTransition } from "../../components/Transitions";
15
+ import { Body2 } from "../../components/Typography";
16
+
17
+ /* Project "..." options menu (Menu + List with leading-icon items). Two items
18
+ (Favorite, Subscribe) have a checkbox on the right. Clicks are no-ops. When
19
+ the `source` module is loaded a Repositories item drills in to a submenu.
20
+
21
+ Shared by the project page header (Project Repos presentation) and the
22
+ Projects listing (Projects List presentation), so the "..." menu behaves the
23
+ same wherever a project is shown. */
24
+ const StyledProjectMenu = styled.div.withConfig({
25
+ displayName: "ProjectOptionsMenu__StyledProjectMenu",
26
+ componentId: "sc-1k8fz6q-0"
27
+ })([".toggle-item{justify-content:space-between;}.toggle-item .opt-left{display:flex;align-items:center;min-width:0;}.toggle-item .opt-left svg{margin-right:8px;flex-shrink:0;}.toggle-item .c-complete-checkbox{width:16px;height:16px;border-radius:3px;align-self:center;flex-shrink:0;}.submenu-item{justify-content:space-between;}.submenu-item .repo-right{display:flex;align-items:center;gap:8px;flex-shrink:0;}.submenu-item .repo-right .c-badge{background-color:var(--color-theme-300);color:var(--color-theme-700);}.submenu-item .repo-caret{flex-shrink:0;fill:var(--color-theme-600);}.repo-row{min-width:0;}.repo-row > svg{flex-shrink:0;}.repo-name{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}"]);
28
+
29
+ /* The project "..." menu shares the Webhook Logs dialog's repository /
30
+ * connection universe, so a repository connected here is one that dialog can
31
+ * pre-filter by. `WebhookConnection` and `Connection` share a shape, and a
32
+ * `WebhookRepository`'s `path` maps onto a `Repository`'s `name`. */
33
+ const PROJECT_MENU_CONNECTIONS = WEBHOOK_CONNECTIONS;
34
+ const PROJECT_MENU_REPOSITORIES = WEBHOOK_REPOSITORIES.map(repo => ({
35
+ id: repo.id,
36
+ name: repo.path,
37
+ connectionId: repo.connectionId
38
+ }));
39
+
40
+ /** Submenu row label for a connected repository: "path (Connection)". The
41
+ * service type is omitted because the leading provider icon already conveys
42
+ * it. */
43
+ const repositoryMenuLabel = repo => {
44
+ const connection = PROJECT_MENU_CONNECTIONS.find(c => c.id === repo.connectionId);
45
+ return connection ? repo.name + " (" + connection.name + ")" : repo.name;
46
+ };
47
+
48
+ /** Provider glyph for a connected repository: GitHub / GitLab for those
49
+ * services, and the generic Git mark for anything else (e.g. an upcoming
50
+ * Bitbucket connection). */
51
+ const repositoryIcon = repo => {
52
+ const connection = PROJECT_MENU_CONNECTIONS.find(c => c.id === repo.connectionId);
53
+ switch (connection == null ? void 0 : connection.service) {
54
+ case "github":
55
+ return GitHubIcon;
56
+ case "gitlab":
57
+ return GitLabIcon;
58
+ default:
59
+ return GitIcon;
60
+ }
61
+ };
62
+
63
+ /** Width of the project "..." menu (matches the DS "normal" menu mode). */
64
+ const PROJECT_MENU_WIDTH = 260;
65
+
66
+ /* The menu drills in place (index → Repositories), so the paper must clip the
67
+ sliding panels and give them a positioning context. */
68
+ const ProjectMenuSliderStyle = createGlobalStyle([".c-simple-menu__paper.project-options-menu{overflow:hidden;position:relative;}"]);
69
+
70
+ /* Toast anchor — fixed, upper-right corner (the toast slides down from the
71
+ top). The wrapper ignores pointer events so it never blocks the page; only
72
+ the toast itself is interactive. */
73
+ const StyledToastAnchor = styled.div.withConfig({
74
+ displayName: "ProjectOptionsMenu__StyledToastAnchor",
75
+ componentId: "sc-1k8fz6q-1"
76
+ })(["position:fixed;top:16px;right:16px;z-index:10000;pointer-events:none;.c-toast-message{pointer-events:auto;}"]);
77
+ /**
78
+ * The project "..." options menu. When the `source` module is loaded it gains
79
+ * a **Repositories** item that, instead of flying out to the side, **drills in
80
+ * within the same menu** (the pattern used across the app — see `Filter`): the
81
+ * index slides out to the left and the Repositories view (a back-arrow header,
82
+ * the connected repositories sorted by name, and a **Connect Repository**
83
+ * action) slides in. Connecting adds a repository to the list; clicking one
84
+ * would, in production, open it in a new tab (surfaced here via a dialog).
85
+ */
86
+ export const ProjectOptionsMenu = _ref => {
87
+ let _ref$sourceModuleLoad = _ref.sourceModuleLoaded,
88
+ sourceModuleLoaded = _ref$sourceModuleLoad === void 0 ? false : _ref$sourceModuleLoad,
89
+ _ref$initialConnected = _ref.initialConnectedRepositories,
90
+ initialConnectedRepositories = _ref$initialConnected === void 0 ? [] : _ref$initialConnected,
91
+ _ref$canManageProject = _ref.canManageProjectRepositories,
92
+ canManageProjectRepositories = _ref$canManageProject === void 0 ? true : _ref$canManageProject,
93
+ className = _ref.className,
94
+ size = _ref.size;
95
+ const _useState = useState(false),
96
+ open = _useState[0],
97
+ setOpen = _useState[1];
98
+ const _useState2 = useState("index"),
99
+ view = _useState2[0],
100
+ setView = _useState2[1];
101
+ const _useState3 = useState(false),
102
+ webhookLogsOpen = _useState3[0],
103
+ setWebhookLogsOpen = _useState3[1];
104
+ const _useState4 = useState(true),
105
+ isLeft = _useState4[0],
106
+ setIsLeft = _useState4[1];
107
+ const _useState5 = useState(0),
108
+ height = _useState5[0],
109
+ setHeight = _useState5[1];
110
+ // Connected repositories drive the count badge on the Repositories item. In
111
+ // production this count comes from the project's `count_repositories` counter,
112
+ // kept current via pusher/websocket events, so the badge reflects repositories
113
+ // connected or disconnected by anyone — not just the current user's actions.
114
+ const _useState6 = useState(initialConnectedRepositories),
115
+ connectedRepos = _useState6[0],
116
+ setConnectedRepos = _useState6[1];
117
+ const _useState7 = useState(false),
118
+ connectOpen = _useState7[0],
119
+ setConnectOpen = _useState7[1];
120
+ const _useState8 = useState(false),
121
+ infoOpen = _useState8[0],
122
+ setInfoOpen = _useState8[1];
123
+ const _useState9 = useState(false),
124
+ toastOpen = _useState9[0],
125
+ setToastOpen = _useState9[1];
126
+ // Bumped on each connect so the toast remounts and its auto-hide timer
127
+ // restarts from the moment it is shown.
128
+ const _useState0 = useState(0),
129
+ toastKey = _useState0[0],
130
+ setToastKey = _useState0[1];
131
+
132
+ // Repositories still available to connect (not already on the project).
133
+ const connectableRepos = PROJECT_MENU_REPOSITORIES.filter(r => !connectedRepos.some(c => c.id === r.id));
134
+
135
+ // Connected repositories are listed in the submenu sorted by name.
136
+ const sortedRepos = [...connectedRepos].sort((a, b) => a.name.localeCompare(b.name));
137
+
138
+ // Each view measures itself as it mounts so the paper can animate its height.
139
+ const measure = useCallback(node => {
140
+ if (node) {
141
+ setHeight(node.offsetHeight);
142
+ }
143
+ }, []);
144
+ const goToRepositories = () => {
145
+ setView("repositories");
146
+ setIsLeft(true);
147
+ };
148
+ const backToIndex = () => {
149
+ setView("index");
150
+ setIsLeft(false);
151
+ };
152
+ const handleClose = () => {
153
+ setOpen(false);
154
+ // Reset to the index so the next open starts at the top level.
155
+ setView("index");
156
+ setIsLeft(true);
157
+ };
158
+ const handleConnected = repo => {
159
+ setConnectedRepos(prev => prev.some(r => r.id === repo.id) ? prev : [...prev, repo]);
160
+ setToastOpen(true);
161
+ setToastKey(k => k + 1);
162
+ };
163
+ const handleConnect = () => {
164
+ handleClose();
165
+ setConnectOpen(true);
166
+ };
167
+
168
+ // In production this closes the menu and opens the repository in a new tab;
169
+ // in the mock we surface that behaviour in a small dialog instead.
170
+ const handleOpenRepository = () => {
171
+ handleClose();
172
+ setInfoOpen(true);
173
+ };
174
+ const handleOpenWebhookLogs = () => {
175
+ handleClose();
176
+ setWebhookLogsOpen(true);
177
+ };
178
+ const indexView = /*#__PURE__*/React.createElement(StyledProjectMenu, null, /*#__PURE__*/React.createElement(List, {
179
+ style: {
180
+ padding: "8px 0"
181
+ },
182
+ tabIndex: -1
183
+ }, /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(EditIcon, null), "Edit"), /*#__PURE__*/React.createElement(ListItem, {
184
+ className: "toggle-item"
185
+ }, /*#__PURE__*/React.createElement("span", {
186
+ className: "opt-left"
187
+ }, /*#__PURE__*/React.createElement(StarIcon, null), "Mark as Favorite"), /*#__PURE__*/React.createElement(CompleteCheckbox, {
188
+ primary: true,
189
+ completed: true
190
+ })), /*#__PURE__*/React.createElement(ListItem, {
191
+ className: "toggle-item"
192
+ }, /*#__PURE__*/React.createElement("span", {
193
+ className: "opt-left"
194
+ }, /*#__PURE__*/React.createElement(NotificationBellIcon, null), "Subscribe to Everything"), /*#__PURE__*/React.createElement(CompleteCheckbox, {
195
+ primary: true,
196
+ completed: false
197
+ })), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(LabelsIcon, null), "Manage Task Labels"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(InsertLinkIcon, null), "Copy Link"), /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(CheckboxBlankTogglerIcon, null), "Complete"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(DownloadIcon, null), "Export"), sourceModuleLoaded ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement(ListItem, {
198
+ className: "toggle-item submenu-item",
199
+ onClick: goToRepositories
200
+ }, /*#__PURE__*/React.createElement("span", {
201
+ className: "opt-left"
202
+ }, /*#__PURE__*/React.createElement(GitRepositoryIcon, null), "Repositories"), /*#__PURE__*/React.createElement("span", {
203
+ className: "repo-right"
204
+ }, connectedRepos.length > 0 ? /*#__PURE__*/React.createElement(Badge, {
205
+ isStandalone: true,
206
+ dimension: 16,
207
+ value: connectedRepos.length
208
+ }) : null, /*#__PURE__*/React.createElement(CaretRightIcon, {
209
+ className: "repo-caret",
210
+ width: 16,
211
+ height: 16
212
+ })))) : null, /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(DuplicateIcon, null), "Duplicate"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(ProjectTemplateIcon, null), "Apply Template"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(ProjectTemplateConvertIcon, null), "Convert to Template"), /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(TrashIcon, null), "Delete")));
213
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProjectMenuSliderStyle, null), /*#__PURE__*/React.createElement(Menu, {
214
+ open: open,
215
+ onOpen: () => setOpen(true),
216
+ onClose: handleClose,
217
+ position: "bottom-end",
218
+ menuClassName: sourceModuleLoaded ? "project-options-menu" : undefined,
219
+ target: /*#__PURE__*/React.createElement(IconButton, {
220
+ type: "button",
221
+ variant: "text gray",
222
+ size: size,
223
+ className: className,
224
+ active: open
225
+ }, /*#__PURE__*/React.createElement(TreeDotsIcon, null))
226
+ }, sourceModuleLoaded ? /*#__PURE__*/React.createElement(ResizeTransition, {
227
+ in: true,
228
+ style: {
229
+ height,
230
+ width: PROJECT_MENU_WIDTH
231
+ }
232
+ }, /*#__PURE__*/React.createElement("div", {
233
+ style: {
234
+ position: "relative",
235
+ overflow: "hidden"
236
+ }
237
+ }, /*#__PURE__*/React.createElement(SlideLeftRightTransition, {
238
+ in: view === "index",
239
+ direction: isLeft ? "left" : "right"
240
+ }, /*#__PURE__*/React.createElement("div", {
241
+ ref: measure,
242
+ style: {
243
+ width: PROJECT_MENU_WIDTH
244
+ }
245
+ }, indexView)), /*#__PURE__*/React.createElement(SlideLeftRightTransition, {
246
+ in: view === "repositories",
247
+ direction: isLeft ? "left" : "right"
248
+ }, /*#__PURE__*/React.createElement("div", {
249
+ ref: measure,
250
+ style: {
251
+ width: PROJECT_MENU_WIDTH
252
+ }
253
+ }, /*#__PURE__*/React.createElement(MenuHeader, {
254
+ title: "Repositories",
255
+ leftElement: /*#__PURE__*/React.createElement(IconButton, {
256
+ type: "button",
257
+ variant: "text gray",
258
+ size: "small",
259
+ onClick: backToIndex,
260
+ "aria-label": "Back"
261
+ }, /*#__PURE__*/React.createElement(ArrowLeftIcon, null))
262
+ }), /*#__PURE__*/React.createElement(StyledProjectMenu, null, /*#__PURE__*/React.createElement(List, {
263
+ style: {
264
+ padding: "8px 0"
265
+ },
266
+ tabIndex: -1
267
+ }, sortedRepos.map(repo => {
268
+ const RepoIcon = repositoryIcon(repo);
269
+ return /*#__PURE__*/React.createElement(ListItem, {
270
+ key: repo.id,
271
+ className: "repo-row",
272
+ onClick: () => handleOpenRepository()
273
+ }, /*#__PURE__*/React.createElement(RepoIcon, null), /*#__PURE__*/React.createElement("span", {
274
+ className: "repo-name"
275
+ }, repositoryMenuLabel(repo)));
276
+ }), sortedRepos.length > 0 ? /*#__PURE__*/React.createElement(ListSeparator, null) : null, sortedRepos.length > 0 && canManageProjectRepositories ? /*#__PURE__*/React.createElement(ListItem, {
277
+ onClick: handleOpenWebhookLogs
278
+ }, /*#__PURE__*/React.createElement(AccessLogIcon, null), "Webhook Logs") : null, /*#__PURE__*/React.createElement(ListItem, {
279
+ onClick: handleConnect
280
+ }, /*#__PURE__*/React.createElement(GitRepositoryConnectIcon, null), "Connect Repository"))))))) : indexView), /*#__PURE__*/React.createElement(ConnectRepositoryDialog, {
281
+ open: connectOpen,
282
+ onClose: () => setConnectOpen(false),
283
+ onConnect: handleConnected,
284
+ repositories: connectableRepos,
285
+ connections: PROJECT_MENU_CONNECTIONS
286
+ }), /*#__PURE__*/React.createElement(WebhookLogsDialog, {
287
+ open: webhookLogsOpen,
288
+ onClose: () => setWebhookLogsOpen(false),
289
+ repositoryIds: sortedRepos.map(repo => repo.id)
290
+ }), /*#__PURE__*/React.createElement(Dialog, {
291
+ open: infoOpen,
292
+ onClose: () => setInfoOpen(false),
293
+ enableBackgroundClick: true
294
+ }, /*#__PURE__*/React.createElement(Dialog.Title, null, "Open Repository"), /*#__PURE__*/React.createElement(Dialog.ContentDivider, null), /*#__PURE__*/React.createElement(Dialog.Content, null, /*#__PURE__*/React.createElement(Body2, null, "In production, this click would close the menu and open the repository in a new browser tab.")), /*#__PURE__*/React.createElement(Dialog.ContentDivider, null), /*#__PURE__*/React.createElement(Dialog.Actions, null, /*#__PURE__*/React.createElement(Button, {
295
+ variant: "primary",
296
+ onClick: () => setInfoOpen(false)
297
+ }, "Got it"))), /*#__PURE__*/React.createElement(StyledToastAnchor, null, /*#__PURE__*/React.createElement(SlideFromTop, {
298
+ in: toastOpen
299
+ }, /*#__PURE__*/React.createElement(ToastMessage, {
300
+ key: toastKey,
301
+ className: "c-toast-message",
302
+ type: "success",
303
+ text: "Repository connected.",
304
+ dismissible: true,
305
+ dropShadow: true,
306
+ timeout: 3000,
307
+ onClose: () => setToastOpen(false)
308
+ }))));
309
+ };
310
+ ProjectOptionsMenu.displayName = "ProjectOptionsMenu";
311
+ //# sourceMappingURL=ProjectOptionsMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectOptionsMenu.js","names":["React","useCallback","useState","styled","createGlobalStyle","ConnectRepositoryDialog","WEBHOOK_CONNECTIONS","WEBHOOK_REPOSITORIES","WebhookLogsDialog","Badge","Button","CompleteCheckbox","Dialog","IconButton","AccessLogIcon","ArrowLeftIcon","CaretRightIcon","CheckboxBlankTogglerIcon","DownloadIcon","DuplicateIcon","EditIcon","GitHubIcon","GitIcon","GitLabIcon","GitRepositoryConnectIcon","GitRepositoryIcon","InsertLinkIcon","LabelsIcon","NotificationBellIcon","ProjectTemplateConvertIcon","ProjectTemplateIcon","StarIcon","TrashIcon","TreeDotsIcon","List","ListItem","ListSeparator","Menu","MenuHeader","ToastMessage","ResizeTransition","SlideFromTop","SlideLeftRightTransition","Body2","StyledProjectMenu","div","withConfig","displayName","componentId","PROJECT_MENU_CONNECTIONS","PROJECT_MENU_REPOSITORIES","map","repo","id","name","path","connectionId","repositoryMenuLabel","connection","find","c","repositoryIcon","service","PROJECT_MENU_WIDTH","ProjectMenuSliderStyle","StyledToastAnchor","ProjectOptionsMenu","_ref","_ref$sourceModuleLoad","sourceModuleLoaded","_ref$initialConnected","initialConnectedRepositories","_ref$canManageProject","canManageProjectRepositories","className","size","_useState","open","setOpen","_useState2","view","setView","_useState3","webhookLogsOpen","setWebhookLogsOpen","_useState4","isLeft","setIsLeft","_useState5","height","setHeight","_useState6","connectedRepos","setConnectedRepos","_useState7","connectOpen","setConnectOpen","_useState8","infoOpen","setInfoOpen","_useState9","toastOpen","setToastOpen","_useState0","toastKey","setToastKey","connectableRepos","filter","r","some","sortedRepos","sort","a","b","localeCompare","measure","node","offsetHeight","goToRepositories","backToIndex","handleClose","handleConnected","prev","k","handleConnect","handleOpenRepository","handleOpenWebhookLogs","indexView","createElement","style","padding","tabIndex","primary","completed","Fragment","onClick","length","isStandalone","dimension","value","width","onOpen","onClose","position","menuClassName","undefined","target","type","variant","active","in","overflow","direction","ref","title","leftElement","RepoIcon","key","onConnect","repositories","connections","repositoryIds","enableBackgroundClick","Title","ContentDivider","Content","Actions","text","dismissible","dropShadow","timeout"],"sources":["../../../../src/presentation/shared/ProjectOptionsMenu.tsx"],"sourcesContent":["import React, { ElementType, ReactElement, useCallback, useState } from \"react\";\n\nimport styled, { createGlobalStyle } from \"styled-components\";\n\nimport {\n Connection,\n ConnectRepositoryDialog,\n Repository,\n} from \"./ConnectRepositoryDialog\";\nimport {\n WEBHOOK_CONNECTIONS,\n WEBHOOK_REPOSITORIES,\n WebhookLogsDialog,\n} from \"./WebhookLogsDialog\";\nimport { Badge } from \"../../components/Badge\";\nimport { Button } from \"../../components/Button\";\nimport { CompleteCheckbox } from \"../../components/CompleteCheckbox\";\nimport { Dialog } from \"../../components/Dialog\";\nimport { IconButton } from \"../../components/IconButton\";\nimport {\n AccessLogIcon,\n ArrowLeftIcon,\n CaretRightIcon,\n CheckboxBlankTogglerIcon,\n DownloadIcon,\n DuplicateIcon,\n EditIcon,\n GitHubIcon,\n GitIcon,\n GitLabIcon,\n GitRepositoryConnectIcon,\n GitRepositoryIcon,\n InsertLinkIcon,\n LabelsIcon,\n NotificationBellIcon,\n ProjectTemplateConvertIcon,\n ProjectTemplateIcon,\n StarIcon,\n TrashIcon,\n TreeDotsIcon,\n} from \"../../components/Icons\";\nimport { List, ListItem, ListSeparator } from \"../../components/List\";\nimport { Menu, MenuHeader } from \"../../components/Menu\";\nimport { ToastMessage } from \"../../components/ToastMessage\";\nimport {\n ResizeTransition,\n SlideFromTop,\n SlideLeftRightTransition,\n} from \"../../components/Transitions\";\nimport { Body2 } from \"../../components/Typography\";\n\n/* Project \"...\" options menu (Menu + List with leading-icon items). Two items\n (Favorite, Subscribe) have a checkbox on the right. Clicks are no-ops. When\n the `source` module is loaded a Repositories item drills in to a submenu.\n\n Shared by the project page header (Project Repos presentation) and the\n Projects listing (Projects List presentation), so the \"...\" menu behaves the\n same wherever a project is shown. */\nconst StyledProjectMenu = styled.div`\n .toggle-item {\n justify-content: space-between;\n }\n\n .toggle-item .opt-left {\n display: flex;\n align-items: center;\n min-width: 0;\n }\n\n .toggle-item .opt-left svg {\n margin-right: 8px;\n flex-shrink: 0;\n }\n\n /* the app renders the toggle as a small rounded (not circular) CompleteCheckbox */\n .toggle-item .c-complete-checkbox {\n width: 16px;\n height: 16px;\n border-radius: 3px;\n align-self: center;\n flex-shrink: 0;\n }\n\n /* \"Repositories\" item: caret pushed to the right edge */\n .submenu-item {\n justify-content: space-between;\n }\n\n /* right side of the \"Repositories\" item: connected-count badge + caret */\n .submenu-item .repo-right {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n /* muted count badge — a quiet neutral pill rather than the bold primary\n default, so it informs without pulling focus */\n .submenu-item .repo-right .c-badge {\n background-color: var(--color-theme-300);\n color: var(--color-theme-700);\n }\n\n .submenu-item .repo-caret {\n flex-shrink: 0;\n fill: var(--color-theme-600);\n }\n\n /* a connected-repository row inside the submenu — long \"path (Connection,\n Type)\" labels truncate with an ellipsis rather than wrapping */\n .repo-row {\n min-width: 0;\n }\n\n .repo-row > svg {\n flex-shrink: 0;\n }\n\n .repo-name {\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n`;\n\n/* The project \"...\" menu shares the Webhook Logs dialog's repository /\n * connection universe, so a repository connected here is one that dialog can\n * pre-filter by. `WebhookConnection` and `Connection` share a shape, and a\n * `WebhookRepository`'s `path` maps onto a `Repository`'s `name`. */\nconst PROJECT_MENU_CONNECTIONS: Connection[] = WEBHOOK_CONNECTIONS;\nconst PROJECT_MENU_REPOSITORIES: Repository[] = WEBHOOK_REPOSITORIES.map(\n (repo) => ({ id: repo.id, name: repo.path, connectionId: repo.connectionId })\n);\n\n/** Submenu row label for a connected repository: \"path (Connection)\". The\n * service type is omitted because the leading provider icon already conveys\n * it. */\nconst repositoryMenuLabel = (repo: Repository): string => {\n const connection = PROJECT_MENU_CONNECTIONS.find(\n (c) => c.id === repo.connectionId\n );\n return connection ? `${repo.name} (${connection.name})` : repo.name;\n};\n\n/** Provider glyph for a connected repository: GitHub / GitLab for those\n * services, and the generic Git mark for anything else (e.g. an upcoming\n * Bitbucket connection). */\nconst repositoryIcon = (repo: Repository): ElementType => {\n const connection = PROJECT_MENU_CONNECTIONS.find(\n (c) => c.id === repo.connectionId\n );\n switch (connection?.service) {\n case \"github\":\n return GitHubIcon;\n case \"gitlab\":\n return GitLabIcon;\n default:\n return GitIcon;\n }\n};\n\n/** Width of the project \"...\" menu (matches the DS \"normal\" menu mode). */\nconst PROJECT_MENU_WIDTH = 260;\n\n/* The menu drills in place (index → Repositories), so the paper must clip the\n sliding panels and give them a positioning context. */\nconst ProjectMenuSliderStyle = createGlobalStyle`\n .c-simple-menu__paper.project-options-menu {\n overflow: hidden;\n position: relative;\n }\n`;\n\n/* Toast anchor — fixed, upper-right corner (the toast slides down from the\n top). The wrapper ignores pointer events so it never blocks the page; only\n the toast itself is interactive. */\nconst StyledToastAnchor = styled.div`\n position: fixed;\n top: 16px;\n right: 16px;\n z-index: 10000;\n pointer-events: none;\n\n .c-toast-message {\n pointer-events: auto;\n }\n`;\n\nexport interface ProjectOptionsMenuProps {\n /** When the `source` module is loaded, show the Repositories section. */\n sourceModuleLoaded?: boolean;\n /** Repositories already connected to the project when the menu first mounts. */\n initialConnectedRepositories?: Repository[];\n /**\n * Whether the current user can manage the project's repositories. Gates the\n * Webhook Logs entry (a manage-only action) — see note 09, Permissions.\n */\n canManageProjectRepositories?: boolean;\n /** Extra class on the TreeDots trigger (e.g. for hover-reveal in a listing). */\n className?: string;\n /** IconButton size of the trigger (omit for the default/regular size). */\n size?: \"small\" | \"big\";\n}\n\n/**\n * The project \"...\" options menu. When the `source` module is loaded it gains\n * a **Repositories** item that, instead of flying out to the side, **drills in\n * within the same menu** (the pattern used across the app — see `Filter`): the\n * index slides out to the left and the Repositories view (a back-arrow header,\n * the connected repositories sorted by name, and a **Connect Repository**\n * action) slides in. Connecting adds a repository to the list; clicking one\n * would, in production, open it in a new tab (surfaced here via a dialog).\n */\nexport const ProjectOptionsMenu = ({\n sourceModuleLoaded = false,\n initialConnectedRepositories = [],\n canManageProjectRepositories = true,\n className,\n size,\n}: ProjectOptionsMenuProps): ReactElement => {\n const [open, setOpen] = useState(false);\n const [view, setView] = useState<\"index\" | \"repositories\">(\"index\");\n const [webhookLogsOpen, setWebhookLogsOpen] = useState(false);\n const [isLeft, setIsLeft] = useState(true);\n const [height, setHeight] = useState(0);\n // Connected repositories drive the count badge on the Repositories item. In\n // production this count comes from the project's `count_repositories` counter,\n // kept current via pusher/websocket events, so the badge reflects repositories\n // connected or disconnected by anyone — not just the current user's actions.\n const [connectedRepos, setConnectedRepos] = useState<Repository[]>(\n initialConnectedRepositories\n );\n const [connectOpen, setConnectOpen] = useState(false);\n const [infoOpen, setInfoOpen] = useState(false);\n const [toastOpen, setToastOpen] = useState(false);\n // Bumped on each connect so the toast remounts and its auto-hide timer\n // restarts from the moment it is shown.\n const [toastKey, setToastKey] = useState(0);\n\n // Repositories still available to connect (not already on the project).\n const connectableRepos = PROJECT_MENU_REPOSITORIES.filter(\n (r) => !connectedRepos.some((c) => c.id === r.id)\n );\n\n // Connected repositories are listed in the submenu sorted by name.\n const sortedRepos = [...connectedRepos].sort((a, b) =>\n a.name.localeCompare(b.name)\n );\n\n // Each view measures itself as it mounts so the paper can animate its height.\n const measure = useCallback((node: HTMLDivElement | null) => {\n if (node) {\n setHeight(node.offsetHeight);\n }\n }, []);\n\n const goToRepositories = (): void => {\n setView(\"repositories\");\n setIsLeft(true);\n };\n\n const backToIndex = (): void => {\n setView(\"index\");\n setIsLeft(false);\n };\n\n const handleClose = (): void => {\n setOpen(false);\n // Reset to the index so the next open starts at the top level.\n setView(\"index\");\n setIsLeft(true);\n };\n\n const handleConnected = (repo: Repository): void => {\n setConnectedRepos((prev) =>\n prev.some((r) => r.id === repo.id) ? prev : [...prev, repo]\n );\n setToastOpen(true);\n setToastKey((k) => k + 1);\n };\n\n const handleConnect = (): void => {\n handleClose();\n setConnectOpen(true);\n };\n\n // In production this closes the menu and opens the repository in a new tab;\n // in the mock we surface that behaviour in a small dialog instead.\n const handleOpenRepository = (): void => {\n handleClose();\n setInfoOpen(true);\n };\n\n const handleOpenWebhookLogs = (): void => {\n handleClose();\n setWebhookLogsOpen(true);\n };\n\n const indexView = (\n <StyledProjectMenu>\n <List style={{ padding: \"8px 0\" }} tabIndex={-1}>\n <ListItem>\n <EditIcon />\n Edit\n </ListItem>\n <ListItem className=\"toggle-item\">\n <span className=\"opt-left\">\n <StarIcon />\n Mark as Favorite\n </span>\n <CompleteCheckbox primary completed />\n </ListItem>\n <ListItem className=\"toggle-item\">\n <span className=\"opt-left\">\n <NotificationBellIcon />\n Subscribe to Everything\n </span>\n <CompleteCheckbox primary completed={false} />\n </ListItem>\n <ListItem>\n <LabelsIcon />\n Manage Task Labels\n </ListItem>\n <ListItem>\n <InsertLinkIcon />\n Copy Link\n </ListItem>\n <ListSeparator />\n <ListItem>\n <CheckboxBlankTogglerIcon />\n Complete\n </ListItem>\n <ListItem>\n <DownloadIcon />\n Export\n </ListItem>\n {sourceModuleLoaded ? (\n <>\n <ListSeparator />\n <ListItem\n className=\"toggle-item submenu-item\"\n onClick={goToRepositories}\n >\n <span className=\"opt-left\">\n <GitRepositoryIcon />\n Repositories\n </span>\n <span className=\"repo-right\">\n {connectedRepos.length > 0 ? (\n <Badge\n isStandalone\n dimension={16}\n value={connectedRepos.length}\n />\n ) : null}\n <CaretRightIcon className=\"repo-caret\" width={16} height={16} />\n </span>\n </ListItem>\n </>\n ) : null}\n <ListSeparator />\n <ListItem>\n <DuplicateIcon />\n Duplicate\n </ListItem>\n <ListItem>\n <ProjectTemplateIcon />\n Apply Template\n </ListItem>\n <ListItem>\n <ProjectTemplateConvertIcon />\n Convert to Template\n </ListItem>\n <ListSeparator />\n <ListItem>\n <TrashIcon />\n Delete\n </ListItem>\n </List>\n </StyledProjectMenu>\n );\n\n return (\n <>\n <ProjectMenuSliderStyle />\n <Menu\n open={open}\n onOpen={() => setOpen(true)}\n onClose={handleClose}\n position=\"bottom-end\"\n menuClassName={sourceModuleLoaded ? \"project-options-menu\" : undefined}\n target={\n <IconButton\n type=\"button\"\n variant=\"text gray\"\n size={size}\n className={className}\n active={open}\n >\n <TreeDotsIcon />\n </IconButton>\n }\n >\n {sourceModuleLoaded ? (\n <ResizeTransition in style={{ height, width: PROJECT_MENU_WIDTH }}>\n <div style={{ position: \"relative\", overflow: \"hidden\" }}>\n <SlideLeftRightTransition\n in={view === \"index\"}\n direction={isLeft ? \"left\" : \"right\"}\n >\n <div ref={measure} style={{ width: PROJECT_MENU_WIDTH }}>\n {indexView}\n </div>\n </SlideLeftRightTransition>\n <SlideLeftRightTransition\n in={view === \"repositories\"}\n direction={isLeft ? \"left\" : \"right\"}\n >\n <div ref={measure} style={{ width: PROJECT_MENU_WIDTH }}>\n <MenuHeader\n title=\"Repositories\"\n leftElement={\n <IconButton\n type=\"button\"\n variant=\"text gray\"\n size=\"small\"\n onClick={backToIndex}\n aria-label=\"Back\"\n >\n <ArrowLeftIcon />\n </IconButton>\n }\n />\n <StyledProjectMenu>\n <List style={{ padding: \"8px 0\" }} tabIndex={-1}>\n {sortedRepos.map((repo) => {\n const RepoIcon = repositoryIcon(repo);\n return (\n <ListItem\n key={repo.id}\n className=\"repo-row\"\n onClick={() => handleOpenRepository()}\n >\n <RepoIcon />\n <span className=\"repo-name\">\n {repositoryMenuLabel(repo)}\n </span>\n </ListItem>\n );\n })}\n {sortedRepos.length > 0 ? <ListSeparator /> : null}\n {sortedRepos.length > 0 &&\n canManageProjectRepositories ? (\n <ListItem onClick={handleOpenWebhookLogs}>\n <AccessLogIcon />\n Webhook Logs\n </ListItem>\n ) : null}\n <ListItem onClick={handleConnect}>\n <GitRepositoryConnectIcon />\n Connect Repository\n </ListItem>\n </List>\n </StyledProjectMenu>\n </div>\n </SlideLeftRightTransition>\n </div>\n </ResizeTransition>\n ) : (\n indexView\n )}\n </Menu>\n\n <ConnectRepositoryDialog\n open={connectOpen}\n onClose={() => setConnectOpen(false)}\n onConnect={handleConnected}\n repositories={connectableRepos}\n connections={PROJECT_MENU_CONNECTIONS}\n />\n\n <WebhookLogsDialog\n open={webhookLogsOpen}\n onClose={() => setWebhookLogsOpen(false)}\n repositoryIds={sortedRepos.map((repo) => repo.id)}\n />\n\n <Dialog\n open={infoOpen}\n onClose={() => setInfoOpen(false)}\n enableBackgroundClick\n >\n <Dialog.Title>Open Repository</Dialog.Title>\n <Dialog.ContentDivider />\n <Dialog.Content>\n <Body2>\n In production, this click would close the menu and open the\n repository in a new browser tab.\n </Body2>\n </Dialog.Content>\n <Dialog.ContentDivider />\n <Dialog.Actions>\n <Button variant=\"primary\" onClick={() => setInfoOpen(false)}>\n Got it\n </Button>\n </Dialog.Actions>\n </Dialog>\n\n <StyledToastAnchor>\n <SlideFromTop in={toastOpen}>\n <ToastMessage\n key={toastKey}\n className=\"c-toast-message\"\n type=\"success\"\n text=\"Repository connected.\"\n dismissible\n dropShadow\n timeout={3000}\n onClose={() => setToastOpen(false)}\n />\n </SlideFromTop>\n </StyledToastAnchor>\n </>\n );\n};\n\nProjectOptionsMenu.displayName = \"ProjectOptionsMenu\";\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,203 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ /** Stacked-chart series palette, same order as TotalTrackedHoursChart.js. */
3
+ export declare const CHART_SERIES_COLORS: string[];
4
+ /** Ring/section colour pairs used by the app's Projects Overview widget. */
5
+ export declare const OVERVIEW_SECTION_COLORS: {
6
+ tasks: {
7
+ color: string;
8
+ track: string;
9
+ };
10
+ time: {
11
+ color: string;
12
+ track: string;
13
+ };
14
+ budget: {
15
+ color: string;
16
+ track: string;
17
+ };
18
+ };
19
+ export declare const WidgetGrid: import("styled-components").StyledComponent<"div", any, {}, never>;
20
+ export interface WidgetGroupByProps {
21
+ options: {
22
+ id: string;
23
+ name: string;
24
+ }[];
25
+ /** Initially selected option id (the mock keeps its own state after that). */
26
+ initial?: string;
27
+ onChange?: (id: string) => void;
28
+ }
29
+ /** The sort-lines icon button + radio list every widget corner uses. */
30
+ export declare const WidgetGroupBy: {
31
+ ({ options, initial, onChange, }: WidgetGroupByProps): ReactElement;
32
+ displayName: string;
33
+ };
34
+ /** The app's completed-widget periods (CompletedWidgetTarget radio list). */
35
+ export declare const PERIOD_OPTIONS: {
36
+ id: string;
37
+ name: string;
38
+ }[];
39
+ export interface PeriodPickerProps {
40
+ selected: string;
41
+ onChange: (id: string) => void;
42
+ }
43
+ /** One labelled period control (ValueButton + radio list) that a whole
44
+ * section of period-scoped widgets can share. */
45
+ export declare const PeriodPicker: {
46
+ ({ selected, onChange, }: PeriodPickerProps): ReactElement;
47
+ displayName: string;
48
+ };
49
+ export interface StatWidgetProps {
50
+ /** Preformatted total ("135", "1.4K"). */
51
+ value: string;
52
+ /** Muted unit beside the total ("H", "USD"). */
53
+ unit?: string;
54
+ title: string;
55
+ description: string;
56
+ linkText?: string;
57
+ /** Red treatment (overdue / underestimated above zero). */
58
+ alert?: boolean;
59
+ /** Green treatment (e.g. positive profit). */
60
+ success?: boolean;
61
+ /** Group-by picker in the top-right corner. */
62
+ groupBy?: WidgetGroupByProps;
63
+ /** Alternative top-right adornment (e.g. a period icon). */
64
+ cornerControl?: ReactNode;
65
+ /** Extra content between description and link (e.g. WidgetRankedList). */
66
+ children?: ReactNode;
67
+ }
68
+ export declare const StatWidget: {
69
+ ({ value, unit, title, description, linkText, alert, success, groupBy, cornerControl, children, }: StatWidgetProps): ReactElement;
70
+ displayName: string;
71
+ };
72
+ export interface RankedListItem {
73
+ name: string;
74
+ value: string;
75
+ }
76
+ /** The striped name/count rows inside a tall stat widget. */
77
+ export declare const WidgetRankedList: {
78
+ ({ items, }: {
79
+ items: RankedListItem[];
80
+ }): ReactElement;
81
+ displayName: string;
82
+ };
83
+ export interface OverviewSectionData {
84
+ id: string;
85
+ /** Preformatted pair ("956 of 1.4K", "1.2K / 8.3K"). */
86
+ value: string;
87
+ /** Muted unit after the value ("Hours", "USD"). */
88
+ unit?: string;
89
+ description: string;
90
+ /** Info-icon tooltip next to the description. */
91
+ explainer?: string;
92
+ linkText: string;
93
+ /** Accent-line + ring colour (a data colour). */
94
+ color: string;
95
+ /** Ring track colour (the translucent tint of `color`). */
96
+ trackColor: string;
97
+ /** 0–100+; above 100 the section and its ring go red. */
98
+ progress: number;
99
+ }
100
+ export interface OverviewWidgetProps {
101
+ title: string;
102
+ subtitle: string;
103
+ /** Up to three sections, outer ring first. */
104
+ sections: OverviewSectionData[];
105
+ /** Top-right control (e.g. the currency picker). */
106
+ headerRight?: ReactNode;
107
+ }
108
+ /** The big overview card: accent-line metric sections + nested rings.
109
+ * Hovering a section highlights its ring and mutes the other rings,
110
+ * exactly like the app's Projects Overview. */
111
+ export declare const OverviewWidget: {
112
+ ({ title, subtitle, sections, headerRight, }: OverviewWidgetProps): ReactElement;
113
+ displayName: string;
114
+ };
115
+ export interface AreaChartWidgetProps {
116
+ title: string;
117
+ linkText?: string;
118
+ /** The series, one value per day. */
119
+ points: number[];
120
+ /** X labels, spread evenly under the plot (pass a subset). */
121
+ xLabels: string[];
122
+ /** Y tick values; min/max define the scale. */
123
+ yTicks: number[];
124
+ }
125
+ /** Sharp-edged line with a soft gradient below, like "Number of Open Tasks". */
126
+ export declare const AreaChartWidget: {
127
+ ({ title, linkText, points, xLabels, yTicks, }: AreaChartWidgetProps): ReactElement;
128
+ displayName: string;
129
+ };
130
+ export interface DailyDeltaPoint {
131
+ /** Count above the axis (new tasks). */
132
+ up: number;
133
+ /** Count below the axis (completed tasks). */
134
+ down: number;
135
+ }
136
+ export interface DailyDeltaChartWidgetProps {
137
+ title: string;
138
+ linkText?: string;
139
+ data: DailyDeltaPoint[];
140
+ /** X labels, spread evenly under the plot (pass a subset). */
141
+ xLabels: string[];
142
+ /** Scale above the axis. */
143
+ upMax: number;
144
+ /** Scale below the axis (can differ — the axis sits off-centre). */
145
+ downMax: number;
146
+ /** Tick values above the axis (0 and below-axis ticks are derived). */
147
+ yTicksUp: number[];
148
+ /** Tick values below the axis. */
149
+ yTicksDown: number[];
150
+ }
151
+ /** Thin daily bars above/below a zero line, like "New vs Completed Tasks". */
152
+ export declare const DailyDeltaChartWidget: {
153
+ ({ title, linkText, data, xLabels, upMax, downMax, yTicksUp, yTicksDown, }: DailyDeltaChartWidgetProps): ReactElement;
154
+ displayName: string;
155
+ };
156
+ export interface LeaderboardRowData {
157
+ label: string;
158
+ /** Preformatted value on the right ("25:00"). */
159
+ value: string;
160
+ /** Bar length as % of the longest row (100 for the leader). */
161
+ percentOfMax: number;
162
+ /** Billable share 0–100 — fills the green part of the bar. */
163
+ billableShare: number;
164
+ }
165
+ export interface LeaderboardWidgetProps {
166
+ title: string;
167
+ description: string;
168
+ rows: LeaderboardRowData[];
169
+ groupBy?: WidgetGroupByProps;
170
+ }
171
+ /** Ranked bars: label, billable/non-billable bar, value — like Time's
172
+ * Leaderboard. Bar length = share of the leader; green = billable part. */
173
+ export declare const LeaderboardWidget: {
174
+ ({ title, description, rows, groupBy, }: LeaderboardWidgetProps): ReactElement;
175
+ displayName: string;
176
+ };
177
+ export interface StackedBarColumn {
178
+ label: string;
179
+ /** One value per series, bottom segment first (palette order). */
180
+ segments: number[];
181
+ }
182
+ export interface StackedBarChartWidgetProps {
183
+ title?: string;
184
+ /** Preformatted big total shown top-right ("318:11"). */
185
+ total?: string;
186
+ data: StackedBarColumn[];
187
+ /** Series names for the segment tooltips, palette order. */
188
+ seriesLabels: string[];
189
+ /** Y tick values; the max defines the scale. */
190
+ yTicks: number[];
191
+ /** Column width in px — the real charts are narrow (default 28). */
192
+ barWidth?: number;
193
+ /** Plot height in px (default 220 — this widget is usually taller). */
194
+ height?: number;
195
+ groupBy?: WidgetGroupByProps;
196
+ }
197
+ /** Narrow stacked time columns, like the Time dashboard's tracked-hours
198
+ * chart. Segment order and palette follow the real chart. */
199
+ export declare const StackedBarChartWidget: {
200
+ ({ title, total, data, seriesLabels, yTicks, barWidth, height, groupBy, }: StackedBarChartWidgetProps): ReactElement;
201
+ displayName: string;
202
+ };
203
+ //# sourceMappingURL=dashboardWidgets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardWidgets.d.ts","sourceRoot":"","sources":["../../../../src/presentation/shared/dashboardWidgets.tsx"],"names":[],"mappings":"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"}