@activecollab/components 2.0.397 → 2.0.399
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.
- package/dist/cjs/presentation/whiteboard/bottomDock.js +194 -0
- package/dist/cjs/presentation/whiteboard/bottomDock.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/canvasElements.js +877 -0
- package/dist/cjs/presentation/whiteboard/canvasElements.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/elements.js +816 -0
- package/dist/cjs/presentation/whiteboard/elements.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/fileElement.js +457 -0
- package/dist/cjs/presentation/whiteboard/fileElement.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/glyphs.js +67 -0
- package/dist/cjs/presentation/whiteboard/glyphs.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/inspector.js +884 -0
- package/dist/cjs/presentation/whiteboard/inspector.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/linkElement.js +357 -0
- package/dist/cjs/presentation/whiteboard/linkElement.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/outline.js +966 -0
- package/dist/cjs/presentation/whiteboard/outline.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/peopleMenu.js +516 -0
- package/dist/cjs/presentation/whiteboard/peopleMenu.js.map +1 -0
- package/dist/cjs/presentation/whiteboard/settingsMenu.js +177 -0
- package/dist/cjs/presentation/whiteboard/settingsMenu.js.map +1 -0
- package/dist/esm/presentation/whiteboard/bottomDock.d.ts +51 -0
- package/dist/esm/presentation/whiteboard/bottomDock.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/bottomDock.js +162 -0
- package/dist/esm/presentation/whiteboard/bottomDock.js.map +1 -0
- package/dist/esm/presentation/whiteboard/canvasElements.d.ts +61 -0
- package/dist/esm/presentation/whiteboard/canvasElements.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/canvasElements.js +746 -0
- package/dist/esm/presentation/whiteboard/canvasElements.js.map +1 -0
- package/dist/esm/presentation/whiteboard/elements.d.ts +180 -0
- package/dist/esm/presentation/whiteboard/elements.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/elements.js +736 -0
- package/dist/esm/presentation/whiteboard/elements.js.map +1 -0
- package/dist/esm/presentation/whiteboard/fileElement.d.ts +113 -0
- package/dist/esm/presentation/whiteboard/fileElement.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/fileElement.js +430 -0
- package/dist/esm/presentation/whiteboard/fileElement.js.map +1 -0
- package/dist/esm/presentation/whiteboard/glyphs.d.ts +32 -0
- package/dist/esm/presentation/whiteboard/glyphs.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/glyphs.js +50 -0
- package/dist/esm/presentation/whiteboard/glyphs.js.map +1 -0
- package/dist/esm/presentation/whiteboard/inspector.d.ts +100 -0
- package/dist/esm/presentation/whiteboard/inspector.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/inspector.js +753 -0
- package/dist/esm/presentation/whiteboard/inspector.js.map +1 -0
- package/dist/esm/presentation/whiteboard/linkElement.d.ts +97 -0
- package/dist/esm/presentation/whiteboard/linkElement.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/linkElement.js +327 -0
- package/dist/esm/presentation/whiteboard/linkElement.js.map +1 -0
- package/dist/esm/presentation/whiteboard/outline.d.ts +89 -0
- package/dist/esm/presentation/whiteboard/outline.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/outline.js +870 -0
- package/dist/esm/presentation/whiteboard/outline.js.map +1 -0
- package/dist/esm/presentation/whiteboard/peopleMenu.d.ts +44 -0
- package/dist/esm/presentation/whiteboard/peopleMenu.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/peopleMenu.js +440 -0
- package/dist/esm/presentation/whiteboard/peopleMenu.js.map +1 -0
- package/dist/esm/presentation/whiteboard/settingsMenu.d.ts +13 -0
- package/dist/esm/presentation/whiteboard/settingsMenu.d.ts.map +1 -0
- package/dist/esm/presentation/whiteboard/settingsMenu.js +155 -0
- package/dist/esm/presentation/whiteboard/settingsMenu.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import React, { useCallback, useMemo, useState } from "react";
|
|
3
|
+
import styled, { createGlobalStyle } from "styled-components";
|
|
4
|
+
import { Button } from "../../components/Button";
|
|
5
|
+
import { Checkbox } from "../../components/Checkbox";
|
|
6
|
+
import { ConfirmDialog } from "../../components/ConfirmDialog";
|
|
7
|
+
import { CounterButton } from "../../components/CounterButton";
|
|
8
|
+
import { Dialog } from "../../components/Dialog";
|
|
9
|
+
import { IconButton } from "../../components/IconButton";
|
|
10
|
+
import { AddCrossTinyIcon, CloseSmallIcon, CrownBlankIcon, CrownSelectedIcon, PeopleIcon, SortGeneralIcon } from "../../components/Icons";
|
|
11
|
+
import { Label } from "../../components/Label";
|
|
12
|
+
import { List, ListItem } from "../../components/List";
|
|
13
|
+
import { Menu, MenuHeader } from "../../components/Menu";
|
|
14
|
+
import { Select } from "../../components/Select";
|
|
15
|
+
import { SelectTrigger } from "../../components/SelectTrigger";
|
|
16
|
+
import { Textarea } from "../../components/Textarea";
|
|
17
|
+
import { Tooltip } from "../../components/Tooltip";
|
|
18
|
+
import { Body2, Caption1 } from "../../components/Typography";
|
|
19
|
+
import { AVATAR_COLORS, RoundAvatar } from "../shared";
|
|
20
|
+
|
|
21
|
+
/* ------------------------------------------------------------------ */
|
|
22
|
+
/* People menu (copy of the project header People popover) */
|
|
23
|
+
/* ------------------------------------------------------------------ */
|
|
24
|
+
|
|
25
|
+
/* 12 people (9 members + 3 clients) so the 330px list visibly scrolls.
|
|
26
|
+
Jasna (id 1) starts as the board manager. */
|
|
27
|
+
export const BOARD_MEMBERS = [{
|
|
28
|
+
id: 1,
|
|
29
|
+
name: "Jasna Simic",
|
|
30
|
+
initials: "JS",
|
|
31
|
+
color: AVATAR_COLORS.purple
|
|
32
|
+
}, {
|
|
33
|
+
id: 2,
|
|
34
|
+
name: "Marko Antic",
|
|
35
|
+
initials: "MA",
|
|
36
|
+
color: AVATAR_COLORS.teal
|
|
37
|
+
}, {
|
|
38
|
+
id: 3,
|
|
39
|
+
name: "Dario Kovac",
|
|
40
|
+
initials: "DK",
|
|
41
|
+
color: AVATAR_COLORS.orange
|
|
42
|
+
}, {
|
|
43
|
+
id: 4,
|
|
44
|
+
name: "Ivana Lukic",
|
|
45
|
+
initials: "IL",
|
|
46
|
+
color: AVATAR_COLORS.green
|
|
47
|
+
}, {
|
|
48
|
+
id: 5,
|
|
49
|
+
name: "Petar Novak",
|
|
50
|
+
initials: "PN",
|
|
51
|
+
color: AVATAR_COLORS.blue
|
|
52
|
+
}, {
|
|
53
|
+
id: 6,
|
|
54
|
+
name: "Sara Milic",
|
|
55
|
+
initials: "SM",
|
|
56
|
+
color: AVATAR_COLORS.yellow
|
|
57
|
+
}, {
|
|
58
|
+
id: 7,
|
|
59
|
+
name: "Luka Peric",
|
|
60
|
+
initials: "LP",
|
|
61
|
+
color: AVATAR_COLORS.purple
|
|
62
|
+
}, {
|
|
63
|
+
id: 8,
|
|
64
|
+
name: "Mia Radic",
|
|
65
|
+
initials: "MR",
|
|
66
|
+
color: AVATAR_COLORS.teal
|
|
67
|
+
}, {
|
|
68
|
+
id: 9,
|
|
69
|
+
name: "Nikola Vukic",
|
|
70
|
+
initials: "NV",
|
|
71
|
+
color: AVATAR_COLORS.orange
|
|
72
|
+
}, {
|
|
73
|
+
id: 10,
|
|
74
|
+
name: "Ana Klein",
|
|
75
|
+
initials: "AK",
|
|
76
|
+
color: AVATAR_COLORS.green,
|
|
77
|
+
isClient: true
|
|
78
|
+
}, {
|
|
79
|
+
id: 11,
|
|
80
|
+
name: "Tom Becker",
|
|
81
|
+
initials: "TB",
|
|
82
|
+
color: AVATAR_COLORS.blue,
|
|
83
|
+
isClient: true
|
|
84
|
+
}, {
|
|
85
|
+
id: 12,
|
|
86
|
+
name: "Eva Fischer",
|
|
87
|
+
initials: "EF",
|
|
88
|
+
color: AVATAR_COLORS.yellow,
|
|
89
|
+
isClient: true
|
|
90
|
+
}];
|
|
91
|
+
|
|
92
|
+
/* Mirrors ProjectPeopleWrapper + view.project_top_bar.less:
|
|
93
|
+
Menu 260px, "People" MenuHeader with an (inert) "+", 330px scroll area,
|
|
94
|
+
Members/Clients Caption1 section labels, rows with hover-only options. */
|
|
95
|
+
export const StyledPeopleMenu = styled.div.withConfig({
|
|
96
|
+
displayName: "peopleMenu__StyledPeopleMenu",
|
|
97
|
+
componentId: "sc-uidi4w-0"
|
|
98
|
+
})([".people-scroll{max-height:330px;overflow-y:auto;overflow-x:hidden;padding-bottom:8px;}.people-section-label{display:block;margin:8px 0;padding:0 16px;}.member-item{justify-content:space-between;margin:4px 8px;padding:0 8px;border-radius:4px;cursor:auto;}.member-options{display:none;align-items:center;}.member-item:hover .member-options{display:flex;}.member-side{display:flex;align-items:center;flex-shrink:0;}.member-user{display:inline-flex;align-items:center;gap:8px;padding:2px 0;overflow:hidden;.member-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}}.manager-avatar{outline:2px #ffcc6b solid;outline-offset:-2px;}"]);
|
|
99
|
+
/* Rows sorted by name. Manager: gold crown + ring, no hover options (the
|
|
100
|
+
role must be handed over before removal). Crown option only on non-client
|
|
101
|
+
rows; X on everyone else. */
|
|
102
|
+
export const PeopleMenuSection = _ref => {
|
|
103
|
+
let label = _ref.label,
|
|
104
|
+
people = _ref.people,
|
|
105
|
+
managerId = _ref.managerId,
|
|
106
|
+
onMakeManager = _ref.onMakeManager,
|
|
107
|
+
onRemove = _ref.onRemove;
|
|
108
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Caption1, {
|
|
109
|
+
weight: "bold",
|
|
110
|
+
className: "people-section-label"
|
|
111
|
+
}, label), /*#__PURE__*/React.createElement(List, null, [...people].sort((a, b) => a.name.localeCompare(b.name)).map(person => {
|
|
112
|
+
const isManager = person.id === managerId;
|
|
113
|
+
return /*#__PURE__*/React.createElement(ListItem, {
|
|
114
|
+
key: person.id,
|
|
115
|
+
className: "member-item"
|
|
116
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
117
|
+
className: "member-user"
|
|
118
|
+
}, /*#__PURE__*/React.createElement(RoundAvatar, {
|
|
119
|
+
$bg: person.color,
|
|
120
|
+
$bordered: false,
|
|
121
|
+
className: isManager ? "manager-avatar" : undefined
|
|
122
|
+
}, person.initials), /*#__PURE__*/React.createElement(Body2, {
|
|
123
|
+
className: "member-name"
|
|
124
|
+
}, person.name)), /*#__PURE__*/React.createElement("span", {
|
|
125
|
+
className: "member-side"
|
|
126
|
+
}, isManager ? /*#__PURE__*/React.createElement(CrownSelectedIcon, {
|
|
127
|
+
fill: "#FFCC6B"
|
|
128
|
+
}) : null, /*#__PURE__*/React.createElement("span", {
|
|
129
|
+
className: "member-options"
|
|
130
|
+
}, !isManager && !person.isClient ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
131
|
+
title: "Set as Whiteboard Manager"
|
|
132
|
+
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
133
|
+
size: "small",
|
|
134
|
+
variant: "text gray",
|
|
135
|
+
onClick: () => onMakeManager(person)
|
|
136
|
+
}, /*#__PURE__*/React.createElement(CrownBlankIcon, null))) : null, !isManager ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
137
|
+
title: "Remove from Whiteboard"
|
|
138
|
+
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
139
|
+
size: "small",
|
|
140
|
+
variant: "text gray",
|
|
141
|
+
onClick: () => onRemove(person)
|
|
142
|
+
}, /*#__PURE__*/React.createElement(CloseSmallIcon, null))) : null)));
|
|
143
|
+
})));
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/* ------------------------------------------------------------------ */
|
|
147
|
+
/* Add-members dialog (people "+" → DS Dialog + invite-style picker) */
|
|
148
|
+
/* ------------------------------------------------------------------ */
|
|
149
|
+
|
|
150
|
+
/* Owner company first, remaining companies sorted by name; people sorted
|
|
151
|
+
by name within each company — same ordering as the real user picker.
|
|
152
|
+
Members of non-owner companies join the board as clients. */
|
|
153
|
+
export const INVITE_COMPANIES = [{
|
|
154
|
+
name: "ActiveCollab",
|
|
155
|
+
isOwnerCompany: true,
|
|
156
|
+
people: [{
|
|
157
|
+
id: 101,
|
|
158
|
+
name: "Ana Ilic",
|
|
159
|
+
initials: "AI",
|
|
160
|
+
color: AVATAR_COLORS.green
|
|
161
|
+
}, {
|
|
162
|
+
id: 102,
|
|
163
|
+
name: "Bojan Peric",
|
|
164
|
+
initials: "BP",
|
|
165
|
+
color: AVATAR_COLORS.blue
|
|
166
|
+
}, {
|
|
167
|
+
id: 103,
|
|
168
|
+
name: "Goran Simovic",
|
|
169
|
+
initials: "GS",
|
|
170
|
+
color: AVATAR_COLORS.orange
|
|
171
|
+
}, {
|
|
172
|
+
id: 104,
|
|
173
|
+
name: "Vera Antic",
|
|
174
|
+
initials: "VA",
|
|
175
|
+
color: AVATAR_COLORS.purple
|
|
176
|
+
}]
|
|
177
|
+
}, {
|
|
178
|
+
name: "Bitlab Studio",
|
|
179
|
+
people: [{
|
|
180
|
+
id: 201,
|
|
181
|
+
name: "Elena Weber",
|
|
182
|
+
initials: "EW",
|
|
183
|
+
color: AVATAR_COLORS.teal
|
|
184
|
+
}, {
|
|
185
|
+
id: 202,
|
|
186
|
+
name: "Jonas Richter",
|
|
187
|
+
initials: "JR",
|
|
188
|
+
color: AVATAR_COLORS.yellow
|
|
189
|
+
}]
|
|
190
|
+
}, {
|
|
191
|
+
name: "Nova Consulting",
|
|
192
|
+
people: [{
|
|
193
|
+
id: 301,
|
|
194
|
+
name: "Iris Novak",
|
|
195
|
+
initials: "IN",
|
|
196
|
+
color: AVATAR_COLORS.blue
|
|
197
|
+
}, {
|
|
198
|
+
id: 302,
|
|
199
|
+
name: "Karlo Babic",
|
|
200
|
+
initials: "KB",
|
|
201
|
+
color: AVATAR_COLORS.green
|
|
202
|
+
}, {
|
|
203
|
+
id: 303,
|
|
204
|
+
name: "Tea Grgic",
|
|
205
|
+
initials: "TG",
|
|
206
|
+
color: AVATAR_COLORS.purple
|
|
207
|
+
}]
|
|
208
|
+
}];
|
|
209
|
+
|
|
210
|
+
/* The Select panel and the Dialog render through portals, so they can only
|
|
211
|
+
be styled via real global classes — wrapper descendant selectors can't
|
|
212
|
+
reach them. Actions gap 12px = the app's "tw-flex tw-gap-3" on
|
|
213
|
+
Dialog.Actions (InviteToProjectsDialog). */
|
|
214
|
+
export const AddMembersDialogStyle = createGlobalStyle([".wb-user-select{width:480px;max-width:calc(100vw - 32px);}.wb-dialog-actions{display:flex;gap:12px;}"]);
|
|
215
|
+
export const StyledCandidateRow = styled.span.withConfig({
|
|
216
|
+
displayName: "peopleMenu__StyledCandidateRow",
|
|
217
|
+
componentId: "sc-uidi4w-1"
|
|
218
|
+
})(["display:inline-flex;align-items:center;gap:8px;min-width:0;flex-grow:1;.candidate-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}"]);
|
|
219
|
+
|
|
220
|
+
/* same offset the Select's built-in row checkbox has */
|
|
221
|
+
export const StyledRowCheckbox = styled(Checkbox).withConfig({
|
|
222
|
+
displayName: "peopleMenu__StyledRowCheckbox",
|
|
223
|
+
componentId: "sc-uidi4w-2"
|
|
224
|
+
})(["margin-left:12px;"]);
|
|
225
|
+
export const StyledDialogFields = styled.div.withConfig({
|
|
226
|
+
displayName: "peopleMenu__StyledDialogFields",
|
|
227
|
+
componentId: "sc-uidi4w-3"
|
|
228
|
+
})(["display:flex;flex-direction:column;.field{display:flex;flex-direction:column;gap:4px;}.field + .field{margin-top:16px;}button.wb-user-trigger{width:100%;}textarea.wb-invite-message{width:100%;box-sizing:border-box;}"]);
|
|
229
|
+
/* Closes on Esc (DS Dialog default) and Cancel; background click stays
|
|
230
|
+
disabled (enableBackgroundClick not set). Add is disabled until at least
|
|
231
|
+
one user is selected; on Add the selection joins the members list (in the
|
|
232
|
+
real app this also sends the invitation email with the optional message,
|
|
233
|
+
and Add stays disabled while the request is in flight). */
|
|
234
|
+
export const AddMembersDialog = _ref2 => {
|
|
235
|
+
let open = _ref2.open,
|
|
236
|
+
onClose = _ref2.onClose,
|
|
237
|
+
existingIds = _ref2.existingIds,
|
|
238
|
+
onAdd = _ref2.onAdd;
|
|
239
|
+
const _useState = useState([]),
|
|
240
|
+
selectedIds = _useState[0],
|
|
241
|
+
setSelectedIds = _useState[1];
|
|
242
|
+
const _useState2 = useState(""),
|
|
243
|
+
message = _useState2[0],
|
|
244
|
+
setMessage = _useState2[1];
|
|
245
|
+
|
|
246
|
+
/* current members drop out of the picker; companies left empty disappear */
|
|
247
|
+
const options = useMemo(() => INVITE_COMPANIES.map((company, index) => ({
|
|
248
|
+
id: 1000 + index,
|
|
249
|
+
name: company.name,
|
|
250
|
+
options: company.people.filter(person => !existingIds.includes(person.id)).map(person => _extends({}, person))
|
|
251
|
+
})).filter(company => company.options.length > 0), [existingIds]);
|
|
252
|
+
const triggerText = selectedIds.length === 0 ? "Choose users" : selectedIds.length + " " + (selectedIds.length === 1 ? "user" : "users") + " selected";
|
|
253
|
+
const handleAdd = useCallback(() => {
|
|
254
|
+
const added = INVITE_COMPANIES.flatMap(company => company.people.filter(person => selectedIds.includes(person.id)).map(person => ({
|
|
255
|
+
id: person.id,
|
|
256
|
+
name: person.name,
|
|
257
|
+
initials: person.initials,
|
|
258
|
+
color: person.color,
|
|
259
|
+
isClient: !company.isOwnerCompany
|
|
260
|
+
})));
|
|
261
|
+
onAdd(added);
|
|
262
|
+
setSelectedIds([]);
|
|
263
|
+
setMessage("");
|
|
264
|
+
onClose();
|
|
265
|
+
}, [onAdd, onClose, selectedIds]);
|
|
266
|
+
return /*#__PURE__*/React.createElement(Dialog, {
|
|
267
|
+
open: open,
|
|
268
|
+
onClose: onClose
|
|
269
|
+
}, /*#__PURE__*/React.createElement(AddMembersDialogStyle, null), /*#__PURE__*/React.createElement(Dialog.Title, null, "Add Users"), /*#__PURE__*/React.createElement(Dialog.ContentDivider, null), /*#__PURE__*/React.createElement(Dialog.Content, null, /*#__PURE__*/React.createElement(StyledDialogFields, null, /*#__PURE__*/React.createElement("div", {
|
|
270
|
+
className: "field"
|
|
271
|
+
}, /*#__PURE__*/React.createElement(Label, {
|
|
272
|
+
htmlFor: "wb-users",
|
|
273
|
+
required: true
|
|
274
|
+
}, "Users"), /*#__PURE__*/React.createElement(Select, {
|
|
275
|
+
type: "multiple",
|
|
276
|
+
options: options,
|
|
277
|
+
selected: selectedIds,
|
|
278
|
+
onChange: value => setSelectedIds(Array.isArray(value) ? value : []),
|
|
279
|
+
noResultText: "No results",
|
|
280
|
+
selectClassName: "wb-user-select",
|
|
281
|
+
target: /*#__PURE__*/React.createElement(SelectTrigger, {
|
|
282
|
+
id: "wb-users",
|
|
283
|
+
className: "wb-user-trigger",
|
|
284
|
+
typographyProps: {
|
|
285
|
+
color: selectedIds.length > 0 ? "primary" : "quaternary"
|
|
286
|
+
}
|
|
287
|
+
}, triggerText),
|
|
288
|
+
endAdornment: /*#__PURE__*/React.createElement(Tooltip, {
|
|
289
|
+
title: "Group by"
|
|
290
|
+
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
291
|
+
variant: "text gray"
|
|
292
|
+
}, /*#__PURE__*/React.createElement(SortGeneralIcon, null))),
|
|
293
|
+
renderOption: (option, data) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StyledCandidateRow, null, /*#__PURE__*/React.createElement(RoundAvatar, {
|
|
294
|
+
$bg: String(option.color),
|
|
295
|
+
$size: 24,
|
|
296
|
+
$bordered: false
|
|
297
|
+
}, option.initials), /*#__PURE__*/React.createElement(Body2, {
|
|
298
|
+
className: "candidate-name"
|
|
299
|
+
}, option.name)), /*#__PURE__*/React.createElement(StyledRowCheckbox, data))
|
|
300
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
301
|
+
className: "field"
|
|
302
|
+
}, /*#__PURE__*/React.createElement(Label, {
|
|
303
|
+
htmlFor: "wb-invite-message"
|
|
304
|
+
}, "Message to Users"), /*#__PURE__*/React.createElement(Textarea, {
|
|
305
|
+
id: "wb-invite-message",
|
|
306
|
+
className: "wb-invite-message",
|
|
307
|
+
placeholder: "Short note to invited users",
|
|
308
|
+
value: message,
|
|
309
|
+
onChange: event => setMessage(event.target.value)
|
|
310
|
+
}), /*#__PURE__*/React.createElement(Caption1, {
|
|
311
|
+
color: "tertiary"
|
|
312
|
+
}, "Let people know what this whiteboard is for and why you're inviting them. If provided, this message is included in the invitation email.")))), /*#__PURE__*/React.createElement(Dialog.ContentDivider, null), /*#__PURE__*/React.createElement(Dialog.Actions, {
|
|
313
|
+
className: "wb-dialog-actions"
|
|
314
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
315
|
+
variant: "primary",
|
|
316
|
+
disabled: selectedIds.length === 0,
|
|
317
|
+
onClick: handleAdd
|
|
318
|
+
}, "Add"), /*#__PURE__*/React.createElement(Button, {
|
|
319
|
+
variant: "secondary",
|
|
320
|
+
onClick: onClose
|
|
321
|
+
}, "Cancel")));
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
/* People trigger (icon + member count) + the popover + the dialogs.
|
|
325
|
+
|
|
326
|
+
Flows mirror the implementation spec. The mock acts as a non-owner
|
|
327
|
+
manager, so a crown click always shows the confirm dialog (owners would
|
|
328
|
+
transfer immediately), and hover options stay visible after a transfer so
|
|
329
|
+
the flows can be replayed. */
|
|
330
|
+
export const WhiteboardPeopleMenu = () => {
|
|
331
|
+
var _removeTarget$name$sp;
|
|
332
|
+
const _useState3 = useState(false),
|
|
333
|
+
open = _useState3[0],
|
|
334
|
+
setOpen = _useState3[1];
|
|
335
|
+
const handleOpen = useCallback(() => setOpen(true), []);
|
|
336
|
+
const handleClose = useCallback(() => setOpen(false), []);
|
|
337
|
+
const _useState4 = useState(BOARD_MEMBERS),
|
|
338
|
+
boardMembers = _useState4[0],
|
|
339
|
+
setBoardMembers = _useState4[1];
|
|
340
|
+
const _useState5 = useState(1),
|
|
341
|
+
managerId = _useState5[0],
|
|
342
|
+
setManagerId = _useState5[1];
|
|
343
|
+
const _useState6 = useState(null),
|
|
344
|
+
managerTarget = _useState6[0],
|
|
345
|
+
setManagerTarget = _useState6[1];
|
|
346
|
+
const _useState7 = useState(null),
|
|
347
|
+
removeTarget = _useState7[0],
|
|
348
|
+
setRemoveTarget = _useState7[1];
|
|
349
|
+
const _useState8 = useState(false),
|
|
350
|
+
dialogOpen = _useState8[0],
|
|
351
|
+
setDialogOpen = _useState8[1];
|
|
352
|
+
const handleDialogOpen = useCallback(() => {
|
|
353
|
+
setOpen(false);
|
|
354
|
+
setDialogOpen(true);
|
|
355
|
+
}, []);
|
|
356
|
+
const handleDialogClose = useCallback(() => setDialogOpen(false), []);
|
|
357
|
+
const handleAddMembers = useCallback(added => {
|
|
358
|
+
setBoardMembers(current => [...current, ...added]);
|
|
359
|
+
}, []);
|
|
360
|
+
|
|
361
|
+
/* close the menu before opening any dialog (menus-that-open-dialogs rule) */
|
|
362
|
+
const handleMakeManager = useCallback(person => {
|
|
363
|
+
setOpen(false);
|
|
364
|
+
setManagerTarget(person);
|
|
365
|
+
}, []);
|
|
366
|
+
const handleRemove = useCallback(person => {
|
|
367
|
+
setOpen(false);
|
|
368
|
+
setRemoveTarget(person);
|
|
369
|
+
}, []);
|
|
370
|
+
const handleManagerConfirm = useCallback(() => {
|
|
371
|
+
if (managerTarget) {
|
|
372
|
+
setManagerId(managerTarget.id);
|
|
373
|
+
}
|
|
374
|
+
setManagerTarget(null);
|
|
375
|
+
}, [managerTarget]);
|
|
376
|
+
const handleRemoveConfirm = useCallback(() => {
|
|
377
|
+
if (removeTarget) {
|
|
378
|
+
setBoardMembers(current => current.filter(person => person.id !== removeTarget.id));
|
|
379
|
+
}
|
|
380
|
+
setRemoveTarget(null);
|
|
381
|
+
}, [removeTarget]);
|
|
382
|
+
const members = boardMembers.filter(person => !person.isClient);
|
|
383
|
+
const clients = boardMembers.filter(person => person.isClient);
|
|
384
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(AddMembersDialog, {
|
|
385
|
+
open: dialogOpen,
|
|
386
|
+
onClose: handleDialogClose,
|
|
387
|
+
existingIds: boardMembers.map(person => person.id),
|
|
388
|
+
onAdd: handleAddMembers
|
|
389
|
+
}), /*#__PURE__*/React.createElement(ConfirmDialog, {
|
|
390
|
+
open: managerTarget !== null,
|
|
391
|
+
dialogTitle: "Change Whiteboard Manager",
|
|
392
|
+
dialogContent: "By changing the Whiteboard Manager, you'll lose the ability to manage this whiteboard.",
|
|
393
|
+
confirmBtnText: "Change",
|
|
394
|
+
shouldShowCancelButton: true,
|
|
395
|
+
onConfirm: handleManagerConfirm,
|
|
396
|
+
onCancel: () => setManagerTarget(null)
|
|
397
|
+
}), /*#__PURE__*/React.createElement(ConfirmDialog, {
|
|
398
|
+
open: removeTarget !== null,
|
|
399
|
+
dialogTitle: "Remove from Whiteboard",
|
|
400
|
+
dialogContent: "Remove " + ((_removeTarget$name$sp = removeTarget == null ? void 0 : removeTarget.name.split(" ")[0]) != null ? _removeTarget$name$sp : "") + " from this whiteboard? They will immediately lose access to it.",
|
|
401
|
+
confirmBtnText: "Remove",
|
|
402
|
+
shouldShowCancelButton: true,
|
|
403
|
+
onConfirm: handleRemoveConfirm,
|
|
404
|
+
onCancel: () => setRemoveTarget(null)
|
|
405
|
+
}), /*#__PURE__*/React.createElement(Menu, {
|
|
406
|
+
open: open,
|
|
407
|
+
onOpen: handleOpen,
|
|
408
|
+
onClose: handleClose,
|
|
409
|
+
position: "bottom-start",
|
|
410
|
+
target: /*#__PURE__*/React.createElement(CounterButton, {
|
|
411
|
+
active: open,
|
|
412
|
+
label: String(boardMembers.length),
|
|
413
|
+
icon: /*#__PURE__*/React.createElement(PeopleIcon, null),
|
|
414
|
+
className: open ? "open" : undefined,
|
|
415
|
+
onClearAll: () => undefined
|
|
416
|
+
})
|
|
417
|
+
}, /*#__PURE__*/React.createElement(StyledPeopleMenu, null, /*#__PURE__*/React.createElement(MenuHeader, {
|
|
418
|
+
title: "People",
|
|
419
|
+
rightElement: /*#__PURE__*/React.createElement(IconButton, {
|
|
420
|
+
size: "small",
|
|
421
|
+
variant: "text gray",
|
|
422
|
+
onClick: handleDialogOpen
|
|
423
|
+
}, /*#__PURE__*/React.createElement(AddCrossTinyIcon, null))
|
|
424
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
425
|
+
className: "people-scroll"
|
|
426
|
+
}, /*#__PURE__*/React.createElement(PeopleMenuSection, {
|
|
427
|
+
label: "Members",
|
|
428
|
+
people: members,
|
|
429
|
+
managerId: managerId,
|
|
430
|
+
onMakeManager: handleMakeManager,
|
|
431
|
+
onRemove: handleRemove
|
|
432
|
+
}), clients.length > 0 ? /*#__PURE__*/React.createElement(PeopleMenuSection, {
|
|
433
|
+
label: "Clients",
|
|
434
|
+
people: clients,
|
|
435
|
+
managerId: managerId,
|
|
436
|
+
onMakeManager: handleMakeManager,
|
|
437
|
+
onRemove: handleRemove
|
|
438
|
+
}) : null))));
|
|
439
|
+
};
|
|
440
|
+
//# sourceMappingURL=peopleMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peopleMenu.js","names":["React","useCallback","useMemo","useState","styled","createGlobalStyle","Button","Checkbox","ConfirmDialog","CounterButton","Dialog","IconButton","AddCrossTinyIcon","CloseSmallIcon","CrownBlankIcon","CrownSelectedIcon","PeopleIcon","SortGeneralIcon","Label","List","ListItem","Menu","MenuHeader","Select","SelectTrigger","Textarea","Tooltip","Body2","Caption1","AVATAR_COLORS","RoundAvatar","BOARD_MEMBERS","id","name","initials","color","purple","teal","orange","green","blue","yellow","isClient","StyledPeopleMenu","div","withConfig","displayName","componentId","PeopleMenuSection","_ref","label","people","managerId","onMakeManager","onRemove","createElement","Fragment","weight","className","sort","a","b","localeCompare","map","person","isManager","key","$bg","$bordered","undefined","fill","title","size","variant","onClick","INVITE_COMPANIES","isOwnerCompany","AddMembersDialogStyle","StyledCandidateRow","span","StyledRowCheckbox","StyledDialogFields","AddMembersDialog","_ref2","open","onClose","existingIds","onAdd","_useState","selectedIds","setSelectedIds","_useState2","message","setMessage","options","company","index","filter","includes","_extends","length","triggerText","handleAdd","added","flatMap","Title","ContentDivider","Content","htmlFor","required","type","selected","onChange","value","Array","isArray","noResultText","selectClassName","target","typographyProps","endAdornment","renderOption","option","data","String","$size","placeholder","event","Actions","disabled","WhiteboardPeopleMenu","_removeTarget$name$sp","_useState3","setOpen","handleOpen","handleClose","_useState4","boardMembers","setBoardMembers","_useState5","setManagerId","_useState6","managerTarget","setManagerTarget","_useState7","removeTarget","setRemoveTarget","_useState8","dialogOpen","setDialogOpen","handleDialogOpen","handleDialogClose","handleAddMembers","current","handleMakeManager","handleRemove","handleManagerConfirm","handleRemoveConfirm","members","clients","dialogTitle","dialogContent","confirmBtnText","shouldShowCancelButton","onConfirm","onCancel","split","onOpen","position","active","icon","onClearAll","rightElement"],"sources":["../../../../src/presentation/whiteboard/peopleMenu.tsx"],"sourcesContent":["import React, { ReactElement, useCallback, useMemo, useState } from \"react\";\n\nimport styled, { createGlobalStyle } from \"styled-components\";\n\nimport { Button } from \"../../components/Button\";\nimport { Checkbox } from \"../../components/Checkbox\";\nimport { ConfirmDialog } from \"../../components/ConfirmDialog\";\nimport { CounterButton } from \"../../components/CounterButton\";\nimport { Dialog } from \"../../components/Dialog\";\nimport { IconButton } from \"../../components/IconButton\";\nimport {\n AddCrossTinyIcon,\n CloseSmallIcon,\n CrownBlankIcon,\n CrownSelectedIcon,\n PeopleIcon,\n SortGeneralIcon,\n} from \"../../components/Icons\";\nimport { Label } from \"../../components/Label\";\nimport { List, ListItem } from \"../../components/List\";\nimport { Menu, MenuHeader } from \"../../components/Menu\";\nimport { Select } from \"../../components/Select\";\nimport { SelectTrigger } from \"../../components/SelectTrigger\";\nimport { Textarea } from \"../../components/Textarea\";\nimport { Tooltip } from \"../../components/Tooltip\";\nimport { Body2, Caption1 } from \"../../components/Typography\";\nimport { AVATAR_COLORS, RoundAvatar } from \"../shared\";\n\n/* ------------------------------------------------------------------ */\n/* People menu (copy of the project header People popover) */\n/* ------------------------------------------------------------------ */\n\nexport interface BoardMember {\n id: number;\n name: string;\n initials: string;\n color: string;\n isClient?: boolean;\n}\n\n/* 12 people (9 members + 3 clients) so the 330px list visibly scrolls.\n Jasna (id 1) starts as the board manager. */\nexport const BOARD_MEMBERS: BoardMember[] = [\n { id: 1, name: \"Jasna Simic\", initials: \"JS\", color: AVATAR_COLORS.purple },\n { id: 2, name: \"Marko Antic\", initials: \"MA\", color: AVATAR_COLORS.teal },\n { id: 3, name: \"Dario Kovac\", initials: \"DK\", color: AVATAR_COLORS.orange },\n { id: 4, name: \"Ivana Lukic\", initials: \"IL\", color: AVATAR_COLORS.green },\n { id: 5, name: \"Petar Novak\", initials: \"PN\", color: AVATAR_COLORS.blue },\n { id: 6, name: \"Sara Milic\", initials: \"SM\", color: AVATAR_COLORS.yellow },\n { id: 7, name: \"Luka Peric\", initials: \"LP\", color: AVATAR_COLORS.purple },\n { id: 8, name: \"Mia Radic\", initials: \"MR\", color: AVATAR_COLORS.teal },\n { id: 9, name: \"Nikola Vukic\", initials: \"NV\", color: AVATAR_COLORS.orange },\n {\n id: 10,\n name: \"Ana Klein\",\n initials: \"AK\",\n color: AVATAR_COLORS.green,\n isClient: true,\n },\n {\n id: 11,\n name: \"Tom Becker\",\n initials: \"TB\",\n color: AVATAR_COLORS.blue,\n isClient: true,\n },\n {\n id: 12,\n name: \"Eva Fischer\",\n initials: \"EF\",\n color: AVATAR_COLORS.yellow,\n isClient: true,\n },\n];\n\n/* Mirrors ProjectPeopleWrapper + view.project_top_bar.less:\n Menu 260px, \"People\" MenuHeader with an (inert) \"+\", 330px scroll area,\n Members/Clients Caption1 section labels, rows with hover-only options. */\nexport const StyledPeopleMenu = styled.div`\n .people-scroll {\n max-height: 330px;\n overflow-y: auto;\n overflow-x: hidden;\n padding-bottom: 8px;\n }\n\n .people-section-label {\n display: block;\n margin: 8px 0;\n padding: 0 16px;\n }\n\n /* .project-members li overrides: radius, 8px h-padding, tw-mx-2 */\n .member-item {\n justify-content: space-between;\n margin: 4px 8px;\n padding: 0 8px;\n border-radius: 4px;\n cursor: auto;\n }\n\n /* options hidden until row hover (.project-member-options pattern) */\n .member-options {\n display: none;\n align-items: center;\n }\n\n .member-item:hover .member-options {\n display: flex;\n }\n\n .member-side {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n /* UserLink: avatar + name, 8px gap, truncated (2px v-padding) */\n .member-user {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 2px 0;\n overflow: hidden;\n\n .member-name {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n }\n\n /* gold ring on the manager's avatar (.project-leader-avatar) */\n .manager-avatar {\n outline: 2px #ffcc6b solid;\n outline-offset: -2px;\n }\n`;\n\nexport interface PeopleMenuSectionProps {\n label: string;\n people: BoardMember[];\n managerId: number;\n onMakeManager: (person: BoardMember) => void;\n onRemove: (person: BoardMember) => void;\n}\n\n/* Rows sorted by name. Manager: gold crown + ring, no hover options (the\n role must be handed over before removal). Crown option only on non-client\n rows; X on everyone else. */\nexport const PeopleMenuSection = ({\n label,\n people,\n managerId,\n onMakeManager,\n onRemove,\n}: PeopleMenuSectionProps): ReactElement => (\n <>\n <Caption1 weight=\"bold\" className=\"people-section-label\">\n {label}\n </Caption1>\n <List>\n {[...people]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((person) => {\n const isManager = person.id === managerId;\n\n return (\n <ListItem key={person.id} className=\"member-item\">\n <span className=\"member-user\">\n <RoundAvatar\n $bg={person.color}\n $bordered={false}\n className={isManager ? \"manager-avatar\" : undefined}\n >\n {person.initials}\n </RoundAvatar>\n <Body2 className=\"member-name\">{person.name}</Body2>\n </span>\n <span className=\"member-side\">\n {isManager ? <CrownSelectedIcon fill=\"#FFCC6B\" /> : null}\n <span className=\"member-options\">\n {!isManager && !person.isClient ? (\n <Tooltip title=\"Set as Whiteboard Manager\">\n <IconButton\n size=\"small\"\n variant=\"text gray\"\n onClick={() => onMakeManager(person)}\n >\n <CrownBlankIcon />\n </IconButton>\n </Tooltip>\n ) : null}\n {!isManager ? (\n <Tooltip title=\"Remove from Whiteboard\">\n <IconButton\n size=\"small\"\n variant=\"text gray\"\n onClick={() => onRemove(person)}\n >\n <CloseSmallIcon />\n </IconButton>\n </Tooltip>\n ) : null}\n </span>\n </span>\n </ListItem>\n );\n })}\n </List>\n </>\n);\n\n/* ------------------------------------------------------------------ */\n/* Add-members dialog (people \"+\" → DS Dialog + invite-style picker) */\n/* ------------------------------------------------------------------ */\n\nexport interface InviteCandidate {\n id: number;\n name: string;\n initials: string;\n color: string;\n}\n\nexport interface InviteCompany {\n name: string;\n isOwnerCompany?: boolean;\n people: InviteCandidate[];\n}\n\n/* Owner company first, remaining companies sorted by name; people sorted\n by name within each company — same ordering as the real user picker.\n Members of non-owner companies join the board as clients. */\nexport const INVITE_COMPANIES: InviteCompany[] = [\n {\n name: \"ActiveCollab\",\n isOwnerCompany: true,\n people: [\n { id: 101, name: \"Ana Ilic\", initials: \"AI\", color: AVATAR_COLORS.green },\n {\n id: 102,\n name: \"Bojan Peric\",\n initials: \"BP\",\n color: AVATAR_COLORS.blue,\n },\n {\n id: 103,\n name: \"Goran Simovic\",\n initials: \"GS\",\n color: AVATAR_COLORS.orange,\n },\n {\n id: 104,\n name: \"Vera Antic\",\n initials: \"VA\",\n color: AVATAR_COLORS.purple,\n },\n ],\n },\n {\n name: \"Bitlab Studio\",\n people: [\n {\n id: 201,\n name: \"Elena Weber\",\n initials: \"EW\",\n color: AVATAR_COLORS.teal,\n },\n {\n id: 202,\n name: \"Jonas Richter\",\n initials: \"JR\",\n color: AVATAR_COLORS.yellow,\n },\n ],\n },\n {\n name: \"Nova Consulting\",\n people: [\n {\n id: 301,\n name: \"Iris Novak\",\n initials: \"IN\",\n color: AVATAR_COLORS.blue,\n },\n {\n id: 302,\n name: \"Karlo Babic\",\n initials: \"KB\",\n color: AVATAR_COLORS.green,\n },\n {\n id: 303,\n name: \"Tea Grgic\",\n initials: \"TG\",\n color: AVATAR_COLORS.purple,\n },\n ],\n },\n];\n\n/* The Select panel and the Dialog render through portals, so they can only\n be styled via real global classes — wrapper descendant selectors can't\n reach them. Actions gap 12px = the app's \"tw-flex tw-gap-3\" on\n Dialog.Actions (InviteToProjectsDialog). */\nexport const AddMembersDialogStyle = createGlobalStyle`\n .wb-user-select {\n width: 480px;\n max-width: calc(100vw - 32px);\n }\n\n .wb-dialog-actions {\n display: flex;\n gap: 12px;\n }\n`;\n\nexport const StyledCandidateRow = styled.span`\n display: inline-flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex-grow: 1;\n\n .candidate-name {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n`;\n\n/* same offset the Select's built-in row checkbox has */\nexport const StyledRowCheckbox = styled(Checkbox)`\n margin-left: 12px;\n`;\n\nexport const StyledDialogFields = styled.div`\n display: flex;\n flex-direction: column;\n\n .field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .field + .field {\n margin-top: 16px;\n }\n\n /* DS fixed widths (SelectTrigger 300px, Textarea 360px) → full width */\n button.wb-user-trigger {\n width: 100%;\n }\n\n textarea.wb-invite-message {\n width: 100%;\n box-sizing: border-box;\n }\n`;\n\nexport interface AddMembersDialogProps {\n open: boolean;\n onClose: () => void;\n /** ids of current board members — excluded from the picker */\n existingIds: number[];\n onAdd: (people: BoardMember[]) => void;\n}\n\n/* Closes on Esc (DS Dialog default) and Cancel; background click stays\n disabled (enableBackgroundClick not set). Add is disabled until at least\n one user is selected; on Add the selection joins the members list (in the\n real app this also sends the invitation email with the optional message,\n and Add stays disabled while the request is in flight). */\nexport const AddMembersDialog = ({\n open,\n onClose,\n existingIds,\n onAdd,\n}: AddMembersDialogProps): ReactElement => {\n const [selectedIds, setSelectedIds] = useState<(string | number)[]>([]);\n const [message, setMessage] = useState(\"\");\n\n /* current members drop out of the picker; companies left empty disappear */\n const options = useMemo(\n () =>\n INVITE_COMPANIES.map((company, index) => ({\n id: 1000 + index,\n name: company.name,\n options: company.people\n .filter((person) => !existingIds.includes(person.id))\n .map((person) => ({ ...person })),\n })).filter((company) => company.options.length > 0),\n [existingIds]\n );\n\n const triggerText =\n selectedIds.length === 0\n ? \"Choose users\"\n : `${selectedIds.length} ${\n selectedIds.length === 1 ? \"user\" : \"users\"\n } selected`;\n\n const handleAdd = useCallback(() => {\n const added = INVITE_COMPANIES.flatMap((company) =>\n company.people\n .filter((person) => selectedIds.includes(person.id))\n .map((person) => ({\n id: person.id,\n name: person.name,\n initials: person.initials,\n color: person.color,\n isClient: !company.isOwnerCompany,\n }))\n );\n\n onAdd(added);\n setSelectedIds([]);\n setMessage(\"\");\n onClose();\n }, [onAdd, onClose, selectedIds]);\n\n return (\n <Dialog open={open} onClose={onClose}>\n <AddMembersDialogStyle />\n <Dialog.Title>Add Users</Dialog.Title>\n <Dialog.ContentDivider />\n <Dialog.Content>\n <StyledDialogFields>\n <div className=\"field\">\n <Label htmlFor=\"wb-users\" required>\n Users\n </Label>\n <Select\n type=\"multiple\"\n options={options}\n selected={selectedIds}\n onChange={(value) =>\n setSelectedIds(Array.isArray(value) ? value : [])\n }\n noResultText=\"No results\"\n selectClassName=\"wb-user-select\"\n target={\n <SelectTrigger\n id=\"wb-users\"\n className=\"wb-user-trigger\"\n typographyProps={{\n color: selectedIds.length > 0 ? \"primary\" : \"quaternary\",\n }}\n >\n {triggerText}\n </SelectTrigger>\n }\n endAdornment={\n <Tooltip title=\"Group by\">\n <IconButton variant=\"text gray\">\n <SortGeneralIcon />\n </IconButton>\n </Tooltip>\n }\n renderOption={(option, data) => (\n <>\n <StyledCandidateRow>\n <RoundAvatar\n $bg={String(option.color)}\n $size={24}\n $bordered={false}\n >\n {option.initials}\n </RoundAvatar>\n <Body2 className=\"candidate-name\">{option.name}</Body2>\n </StyledCandidateRow>\n <StyledRowCheckbox\n {...(data as {\n id?: string;\n checked?: boolean;\n onChange?: () => void;\n })}\n />\n </>\n )}\n />\n </div>\n <div className=\"field\">\n <Label htmlFor=\"wb-invite-message\">Message to Users</Label>\n <Textarea\n id=\"wb-invite-message\"\n className=\"wb-invite-message\"\n placeholder=\"Short note to invited users\"\n value={message}\n onChange={(event) => setMessage(event.target.value)}\n />\n <Caption1 color=\"tertiary\">\n Let people know what this whiteboard is for and why you're\n inviting them. If provided, this message is included in the\n invitation email.\n </Caption1>\n </div>\n </StyledDialogFields>\n </Dialog.Content>\n <Dialog.ContentDivider />\n <Dialog.Actions className=\"wb-dialog-actions\">\n <Button\n variant=\"primary\"\n disabled={selectedIds.length === 0}\n onClick={handleAdd}\n >\n Add\n </Button>\n <Button variant=\"secondary\" onClick={onClose}>\n Cancel\n </Button>\n </Dialog.Actions>\n </Dialog>\n );\n};\n\n/* People trigger (icon + member count) + the popover + the dialogs.\n\n Flows mirror the implementation spec. The mock acts as a non-owner\n manager, so a crown click always shows the confirm dialog (owners would\n transfer immediately), and hover options stay visible after a transfer so\n the flows can be replayed. */\nexport const WhiteboardPeopleMenu = (): ReactElement => {\n const [open, setOpen] = useState(false);\n const handleOpen = useCallback(() => setOpen(true), []);\n const handleClose = useCallback(() => setOpen(false), []);\n\n const [boardMembers, setBoardMembers] = useState(BOARD_MEMBERS);\n const [managerId, setManagerId] = useState(1);\n const [managerTarget, setManagerTarget] = useState<BoardMember | null>(null);\n const [removeTarget, setRemoveTarget] = useState<BoardMember | null>(null);\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const handleDialogOpen = useCallback(() => {\n setOpen(false);\n setDialogOpen(true);\n }, []);\n const handleDialogClose = useCallback(() => setDialogOpen(false), []);\n\n const handleAddMembers = useCallback((added: BoardMember[]) => {\n setBoardMembers((current) => [...current, ...added]);\n }, []);\n\n /* close the menu before opening any dialog (menus-that-open-dialogs rule) */\n const handleMakeManager = useCallback((person: BoardMember) => {\n setOpen(false);\n setManagerTarget(person);\n }, []);\n\n const handleRemove = useCallback((person: BoardMember) => {\n setOpen(false);\n setRemoveTarget(person);\n }, []);\n\n const handleManagerConfirm = useCallback(() => {\n if (managerTarget) {\n setManagerId(managerTarget.id);\n }\n setManagerTarget(null);\n }, [managerTarget]);\n\n const handleRemoveConfirm = useCallback(() => {\n if (removeTarget) {\n setBoardMembers((current) =>\n current.filter((person) => person.id !== removeTarget.id)\n );\n }\n setRemoveTarget(null);\n }, [removeTarget]);\n\n const members = boardMembers.filter((person) => !person.isClient);\n const clients = boardMembers.filter((person) => person.isClient);\n\n return (\n <>\n <AddMembersDialog\n open={dialogOpen}\n onClose={handleDialogClose}\n existingIds={boardMembers.map((person) => person.id)}\n onAdd={handleAddMembers}\n />\n <ConfirmDialog\n open={managerTarget !== null}\n dialogTitle=\"Change Whiteboard Manager\"\n dialogContent=\"By changing the Whiteboard Manager, you'll lose the ability to manage this whiteboard.\"\n confirmBtnText=\"Change\"\n shouldShowCancelButton\n onConfirm={handleManagerConfirm}\n onCancel={() => setManagerTarget(null)}\n />\n <ConfirmDialog\n open={removeTarget !== null}\n dialogTitle=\"Remove from Whiteboard\"\n dialogContent={`Remove ${\n removeTarget?.name.split(\" \")[0] ?? \"\"\n } from this whiteboard? They will immediately lose access to it.`}\n confirmBtnText=\"Remove\"\n shouldShowCancelButton\n onConfirm={handleRemoveConfirm}\n onCancel={() => setRemoveTarget(null)}\n />\n <Menu\n open={open}\n onOpen={handleOpen}\n onClose={handleClose}\n position=\"bottom-start\"\n target={\n <CounterButton\n active={open}\n label={String(boardMembers.length)}\n icon={<PeopleIcon />}\n className={open ? \"open\" : undefined}\n onClearAll={() => undefined}\n />\n }\n >\n <StyledPeopleMenu>\n <MenuHeader\n title=\"People\"\n rightElement={\n <IconButton\n size=\"small\"\n variant=\"text gray\"\n onClick={handleDialogOpen}\n >\n <AddCrossTinyIcon />\n </IconButton>\n }\n />\n <div className=\"people-scroll\">\n <PeopleMenuSection\n label=\"Members\"\n people={members}\n managerId={managerId}\n onMakeManager={handleMakeManager}\n onRemove={handleRemove}\n />\n {clients.length > 0 ? (\n <PeopleMenuSection\n label=\"Clients\"\n people={clients}\n managerId={managerId}\n onMakeManager={handleMakeManager}\n onRemove={handleRemove}\n />\n ) : null}\n </div>\n </StyledPeopleMenu>\n </Menu>\n </>\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { GridSize } from "./elements";
|
|
3
|
+
export declare const BOARD_MENU_WIDTH = 264;
|
|
4
|
+
export declare const BoardMenuSliderStyle: import("styled-components").GlobalStyleComponent<{}, import("styled-components").DefaultTheme>;
|
|
5
|
+
export declare const StyledBoardSettingsMenu: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
|
+
export interface BoardSettingsMenuProps {
|
|
7
|
+
gridSize: GridSize;
|
|
8
|
+
snapToGrid: boolean;
|
|
9
|
+
onGridSizeChange: (value: GridSize) => void;
|
|
10
|
+
onSnapToGridChange: (value: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const BoardSettingsMenu: ({ gridSize, snapToGrid, onGridSizeChange, onSnapToGridChange, }: BoardSettingsMenuProps) => ReactElement;
|
|
13
|
+
//# sourceMappingURL=settingsMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settingsMenu.d.ts","sourceRoot":"","sources":["../../../../src/presentation/whiteboard/settingsMenu.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AAInE,OAAO,EAAe,QAAQ,EAAa,MAAM,YAAY,CAAC;AAqB9D,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAIpC,eAAO,MAAM,oBAAoB,gGAKhC,CAAC;AAEF,eAAO,MAAM,uBAAuB,oEA2CnC,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC5C,kBAAkB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9C;AAED,eAAO,MAAM,iBAAiB,GAAI,iEAK/B,sBAAsB,KAAG,YAmI3B,CAAC"}
|