@activecollab/components 2.0.421 → 2.0.422
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/components/RadioCard/RadioCard.js +81 -0
- package/dist/cjs/components/RadioCard/RadioCard.js.map +1 -0
- package/dist/cjs/components/RadioCard/Styles.js +39 -0
- package/dist/cjs/components/RadioCard/Styles.js.map +1 -0
- package/dist/cjs/components/RadioCard/index.js +17 -0
- package/dist/cjs/components/RadioCard/index.js.map +1 -0
- package/dist/cjs/components/RadioGroup/RadioGroup.js +102 -0
- package/dist/cjs/components/RadioGroup/RadioGroup.js.map +1 -0
- package/dist/cjs/components/RadioGroup/Styles.js +38 -0
- package/dist/cjs/components/RadioGroup/Styles.js.map +1 -0
- package/dist/cjs/components/RadioGroup/index.js +17 -0
- package/dist/cjs/components/RadioGroup/index.js.map +1 -0
- package/dist/cjs/components/index.js +22 -0
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/presentation/shared/PortfolioOptionsMenu.js +74 -15
- package/dist/cjs/presentation/shared/PortfolioOptionsMenu.js.map +1 -1
- package/dist/cjs/presentation/shared/index.js +93 -1
- package/dist/cjs/presentation/shared/index.js.map +1 -1
- package/dist/cjs/presentation/shared/portfolioDetails.js +566 -0
- package/dist/cjs/presentation/shared/portfolioDetails.js.map +1 -0
- package/dist/cjs/utils/useStableId.js +33 -0
- package/dist/cjs/utils/useStableId.js.map +1 -0
- package/dist/esm/components/RadioCard/RadioCard.d.ts +27 -0
- package/dist/esm/components/RadioCard/RadioCard.d.ts.map +1 -0
- package/dist/esm/components/RadioCard/RadioCard.js +72 -0
- package/dist/esm/components/RadioCard/RadioCard.js.map +1 -0
- package/dist/esm/components/RadioCard/Styles.d.ts +16 -0
- package/dist/esm/components/RadioCard/Styles.d.ts.map +1 -0
- package/dist/esm/components/RadioCard/Styles.js +26 -0
- package/dist/esm/components/RadioCard/Styles.js.map +1 -0
- package/dist/esm/components/RadioCard/index.d.ts +2 -0
- package/dist/esm/components/RadioCard/index.d.ts.map +1 -0
- package/dist/esm/components/RadioCard/index.js +2 -0
- package/dist/esm/components/RadioCard/index.js.map +1 -0
- package/dist/esm/components/RadioGroup/RadioGroup.d.ts +48 -0
- package/dist/esm/components/RadioGroup/RadioGroup.d.ts.map +1 -0
- package/dist/esm/components/RadioGroup/RadioGroup.js +89 -0
- package/dist/esm/components/RadioGroup/RadioGroup.js.map +1 -0
- package/dist/esm/components/RadioGroup/Styles.d.ts +22 -0
- package/dist/esm/components/RadioGroup/Styles.d.ts.map +1 -0
- package/dist/esm/components/RadioGroup/Styles.js +23 -0
- package/dist/esm/components/RadioGroup/Styles.js.map +1 -0
- package/dist/esm/components/RadioGroup/index.d.ts +2 -0
- package/dist/esm/components/RadioGroup/index.d.ts.map +1 -0
- package/dist/esm/components/RadioGroup/index.js +2 -0
- package/dist/esm/components/RadioGroup/index.js.map +1 -0
- package/dist/esm/components/index.d.ts +2 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +2 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/presentation/shared/PortfolioOptionsMenu.d.ts +5 -1
- package/dist/esm/presentation/shared/PortfolioOptionsMenu.d.ts.map +1 -1
- package/dist/esm/presentation/shared/PortfolioOptionsMenu.js +61 -14
- package/dist/esm/presentation/shared/PortfolioOptionsMenu.js.map +1 -1
- package/dist/esm/presentation/shared/index.d.ts +2 -0
- package/dist/esm/presentation/shared/index.d.ts.map +1 -1
- package/dist/esm/presentation/shared/index.js +1 -0
- package/dist/esm/presentation/shared/index.js.map +1 -1
- package/dist/esm/presentation/shared/portfolioDetails.d.ts +74 -0
- package/dist/esm/presentation/shared/portfolioDetails.d.ts.map +1 -0
- package/dist/esm/presentation/shared/portfolioDetails.js +490 -0
- package/dist/esm/presentation/shared/portfolioDetails.js.map +1 -0
- package/dist/esm/utils/useStableId.d.ts +2 -0
- package/dist/esm/utils/useStableId.d.ts.map +1 -0
- package/dist/esm/utils/useStableId.js +25 -0
- package/dist/esm/utils/useStableId.js.map +1 -0
- package/dist/index.js +1068 -815
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sampleProjectOptionIds = exports.leaderShortName = exports.isPortfolioDetailsValid = exports.defaultPortfolioName = exports.contextFieldLabel = exports.VISIBILITY_OPTIONS = exports.PortfolioDetailsFields = exports.PORTFOLIO_TYPES = exports.LEADERS_LIST = exports.EditPortfolioDialog = exports.DEFAULT_PORTFOLIO_FORM_VALUES = exports.CLIENTS = exports.CATEGORIES = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
9
|
+
var _Button = require("../../components/Button");
|
|
10
|
+
var _Dialog = require("../../components/Dialog");
|
|
11
|
+
var _IconButton = require("../../components/IconButton");
|
|
12
|
+
var _Icons = require("../../components/Icons");
|
|
13
|
+
var _Input = require("../../components/Input");
|
|
14
|
+
var _Label = require("../../components/Label");
|
|
15
|
+
var _RadioGroup = require("../../components/RadioGroup");
|
|
16
|
+
var _Select = require("../../components/Select");
|
|
17
|
+
var _SelectTrigger = require("../../components/SelectTrigger");
|
|
18
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
20
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
21
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
22
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
23
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
24
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
25
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
26
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
27
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
28
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
29
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
30
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
31
|
+
/*
|
|
32
|
+
Portfolio details form — the shared "step 2" of the Create Portfolio wizard,
|
|
33
|
+
reused verbatim as the Edit Portfolio dialog.
|
|
34
|
+
|
|
35
|
+
This mirrors a pattern used across the app: the fields that make up the final
|
|
36
|
+
step of a creation wizard are the same fields shown, later, when the object is
|
|
37
|
+
edited. So the form body (name, the type's picker, visibility) and its
|
|
38
|
+
validation live here once, and two consumers render it:
|
|
39
|
+
|
|
40
|
+
- The Create Portfolio wizard (PortfoliosList.stories.tsx) renders
|
|
41
|
+
<PortfolioDetailsFields> inside its step-2 <Dialog.Content>, with a
|
|
42
|
+
"Create Portfolio" action.
|
|
43
|
+
- <EditPortfolioDialog> (opened from PortfolioOptionsMenu's Edit item)
|
|
44
|
+
renders the SAME <PortfolioDetailsFields> inside a standalone <Dialog>,
|
|
45
|
+
with a "Save Changes" action.
|
|
46
|
+
|
|
47
|
+
Both use isPortfolioDetailsValid() and the same always-enabled-submit,
|
|
48
|
+
outline-on-submit validation rule.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/* ------------------------------------------------------------------ */
|
|
52
|
+
/* Domain types */
|
|
53
|
+
/* ------------------------------------------------------------------ */
|
|
54
|
+
|
|
55
|
+
/** How a portfolio decides its members (two kinds, three context types). */
|
|
56
|
+
|
|
57
|
+
/** Grouping of the projects multi-select — matches Invite-to-Projects. */
|
|
58
|
+
|
|
59
|
+
/** The editable shape shared by create step 2 and the edit dialog. */
|
|
60
|
+
|
|
61
|
+
/** A blank custom portfolio — the fallback seed for the edit dialog. */
|
|
62
|
+
var DEFAULT_PORTFOLIO_FORM_VALUES = exports.DEFAULT_PORTFOLIO_FORM_VALUES = {
|
|
63
|
+
type: "custom",
|
|
64
|
+
name: "",
|
|
65
|
+
context: undefined,
|
|
66
|
+
projectIds: [],
|
|
67
|
+
groupBy: "favorites",
|
|
68
|
+
visibility: "everyone"
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/* ------------------------------------------------------------------ */
|
|
72
|
+
/* Pickers' mock data */
|
|
73
|
+
/* ------------------------------------------------------------------ */
|
|
74
|
+
|
|
75
|
+
var LEADERS_LIST = exports.LEADERS_LIST = [{
|
|
76
|
+
name: "Theo Brandt",
|
|
77
|
+
short: "Theo B."
|
|
78
|
+
}, {
|
|
79
|
+
name: "Isabel Cortez",
|
|
80
|
+
short: "Isabel C."
|
|
81
|
+
}, {
|
|
82
|
+
name: "Grace Bauer",
|
|
83
|
+
short: "Grace B."
|
|
84
|
+
}, {
|
|
85
|
+
name: "Noah Mercer",
|
|
86
|
+
short: "Noah M."
|
|
87
|
+
}];
|
|
88
|
+
var CATEGORIES = exports.CATEGORIES = ["Brand & Identity", "Web & Product", "Marketing", "Internal Ops"];
|
|
89
|
+
var CLIENTS = exports.CLIENTS = ["Aperture Studio", "Orbit Telecom", "Northwind Traders", "Meridian Health"];
|
|
90
|
+
var PICKER_PROJECTS = [{
|
|
91
|
+
id: 1,
|
|
92
|
+
name: "Website Redesign",
|
|
93
|
+
client: "Aperture Studio",
|
|
94
|
+
category: "Web & Product",
|
|
95
|
+
label: "Design",
|
|
96
|
+
leader: "Theo Brandt",
|
|
97
|
+
favorite: true
|
|
98
|
+
}, {
|
|
99
|
+
id: 2,
|
|
100
|
+
name: "Brand Refresh",
|
|
101
|
+
client: "Aperture Studio",
|
|
102
|
+
category: "Brand & Identity",
|
|
103
|
+
label: "Design",
|
|
104
|
+
leader: "Isabel Cortez",
|
|
105
|
+
favorite: true
|
|
106
|
+
}, {
|
|
107
|
+
id: 3,
|
|
108
|
+
name: "Mobile App",
|
|
109
|
+
client: "Orbit Telecom",
|
|
110
|
+
category: "Web & Product",
|
|
111
|
+
label: "Build",
|
|
112
|
+
leader: "Grace Bauer",
|
|
113
|
+
favorite: false
|
|
114
|
+
}, {
|
|
115
|
+
id: 4,
|
|
116
|
+
name: "Q3 Campaign",
|
|
117
|
+
client: "Orbit Telecom",
|
|
118
|
+
category: "Marketing",
|
|
119
|
+
label: "Campaign",
|
|
120
|
+
leader: "Noah Mercer",
|
|
121
|
+
favorite: true
|
|
122
|
+
}, {
|
|
123
|
+
id: 5,
|
|
124
|
+
name: "Internal Wiki",
|
|
125
|
+
client: "",
|
|
126
|
+
category: "Internal Ops",
|
|
127
|
+
label: "",
|
|
128
|
+
leader: "Theo Brandt",
|
|
129
|
+
favorite: false
|
|
130
|
+
}, {
|
|
131
|
+
id: 6,
|
|
132
|
+
name: "Packaging System",
|
|
133
|
+
client: "Northwind Traders",
|
|
134
|
+
category: "Brand & Identity",
|
|
135
|
+
label: "Design",
|
|
136
|
+
leader: "Isabel Cortez",
|
|
137
|
+
favorite: false
|
|
138
|
+
}, {
|
|
139
|
+
id: 7,
|
|
140
|
+
name: "Support Portal",
|
|
141
|
+
client: "Meridian Health",
|
|
142
|
+
category: "Web & Product",
|
|
143
|
+
label: "Build",
|
|
144
|
+
leader: "Grace Bauer",
|
|
145
|
+
favorite: false
|
|
146
|
+
}, {
|
|
147
|
+
id: 8,
|
|
148
|
+
name: "Annual Report",
|
|
149
|
+
client: "Northwind Traders",
|
|
150
|
+
category: "Marketing",
|
|
151
|
+
label: "Campaign",
|
|
152
|
+
leader: "Noah Mercer",
|
|
153
|
+
favorite: true
|
|
154
|
+
}];
|
|
155
|
+
|
|
156
|
+
/* Group-by options and default match the Invite-to-Projects picker exactly. */
|
|
157
|
+
var GROUP_BY_OPTIONS = [{
|
|
158
|
+
id: "favorites",
|
|
159
|
+
name: "Favorites"
|
|
160
|
+
}, {
|
|
161
|
+
id: "labels",
|
|
162
|
+
name: "Label"
|
|
163
|
+
}, {
|
|
164
|
+
id: "companies",
|
|
165
|
+
name: "Client"
|
|
166
|
+
}, {
|
|
167
|
+
id: "categories",
|
|
168
|
+
name: "Category"
|
|
169
|
+
}, {
|
|
170
|
+
id: "leaders",
|
|
171
|
+
name: "Project Leader"
|
|
172
|
+
}];
|
|
173
|
+
var projectOptionId = function projectOptionId(project) {
|
|
174
|
+
return "p".concat(project.id);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/** A small deterministic set of project option ids — seeds a custom
|
|
178
|
+
portfolio's edit dialog so the picker reads as an existing selection. */
|
|
179
|
+
var sampleProjectOptionIds = exports.sampleProjectOptionIds = function sampleProjectOptionIds(count) {
|
|
180
|
+
return PICKER_PROJECTS.slice(0, Math.max(0, count)).map(projectOptionId);
|
|
181
|
+
};
|
|
182
|
+
var toProjectOptions = function toProjectOptions(projects) {
|
|
183
|
+
return projects.map(function (project) {
|
|
184
|
+
return {
|
|
185
|
+
id: projectOptionId(project),
|
|
186
|
+
name: project.name
|
|
187
|
+
};
|
|
188
|
+
}).sort(function (a, b) {
|
|
189
|
+
return a.name.localeCompare(b.name);
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/* Build the grouped option tree the Select expects. Alphabetical rows and
|
|
194
|
+
groups; the "Without ..." / "Other" bucket sits last; the Favorites grouping
|
|
195
|
+
collapses to a flat list when it is the only group (as the app's does). */
|
|
196
|
+
var groupPickerProjects = function groupPickerProjects(groupBy) {
|
|
197
|
+
if (groupBy === "favorites") {
|
|
198
|
+
var favorite = PICKER_PROJECTS.filter(function (project) {
|
|
199
|
+
return project.favorite;
|
|
200
|
+
});
|
|
201
|
+
var other = PICKER_PROJECTS.filter(function (project) {
|
|
202
|
+
return !project.favorite;
|
|
203
|
+
});
|
|
204
|
+
var groups = [];
|
|
205
|
+
if (favorite.length) {
|
|
206
|
+
groups.push({
|
|
207
|
+
id: "g-fav",
|
|
208
|
+
name: "Favorite",
|
|
209
|
+
options: toProjectOptions(favorite)
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (other.length) {
|
|
213
|
+
groups.push({
|
|
214
|
+
id: "g-other",
|
|
215
|
+
name: "Other",
|
|
216
|
+
options: toProjectOptions(other)
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return groups.length === 1 ? groups[0].options : groups;
|
|
220
|
+
}
|
|
221
|
+
var field = groupBy === "labels" ? "label" : groupBy === "companies" ? "client" : groupBy === "categories" ? "category" : "leader";
|
|
222
|
+
var without = groupBy === "labels" ? "Without Label" : groupBy === "companies" ? "Without Client" : groupBy === "categories" ? "Without Category" : "Without Leader";
|
|
223
|
+
var buckets = new Map();
|
|
224
|
+
PICKER_PROJECTS.forEach(function (project) {
|
|
225
|
+
var _buckets$get;
|
|
226
|
+
var key = project[field] || without;
|
|
227
|
+
if (!buckets.has(key)) {
|
|
228
|
+
buckets.set(key, []);
|
|
229
|
+
}
|
|
230
|
+
(_buckets$get = buckets.get(key)) === null || _buckets$get === void 0 || _buckets$get.push(project);
|
|
231
|
+
});
|
|
232
|
+
return Array.from(buckets.entries()).map(function (_ref) {
|
|
233
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
234
|
+
name = _ref2[0],
|
|
235
|
+
projects = _ref2[1];
|
|
236
|
+
return {
|
|
237
|
+
id: "g-".concat(name),
|
|
238
|
+
name,
|
|
239
|
+
options: toProjectOptions(projects)
|
|
240
|
+
};
|
|
241
|
+
}).sort(function (a, b) {
|
|
242
|
+
return a.name === without ? 1 : b.name === without ? -1 : a.name.localeCompare(b.name);
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/* ------------------------------------------------------------------ */
|
|
247
|
+
/* Type + visibility option copy */
|
|
248
|
+
/* ------------------------------------------------------------------ */
|
|
249
|
+
|
|
250
|
+
var PORTFOLIO_TYPES = exports.PORTFOLIO_TYPES = [{
|
|
251
|
+
id: "custom",
|
|
252
|
+
title: "Custom Portfolio",
|
|
253
|
+
description: "The projects you pick by hand. Nothing joins automatically."
|
|
254
|
+
}, {
|
|
255
|
+
id: "client",
|
|
256
|
+
title: "Client Portfolio",
|
|
257
|
+
description: "All projects for a client company. New ones join automatically."
|
|
258
|
+
}, {
|
|
259
|
+
id: "leader",
|
|
260
|
+
title: "Project Leader Portfolio",
|
|
261
|
+
description: "All projects led by a person. New ones join automatically."
|
|
262
|
+
}, {
|
|
263
|
+
id: "category",
|
|
264
|
+
title: "Category Portfolio",
|
|
265
|
+
description: "All projects in a project category. New ones join automatically."
|
|
266
|
+
}];
|
|
267
|
+
var VISIBILITY_OPTIONS = exports.VISIBILITY_OPTIONS = [{
|
|
268
|
+
id: "everyone",
|
|
269
|
+
title: "Visible to Everyone",
|
|
270
|
+
description: "Anyone who can use portfolios sees this one. They still only see the projects they already have access to."
|
|
271
|
+
}, {
|
|
272
|
+
id: "me",
|
|
273
|
+
title: "Visible Only to Me",
|
|
274
|
+
description: "Nobody else sees this portfolio."
|
|
275
|
+
}];
|
|
276
|
+
var contextFieldLabel = exports.contextFieldLabel = function contextFieldLabel(type) {
|
|
277
|
+
return type === "custom" ? "Projects" : type === "category" ? "Category" : type === "client" ? "Client" : "Project leader";
|
|
278
|
+
};
|
|
279
|
+
var leaderShortName = exports.leaderShortName = function leaderShortName(name) {
|
|
280
|
+
var _LEADERS_LIST$find$sh, _LEADERS_LIST$find;
|
|
281
|
+
return (_LEADERS_LIST$find$sh = (_LEADERS_LIST$find = LEADERS_LIST.find(function (leader) {
|
|
282
|
+
return leader.name === name;
|
|
283
|
+
})) === null || _LEADERS_LIST$find === void 0 ? void 0 : _LEADERS_LIST$find.short) !== null && _LEADERS_LIST$find$sh !== void 0 ? _LEADERS_LIST$find$sh : name;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/* Default names: "{Category} Projects", "{Client} Projects", "Lead by {N.}". */
|
|
287
|
+
var defaultPortfolioName = exports.defaultPortfolioName = function defaultPortfolioName(type, context) {
|
|
288
|
+
if (!context) return "";
|
|
289
|
+
if (type === "category" || type === "client") return "".concat(context, " Projects");
|
|
290
|
+
if (type === "leader") return "Lead by ".concat(leaderShortName(context));
|
|
291
|
+
return "";
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
/* ------------------------------------------------------------------ */
|
|
295
|
+
/* Validation (shared by create step 2 and the edit dialog) */
|
|
296
|
+
/* ------------------------------------------------------------------ */
|
|
297
|
+
|
|
298
|
+
/** Name is required; a custom portfolio needs at least one project, a context
|
|
299
|
+
portfolio needs its context chosen. Same rule for create and edit. */
|
|
300
|
+
var isPortfolioDetailsValid = exports.isPortfolioDetailsValid = function isPortfolioDetailsValid(values) {
|
|
301
|
+
return values.name.trim().length > 0 && (values.type === "custom" ? values.projectIds.length > 0 : Boolean(values.context));
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/* ------------------------------------------------------------------ */
|
|
305
|
+
/* Pickers */
|
|
306
|
+
/* ------------------------------------------------------------------ */
|
|
307
|
+
|
|
308
|
+
/* Group-by control: the SortGeneralIcon button the Invite-to-Projects picker
|
|
309
|
+
shows as the search bar's right-side adornment. Controls grouping, not sort. */
|
|
310
|
+
var ProjectsGroupBy = function ProjectsGroupBy(_ref3) {
|
|
311
|
+
var selected = _ref3.selected,
|
|
312
|
+
_onChange = _ref3.onChange;
|
|
313
|
+
return /*#__PURE__*/_react.default.createElement(_Select.Select, {
|
|
314
|
+
keepSameOptionsOrder: true,
|
|
315
|
+
disableSearch: true,
|
|
316
|
+
disabledInternalSort: true,
|
|
317
|
+
forceCloseMenu: true,
|
|
318
|
+
position: "bottom-end",
|
|
319
|
+
selected: selected,
|
|
320
|
+
onChange: function onChange(value) {
|
|
321
|
+
return _onChange(value);
|
|
322
|
+
},
|
|
323
|
+
options: GROUP_BY_OPTIONS,
|
|
324
|
+
target: /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
|
|
325
|
+
type: "button",
|
|
326
|
+
variant: "text gray"
|
|
327
|
+
}, /*#__PURE__*/_react.default.createElement(_Icons.SortGeneralIcon, null))
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
var ProjectsPicker = function ProjectsPicker(_ref4) {
|
|
331
|
+
var selected = _ref4.selected,
|
|
332
|
+
_onChange2 = _ref4.onChange,
|
|
333
|
+
groupBy = _ref4.groupBy,
|
|
334
|
+
onGroupBy = _ref4.onGroupBy,
|
|
335
|
+
invalid = _ref4.invalid;
|
|
336
|
+
var options = (0, _react.useMemo)(function () {
|
|
337
|
+
return groupPickerProjects(groupBy);
|
|
338
|
+
}, [groupBy]);
|
|
339
|
+
var count = selected.length;
|
|
340
|
+
var triggerText = count === 0 ? "Choose projects" : count === 1 ? "1 project selected" : "".concat(count, " projects selected");
|
|
341
|
+
return /*#__PURE__*/_react.default.createElement(_Select.Select, {
|
|
342
|
+
type: "multiple",
|
|
343
|
+
options: options,
|
|
344
|
+
selected: selected,
|
|
345
|
+
onChange: function onChange(value) {
|
|
346
|
+
return _onChange2(value);
|
|
347
|
+
},
|
|
348
|
+
noResultText: "No results",
|
|
349
|
+
endAdornment: /*#__PURE__*/_react.default.createElement(ProjectsGroupBy, {
|
|
350
|
+
selected: groupBy,
|
|
351
|
+
onChange: onGroupBy
|
|
352
|
+
}),
|
|
353
|
+
target: /*#__PURE__*/_react.default.createElement(_SelectTrigger.SelectTrigger, {
|
|
354
|
+
id: "pf-projects",
|
|
355
|
+
className: "pf-trigger",
|
|
356
|
+
invalid: invalid,
|
|
357
|
+
typographyProps: {
|
|
358
|
+
color: count > 0 ? "primary" : "quaternary"
|
|
359
|
+
}
|
|
360
|
+
}, triggerText)
|
|
361
|
+
});
|
|
362
|
+
};
|
|
363
|
+
var ContextPicker = function ContextPicker(_ref5) {
|
|
364
|
+
var type = _ref5.type,
|
|
365
|
+
value = _ref5.value,
|
|
366
|
+
_onChange3 = _ref5.onChange,
|
|
367
|
+
invalid = _ref5.invalid;
|
|
368
|
+
var options = type === "category" ? CATEGORIES.map(function (name) {
|
|
369
|
+
return {
|
|
370
|
+
id: name,
|
|
371
|
+
name
|
|
372
|
+
};
|
|
373
|
+
}) : type === "client" ? CLIENTS.map(function (name) {
|
|
374
|
+
return {
|
|
375
|
+
id: name,
|
|
376
|
+
name
|
|
377
|
+
};
|
|
378
|
+
}) : LEADERS_LIST.map(function (leader) {
|
|
379
|
+
return {
|
|
380
|
+
id: leader.name,
|
|
381
|
+
name: leader.name
|
|
382
|
+
};
|
|
383
|
+
});
|
|
384
|
+
var placeholder = type === "category" ? "Choose a category" : type === "client" ? "Choose a client" : "Choose a project leader";
|
|
385
|
+
return /*#__PURE__*/_react.default.createElement(_Select.Select, {
|
|
386
|
+
forceCloseMenu: true,
|
|
387
|
+
options: options,
|
|
388
|
+
selected: value !== null && value !== void 0 ? value : "",
|
|
389
|
+
onChange: function onChange(next) {
|
|
390
|
+
return _onChange3(String(next));
|
|
391
|
+
},
|
|
392
|
+
target: /*#__PURE__*/_react.default.createElement(_SelectTrigger.SelectTrigger, {
|
|
393
|
+
id: "pf-context",
|
|
394
|
+
className: "pf-trigger",
|
|
395
|
+
invalid: invalid,
|
|
396
|
+
typographyProps: {
|
|
397
|
+
color: value ? "primary" : "quaternary"
|
|
398
|
+
}
|
|
399
|
+
}, value !== null && value !== void 0 ? value : placeholder)
|
|
400
|
+
});
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
/* ------------------------------------------------------------------ */
|
|
404
|
+
/* The reusable form body */
|
|
405
|
+
/* ------------------------------------------------------------------ */
|
|
406
|
+
|
|
407
|
+
var StyledDetailsForm = _styledComponents.default.div.withConfig({
|
|
408
|
+
displayName: "portfolioDetails__StyledDetailsForm",
|
|
409
|
+
componentId: "sc-yxi1uj-0"
|
|
410
|
+
})(["display:flex;flex-direction:column;gap:24px;.field{display:flex;flex-direction:column;gap:8px;}.field .c-input-wrapper{width:100%;}.field .pf-trigger{width:100%;}"]);
|
|
411
|
+
/** Name + the type's picker + visibility. No Dialog wrappers and no action
|
|
412
|
+
button — the consumer (create step or edit dialog) supplies those. */
|
|
413
|
+
var PortfolioDetailsFields = exports.PortfolioDetailsFields = function PortfolioDetailsFields(_ref6) {
|
|
414
|
+
var values = _ref6.values,
|
|
415
|
+
onName = _ref6.onName,
|
|
416
|
+
onContext = _ref6.onContext,
|
|
417
|
+
onProjects = _ref6.onProjects,
|
|
418
|
+
onGroupBy = _ref6.onGroupBy,
|
|
419
|
+
onVisibility = _ref6.onVisibility,
|
|
420
|
+
showErrors = _ref6.showErrors;
|
|
421
|
+
var type = values.type,
|
|
422
|
+
name = values.name,
|
|
423
|
+
context = values.context,
|
|
424
|
+
projectIds = values.projectIds,
|
|
425
|
+
groupBy = values.groupBy,
|
|
426
|
+
visibility = values.visibility;
|
|
427
|
+
var nameInvalid = showErrors && name.trim().length === 0;
|
|
428
|
+
var pickerInvalid = showErrors && (type === "custom" ? projectIds.length === 0 : !context);
|
|
429
|
+
return /*#__PURE__*/_react.default.createElement(StyledDetailsForm, null, /*#__PURE__*/_react.default.createElement("div", {
|
|
430
|
+
className: "field"
|
|
431
|
+
}, /*#__PURE__*/_react.default.createElement(_Label.Label, {
|
|
432
|
+
htmlFor: "pf-name"
|
|
433
|
+
}, "Name"), /*#__PURE__*/_react.default.createElement(_Input.Input, {
|
|
434
|
+
id: "pf-name",
|
|
435
|
+
value: name,
|
|
436
|
+
placeholder: "Portfolio name",
|
|
437
|
+
invalid: nameInvalid,
|
|
438
|
+
onChange: function onChange(event) {
|
|
439
|
+
return onName(event.target.value);
|
|
440
|
+
}
|
|
441
|
+
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
442
|
+
className: "field"
|
|
443
|
+
}, /*#__PURE__*/_react.default.createElement(_Label.Label, {
|
|
444
|
+
htmlFor: type === "custom" ? "pf-projects" : "pf-context"
|
|
445
|
+
}, contextFieldLabel(type)), type === "custom" ? /*#__PURE__*/_react.default.createElement(ProjectsPicker, {
|
|
446
|
+
selected: projectIds,
|
|
447
|
+
onChange: onProjects,
|
|
448
|
+
groupBy: groupBy,
|
|
449
|
+
onGroupBy: onGroupBy,
|
|
450
|
+
invalid: pickerInvalid
|
|
451
|
+
}) : /*#__PURE__*/_react.default.createElement(ContextPicker, {
|
|
452
|
+
type: type,
|
|
453
|
+
value: context,
|
|
454
|
+
onChange: onContext,
|
|
455
|
+
invalid: pickerInvalid
|
|
456
|
+
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
457
|
+
className: "field"
|
|
458
|
+
}, /*#__PURE__*/_react.default.createElement(_RadioGroup.RadioGroup, {
|
|
459
|
+
label: "Visibility",
|
|
460
|
+
variant: "plain",
|
|
461
|
+
value: visibility,
|
|
462
|
+
onChange: function onChange(value) {
|
|
463
|
+
return onVisibility(value);
|
|
464
|
+
},
|
|
465
|
+
options: VISIBILITY_OPTIONS.map(function (option) {
|
|
466
|
+
return {
|
|
467
|
+
id: option.id,
|
|
468
|
+
name: option.title,
|
|
469
|
+
description: option.description
|
|
470
|
+
};
|
|
471
|
+
})
|
|
472
|
+
})));
|
|
473
|
+
};
|
|
474
|
+
PortfolioDetailsFields.displayName = "PortfolioDetailsFields";
|
|
475
|
+
|
|
476
|
+
/* ------------------------------------------------------------------ */
|
|
477
|
+
/* Edit Portfolio dialog — the create wizard's step 2, on its own */
|
|
478
|
+
/* ------------------------------------------------------------------ */
|
|
479
|
+
|
|
480
|
+
/*
|
|
481
|
+
Same fields, same validation as create step 2. The type is fixed to the
|
|
482
|
+
portfolio's kind (edit changes the details, not the kind), so there is no
|
|
483
|
+
type radio here — only the name, the type's picker, and visibility.
|
|
484
|
+
*/
|
|
485
|
+
var EditPortfolioDialog = exports.EditPortfolioDialog = function EditPortfolioDialog(_ref7) {
|
|
486
|
+
var open = _ref7.open,
|
|
487
|
+
initialValues = _ref7.initialValues,
|
|
488
|
+
onClose = _ref7.onClose,
|
|
489
|
+
onSave = _ref7.onSave;
|
|
490
|
+
var _useState = (0, _react.useState)(initialValues),
|
|
491
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
492
|
+
values = _useState2[0],
|
|
493
|
+
setValues = _useState2[1];
|
|
494
|
+
var _useState3 = (0, _react.useState)(false),
|
|
495
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
496
|
+
showErrors = _useState4[0],
|
|
497
|
+
setShowErrors = _useState4[1];
|
|
498
|
+
|
|
499
|
+
/* Re-seed from the portfolio each time the dialog opens. */
|
|
500
|
+
(0, _react.useEffect)(function () {
|
|
501
|
+
if (open) {
|
|
502
|
+
setValues(initialValues);
|
|
503
|
+
setShowErrors(false);
|
|
504
|
+
}
|
|
505
|
+
// Seed on open only — initialValues is read at that moment by design.
|
|
506
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
507
|
+
}, [open]);
|
|
508
|
+
var patch = function patch(next) {
|
|
509
|
+
return setValues(function (current) {
|
|
510
|
+
return _objectSpread(_objectSpread({}, current), next);
|
|
511
|
+
});
|
|
512
|
+
};
|
|
513
|
+
var handleSave = function handleSave() {
|
|
514
|
+
if (!isPortfolioDetailsValid(values)) {
|
|
515
|
+
setShowErrors(true);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
onSave === null || onSave === void 0 || onSave(values);
|
|
519
|
+
onClose();
|
|
520
|
+
};
|
|
521
|
+
return /*#__PURE__*/_react.default.createElement(_Dialog.Dialog, {
|
|
522
|
+
open: open,
|
|
523
|
+
onClose: onClose,
|
|
524
|
+
disableCloseOnEsc: true
|
|
525
|
+
}, /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.Title, null, "Edit Portfolio"), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.ContentDivider, null), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.Content, null, /*#__PURE__*/_react.default.createElement(PortfolioDetailsFields, {
|
|
526
|
+
values: values,
|
|
527
|
+
onName: function onName(name) {
|
|
528
|
+
return patch({
|
|
529
|
+
name
|
|
530
|
+
});
|
|
531
|
+
},
|
|
532
|
+
onContext: function onContext(context) {
|
|
533
|
+
return patch({
|
|
534
|
+
context
|
|
535
|
+
});
|
|
536
|
+
},
|
|
537
|
+
onProjects: function onProjects(projectIds) {
|
|
538
|
+
return patch({
|
|
539
|
+
projectIds
|
|
540
|
+
});
|
|
541
|
+
},
|
|
542
|
+
onGroupBy: function onGroupBy(groupBy) {
|
|
543
|
+
return patch({
|
|
544
|
+
groupBy
|
|
545
|
+
});
|
|
546
|
+
},
|
|
547
|
+
onVisibility: function onVisibility(visibility) {
|
|
548
|
+
return patch({
|
|
549
|
+
visibility
|
|
550
|
+
});
|
|
551
|
+
},
|
|
552
|
+
showErrors: showErrors
|
|
553
|
+
})), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.ContentDivider, null), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.Actions, null, /*#__PURE__*/_react.default.createElement(_Button.Button, {
|
|
554
|
+
variant: "primary",
|
|
555
|
+
style: {
|
|
556
|
+
marginRight: "12px"
|
|
557
|
+
},
|
|
558
|
+
onClick: handleSave
|
|
559
|
+
}, "Save Changes"), /*#__PURE__*/_react.default.createElement(_Button.Button, {
|
|
560
|
+
variant: "secondary",
|
|
561
|
+
"data-action": "cancel",
|
|
562
|
+
onClick: onClose
|
|
563
|
+
}, "Cancel")));
|
|
564
|
+
};
|
|
565
|
+
EditPortfolioDialog.displayName = "EditPortfolioDialog";
|
|
566
|
+
//# sourceMappingURL=portfolioDetails.js.map
|