5709 lines
233 KiB
Plaintext
5709 lines
233 KiB
Plaintext
/* @ds-bundle: {"format":3,"namespace":"MONAFamilyDesignSystem_68e947","components":[{"name":"AppHeader","sourcePath":"uploads/MONA Family Design System-handoff/project/components/app/AppHeader.jsx"},{"name":"LoginScreen","sourcePath":"uploads/MONA Family Design System-handoff/project/components/app/LoginScreen.jsx"},{"name":"SortableHeader","sourcePath":"uploads/MONA Family Design System-handoff/project/components/data/SortableHeader.jsx"},{"name":"Table","sourcePath":"uploads/MONA Family Design System-handoff/project/components/data/Table.jsx"},{"name":"Badge","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/Badge.jsx"},{"name":"EmptyState","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/EmptyState.jsx"},{"name":"EnvChip","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/EnvChip.jsx"},{"name":"ErrorState","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/ErrorState.jsx"},{"name":"ProgressBar","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/ProgressBar.jsx"},{"name":"RoleBadge","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/RoleBadge.jsx"},{"name":"Skeleton","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/Skeleton.jsx"},{"name":"StatusGrid","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/StatusGrid.jsx"},{"name":"Timeline","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/Timeline.jsx"},{"name":"Toast","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/Toast.jsx"},{"name":"ToastStack","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/Toast.jsx"},{"name":"Tooltip","sourcePath":"uploads/MONA Family Design System-handoff/project/components/feedback/Tooltip.jsx"},{"name":"Button","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/Button.jsx"},{"name":"Checkbox","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/Checkbox.jsx"},{"name":"CodeBlock","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/CodeBlock.jsx"},{"name":"CopyButton","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/CopyButton.jsx"},{"name":"IconButton","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/IconButton.jsx"},{"name":"Input","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/Input.jsx"},{"name":"MaskedField","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/MaskedField.jsx"},{"name":"RadioGroup","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/RadioGroup.jsx"},{"name":"Select","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/Select.jsx"},{"name":"Switch","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/Switch.jsx"},{"name":"Textarea","sourcePath":"uploads/MONA Family Design System-handoff/project/components/forms/Textarea.jsx"},{"name":"Breadcrumb","sourcePath":"uploads/MONA Family Design System-handoff/project/components/navigation/Breadcrumb.jsx"},{"name":"Pagination","sourcePath":"uploads/MONA Family Design System-handoff/project/components/navigation/Pagination.jsx"},{"name":"ProjectSwitcher","sourcePath":"uploads/MONA Family Design System-handoff/project/components/navigation/ProjectSwitcher.jsx"},{"name":"Tabs","sourcePath":"uploads/MONA Family Design System-handoff/project/components/navigation/Tabs.jsx"},{"name":"Card","sourcePath":"uploads/MONA Family Design System-handoff/project/components/surfaces/Card.jsx"},{"name":"ConfirmDialog","sourcePath":"uploads/MONA Family Design System-handoff/project/components/surfaces/ConfirmDialog.jsx"},{"name":"EnvBanner","sourcePath":"uploads/MONA Family Design System-handoff/project/components/surfaces/EnvBanner.jsx"},{"name":"Modal","sourcePath":"uploads/MONA Family Design System-handoff/project/components/surfaces/Modal.jsx"},{"name":"StatCard","sourcePath":"uploads/MONA Family Design System-handoff/project/components/surfaces/StatCard.jsx"}],"sourceHashes":{"uploads/MONA Family Design System-handoff/project/components/app/AppHeader.jsx":"6c8b78bb90ad","uploads/MONA Family Design System-handoff/project/components/app/LoginScreen.jsx":"a7541d0392f9","uploads/MONA Family Design System-handoff/project/components/data/SortableHeader.jsx":"f20c60b6e463","uploads/MONA Family Design System-handoff/project/components/data/Table.jsx":"fee9157d5583","uploads/MONA Family Design System-handoff/project/components/feedback/Badge.jsx":"382c4271bc43","uploads/MONA Family Design System-handoff/project/components/feedback/EmptyState.jsx":"36a27b3bbcf8","uploads/MONA Family Design System-handoff/project/components/feedback/EnvChip.jsx":"f207c64207bb","uploads/MONA Family Design System-handoff/project/components/feedback/ErrorState.jsx":"c78f3e17cf38","uploads/MONA Family Design System-handoff/project/components/feedback/ProgressBar.jsx":"00e079f34588","uploads/MONA Family Design System-handoff/project/components/feedback/RoleBadge.jsx":"8f9681d47b2e","uploads/MONA Family Design System-handoff/project/components/feedback/Skeleton.jsx":"fa638ece5ae3","uploads/MONA Family Design System-handoff/project/components/feedback/StatusGrid.jsx":"eb9cf0eb4cf1","uploads/MONA Family Design System-handoff/project/components/feedback/Timeline.jsx":"8cfde353c927","uploads/MONA Family Design System-handoff/project/components/feedback/Toast.jsx":"a5bb2f7feb4a","uploads/MONA Family Design System-handoff/project/components/feedback/Tooltip.jsx":"01ccf23f0807","uploads/MONA Family Design System-handoff/project/components/forms/Button.jsx":"60ff89fa879e","uploads/MONA Family Design System-handoff/project/components/forms/Checkbox.jsx":"2d04cec07990","uploads/MONA Family Design System-handoff/project/components/forms/CodeBlock.jsx":"06c371b22a70","uploads/MONA Family Design System-handoff/project/components/forms/CopyButton.jsx":"ba2768cecca8","uploads/MONA Family Design System-handoff/project/components/forms/IconButton.jsx":"fa21bdcf5aa4","uploads/MONA Family Design System-handoff/project/components/forms/Input.jsx":"e64dba91df63","uploads/MONA Family Design System-handoff/project/components/forms/MaskedField.jsx":"3a26776a6624","uploads/MONA Family Design System-handoff/project/components/forms/RadioGroup.jsx":"740afb99b703","uploads/MONA Family Design System-handoff/project/components/forms/Select.jsx":"528c1fd12d0e","uploads/MONA Family Design System-handoff/project/components/forms/Switch.jsx":"2b661aca2724","uploads/MONA Family Design System-handoff/project/components/forms/Textarea.jsx":"3ba886bbe82f","uploads/MONA Family Design System-handoff/project/components/navigation/Breadcrumb.jsx":"b1ceb08ec25a","uploads/MONA Family Design System-handoff/project/components/navigation/Pagination.jsx":"2482587cd467","uploads/MONA Family Design System-handoff/project/components/navigation/ProjectSwitcher.jsx":"4f1728ea8203","uploads/MONA Family Design System-handoff/project/components/navigation/Tabs.jsx":"c9bec984a757","uploads/MONA Family Design System-handoff/project/components/surfaces/Card.jsx":"3bf56605d926","uploads/MONA Family Design System-handoff/project/components/surfaces/ConfirmDialog.jsx":"be0ad5ddd04e","uploads/MONA Family Design System-handoff/project/components/surfaces/EnvBanner.jsx":"859f4395cba8","uploads/MONA Family Design System-handoff/project/components/surfaces/Modal.jsx":"efb655cffed7","uploads/MONA Family Design System-handoff/project/components/surfaces/StatCard.jsx":"98c5eb626506","uploads/MONA Family Design System-handoff/project/components/util.js":"536a9fc1f4ed","uploads/MONA Family Design System-handoff/project/ui_kits/airsflow/screens.jsx":"797d96a25b88","uploads/MONA Family Design System-handoff/project/ui_kits/files/screens.jsx":"751cf24d37f9","uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-admin.jsx":"7a521bbc5e8b","uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-detail.jsx":"85056062aba9","uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-request-project.jsx":"8260e261f374","uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-requests.jsx":"18bfb186c971","uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens.jsx":"18d80e0f96cd"},"inlinedExternals":[],"unexposedExports":[{"name":"cx","sourcePath":"uploads/MONA Family Design System-handoff/project/components/util.js"},{"name":"injectStyle","sourcePath":"uploads/MONA Family Design System-handoff/project/components/util.js"}]} */
|
||
|
||
(() => {
|
||
|
||
const __ds_ns = (window.MONAFamilyDesignSystem_68e947 = window.MONAFamilyDesignSystem_68e947 || {});
|
||
|
||
const __ds_scope = {};
|
||
|
||
(__ds_ns.__errors = __ds_ns.__errors || []);
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/util.js
|
||
try { (() => {
|
||
// MONA Family — shared helpers for components.
|
||
// Not a component (lowercase, no .d.ts): a tiny runtime util that lets each
|
||
// component register its CSS once. Components stay styled by the family tokens
|
||
// (var(--…)) and get real :hover / :focus-visible / :disabled states that
|
||
// inline styles can't express.
|
||
|
||
const _injected = new Set();
|
||
function injectStyle(id, css) {
|
||
if (typeof document === 'undefined') return;
|
||
if (_injected.has(id)) return;
|
||
_injected.add(id);
|
||
const el = document.createElement('style');
|
||
el.setAttribute('data-mona', id);
|
||
el.textContent = css;
|
||
document.head.appendChild(el);
|
||
}
|
||
|
||
// clsx-lite: join truthy class names.
|
||
function cx(...parts) {
|
||
return parts.filter(Boolean).join(' ');
|
||
}
|
||
Object.assign(__ds_scope, { injectStyle, cx });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/util.js", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/data/SortableHeader.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-sortableheader', `
|
||
.mona-sorth { cursor: pointer; user-select: none; }
|
||
.mona-sorth__inner { display: inline-flex; align-items: center; gap: 5px; }
|
||
.mona-sorth:hover .mona-sorth__inner { color: var(--text-secondary); }
|
||
.mona-sorth--active .mona-sorth__inner { color: var(--color-primary); }
|
||
.mona-sorth__icon { display: flex; opacity: 0.5; }
|
||
.mona-sorth--active .mona-sorth__icon { opacity: 1; }
|
||
.mona-sorth--right .mona-sorth__inner { justify-content: flex-end; }
|
||
`);
|
||
const ICONS = {
|
||
asc: /*#__PURE__*/React.createElement("path", {
|
||
d: "m18 15-6-6-6 6"
|
||
}),
|
||
desc: /*#__PURE__*/React.createElement("path", {
|
||
d: "m6 9 6 6 6-6"
|
||
}),
|
||
none: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("path", {
|
||
d: "m7 15 5 5 5-5"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m7 9 5-5 5 5"
|
||
}))
|
||
};
|
||
|
||
/**
|
||
* SortableHeader — a <th> that cycles asc → desc → none on click and shows
|
||
* the matching arrow. Pair with Table.
|
||
*/
|
||
function SortableHeader({
|
||
label,
|
||
direction = 'none',
|
||
onSort,
|
||
align = 'left',
|
||
className,
|
||
...rest
|
||
}) {
|
||
const next = direction === 'none' ? 'asc' : direction === 'asc' ? 'desc' : 'none';
|
||
return /*#__PURE__*/React.createElement("th", _extends({
|
||
className: __ds_scope.cx('mona-sorth', direction !== 'none' && 'mona-sorth--active', align === 'right' && 'mona-sorth--right', className),
|
||
onClick: () => onSort && onSort(next),
|
||
"aria-sort": direction === 'asc' ? 'ascending' : direction === 'desc' ? 'descending' : 'none'
|
||
}, rest), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-sorth__inner"
|
||
}, label, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-sorth__icon",
|
||
"aria-hidden": "true"
|
||
}, /*#__PURE__*/React.createElement("svg", {
|
||
width: "13",
|
||
height: "13",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, ICONS[direction]))));
|
||
}
|
||
Object.assign(__ds_scope, { SortableHeader });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/data/SortableHeader.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/data/Table.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-table', `
|
||
.mona-table-wrap { width: 100%; overflow-x: auto; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); background: var(--surface-card); }
|
||
.mona-table { width: 100%; border-collapse: collapse; font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans); }
|
||
.mona-table thead th {
|
||
position: sticky; top: 0; z-index: var(--z-sticky);
|
||
text-align: left; font-weight: var(--font-semibold); font-size: var(--text-2xs);
|
||
text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-muted);
|
||
background: var(--surface-subtle); padding: 10px 14px; border-bottom: var(--border-width) solid var(--color-border); white-space: nowrap;
|
||
}
|
||
.mona-table tbody td { padding: 11px 14px; border-bottom: var(--border-width) solid var(--color-border); color: var(--text-body); vertical-align: middle; }
|
||
.mona-table tbody tr:last-child td { border-bottom: 0; }
|
||
.mona-table--hover tbody tr { transition: background-color var(--duration-fast) var(--ease); }
|
||
.mona-table--hover tbody tr:hover td { background: var(--surface-hover); }
|
||
.mona-table--zebra tbody tr:nth-child(even) td { background: var(--surface-subtle); }
|
||
`);
|
||
|
||
/**
|
||
* Table — styled wrapper around a native <table>. Provide <thead>/<tbody>
|
||
* (use SortableHeader for sortable columns). Sticky header, optional hover
|
||
* and zebra striping.
|
||
*/
|
||
function Table({
|
||
hover = true,
|
||
zebra = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-table-wrap"
|
||
}, /*#__PURE__*/React.createElement("table", _extends({
|
||
className: __ds_scope.cx('mona-table', hover && 'mona-table--hover', zebra && 'mona-table--zebra', className)
|
||
}, rest), children));
|
||
}
|
||
Object.assign(__ds_scope, { Table });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/data/Table.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/Badge.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-badge', `
|
||
.mona-badge {
|
||
display: inline-flex; align-items: center; gap: 5px;
|
||
font-family: var(--font-sans); font-weight: var(--font-semibold);
|
||
border: var(--border-width) solid transparent; white-space: nowrap;
|
||
}
|
||
.mona-badge--sm { font-size: var(--text-2xs); padding: 2px 7px; }
|
||
.mona-badge--md { font-size: var(--text-xs); padding: 3px 9px; }
|
||
.mona-badge--square { border-radius: var(--radius-sm); }
|
||
.mona-badge--pill { border-radius: var(--radius-pill); }
|
||
.mona-badge--upper { text-transform: uppercase; letter-spacing: var(--tracking-wide); }
|
||
.mona-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
||
|
||
.mona-badge--neutral { background: var(--surface-sunken); color: var(--text-secondary); border-color: var(--color-border); }
|
||
.mona-badge--primary { background: var(--color-primary-subtle); color: var(--color-primary); }
|
||
.mona-badge--success { background: var(--color-success-subtle); color: var(--color-success); }
|
||
.mona-badge--warning { background: var(--color-warning-subtle); color: var(--color-warning); }
|
||
.mona-badge--danger { background: var(--color-danger-subtle); color: var(--color-danger); }
|
||
.mona-badge--info { background: var(--color-info-subtle); color: var(--color-info); }
|
||
.mona-badge--purple { background: var(--color-role-platform-subtle); color: var(--color-role-platform); }
|
||
`);
|
||
|
||
/**
|
||
* Badge — compact status / category label. Maps onto the semantic palette
|
||
* (neutral / primary / success / warning / danger / info / purple).
|
||
*/
|
||
function Badge({
|
||
variant = 'neutral',
|
||
size = 'md',
|
||
shape = 'square',
|
||
uppercase = false,
|
||
dot = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("span", _extends({
|
||
className: __ds_scope.cx('mona-badge', `mona-badge--${variant}`, `mona-badge--${size}`, `mona-badge--${shape}`, uppercase && 'mona-badge--upper', className)
|
||
}, rest), dot && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-badge__dot"
|
||
}), children);
|
||
}
|
||
Object.assign(__ds_scope, { Badge });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/Badge.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/EmptyState.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-emptystate', `
|
||
.mona-empty { display: flex; flex-direction: column; align-items: center; text-align: center; }
|
||
.mona-empty--sm { padding: 24px 16px; gap: 8px; }
|
||
.mona-empty--md { padding: 40px 24px; gap: 10px; }
|
||
.mona-empty--lg { padding: 64px 24px; gap: 12px; }
|
||
.mona-empty__icon {
|
||
display: grid; place-items: center; color: var(--text-disabled);
|
||
background: var(--surface-sunken); border-radius: var(--radius-pill);
|
||
width: 56px; height: 56px; margin-bottom: 4px;
|
||
}
|
||
.mona-empty--sm .mona-empty__icon { width: 44px; height: 44px; }
|
||
.mona-empty__title { font: var(--font-semibold) var(--text-md)/1.4 var(--font-sans); color: var(--text-body); }
|
||
.mona-empty--sm .mona-empty__title { font-size: var(--text-sm); }
|
||
.mona-empty__desc { font: var(--font-regular) var(--text-sm)/1.5 var(--font-sans); color: var(--text-muted); max-width: 340px; }
|
||
.mona-empty__action { margin-top: 6px; }
|
||
`);
|
||
|
||
/**
|
||
* EmptyState — centered icon + title + description (+ optional action) for
|
||
* empty lists, no-results and zero-data screens. The unified family API
|
||
* (Files' text-only version is absorbed into this).
|
||
*/
|
||
function EmptyState({
|
||
icon = null,
|
||
title,
|
||
description,
|
||
action = null,
|
||
size = 'md',
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-empty', `mona-empty--${size}`, className)
|
||
}, rest), icon && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-empty__icon",
|
||
"aria-hidden": "true"
|
||
}, icon), title && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-empty__title"
|
||
}, title), description && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-empty__desc"
|
||
}, description), action && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-empty__action"
|
||
}, action));
|
||
}
|
||
Object.assign(__ds_scope, { EmptyState });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/EmptyState.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/EnvChip.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-envchip', `
|
||
.mona-envchip { display: inline-flex; align-items: center; gap: 6px; font: var(--font-semibold) var(--text-2xs)/1 var(--font-sans); padding: 4px 9px; border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
|
||
.mona-envchip__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
||
.mona-envchip--dev { background: var(--color-env-dev-subtle); color: var(--color-env-dev); }
|
||
.mona-envchip--stage { background: var(--color-env-stage-subtle); color: var(--color-env-stage); }
|
||
.mona-envchip--prod { background: var(--color-env-prod-subtle); color: var(--color-env-prod); }
|
||
.mona-envchip--plain { padding-left: 8px; }
|
||
`);
|
||
|
||
/**
|
||
* EnvChip — environment label (dev / stage / prod) rendered from the family
|
||
* `--color-env-*` tokens. Smaller, inline counterpart to the full-width EnvBanner.
|
||
*/
|
||
function EnvChip({
|
||
env = 'dev',
|
||
dot = true,
|
||
children,
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("span", _extends({
|
||
className: __ds_scope.cx('mona-envchip', `mona-envchip--${env}`, !dot && 'mona-envchip--plain', className)
|
||
}, rest), dot && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-envchip__dot"
|
||
}), children ?? env);
|
||
}
|
||
Object.assign(__ds_scope, { EnvChip });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/EnvChip.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/ErrorState.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-errorstate', `
|
||
.mona-err { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 56px 24px; gap: 12px; }
|
||
.mona-err__icon { display: grid; place-items: center; width: 60px; height: 60px; border-radius: var(--radius-pill); color: var(--color-danger); background: var(--color-danger-subtle); margin-bottom: 4px; }
|
||
.mona-err__icon--warning { color: var(--color-warning); background: var(--color-warning-subtle); }
|
||
.mona-err__icon--muted { color: var(--text-muted); background: var(--surface-sunken); }
|
||
.mona-err__code { font: var(--font-bold) var(--text-2xl)/1 var(--font-mono); color: var(--text-disabled); letter-spacing: var(--tracking-tight); }
|
||
.mona-err__title { font: var(--font-bold) var(--text-lg)/1.3 var(--font-sans); color: var(--text-body); }
|
||
.mona-err__msg { font: var(--font-regular) var(--text-sm)/1.6 var(--font-sans); color: var(--text-muted); max-width: 420px; }
|
||
.mona-err__detail { font: var(--font-regular) var(--text-xs)/1.6 var(--font-mono); color: var(--text-secondary); background: var(--surface-sunken); border-radius: var(--radius-md); padding: 10px 12px; max-width: 460px; overflow: auto; text-align: left; margin-top: 4px; }
|
||
.mona-err__actions { display: flex; gap: 10px; margin-top: 8px; }
|
||
`);
|
||
|
||
/**
|
||
* ErrorState — full-page / full-panel error surface, distinct from EmptyState.
|
||
* Use for ErrorBoundary fallbacks and proxy errors (401/404/502/504). Optional
|
||
* status `code`, monospace `detail` block and retry/refresh actions.
|
||
*/
|
||
function ErrorState({
|
||
icon = null,
|
||
code,
|
||
title,
|
||
message,
|
||
detail,
|
||
actions = null,
|
||
tone = 'danger',
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-err', className)
|
||
}, rest), icon && /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-err__icon', tone !== 'danger' && `mona-err__icon--${tone}`)
|
||
}, icon), code != null && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-err__code"
|
||
}, code), title && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-err__title"
|
||
}, title), message && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-err__msg"
|
||
}, message), detail && /*#__PURE__*/React.createElement("pre", {
|
||
className: "mona-err__detail"
|
||
}, detail), actions && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-err__actions"
|
||
}, actions));
|
||
}
|
||
Object.assign(__ds_scope, { ErrorState });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/ErrorState.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/ProgressBar.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-progress', `
|
||
.mona-prog { width: 100%; }
|
||
.mona-prog__top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 6px; }
|
||
.mona-prog__label { font: var(--font-medium) var(--text-xs)/1.3 var(--font-sans); color: var(--text-secondary); }
|
||
.mona-prog__value { font: var(--font-medium) var(--text-2xs)/1 var(--font-mono); color: var(--text-muted); }
|
||
.mona-prog__track { width: 100%; height: 8px; background: var(--surface-sunken); border-radius: var(--radius-pill); overflow: hidden; }
|
||
.mona-prog__track--sm { height: 5px; }
|
||
.mona-prog__track--lg { height: 12px; }
|
||
.mona-prog__fill { height: 100%; border-radius: var(--radius-pill); background: var(--color-primary); transition: width var(--duration) var(--ease), background-color var(--duration) var(--ease); }
|
||
.mona-prog__fill--success { background: var(--color-success); }
|
||
.mona-prog__fill--warning { background: var(--color-warning); }
|
||
.mona-prog__fill--danger { background: var(--color-danger); }
|
||
.mona-prog__fill--indeterminate { width: 40% !important; animation: mona-loading-bar 1.4s var(--ease) infinite; }
|
||
`);
|
||
|
||
/**
|
||
* ProgressBar / Meter — track + fill for quota usage, cluster utilization and
|
||
* upload progress. Pass `threshold` to auto-color (>=90% danger, >=70% warning),
|
||
* or set `variant` explicitly. `indeterminate` for unknown-duration loading.
|
||
*/
|
||
function ProgressBar({
|
||
value = 0,
|
||
max = 100,
|
||
variant,
|
||
threshold = false,
|
||
indeterminate = false,
|
||
size = 'md',
|
||
label,
|
||
valueText,
|
||
showValue = false,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const pct = max > 0 ? Math.min(100, Math.max(0, value / max * 100)) : 0;
|
||
let v = variant || 'primary';
|
||
if (threshold && !variant) v = pct >= 90 ? 'danger' : pct >= 70 ? 'warning' : 'primary';
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-prog', className)
|
||
}, rest), (label || showValue || valueText) && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-prog__top"
|
||
}, label && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-prog__label"
|
||
}, label), (valueText || showValue) && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-prog__value"
|
||
}, valueText ?? `${Math.round(pct)}%`)), /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-prog__track', `mona-prog__track--${size}`),
|
||
role: "progressbar",
|
||
"aria-valuenow": indeterminate ? undefined : Math.round(pct),
|
||
"aria-valuemin": 0,
|
||
"aria-valuemax": 100
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-prog__fill', `mona-prog__fill--${v}`, indeterminate && 'mona-prog__fill--indeterminate'),
|
||
style: indeterminate ? undefined : {
|
||
width: `${pct}%`
|
||
}
|
||
})));
|
||
}
|
||
Object.assign(__ds_scope, { ProgressBar });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/ProgressBar.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/RoleBadge.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-rolebadge', `
|
||
.mona-role {
|
||
display: inline-flex; align-items: center;
|
||
font-family: var(--font-sans); font-weight: var(--font-semibold);
|
||
font-size: var(--text-2xs); line-height: 1;
|
||
text-transform: uppercase; letter-spacing: var(--tracking-wide);
|
||
padding: 4px 9px; border-radius: var(--radius-pill);
|
||
border: var(--border-width) solid transparent;
|
||
}
|
||
.mona-role--admin { background: var(--color-role-admin-subtle); color: var(--color-role-admin); }
|
||
.mona-role--developer { background: var(--color-role-developer-subtle); color: var(--color-role-developer); }
|
||
.mona-role--viewer { background: var(--color-role-viewer-subtle); color: var(--color-role-viewer); }
|
||
.mona-role--platform { background: var(--color-role-platform-subtle); color: var(--color-role-platform); }
|
||
`);
|
||
const LABELS = {
|
||
admin: 'admin',
|
||
developer: 'developer',
|
||
viewer: 'viewer'
|
||
};
|
||
|
||
/**
|
||
* RoleBadge — the unified family role chip. Resolves the old per-site
|
||
* mismatch (Pass admin=red, AiRSFlow admin=amber) into ONE standard:
|
||
* admin=amber, developer=blue, viewer=slate. Global platform-* roles use
|
||
* purple and a "P-" prefix.
|
||
*/
|
||
function RoleBadge({
|
||
role = 'viewer',
|
||
isPlatform = false,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const variant = isPlatform ? 'platform' : role;
|
||
const label = (isPlatform ? 'P-' : '') + (LABELS[role] || role);
|
||
return /*#__PURE__*/React.createElement("span", _extends({
|
||
className: __ds_scope.cx('mona-role', `mona-role--${variant}`, className)
|
||
}, rest), label);
|
||
}
|
||
Object.assign(__ds_scope, { RoleBadge });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/RoleBadge.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/Skeleton.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-skeleton', `
|
||
.mona-skel { display: block; background: var(--surface-sunken); border-radius: var(--radius-sm); position: relative; overflow: hidden; }
|
||
.mona-skel::after {
|
||
content: ''; position: absolute; inset: 0;
|
||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.45), transparent);
|
||
transform: translateX(-100%); animation: mona-loading-bar 1.4s var(--ease) infinite;
|
||
}
|
||
.dark .mona-skel::after { background: linear-gradient(90deg, transparent, rgba(255,255,255,0.06), transparent); }
|
||
.mona-skel--text { height: 0.75em; border-radius: var(--radius-pill); margin: 0.25em 0; }
|
||
.mona-skel--circle { border-radius: 50%; }
|
||
`);
|
||
|
||
/**
|
||
* Skeleton — animated loading placeholder. Compose blocks to mirror the
|
||
* shape of content while it loads (Files had no loader — this fills the gap).
|
||
*/
|
||
function Skeleton({
|
||
width,
|
||
height,
|
||
variant = 'block',
|
||
radius,
|
||
className,
|
||
style,
|
||
...rest
|
||
}) {
|
||
const s = {
|
||
...style
|
||
};
|
||
if (width != null) s.width = typeof width === 'number' ? `${width}px` : width;
|
||
if (height != null) s.height = typeof height === 'number' ? `${height}px` : height;
|
||
if (radius != null) s.borderRadius = typeof radius === 'number' ? `${radius}px` : radius;
|
||
return /*#__PURE__*/React.createElement("span", _extends({
|
||
className: __ds_scope.cx('mona-skel', variant !== 'block' && `mona-skel--${variant}`, className),
|
||
style: s
|
||
}, rest));
|
||
}
|
||
Object.assign(__ds_scope, { Skeleton });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/Skeleton.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/StatusGrid.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-statusgrid', `
|
||
.mona-sg { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
|
||
.mona-sg__cell { display: flex; align-items: center; gap: 9px; padding: 11px 13px; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-md); background: var(--surface-card); }
|
||
.mona-sg__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
|
||
.mona-sg__name { font: var(--font-medium) var(--text-sm)/1.2 var(--font-sans); color: var(--text-body); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.mona-sg__status { font: var(--font-medium) var(--text-2xs)/1 var(--font-sans); color: var(--text-muted); }
|
||
/* ok */
|
||
.mona-sg__cell--ok { border-color: var(--color-success-subtle); background: var(--color-success-subtle); }
|
||
.mona-sg__cell--ok .mona-sg__dot { background: var(--color-success); }
|
||
.mona-sg__cell--ok .mona-sg__status { color: var(--color-success); }
|
||
/* error */
|
||
.mona-sg__cell--error { border-color: var(--color-danger-subtle); background: var(--color-danger-subtle); }
|
||
.mona-sg__cell--error .mona-sg__dot { background: var(--color-danger); }
|
||
.mona-sg__cell--error .mona-sg__status { color: var(--color-danger); }
|
||
/* pending */
|
||
.mona-sg__cell--pending .mona-sg__dot { background: var(--color-warning); }
|
||
.mona-sg__cell--pending .mona-sg__status { color: var(--color-warning); }
|
||
/* off / disabled */
|
||
.mona-sg__cell--off { opacity: 0.6; }
|
||
.mona-sg__cell--off .mona-sg__dot { background: var(--text-disabled); }
|
||
`);
|
||
const LABELS = {
|
||
ok: '정상',
|
||
error: '오류',
|
||
pending: '대기',
|
||
off: '비활성'
|
||
};
|
||
|
||
/**
|
||
* StatusGrid — compact grid of integration/service health cells (Namespace,
|
||
* Keycloak, ArgoCD, Grafana, S3, MLflow…). Each item: {name, status} where
|
||
* status is ok / error / pending / off. Optional per-item statusLabel override.
|
||
*/
|
||
function StatusGrid({
|
||
items = [],
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-sg', className)
|
||
}, rest), items.map(it => {
|
||
const s = it.status || 'ok';
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-sg__cell', `mona-sg__cell--${s}`),
|
||
key: it.name
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-sg__dot"
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-sg__name"
|
||
}, it.name), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-sg__status"
|
||
}, it.statusLabel ?? LABELS[s]));
|
||
}));
|
||
}
|
||
Object.assign(__ds_scope, { StatusGrid });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/StatusGrid.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/Timeline.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-timeline', `
|
||
.mona-tl { display: flex; flex-direction: column; }
|
||
.mona-tl__item { display: grid; grid-template-columns: 18px 1fr; gap: 12px; }
|
||
.mona-tl__rail { display: flex; flex-direction: column; align-items: center; }
|
||
.mona-tl__dot { width: 11px; height: 11px; border-radius: 50%; margin-top: 3px; flex: none; background: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-subtle); }
|
||
.mona-tl__dot--success { background: var(--color-success); box-shadow: 0 0 0 3px var(--color-success-subtle); }
|
||
.mona-tl__dot--warning { background: var(--color-warning); box-shadow: 0 0 0 3px var(--color-warning-subtle); }
|
||
.mona-tl__dot--danger { background: var(--color-danger); box-shadow: 0 0 0 3px var(--color-danger-subtle); }
|
||
.mona-tl__dot--muted { background: var(--text-disabled); box-shadow: 0 0 0 3px var(--surface-sunken); }
|
||
.mona-tl__line { flex: 1; width: 2px; background: var(--color-border); margin: 4px 0; min-height: 8px; }
|
||
.mona-tl__body { padding-bottom: 18px; }
|
||
.mona-tl__item:last-child .mona-tl__body { padding-bottom: 0; }
|
||
.mona-tl__title { font: var(--font-medium) var(--text-sm)/1.4 var(--font-sans); color: var(--text-body); }
|
||
.mona-tl__meta { font: var(--font-regular) var(--text-xs)/1.4 var(--font-sans); color: var(--text-muted); margin-top: 2px; }
|
||
.mona-tl__desc { font: var(--font-regular) var(--text-sm)/1.5 var(--font-sans); color: var(--text-secondary); margin-top: 4px; }
|
||
`);
|
||
|
||
/**
|
||
* Timeline — vertical event trail for request history and project activity
|
||
* logs. Each item has a status dot (primary/success/warning/danger/muted),
|
||
* a title, optional meta line and description.
|
||
*/
|
||
function Timeline({
|
||
items = [],
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-tl', className)
|
||
}, rest), items.map((it, i) => {
|
||
const last = i === items.length - 1;
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-tl__item",
|
||
key: i
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-tl__rail"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: __ds_scope.cx('mona-tl__dot', it.status && `mona-tl__dot--${it.status}`)
|
||
}), !last && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-tl__line"
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-tl__body"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-tl__title"
|
||
}, it.title), it.meta && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-tl__meta"
|
||
}, it.meta), it.description && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-tl__desc"
|
||
}, it.description)));
|
||
}));
|
||
}
|
||
Object.assign(__ds_scope, { Timeline });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/Timeline.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/Toast.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-toast', `
|
||
.mona-toast {
|
||
display: flex; align-items: flex-start; gap: 11px;
|
||
width: 360px; max-width: calc(100vw - 32px);
|
||
background: var(--surface-card); border: var(--border-width) solid var(--color-border);
|
||
border-radius: var(--radius-lg); box-shadow: var(--shadow-xl);
|
||
padding: 13px 14px; animation: mona-fade-in var(--duration) var(--ease-out);
|
||
}
|
||
.mona-toast__icon { flex: none; margin-top: 1px; display: flex; }
|
||
.mona-toast__body { flex: 1; min-width: 0; }
|
||
.mona-toast__title { font: var(--font-semibold) var(--text-sm)/1.4 var(--font-sans); color: var(--text-body); }
|
||
.mona-toast__msg { font: var(--font-regular) var(--text-xs)/1.5 var(--font-sans); color: var(--text-secondary); margin-top: 2px; word-break: break-word; }
|
||
.mona-toast__close { flex: none; border: 0; background: transparent; cursor: pointer; color: var(--text-muted); border-radius: var(--radius-sm); padding: 2px; display: flex; }
|
||
.mona-toast__close:hover { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-toast--success .mona-toast__icon { color: var(--color-success); }
|
||
.mona-toast--error .mona-toast__icon { color: var(--color-danger); }
|
||
.mona-toast--warning .mona-toast__icon { color: var(--color-warning); }
|
||
.mona-toast--info .mona-toast__icon { color: var(--color-info); }
|
||
.mona-toaststack { position: fixed; bottom: 20px; right: 20px; display: flex; flex-direction: column; gap: 10px; z-index: var(--z-toast); }
|
||
`);
|
||
const ICONS = {
|
||
success: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("path", {
|
||
d: "M21.801 10A10 10 0 1 1 17 3.335"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m9 11 3 3L22 4"
|
||
})),
|
||
error: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("circle", {
|
||
cx: "12",
|
||
cy: "12",
|
||
r: "10"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m15 9-6 6"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m9 9 6 6"
|
||
})),
|
||
warning: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("path", {
|
||
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 9v4"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 17h.01"
|
||
})),
|
||
info: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("circle", {
|
||
cx: "12",
|
||
cy: "12",
|
||
r: "10"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 16v-4"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 8h.01"
|
||
}))
|
||
};
|
||
const TITLES = {
|
||
success: '완료',
|
||
error: '오류',
|
||
warning: '경고',
|
||
info: '알림'
|
||
};
|
||
|
||
/**
|
||
* Toast — a single transient notification. Render inside <ToastStack>.
|
||
* Four variants: success / error / warning / info.
|
||
*/
|
||
function Toast({
|
||
variant = 'info',
|
||
title,
|
||
message,
|
||
onClose,
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-toast', `mona-toast--${variant}`, className),
|
||
role: "status"
|
||
}, rest), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-toast__icon",
|
||
"aria-hidden": "true"
|
||
}, /*#__PURE__*/React.createElement("svg", {
|
||
width: "18",
|
||
height: "18",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, ICONS[variant])), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-toast__body"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-toast__title"
|
||
}, title ?? TITLES[variant]), message && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-toast__msg"
|
||
}, message)), onClose && /*#__PURE__*/React.createElement("button", {
|
||
className: "mona-toast__close",
|
||
"aria-label": "\uB2EB\uAE30",
|
||
onClick: onClose
|
||
}, /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M18 6 6 18"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m6 6 12 12"
|
||
}))));
|
||
}
|
||
|
||
/** ToastStack — fixed bottom-right container for stacked toasts. */
|
||
function ToastStack({
|
||
children,
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-toaststack', className)
|
||
}, rest), children);
|
||
}
|
||
Object.assign(__ds_scope, { Toast, ToastStack });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/Toast.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/feedback/Tooltip.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-tooltip', `
|
||
.mona-tip { position: relative; display: inline-flex; }
|
||
.mona-tip__pop {
|
||
position: absolute; z-index: var(--z-dropdown); pointer-events: none;
|
||
background: var(--zinc-900); color: var(--zinc-50);
|
||
font: var(--font-medium) var(--text-xs)/1.3 var(--font-sans);
|
||
padding: 6px 9px; border-radius: var(--radius-sm); white-space: nowrap;
|
||
box-shadow: var(--shadow-lg);
|
||
opacity: 0; transform: translateY(2px); transition: opacity var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
|
||
}
|
||
.dark .mona-tip__pop { background: var(--zinc-100); color: var(--zinc-900); }
|
||
.mona-tip:hover .mona-tip__pop, .mona-tip:focus-within .mona-tip__pop { opacity: 1; transform: translateY(0); }
|
||
.mona-tip__pop--top { bottom: calc(100% + 7px); left: 50%; translate: -50% 0; }
|
||
.mona-tip__pop--bottom { top: calc(100% + 7px); left: 50%; translate: -50% 0; }
|
||
.mona-tip__pop--left { right: calc(100% + 7px); top: 50%; translate: 0 -50%; }
|
||
.mona-tip__pop--right { left: calc(100% + 7px); top: 50%; translate: 0 -50%; }
|
||
`);
|
||
|
||
/**
|
||
* Tooltip — lightweight hover/focus label. Wraps a single interactive child;
|
||
* CSS-only, no portal. For rich help content use a popover instead.
|
||
*/
|
||
function Tooltip({
|
||
label,
|
||
side = 'top',
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("span", _extends({
|
||
className: __ds_scope.cx('mona-tip', className)
|
||
}, rest), children, /*#__PURE__*/React.createElement("span", {
|
||
className: `mona-tip__pop mona-tip__pop--${side}`,
|
||
role: "tooltip"
|
||
}, label));
|
||
}
|
||
Object.assign(__ds_scope, { Tooltip });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/feedback/Tooltip.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/Button.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-button', `
|
||
.mona-btn {
|
||
display: inline-flex; align-items: center; justify-content: center; gap: 7px;
|
||
font-family: var(--font-sans); font-weight: var(--font-semibold);
|
||
border: var(--border-width) solid transparent; border-radius: var(--radius-md);
|
||
cursor: pointer; white-space: nowrap; text-decoration: none;
|
||
transition: background-color var(--duration-fast) var(--ease),
|
||
border-color var(--duration-fast) var(--ease),
|
||
color var(--duration-fast) var(--ease),
|
||
box-shadow var(--duration-fast) var(--ease),
|
||
transform var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
||
.mona-btn:active:not(:disabled) { transform: scale(0.97); }
|
||
.mona-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||
.mona-btn--pill { border-radius: var(--radius-pill); }
|
||
.mona-btn--block { width: 100%; }
|
||
|
||
/* sizes */
|
||
.mona-btn--sm { font-size: var(--text-xs); padding: 0 12px; height: 30px; }
|
||
.mona-btn--md { font-size: var(--text-sm); padding: 0 16px; height: 38px; }
|
||
.mona-btn--lg { font-size: var(--text-base); padding: 0 22px; height: 46px; }
|
||
|
||
/* variants */
|
||
.mona-btn--primary { background: var(--color-primary); color: var(--color-on-primary, var(--text-on-primary)); box-shadow: var(--shadow-sm); }
|
||
.mona-btn--primary:hover:not(:disabled) { background: var(--color-primary-hover); }
|
||
.mona-btn--primary:active:not(:disabled) { background: var(--color-primary-active); }
|
||
|
||
.mona-btn--secondary { background: var(--surface-card); color: var(--text-body); border-color: var(--color-border-strong); }
|
||
.mona-btn--secondary:hover:not(:disabled) { background: var(--surface-hover); }
|
||
|
||
.mona-btn--ghost { background: transparent; color: var(--text-secondary); }
|
||
.mona-btn--ghost:hover:not(:disabled) { background: var(--surface-hover); color: var(--text-body); }
|
||
|
||
.mona-btn--danger { background: var(--color-danger); color: #fff; }
|
||
.mona-btn--danger:hover:not(:disabled) { filter: brightness(1.06); }
|
||
|
||
.mona-btn--danger-outline { background: var(--surface-card); color: var(--color-danger); border-color: var(--color-border-strong); }
|
||
.mona-btn--danger-outline:hover:not(:disabled) { background: var(--color-danger-subtle); border-color: var(--color-danger); }
|
||
`);
|
||
|
||
/**
|
||
* Button — the family's primary action control.
|
||
* 8px radius by default (set `pill` for the rounded variant).
|
||
*/
|
||
function Button({
|
||
variant = 'primary',
|
||
size = 'md',
|
||
pill = false,
|
||
block = false,
|
||
leadingIcon = null,
|
||
trailingIcon = null,
|
||
as = 'button',
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
const Tag = as;
|
||
return /*#__PURE__*/React.createElement(Tag, _extends({
|
||
className: __ds_scope.cx('mona-btn', `mona-btn--${variant}`, `mona-btn--${size}`, pill && 'mona-btn--pill', block && 'mona-btn--block', className)
|
||
}, rest), leadingIcon, children, trailingIcon);
|
||
}
|
||
Object.assign(__ds_scope, { Button });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/Button.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/app/LoginScreen.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-login', `
|
||
.mona-login {
|
||
min-height: 100%; display: grid; place-items: center; padding: 32px;
|
||
background:
|
||
radial-gradient(120% 90% at 0% 0%, var(--color-primary-subtle), transparent 55%),
|
||
radial-gradient(120% 90% at 100% 100%, var(--color-primary-subtle), transparent 55%),
|
||
var(--color-bg);
|
||
}
|
||
.mona-login__card {
|
||
width: 100%; max-width: 400px; background: var(--surface-card);
|
||
border: var(--border-width) solid var(--color-border); border-radius: var(--radius-xl);
|
||
box-shadow: var(--shadow-xl); padding: 32px 30px;
|
||
}
|
||
.mona-login__logo { width: 52px; height: 52px; border-radius: var(--radius-lg); display: block; margin-bottom: 18px; }
|
||
.mona-login__wordmark { font: var(--font-bold) var(--text-xl)/1 var(--font-sans); letter-spacing: var(--tracking-tight); color: var(--text-body); margin-bottom: 20px; }
|
||
.mona-login__wordmark b { color: var(--color-primary); font-weight: var(--font-bold); }
|
||
.mona-login__title { font: var(--font-bold) var(--text-2xl)/1.25 var(--font-sans); color: var(--text-body); letter-spacing: var(--tracking-tight); }
|
||
.mona-login__subtitle { font: var(--font-regular) var(--text-sm)/1.6 var(--font-sans); color: var(--text-secondary); margin-top: 8px; }
|
||
.mona-login__action { margin-top: 22px; }
|
||
.mona-login__note { font: var(--font-regular) var(--text-xs)/1.6 var(--font-sans); color: var(--text-muted); margin-top: 16px; text-align: center; }
|
||
.mona-login__note a { color: var(--color-primary); }
|
||
`);
|
||
const ArrowRight = /*#__PURE__*/React.createElement("svg", {
|
||
width: "17",
|
||
height: "17",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M5 12h14"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m12 5 7 7-7 7"
|
||
}));
|
||
|
||
/**
|
||
* LoginScreen — the shared SSO entry card (all sites use the same Keycloak).
|
||
* Centered card with logo, wordmark, headline, sub-copy and one SSO button.
|
||
*/
|
||
function LoginScreen({
|
||
logo,
|
||
product,
|
||
title,
|
||
subtitle,
|
||
buttonLabel = 'SSO 로그인',
|
||
onLogin,
|
||
note,
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-login', className)
|
||
}, rest), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-login__card"
|
||
}, logo && /*#__PURE__*/React.createElement("img", {
|
||
className: "mona-login__logo",
|
||
src: logo,
|
||
alt: ""
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-login__wordmark"
|
||
}, "MONA", /*#__PURE__*/React.createElement("b", null, " ", product)), /*#__PURE__*/React.createElement("h1", {
|
||
className: "mona-login__title"
|
||
}, title), subtitle && /*#__PURE__*/React.createElement("p", {
|
||
className: "mona-login__subtitle"
|
||
}, subtitle), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-login__action"
|
||
}, /*#__PURE__*/React.createElement(__ds_scope.Button, {
|
||
block: true,
|
||
size: "lg",
|
||
onClick: onLogin,
|
||
trailingIcon: ArrowRight
|
||
}, buttonLabel)), note && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-login__note"
|
||
}, note)));
|
||
}
|
||
Object.assign(__ds_scope, { LoginScreen });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/app/LoginScreen.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/Checkbox.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-checkbox', `
|
||
.mona-check { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans); color: var(--text-body); user-select: none; }
|
||
.mona-check input { position: absolute; opacity: 0; width: 0; height: 0; }
|
||
.mona-check__box {
|
||
width: 18px; height: 18px; flex: none; border-radius: 5px;
|
||
border: 1.5px solid var(--color-border-strong); background: var(--surface-card);
|
||
display: grid; place-items: center; color: #fff;
|
||
transition: background-color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-check__box svg { opacity: 0; transform: scale(0.6); transition: opacity var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease); }
|
||
.mona-check input:checked + .mona-check__box { background: var(--color-primary); border-color: var(--color-primary); }
|
||
.mona-check input:checked + .mona-check__box svg { opacity: 1; transform: scale(1); }
|
||
.mona-check input:indeterminate + .mona-check__box { background: var(--color-primary); border-color: var(--color-primary); }
|
||
.mona-check input:focus-visible + .mona-check__box { box-shadow: var(--focus-ring); }
|
||
.mona-check input:disabled ~ * { opacity: 0.5; }
|
||
.mona-check--disabled { cursor: not-allowed; }
|
||
`);
|
||
|
||
/**
|
||
* Checkbox — boolean toggle with an animated check. Renders a label when
|
||
* `children` are provided. Supports the indeterminate state.
|
||
*/
|
||
function Checkbox({
|
||
indeterminate = false,
|
||
disabled = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
const ref = React.useRef(null);
|
||
React.useEffect(() => {
|
||
if (ref.current) ref.current.indeterminate = indeterminate;
|
||
}, [indeterminate]);
|
||
return /*#__PURE__*/React.createElement("label", {
|
||
className: __ds_scope.cx('mona-check', disabled && 'mona-check--disabled', className)
|
||
}, /*#__PURE__*/React.createElement("input", _extends({
|
||
ref: ref,
|
||
type: "checkbox",
|
||
disabled: disabled
|
||
}, rest)), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-check__box",
|
||
"aria-hidden": "true"
|
||
}, /*#__PURE__*/React.createElement("svg", {
|
||
width: "12",
|
||
height: "12",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "3.5",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M20 6 9 17l-5-5"
|
||
}))), children && /*#__PURE__*/React.createElement("span", null, children));
|
||
}
|
||
Object.assign(__ds_scope, { Checkbox });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/Checkbox.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/CopyButton.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-copybtn', `
|
||
.mona-copy { display: inline-flex; align-items: center; gap: 6px; font: var(--font-medium) var(--text-xs)/1 var(--font-sans); color: var(--text-secondary); background: transparent; border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-sm); padding: 5px 9px; cursor: pointer; transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease); }
|
||
.mona-copy:hover { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-copy.is-copied { color: var(--color-success); border-color: var(--color-success); }
|
||
.mona-copy--on-dark { color: #d4d4d8; border-color: rgba(255,255,255,0.18); }
|
||
.mona-copy--on-dark:hover { background: rgba(255,255,255,0.08); color: #fff; }
|
||
.mona-copy svg { display: block; }
|
||
`);
|
||
const COPY = /*#__PURE__*/React.createElement("svg", {
|
||
width: "14",
|
||
height: "14",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("rect", {
|
||
width: "14",
|
||
height: "14",
|
||
x: "8",
|
||
y: "8",
|
||
rx: "2",
|
||
ry: "2"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
|
||
}));
|
||
const CHECK = /*#__PURE__*/React.createElement("svg", {
|
||
width: "14",
|
||
height: "14",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2.4",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M20 6 9 17l-5-5"
|
||
}));
|
||
|
||
/**
|
||
* CopyButton — copies `value` to the clipboard and flips to a check for ~1.5s.
|
||
* Use `onDark` inside dark code blocks.
|
||
*/
|
||
function CopyButton({
|
||
value,
|
||
label = '복사',
|
||
copiedLabel = '복사됨',
|
||
onDark = false,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const [copied, setCopied] = React.useState(false);
|
||
const copy = () => {
|
||
try {
|
||
navigator.clipboard && navigator.clipboard.writeText(String(value));
|
||
} catch (e) {/* noop */}
|
||
setCopied(true);
|
||
setTimeout(() => setCopied(false), 1500);
|
||
};
|
||
return /*#__PURE__*/React.createElement("button", _extends({
|
||
type: "button",
|
||
className: __ds_scope.cx('mona-copy', onDark && 'mona-copy--on-dark', copied && 'is-copied', className),
|
||
onClick: copy
|
||
}, rest), copied ? CHECK : COPY, copied ? copiedLabel : label);
|
||
}
|
||
Object.assign(__ds_scope, { CopyButton });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/CopyButton.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/CodeBlock.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-codeblock', `
|
||
.mona-code { background: var(--zinc-900); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; }
|
||
.dark .mona-code { background: #0c0c0e; }
|
||
.mona-code__bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 12px; border-bottom: 1px solid rgba(255,255,255,0.08); }
|
||
.mona-code__title { font: var(--font-medium) var(--text-2xs)/1 var(--font-mono); color: #a1a1aa; text-transform: uppercase; letter-spacing: var(--tracking-wide); }
|
||
.mona-code__pre { margin: 0; padding: 13px 14px; overflow: auto; font: var(--font-regular) var(--text-xs)/1.7 var(--font-mono); color: #e4e4e7; }
|
||
.mona-code__pre .g { color: #4ade80; }
|
||
.mona-code__pre .b { color: #60a5fa; }
|
||
.mona-code__pre .c { color: #71717a; }
|
||
`);
|
||
|
||
/**
|
||
* CodeBlock — dark monospace block for CLI snippets (kubectl, AWS CLI) and
|
||
* config, with an optional title bar and copy button. Pass plain text as
|
||
* children, or pre-highlighted nodes.
|
||
*/
|
||
function CodeBlock({
|
||
title,
|
||
copy = true,
|
||
copyValue,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
const text = copyValue != null ? copyValue : typeof children === 'string' ? children : '';
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-code', className)
|
||
}, rest), (title || copy) && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-code__bar"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-code__title"
|
||
}, title), copy && /*#__PURE__*/React.createElement(__ds_scope.CopyButton, {
|
||
value: text,
|
||
onDark: true
|
||
})), /*#__PURE__*/React.createElement("pre", {
|
||
className: "mona-code__pre"
|
||
}, children));
|
||
}
|
||
Object.assign(__ds_scope, { CodeBlock });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/CodeBlock.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/IconButton.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-iconbutton', `
|
||
.mona-iconbtn {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
border: var(--border-width) solid transparent; border-radius: var(--radius-md);
|
||
cursor: pointer; color: var(--text-secondary); background: transparent;
|
||
transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-iconbtn svg { display: block; }
|
||
.mona-iconbtn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
||
.mona-iconbtn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||
.mona-iconbtn--round { border-radius: var(--radius-pill); }
|
||
|
||
.mona-iconbtn--sm { width: 28px; height: 28px; }
|
||
.mona-iconbtn--md { width: 34px; height: 34px; }
|
||
.mona-iconbtn--lg { width: 40px; height: 40px; }
|
||
|
||
.mona-iconbtn--ghost:hover:not(:disabled) { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-iconbtn--secondary { background: var(--surface-card); border-color: var(--color-border); color: var(--text-secondary); }
|
||
.mona-iconbtn--secondary:hover:not(:disabled) { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-iconbtn--primary { background: var(--color-primary); color: #fff; }
|
||
.mona-iconbtn--primary:hover:not(:disabled) { background: var(--color-primary-hover); }
|
||
.mona-iconbtn--danger:hover:not(:disabled) { background: var(--color-danger-subtle); color: var(--color-danger); }
|
||
`);
|
||
|
||
/**
|
||
* IconButton — square/round button for a single icon (toolbar actions,
|
||
* theme toggle, close buttons). Always pass an accessible `aria-label`.
|
||
*/
|
||
function IconButton({
|
||
variant = 'ghost',
|
||
size = 'md',
|
||
round = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("button", _extends({
|
||
type: "button",
|
||
className: __ds_scope.cx('mona-iconbtn', `mona-iconbtn--${variant}`, `mona-iconbtn--${size}`, round && 'mona-iconbtn--round', className)
|
||
}, rest), children);
|
||
}
|
||
Object.assign(__ds_scope, { IconButton });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/IconButton.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/app/AppHeader.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-appheader', `
|
||
.mona-header {
|
||
display: flex; align-items: center; gap: 16px; height: var(--header-height);
|
||
padding: 0 var(--container-pad); background: var(--surface-card);
|
||
border-bottom: var(--border-width) solid var(--color-border);
|
||
}
|
||
.mona-header__brand { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; flex: none; }
|
||
.mona-header__logo { width: 30px; height: 30px; border-radius: var(--radius-md); display: block; }
|
||
.mona-header__wordmark { font: var(--font-bold) var(--text-md)/1 var(--font-sans); letter-spacing: var(--tracking-tight); color: var(--text-body); white-space: nowrap; }
|
||
.mona-header__wordmark b { color: var(--color-primary); font-weight: var(--font-bold); }
|
||
.mona-header__nav { display: flex; align-items: center; gap: 2px; }
|
||
.mona-header__navlink {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
font: var(--font-medium) var(--text-sm)/1 var(--font-sans); color: var(--text-secondary);
|
||
padding: 8px 11px; border-radius: var(--radius-md); cursor: pointer; text-decoration: none;
|
||
transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-header__navlink:hover { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-header__navlink--active { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-header__spacer { flex: 1; }
|
||
.mona-header__right { display: flex; align-items: center; gap: 8px; }
|
||
.mona-header__divider { width: 1px; height: 22px; background: var(--color-border); margin: 0 2px; }
|
||
.mona-header__avatar {
|
||
width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
|
||
font: var(--font-semibold) var(--text-xs)/1 var(--font-sans); color: #fff;
|
||
background: linear-gradient(135deg, var(--color-primary), var(--color-role-platform)); cursor: pointer;
|
||
}
|
||
`);
|
||
const Sun = /*#__PURE__*/React.createElement("svg", {
|
||
width: "18",
|
||
height: "18",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("circle", {
|
||
cx: "12",
|
||
cy: "12",
|
||
r: "4"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"
|
||
}));
|
||
const Moon = /*#__PURE__*/React.createElement("svg", {
|
||
width: "18",
|
||
height: "18",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"
|
||
}));
|
||
function initials(name) {
|
||
if (!name) return '·';
|
||
const t = name.trim();
|
||
return t.length <= 2 ? t : t.slice(0, 2);
|
||
}
|
||
|
||
/**
|
||
* AppHeader — the shared family top bar. Logo + wordmark, nav links, a free
|
||
* `center` slot (e.g. ProjectSwitcher for Files), theme toggle, custom right
|
||
* actions and an avatar. One header, every site.
|
||
*/
|
||
function AppHeader({
|
||
logo,
|
||
product,
|
||
nav = [],
|
||
activeNav,
|
||
onNav,
|
||
center = null,
|
||
theme = 'light',
|
||
onThemeToggle,
|
||
rightExtra = null,
|
||
user,
|
||
onAvatar,
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("header", _extends({
|
||
className: __ds_scope.cx('mona-header', className)
|
||
}, rest), /*#__PURE__*/React.createElement("a", {
|
||
className: "mona-header__brand",
|
||
href: "#",
|
||
onClick: e => e.preventDefault()
|
||
}, logo && /*#__PURE__*/React.createElement("img", {
|
||
className: "mona-header__logo",
|
||
src: logo,
|
||
alt: ""
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-header__wordmark"
|
||
}, "MONA", /*#__PURE__*/React.createElement("b", null, " ", product))), nav.length > 0 && /*#__PURE__*/React.createElement("nav", {
|
||
className: "mona-header__nav"
|
||
}, nav.map(n => {
|
||
const id = n.id ?? n.label;
|
||
return /*#__PURE__*/React.createElement("a", {
|
||
key: id,
|
||
className: __ds_scope.cx('mona-header__navlink', id === activeNav && 'mona-header__navlink--active'),
|
||
href: n.href || '#',
|
||
onClick: e => {
|
||
if (!n.href) e.preventDefault();
|
||
onNav && onNav(id);
|
||
}
|
||
}, n.icon, n.label);
|
||
})), center && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginLeft: 4
|
||
}
|
||
}, center), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-header__spacer"
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-header__right"
|
||
}, rightExtra, onThemeToggle && /*#__PURE__*/React.createElement(__ds_scope.IconButton, {
|
||
"aria-label": "\uD14C\uB9C8 \uC804\uD658",
|
||
onClick: onThemeToggle
|
||
}, theme === 'dark' ? Sun : Moon), user && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-header__divider"
|
||
}), user && /*#__PURE__*/React.createElement("button", {
|
||
className: "mona-header__avatar",
|
||
onClick: onAvatar,
|
||
title: user.name,
|
||
"aria-label": user.name
|
||
}, initials(user.name))));
|
||
}
|
||
Object.assign(__ds_scope, { AppHeader });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/app/AppHeader.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/Input.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-input', `
|
||
.mona-field { display: flex; flex-direction: column; gap: 6px; }
|
||
.mona-field__label { font: var(--font-medium) var(--text-xs)/1.4 var(--font-sans); color: var(--text-secondary); }
|
||
.mona-field__label .req { color: var(--color-danger); margin-left: 2px; }
|
||
.mona-inputwrap { position: relative; display: flex; align-items: center; }
|
||
.mona-inputwrap__icon { position: absolute; left: 12px; display: flex; color: var(--text-muted); pointer-events: none; }
|
||
.mona-input {
|
||
width: 100%; font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans);
|
||
color: var(--text-body); background: var(--surface-card);
|
||
border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-md);
|
||
padding: 9px 12px; transition: border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-inputwrap--with-icon .mona-input { padding-left: 36px; }
|
||
.mona-input::placeholder { color: var(--text-disabled); }
|
||
.mona-input:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
|
||
.mona-input:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); }
|
||
.mona-input:disabled { background: var(--surface-sunken); color: var(--text-disabled); cursor: not-allowed; }
|
||
.mona-field--error .mona-input { border-color: var(--color-danger); }
|
||
.mona-field--error .mona-input:focus { box-shadow: 0 0 0 3px var(--color-danger-subtle); }
|
||
.mona-field__hint { font: var(--font-regular) var(--text-xs)/1.4 var(--font-sans); color: var(--text-muted); }
|
||
.mona-field__hint--error { color: var(--color-danger); }
|
||
`);
|
||
|
||
/**
|
||
* Input — single-line text field with optional label, leading icon and
|
||
* hint / error message. Wraps a native <input>.
|
||
*/
|
||
function Input({
|
||
label,
|
||
hint,
|
||
error,
|
||
required = false,
|
||
leadingIcon = null,
|
||
id,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const fieldId = id || (label ? `f-${Math.random().toString(36).slice(2, 8)}` : undefined);
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-field', error && 'mona-field--error', className)
|
||
}, label && /*#__PURE__*/React.createElement("label", {
|
||
className: "mona-field__label",
|
||
htmlFor: fieldId
|
||
}, label, required && /*#__PURE__*/React.createElement("span", {
|
||
className: "req"
|
||
}, "*")), /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-inputwrap', leadingIcon && 'mona-inputwrap--with-icon')
|
||
}, leadingIcon && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-inputwrap__icon"
|
||
}, leadingIcon), /*#__PURE__*/React.createElement("input", _extends({
|
||
id: fieldId,
|
||
className: "mona-input",
|
||
"aria-invalid": !!error
|
||
}, rest))), (error || hint) && /*#__PURE__*/React.createElement("span", {
|
||
className: __ds_scope.cx('mona-field__hint', error && 'mona-field__hint--error')
|
||
}, error || hint));
|
||
}
|
||
Object.assign(__ds_scope, { Input });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/Input.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/MaskedField.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-masked', `
|
||
.mona-masked { display: flex; flex-direction: column; gap: 6px; }
|
||
.mona-masked__label { font: var(--font-medium) var(--text-xs)/1.4 var(--font-sans); color: var(--text-secondary); }
|
||
.mona-masked__row { display: flex; align-items: center; gap: 8px; background: var(--surface-sunken); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-md); padding: 8px 10px; }
|
||
.mona-masked__val { flex: 1; min-width: 0; font: var(--font-regular) var(--text-sm)/1.4 var(--font-mono); color: var(--text-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.mona-masked__btn { display: flex; border: 0; background: transparent; color: var(--text-muted); cursor: pointer; padding: 4px; border-radius: var(--radius-sm); }
|
||
.mona-masked__btn:hover { background: var(--surface-hover); color: var(--text-body); }
|
||
`);
|
||
const EYE = /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"
|
||
}), /*#__PURE__*/React.createElement("circle", {
|
||
cx: "12",
|
||
cy: "12",
|
||
r: "3"
|
||
}));
|
||
const EYE_OFF = /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M14.084 14.158a3 3 0 0 1-4.242-4.242"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m2 2 20 20"
|
||
}));
|
||
|
||
/**
|
||
* MaskedField — reveals/hides a secret (S3 access key, token) with an eye
|
||
* toggle and a copy button. Shows a dotted mask until revealed.
|
||
*/
|
||
function MaskedField({
|
||
label,
|
||
value = '',
|
||
revealed: controlled,
|
||
onToggle,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const [local, setLocal] = React.useState(false);
|
||
const shown = controlled != null ? controlled : local;
|
||
const toggle = () => {
|
||
onToggle ? onToggle(!shown) : setLocal(s => !s);
|
||
};
|
||
const masked = '•'.repeat(Math.min(24, Math.max(8, String(value).length)));
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-masked', className)
|
||
}, rest), label && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-masked__label"
|
||
}, label), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-masked__row"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-masked__val"
|
||
}, shown ? value : masked), /*#__PURE__*/React.createElement("button", {
|
||
type: "button",
|
||
className: "mona-masked__btn",
|
||
"aria-label": shown ? '가리기' : '표시',
|
||
onClick: toggle
|
||
}, shown ? EYE_OFF : EYE), /*#__PURE__*/React.createElement(__ds_scope.CopyButton, {
|
||
value: value,
|
||
label: "",
|
||
copiedLabel: ""
|
||
})));
|
||
}
|
||
Object.assign(__ds_scope, { MaskedField });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/MaskedField.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/RadioGroup.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-radio', `
|
||
.mona-radiogroup { display: flex; flex-direction: column; gap: 8px; }
|
||
.mona-radiogroup--row { flex-direction: row; flex-wrap: wrap; gap: 16px; }
|
||
.mona-radio { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; font-family: var(--font-sans); }
|
||
.mona-radio--card { border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-md); padding: 12px 14px; transition: border-color var(--duration-fast) var(--ease), background-color var(--duration-fast) var(--ease); }
|
||
.mona-radio--card.is-checked { border-color: var(--color-primary); background: var(--color-primary-subtle); }
|
||
.mona-radio--card.is-checked.is-danger { border-color: var(--color-danger); background: var(--color-danger-subtle); }
|
||
.mona-radio input { position: absolute; opacity: 0; width: 0; height: 0; }
|
||
.mona-radio__mark { width: 18px; height: 18px; flex: none; margin-top: 1px; border-radius: 50%; border: 1.5px solid var(--color-border-strong); display: grid; place-items: center; transition: border-color var(--duration-fast) var(--ease); }
|
||
.mona-radio__mark::after { content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--color-primary); transform: scale(0); transition: transform var(--duration-fast) var(--ease); }
|
||
.mona-radio input:checked + .mona-radio__mark { border-color: var(--color-primary); }
|
||
.mona-radio input:checked + .mona-radio__mark::after { transform: scale(1); }
|
||
.mona-radio.is-danger input:checked + .mona-radio__mark { border-color: var(--color-danger); }
|
||
.mona-radio.is-danger input:checked + .mona-radio__mark::after { background: var(--color-danger); }
|
||
.mona-radio input:focus-visible + .mona-radio__mark { box-shadow: var(--focus-ring); }
|
||
.mona-radio__body { display: flex; flex-direction: column; gap: 3px; }
|
||
.mona-radio__label { font: var(--font-medium) var(--text-sm)/1.3 var(--font-sans); color: var(--text-body); }
|
||
.mona-radio__desc { font: var(--font-regular) var(--text-xs)/1.5 var(--font-sans); color: var(--text-muted); }
|
||
`);
|
||
|
||
/**
|
||
* RadioGroup — single-select option set. Plain rows by default; `card` renders
|
||
* bordered option cards (used by the destructive delete-policy dialog). Mark an
|
||
* option `danger: true` to color its selected card red.
|
||
*/
|
||
function RadioGroup({
|
||
name,
|
||
value,
|
||
onChange,
|
||
options = [],
|
||
variant = 'list',
|
||
card = false,
|
||
row = false,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const gname = name || React.useId();
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-radiogroup', row && 'mona-radiogroup--row', className),
|
||
role: "radiogroup"
|
||
}, rest), options.map(o => {
|
||
const checked = o.value === value;
|
||
return /*#__PURE__*/React.createElement("label", {
|
||
key: o.value,
|
||
className: __ds_scope.cx('mona-radio', card && 'mona-radio--card', checked && 'is-checked', o.danger && 'is-danger')
|
||
}, /*#__PURE__*/React.createElement("input", {
|
||
type: "radio",
|
||
name: gname,
|
||
value: o.value,
|
||
checked: checked,
|
||
onChange: () => onChange && onChange(o.value)
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-radio__mark",
|
||
"aria-hidden": "true"
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-radio__body"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-radio__label"
|
||
}, o.label), o.description && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-radio__desc"
|
||
}, o.description)));
|
||
}));
|
||
}
|
||
Object.assign(__ds_scope, { RadioGroup });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/RadioGroup.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/Select.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-select', `
|
||
.mona-selectwrap { position: relative; display: inline-flex; align-items: center; width: 100%; }
|
||
.mona-select {
|
||
width: 100%; appearance: none; -webkit-appearance: none;
|
||
font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans); color: var(--text-body);
|
||
background: var(--surface-card); border: var(--border-width) solid var(--color-border-strong);
|
||
border-radius: var(--radius-md); padding: 9px 34px 9px 12px; cursor: pointer;
|
||
transition: border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-select:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
|
||
.mona-select:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); }
|
||
.mona-select:disabled { background: var(--surface-sunken); color: var(--text-disabled); cursor: not-allowed; }
|
||
.mona-selectwrap__chev { position: absolute; right: 11px; pointer-events: none; color: var(--text-muted); display: flex; }
|
||
`);
|
||
|
||
/**
|
||
* Select — styled wrapper over a native <select> with a custom chevron.
|
||
* Pass options as {value,label}[] or provide <option> children directly.
|
||
*/
|
||
function Select({
|
||
options,
|
||
className,
|
||
children,
|
||
disabled,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("span", {
|
||
className: __ds_scope.cx('mona-selectwrap', className)
|
||
}, /*#__PURE__*/React.createElement("select", _extends({
|
||
className: "mona-select",
|
||
disabled: disabled
|
||
}, rest), options ? options.map(o => /*#__PURE__*/React.createElement("option", {
|
||
key: o.value,
|
||
value: o.value
|
||
}, o.label)) : children), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-selectwrap__chev",
|
||
"aria-hidden": "true"
|
||
}, /*#__PURE__*/React.createElement("svg", {
|
||
width: "14",
|
||
height: "14",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "m6 9 6 6 6-6"
|
||
}))));
|
||
}
|
||
Object.assign(__ds_scope, { Select });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/Select.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/Switch.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-switch', `
|
||
.mona-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans); color: var(--text-body); user-select: none; }
|
||
.mona-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
|
||
.mona-switch__track {
|
||
width: 38px; height: 22px; flex: none; border-radius: var(--radius-pill);
|
||
background: var(--color-border-strong); position: relative;
|
||
transition: background-color var(--duration) var(--ease), box-shadow var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-switch__thumb {
|
||
position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
|
||
border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm);
|
||
transition: transform var(--duration) var(--ease);
|
||
}
|
||
.mona-switch input:checked + .mona-switch__track { background: var(--color-primary); }
|
||
.mona-switch input:checked + .mona-switch__track .mona-switch__thumb { transform: translateX(16px); }
|
||
.mona-switch input:focus-visible + .mona-switch__track { box-shadow: var(--focus-ring); }
|
||
.mona-switch input:disabled ~ * { opacity: 0.5; }
|
||
.mona-switch--disabled { cursor: not-allowed; }
|
||
`);
|
||
|
||
/**
|
||
* Switch — on/off toggle for settings (theme, feature flags). Children
|
||
* render as an inline label after the track.
|
||
*/
|
||
function Switch({
|
||
disabled = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("label", {
|
||
className: __ds_scope.cx('mona-switch', disabled && 'mona-switch--disabled', className)
|
||
}, /*#__PURE__*/React.createElement("input", _extends({
|
||
type: "checkbox",
|
||
role: "switch",
|
||
disabled: disabled
|
||
}, rest)), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-switch__track",
|
||
"aria-hidden": "true"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-switch__thumb"
|
||
})), children && /*#__PURE__*/React.createElement("span", null, children));
|
||
}
|
||
Object.assign(__ds_scope, { Switch });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/Switch.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/forms/Textarea.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-textarea', `
|
||
.mona-ta { display: flex; flex-direction: column; gap: 6px; }
|
||
.mona-ta__label { font: var(--font-medium) var(--text-xs)/1.4 var(--font-sans); color: var(--text-secondary); }
|
||
.mona-ta__label .req { color: var(--color-danger); margin-left: 2px; }
|
||
.mona-ta__input {
|
||
width: 100%; font: var(--font-regular) var(--text-sm)/1.6 var(--font-sans); color: var(--text-body);
|
||
background: var(--surface-card); border: var(--border-width) solid var(--color-border-strong);
|
||
border-radius: var(--radius-md); padding: 10px 12px; resize: vertical; min-height: 84px;
|
||
transition: border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-ta__input::placeholder { color: var(--text-disabled); }
|
||
.mona-ta__input:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
|
||
.mona-ta__input:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); }
|
||
.mona-ta__input:disabled { background: var(--surface-sunken); color: var(--text-disabled); cursor: not-allowed; }
|
||
.mona-ta--mono .mona-ta__input { font-family: var(--font-mono); font-size: var(--text-xs); }
|
||
.mona-ta--error .mona-ta__input { border-color: var(--color-danger); }
|
||
.mona-ta__hint { display: flex; justify-content: space-between; gap: 8px; font: var(--font-regular) var(--text-xs)/1.4 var(--font-sans); color: var(--text-muted); }
|
||
.mona-ta__hint--error { color: var(--color-danger); }
|
||
`);
|
||
|
||
/**
|
||
* Textarea — multi-line text field with optional label, hint/error and a
|
||
* character counter. `mono` switches to the monospace stack (YAML, manifests).
|
||
*/
|
||
function Textarea({
|
||
label,
|
||
hint,
|
||
error,
|
||
required = false,
|
||
mono = false,
|
||
maxLength,
|
||
value,
|
||
id,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const fieldId = id || (label ? `t-${Math.random().toString(36).slice(2, 8)}` : undefined);
|
||
const count = typeof value === 'string' ? value.length : null;
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-ta', mono && 'mona-ta--mono', error && 'mona-ta--error', className)
|
||
}, label && /*#__PURE__*/React.createElement("label", {
|
||
className: "mona-ta__label",
|
||
htmlFor: fieldId
|
||
}, label, required && /*#__PURE__*/React.createElement("span", {
|
||
className: "req"
|
||
}, "*")), /*#__PURE__*/React.createElement("textarea", _extends({
|
||
id: fieldId,
|
||
className: "mona-ta__input",
|
||
maxLength: maxLength,
|
||
value: value,
|
||
"aria-invalid": !!error
|
||
}, rest)), (error || hint || maxLength && count != null) && /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-ta__hint', error && 'mona-ta__hint--error')
|
||
}, /*#__PURE__*/React.createElement("span", null, error || hint), maxLength && count != null && /*#__PURE__*/React.createElement("span", null, count, "/", maxLength)));
|
||
}
|
||
Object.assign(__ds_scope, { Textarea });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/forms/Textarea.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/navigation/Breadcrumb.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-breadcrumb', `
|
||
.mona-crumb { display: flex; align-items: center; gap: 4px; font: var(--font-regular) var(--text-sm)/1 var(--font-sans); flex-wrap: wrap; }
|
||
.mona-crumb__item { display: inline-flex; align-items: center; gap: 5px; color: var(--text-secondary); background: transparent; border: 0; padding: 4px 6px; border-radius: var(--radius-sm); cursor: pointer; text-decoration: none; font: inherit; }
|
||
.mona-crumb__item:hover { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-crumb__item--current { color: var(--text-body); font-weight: var(--font-medium); pointer-events: none; }
|
||
.mona-crumb__sep { color: var(--text-disabled); display: flex; }
|
||
`);
|
||
const CHEV = /*#__PURE__*/React.createElement("svg", {
|
||
width: "14",
|
||
height: "14",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "m9 18 6-6-6-6"
|
||
}));
|
||
|
||
/**
|
||
* Breadcrumb — path trail with chevron separators. Items render as buttons
|
||
* (or links when `href` is set); the last item is the non-interactive current.
|
||
*/
|
||
function Breadcrumb({
|
||
items = [],
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("nav", _extends({
|
||
className: __ds_scope.cx('mona-crumb', className),
|
||
"aria-label": "breadcrumb"
|
||
}, rest), items.map((it, i) => {
|
||
const last = i === items.length - 1;
|
||
const Tag = it.href && !last ? 'a' : 'button';
|
||
return /*#__PURE__*/React.createElement(React.Fragment, {
|
||
key: i
|
||
}, /*#__PURE__*/React.createElement(Tag, {
|
||
className: __ds_scope.cx('mona-crumb__item', last && 'mona-crumb__item--current'),
|
||
href: it.href,
|
||
onClick: it.onClick,
|
||
"aria-current": last ? 'page' : undefined
|
||
}, it.icon, it.label), !last && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-crumb__sep",
|
||
"aria-hidden": "true"
|
||
}, CHEV));
|
||
}));
|
||
}
|
||
Object.assign(__ds_scope, { Breadcrumb });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/navigation/Breadcrumb.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/navigation/Pagination.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-pagination', `
|
||
.mona-pg { display: flex; align-items: center; gap: 4px; }
|
||
.mona-pg__btn {
|
||
min-width: 30px; height: 30px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center;
|
||
font: var(--font-medium) var(--text-sm)/1 var(--font-sans); color: var(--text-secondary);
|
||
background: transparent; border: var(--border-width) solid transparent; border-radius: var(--radius-md); cursor: pointer;
|
||
transition: background-color var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-pg__btn:hover:not(:disabled):not(.mona-pg__btn--active) { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-pg__btn--active { background: var(--color-primary); color: #fff; }
|
||
.mona-pg__btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
||
.mona-pg__btn svg { display: block; }
|
||
.mona-pg__info { font: var(--font-regular) var(--text-xs)/1 var(--font-sans); color: var(--text-muted); margin-right: 10px; }
|
||
`);
|
||
const ICON = d => /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, d);
|
||
|
||
/**
|
||
* Pagination — page navigation in groups of 5, with prev/next and an
|
||
* optional "전체 N개 중 a–b" summary.
|
||
*/
|
||
function Pagination({
|
||
page = 1,
|
||
pageCount = 1,
|
||
total,
|
||
pageSize,
|
||
onChange,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const go = p => {
|
||
if (p >= 1 && p <= pageCount && p !== page && onChange) onChange(p);
|
||
};
|
||
const group = Math.floor((page - 1) / 5);
|
||
const start = group * 5 + 1;
|
||
const end = Math.min(start + 4, pageCount);
|
||
const pages = [];
|
||
for (let p = start; p <= end; p++) pages.push(p);
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-pg', className)
|
||
}, rest), total != null && pageSize != null && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-pg__info"
|
||
}, "\uC804\uCCB4 ", total, "\uAC1C \uC911 ", (page - 1) * pageSize + 1, "\u2013", Math.min(page * pageSize, total)), /*#__PURE__*/React.createElement("button", {
|
||
className: "mona-pg__btn",
|
||
disabled: page <= 1,
|
||
onClick: () => go(page - 1),
|
||
"aria-label": "\uC774\uC804"
|
||
}, ICON(/*#__PURE__*/React.createElement("path", {
|
||
d: "m15 18-6-6 6-6"
|
||
}))), pages.map(p => /*#__PURE__*/React.createElement("button", {
|
||
key: p,
|
||
className: __ds_scope.cx('mona-pg__btn', p === page && 'mona-pg__btn--active'),
|
||
"aria-current": p === page ? 'page' : undefined,
|
||
onClick: () => go(p)
|
||
}, p)), /*#__PURE__*/React.createElement("button", {
|
||
className: "mona-pg__btn",
|
||
disabled: page >= pageCount,
|
||
onClick: () => go(page + 1),
|
||
"aria-label": "\uB2E4\uC74C"
|
||
}, ICON(/*#__PURE__*/React.createElement("path", {
|
||
d: "m9 18 6-6-6-6"
|
||
}))));
|
||
}
|
||
Object.assign(__ds_scope, { Pagination });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/navigation/Pagination.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/navigation/ProjectSwitcher.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-projectswitcher', `
|
||
.mona-ps { position: relative; display: inline-block; }
|
||
.mona-ps__btn {
|
||
display: inline-flex; align-items: center; gap: 8px; max-width: 340px;
|
||
font: var(--font-semibold) var(--text-sm)/1 var(--font-sans); color: var(--text-body);
|
||
background: var(--surface-sunken); border: var(--border-width) solid var(--color-border);
|
||
border-radius: var(--radius-pill); padding: 7px 12px; cursor: pointer;
|
||
transition: background-color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-ps__btn:hover { border-color: var(--color-border-strong); }
|
||
.mona-ps__btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
||
.mona-ps__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.mona-ps__chev { display: flex; color: var(--text-muted); transition: transform var(--duration-fast) var(--ease); }
|
||
.mona-ps--open .mona-ps__chev { transform: rotate(180deg); }
|
||
|
||
.mona-ps__panel {
|
||
position: absolute; top: calc(100% + 8px); left: 0; z-index: var(--z-dropdown);
|
||
width: 460px; max-width: calc(100vw - 32px); background: var(--surface-card);
|
||
border: var(--border-width) solid var(--color-border); border-radius: var(--radius-xl);
|
||
box-shadow: var(--shadow-2xl); padding: 8px; animation: mona-ps-pop var(--duration-fast) var(--ease-out);
|
||
}
|
||
@keyframes mona-ps-pop { from { transform: translateY(-4px); } to { transform: translateY(0); } }
|
||
.mona-ps__searchwrap { position: relative; display: flex; align-items: center; margin-bottom: 6px; }
|
||
.mona-ps__searchicon { position: absolute; left: 14px; display: flex; color: var(--text-muted); pointer-events: none; }
|
||
.mona-ps__search {
|
||
width: 100%; font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans); color: var(--text-body);
|
||
background: var(--surface-sunken); border: var(--border-width) solid var(--color-border);
|
||
border-radius: var(--radius-lg); padding: 11px 12px 11px 40px;
|
||
}
|
||
.mona-ps__search::placeholder { color: var(--text-muted); }
|
||
.mona-ps__search:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); background: var(--surface-card); }
|
||
.mona-ps__list { max-height: 420px; overflow-y: auto; overflow-x: hidden; padding: 2px; }
|
||
|
||
.mona-ps__sechead { display: flex; align-items: center; gap: 8px; padding: 13px 10px 7px; }
|
||
.mona-ps__sechead:first-child { padding-top: 5px; }
|
||
.mona-ps__secicon { display: flex; flex: none; }
|
||
.mona-ps__secicon--fav { color: #f59e0b; }
|
||
.mona-ps__secicon--recent { color: var(--text-muted); }
|
||
.mona-ps__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
|
||
.mona-ps__seclabel { font: var(--font-semibold) var(--text-sm)/1 var(--font-sans); color: var(--text-secondary); white-space: nowrap; }
|
||
.mona-ps__seccount { margin-left: auto; font: var(--font-medium) var(--text-sm)/1 var(--font-sans); color: var(--text-disabled); }
|
||
|
||
.mona-ps__item {
|
||
display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
|
||
border: 0; border-radius: var(--radius-lg); padding: 9px 10px; cursor: pointer;
|
||
background: transparent; transition: background-color var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-ps__item:hover { background: var(--surface-hover); }
|
||
.mona-ps__item--active { background: var(--color-primary-subtle); }
|
||
.mona-ps__item:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
||
.mona-ps__avatar { width: 38px; height: 38px; border-radius: 11px; flex: none; display: grid; place-items: center; font: var(--font-bold) var(--text-xs)/1 var(--font-sans); letter-spacing: 0.02em; }
|
||
.mona-ps__itemname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--font-regular) var(--text-base)/1.25 var(--font-sans); color: var(--text-body); }
|
||
.mona-ps__prefix { color: var(--text-muted); }
|
||
.mona-ps__itemname b { font-weight: var(--font-semibold); color: var(--text-body); }
|
||
.mona-ps__star { flex: none; border: 0; background: transparent; cursor: pointer; padding: 4px; display: flex; color: var(--text-disabled); opacity: 0; transition: opacity var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease); }
|
||
.mona-ps__item:hover .mona-ps__star { opacity: 1; }
|
||
.mona-ps__star:hover { color: #f59e0b; transform: scale(1.12); }
|
||
.mona-ps__star.is-fav { opacity: 1; color: #f59e0b; }
|
||
.mona-ps__check { flex: none; width: 20px; display: flex; justify-content: center; color: var(--color-primary); }
|
||
.mona-ps__empty { padding: 28px 10px; text-align: center; font: var(--font-regular) var(--text-sm)/1.4 var(--font-sans); color: var(--text-muted); }
|
||
`);
|
||
const CHEV = /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "m6 9 6 6 6-6"
|
||
}));
|
||
const CHECK = /*#__PURE__*/React.createElement("svg", {
|
||
width: "17",
|
||
height: "17",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2.5",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M20 6 9 17l-5-5"
|
||
}));
|
||
const SEARCH = /*#__PURE__*/React.createElement("svg", {
|
||
width: "17",
|
||
height: "17",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("circle", {
|
||
cx: "11",
|
||
cy: "11",
|
||
r: "8"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m21 21-4.3-4.3"
|
||
}));
|
||
const CLOCK = /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("circle", {
|
||
cx: "12",
|
||
cy: "12",
|
||
r: "10"
|
||
}), /*#__PURE__*/React.createElement("polyline", {
|
||
points: "12 6 12 12 16 14"
|
||
}));
|
||
const STAR_FILL = /*#__PURE__*/React.createElement("svg", {
|
||
width: "16",
|
||
height: "16",
|
||
viewBox: "0 0 24 24",
|
||
fill: "currentColor",
|
||
stroke: "currentColor",
|
||
strokeWidth: "1",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M11.48 3.5a.6.6 0 0 1 1.04 0l2.34 4.74 5.23.76a.6.6 0 0 1 .33 1.02l-3.78 3.69.89 5.21a.6.6 0 0 1-.87.63L12 17.9l-4.68 2.46a.6.6 0 0 1-.87-.63l.89-5.21-3.78-3.69a.6.6 0 0 1 .33-1.02l5.23-.76z"
|
||
}));
|
||
const STAR_LINE = /*#__PURE__*/React.createElement("svg", {
|
||
width: "16",
|
||
height: "16",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M11.48 3.5a.6.6 0 0 1 1.04 0l2.34 4.74 5.23.76a.6.6 0 0 1 .33 1.02l-3.78 3.69.89 5.21a.6.6 0 0 1-.87.63L12 17.9l-4.68 2.46a.6.6 0 0 1-.87-.63l.89-5.21-3.78-3.69a.6.6 0 0 1 .33-1.02l5.23-.76z"
|
||
}));
|
||
const PALETTE = ['#2563eb', '#7e22ce', '#16a34a', '#d97706', '#0e7490', '#db2777', '#4f46e5', '#0891b2'];
|
||
function hashIdx(str, mod) {
|
||
let h = 0;
|
||
for (let i = 0; i < (str || '').length; i++) h = h * 31 + str.charCodeAt(i) >>> 0;
|
||
return h % mod;
|
||
}
|
||
function splitName(name, group) {
|
||
if (group && name.toLowerCase().startsWith((group + '-').toLowerCase())) {
|
||
return {
|
||
prefix: name.slice(0, group.length + 1),
|
||
rest: name.slice(group.length + 1)
|
||
};
|
||
}
|
||
return {
|
||
prefix: '',
|
||
rest: name
|
||
};
|
||
}
|
||
function initialsFor(name, group) {
|
||
const {
|
||
rest
|
||
} = splitName(name, group);
|
||
const segs = (rest || name).split(/[-_\s]+/).filter(Boolean);
|
||
const s = segs.length >= 2 ? segs[0][0] + segs[1][0] : (rest || name).replace(/[^a-z0-9]/gi, '').slice(0, 2);
|
||
return s.toUpperCase();
|
||
}
|
||
|
||
/**
|
||
* ProjectSwitcher — the unified project selector. Pill trigger + rich dropdown:
|
||
* search, group-colored avatar tiles, 즐겨찾기 (favorites) and 최근 사용 (recent)
|
||
* sections, namespace groups with colored dots + counts, per-row star toggle,
|
||
* role badge and a selected check. Falls back to a flat list when there are no
|
||
* groups/favorites/recents (AiRSFlow-style).
|
||
*/
|
||
function ProjectSwitcher({
|
||
projects = [],
|
||
value,
|
||
onChange,
|
||
onToggleFavorite,
|
||
recentIds,
|
||
groups,
|
||
label = '프로젝트',
|
||
defaultOpen = false,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const [open, setOpen] = React.useState(defaultOpen);
|
||
const [q, setQ] = React.useState('');
|
||
const [favs, setFavs] = React.useState(() => new Set(projects.filter(p => p.favorite).map(p => p.id)));
|
||
const ref = React.useRef(null);
|
||
const current = projects.find(p => p.id === value) || projects[0];
|
||
React.useEffect(() => {
|
||
if (!open) return;
|
||
const onDoc = e => {
|
||
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
||
};
|
||
document.addEventListener('mousedown', onDoc);
|
||
return () => document.removeEventListener('mousedown', onDoc);
|
||
}, [open]);
|
||
|
||
// group config (explicit `groups` prop, else derived in first-seen order)
|
||
const groupList = React.useMemo(() => {
|
||
if (groups && groups.length) return groups;
|
||
const seen = [];
|
||
const map = {};
|
||
projects.forEach(p => {
|
||
const k = p.group;
|
||
if (k && !map[k]) {
|
||
map[k] = {
|
||
key: k,
|
||
label: String(k).toUpperCase()
|
||
};
|
||
seen.push(map[k]);
|
||
}
|
||
});
|
||
return seen;
|
||
}, [groups, projects]);
|
||
const accentByKey = {};
|
||
groupList.forEach((g, i) => {
|
||
accentByKey[g.key] = g.accent || PALETTE[i % PALETTE.length];
|
||
});
|
||
const accentFor = p => p.accent || accentByKey[p.group] || PALETTE[hashIdx(p.group || p.id, PALETTE.length)];
|
||
const match = p => !q || p.name.toLowerCase().includes(q.toLowerCase());
|
||
const isFav = id => favs.has(id);
|
||
const toggleFav = (e, id) => {
|
||
e.stopPropagation();
|
||
setFavs(prev => {
|
||
const n = new Set(prev);
|
||
n.has(id) ? n.delete(id) : n.add(id);
|
||
return n;
|
||
});
|
||
onToggleFavorite && onToggleFavorite(id);
|
||
};
|
||
const select = id => {
|
||
onChange && onChange(id);
|
||
setOpen(false);
|
||
setQ('');
|
||
};
|
||
const byId = {};
|
||
projects.forEach(p => {
|
||
byId[p.id] = p;
|
||
});
|
||
const favList = projects.filter(p => isFav(p.id) && match(p));
|
||
const recentList = (recentIds || []).map(id => byId[id]).filter(p => p && match(p));
|
||
const flat = groupList.length <= 1 && favList.length === 0 && recentList.length === 0;
|
||
const Row = (p, keyPrefix) => {
|
||
const {
|
||
prefix,
|
||
rest
|
||
} = splitName(p.name, p.group);
|
||
const accent = accentFor(p);
|
||
const active = p.id === value;
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
key: keyPrefix + p.id,
|
||
role: "option",
|
||
"aria-selected": active,
|
||
tabIndex: 0,
|
||
className: __ds_scope.cx('mona-ps__item', active && 'mona-ps__item--active'),
|
||
onClick: () => select(p.id),
|
||
onKeyDown: e => {
|
||
if (e.key === 'Enter' || e.key === ' ') {
|
||
e.preventDefault();
|
||
select(p.id);
|
||
}
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__avatar",
|
||
style: {
|
||
background: accent + '22',
|
||
color: accent
|
||
}
|
||
}, initialsFor(p.name, p.group)), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__itemname"
|
||
}, prefix && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__prefix"
|
||
}, prefix), /*#__PURE__*/React.createElement("b", null, rest)), /*#__PURE__*/React.createElement("button", {
|
||
type: "button",
|
||
className: __ds_scope.cx('mona-ps__star', isFav(p.id) && 'is-fav'),
|
||
"aria-label": isFav(p.id) ? '즐겨찾기 해제' : '즐겨찾기',
|
||
"aria-pressed": isFav(p.id),
|
||
onClick: e => toggleFav(e, p.id)
|
||
}, isFav(p.id) ? STAR_FILL : STAR_LINE), p.role && /*#__PURE__*/React.createElement(__ds_scope.RoleBadge, {
|
||
role: p.role
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__check",
|
||
"aria-hidden": "true"
|
||
}, active ? CHECK : null));
|
||
};
|
||
const SecHead = (key, icon, dot, lbl, count) => /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-ps__sechead",
|
||
key: 'h-' + key
|
||
}, dot ? /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__dot",
|
||
style: {
|
||
background: dot
|
||
}
|
||
}) : /*#__PURE__*/React.createElement("span", {
|
||
className: __ds_scope.cx('mona-ps__secicon', icon === CLOCK ? 'mona-ps__secicon--recent' : 'mona-ps__secicon--fav')
|
||
}, icon), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__seclabel"
|
||
}, lbl), count != null && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__seccount"
|
||
}, count));
|
||
const anyResult = flat ? projects.some(match) : favList.length || recentList.length || groupList.some(g => projects.some(p => p.group === g.key && match(p)));
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-ps', open && 'mona-ps--open', className),
|
||
ref: ref
|
||
}, rest), /*#__PURE__*/React.createElement("button", {
|
||
className: "mona-ps__btn",
|
||
"aria-haspopup": "listbox",
|
||
"aria-expanded": open,
|
||
onClick: () => setOpen(o => !o)
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__name"
|
||
}, current ? current.name : label), current && current.role && /*#__PURE__*/React.createElement(__ds_scope.RoleBadge, {
|
||
role: current.role
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__chev",
|
||
"aria-hidden": "true"
|
||
}, CHEV)), open && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-ps__panel"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-ps__searchwrap"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-ps__searchicon",
|
||
"aria-hidden": "true"
|
||
}, SEARCH), /*#__PURE__*/React.createElement("input", {
|
||
className: "mona-ps__search",
|
||
placeholder: "\uD504\uB85C\uC81D\uD2B8 \uAC80\uC0C9\u2026",
|
||
value: q,
|
||
autoFocus: true,
|
||
onChange: e => setQ(e.target.value)
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-ps__list",
|
||
role: "listbox"
|
||
}, !anyResult && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-ps__empty"
|
||
}, "\uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4"), flat && projects.filter(match).map(p => Row(p, 'f-')), !flat && favList.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, {
|
||
key: "sec-fav"
|
||
}, SecHead('fav', STAR_FILL, null, '즐겨찾기', favList.length), favList.map(p => Row(p, 'fav-'))), !flat && recentList.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, {
|
||
key: "sec-recent"
|
||
}, SecHead('recent', CLOCK, null, '최근 사용', null), recentList.map(p => Row(p, 'rec-'))), !flat && groupList.map(g => {
|
||
const items = projects.filter(p => p.group === g.key && match(p));
|
||
if (items.length === 0) return null;
|
||
return /*#__PURE__*/React.createElement(React.Fragment, {
|
||
key: 'sec-' + g.key
|
||
}, SecHead(g.key, null, accentByKey[g.key], g.label, items.length), items.map(p => Row(p, g.key + '-')));
|
||
}))));
|
||
}
|
||
Object.assign(__ds_scope, { ProjectSwitcher });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/navigation/ProjectSwitcher.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/navigation/Tabs.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-tabs', `
|
||
.mona-tabs { display: flex; gap: 2px; border-bottom: var(--border-width) solid var(--color-border); }
|
||
.mona-tabs--pill { gap: 6px; border-bottom: 0; }
|
||
.mona-tab {
|
||
position: relative; display: inline-flex; align-items: center; gap: 7px;
|
||
font: var(--font-medium) var(--text-sm)/1 var(--font-sans); color: var(--text-secondary);
|
||
background: transparent; border: 0; cursor: pointer; padding: 11px 14px;
|
||
border-bottom: 2px solid transparent; margin-bottom: -1px;
|
||
transition: color var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease), background-color var(--duration-fast) var(--ease);
|
||
}
|
||
.mona-tab:hover { color: var(--text-body); }
|
||
.mona-tab--active { color: var(--color-primary); border-bottom-color: var(--color-primary); }
|
||
.mona-tab__count {
|
||
font-size: var(--text-2xs); font-weight: var(--font-semibold);
|
||
background: var(--surface-sunken); color: var(--text-secondary);
|
||
border-radius: var(--radius-pill); padding: 1px 7px;
|
||
}
|
||
.mona-tab--active .mona-tab__count { background: var(--color-primary-subtle); color: var(--color-primary); }
|
||
/* pill variant (segmented) */
|
||
.mona-tabs--pill .mona-tab { border: 0; margin: 0; border-radius: var(--radius-md); padding: 7px 13px; }
|
||
.mona-tabs--pill .mona-tab--active { background: var(--color-primary-subtle); color: var(--color-primary); }
|
||
`);
|
||
|
||
/**
|
||
* Tabs — horizontal tab bar. Default underline style for page sections;
|
||
* `variant="pill"` for segmented filters. Controlled via `value`/`onChange`.
|
||
*/
|
||
function Tabs({
|
||
tabs = [],
|
||
value,
|
||
onChange,
|
||
variant = 'underline',
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-tabs', variant === 'pill' && 'mona-tabs--pill', className),
|
||
role: "tablist"
|
||
}, rest), tabs.map(t => {
|
||
const id = t.id ?? t.value ?? t.label;
|
||
const active = id === value;
|
||
return /*#__PURE__*/React.createElement("button", {
|
||
key: id,
|
||
role: "tab",
|
||
"aria-selected": active,
|
||
className: __ds_scope.cx('mona-tab', active && 'mona-tab--active'),
|
||
onClick: () => onChange && onChange(id)
|
||
}, t.icon, t.label, t.count != null && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-tab__count"
|
||
}, t.count));
|
||
}));
|
||
}
|
||
Object.assign(__ds_scope, { Tabs });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/navigation/Tabs.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/surfaces/Card.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-card', `
|
||
.mona-card {
|
||
background: var(--surface-card); border: var(--border-width) solid var(--color-border);
|
||
border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
|
||
transition: box-shadow var(--duration) var(--ease), transform var(--duration) var(--ease), border-color var(--duration) var(--ease);
|
||
}
|
||
.mona-card--hover:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
|
||
.mona-card--selected { border-color: var(--color-primary); box-shadow: var(--focus-ring); }
|
||
.mona-card--flat { box-shadow: none; }
|
||
.mona-card__header { display: flex; align-items: center; gap: 10px; padding: 14px var(--space-5); border-bottom: var(--border-width) solid var(--color-border); }
|
||
.mona-card__title { font: var(--font-semibold) var(--text-md)/1.3 var(--font-sans); color: var(--text-body); }
|
||
.mona-card__header-actions { margin-left: auto; display: flex; gap: 6px; align-items: center; }
|
||
.mona-card__body { padding: var(--space-5); }
|
||
.mona-card__body--tight { padding: var(--space-4); }
|
||
.mona-card__footer { padding: 12px var(--space-5); border-top: var(--border-width) solid var(--color-border); background: var(--surface-subtle); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
|
||
`);
|
||
|
||
/**
|
||
* Card — the family surface container. Optional header (title + actions) and
|
||
* footer. Use `interactive` for hover-lift list cards and `selected` for the
|
||
* active state.
|
||
*/
|
||
function Card({
|
||
title,
|
||
icon = null,
|
||
headerActions = null,
|
||
footer = null,
|
||
interactive = false,
|
||
selected = false,
|
||
flat = false,
|
||
tight = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-card', interactive && 'mona-card--hover', selected && 'mona-card--selected', flat && 'mona-card--flat', className)
|
||
}, rest), (title || headerActions) && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-card__header"
|
||
}, icon, title && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-card__title"
|
||
}, title), headerActions && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-card__header-actions"
|
||
}, headerActions)), /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-card__body', tight && 'mona-card__body--tight')
|
||
}, children), footer && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-card__footer"
|
||
}, footer));
|
||
}
|
||
Object.assign(__ds_scope, { Card });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/surfaces/Card.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/surfaces/EnvBanner.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-envbanner', `
|
||
.mona-envbanner {
|
||
display: flex; align-items: center; justify-content: center; gap: 8px;
|
||
min-height: var(--banner-height); padding: 6px 16px; text-align: center;
|
||
font: var(--font-semibold) var(--text-xs)/1.4 var(--font-sans);
|
||
background: var(--color-warning); color: #3f2d06;
|
||
}
|
||
.mona-envbanner svg { flex: none; }
|
||
.mona-envbanner--prod { background: var(--color-env-prod); color: #fff; }
|
||
.mona-envbanner--stage { background: var(--color-env-stage); color: #fff; }
|
||
`);
|
||
const WARN = /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2.2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 9v4"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 17h.01"
|
||
}));
|
||
|
||
/**
|
||
* EnvBanner — full-width environment warning bar shown at the very top
|
||
* (above the header). Amber for dev — the family-shared dev signal.
|
||
*/
|
||
function EnvBanner({
|
||
env = 'dev',
|
||
label,
|
||
className,
|
||
...rest
|
||
}) {
|
||
const text = label || (env === 'dev' ? '개발망 (Development)' : env === 'stage' ? '스테이징 (Staging)' : '운영 환경 (Production)');
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-envbanner', env !== 'dev' && `mona-envbanner--${env}`, className),
|
||
role: "alert"
|
||
}, rest), WARN, /*#__PURE__*/React.createElement("span", null, text));
|
||
}
|
||
Object.assign(__ds_scope, { EnvBanner });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/surfaces/EnvBanner.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/surfaces/Modal.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-modal', `
|
||
.mona-modal__overlay {
|
||
position: fixed; inset: 0; z-index: var(--z-overlay);
|
||
background: var(--color-overlay); backdrop-filter: blur(2px);
|
||
display: flex; align-items: center; justify-content: center; padding: 20px;
|
||
animation: mona-fade-in var(--duration) var(--ease-out);
|
||
}
|
||
.mona-modal {
|
||
background: var(--surface-card); border: var(--border-width) solid var(--color-border);
|
||
border-radius: var(--radius-lg); box-shadow: var(--shadow-2xl);
|
||
width: 100%; max-height: 90dvh; display: flex; flex-direction: column;
|
||
z-index: var(--z-modal);
|
||
}
|
||
.mona-modal--sm { max-width: 400px; }
|
||
.mona-modal--md { max-width: 520px; }
|
||
.mona-modal--lg { max-width: 680px; }
|
||
.mona-modal--xl { max-width: 880px; }
|
||
.mona-modal__header { display: flex; align-items: center; gap: 10px; padding: 16px var(--space-6); border-bottom: var(--border-width) solid var(--color-border); }
|
||
.mona-modal__title { font: var(--font-bold) var(--text-lg)/1.3 var(--font-sans); color: var(--text-body); }
|
||
.mona-modal__close { margin-left: auto; border: 0; background: transparent; cursor: pointer; color: var(--text-muted); border-radius: var(--radius-sm); padding: 4px; display: flex; }
|
||
.mona-modal__close:hover { background: var(--surface-hover); color: var(--text-body); }
|
||
.mona-modal__body { padding: var(--space-6); overflow: auto; font: var(--font-regular) var(--text-sm)/1.6 var(--font-sans); color: var(--text-secondary); }
|
||
.mona-modal__footer { display: flex; justify-content: flex-end; gap: 10px; padding: 14px var(--space-6); border-top: var(--border-width) solid var(--color-border); background: var(--surface-subtle); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
|
||
`);
|
||
|
||
/**
|
||
* Modal — centered dialog with scrim, header (title + close), scrollable body
|
||
* and footer action bar. The single family dialog pattern (replaces Files'
|
||
* window.confirm and Pass's one-off overlays).
|
||
*/
|
||
function Modal({
|
||
open = true,
|
||
title,
|
||
onClose,
|
||
size = 'md',
|
||
footer = null,
|
||
closeOnOverlay = true,
|
||
className,
|
||
children,
|
||
...rest
|
||
}) {
|
||
if (!open) return null;
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-modal__overlay",
|
||
onClick: closeOnOverlay && onClose ? e => {
|
||
if (e.target === e.currentTarget) onClose();
|
||
} : undefined
|
||
}, /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-modal', `mona-modal--${size}`, className),
|
||
role: "dialog",
|
||
"aria-modal": "true"
|
||
}, rest), (title || onClose) && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-modal__header"
|
||
}, title && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-modal__title"
|
||
}, title), onClose && /*#__PURE__*/React.createElement("button", {
|
||
className: "mona-modal__close",
|
||
"aria-label": "\uB2EB\uAE30",
|
||
onClick: onClose
|
||
}, /*#__PURE__*/React.createElement("svg", {
|
||
width: "18",
|
||
height: "18",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "M18 6 6 18"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "m6 6 12 12"
|
||
})))), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-modal__body"
|
||
}, children), footer && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-modal__footer"
|
||
}, footer)));
|
||
}
|
||
Object.assign(__ds_scope, { Modal });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/surfaces/Modal.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/surfaces/ConfirmDialog.jsx
|
||
try { (() => {
|
||
__ds_scope.injectStyle('mona-confirm', `
|
||
.mona-confirm__msg { font: var(--font-regular) var(--text-sm)/1.6 var(--font-sans); color: var(--text-secondary); }
|
||
.mona-confirm__warn { display: flex; gap: 9px; align-items: flex-start; background: var(--color-danger-subtle); color: var(--color-danger); border-radius: var(--radius-md); padding: 11px 13px; font: var(--font-medium) var(--text-xs)/1.5 var(--font-sans); margin-top: 14px; }
|
||
.mona-confirm__warn svg { flex: none; margin-top: 1px; }
|
||
.mona-confirm__section { margin-top: 16px; }
|
||
.mona-confirm__seclabel { font: var(--font-semibold) var(--text-xs)/1 var(--font-sans); color: var(--text-secondary); margin-bottom: 9px; }
|
||
.mona-confirm__confirm { margin-top: 16px; }
|
||
.mona-confirm__confirm label { display: block; font: var(--font-regular) var(--text-xs)/1.5 var(--font-sans); color: var(--text-muted); margin-bottom: 7px; }
|
||
.mona-confirm__confirm code { font-family: var(--font-mono); color: var(--text-body); font-weight: var(--font-semibold); }
|
||
.mona-confirm__input { width: 100%; font: var(--font-regular) var(--text-sm)/1.4 var(--font-mono); color: var(--text-body); background: var(--surface-card); border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-md); padding: 9px 12px; }
|
||
.mona-confirm__input:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); }
|
||
`);
|
||
const WARN = /*#__PURE__*/React.createElement("svg", {
|
||
width: "15",
|
||
height: "15",
|
||
viewBox: "0 0 24 24",
|
||
fill: "none",
|
||
stroke: "currentColor",
|
||
strokeWidth: "2.2",
|
||
strokeLinecap: "round",
|
||
strokeLinejoin: "round"
|
||
}, /*#__PURE__*/React.createElement("path", {
|
||
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 9v4"
|
||
}), /*#__PURE__*/React.createElement("path", {
|
||
d: "M12 17h.01"
|
||
}));
|
||
|
||
/**
|
||
* ConfirmDialog — the family's canonical confirm/destructive dialog (built on
|
||
* Modal). Neutral by default; `tone="destructive"` colors the confirm button
|
||
* red. Supports a warning callout, an optional policy RadioGroup, and a
|
||
* type-to-confirm phrase that gates the confirm button (delete flows).
|
||
*/
|
||
function ConfirmDialog({
|
||
open = true,
|
||
tone = 'neutral',
|
||
title,
|
||
message,
|
||
warning,
|
||
policies,
|
||
policyValue,
|
||
onPolicyChange,
|
||
confirmPhrase,
|
||
confirmLabel,
|
||
cancelLabel = '취소',
|
||
onConfirm,
|
||
onCancel,
|
||
children
|
||
}) {
|
||
const [typed, setTyped] = React.useState('');
|
||
React.useEffect(() => {
|
||
if (!open) setTyped('');
|
||
}, [open]);
|
||
const phraseOK = !confirmPhrase || typed === confirmPhrase;
|
||
const destructive = tone === 'destructive';
|
||
return /*#__PURE__*/React.createElement(__ds_scope.Modal, {
|
||
open: open,
|
||
size: "sm",
|
||
title: title,
|
||
onClose: onCancel,
|
||
footer: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(__ds_scope.Button, {
|
||
variant: "ghost",
|
||
onClick: onCancel
|
||
}, cancelLabel), /*#__PURE__*/React.createElement(__ds_scope.Button, {
|
||
variant: destructive ? 'danger' : 'primary',
|
||
disabled: !phraseOK,
|
||
onClick: onConfirm
|
||
}, confirmLabel || (destructive ? '삭제' : '확인')))
|
||
}, message && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-confirm__msg"
|
||
}, message), children, policies && policies.length > 0 && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-confirm__section"
|
||
}, /*#__PURE__*/React.createElement(__ds_scope.RadioGroup, {
|
||
card: true,
|
||
options: policies,
|
||
value: policyValue,
|
||
onChange: onPolicyChange
|
||
})), warning && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-confirm__warn"
|
||
}, WARN, /*#__PURE__*/React.createElement("span", null, warning)), confirmPhrase && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-confirm__confirm"
|
||
}, /*#__PURE__*/React.createElement("label", null, "\uD655\uC778\uC744 \uC704\uD574 \uC544\uB798 \uC785\uB825\uCC3D\uC5D0 ", /*#__PURE__*/React.createElement("code", null, confirmPhrase), " \uC744(\uB97C) \uC785\uB825\uD558\uC138\uC694."), /*#__PURE__*/React.createElement("input", {
|
||
className: "mona-confirm__input",
|
||
value: typed,
|
||
placeholder: confirmPhrase,
|
||
onChange: e => setTyped(e.target.value),
|
||
onPaste: e => e.preventDefault()
|
||
})));
|
||
}
|
||
Object.assign(__ds_scope, { ConfirmDialog });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/surfaces/ConfirmDialog.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/components/surfaces/StatCard.jsx
|
||
try { (() => {
|
||
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
||
__ds_scope.injectStyle('mona-statcard', `
|
||
.mona-stat { background: var(--surface-card); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 16px 18px; }
|
||
.mona-stat__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
|
||
.mona-stat__label { font: var(--font-medium) var(--text-xs)/1.3 var(--font-sans); color: var(--text-muted); }
|
||
.mona-stat__icon { display: flex; color: var(--color-primary); flex: none; }
|
||
.mona-stat__value { font: var(--font-bold) var(--text-3xl)/1 var(--font-sans); color: var(--text-body); letter-spacing: var(--tracking-tight); margin-top: 10px; }
|
||
.mona-stat__value--md { font-size: var(--text-2xl); }
|
||
.mona-stat__foot { display: flex; align-items: center; gap: 6px; margin-top: 8px; font: var(--font-regular) var(--text-xs)/1.3 var(--font-sans); color: var(--text-muted); }
|
||
.mona-stat__delta { font-weight: var(--font-semibold); }
|
||
.mona-stat__delta--up { color: var(--color-success); }
|
||
.mona-stat__delta--down { color: var(--color-danger); }
|
||
`);
|
||
|
||
/**
|
||
* StatCard — labeled metric card for dashboards and detail headers
|
||
* (project count, member count, quota totals…). Optional icon, footnote and
|
||
* trend delta.
|
||
*/
|
||
function StatCard({
|
||
label,
|
||
value,
|
||
icon = null,
|
||
accent,
|
||
footnote = null,
|
||
delta,
|
||
size = 'lg',
|
||
className,
|
||
...rest
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", _extends({
|
||
className: __ds_scope.cx('mona-stat', className)
|
||
}, rest), /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-stat__top"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-stat__label"
|
||
}, label), icon && /*#__PURE__*/React.createElement("span", {
|
||
className: "mona-stat__icon",
|
||
style: accent ? {
|
||
color: accent
|
||
} : undefined
|
||
}, icon)), /*#__PURE__*/React.createElement("div", {
|
||
className: __ds_scope.cx('mona-stat__value', size === 'md' && 'mona-stat__value--md')
|
||
}, value), (footnote || delta) && /*#__PURE__*/React.createElement("div", {
|
||
className: "mona-stat__foot"
|
||
}, delta && /*#__PURE__*/React.createElement("span", {
|
||
className: __ds_scope.cx('mona-stat__delta', delta.dir && `mona-stat__delta--${delta.dir}`)
|
||
}, delta.label), footnote));
|
||
}
|
||
Object.assign(__ds_scope, { StatCard });
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/components/surfaces/StatCard.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/airsflow/screens.jsx
|
||
try { (() => {
|
||
/* MONA AiRSFlow — UI kit. The ONLY design surfaces we control are the family
|
||
header, the project selector, and the error/empty screens. The Airflow 3 UI
|
||
inside the iframe is an external system — shown here only as a bounded region. */
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
AppHeader,
|
||
LoginScreen,
|
||
EnvBanner,
|
||
ProjectSwitcher,
|
||
Button,
|
||
EmptyState
|
||
} = NS;
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
const PROJECTS = [{
|
||
id: 'demo',
|
||
name: 'mona-demo',
|
||
role: 'admin'
|
||
}, {
|
||
id: 'reco',
|
||
name: '추천 파이프라인',
|
||
role: 'developer'
|
||
}, {
|
||
id: 'ads',
|
||
name: '광고주센터 api',
|
||
role: 'viewer'
|
||
}];
|
||
function Shell({
|
||
theme,
|
||
onToggle,
|
||
hasProjects,
|
||
project,
|
||
setProject,
|
||
showError
|
||
}) {
|
||
const right = /*#__PURE__*/React.createElement("div", {
|
||
className: "af-linkrow"
|
||
}, /*#__PURE__*/React.createElement("a", {
|
||
className: "af-link",
|
||
href: "#",
|
||
onClick: e => e.preventDefault()
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "BookOpen",
|
||
size: 15
|
||
}), "\uAC00\uC774\uB4DC"), /*#__PURE__*/React.createElement("a", {
|
||
className: "af-link",
|
||
href: "#",
|
||
onClick: e => e.preventDefault()
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "LogOut",
|
||
size: 15
|
||
}), "\uB85C\uADF8\uC544\uC6C3"));
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "af-app"
|
||
}, /*#__PURE__*/React.createElement(EnvBanner, {
|
||
env: "dev"
|
||
}), /*#__PURE__*/React.createElement(AppHeader, {
|
||
logo: "../../assets/logos/airsflow.svg",
|
||
product: "AiRSFlow",
|
||
center: hasProjects ? /*#__PURE__*/React.createElement(ProjectSwitcher, {
|
||
projects: PROJECTS,
|
||
value: project,
|
||
onChange: setProject
|
||
}) : null,
|
||
theme: theme,
|
||
onThemeToggle: onToggle,
|
||
rightExtra: right,
|
||
user: {
|
||
name: 'bsb'
|
||
}
|
||
}), hasProjects && !showError && /*#__PURE__*/React.createElement("div", {
|
||
className: "af-iframe"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "af-iframe__boundary"
|
||
}), /*#__PURE__*/React.createElement("span", {
|
||
className: "af-iframe__tag"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ExternalLink",
|
||
size: 13
|
||
}), " AiRSFlow (Airflow 3) \xB7 \uC678\uBD80 \uC2DC\uC2A4\uD15C (iframe)"), /*#__PURE__*/React.createElement("div", {
|
||
className: "af-iframe__center"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "af-iframe__icon"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Workflow",
|
||
size: 46,
|
||
stroke: 1.5
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
className: "af-iframe__title"
|
||
}, "Airflow 3 UI\uAC00 \uC774 \uC601\uC5ED\uC5D0 \uC784\uBCA0\uB4DC\uB429\uB2C8\uB2E4"), /*#__PURE__*/React.createElement("div", {
|
||
className: "af-iframe__desc"
|
||
}, "iframe \uB0B4\uBD80\uB294 \uC678\uBD80 \uC2DC\uC2A4\uD15C\uC73C\uB85C \uD328\uBC00\uB9AC \uB514\uC790\uC778 \uD1B5\uC81C \uBC94\uC704 \uBC16\uC785\uB2C8\uB2E4. \uC6B0\uB9AC\uAC00 \uB514\uC790\uC778\uD558\uB294 \uD45C\uBA74\uC740 \uC0C1\uB2E8 \uD5E4\uB354\xB7\uD504\uB85C\uC81D\uD2B8 \uC140\uB809\uD130\xB7\uC5D0\uB7EC \uD654\uBA74\uBFD0\uC785\uB2C8\uB2E4."))), showError && /*#__PURE__*/React.createElement("div", {
|
||
className: "af-error"
|
||
}, /*#__PURE__*/React.createElement(EmptyState, {
|
||
size: "lg",
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ShieldAlert",
|
||
size: 26
|
||
}),
|
||
title: "\uC811\uADFC \uAC00\uB2A5\uD55C AiRSFlow\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4",
|
||
description: "\uD604\uC7AC \uACC4\uC815\uC73C\uB85C \uC811\uADFC \uAC00\uB2A5\uD55C AiRSFlow hub\uAC00 \uB4F1\uB85D\uB41C \uD504\uB85C\uC81D\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uD504\uB85C\uC81D\uD2B8 \uAD8C\uD55C\uC744 \uD655\uC778\uD558\uAC70\uB098 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD558\uC138\uC694.",
|
||
action: /*#__PURE__*/React.createElement(Button, {
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "LogOut",
|
||
size: 15
|
||
})
|
||
}, "\uB85C\uADF8\uC544\uC6C3")
|
||
})));
|
||
}
|
||
function AiRSFlowRoot() {
|
||
const [authed, setAuthed] = React.useState(false);
|
||
const [theme, setTheme] = React.useState('light');
|
||
const [project, setProject] = React.useState('demo');
|
||
const [mode, setMode] = React.useState('shell'); // 'shell' | 'error'
|
||
React.useEffect(() => {
|
||
document.documentElement.classList.toggle('dark', theme === 'dark');
|
||
}, [theme]);
|
||
if (!authed) {
|
||
return /*#__PURE__*/React.createElement(LoginScreen, {
|
||
logo: "../../assets/logos/airsflow.svg",
|
||
product: "AiRSFlow",
|
||
title: "Airflow\uB97C \uAD8C\uD55C \uBAA8\uB378 \uC548\uC5D0\uC11C",
|
||
subtitle: "\uD504\uB85C\uC81D\uD2B8 \uAD8C\uD55C\uC73C\uB85C AiRSFlow(Airflow 3) UI\uC5D0 \uC548\uC804\uD558\uAC8C \uC811\uADFC\uD569\uB2C8\uB2E4.",
|
||
buttonLabel: "SSO \uB85C\uADF8\uC778",
|
||
onLogin: () => setAuthed(true),
|
||
note: /*#__PURE__*/React.createElement(React.Fragment, null, "OSS \uACC4\uC815\uC73C\uB85C \uB85C\uADF8\uC778\uD569\uB2C8\uB2E4 \xB7 ", /*#__PURE__*/React.createElement("a", {
|
||
href: "#",
|
||
onClick: e => e.preventDefault()
|
||
}, "\uAC00\uC774\uB4DC"))
|
||
});
|
||
}
|
||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Shell, {
|
||
theme: theme,
|
||
onToggle: () => setTheme(t => t === 'dark' ? 'light' : 'dark'),
|
||
hasProjects: mode === 'shell',
|
||
project: project,
|
||
setProject: setProject,
|
||
showError: mode === 'error'
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
className: "demo-toggle"
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
onClick: () => setMode(m => m === 'shell' ? 'error' : 'shell')
|
||
}, mode === 'shell' ? '403 에러 화면 보기' : 'shell 화면 보기')));
|
||
}
|
||
ReactDOM.createRoot(document.getElementById('root')).render(/*#__PURE__*/React.createElement(AiRSFlowRoot, null));
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/airsflow/screens.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/files/screens.jsx
|
||
try { (() => {
|
||
/* MONA Files — interactive 3-pane S3 browser. Composes family components +
|
||
Files-specific layout (tree / file pane / details). */
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
AppHeader,
|
||
LoginScreen,
|
||
EnvBanner,
|
||
ProjectSwitcher,
|
||
Input,
|
||
Button,
|
||
IconButton,
|
||
Badge,
|
||
RoleBadge,
|
||
EmptyState,
|
||
Skeleton
|
||
} = NS;
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
|
||
/* ---- File-type icon mapping (Files-specific colors, tokenized) ---- */
|
||
function FileIcon({
|
||
kind,
|
||
size = 19
|
||
}) {
|
||
const map = {
|
||
folder: {
|
||
name: 'Folder',
|
||
color: 'var(--color-file-folder)'
|
||
},
|
||
json: {
|
||
name: 'FileJson',
|
||
color: 'var(--color-file-doc)'
|
||
},
|
||
yaml: {
|
||
name: 'FileCode2',
|
||
color: 'var(--color-file-doc)'
|
||
},
|
||
csv: {
|
||
name: 'FileSpreadsheet',
|
||
color: 'var(--color-file-doc)'
|
||
},
|
||
text: {
|
||
name: 'FileText',
|
||
color: 'var(--color-file-text)'
|
||
},
|
||
model: {
|
||
name: 'Box',
|
||
color: 'var(--color-file-folder)'
|
||
},
|
||
archive: {
|
||
name: 'FileArchive',
|
||
color: 'var(--color-file-doc)'
|
||
},
|
||
binary: {
|
||
name: 'HardDrive',
|
||
color: 'var(--color-file-folder)'
|
||
},
|
||
file: {
|
||
name: 'File',
|
||
color: 'var(--color-file-folder)'
|
||
}
|
||
};
|
||
const m = map[kind] || map.file;
|
||
return /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: m.color,
|
||
display: 'flex'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: m.name,
|
||
size: size
|
||
}));
|
||
}
|
||
const PROJECTS = [{
|
||
id: 'ad-ai-ad-management',
|
||
name: 'ad-ai-ad-management',
|
||
role: 'admin',
|
||
group: 'ad-ai',
|
||
favorite: true
|
||
}, {
|
||
id: 'ad-ai-ava',
|
||
name: 'ad-ai-ava',
|
||
role: 'admin',
|
||
group: 'ad-ai'
|
||
}, {
|
||
id: 'ad-ai-gfa-serving',
|
||
name: 'ad-ai-gfa-serving',
|
||
role: 'admin',
|
||
group: 'ad-ai'
|
||
}, {
|
||
id: 'ad-ai-pmax-prediction',
|
||
name: 'ad-ai-pmax-prediction',
|
||
role: 'admin',
|
||
group: 'ad-ai'
|
||
}, {
|
||
id: 'ad-ai-pmax-training-status-collector',
|
||
name: 'ad-ai-pmax-training-status-collector',
|
||
role: 'admin',
|
||
group: 'ad-ai'
|
||
}, {
|
||
id: 'ad-ai-sa-ranker',
|
||
name: 'ad-ai-sa-ranker',
|
||
role: 'admin',
|
||
group: 'ad-ai'
|
||
}, {
|
||
id: 'mona-ad-routing',
|
||
name: 'mona-ad-routing',
|
||
role: 'admin',
|
||
group: 'mona'
|
||
}, {
|
||
id: 'mona-demo',
|
||
name: 'mona-demo',
|
||
role: 'admin',
|
||
group: 'mona'
|
||
}, {
|
||
id: 'mona-mdp',
|
||
name: 'mona-mdp',
|
||
role: 'admin',
|
||
group: 'mona'
|
||
}, {
|
||
id: 'mona-shoppingvm-v2',
|
||
name: 'mona-shoppingvm-v2',
|
||
role: 'admin',
|
||
group: 'mona'
|
||
}, {
|
||
id: 'mona-system',
|
||
name: 'mona-system',
|
||
role: 'admin',
|
||
group: 'mona',
|
||
favorite: true
|
||
}, {
|
||
id: 'mona-test',
|
||
name: 'mona-test',
|
||
role: 'admin',
|
||
group: 'mona'
|
||
}];
|
||
const GROUPS = [{
|
||
key: 'ad-ai',
|
||
label: 'AD-AI',
|
||
accent: '#2563eb'
|
||
}, {
|
||
key: 'mona',
|
||
label: 'MONA',
|
||
accent: '#7e22ce'
|
||
}];
|
||
const RECENT_IDS = ['ad-ai-ad-management', 'mona-system', 'ad-ai-sa-ranker', 'mona-shoppingvm-v2'];
|
||
const BUCKET = 'mpd-ad-ai-ad-management';
|
||
const CRUMB = ['test'];
|
||
const TREE = [{
|
||
name: 'test',
|
||
open: false,
|
||
children: []
|
||
}, {
|
||
name: 'test2',
|
||
open: false,
|
||
children: []
|
||
}];
|
||
const FILES = [{
|
||
name: 'checkpoints',
|
||
kind: 'folder',
|
||
type: '폴더',
|
||
size: '—',
|
||
mod: '2026-06-14'
|
||
}, {
|
||
name: 'model.tar.gz',
|
||
kind: 'archive',
|
||
type: 'GZ',
|
||
size: '143 MB',
|
||
mod: '2026-06-13'
|
||
}, {
|
||
name: 'pycharm-2026.1.2-aarch64.dmg',
|
||
kind: 'binary',
|
||
type: 'DMG',
|
||
size: '1.1 GB',
|
||
mod: '2026-06-14'
|
||
}, {
|
||
name: 'train_config.yaml',
|
||
kind: 'yaml',
|
||
type: 'YAML',
|
||
size: '4.2 KB',
|
||
mod: '2026-06-12'
|
||
}, {
|
||
name: 'metrics.json',
|
||
kind: 'json',
|
||
type: 'JSON',
|
||
size: '18 KB',
|
||
mod: '2026-06-12'
|
||
}, {
|
||
name: 'eval_results.csv',
|
||
kind: 'csv',
|
||
type: 'CSV',
|
||
size: '212 KB',
|
||
mod: '2026-06-11'
|
||
}, {
|
||
name: 'README.md',
|
||
kind: 'text',
|
||
type: 'Markdown',
|
||
size: '2.1 KB',
|
||
mod: '2026-06-09'
|
||
}];
|
||
|
||
/* ---- Tree pane ---- */
|
||
function TreeNode({
|
||
node,
|
||
depth,
|
||
path,
|
||
active,
|
||
onSelect
|
||
}) {
|
||
const [open, setOpen] = React.useState(!!node.open);
|
||
const hasKids = node.children && node.children.length > 0;
|
||
const full = path + '/' + node.name;
|
||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
className: 'mf-treerow' + (open ? ' open' : '') + (active === full ? ' on' : ''),
|
||
style: {
|
||
paddingLeft: 8 + depth * 14
|
||
},
|
||
onClick: () => {
|
||
onSelect(full);
|
||
if (hasKids) setOpen(o => !o);
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "chev",
|
||
style: {
|
||
visibility: hasKids ? 'visible' : 'hidden'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ChevronRight",
|
||
size: 14
|
||
})), /*#__PURE__*/React.createElement(FileIcon, {
|
||
kind: "folder",
|
||
size: 16
|
||
}), /*#__PURE__*/React.createElement("span", null, node.name)), open && hasKids && node.children.map(c => /*#__PURE__*/React.createElement(TreeNode, {
|
||
key: c.name,
|
||
node: c,
|
||
depth: depth + 1,
|
||
path: full,
|
||
active: active,
|
||
onSelect: onSelect
|
||
})));
|
||
}
|
||
|
||
/* ---- Files main ---- */
|
||
function MainApp() {
|
||
const [view, setView] = React.useState('list');
|
||
const [sel, setSel] = React.useState(FILES[2]);
|
||
const [treeSel, setTreeSel] = React.useState('/');
|
||
const selFile = sel || FILES[0];
|
||
const isFolder = selFile.kind === 'folder';
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-app"
|
||
}, /*#__PURE__*/React.createElement(EnvBanner, {
|
||
env: "dev"
|
||
}), /*#__PURE__*/React.createElement(AppHeader, {
|
||
logo: "../../assets/logos/files.svg",
|
||
product: "Files",
|
||
center: /*#__PURE__*/React.createElement(ProjectSwitcher, {
|
||
projects: PROJECTS,
|
||
groups: GROUPS,
|
||
recentIds: RECENT_IDS,
|
||
value: "ad-ai-ad-management",
|
||
onChange: () => {}
|
||
}),
|
||
rightExtra: /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-search"
|
||
}, /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "\uC774 \uBC84\uD0B7\uC758 \uD30C\uC77C \uAC80\uC0C9",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Search",
|
||
size: 15
|
||
})
|
||
})),
|
||
theme: window.__filesTheme,
|
||
onThemeToggle: window.__toggleTheme,
|
||
user: {
|
||
name: 'RK'
|
||
}
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-context"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-context__left"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 6,
|
||
font: 'var(--font-medium) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)',
|
||
flexWrap: 'wrap'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)',
|
||
display: 'flex'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Database",
|
||
size: 15
|
||
})), /*#__PURE__*/React.createElement("span", null, "ad-ai-ad-management"), CRUMB.map((c, i) => /*#__PURE__*/React.createElement(React.Fragment, {
|
||
key: c
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--text-disabled)',
|
||
display: 'flex'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ChevronRight",
|
||
size: 13
|
||
})), /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: i === CRUMB.length - 1 ? 'var(--text-body)' : 'var(--text-secondary)',
|
||
fontWeight: i === CRUMB.length - 1 ? 'var(--font-semibold)' : 'var(--font-medium)'
|
||
}
|
||
}, c)))), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-bucketline"
|
||
}, "\uBC84\uD0B7 ", BUCKET, "/")), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-context__actions"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-seg"
|
||
}, /*#__PURE__*/React.createElement("button", {
|
||
className: view === 'list' ? 'on' : '',
|
||
onClick: () => setView('list'),
|
||
"aria-label": "\uB9AC\uC2A4\uD2B8"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "List",
|
||
size: 16
|
||
})), /*#__PURE__*/React.createElement("button", {
|
||
className: view === 'grid' ? 'on' : '',
|
||
onClick: () => setView('grid'),
|
||
"aria-label": "\uCE74\uB4DC"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Grid2x2",
|
||
size: 16
|
||
}))), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Upload",
|
||
size: 15
|
||
})
|
||
}, "\uC5C5\uB85C\uB4DC"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "FolderPlus",
|
||
size: 15
|
||
})
|
||
}, "\uC0C8 \uD3F4\uB354"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "danger-outline",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Trash2",
|
||
size: 15
|
||
})
|
||
}, "\uC0AD\uC81C"))), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-main"
|
||
}, /*#__PURE__*/React.createElement("aside", {
|
||
className: "mf-tree"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-paneltitle"
|
||
}, "\uBC84\uD0B7 \uD30C\uC77C \uD2B8\uB9AC"), /*#__PURE__*/React.createElement("div", {
|
||
className: 'mf-treerow' + (treeSel === '/' ? ' on' : ''),
|
||
onClick: () => setTreeSel('/')
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "chev",
|
||
style: {
|
||
visibility: 'hidden'
|
||
}
|
||
}), /*#__PURE__*/React.createElement(FileIcon, {
|
||
kind: "folder",
|
||
size: 16
|
||
}), /*#__PURE__*/React.createElement("span", null, "/")), TREE.map(n => /*#__PURE__*/React.createElement(TreeNode, {
|
||
key: n.name,
|
||
node: n,
|
||
depth: 1,
|
||
path: "",
|
||
active: treeSel,
|
||
onSelect: setTreeSel
|
||
}))), /*#__PURE__*/React.createElement("section", {
|
||
className: "mf-files"
|
||
}, view === 'list' ? /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-list"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-listhead"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uC774\uB984"), /*#__PURE__*/React.createElement("span", null, "\uC720\uD615"), /*#__PURE__*/React.createElement("span", null, "\uD06C\uAE30"), /*#__PURE__*/React.createElement("span", null, "\uC218\uC815\uC77C")), FILES.map(f => /*#__PURE__*/React.createElement("div", {
|
||
key: f.name,
|
||
className: 'mf-row' + (selFile.name === f.name ? ' sel' : ''),
|
||
onClick: () => setSel(f)
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-name"
|
||
}, /*#__PURE__*/React.createElement(FileIcon, {
|
||
kind: f.kind
|
||
}), /*#__PURE__*/React.createElement("span", null, f.name)), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-meta"
|
||
}, f.type), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-meta"
|
||
}, f.size), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-meta"
|
||
}, f.mod)))) : /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-grid"
|
||
}, FILES.map(f => /*#__PURE__*/React.createElement("div", {
|
||
key: f.name,
|
||
className: 'mf-tile' + (selFile.name === f.name ? ' sel' : ''),
|
||
onClick: () => setSel(f)
|
||
}, /*#__PURE__*/React.createElement(FileIcon, {
|
||
kind: f.kind,
|
||
size: 40
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-tile__name"
|
||
}, f.name), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-tile__meta"
|
||
}, f.size))))), /*#__PURE__*/React.createElement("aside", {
|
||
className: "mf-details"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-paneltitle"
|
||
}, "\uC0C1\uC138 \uC815\uBCF4"), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-preview"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-preview__icon"
|
||
}, /*#__PURE__*/React.createElement(FileIcon, {
|
||
kind: selFile.kind,
|
||
size: 34
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-preview__name"
|
||
}, selFile.name), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-preview__type"
|
||
}, selFile.type, " \xB7 ", selFile.size)), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-detail-actions"
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
block: true,
|
||
disabled: isFolder,
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Download",
|
||
size: 15
|
||
})
|
||
}, "\uB2E4\uC6B4\uB85C\uB4DC"), /*#__PURE__*/React.createElement(Button, {
|
||
block: true,
|
||
variant: "danger-outline",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Trash2",
|
||
size: 15
|
||
})
|
||
}, "\uC0AD\uC81C")), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-metalist"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-metarow"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uC720\uD615"), /*#__PURE__*/React.createElement("b", null, selFile.type)), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-metarow"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uC218\uC815\uC77C"), /*#__PURE__*/React.createElement("b", null, selFile.mod, " 17:31")), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-metarow"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uC5C5\uB85C\uB4DC"), /*#__PURE__*/React.createElement("b", {
|
||
className: "dim"
|
||
}, "\uC815\uBCF4 \uC5C6\uC74C")), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-pathwrap"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "mf-pathlabel"
|
||
}, "\uACBD\uB85C"), /*#__PURE__*/React.createElement("code", {
|
||
className: "mf-pathbox"
|
||
}, BUCKET, "/", CRUMB.join('/'), "/", selFile.name))), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-usage"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-paneltitle",
|
||
style: {
|
||
paddingLeft: 0
|
||
}
|
||
}, "\uBC84\uD0B7 \uC0AC\uC6A9\uB7C9"), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-statgrid"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-statbox"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-stat__v"
|
||
}, "1.4 GB"), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-stat__l"
|
||
}, "\uC0AC\uC6A9 \uC6A9\uB7C9")), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-statbox"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-stat__v"
|
||
}, "7"), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-stat__l"
|
||
}, "\uAC1D\uCCB4 \uC218"))), /*#__PURE__*/React.createElement("div", {
|
||
className: "mf-usage-note"
|
||
}, "\uCD1D \uD55C\uB3C4 \uC815\uBCF4 \uBBF8\uC81C\uACF5 \xB7 ", BUCKET)))));
|
||
}
|
||
|
||
/* ---- Root: login → app, theme toggle ---- */
|
||
function FilesRoot() {
|
||
const [authed, setAuthed] = React.useState(false);
|
||
const [theme, setTheme] = React.useState('light');
|
||
React.useEffect(() => {
|
||
document.documentElement.classList.toggle('dark', theme === 'dark');
|
||
}, [theme]);
|
||
window.__filesTheme = theme;
|
||
window.__toggleTheme = () => setTheme(t => t === 'dark' ? 'light' : 'dark');
|
||
if (!authed) {
|
||
return /*#__PURE__*/React.createElement(LoginScreen, {
|
||
logo: "../../assets/logos/files.svg",
|
||
product: "Files",
|
||
title: "\uD504\uB85C\uC81D\uD2B8 \uD30C\uC77C\uC744 \uC548\uC804\uD558\uAC8C \uD0D0\uC0C9\uD569\uB2C8\uB2E4",
|
||
subtitle: "Keycloak \uAD8C\uD55C\uC73C\uB85C \uC811\uADFC \uAC00\uB2A5\uD55C \uD504\uB85C\uC81D\uD2B8 S3 \uBC84\uD0B7\uB9CC \uD45C\uC2DC\uB429\uB2C8\uB2E4.",
|
||
buttonLabel: "SSO \uB85C\uADF8\uC778",
|
||
onLogin: () => setAuthed(true),
|
||
note: /*#__PURE__*/React.createElement(React.Fragment, null, "OSS \uACC4\uC815\uC73C\uB85C \uB85C\uADF8\uC778\uD569\uB2C8\uB2E4 \xB7 ", /*#__PURE__*/React.createElement("a", {
|
||
href: "#",
|
||
onClick: e => e.preventDefault()
|
||
}, "\uB3C4\uC6C0\uB9D0"))
|
||
});
|
||
}
|
||
return /*#__PURE__*/React.createElement(MainApp, null);
|
||
}
|
||
ReactDOM.createRoot(document.getElementById('root')).render(/*#__PURE__*/React.createElement(FilesRoot, null));
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/files/screens.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-admin.jsx
|
||
try { (() => {
|
||
/* MONA Pass — Admin console (8 tabs). Demonstrates Tabs+counts, Table,
|
||
SortableHeader, ProgressBar, StatCard, EmptyState, EnvChip, settings cards. */
|
||
(() => {
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
Tabs,
|
||
Card,
|
||
Table,
|
||
SortableHeader,
|
||
Badge,
|
||
RoleBadge,
|
||
Button,
|
||
IconButton,
|
||
EmptyState,
|
||
Input,
|
||
Select,
|
||
Switch,
|
||
Pagination,
|
||
EnvChip,
|
||
Checkbox
|
||
} = NS;
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
const lbl = {
|
||
font: 'var(--font-medium) var(--text-2xs)/1 var(--font-mono)',
|
||
color: 'var(--text-muted)'
|
||
};
|
||
const mono = {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)',
|
||
color: 'var(--text-secondary)'
|
||
};
|
||
const PROJECTS = [['ad-ai-ad-management', '광고주센터 api', 'Platform Team', 2], ['ad-ai-ava', 'ava atm', 'Platform Team', 6], ['ad-ai-gfa-serving', 'GFA', 'Platform Team', 2], ['ad-ai-pmax-prediction', 'pmax', 'Platform Team', 1], ['mona-ad-routing', '홈피드 쇼핑, da 분류 라우팅 모델', 'Platform Team', 3], ['mona-demo', 'MONA - DEMO', 'Platform Team', 5]];
|
||
const AUDIT = [['김준석', 'rock.kim@navercorp.com', '로그인', '-', '2026-06-14 19:56:19', '10.25.91.60'], ['bestend', 'sftpgo-poc@navercorp.com', 'S3_TOKEN_ISSUE', 'mpd-mona-test', '2026-06-14 05:08:22', '10.25.101.65'], ['박인영', 'inyeong.park@navercorp.com', '프로젝트 수정', 'ad-ai-sa-ranker', '2026-06-13 18:12:26', '10.25.90.184']];
|
||
const RBAC = [{
|
||
name: 'mona-platform-admin',
|
||
scope: 'platform',
|
||
rules: [['*', '*', 'ALL'], ['""', '*', 'ALL']]
|
||
}, {
|
||
name: 'mona-project-developer',
|
||
scope: 'project',
|
||
rules: [['""', 'pods, services, configmaps', 'ALL'], ['apps', 'deployments, statefulsets', 'ALL'], ['batch', 'jobs, cronjobs', 'ALL']]
|
||
}];
|
||
const SETTINGS = [{
|
||
name: '프로젝트 삭제',
|
||
key: 'project_delete_enabled',
|
||
tag: 'MODIFIED',
|
||
desc: '프로젝트 삭제 기능을 활성화합니다.',
|
||
type: 'toggle',
|
||
on: true
|
||
}, {
|
||
name: '요청 만료 기간',
|
||
key: 'request_expiry_days',
|
||
tag: 'DEFAULT',
|
||
desc: '미승인 요청의 자동 만료 기간(일).',
|
||
type: 'num',
|
||
val: '30'
|
||
}, {
|
||
name: '토큰 유효 기간',
|
||
key: 'token_expiration_days',
|
||
tag: 'DEFAULT',
|
||
desc: 'Kubeconfig 토큰 유효 기간(일).',
|
||
type: 'num',
|
||
val: '365'
|
||
}];
|
||
window.PassAdmin = function Admin() {
|
||
const [tab, setTab] = React.useState('projects');
|
||
const [page, setPage] = React.useState(1);
|
||
const tabs = [{
|
||
id: 'pending',
|
||
label: '승인 대기',
|
||
count: 0
|
||
}, {
|
||
id: 'projects',
|
||
label: '전체 프로젝트',
|
||
count: 12
|
||
}, {
|
||
id: 'users',
|
||
label: '사용자 관리',
|
||
count: 38
|
||
}, {
|
||
id: 'clusters',
|
||
label: '클러스터',
|
||
count: 3
|
||
}, {
|
||
id: 'notices',
|
||
label: '공지사항',
|
||
count: 9
|
||
}, {
|
||
id: 'audit',
|
||
label: '감사 로그'
|
||
}, {
|
||
id: 'roles',
|
||
label: '클러스터 롤'
|
||
}, {
|
||
id: 'settings',
|
||
label: '시스템 설정'
|
||
}];
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uAD00\uB9AC\uC790 \uCF58\uC194")), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__sub"
|
||
}, "\uD504\uB85C\uC81D\uD2B8 \uC2E0\uCCAD \uAD00\uB9AC \uBC0F \uD50C\uB7AB\uD3FC \uB9AC\uC18C\uC2A4 \uD604\uD669"), /*#__PURE__*/React.createElement(Tabs, {
|
||
value: tab,
|
||
onChange: setTab,
|
||
tabs: tabs
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 18
|
||
}
|
||
}, tab === 'pending' && /*#__PURE__*/React.createElement(Card, {
|
||
flat: true
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
padding: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement(EmptyState, {
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Inbox",
|
||
size: 24
|
||
}),
|
||
title: "\uB300\uAE30 \uC911\uC778 \uC694\uCCAD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4",
|
||
description: "\uC0C8 \uC2E0\uCCAD\uC774 \uB4E4\uC5B4\uC624\uBA74 \uC5EC\uAE30\uC5D0\uC11C \uC2B9\uC778\uD558\uAC70\uB098 \uBC18\uB824\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
|
||
}))), tab === 'projects' && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
justifyContent: 'flex-end',
|
||
gap: 8,
|
||
marginBottom: 12
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Filter",
|
||
size: 14
|
||
})
|
||
}, "OutOfSync\uB9CC \uC120\uD0DD"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "RefreshCw",
|
||
size: 14
|
||
})
|
||
}, "\uC120\uD0DD \uD56D\uBAA9 \uB3D9\uAE30\uD654")), /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", {
|
||
style: {
|
||
width: 32
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Checkbox, null)), /*#__PURE__*/React.createElement("th", null, "\uD504\uB85C\uC81D\uD2B8 ID"), /*#__PURE__*/React.createElement("th", null, "\uC774\uB984"), /*#__PURE__*/React.createElement("th", null, "\uD300"), /*#__PURE__*/React.createElement("th", null, "\uD658\uACBD"), /*#__PURE__*/React.createElement("th", {
|
||
style: {
|
||
textAlign: 'right'
|
||
}
|
||
}, "\uBA64\uBC84"), /*#__PURE__*/React.createElement("th", null, "\uC0C1\uD0DC"), /*#__PURE__*/React.createElement("th", null))), /*#__PURE__*/React.createElement("tbody", null, PROJECTS.map(p => /*#__PURE__*/React.createElement("tr", {
|
||
key: p[0]
|
||
}, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Checkbox, null)), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, p[0]), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, p[1]), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, p[2]), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(EnvChip, {
|
||
env: "dev",
|
||
dot: false
|
||
})), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
textAlign: 'right'
|
||
}
|
||
}, p[3]), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "success",
|
||
dot: true,
|
||
size: "sm"
|
||
}, "Synced")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
textAlign: 'right',
|
||
whiteSpace: 'nowrap'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(IconButton, {
|
||
size: "sm",
|
||
"aria-label": "sync"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "RefreshCw",
|
||
size: 14
|
||
})), /*#__PURE__*/React.createElement(IconButton, {
|
||
size: "sm",
|
||
variant: "ghost",
|
||
"aria-label": "\uC0AD\uC81C"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Trash2",
|
||
size: 14
|
||
}))))))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
justifyContent: 'flex-end',
|
||
marginTop: 14
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Pagination, {
|
||
page: page,
|
||
pageCount: 2,
|
||
total: 12,
|
||
pageSize: 10,
|
||
onChange: setPage
|
||
}))), tab === 'users' && /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "\uC0AC\uC6A9\uC790"), /*#__PURE__*/React.createElement("th", null, "\uBD80\uC11C"), /*#__PURE__*/React.createElement("th", null, "\uD50C\uB7AB\uD3FC \uAD8C\uD55C"), /*#__PURE__*/React.createElement("th", null, "\uCC38\uC5EC \uD504\uB85C\uC81D\uD2B8"), /*#__PURE__*/React.createElement("th", null, "\uCD5C\uADFC \uC811\uC18D"))), /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "\uAC15\uCC3D\uD55C"), /*#__PURE__*/React.createElement("div", {
|
||
style: mono
|
||
}, "changhan.kang@navercorp.com")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "Agent Platform"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: "admin",
|
||
isPlatform: true
|
||
})), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("a", {
|
||
href: "#",
|
||
onClick: e => e.preventDefault(),
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, "2\uAC1C")), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "2026-06-04 15:39")), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "\uC815\uB2E4\uC6B4"), /*#__PURE__*/React.createElement("div", {
|
||
style: mono
|
||
}, "daun.jeong@navercorp.com")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "Agent Action Engine"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, "User")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("a", {
|
||
href: "#",
|
||
onClick: e => e.preventDefault(),
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, "3\uAC1C")), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "2026-06-12 11:15")), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "\uAE40\uD5CC"), /*#__PURE__*/React.createElement("div", {
|
||
style: mono
|
||
}, "hkim.1@navercorp.com")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "\uAD11\uACE0 \uB9AC\uD3EC\uD2B8 \uAC1C\uBC1C2"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, "User")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, "0\uAC1C"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "2026-06-03 12:06")))), tab === 'clusters' && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(3,1fr)',
|
||
gap: 14
|
||
}
|
||
}, [['rancher-dev', '랜처 클러스터(개발)', '평촌'], ['common-dev', '관리 클러스터(개발)', '평촌'], ['service-dev', '서비스 클러스터(개발)', '세종']].map(c => /*#__PURE__*/React.createElement(Card, {
|
||
key: c[0],
|
||
interactive: true,
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Server",
|
||
size: 17
|
||
})),
|
||
title: c[0],
|
||
headerActions: c[0] === 'service-dev' ? /*#__PURE__*/React.createElement(EnvChip, {
|
||
env: "dev",
|
||
dot: false
|
||
}) : null
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-sm)/1.5 var(--font-sans)',
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, c[1]), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 5,
|
||
marginTop: 8,
|
||
font: 'var(--font-regular) var(--text-xs)/1 var(--font-sans)',
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "MapPin",
|
||
size: 12
|
||
}), c[2])))), tab === 'notices' && /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "\uC81C\uBAA9"), /*#__PURE__*/React.createElement("th", null, "\uC0C1\uD0DC"), /*#__PURE__*/React.createElement("th", null, "\uC218\uC2E0 \uB300\uC0C1"), /*#__PURE__*/React.createElement("th", null, "\uC791\uC131\uC790"), /*#__PURE__*/React.createElement("th", null, "\uC608\uC57D/\uBC1C\uC1A1 \uC77C\uC2DC"))), /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "2\uC6D4 \uC815\uAE30 \uC810\uAC80 \uC0AC\uC804 \uC548\uB0B4"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "success",
|
||
size: "sm"
|
||
}, "\uBC1C\uC1A1\uB428")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "\uC804\uCCB4 \uC0AC\uC6A9\uC790"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "jeehoon.lim"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "2026-01-29 13:22")), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "Kubeconfig \uBC1C\uAE09 \uC815\uCC45 \uBCC0\uACBD \uC608\uC815"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, "\uCD08\uC548")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "\uC804\uCCB4 \uC0AC\uC6A9\uC790"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "jeehoon.lim"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "2026-01-22 10:22")), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "[\uAE34\uAE09] \uC2DC\uC2A4\uD15C \uC810\uAC80 \uC548\uB0B4"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "success",
|
||
size: "sm"
|
||
}, "\uBC1C\uC1A1\uB428")), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "\uC804\uCCB4 \uC0AC\uC6A9\uC790"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "jeehoon.lim"), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, "2026-01-20 13:22")))), tab === 'audit' && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
gap: 10,
|
||
marginBottom: 12,
|
||
flexWrap: 'wrap'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1,
|
||
minWidth: 180,
|
||
maxWidth: 280
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "\uC0AC\uC6A9\uC790 \uAC80\uC0C9\u2026",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Search",
|
||
size: 15
|
||
})
|
||
})), /*#__PURE__*/React.createElement(Select, {
|
||
options: [{
|
||
value: 'all',
|
||
label: '모든 작업'
|
||
}, {
|
||
value: 'login',
|
||
label: '로그인'
|
||
}]
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginLeft: 'auto'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Download",
|
||
size: 14
|
||
})
|
||
}, "CSV \uB0B4\uBCF4\uB0B4\uAE30"))), /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "\uC0AC\uC6A9\uC790"), /*#__PURE__*/React.createElement("th", null, "\uC791\uC5C5"), /*#__PURE__*/React.createElement("th", null, "\uB300\uC0C1"), /*#__PURE__*/React.createElement("th", null, "\uACB0\uACFC"), /*#__PURE__*/React.createElement("th", null, "\uC2DC\uAC04"), /*#__PURE__*/React.createElement("th", null, "IP \uC8FC\uC18C"))), /*#__PURE__*/React.createElement("tbody", null, AUDIT.map((a, i) => /*#__PURE__*/React.createElement("tr", {
|
||
key: i
|
||
}, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, a[0]), /*#__PURE__*/React.createElement("div", {
|
||
style: mono
|
||
}, a[1])), /*#__PURE__*/React.createElement("td", null, a[2]), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, a[3]), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-success)',
|
||
font: 'var(--font-medium) var(--text-xs)/1 var(--font-sans)'
|
||
}
|
||
}, "Success")), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, a[4]), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, a[5])))))), tab === 'roles' && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(2,1fr)',
|
||
gap: 14
|
||
}
|
||
}, RBAC.map(r => /*#__PURE__*/React.createElement(Card, {
|
||
key: r.name,
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ShieldCheck",
|
||
size: 17
|
||
})),
|
||
title: /*#__PURE__*/React.createElement("span", {
|
||
style: mono
|
||
}, r.name),
|
||
headerActions: /*#__PURE__*/React.createElement(Badge, {
|
||
variant: r.scope === 'platform' ? 'purple' : 'primary',
|
||
size: "sm"
|
||
}, r.scope)
|
||
}, /*#__PURE__*/React.createElement(Table, {
|
||
hover: false
|
||
}, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "API GROUPS"), /*#__PURE__*/React.createElement("th", null, "RESOURCES"), /*#__PURE__*/React.createElement("th", null, "VERBS"))), /*#__PURE__*/React.createElement("tbody", null, r.rules.map((rule, i) => /*#__PURE__*/React.createElement("tr", {
|
||
key: i
|
||
}, /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, rule[0]), /*#__PURE__*/React.createElement("td", {
|
||
style: mono
|
||
}, rule[1]), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: rule[2] === 'ALL' ? 'var(--color-danger)' : 'var(--text-secondary)',
|
||
font: 'var(--font-semibold) var(--text-2xs)/1 var(--font-mono)'
|
||
}
|
||
}, rule[2]))))))))), tab === 'settings' && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(3,1fr)',
|
||
gap: 14
|
||
}
|
||
}, SETTINGS.map(s => /*#__PURE__*/React.createElement(Card, {
|
||
key: s.key
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 8
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-semibold) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, s.name), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: s.tag === 'MODIFIED' ? 'primary' : 'neutral',
|
||
size: "sm"
|
||
}, s.tag)), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-xs)/1.5 var(--font-sans)',
|
||
color: 'var(--text-muted)',
|
||
margin: '8px 0'
|
||
}
|
||
}, s.desc), /*#__PURE__*/React.createElement("div", {
|
||
style: lbl
|
||
}, s.key), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 12
|
||
}
|
||
}, s.type === 'toggle' ? /*#__PURE__*/React.createElement(Switch, {
|
||
defaultChecked: s.on
|
||
}) : /*#__PURE__*/React.createElement(Input, {
|
||
defaultValue: s.val
|
||
})))))));
|
||
};
|
||
})();
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-admin.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-detail.jsx
|
||
try { (() => {
|
||
/* MONA Pass — ProjectDetail screen (overview / status / members / activity).
|
||
Demonstrates Tabs, StatCard, ProgressBar, StatusGrid, Timeline, RoleBadge,
|
||
ConfirmDialog (destructive delete with policy + type-to-confirm). */
|
||
(() => {
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
Tabs,
|
||
Card,
|
||
StatCard,
|
||
ProgressBar,
|
||
StatusGrid,
|
||
Timeline,
|
||
RoleBadge,
|
||
Badge,
|
||
Button,
|
||
Breadcrumb,
|
||
ConfirmDialog
|
||
} = NS;
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
const RES_LINKS = [{
|
||
name: 'ArgoCD',
|
||
url: 'https://argocd.sys.dev-mona.navercorp.com'
|
||
}, {
|
||
name: 'Grafana',
|
||
url: 'https://grafana.sys.dev-mona.navercorp.com/?orgId=769'
|
||
}, {
|
||
name: 'MLflow',
|
||
url: 'https://mona-demo-mlflow.sys.dev-mona.navercorp.com'
|
||
}, {
|
||
name: 'Airflow',
|
||
url: 'https://airflow.sys.dev-mona.navercorp.com/?project=mona-demo'
|
||
}];
|
||
const SYSTEMS = [{
|
||
name: 'ArgoCD',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'Grafana',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'Keycloak',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'Mimir',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'Namespace',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'NELO',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'OTel',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'S3',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'MLflow',
|
||
status: 'ok'
|
||
}, {
|
||
name: 'AiRSFlow',
|
||
status: 'ok'
|
||
}];
|
||
const MEMBERS = [{
|
||
name: '강창한',
|
||
email: 'changhan.kang@navercorp.com',
|
||
dept: 'Agent Platform'
|
||
}, {
|
||
name: '하재권',
|
||
email: 'jaekwon.ha@navercorp.com',
|
||
dept: 'Agent Platform'
|
||
}, {
|
||
name: '임지훈[ newry ]',
|
||
email: 'jeehoon.lim@navercorp.com',
|
||
dept: 'Agent Platform'
|
||
}, {
|
||
name: '김준석',
|
||
email: 'rock.kim@navercorp.com',
|
||
dept: 'Agent Platform'
|
||
}, {
|
||
name: '권서연',
|
||
email: 'seoyeon.kwon@navercorp.com',
|
||
dept: 'Agent Platform'
|
||
}];
|
||
const ACTIVITY = [{
|
||
title: '프로젝트 설정이 수정되었습니다.',
|
||
status: 'primary',
|
||
meta: 'jaekwon.ha@navercorp.com · 2026-06-12 10:13:32'
|
||
}, {
|
||
title: 'MODIFY 요청이 반려되었습니다. 사유: aa',
|
||
status: 'danger',
|
||
meta: 'jaekwon.ha@navercorp.com · 2026-06-12 07:26:08'
|
||
}, {
|
||
title: "'jaekwon.ha@navercorp.com'님이 admin 역할로 추가되었습니다.",
|
||
status: 'success',
|
||
meta: '2026-06-05 18:09:18'
|
||
}, {
|
||
title: "프로젝트 'mona-demo'가 생성되었습니다.",
|
||
status: 'success',
|
||
meta: 'jaekwon.ha@navercorp.com · 2026-05-27 19:53:18'
|
||
}];
|
||
function Quota({
|
||
icon,
|
||
label,
|
||
used,
|
||
hard,
|
||
variant
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: '120px 1fr',
|
||
gap: 14,
|
||
alignItems: 'center',
|
||
padding: '6px 0'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 7,
|
||
font: 'var(--font-medium) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)',
|
||
display: 'flex'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: icon,
|
||
size: 15
|
||
})), label), /*#__PURE__*/React.createElement(ProgressBar, {
|
||
value: used,
|
||
max: hard,
|
||
threshold: true,
|
||
valueText: `${used} / ${hard}`,
|
||
showValue: true,
|
||
size: "sm"
|
||
}));
|
||
}
|
||
window.PassProjectDetail = function ProjectDetail({
|
||
onBack
|
||
}) {
|
||
const [tab, setTab] = React.useState('overview');
|
||
const [del, setDel] = React.useState(false);
|
||
const [policy, setPolicy] = React.useState('delete');
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginBottom: 12
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Breadcrumb, {
|
||
items: [{
|
||
label: '프로젝트',
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "FolderOpen",
|
||
size: 14
|
||
}),
|
||
onClick: onBack
|
||
}, {
|
||
label: 'MONA - DEMO'
|
||
}]
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'flex-start',
|
||
gap: 14,
|
||
flexWrap: 'wrap'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 10
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "MONA - DEMO"), /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: "admin"
|
||
}), /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: "admin",
|
||
isPlatform: true
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-sm)/1.7 var(--font-mono)',
|
||
color: 'var(--text-muted)',
|
||
marginTop: 4
|
||
}
|
||
}, "ID: mona-demo")), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginLeft: 'auto',
|
||
display: 'flex',
|
||
gap: 8,
|
||
flexWrap: 'wrap'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Settings",
|
||
size: 14
|
||
})
|
||
}, "\uBCC0\uACBD \uC694\uCCAD"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Copy",
|
||
size: 14
|
||
})
|
||
}, "\uBCF5\uC81C \uC2E0\uCCAD"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "danger-outline",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Trash2",
|
||
size: 14
|
||
}),
|
||
onClick: () => setDel(true)
|
||
}, "\uC0AD\uC81C \uC694\uCCAD"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "ghost",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "LogOut",
|
||
size: 14
|
||
})
|
||
}, "\uD0C8\uD1F4"))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Tabs, {
|
||
value: tab,
|
||
onChange: setTab,
|
||
tabs: [{
|
||
id: 'overview',
|
||
label: '개요'
|
||
}, {
|
||
id: 'status',
|
||
label: '상태'
|
||
}, {
|
||
id: 'members',
|
||
label: '멤버',
|
||
count: MEMBERS.length
|
||
}, {
|
||
id: 'activity',
|
||
label: '활동 로그'
|
||
}]
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 20
|
||
}
|
||
}, tab === 'overview' && /*#__PURE__*/React.createElement("div", {
|
||
className: "col",
|
||
style: {
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Card, {
|
||
title: "\uB9AC\uC18C\uC2A4 \uB9C1\uD06C",
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Link",
|
||
size: 17
|
||
}))
|
||
}, RES_LINKS.map(r => /*#__PURE__*/React.createElement("div", {
|
||
key: r.name,
|
||
style: {
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'center',
|
||
padding: '7px 0',
|
||
borderBottom: '1px solid var(--color-border)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-medium) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, r.name), /*#__PURE__*/React.createElement("a", {
|
||
href: r.url,
|
||
onClick: e => e.preventDefault(),
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-xs)/1 var(--font-mono)',
|
||
color: 'var(--color-primary)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 5
|
||
}
|
||
}, r.url, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ExternalLink",
|
||
size: 12
|
||
}))))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(4,1fr)',
|
||
gap: 14
|
||
}
|
||
}, /*#__PURE__*/React.createElement(StatCard, {
|
||
size: "md",
|
||
label: "\uC18C\uC720 \uD300",
|
||
value: "Platform Team",
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Users",
|
||
size: 16
|
||
})
|
||
}), /*#__PURE__*/React.createElement(StatCard, {
|
||
size: "md",
|
||
label: "\uBA64\uBC84",
|
||
value: "5\uBA85",
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "User",
|
||
size: 16
|
||
})
|
||
}), /*#__PURE__*/React.createElement(StatCard, {
|
||
size: "md",
|
||
label: "\uD658\uACBD",
|
||
value: "1\uAC1C",
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Server",
|
||
size: 16
|
||
})
|
||
}), /*#__PURE__*/React.createElement(StatCard, {
|
||
size: "md",
|
||
label: "\uC0DD\uC131\uC77C",
|
||
value: "2026-05-27",
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Calendar",
|
||
size: 16
|
||
})
|
||
}))), tab === 'status' && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Card, {
|
||
title: "\uC2DC\uC2A4\uD15C \uC5F0\uB3D9",
|
||
headerActions: /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "success",
|
||
dot: true,
|
||
size: "sm"
|
||
}, "Synced")
|
||
}, /*#__PURE__*/React.createElement(StatusGrid, {
|
||
items: SYSTEMS
|
||
})), /*#__PURE__*/React.createElement(Card, {
|
||
title: "DEV \xB7 service-dev",
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Boxes",
|
||
size: 17
|
||
})),
|
||
headerActions: /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "success",
|
||
dot: true,
|
||
size: "sm"
|
||
}, "Synced")
|
||
}, /*#__PURE__*/React.createElement(Quota, {
|
||
icon: "Cpu",
|
||
label: "CPU",
|
||
used: 12,
|
||
hard: 96
|
||
}), /*#__PURE__*/React.createElement(Quota, {
|
||
icon: "MemoryStick",
|
||
label: "Memory",
|
||
used: 74,
|
||
hard: 96
|
||
}), /*#__PURE__*/React.createElement(Quota, {
|
||
icon: "Box",
|
||
label: "Pods",
|
||
used: 11,
|
||
hard: 25
|
||
}))), tab === 'members' && /*#__PURE__*/React.createElement(Card, {
|
||
flat: true,
|
||
tight: true
|
||
}, MEMBERS.map(m => /*#__PURE__*/React.createElement("div", {
|
||
key: m.email,
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 12,
|
||
padding: '11px 6px',
|
||
borderBottom: '1px solid var(--color-border)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
width: 32,
|
||
height: 32,
|
||
borderRadius: '50%',
|
||
display: 'grid',
|
||
placeItems: 'center',
|
||
background: 'var(--surface-sunken)',
|
||
color: 'var(--text-secondary)',
|
||
font: 'var(--font-semibold) var(--text-xs)/1 var(--font-sans)'
|
||
}
|
||
}, m.name.slice(0, 1)), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-medium) var(--text-sm)/1.3 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, m.name), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-xs)/1.3 var(--font-sans)',
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, m.email, " \xB7 ", m.dept)), /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: "admin"
|
||
}), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "ghost"
|
||
}, "\uAD00\uB9AC")))), tab === 'activity' && /*#__PURE__*/React.createElement(Card, {
|
||
title: "\uD65C\uB3D9 \uB85C\uADF8",
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Activity",
|
||
size: 17
|
||
}))
|
||
}, /*#__PURE__*/React.createElement(Timeline, {
|
||
items: ACTIVITY
|
||
}))), /*#__PURE__*/React.createElement(ConfirmDialog, {
|
||
open: del,
|
||
tone: "destructive",
|
||
title: "\uD504\uB85C\uC81D\uD2B8 \uC0AD\uC81C \uC694\uCCAD",
|
||
message: "\uC0AD\uC81C \uC815\uCC45\uC744 \uC120\uD0DD\uD558\uC138\uC694.",
|
||
policies: [{
|
||
value: 'delete',
|
||
label: 'Delete — 모든 Kubernetes 리소스 삭제',
|
||
description: 'Namespace, Deployment 등 모든 리소스가 영구적으로 삭제됩니다.',
|
||
danger: true
|
||
}, {
|
||
value: 'retain',
|
||
label: 'Retain — MONA Pass에서만 제거',
|
||
description: 'Kubernetes 리소스는 유지되고, 관리 목록에서만 제거됩니다.'
|
||
}],
|
||
policyValue: policy,
|
||
onPolicyChange: setPolicy,
|
||
confirmPhrase: "mona-demo",
|
||
confirmLabel: "\uC0AD\uC81C \uC694\uCCAD",
|
||
onConfirm: () => setDel(false),
|
||
onCancel: () => setDel(false)
|
||
}));
|
||
};
|
||
})();
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-detail.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-request-project.jsx
|
||
try { (() => {
|
||
/* MONA Pass — RequestProject form (single-scroll, numbered sections).
|
||
Demonstrates the family form pattern: Input/Select/Textarea/RadioGroup/
|
||
Switch/Checkbox/EnvChip/Button over DS tokens. No new primitives required. */
|
||
(() => {
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
Card,
|
||
Input,
|
||
Select,
|
||
Textarea,
|
||
RadioGroup,
|
||
Switch,
|
||
Checkbox,
|
||
Button,
|
||
Badge,
|
||
EnvChip,
|
||
Tabs
|
||
} = NS;
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
function Section({
|
||
n,
|
||
title,
|
||
badge,
|
||
toggle,
|
||
children
|
||
}) {
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
background: 'var(--surface-card)',
|
||
border: '1px solid var(--color-border)',
|
||
borderRadius: 'var(--radius-lg)',
|
||
boxShadow: 'var(--shadow-sm)',
|
||
padding: '22px 24px',
|
||
marginBottom: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 10,
|
||
marginBottom: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
width: 24,
|
||
height: 24,
|
||
borderRadius: '50%',
|
||
background: 'var(--text-body)',
|
||
color: 'var(--color-bg)',
|
||
display: 'grid',
|
||
placeItems: 'center',
|
||
font: 'var(--font-bold) var(--text-xs)/1 var(--font-sans)'
|
||
}
|
||
}, n), /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-bold) var(--text-md)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, title), badge, toggle && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginLeft: 'auto'
|
||
}
|
||
}, toggle)), children);
|
||
}
|
||
const labelStyle = {
|
||
display: 'block',
|
||
font: 'var(--font-medium) var(--text-xs)/1.4 var(--font-sans)',
|
||
color: 'var(--text-secondary)',
|
||
marginBottom: 6
|
||
};
|
||
const QuotaRow = ({
|
||
label,
|
||
value
|
||
}) => /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'space-between',
|
||
gap: 12,
|
||
padding: '9px 0',
|
||
borderBottom: '1px solid var(--color-border)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, label), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
width: 110
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Input, {
|
||
defaultValue: value,
|
||
style: {
|
||
textAlign: 'right'
|
||
}
|
||
})));
|
||
window.PassRequestProject = function RequestProject({
|
||
onCancel
|
||
}) {
|
||
const [size, setSize] = React.useState('small');
|
||
const [env, setEnv] = React.useState(true);
|
||
const [argo, setArgo] = React.useState(true);
|
||
const [airs, setAirs] = React.useState(true);
|
||
const [mlflow, setMlflow] = React.useState(true);
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg",
|
||
style: {
|
||
maxWidth: 980
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginBottom: 6,
|
||
font: 'var(--font-regular) var(--text-xs)/1 var(--font-sans)',
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("a", {
|
||
href: "#",
|
||
onClick: e => {
|
||
e.preventDefault();
|
||
onCancel && onCancel();
|
||
},
|
||
style: {
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, "\uC2E0\uCCAD"), " \u203A \uD504\uB85C\uC81D\uD2B8 \uC2E0\uCCAD"), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uD504\uB85C\uC81D\uD2B8 \uC2E0\uCCAD")), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__sub"
|
||
}, "\uC0C8 \uD504\uB85C\uC81D\uD2B8 \uD658\uACBD\uC744 \uAD6C\uC131\uD558\uACE0 \uB9AC\uC18C\uC2A4\uB97C \uD560\uB2F9\uD569\uB2C8\uB2E4."), /*#__PURE__*/React.createElement(Section, {
|
||
n: "1",
|
||
title: "\uAE30\uBCF8 \uC815\uBCF4"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: '1fr 1fr',
|
||
gap: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "Project ID *"), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 8
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
width: 110
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Select, {
|
||
options: [{
|
||
value: 'mona',
|
||
label: 'mona'
|
||
}, {
|
||
value: 'ad-ai',
|
||
label: 'ad-ai'
|
||
}]
|
||
})), /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, "\u2014"), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "my-ml-project"
|
||
}))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-2xs)/1.4 var(--font-mono)',
|
||
color: 'var(--text-muted)',
|
||
marginTop: 6
|
||
}
|
||
}, "\uCD5C\uC885 ID: mona-(\uC785\uB825)")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "Display Name *"), /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "ML \uCD94\uCC9C \uBAA8\uB378 \uD504\uB85C\uC81D\uD2B8"
|
||
}))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 16
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Textarea, {
|
||
label: "\uC124\uBA85",
|
||
placeholder: "\uD504\uB85C\uC81D\uD2B8 \uBAA9\uC801\uC774\uB098 \uC6A9\uB3C4\uB97C \uAC04\uB7B5\uD788 \uC124\uBA85\uD558\uC138\uC694"
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: '1fr 1fr',
|
||
gap: 18,
|
||
marginTop: 16
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "Owner *"), /*#__PURE__*/React.createElement(Input, {
|
||
defaultValue: "Platform Team"
|
||
})), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "Deletion Policy"), /*#__PURE__*/React.createElement(Select, {
|
||
options: [{
|
||
value: 'delete',
|
||
label: 'Delete (리소스 함께 삭제)'
|
||
}, {
|
||
value: 'retain',
|
||
label: 'Retain (리소스 유지)'
|
||
}]
|
||
})))), /*#__PURE__*/React.createElement(Section, {
|
||
n: "2",
|
||
title: "\uD658\uACBD \uBC0F \uB9AC\uC18C\uC2A4 \uC124\uC815",
|
||
badge: /*#__PURE__*/React.createElement(EnvChip, {
|
||
env: "dev",
|
||
dot: false
|
||
})
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 12,
|
||
background: 'var(--color-primary-subtle)',
|
||
border: '1px solid var(--color-border)',
|
||
borderRadius: 'var(--radius-md)',
|
||
padding: '14px 16px',
|
||
marginBottom: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Checkbox, {
|
||
checked: env,
|
||
onChange: e => setEnv(e.target.checked)
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-semibold) var(--text-sm)/1.3 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, "DEV \uD658\uACBD \uD65C\uC131\uD654"), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-xs)/1.4 var(--font-sans)',
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "k8s \uD074\uB7EC\uC2A4\uD130 DEV \uD658\uACBD\uC758 Namespace\xB7ResourceQuota\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.")), /*#__PURE__*/React.createElement(Switch, {
|
||
checked: env,
|
||
onChange: e => setEnv(e.target.checked)
|
||
})), /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "Resource Size"), /*#__PURE__*/React.createElement(Tabs, {
|
||
variant: "pill",
|
||
value: size,
|
||
onChange: setSize,
|
||
tabs: [{
|
||
id: 'small',
|
||
label: 'Small'
|
||
}, {
|
||
id: 'medium',
|
||
label: 'Medium'
|
||
}, {
|
||
id: 'large',
|
||
label: 'Large'
|
||
}, {
|
||
id: 'custom',
|
||
label: 'Custom'
|
||
}]
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: '1fr 1fr',
|
||
gap: 18,
|
||
marginTop: 16
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 8,
|
||
marginBottom: 6
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-semibold) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, "ResourceQuota"), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, "Namespace Limit")), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Requests CPU",
|
||
value: "96"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Requests Memory",
|
||
value: "96Gi"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Limits CPU",
|
||
value: "96"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Limits Memory",
|
||
value: "96Gi"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Ephemeral Storage",
|
||
value: "192Gi"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Max Pods",
|
||
value: "25"
|
||
})), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 8,
|
||
marginBottom: 6
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-semibold) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, "LimitRange"), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, "Per Pod/Container")), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Container CPU Default",
|
||
value: "4"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Container CPU Max",
|
||
value: "8"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Container Mem Default",
|
||
value: "4Gi"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Container Mem Max",
|
||
value: "16Gi"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Pod CPU Max",
|
||
value: "16"
|
||
}), /*#__PURE__*/React.createElement(QuotaRow, {
|
||
label: "Pod Mem Max",
|
||
value: "16Gi"
|
||
})))), /*#__PURE__*/React.createElement(Section, {
|
||
n: "3",
|
||
title: "ArgoCD \uC124\uC815",
|
||
toggle: /*#__PURE__*/React.createElement(Switch, {
|
||
checked: argo,
|
||
onChange: e => setArgo(e.target.checked)
|
||
})
|
||
}, argo && /*#__PURE__*/React.createElement(Textarea, {
|
||
label: "Source Repositories",
|
||
mono: true,
|
||
defaultValue: 'https://oss.navercorp.com/ad-ai/*\nhttps://oss.navercorp.com/mona/*',
|
||
hint: "ArgoCD Application\uC774 \uCC38\uC870\uD560 Git \uB808\uD3EC\uC9C0\uD1A0\uB9AC URL\uC744 \uC785\uB825\uD558\uC138\uC694 (\uC904\uBC14\uAFC8\uC73C\uB85C \uAD6C\uBD84)."
|
||
})), /*#__PURE__*/React.createElement(Section, {
|
||
n: "4",
|
||
title: "AiRSFlow \uC5F0\uB3D9",
|
||
toggle: /*#__PURE__*/React.createElement(Switch, {
|
||
checked: airs,
|
||
onChange: e => setAirs(e.target.checked)
|
||
})
|
||
}, airs && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "AIDA \uC778\uC99D"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ExternalLink",
|
||
size: 14
|
||
})
|
||
}, "AIDA \uB85C\uADF8\uC778"), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-xs)/1.5 var(--font-sans)',
|
||
color: 'var(--text-muted)',
|
||
margin: '8px 0 16px'
|
||
}
|
||
}, "\uBCF8\uC778 AIDA \uACC4\uC815\uC73C\uB85C \uB85C\uADF8\uC778\uD574 \uC778\uC99D \uC815\uBCF4\uB97C MONA Pass\uC5D0 \uC5F0\uB3D9\uD569\uB2C8\uB2E4."), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 8,
|
||
background: 'var(--color-warning-subtle)',
|
||
color: 'var(--color-warning)',
|
||
borderRadius: 'var(--radius-md)',
|
||
padding: '10px 13px',
|
||
font: 'var(--font-medium) var(--text-xs)/1.5 var(--font-sans)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Info",
|
||
size: 14
|
||
}), "AIDA \uC778\uC99D\uC744 \uC644\uB8CC\uD558\uBA74 \uC120\uD0DD\uD55C \uD504\uB85C\uC81D\uD2B8\uC758 AiRSFlow App \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC788\uC2B5\uB2C8\uB2E4."), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
gap: 8,
|
||
alignItems: 'flex-end',
|
||
marginTop: 14
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1
|
||
}
|
||
}, /*#__PURE__*/React.createElement("label", {
|
||
style: labelStyle
|
||
}, "\uC2E0\uADDC AiRSFlow App ", /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--text-muted)'
|
||
}
|
||
}, "\uAE30\uBCF8\uAC12: mona")), /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "mona"
|
||
})), /*#__PURE__*/React.createElement(Button, {
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Plus",
|
||
size: 14
|
||
})
|
||
}, "\uC2E0\uADDC \uC0DD\uC131")))), /*#__PURE__*/React.createElement(Section, {
|
||
n: "5",
|
||
title: "MLflow \uC5F0\uB3D9",
|
||
toggle: /*#__PURE__*/React.createElement(Switch, {
|
||
checked: mlflow,
|
||
onChange: e => setMlflow(e.target.checked)
|
||
})
|
||
}, mlflow && /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-sm)/1.6 var(--font-sans)',
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "\uD504\uB85C\uC81D\uD2B8 \uC804\uC6A9 MLflow \uC778\uC2A4\uD134\uC2A4\uB97C \uD504\uB85C\uBE44\uC800\uB2DD\uD569\uB2C8\uB2E4. \uC2E4\uD5D8\xB7run \uBA54\uD0C0\uB370\uC774\uD130\uB294 \uC804\uC6A9 DB, \uC544\uD2F0\uD329\uD2B8\uB294 \uACF5\uC720 S3(", /*#__PURE__*/React.createElement("code", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)'
|
||
}
|
||
}, '{project}/mlflow'), ")\uC5D0 \uC800\uC7A5\uB429\uB2C8\uB2E4.")), /*#__PURE__*/React.createElement(Section, {
|
||
n: "6",
|
||
title: "\uC2E0\uCCAD \uC0AC\uC720",
|
||
badge: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-danger)'
|
||
}
|
||
}, "*")
|
||
}, /*#__PURE__*/React.createElement(Textarea, {
|
||
placeholder: "\uD504\uB85C\uC81D\uD2B8 \uC0DD\uC131 \uBAA9\uC801 \uBC0F \uD544\uC694 \uB9AC\uC18C\uC2A4\uC5D0 \uB300\uD55C \uC124\uBA85\uC744 \uC785\uB825\uD558\uC138\uC694...",
|
||
required: true
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
justifyContent: 'flex-end',
|
||
gap: 10,
|
||
marginTop: 4
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
variant: "ghost",
|
||
onClick: onCancel
|
||
}, "\uCDE8\uC18C"), /*#__PURE__*/React.createElement(Button, {
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Send",
|
||
size: 15
|
||
}),
|
||
onClick: onCancel
|
||
}, "\uD504\uB85C\uC81D\uD2B8 \uC2E0\uCCAD")));
|
||
};
|
||
})();
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-request-project.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-requests.jsx
|
||
try { (() => {
|
||
/* MONA Pass — Requests (전체 공개 list + detail with Timeline). */
|
||
(() => {
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
Tabs,
|
||
Card,
|
||
Badge,
|
||
Button,
|
||
Input,
|
||
Select,
|
||
Pagination,
|
||
Timeline,
|
||
Table
|
||
} = NS;
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
const REQS = [{
|
||
id: 'REQ-2026-1252',
|
||
type: '생성',
|
||
title: '쇼핑예측모델 프로젝트 mona version',
|
||
who: '하재권 (jaekwon.ha@navercorp.com)',
|
||
date: '2026-06-13',
|
||
status: 'success',
|
||
label: '승인'
|
||
}, {
|
||
id: 'REQ-2026-1238',
|
||
type: '생성',
|
||
title: 'sadf',
|
||
who: '김준석 (rock.kim@navercorp.com)',
|
||
date: '2026-06-11',
|
||
status: 'success',
|
||
label: '승인'
|
||
}, {
|
||
id: 'REQ-2026-1235',
|
||
type: '생성',
|
||
title: 'jaekwon-20260608-1',
|
||
who: '하재권 (jaekwon.ha@navercorp.com)',
|
||
date: '2026-06-08',
|
||
status: 'neutral',
|
||
label: '삭제됨'
|
||
}, {
|
||
id: 'REQ-2026-1219',
|
||
type: '생성',
|
||
title: '광고주센터 api',
|
||
who: '박인영 (inyeong.park@navercorp.com)',
|
||
date: '2026-06-01',
|
||
status: 'success',
|
||
label: '승인'
|
||
}, {
|
||
id: 'REQ-2026-1218',
|
||
type: '생성',
|
||
title: '홈피드 쇼핑, da 분류 라우팅 모델',
|
||
who: '송승민 (seungmin.song@navercorp.com)',
|
||
date: '2026-05-28',
|
||
status: 'success',
|
||
label: '승인'
|
||
}, {
|
||
id: 'REQ-2026-1211',
|
||
type: '생성',
|
||
title: 'MONA - DEMO',
|
||
who: '하재권 (jaekwon.ha@navercorp.com)',
|
||
date: '2026-05-27',
|
||
status: 'success',
|
||
label: '승인'
|
||
}];
|
||
window.PassRequests = function Requests() {
|
||
const [scope, setScope] = React.useState('all');
|
||
const [sel, setSel] = React.useState(REQS[0]);
|
||
const [page, setPage] = React.useState(1);
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'flex-start'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uC2E0\uCCAD")), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__sub"
|
||
}, "\uC804\uCCB4 \uACF5\uAC1C \xB7 125\uAC74")), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginLeft: 'auto'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Plus",
|
||
size: 15
|
||
}),
|
||
onClick: () => window.__passOpenForm && window.__passOpenForm()
|
||
}, "\uC0C8 \uC2E0\uCCAD"))), /*#__PURE__*/React.createElement(Card, {
|
||
flat: true,
|
||
tight: true,
|
||
className: ""
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
gap: 12,
|
||
alignItems: 'center',
|
||
flexWrap: 'wrap'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Tabs, {
|
||
variant: "pill",
|
||
value: scope,
|
||
onChange: setScope,
|
||
tabs: [{
|
||
id: 'all',
|
||
label: '전체 공개'
|
||
}, {
|
||
id: 'mine',
|
||
label: '내 신청'
|
||
}]
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1,
|
||
minWidth: 180,
|
||
maxWidth: 320
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "\uAC80\uC0C9\u2026",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Search",
|
||
size: 15
|
||
})
|
||
})), /*#__PURE__*/React.createElement(Select, {
|
||
options: [{
|
||
value: 'all',
|
||
label: '모든 상태 (125)'
|
||
}, {
|
||
value: 'approved',
|
||
label: '승인'
|
||
}, {
|
||
value: 'pending',
|
||
label: '신청 중'
|
||
}]
|
||
}))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'grid',
|
||
gridTemplateColumns: '420px 1fr',
|
||
gap: 18,
|
||
alignItems: 'start',
|
||
marginTop: 16
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Card, {
|
||
flat: true,
|
||
tight: true
|
||
}, REQS.map(r => /*#__PURE__*/React.createElement("button", {
|
||
key: r.id,
|
||
onClick: () => setSel(r),
|
||
style: {
|
||
display: 'block',
|
||
width: '100%',
|
||
textAlign: 'left',
|
||
border: 0,
|
||
background: sel.id === r.id ? 'var(--color-primary-subtle)' : 'transparent',
|
||
borderLeft: '3px solid ' + (sel.id === r.id ? 'var(--color-primary)' : 'transparent'),
|
||
padding: '12px 14px',
|
||
cursor: 'pointer',
|
||
borderBottom: '1px solid var(--color-border)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 8
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-semibold) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, r.id), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: r.status,
|
||
size: "sm"
|
||
}, r.label)), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-medium) var(--text-sm)/1.4 var(--font-sans)',
|
||
color: 'var(--text-body)',
|
||
marginTop: 5
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, r.type), " ", r.title), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-xs)/1.4 var(--font-sans)',
|
||
color: 'var(--text-muted)',
|
||
marginTop: 4
|
||
}
|
||
}, r.who, " \xB7 ", r.date))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
padding: 12,
|
||
display: 'flex',
|
||
justifyContent: 'flex-end'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Pagination, {
|
||
page: page,
|
||
pageCount: 13,
|
||
onChange: setPage
|
||
}))), /*#__PURE__*/React.createElement(Card, null, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: 9
|
||
}
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
font: 'var(--font-bold) var(--text-lg)/1 var(--font-sans)',
|
||
color: 'var(--text-body)'
|
||
}
|
||
}, "#", sel.id), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: sel.status,
|
||
dot: true,
|
||
size: "sm"
|
||
}, sel.label)), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
font: 'var(--font-regular) var(--text-sm)/1.5 var(--font-sans)',
|
||
color: 'var(--text-secondary)',
|
||
marginTop: 6
|
||
}
|
||
}, "\uD504\uB85C\uC81D\uD2B8 \uC0DD\uC131 \xB7 ", sel.title), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 18,
|
||
font: 'var(--font-semibold) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)',
|
||
marginBottom: 10
|
||
}
|
||
}, "\uC2E0\uCCAD \uB0B4\uC6A9"), /*#__PURE__*/React.createElement(Table, {
|
||
hover: false
|
||
}, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "\uD658\uACBD"), /*#__PURE__*/React.createElement("th", null, "CPU"), /*#__PURE__*/React.createElement("th", null, "Memory"))), /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, "DEV"), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)'
|
||
}
|
||
}, "96 ~ 96"), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)'
|
||
}
|
||
}, "96Gi ~ 96Gi")))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 18,
|
||
font: 'var(--font-semibold) var(--text-sm)/1 var(--font-sans)',
|
||
color: 'var(--text-body)',
|
||
marginBottom: 12
|
||
}
|
||
}, "\uD0C0\uC784\uB77C\uC778"), /*#__PURE__*/React.createElement(Timeline, {
|
||
items: [{
|
||
title: '프로젝트 생성 완료',
|
||
status: 'success',
|
||
meta: '2026-06-13',
|
||
description: '→ mona-shoppingvm-v2'
|
||
}, {
|
||
title: '승인됨',
|
||
status: 'success',
|
||
meta: '하재권 · 2026-06-13'
|
||
}, {
|
||
title: '신청됨',
|
||
status: 'primary',
|
||
meta: '하재권 · 2026-06-13'
|
||
}]
|
||
}))));
|
||
};
|
||
})();
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens-requests.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
// uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens.jsx
|
||
try { (() => {
|
||
/* MONA Pass — interactive UI kit screens. Composes the family components. */
|
||
const NS = window.MONAFamilyDesignSystem_3cb9a3;
|
||
const {
|
||
AppHeader,
|
||
LoginScreen,
|
||
EnvBanner,
|
||
Card,
|
||
Button,
|
||
IconButton,
|
||
Badge,
|
||
RoleBadge,
|
||
EmptyState,
|
||
Tabs,
|
||
Table,
|
||
SortableHeader,
|
||
Pagination,
|
||
Input,
|
||
Modal,
|
||
Tooltip
|
||
} = NS;
|
||
|
||
/* ---- Lucide icon helper (real Lucide glyphs, not hand-rolled) ---- */
|
||
function Icon({
|
||
name,
|
||
size = 16,
|
||
stroke = 2,
|
||
...rest
|
||
}) {
|
||
const ico = window.lucide && window.lucide.icons && window.lucide.icons[name];
|
||
if (!ico) return null;
|
||
const kids = (ico[2] || []).map((c, i) => React.createElement(c[0], {
|
||
key: i,
|
||
...c[1]
|
||
}));
|
||
return React.createElement('svg', {
|
||
width: size,
|
||
height: size,
|
||
viewBox: '0 0 24 24',
|
||
fill: 'none',
|
||
stroke: 'currentColor',
|
||
strokeWidth: stroke,
|
||
strokeLinecap: 'round',
|
||
strokeLinejoin: 'round',
|
||
...rest
|
||
}, kids);
|
||
}
|
||
|
||
/* ---- Mock data ---- */
|
||
const PROJECTS = [{
|
||
id: 'ads',
|
||
name: '광고주센터 api',
|
||
ns: 'ads-api',
|
||
status: 'Synced',
|
||
role: 'developer',
|
||
members: 12,
|
||
env: 'dev'
|
||
}, {
|
||
id: 'demo',
|
||
name: 'MONA-DEMO',
|
||
ns: 'mona-demo',
|
||
status: 'OutOfSync',
|
||
role: 'admin',
|
||
members: 4,
|
||
env: 'dev'
|
||
}, {
|
||
id: 'swif',
|
||
name: 'swif',
|
||
ns: 'swif',
|
||
status: 'Provisioning',
|
||
role: 'viewer',
|
||
members: 7,
|
||
env: 'stage'
|
||
}, {
|
||
id: 'reco',
|
||
name: '추천 파이프라인',
|
||
ns: 'reco-pipe',
|
||
status: 'Synced',
|
||
role: 'developer',
|
||
members: 9,
|
||
env: 'prod'
|
||
}];
|
||
const REQUESTS = [{
|
||
id: 'REQ-2026-1252',
|
||
type: 'MODIFY',
|
||
status: 'warning',
|
||
label: '신청 중',
|
||
when: '2시간 전 · CPU 8→16'
|
||
}, {
|
||
id: 'REQ-2026-1248',
|
||
type: 'NEW',
|
||
status: 'success',
|
||
label: '승인됨',
|
||
when: '어제 · swif'
|
||
}, {
|
||
id: 'REQ-2026-1240',
|
||
type: 'DELETE',
|
||
status: 'danger',
|
||
label: '반려됨',
|
||
when: '3일 전 · tmp-test'
|
||
}];
|
||
const STATUS_VARIANT = {
|
||
Synced: 'success',
|
||
OutOfSync: 'warning',
|
||
Provisioning: 'info',
|
||
Terminating: 'danger'
|
||
};
|
||
|
||
/* ---- Stat card ---- */
|
||
function Stat({
|
||
label,
|
||
value,
|
||
icon,
|
||
accent
|
||
}) {
|
||
return /*#__PURE__*/React.createElement(Card, {
|
||
tight: true
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'flex-start'
|
||
}
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "stat__label"
|
||
}, label), /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: accent || 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: icon,
|
||
size: 18
|
||
}))), /*#__PURE__*/React.createElement("div", {
|
||
className: "stat__value"
|
||
}, value));
|
||
}
|
||
|
||
/* ---- Dashboard ---- */
|
||
function DashboardScreen() {
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uB300\uC2DC\uBCF4\uB4DC"), /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: "admin",
|
||
isPlatform: true
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__sub"
|
||
}, "\uB0B4 \uD504\uB85C\uC81D\uD2B8\uC640 \uD074\uB7EC\uC2A4\uD130 \uC811\uADFC \uD604\uD669\uC744 \uD55C\uB208\uC5D0 \uD655\uC778\uD558\uC138\uC694."), /*#__PURE__*/React.createElement("div", {
|
||
className: "grid-stat"
|
||
}, /*#__PURE__*/React.createElement(Stat, {
|
||
label: "\uB0B4 \uD504\uB85C\uC81D\uD2B8",
|
||
value: "4",
|
||
icon: "FolderOpen"
|
||
}), /*#__PURE__*/React.createElement(Stat, {
|
||
label: "\uC811\uADFC \uD074\uB7EC\uC2A4\uD130",
|
||
value: "3",
|
||
icon: "Server"
|
||
}), /*#__PURE__*/React.createElement(Stat, {
|
||
label: "\uC9C4\uD589 \uC911 \uC2E0\uCCAD",
|
||
value: "1",
|
||
icon: "ClipboardList",
|
||
accent: "var(--color-warning)"
|
||
}), /*#__PURE__*/React.createElement(Stat, {
|
||
label: "S3 \uBC84\uD0B7",
|
||
value: "6",
|
||
icon: "Database"
|
||
})), /*#__PURE__*/React.createElement("div", {
|
||
className: "dash"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "col"
|
||
}, /*#__PURE__*/React.createElement(Card, {
|
||
title: "Kubeconfig \uB2E4\uC6B4\uB85C\uB4DC",
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Download",
|
||
size: 18
|
||
})),
|
||
headerActions: /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm"
|
||
}, "\uC804\uCCB4 \uB2E4\uC6B4\uB85C\uB4DC")
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "muted"
|
||
}, "\uC811\uADFC \uAC00\uB2A5\uD55C \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uC120\uD0DD\uD574 kubeconfig\uB97C \uBC1C\uAE09\uD569\uB2C8\uB2E4."), /*#__PURE__*/React.createElement("div", {
|
||
className: "codebox"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "b"
|
||
}, "kubectl"), " config use-context ", /*#__PURE__*/React.createElement("span", {
|
||
className: "g"
|
||
}, "mona-demo"), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("span", {
|
||
className: "b"
|
||
}, "kubectl"), " get pods ", /*#__PURE__*/React.createElement("span", {
|
||
className: "g"
|
||
}, "-n mona-demo")), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
gap: 8,
|
||
marginTop: 12
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "info",
|
||
shape: "pill",
|
||
size: "sm",
|
||
dot: true
|
||
}, "dev \xB7 idc-a"), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "purple",
|
||
shape: "pill",
|
||
size: "sm",
|
||
dot: true
|
||
}, "platform"), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "info",
|
||
shape: "pill",
|
||
size: "sm",
|
||
dot: true
|
||
}, "stage \xB7 idc-b"))), /*#__PURE__*/React.createElement(Card, {
|
||
title: "S3 \uC561\uC138\uC2A4 \uD0A4",
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "KeyRound",
|
||
size: 18
|
||
})),
|
||
headerActions: /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "secondary",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "RefreshCw",
|
||
size: 14
|
||
})
|
||
}, "\uC0C8 \uD0A4 \uBC1C\uAE09")
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "Endpoint"), /*#__PURE__*/React.createElement("b", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)'
|
||
}
|
||
}, "s3.dev-mona.navercorp.com")), /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "Access Key"), /*#__PURE__*/React.createElement("b", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)'
|
||
}
|
||
}, "AKIA\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u20227Q2F")), /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uBC84\uD0B7"), /*#__PURE__*/React.createElement("b", null, "mpd-ads-api / mpd-reco"))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
||
className: "sectitle"
|
||
}, "\uB0B4 \uD504\uB85C\uC81D\uD2B8"), /*#__PURE__*/React.createElement("div", {
|
||
className: "projgrid"
|
||
}, PROJECTS.map(p => /*#__PURE__*/React.createElement(Card, {
|
||
key: p.id,
|
||
interactive: true,
|
||
onClick: () => window.__passOpenDetail && window.__passOpenDetail(),
|
||
icon: /*#__PURE__*/React.createElement("span", {
|
||
style: {
|
||
color: 'var(--color-primary)'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Boxes",
|
||
size: 18
|
||
})),
|
||
title: p.name,
|
||
headerActions: /*#__PURE__*/React.createElement(Badge, {
|
||
variant: STATUS_VARIANT[p.status],
|
||
dot: true,
|
||
size: "sm"
|
||
}, p.status)
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uB124\uC784\uC2A4\uD398\uC774\uC2A4"), /*#__PURE__*/React.createElement("b", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)'
|
||
}
|
||
}, p.ns)), /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uB0B4 \uC5ED\uD560"), /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: p.role
|
||
}))))))), /*#__PURE__*/React.createElement("div", {
|
||
className: "col"
|
||
}, /*#__PURE__*/React.createElement(Card, {
|
||
title: "\uCD5C\uADFC \uC2E0\uCCAD \uB0B4\uC5ED"
|
||
}, REQUESTS.map(r => /*#__PURE__*/React.createElement("div", {
|
||
className: "reqitem",
|
||
key: r.id
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "reqitem__top"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "reqitem__id"
|
||
}, r.id), /*#__PURE__*/React.createElement(Badge, {
|
||
variant: r.status,
|
||
size: "sm"
|
||
}, r.label)), /*#__PURE__*/React.createElement("div", {
|
||
className: "reqitem__meta"
|
||
}, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "neutral",
|
||
size: "sm"
|
||
}, r.type), " \xA0", r.when)))), /*#__PURE__*/React.createElement(Card, {
|
||
title: "\uCC38\uC5EC \uC694\uCCAD",
|
||
headerActions: /*#__PURE__*/React.createElement(Badge, {
|
||
variant: "warning",
|
||
size: "sm"
|
||
}, "2")
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uAE40\uB2E4\uC740 \u2192 ads-api"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "ghost"
|
||
}, "\uAC80\uD1A0")), /*#__PURE__*/React.createElement("div", {
|
||
className: "kv"
|
||
}, /*#__PURE__*/React.createElement("span", null, "\uC774\uC900\uD638 \u2192 reco-pipe"), /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "ghost"
|
||
}, "\uAC80\uD1A0"))))));
|
||
}
|
||
|
||
/* ---- Projects ---- */
|
||
function ProjectsScreen() {
|
||
const [seg, setSeg] = React.useState('mine');
|
||
const [sort, setSort] = React.useState({
|
||
key: 'name',
|
||
dir: 'asc'
|
||
});
|
||
const [page, setPage] = React.useState(1);
|
||
const set = key => dir => setSort({
|
||
key,
|
||
dir
|
||
});
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uD504\uB85C\uC81D\uD2B8")), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__sub"
|
||
}, "\uCC38\uC5EC \uC911\uC774\uAC70\uB098 \uC2E0\uCCAD \uAC00\uB2A5\uD55C \uD504\uB85C\uC81D\uD2B8\uB97C \uD0D0\uC0C9\uD558\uC138\uC694."), /*#__PURE__*/React.createElement("div", {
|
||
className: "toolbar"
|
||
}, /*#__PURE__*/React.createElement(Tabs, {
|
||
variant: "pill",
|
||
value: seg,
|
||
onChange: setSeg,
|
||
tabs: [{
|
||
id: 'mine',
|
||
label: '소속'
|
||
}, {
|
||
id: 'other',
|
||
label: '미소속'
|
||
}, {
|
||
id: 'all',
|
||
label: '전체'
|
||
}]
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
flex: 1
|
||
}
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
className: "toolbar__search"
|
||
}, /*#__PURE__*/React.createElement(Input, {
|
||
placeholder: "\uD504\uB85C\uC81D\uD2B8 \uAC80\uC0C9",
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Search",
|
||
size: 15
|
||
})
|
||
})), /*#__PURE__*/React.createElement(Button, {
|
||
leadingIcon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Plus",
|
||
size: 15
|
||
}),
|
||
onClick: () => window.__passOpenForm && window.__passOpenForm()
|
||
}, "\uC0C8 \uD504\uB85C\uC81D\uD2B8 \uC2E0\uCCAD")), /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement(SortableHeader, {
|
||
label: "\uD504\uB85C\uC81D\uD2B8",
|
||
direction: sort.key === 'name' ? sort.dir : 'none',
|
||
onSort: set('name')
|
||
}), /*#__PURE__*/React.createElement(SortableHeader, {
|
||
label: "\uB124\uC784\uC2A4\uD398\uC774\uC2A4",
|
||
direction: sort.key === 'ns' ? sort.dir : 'none',
|
||
onSort: set('ns')
|
||
}), /*#__PURE__*/React.createElement("th", null, "\uC0C1\uD0DC"), /*#__PURE__*/React.createElement("th", null, "\uC18C\uC720 \uD300"), /*#__PURE__*/React.createElement("th", null, "\uB0B4 \uC5ED\uD560"), /*#__PURE__*/React.createElement(SortableHeader, {
|
||
label: "\uBA64\uBC84",
|
||
align: "right",
|
||
direction: sort.key === 'm' ? sort.dir : 'none',
|
||
onSort: set('m')
|
||
}), /*#__PURE__*/React.createElement("th", null))), /*#__PURE__*/React.createElement("tbody", null, PROJECTS.map(p => /*#__PURE__*/React.createElement("tr", {
|
||
key: p.id
|
||
}, /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontWeight: 600
|
||
}
|
||
}, p.name), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
fontFamily: 'var(--font-mono)',
|
||
fontSize: 'var(--text-xs)',
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, p.ns), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Badge, {
|
||
variant: STATUS_VARIANT[p.status],
|
||
dot: true,
|
||
size: "sm"
|
||
}, p.status)), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
color: 'var(--text-secondary)'
|
||
}
|
||
}, "Platform Team"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(RoleBadge, {
|
||
role: p.role
|
||
})), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
textAlign: 'right'
|
||
}
|
||
}, p.members), /*#__PURE__*/React.createElement("td", {
|
||
style: {
|
||
textAlign: 'right'
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Button, {
|
||
size: "sm",
|
||
variant: "ghost",
|
||
onClick: () => window.__passOpenDetail && window.__passOpenDetail()
|
||
}, "\uC0C1\uC138")))))), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
display: 'flex',
|
||
justifyContent: 'flex-end',
|
||
marginTop: 16
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Pagination, {
|
||
page: page,
|
||
pageCount: 4,
|
||
total: 38,
|
||
pageSize: 10,
|
||
onChange: setPage
|
||
})));
|
||
}
|
||
|
||
/* ---- Admin ---- */
|
||
function AdminScreen() {
|
||
const [tab, setTab] = React.useState('pending');
|
||
const tabs = [{
|
||
id: 'pending',
|
||
label: '승인 대기',
|
||
count: 0
|
||
}, {
|
||
id: 'projects',
|
||
label: '프로젝트'
|
||
}, {
|
||
id: 'users',
|
||
label: '사용자'
|
||
}, {
|
||
id: 'clusters',
|
||
label: '클러스터'
|
||
}, {
|
||
id: 'roles',
|
||
label: '클러스터 롤'
|
||
}, {
|
||
id: 'audit',
|
||
label: '감사'
|
||
}, {
|
||
id: 'notice',
|
||
label: '공지'
|
||
}, {
|
||
id: 'settings',
|
||
label: '시스템 설정'
|
||
}];
|
||
return /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uAD00\uB9AC\uC790 \uCF58\uC194")), /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__sub"
|
||
}, "\uD074\uB7EC\uC2A4\uD130, \uC0AC\uC6A9\uC790, \uC2E0\uCCAD\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4."), /*#__PURE__*/React.createElement(Tabs, {
|
||
value: tab,
|
||
onChange: setTab,
|
||
tabs: tabs
|
||
}), /*#__PURE__*/React.createElement("div", {
|
||
style: {
|
||
marginTop: 18
|
||
}
|
||
}, /*#__PURE__*/React.createElement(Card, {
|
||
flat: true
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "admin-empty"
|
||
}, /*#__PURE__*/React.createElement(EmptyState, {
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Inbox",
|
||
size: 24
|
||
}),
|
||
title: "\uB300\uAE30 \uC911\uC778 \uC694\uCCAD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4",
|
||
description: "\uC0C8 \uD504\uB85C\uC81D\uD2B8\xB7\uC218\uC815\xB7\uC0AD\uC81C \uC2E0\uCCAD\uC774 \uB4E4\uC5B4\uC624\uBA74 \uC5EC\uAE30\uC5D0\uC11C \uC2B9\uC778\uD558\uAC70\uB098 \uBC18\uB824\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
|
||
})))));
|
||
}
|
||
|
||
/* ---- App shell ---- */
|
||
function PassApp() {
|
||
const [authed, setAuthed] = React.useState(false);
|
||
const [nav, setNav] = React.useState('dashboard');
|
||
const [view, setView] = React.useState(null); // null | 'detail'
|
||
const [theme, setTheme] = React.useState('light');
|
||
React.useEffect(() => {
|
||
document.documentElement.classList.toggle('dark', theme === 'dark');
|
||
}, [theme]);
|
||
React.useEffect(() => {
|
||
window.__passOpenDetail = () => setView('detail');
|
||
window.__passOpenForm = () => setView('form');
|
||
}, []);
|
||
if (!authed) {
|
||
return /*#__PURE__*/React.createElement(LoginScreen, {
|
||
logo: "../../assets/logos/pass.svg",
|
||
product: "Pass",
|
||
title: "Kubernetes \uAD8C\uD55C \uD1B5\uD569 \uAD00\uB9AC",
|
||
subtitle: "\uD504\uB85C\uC81D\uD2B8\uB97C \uC2E0\uCCAD\uD558\uACE0 \uC2B9\uC778\uBC1B\uC544 kubeconfig\xB7S3 \uD0A4\uB97C \uBC1C\uAE09\uD558\uC138\uC694.",
|
||
buttonLabel: "SSO \uB85C\uADF8\uC778",
|
||
onLogin: () => setAuthed(true),
|
||
note: /*#__PURE__*/React.createElement(React.Fragment, null, "OSS \uACC4\uC815\uC73C\uB85C \uB85C\uADF8\uC778\uD569\uB2C8\uB2E4 \xB7 ", /*#__PURE__*/React.createElement("a", {
|
||
href: "#",
|
||
onClick: e => e.preventDefault()
|
||
}, "\uB3C4\uC6C0\uB9D0"))
|
||
});
|
||
}
|
||
const externalLinks = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Tooltip, {
|
||
label: "REST API"
|
||
}, /*#__PURE__*/React.createElement(IconButton, {
|
||
"aria-label": "api"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Code",
|
||
size: 17
|
||
}))), /*#__PURE__*/React.createElement(Tooltip, {
|
||
label: "\uC774\uC288 \uB9AC\uD3EC\uD2B8"
|
||
}, /*#__PURE__*/React.createElement(IconButton, {
|
||
"aria-label": "issues"
|
||
}, /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Bug",
|
||
size: 17
|
||
}))));
|
||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(EnvBanner, {
|
||
env: "dev"
|
||
}), /*#__PURE__*/React.createElement(AppHeader, {
|
||
logo: "../../assets/logos/pass.svg",
|
||
product: "Pass",
|
||
nav: [{
|
||
id: 'dashboard',
|
||
label: '대시보드',
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "LayoutDashboard",
|
||
size: 15
|
||
})
|
||
}, {
|
||
id: 'projects',
|
||
label: '프로젝트',
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "FolderOpen",
|
||
size: 15
|
||
})
|
||
}, {
|
||
id: 'requests',
|
||
label: '신청',
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "ClipboardList",
|
||
size: 15
|
||
})
|
||
}, {
|
||
id: 'help',
|
||
label: '도움말',
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "BookOpen",
|
||
size: 15
|
||
})
|
||
}, {
|
||
id: 'admin',
|
||
label: '관리자',
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "Settings",
|
||
size: 15
|
||
})
|
||
}],
|
||
activeNav: nav,
|
||
onNav: id => {
|
||
setNav(id);
|
||
setView(null);
|
||
},
|
||
theme: theme,
|
||
onThemeToggle: () => setTheme(t => t === 'dark' ? 'light' : 'dark'),
|
||
rightExtra: externalLinks,
|
||
user: {
|
||
name: 'RK',
|
||
meta: 'Platform Team'
|
||
}
|
||
}), view === 'detail' ? /*#__PURE__*/React.createElement(window.PassProjectDetail, {
|
||
onBack: () => setView(null)
|
||
}) : view === 'form' ? /*#__PURE__*/React.createElement(window.PassRequestProject, {
|
||
onCancel: () => setView(null)
|
||
}) : /*#__PURE__*/React.createElement(React.Fragment, null, nav === 'dashboard' && /*#__PURE__*/React.createElement(DashboardScreen, null), nav === 'projects' && /*#__PURE__*/React.createElement(ProjectsScreen, null), nav === 'admin' && /*#__PURE__*/React.createElement(window.PassAdmin, null), nav === 'requests' && /*#__PURE__*/React.createElement(window.PassRequests, null), nav === 'help' && /*#__PURE__*/React.createElement("div", {
|
||
className: "pg"
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "pg__head"
|
||
}, /*#__PURE__*/React.createElement("span", {
|
||
className: "pg__title"
|
||
}, "\uB3C4\uC6C0\uB9D0")), /*#__PURE__*/React.createElement(Card, {
|
||
flat: true
|
||
}, /*#__PURE__*/React.createElement("div", {
|
||
className: "admin-empty"
|
||
}, /*#__PURE__*/React.createElement(EmptyState, {
|
||
icon: /*#__PURE__*/React.createElement(Icon, {
|
||
name: "BookOpen",
|
||
size: 24
|
||
}),
|
||
title: "\uB3C4\uC6C0\uB9D0 \uC13C\uD130",
|
||
description: "\uCE74\uD14C\uACE0\uB9AC \uAC00\uC774\uB4DC + \uB9C8\uD06C\uB2E4\uC6B4 \uBB38\uC11C(prose) \uD654\uBA74\uC740 \uB2E4\uC74C \uCC28\uC218\uC5D0 \uCD94\uAC00 \uC608\uC815\uC785\uB2C8\uB2E4."
|
||
}))))));
|
||
}
|
||
ReactDOM.createRoot(document.getElementById('root')).render(/*#__PURE__*/React.createElement(PassApp, null));
|
||
})(); } catch (e) { __ds_ns.__errors.push({ path: "uploads/MONA Family Design System-handoff/project/ui_kits/pass/screens.jsx", error: String((e && e.message) || e) }); }
|
||
|
||
__ds_ns.AppHeader = __ds_scope.AppHeader;
|
||
|
||
__ds_ns.LoginScreen = __ds_scope.LoginScreen;
|
||
|
||
__ds_ns.SortableHeader = __ds_scope.SortableHeader;
|
||
|
||
__ds_ns.Table = __ds_scope.Table;
|
||
|
||
__ds_ns.Badge = __ds_scope.Badge;
|
||
|
||
__ds_ns.EmptyState = __ds_scope.EmptyState;
|
||
|
||
__ds_ns.EnvChip = __ds_scope.EnvChip;
|
||
|
||
__ds_ns.ErrorState = __ds_scope.ErrorState;
|
||
|
||
__ds_ns.ProgressBar = __ds_scope.ProgressBar;
|
||
|
||
__ds_ns.RoleBadge = __ds_scope.RoleBadge;
|
||
|
||
__ds_ns.Skeleton = __ds_scope.Skeleton;
|
||
|
||
__ds_ns.StatusGrid = __ds_scope.StatusGrid;
|
||
|
||
__ds_ns.Timeline = __ds_scope.Timeline;
|
||
|
||
__ds_ns.Toast = __ds_scope.Toast;
|
||
|
||
__ds_ns.ToastStack = __ds_scope.ToastStack;
|
||
|
||
__ds_ns.Tooltip = __ds_scope.Tooltip;
|
||
|
||
__ds_ns.Button = __ds_scope.Button;
|
||
|
||
__ds_ns.Checkbox = __ds_scope.Checkbox;
|
||
|
||
__ds_ns.CodeBlock = __ds_scope.CodeBlock;
|
||
|
||
__ds_ns.CopyButton = __ds_scope.CopyButton;
|
||
|
||
__ds_ns.IconButton = __ds_scope.IconButton;
|
||
|
||
__ds_ns.Input = __ds_scope.Input;
|
||
|
||
__ds_ns.MaskedField = __ds_scope.MaskedField;
|
||
|
||
__ds_ns.RadioGroup = __ds_scope.RadioGroup;
|
||
|
||
__ds_ns.Select = __ds_scope.Select;
|
||
|
||
__ds_ns.Switch = __ds_scope.Switch;
|
||
|
||
__ds_ns.Textarea = __ds_scope.Textarea;
|
||
|
||
__ds_ns.Breadcrumb = __ds_scope.Breadcrumb;
|
||
|
||
__ds_ns.Pagination = __ds_scope.Pagination;
|
||
|
||
__ds_ns.ProjectSwitcher = __ds_scope.ProjectSwitcher;
|
||
|
||
__ds_ns.Tabs = __ds_scope.Tabs;
|
||
|
||
__ds_ns.Card = __ds_scope.Card;
|
||
|
||
__ds_ns.ConfirmDialog = __ds_scope.ConfirmDialog;
|
||
|
||
__ds_ns.EnvBanner = __ds_scope.EnvBanner;
|
||
|
||
__ds_ns.Modal = __ds_scope.Modal;
|
||
|
||
__ds_ns.StatCard = __ds_scope.StatCard;
|
||
|
||
})();
|