@activecollab/components
Version:
ActiveCollab Components
605 lines (585 loc) • 33.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TabHeader = exports.ProjectPageHeader = exports.PageHeader = void 0;
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireWildcard(require("styled-components"));
var _ConnectRepositoryDialog = require("./ConnectRepositoryDialog");
var _RoundAvatar = require("./RoundAvatar");
var _tokens = require("./tokens");
var _WebhookLogsDialog = require("./WebhookLogsDialog");
var _Badge = require("../../components/Badge");
var _Button = require("../../components/Button");
var _GlobalAddButton = require("../../components/Button/GlobalAddButton");
var _CompleteCheckbox = require("../../components/CompleteCheckbox");
var _CounterButton = require("../../components/CounterButton");
var _Dialog = require("../../components/Dialog");
var _Header = require("../../components/Header");
var _IconButton = require("../../components/IconButton");
var _Icons = require("../../components/Icons");
var _List = require("../../components/List");
var _Menu = require("../../components/Menu");
var _Nav = require("../../components/Nav");
var _ProgressPie = require("../../components/ProgressPie");
var _ToastMessage = require("../../components/ToastMessage");
var _Tooltip = require("../../components/Tooltip");
var _Transitions = require("../../components/Transitions");
var _Typography = require("../../components/Typography");
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); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
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."); }
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; } }
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; }
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; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
/** Gold used for the project-leader cues (a data colour, not a theme token). */
var LEADER_GOLD = "#FFCC6B";
/* ------------------------------------------------------------------ */
/* Page header row (mirrors PageHeader.jsx) */
/* ------------------------------------------------------------------ */
var StyledPageHeader = _styledComponents.default.div.withConfig({
displayName: "headers__StyledPageHeader",
componentId: "sc-yf6o6n-0"
})(["display:flex;align-items:center;justify-content:space-between;margin:12px 0;width:100%;height:40px;flex-shrink:0;.page-header-left{display:flex;align-items:center;width:100%;max-width:100%;@media (min-width:", "){min-width:0;}}.back-button{flex-shrink:0;margin-right:4px;@media (min-width:", "){margin-right:8px;}}.page-title-desktop{display:none;margin-right:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;@media (min-width:", "){display:block;}}.page-title-mobile{display:block;margin-right:8px;font-weight:300;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;@media (min-width:", "){display:none;}}.page-header-children{flex-shrink:0;display:flex;align-items:center;}.page-header-spacer{display:none;height:100%;width:208px;flex-shrink:0;@media (min-width:", "){display:flex;}}"], _tokens.SM, _tokens.MD, _tokens.MD, _tokens.MD, _tokens.SM);
/** Generic page header (title + optional controls), mirrors PageHeader.jsx. */
var PageHeader = exports.PageHeader = function PageHeader(_ref) {
var title = _ref.title,
children = _ref.children;
return /*#__PURE__*/_react.default.createElement(StyledPageHeader, null, /*#__PURE__*/_react.default.createElement("div", {
className: "page-header-left"
}, /*#__PURE__*/_react.default.createElement(_Typography.Title2, {
className: "page-title-desktop"
}, title), /*#__PURE__*/_react.default.createElement(_Typography.Header2, {
className: "page-title-mobile"
}, title), /*#__PURE__*/_react.default.createElement("div", {
className: "page-header-children"
}, children)), /*#__PURE__*/_react.default.createElement("div", {
className: "page-header-spacer"
}));
};
PageHeader.displayName = "PageHeader";
/* ------------------------------------------------------------------ */
/* Project page header (mirrors ProjectPage.js Page.Header children) */
/* ------------------------------------------------------------------ */
var StyledProjectHeaderChildren = _styledComponents.default.div.withConfig({
displayName: "headers__StyledProjectHeaderChildren",
componentId: "sc-yf6o6n-1"
})(["display:flex;align-items:center;gap:8px;.project-progress{display:flex;align-items:center;margin-left:4px;}"]);
/* Project "..." options menu (Menu + List with leading-icon items). Two items
(Favorite, Subscribe) have a checkbox on the right. Clicks are no-ops. */
var StyledProjectMenu = _styledComponents.default.div.withConfig({
displayName: "headers__StyledProjectMenu",
componentId: "sc-yf6o6n-2"
})([".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;}"]);
/* The project "..." menu shares the Webhook Logs dialog's repository /
* connection universe, so a repository connected here is one that dialog can
* pre-filter by. `WebhookConnection` and `Connection` share a shape, and a
* `WebhookRepository`'s `path` maps onto a `Repository`'s `name`. */
var PROJECT_MENU_CONNECTIONS = _WebhookLogsDialog.WEBHOOK_CONNECTIONS;
var PROJECT_MENU_REPOSITORIES = _WebhookLogsDialog.WEBHOOK_REPOSITORIES.map(function (repo) {
return {
id: repo.id,
name: repo.path,
connectionId: repo.connectionId
};
});
/** Submenu row label for a connected repository: "path (Connection)". The
* service type is omitted because the leading provider icon already conveys
* it. */
var repositoryMenuLabel = function repositoryMenuLabel(repo) {
var connection = PROJECT_MENU_CONNECTIONS.find(function (c) {
return c.id === repo.connectionId;
});
return connection ? "".concat(repo.name, " (").concat(connection.name, ")") : repo.name;
};
/** Provider glyph for a connected repository: GitHub / GitLab for those
* services, and the generic Git mark for anything else (e.g. an upcoming
* Bitbucket connection). */
var repositoryIcon = function repositoryIcon(repo) {
var connection = PROJECT_MENU_CONNECTIONS.find(function (c) {
return c.id === repo.connectionId;
});
switch (connection === null || connection === void 0 ? void 0 : connection.service) {
case "github":
return _Icons.GitHubIcon;
case "gitlab":
return _Icons.GitLabIcon;
default:
return _Icons.GitIcon;
}
};
/** Width of the project "..." menu (matches the DS "normal" menu mode). */
var PROJECT_MENU_WIDTH = 260;
/* The menu drills in place (index → Repositories), so the paper must clip the
sliding panels and give them a positioning context. */
var ProjectMenuSliderStyle = (0, _styledComponents.createGlobalStyle)([".c-simple-menu__paper.project-options-menu{overflow:hidden;position:relative;}"]);
/* Toast anchor — fixed, upper-right corner (the toast slides down from the
top). The wrapper ignores pointer events so it never blocks the page; only
the toast itself is interactive. */
var StyledToastAnchor = _styledComponents.default.div.withConfig({
displayName: "headers__StyledToastAnchor",
componentId: "sc-yf6o6n-3"
})(["position:fixed;top:16px;right:16px;z-index:10000;pointer-events:none;.c-toast-message{pointer-events:auto;}"]);
/**
* The project "..." options menu. When the `source` module is loaded it gains
* a **Repositories** item that, instead of flying out to the side, **drills in
* within the same menu** (the pattern used across the app — see `Filter`): the
* index slides out to the left and the Repositories view (a back-arrow header,
* the connected repositories sorted by name, and a **Connect Repository**
* action) slides in. Connecting adds a repository to the list; clicking one
* would, in production, open it in a new tab (surfaced here via a dialog).
*/
var ProjectOptionsMenu = function ProjectOptionsMenu(_ref2) {
var _ref2$sourceModuleLoa = _ref2.sourceModuleLoaded,
sourceModuleLoaded = _ref2$sourceModuleLoa === void 0 ? false : _ref2$sourceModuleLoa,
_ref2$initialConnecte = _ref2.initialConnectedRepositories,
initialConnectedRepositories = _ref2$initialConnecte === void 0 ? [] : _ref2$initialConnecte,
_ref2$canManageProjec = _ref2.canManageProjectRepositories,
canManageProjectRepositories = _ref2$canManageProjec === void 0 ? true : _ref2$canManageProjec;
var _useState = (0, _react.useState)(false),
_useState2 = _slicedToArray(_useState, 2),
open = _useState2[0],
setOpen = _useState2[1];
var _useState3 = (0, _react.useState)("index"),
_useState4 = _slicedToArray(_useState3, 2),
view = _useState4[0],
setView = _useState4[1];
var _useState5 = (0, _react.useState)(false),
_useState6 = _slicedToArray(_useState5, 2),
webhookLogsOpen = _useState6[0],
setWebhookLogsOpen = _useState6[1];
var _useState7 = (0, _react.useState)(true),
_useState8 = _slicedToArray(_useState7, 2),
isLeft = _useState8[0],
setIsLeft = _useState8[1];
var _useState9 = (0, _react.useState)(0),
_useState0 = _slicedToArray(_useState9, 2),
height = _useState0[0],
setHeight = _useState0[1];
// Connected repositories drive the count badge on the Repositories item. In
// production this count comes from the project's `count_repositories` counter,
// kept current via pusher/websocket events, so the badge reflects repositories
// connected or disconnected by anyone — not just the current user's actions.
var _useState1 = (0, _react.useState)(initialConnectedRepositories),
_useState10 = _slicedToArray(_useState1, 2),
connectedRepos = _useState10[0],
setConnectedRepos = _useState10[1];
var _useState11 = (0, _react.useState)(false),
_useState12 = _slicedToArray(_useState11, 2),
connectOpen = _useState12[0],
setConnectOpen = _useState12[1];
var _useState13 = (0, _react.useState)(false),
_useState14 = _slicedToArray(_useState13, 2),
infoOpen = _useState14[0],
setInfoOpen = _useState14[1];
var _useState15 = (0, _react.useState)(false),
_useState16 = _slicedToArray(_useState15, 2),
toastOpen = _useState16[0],
setToastOpen = _useState16[1];
// Bumped on each connect so the toast remounts and its auto-hide timer
// restarts from the moment it is shown.
var _useState17 = (0, _react.useState)(0),
_useState18 = _slicedToArray(_useState17, 2),
toastKey = _useState18[0],
setToastKey = _useState18[1];
// Repositories still available to connect (not already on the project).
var connectableRepos = PROJECT_MENU_REPOSITORIES.filter(function (r) {
return !connectedRepos.some(function (c) {
return c.id === r.id;
});
});
// Connected repositories are listed in the submenu sorted by name.
var sortedRepos = [...connectedRepos].sort(function (a, b) {
return a.name.localeCompare(b.name);
});
// Each view measures itself as it mounts so the paper can animate its height.
var measure = (0, _react.useCallback)(function (node) {
if (node) {
setHeight(node.offsetHeight);
}
}, []);
var goToRepositories = function goToRepositories() {
setView("repositories");
setIsLeft(true);
};
var backToIndex = function backToIndex() {
setView("index");
setIsLeft(false);
};
var handleClose = function handleClose() {
setOpen(false);
// Reset to the index so the next open starts at the top level.
setView("index");
setIsLeft(true);
};
var handleConnected = function handleConnected(repo) {
setConnectedRepos(function (prev) {
return prev.some(function (r) {
return r.id === repo.id;
}) ? prev : [...prev, repo];
});
setToastOpen(true);
setToastKey(function (k) {
return k + 1;
});
};
var handleConnect = function handleConnect() {
handleClose();
setConnectOpen(true);
};
// In production this closes the menu and opens the repository in a new tab;
// in the mock we surface that behaviour in a small dialog instead.
var handleOpenRepository = function handleOpenRepository() {
handleClose();
setInfoOpen(true);
};
var handleOpenWebhookLogs = function handleOpenWebhookLogs() {
handleClose();
setWebhookLogsOpen(true);
};
var indexView = /*#__PURE__*/_react.default.createElement(StyledProjectMenu, null, /*#__PURE__*/_react.default.createElement(_List.List, {
style: {
padding: "8px 0"
},
tabIndex: -1
}, /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.EditIcon, null), "Edit"), /*#__PURE__*/_react.default.createElement(_List.ListItem, {
className: "toggle-item"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "opt-left"
}, /*#__PURE__*/_react.default.createElement(_Icons.StarIcon, null), "Mark as Favorite"), /*#__PURE__*/_react.default.createElement(_CompleteCheckbox.CompleteCheckbox, {
primary: true,
completed: true
})), /*#__PURE__*/_react.default.createElement(_List.ListItem, {
className: "toggle-item"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "opt-left"
}, /*#__PURE__*/_react.default.createElement(_Icons.NotificationBellIcon, null), "Subscribe to Everything"), /*#__PURE__*/_react.default.createElement(_CompleteCheckbox.CompleteCheckbox, {
primary: true,
completed: false
})), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.LabelsIcon, null), "Manage Task Labels"), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.InsertLinkIcon, null), "Copy Link"), /*#__PURE__*/_react.default.createElement(_List.ListSeparator, null), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.CheckboxBlankTogglerIcon, null), "Complete"), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.DownloadIcon, null), "Export"), sourceModuleLoaded ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_List.ListSeparator, null), /*#__PURE__*/_react.default.createElement(_List.ListItem, {
className: "toggle-item submenu-item",
onClick: goToRepositories
}, /*#__PURE__*/_react.default.createElement("span", {
className: "opt-left"
}, /*#__PURE__*/_react.default.createElement(_Icons.GitRepositoryIcon, null), "Repositories"), /*#__PURE__*/_react.default.createElement("span", {
className: "repo-right"
}, connectedRepos.length > 0 ? /*#__PURE__*/_react.default.createElement(_Badge.Badge, {
isStandalone: true,
dimension: 16,
value: connectedRepos.length
}) : null, /*#__PURE__*/_react.default.createElement(_Icons.CaretRightIcon, {
className: "repo-caret",
width: 16,
height: 16
})))) : null, /*#__PURE__*/_react.default.createElement(_List.ListSeparator, null), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.DuplicateIcon, null), "Duplicate"), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.ProjectTemplateIcon, null), "Apply Template"), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.ProjectTemplateConvertIcon, null), "Convert to Template"), /*#__PURE__*/_react.default.createElement(_List.ListSeparator, null), /*#__PURE__*/_react.default.createElement(_List.ListItem, null, /*#__PURE__*/_react.default.createElement(_Icons.TrashIcon, null), "Delete")));
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(ProjectMenuSliderStyle, null), /*#__PURE__*/_react.default.createElement(_Menu.Menu, {
open: open,
onOpen: function onOpen() {
return setOpen(true);
},
onClose: handleClose,
position: "bottom-end",
menuClassName: sourceModuleLoaded ? "project-options-menu" : undefined,
target: /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
type: "button",
variant: "text gray",
active: open
}, /*#__PURE__*/_react.default.createElement(_Icons.TreeDotsIcon, null))
}, sourceModuleLoaded ? /*#__PURE__*/_react.default.createElement(_Transitions.ResizeTransition, {
in: true,
style: {
height,
width: PROJECT_MENU_WIDTH
}
}, /*#__PURE__*/_react.default.createElement("div", {
style: {
position: "relative",
overflow: "hidden"
}
}, /*#__PURE__*/_react.default.createElement(_Transitions.SlideLeftRightTransition, {
in: view === "index",
direction: isLeft ? "left" : "right"
}, /*#__PURE__*/_react.default.createElement("div", {
ref: measure,
style: {
width: PROJECT_MENU_WIDTH
}
}, indexView)), /*#__PURE__*/_react.default.createElement(_Transitions.SlideLeftRightTransition, {
in: view === "repositories",
direction: isLeft ? "left" : "right"
}, /*#__PURE__*/_react.default.createElement("div", {
ref: measure,
style: {
width: PROJECT_MENU_WIDTH
}
}, /*#__PURE__*/_react.default.createElement(_Menu.MenuHeader, {
title: "Repositories",
leftElement: /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
type: "button",
variant: "text gray",
size: "small",
onClick: backToIndex,
"aria-label": "Back"
}, /*#__PURE__*/_react.default.createElement(_Icons.ArrowLeftIcon, null))
}), /*#__PURE__*/_react.default.createElement(StyledProjectMenu, null, /*#__PURE__*/_react.default.createElement(_List.List, {
style: {
padding: "8px 0"
},
tabIndex: -1
}, sortedRepos.map(function (repo) {
var RepoIcon = repositoryIcon(repo);
return /*#__PURE__*/_react.default.createElement(_List.ListItem, {
key: repo.id,
className: "repo-row",
onClick: function onClick() {
return handleOpenRepository();
}
}, /*#__PURE__*/_react.default.createElement(RepoIcon, null), /*#__PURE__*/_react.default.createElement("span", {
className: "repo-name"
}, repositoryMenuLabel(repo)));
}), sortedRepos.length > 0 ? /*#__PURE__*/_react.default.createElement(_List.ListSeparator, null) : null, sortedRepos.length > 0 && canManageProjectRepositories ? /*#__PURE__*/_react.default.createElement(_List.ListItem, {
onClick: handleOpenWebhookLogs
}, /*#__PURE__*/_react.default.createElement(_Icons.AccessLogIcon, null), "Webhook Logs") : null, /*#__PURE__*/_react.default.createElement(_List.ListItem, {
onClick: handleConnect
}, /*#__PURE__*/_react.default.createElement(_Icons.GitRepositoryConnectIcon, null), "Connect Repository"))))))) : indexView), /*#__PURE__*/_react.default.createElement(_ConnectRepositoryDialog.ConnectRepositoryDialog, {
open: connectOpen,
onClose: function onClose() {
return setConnectOpen(false);
},
onConnect: handleConnected,
repositories: connectableRepos,
connections: PROJECT_MENU_CONNECTIONS
}), /*#__PURE__*/_react.default.createElement(_WebhookLogsDialog.WebhookLogsDialog, {
open: webhookLogsOpen,
onClose: function onClose() {
return setWebhookLogsOpen(false);
},
repositoryIds: sortedRepos.map(function (repo) {
return repo.id;
})
}), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog, {
open: infoOpen,
onClose: function onClose() {
return setInfoOpen(false);
},
enableBackgroundClick: true
}, /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.Title, null, "Open Repository"), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.ContentDivider, null), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.Content, null, /*#__PURE__*/_react.default.createElement(_Typography.Body2, null, "In production, this click would close the menu and open the repository in a new browser tab.")), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.ContentDivider, null), /*#__PURE__*/_react.default.createElement(_Dialog.Dialog.Actions, null, /*#__PURE__*/_react.default.createElement(_Button.Button, {
variant: "primary",
onClick: function onClick() {
return setInfoOpen(false);
}
}, "Got it"))), /*#__PURE__*/_react.default.createElement(StyledToastAnchor, null, /*#__PURE__*/_react.default.createElement(_Transitions.SlideFromTop, {
in: toastOpen
}, /*#__PURE__*/_react.default.createElement(_ToastMessage.ToastMessage, {
key: toastKey,
className: "c-toast-message",
type: "success",
text: "Repository connected.",
dismissible: true,
dropShadow: true,
timeout: 3000,
onClose: function onClose() {
return setToastOpen(false);
}
}))));
};
/* People popover (mirrors the project header People dropdown): a header row
("People" + add button), a "Members" section and a row per member. The
project leader shows a gold crown; other members reveal a "set as leader"
crown and a remove button on hover. Clicks are no-ops. */
var PROJECT_MEMBERS = [{
name: "Theo Brandt",
initials: "TB",
color: _tokens.AVATAR_COLORS.blue,
leader: true
}, {
name: "Iris Calloway",
initials: "IC",
color: _tokens.AVATAR_COLORS.purple
}, {
name: "Account Director",
initials: "AD",
color: "#8A8F98"
}, {
name: "Grace Bennett",
initials: "GB",
color: _tokens.AVATAR_COLORS.orange
}];
var StyledPeopleMenu = _styledComponents.default.div.withConfig({
displayName: "headers__StyledPeopleMenu",
componentId: "sc-yf6o6n-4"
})(["width:256px;.members-label{display:block;margin:8px 0;padding:0 16px;}.member-row{position:relative;display:flex;align-items:center;min-height:40px;margin:0 8px;padding:2px 8px;border-radius:4px;cursor:default;transition:background-color ", ";}.member-row:hover{background-color:var(--color-theme-200);}.member-row.leader::before{content:\"\";position:absolute;top:4px;bottom:4px;left:0;width:4px;border-radius:4px;background-color:", ";}.member-row.leader .member-avatar{outline:2px solid ", ";outline-offset:-2px;}.member-name{flex:1;margin-left:12px;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.member-right{display:flex;align-items:center;gap:2px;flex-shrink:0;margin-left:8px;}.leader-crown{flex-shrink:0;}.member-options{display:none;align-items:center;gap:2px;}.member-row:hover .member-options{display:flex;}"], _tokens.TRANSITION, LEADER_GOLD, LEADER_GOLD);
var PeoplePopover = function PeoplePopover() {
var _useState19 = (0, _react.useState)(false),
_useState20 = _slicedToArray(_useState19, 2),
open = _useState20[0],
setOpen = _useState20[1];
return /*#__PURE__*/_react.default.createElement(_Menu.Menu, {
open: open,
onOpen: function onOpen() {
return setOpen(true);
},
onClose: function onClose() {
return setOpen(false);
},
position: "bottom-end",
target: /*#__PURE__*/_react.default.createElement(_CounterButton.CounterButton, {
label: String(PROJECT_MEMBERS.length),
icon: /*#__PURE__*/_react.default.createElement(_Icons.PeopleIcon, null),
active: open,
onClearAll: function onClearAll() {
return undefined;
}
})
}, /*#__PURE__*/_react.default.createElement(StyledPeopleMenu, null, /*#__PURE__*/_react.default.createElement(_Menu.MenuHeader, {
title: "People",
rightElement: /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
type: "button",
variant: "text gray",
size: "small",
"aria-label": "Add People"
}, /*#__PURE__*/_react.default.createElement(_Icons.AddCrossTinyIcon, null))
}), /*#__PURE__*/_react.default.createElement(_Typography.Caption1, {
weight: "bold",
className: "members-label"
}, "Members"), PROJECT_MEMBERS.map(function (member) {
return /*#__PURE__*/_react.default.createElement("div", {
className: member.leader ? "member-row leader" : "member-row",
key: member.name
}, /*#__PURE__*/_react.default.createElement(_RoundAvatar.RoundAvatar, {
className: "member-avatar",
$bg: member.color,
$bordered: false
}, member.initials), /*#__PURE__*/_react.default.createElement(_Typography.Body2, {
className: "member-name"
}, member.name), /*#__PURE__*/_react.default.createElement("span", {
className: "member-right"
}, member.leader && /*#__PURE__*/_react.default.createElement(_Icons.CrownSelectedIcon, {
className: "leader-crown",
style: {
fill: LEADER_GOLD
}
}), /*#__PURE__*/_react.default.createElement("span", {
className: "member-options"
}, !member.leader && /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Set as Project Leader"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
type: "button",
variant: "text gray",
size: "small"
}, /*#__PURE__*/_react.default.createElement(_Icons.CrownBlankIcon, null))), /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Remove from Project"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
type: "button",
variant: "text gray",
size: "small"
}, /*#__PURE__*/_react.default.createElement(_Icons.CloseSmallIcon, null))))));
})));
};
/** The project page header: back arrow, title, progress, info, people, options. */
var ProjectPageHeader = exports.ProjectPageHeader = function ProjectPageHeader(_ref3) {
var _ref3$title = _ref3.title,
title = _ref3$title === void 0 ? "#131: Ime projekta" : _ref3$title,
_ref3$sourceModuleLoa = _ref3.sourceModuleLoaded,
sourceModuleLoaded = _ref3$sourceModuleLoa === void 0 ? false : _ref3$sourceModuleLoa,
initialConnectedRepositories = _ref3.initialConnectedRepositories,
canManageProjectRepositories = _ref3.canManageProjectRepositories;
return /*#__PURE__*/_react.default.createElement(StyledPageHeader, null, /*#__PURE__*/_react.default.createElement("div", {
className: "page-header-left"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
variant: "text gray",
className: "back-button"
}, /*#__PURE__*/_react.default.createElement(_Icons.ArrowLeftIcon, null)), /*#__PURE__*/_react.default.createElement(_Typography.Title2, {
className: "page-title-desktop"
}, title), /*#__PURE__*/_react.default.createElement(_Typography.Header2, {
className: "page-title-mobile"
}, title), /*#__PURE__*/_react.default.createElement("div", {
className: "page-header-children"
}, /*#__PURE__*/_react.default.createElement(StyledProjectHeaderChildren, null, /*#__PURE__*/_react.default.createElement("span", {
className: "project-progress"
}, /*#__PURE__*/_react.default.createElement(_ProgressPie.ProgressPie, {
radius: 11,
progress: 64,
progressColor: "var(--color-secondary)",
backgroundColor: "var(--color-theme-300)"
})), /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Project Info"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
variant: "text gray"
}, /*#__PURE__*/_react.default.createElement(_Icons.InfoIcon, null))), /*#__PURE__*/_react.default.createElement(PeoplePopover, null), /*#__PURE__*/_react.default.createElement(ProjectOptionsMenu, {
sourceModuleLoaded: sourceModuleLoaded,
initialConnectedRepositories: initialConnectedRepositories,
canManageProjectRepositories: canManageProjectRepositories
})))), /*#__PURE__*/_react.default.createElement("div", {
className: "page-header-spacer"
}));
};
ProjectPageHeader.displayName = "ProjectPageHeader";
/* ------------------------------------------------------------------ */
/* Tab bar (mirrors the <Header> with <Nav> on ProjectPage.js) */
/* ------------------------------------------------------------------ */
var NAV_TABS = ["Tasks", "Discussions", "Files", "Notes", "Activity"];
var StyledTabHeader = (0, _styledComponents.default)(_Header.Header).withConfig({
displayName: "headers__StyledTabHeader",
componentId: "sc-yf6o6n-5"
})(["justify-content:space-between;align-items:center;margin-bottom:16px;min-height:64px;flex-shrink:0;"]);
var StyledTabControls = _styledComponents.default.div.withConfig({
displayName: "headers__StyledTabControls",
componentId: "sc-yf6o6n-6"
})(["display:flex;align-items:center;flex-shrink:0;gap:4px;.vertical-separator{width:1px;height:24px;background-color:var(--color-theme-400);margin:0 8px;}.filter-button{display:flex;align-items:center;gap:6px;}"]);
/** The Tasks/Discussions/… tab bar plus the right-hand view toolbar. */
var TabHeader = exports.TabHeader = function TabHeader(_ref4) {
var _ref4$activeView = _ref4.activeView,
activeView = _ref4$activeView === void 0 ? "list" : _ref4$activeView;
var _useState21 = (0, _react.useState)(0),
_useState22 = _slicedToArray(_useState21, 2),
active = _useState22[0],
setActive = _useState22[1];
return /*#__PURE__*/_react.default.createElement(StyledTabHeader, null, /*#__PURE__*/_react.default.createElement(_Nav.Nav, {
onSelect: setActive
}, NAV_TABS.map(function (label, index) {
return /*#__PURE__*/_react.default.createElement(_Nav.Item, {
active: index === active,
key: label,
name: label
}, /*#__PURE__*/_react.default.createElement(_Typography.Body2, {
color: "secondary",
weight: "medium"
}, label));
})), /*#__PURE__*/_react.default.createElement(StyledTabControls, null, /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Batch Edit"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
variant: "text gray"
}, /*#__PURE__*/_react.default.createElement(_Icons.EditMultipleIcon, null))), /*#__PURE__*/_react.default.createElement("span", {
className: "vertical-separator"
}), /*#__PURE__*/_react.default.createElement(_Button.Button, {
variant: "text gray",
className: "filter-button"
}, /*#__PURE__*/_react.default.createElement(_Icons.FilterIcon, null), "Filter"), /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "List view"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
variant: "text gray",
active: activeView === "list"
}, /*#__PURE__*/_react.default.createElement(_Icons.ViewListIcon, null))), /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Column view"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
variant: "text gray",
active: activeView === "column"
}, /*#__PURE__*/_react.default.createElement(_Icons.ViewListIcon, {
style: {
transform: "rotate(90deg)"
}
}))), /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Timeline view"
}, /*#__PURE__*/_react.default.createElement(_IconButton.IconButton, {
variant: "text gray",
active: activeView === "timeline"
}, /*#__PURE__*/_react.default.createElement(_Icons.ViewTimelineIcon, null))), /*#__PURE__*/_react.default.createElement("span", {
className: "vertical-separator"
}), /*#__PURE__*/_react.default.createElement(_Tooltip.Tooltip, {
title: "Add New"
}, /*#__PURE__*/_react.default.createElement(_GlobalAddButton.GlobalAddButton, null))));
};
TabHeader.displayName = "TabHeader";
//# sourceMappingURL=headers.js.map