@kiteapps/lite-ui 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -2
- package/dist/index.cjs +792 -0
- package/dist/index.css +2070 -0
- package/dist/index.mjs +760 -0
- package/dist/pages.cjs +1319 -0
- package/dist/pages.css +2070 -0
- package/dist/pages.mjs +1287 -0
- package/package.json +53 -4
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,760 @@
|
|
|
1
|
+
// src/widgets/Primitives.jsx
|
|
2
|
+
import React, { useId, useState } from "react";
|
|
3
|
+
import { CircleHelp, Info, X } from "lucide-react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function Button({ children, variant = "neutral", icon: Icon, className = "", ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsxs("button", { className: `ad-button ad-button--${variant} ${className}`, ...props, children: [
|
|
7
|
+
Icon && /* @__PURE__ */ jsx(Icon, { size: 13, strokeWidth: 1.8 }),
|
|
8
|
+
children
|
|
9
|
+
] });
|
|
10
|
+
}
|
|
11
|
+
function IconButton({ icon: Icon, label, ...props }) {
|
|
12
|
+
return /* @__PURE__ */ jsx("button", { type: "button", className: "ad-icon-button", "aria-label": label, title: label, ...props, children: /* @__PURE__ */ jsx(Icon, { size: 15, strokeWidth: 1.8 }) });
|
|
13
|
+
}
|
|
14
|
+
function TextField({ label, hint, id, className = "", ...props }) {
|
|
15
|
+
const generated = useId();
|
|
16
|
+
const inputId = id || generated;
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", { className: `ad-field ${className}`, children: [
|
|
18
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, children: label }),
|
|
19
|
+
/* @__PURE__ */ jsx("input", { id: inputId, className: "ad-input", ...props }),
|
|
20
|
+
hint && /* @__PURE__ */ jsx("span", { className: "ad-hint", children: hint })
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
function SelectField({ label, options = [], value, onChange, className = "", ...props }) {
|
|
24
|
+
const id = useId();
|
|
25
|
+
return /* @__PURE__ */ jsxs("div", { className: `ad-field ${className}`, children: [
|
|
26
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id, children: label }),
|
|
27
|
+
/* @__PURE__ */ jsx("select", { id, className: "ad-select", value, onChange, ...props, children: options.map((option) => {
|
|
28
|
+
const item = typeof option === "string" ? { value: option, label: option } : option;
|
|
29
|
+
return /* @__PURE__ */ jsx("option", { value: item.value, children: item.label }, item.value);
|
|
30
|
+
}) })
|
|
31
|
+
] });
|
|
32
|
+
}
|
|
33
|
+
function CheckRow({ children, defaultChecked = false, checked, onChange, disabled = false, help, className = "" }) {
|
|
34
|
+
const [local, setLocal] = useState(defaultChecked);
|
|
35
|
+
const isChecked = checked === void 0 ? local : checked;
|
|
36
|
+
return /* @__PURE__ */ jsxs("label", { className: `ad-check-row ${disabled ? "is-disabled" : ""} ${className}`, children: [
|
|
37
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: isChecked, disabled, onChange: (e) => {
|
|
38
|
+
setLocal(e.target.checked);
|
|
39
|
+
onChange?.(e.target.checked);
|
|
40
|
+
} }),
|
|
41
|
+
/* @__PURE__ */ jsx("span", { className: "ad-check-box", "aria-hidden": "true" }),
|
|
42
|
+
/* @__PURE__ */ jsx("span", { children }),
|
|
43
|
+
help && /* @__PURE__ */ jsx(HelpTip, { text: help })
|
|
44
|
+
] });
|
|
45
|
+
}
|
|
46
|
+
function RadioRow({ name, value, checked, onChange, children, disabled }) {
|
|
47
|
+
return /* @__PURE__ */ jsxs("label", { className: `ad-radio-row ${disabled ? "is-disabled" : ""}`, children: [
|
|
48
|
+
/* @__PURE__ */ jsx("input", { type: "radio", name, value, checked, disabled, onChange: () => onChange?.(value) }),
|
|
49
|
+
/* @__PURE__ */ jsx("span", { className: "ad-radio-mark", "aria-hidden": "true" }),
|
|
50
|
+
children
|
|
51
|
+
] });
|
|
52
|
+
}
|
|
53
|
+
function HelpTip({ text }) {
|
|
54
|
+
return /* @__PURE__ */ jsx("span", { className: "ad-help", title: text, "aria-label": text, children: /* @__PURE__ */ jsx(CircleHelp, { size: 12 }) });
|
|
55
|
+
}
|
|
56
|
+
function TextLink({ children, onClick, ...props }) {
|
|
57
|
+
return /* @__PURE__ */ jsx("button", { type: "button", className: "ad-text-link", onClick, ...props, children });
|
|
58
|
+
}
|
|
59
|
+
function Tabs({ tabs = [], active, onChange, ariaLabel = "Tabs" }) {
|
|
60
|
+
return /* @__PURE__ */ jsx("div", { className: "ad-tabs", role: "tablist", "aria-label": ariaLabel, children: tabs.map((raw) => {
|
|
61
|
+
const tab = typeof raw === "string" ? { id: raw, label: raw } : raw;
|
|
62
|
+
return /* @__PURE__ */ jsx("button", { type: "button", className: `ad-tab ${tab.id === active ? "is-active" : ""}`, role: "tab", "aria-selected": tab.id === active, onClick: () => onChange?.(tab.id, tab), children: tab.label }, tab.id);
|
|
63
|
+
}) });
|
|
64
|
+
}
|
|
65
|
+
function PageHeader({ title, action, help }) {
|
|
66
|
+
return /* @__PURE__ */ jsxs("div", { className: "ad-page-header", children: [
|
|
67
|
+
/* @__PURE__ */ jsxs("h1", { children: [
|
|
68
|
+
title,
|
|
69
|
+
" ",
|
|
70
|
+
help && /* @__PURE__ */ jsx(HelpTip, { text: help })
|
|
71
|
+
] }),
|
|
72
|
+
action && /* @__PURE__ */ jsx("div", { className: "ad-header-action", children: action })
|
|
73
|
+
] });
|
|
74
|
+
}
|
|
75
|
+
function Panel({ children, className = "" }) {
|
|
76
|
+
return /* @__PURE__ */ jsx("section", { className: `ad-panel ${className}`, children });
|
|
77
|
+
}
|
|
78
|
+
function SectionTitle({ children }) {
|
|
79
|
+
return /* @__PURE__ */ jsx("h2", { className: "ad-section-title", children });
|
|
80
|
+
}
|
|
81
|
+
function FormRow({ label, children, required = false, hint }) {
|
|
82
|
+
return /* @__PURE__ */ jsxs("div", { className: "ad-form-row", children: [
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: "ad-form-label", children: [
|
|
84
|
+
required && /* @__PURE__ */ jsx("b", { children: "* " }),
|
|
85
|
+
label
|
|
86
|
+
] }),
|
|
87
|
+
/* @__PURE__ */ jsxs("div", { className: "ad-form-control", children: [
|
|
88
|
+
children,
|
|
89
|
+
hint && /* @__PURE__ */ jsx("div", { className: "ad-hint", children: hint })
|
|
90
|
+
] })
|
|
91
|
+
] });
|
|
92
|
+
}
|
|
93
|
+
function ActionBar({ onSave, onCancel, saveLabel = "Save", cancelLabel = "Cancel", status }) {
|
|
94
|
+
return /* @__PURE__ */ jsxs("div", { className: "ad-action-bar", children: [
|
|
95
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: onSave, children: saveLabel }),
|
|
96
|
+
onCancel && /* @__PURE__ */ jsx(Button, { onClick: onCancel, children: cancelLabel }),
|
|
97
|
+
status && /* @__PURE__ */ jsx("span", { className: "ad-status", role: "status", children: status })
|
|
98
|
+
] });
|
|
99
|
+
}
|
|
100
|
+
function Notice({ children, tone = "info" }) {
|
|
101
|
+
return /* @__PURE__ */ jsxs("div", { className: `ad-notice ad-notice--${tone}`, children: [
|
|
102
|
+
/* @__PURE__ */ jsx(Info, { size: 15 }),
|
|
103
|
+
/* @__PURE__ */ jsx("div", { children })
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
function DataTable({ columns = [], rows = [], empty = "No Data Available", onRowClick, getRowId = (row, index) => row.id ?? index }) {
|
|
107
|
+
return /* @__PURE__ */ jsx("div", { className: "ad-table-wrap", children: /* @__PURE__ */ jsxs("table", { className: "ad-table", children: [
|
|
108
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((raw, index) => {
|
|
109
|
+
const column = typeof raw === "string" ? { key: index, label: raw } : raw;
|
|
110
|
+
return /* @__PURE__ */ jsx("th", { children: column.label }, column.key ?? index);
|
|
111
|
+
}) }) }),
|
|
112
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.length ? rows.map((row, index) => /* @__PURE__ */ jsx("tr", { onClick: () => onRowClick?.(row, index), children: columns.map((raw, columnIndex) => {
|
|
113
|
+
const column = typeof raw === "string" ? { key: columnIndex, label: raw } : raw;
|
|
114
|
+
return /* @__PURE__ */ jsx("td", { children: column.render ? column.render(row, index) : Array.isArray(row) ? row[columnIndex] : row[column.key] }, column.key ?? columnIndex);
|
|
115
|
+
}) }, getRowId(row, index))) : /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { className: "ad-empty", colSpan: columns.length, children: empty }) }) })
|
|
116
|
+
] }) });
|
|
117
|
+
}
|
|
118
|
+
function Modal({ title, children, open, onClose, footer, closeLabel = "Close" }) {
|
|
119
|
+
if (!open) return null;
|
|
120
|
+
return /* @__PURE__ */ jsx("div", { className: "ad-modal-backdrop", onMouseDown: onClose, children: /* @__PURE__ */ jsxs("div", { className: "ad-modal", role: "dialog", "aria-modal": "true", "aria-label": title, onMouseDown: (e) => e.stopPropagation(), children: [
|
|
121
|
+
/* @__PURE__ */ jsxs("div", { className: "ad-modal-head", children: [
|
|
122
|
+
/* @__PURE__ */ jsx("strong", { children: title }),
|
|
123
|
+
/* @__PURE__ */ jsx(IconButton, { icon: X, label: closeLabel, onClick: onClose })
|
|
124
|
+
] }),
|
|
125
|
+
/* @__PURE__ */ jsx("div", { className: "ad-modal-body", children }),
|
|
126
|
+
footer && /* @__PURE__ */ jsx("div", { className: "ad-modal-footer", children: footer })
|
|
127
|
+
] }) });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/widgets/Shell.jsx
|
|
131
|
+
import React2, { useEffect, useState as useState2 } from "react";
|
|
132
|
+
import { Bell, ChevronDown, ChevronRight, Download, Grid3X3, Search, Settings, UserRound } from "lucide-react";
|
|
133
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
134
|
+
var MAIN_SECTIONS = ["Dashboard", "Reports", "Configuration", "Admin", "Support"];
|
|
135
|
+
var FOOTER_LINKS = ["Admin Guide", "Need Features", "Report an Issue", "User Forums", "Toll free : +1-844-245-1104", "Direct Phone : +1-408-916-9890"];
|
|
136
|
+
function TopNavigation({ sections = MAIN_SECTIONS, active = "Admin", onChange, ariaLabel = "Main navigation" }) {
|
|
137
|
+
return /* @__PURE__ */ jsx2("nav", { className: "ad-main-nav", "aria-label": ariaLabel, children: sections.map((raw) => {
|
|
138
|
+
const section = typeof raw === "string" ? { id: raw, label: raw } : raw;
|
|
139
|
+
return /* @__PURE__ */ jsx2("button", { type: "button", className: section.id === active ? "is-active" : "", "aria-current": section.id === active ? "page" : void 0, onClick: () => onChange?.(section.id, section), children: section.label }, section.id);
|
|
140
|
+
}) });
|
|
141
|
+
}
|
|
142
|
+
function ShellHeader({ brand = "ADSelfService Plus", brandIcon, showBrandOrbit = true, sections = MAIN_SECTIONS, navigationLabel = "Main navigation", activeSection = "Admin", onSectionChange, directories = ["Active Directory", "Microsoft Entra ID"], directory, defaultDirectory, onDirectoryChange, showDownload = true, downloadLabel = "Download Now", onDownload, utilityItems = ["License", "Talk Back"], showNotifications = true, notifications = 2, notificationLabel, onNotificationsClick, showUserMenu = true, userMenuLabel = "User menu", onUserClick, showSearch = true, searchPlaceholder = "Search Employee", searchLabel = "Search Employee", searchValue, onSearchChange, showSettings = true, settingsLabel = "Domain Settings", onSettingsClick, rightContent }) {
|
|
143
|
+
const [localDirectory, setLocalDirectory] = useState2(defaultDirectory ?? directories[0]);
|
|
144
|
+
const [localSearch, setLocalSearch] = useState2("");
|
|
145
|
+
const currentDirectory = directory ?? localDirectory;
|
|
146
|
+
const directoryItem = directories.find((item) => (typeof item === "string" ? item : item.value) === currentDirectory);
|
|
147
|
+
const currentDirectoryLabel = typeof directoryItem === "string" ? directoryItem : directoryItem?.label || currentDirectory;
|
|
148
|
+
const currentSearch = searchValue ?? localSearch;
|
|
149
|
+
const switchDirectory = () => {
|
|
150
|
+
const index = directories.findIndex((item) => (typeof item === "string" ? item : item.value) === currentDirectory);
|
|
151
|
+
const next = directories[(index + 1) % directories.length];
|
|
152
|
+
const value = typeof next === "string" ? next : next?.value;
|
|
153
|
+
if (directory === void 0) setLocalDirectory(value);
|
|
154
|
+
onDirectoryChange?.(value, next);
|
|
155
|
+
};
|
|
156
|
+
return /* @__PURE__ */ jsxs2("header", { className: "ad-header", children: [
|
|
157
|
+
/* @__PURE__ */ jsxs2("div", { className: "ad-header-top", children: [
|
|
158
|
+
/* @__PURE__ */ jsxs2("div", { className: "ad-brand", children: [
|
|
159
|
+
brandIcon === void 0 ? /* @__PURE__ */ jsx2(Grid3X3, { size: 19, strokeWidth: 2.4 }) : brandIcon,
|
|
160
|
+
/* @__PURE__ */ jsx2("span", { children: brand }),
|
|
161
|
+
showBrandOrbit && /* @__PURE__ */ jsx2("span", { className: "ad-brand-orbit" })
|
|
162
|
+
] }),
|
|
163
|
+
directories.length > 0 && /* @__PURE__ */ jsxs2("button", { type: "button", className: "ad-directory", onClick: switchDirectory, children: [
|
|
164
|
+
currentDirectoryLabel,
|
|
165
|
+
/* @__PURE__ */ jsx2(ChevronDown, { size: 12 })
|
|
166
|
+
] }),
|
|
167
|
+
showDownload && /* @__PURE__ */ jsx2(Button, { variant: "download", icon: Download, onClick: onDownload, children: downloadLabel }),
|
|
168
|
+
/* @__PURE__ */ jsxs2("div", { className: "ad-header-right", children: [
|
|
169
|
+
utilityItems.map((raw, index) => {
|
|
170
|
+
const item = typeof raw === "string" ? { label: raw } : raw;
|
|
171
|
+
return /* @__PURE__ */ jsx2("button", { type: "button", onClick: () => item.onClick?.(item), children: item.label }, item.id ?? item.label ?? index);
|
|
172
|
+
}),
|
|
173
|
+
showNotifications && /* @__PURE__ */ jsxs2("button", { type: "button", className: "ad-bell", "aria-label": notificationLabel || `${notifications} notifications`, onClick: onNotificationsClick, children: [
|
|
174
|
+
/* @__PURE__ */ jsx2(Bell, { size: 14 }),
|
|
175
|
+
notifications > 0 && /* @__PURE__ */ jsx2("i", { children: notifications })
|
|
176
|
+
] }),
|
|
177
|
+
showUserMenu && /* @__PURE__ */ jsxs2("button", { type: "button", "aria-label": userMenuLabel, onClick: onUserClick, children: [
|
|
178
|
+
/* @__PURE__ */ jsx2(UserRound, { size: 16 }),
|
|
179
|
+
/* @__PURE__ */ jsx2(ChevronDown, { size: 11 })
|
|
180
|
+
] }),
|
|
181
|
+
rightContent
|
|
182
|
+
] })
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsxs2("div", { className: "ad-header-bottom", children: [
|
|
185
|
+
/* @__PURE__ */ jsx2(TopNavigation, { sections, ariaLabel: navigationLabel, active: activeSection, onChange: onSectionChange }),
|
|
186
|
+
showSearch && /* @__PURE__ */ jsxs2("div", { className: "ad-header-search", children: [
|
|
187
|
+
/* @__PURE__ */ jsx2(Search, { size: 12 }),
|
|
188
|
+
/* @__PURE__ */ jsx2("input", { "aria-label": searchLabel, placeholder: searchPlaceholder, value: currentSearch, onChange: (event) => {
|
|
189
|
+
if (searchValue === void 0) setLocalSearch(event.target.value);
|
|
190
|
+
onSearchChange?.(event.target.value);
|
|
191
|
+
} })
|
|
192
|
+
] }),
|
|
193
|
+
showSettings && /* @__PURE__ */ jsxs2("button", { type: "button", className: "ad-domain-settings", onClick: onSettingsClick, children: [
|
|
194
|
+
/* @__PURE__ */ jsx2(Settings, { size: 12 }),
|
|
195
|
+
" ",
|
|
196
|
+
settingsLabel
|
|
197
|
+
] })
|
|
198
|
+
] })
|
|
199
|
+
] });
|
|
200
|
+
}
|
|
201
|
+
function CollapsibleSidebar({ groups = [], selected, defaultSelected, onSelect, initialOpen, open, onOpenChange, ariaLabel = "Section pages" }) {
|
|
202
|
+
const [localSelected, setLocalSelected] = useState2(defaultSelected ?? groups[0]?.items[0]?.id);
|
|
203
|
+
const currentSelected = selected ?? localSelected;
|
|
204
|
+
const selectedGroup = groups.find((group) => group.items.some((item) => item.id === currentSelected))?.label;
|
|
205
|
+
const [openGroup, setOpenGroup] = useState2(initialOpen || selectedGroup || groups[0]?.label || "");
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
if (selectedGroup) setOpenGroup(selectedGroup);
|
|
208
|
+
}, [selectedGroup]);
|
|
209
|
+
const expanded = open ?? openGroup;
|
|
210
|
+
return /* @__PURE__ */ jsx2("nav", { "aria-label": ariaLabel, children: groups.map((group) => /* @__PURE__ */ jsxs2("div", { className: "ad-nav-group", children: [
|
|
211
|
+
/* @__PURE__ */ jsxs2("button", { type: "button", className: "ad-nav-heading", onClick: () => {
|
|
212
|
+
const next = expanded === group.label ? "" : group.label;
|
|
213
|
+
if (open === void 0) setOpenGroup(next);
|
|
214
|
+
onOpenChange?.(next, group);
|
|
215
|
+
}, "aria-expanded": expanded === group.label, children: [
|
|
216
|
+
group.label,
|
|
217
|
+
expanded === group.label ? /* @__PURE__ */ jsx2(ChevronDown, { size: 12 }) : /* @__PURE__ */ jsx2(ChevronRight, { size: 12 })
|
|
218
|
+
] }),
|
|
219
|
+
expanded === group.label && /* @__PURE__ */ jsx2("div", { className: "ad-nav-items", children: group.items.map((item) => /* @__PURE__ */ jsx2("button", { type: "button", className: `ad-nav-item ${currentSelected === item.id ? "is-active" : ""}`, "aria-current": currentSelected === item.id ? "page" : void 0, onClick: () => {
|
|
220
|
+
if (selected === void 0) setLocalSelected(item.id);
|
|
221
|
+
onSelect?.(item.id, item);
|
|
222
|
+
}, children: item.label }, item.id)) })
|
|
223
|
+
] }, group.id ?? group.label)) });
|
|
224
|
+
}
|
|
225
|
+
function ShellFooter({ items = FOOTER_LINKS, onItemSelect, children }) {
|
|
226
|
+
return /* @__PURE__ */ jsxs2("footer", { className: "ad-footer", children: [
|
|
227
|
+
items.map((raw, index) => {
|
|
228
|
+
const item = typeof raw === "string" ? { id: raw, label: raw } : raw;
|
|
229
|
+
return item.href ? /* @__PURE__ */ jsx2("a", { href: item.href, children: item.label }, item.id ?? index) : /* @__PURE__ */ jsx2("button", { type: "button", onClick: () => onItemSelect?.(item.id, item), children: item.label }, item.id ?? index);
|
|
230
|
+
}),
|
|
231
|
+
children
|
|
232
|
+
] });
|
|
233
|
+
}
|
|
234
|
+
function AppShell({ activeSection = "Admin", onSectionChange, sidebar, sidebarLabel, hideSidebar = false, mainClassName = "", headerProps = {}, footerProps = {}, header, footer, children }) {
|
|
235
|
+
return /* @__PURE__ */ jsxs2("div", { className: "ad-shell", children: [
|
|
236
|
+
header || /* @__PURE__ */ jsx2(ShellHeader, { ...headerProps, activeSection, onSectionChange }),
|
|
237
|
+
/* @__PURE__ */ jsxs2("div", { className: "ad-workspace", children: [
|
|
238
|
+
!hideSidebar && /* @__PURE__ */ jsx2("aside", { className: "ad-sidebar", "aria-label": sidebarLabel || `${activeSection} navigation`, children: sidebar }),
|
|
239
|
+
/* @__PURE__ */ jsx2("main", { className: `ad-main ${mainClassName}`, children })
|
|
240
|
+
] }),
|
|
241
|
+
footer || /* @__PURE__ */ jsx2(ShellFooter, { ...footerProps })
|
|
242
|
+
] });
|
|
243
|
+
}
|
|
244
|
+
function AdminShell({ groups = [], screen, onScreenChange, children, activeSection = "Admin", onSectionChange, sidebar, hideSidebar = false, mainClassName = "", ...shellProps }) {
|
|
245
|
+
return /* @__PURE__ */ jsx2(AppShell, { activeSection, onSectionChange, sidebar: sidebar || /* @__PURE__ */ jsx2(CollapsibleSidebar, { groups, selected: screen, onSelect: onScreenChange }), hideSidebar, mainClassName, ...shellProps, children });
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/widgets/DashboardWidgets.jsx
|
|
249
|
+
import React3, { useState as useState3 } from "react";
|
|
250
|
+
import { Clock3, UserRoundPlus, Files, AppWindow, Maximize2, MoreHorizontal, RefreshCw, Settings as Settings2, X as X2 } from "lucide-react";
|
|
251
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
252
|
+
var DASHBOARD_METRICS = [
|
|
253
|
+
{ title: "Password Expiration", value: "0 / 62", caption: "Soon-to-expire / Expired Passwords", icon: Clock3, tone: "rose", report: "4" },
|
|
254
|
+
{ title: "Enrollment Status", value: "37 / 38", caption: "Enrolled / Non Enrolled Users", icon: UserRoundPlus, tone: "blue", report: "15" },
|
|
255
|
+
{ title: "License Usage", value: "59 / 4941", caption: "Used / Remaining Licenses", icon: Files, tone: "orange", report: "17" },
|
|
256
|
+
{ title: "Endpoint MFA", value: "1 / 4999", caption: "Used / Remaining Licenses", icon: AppWindow, tone: "green", report: "301" }
|
|
257
|
+
];
|
|
258
|
+
var DASHBOARD_SHORTCUTS = [
|
|
259
|
+
{ title: "Highlights", links: ["Password Reset / Unlock Account", "Self Update/Change Password", "Password Expiry Notification", "Password Sync/Single Sign On", "Conditional Access"] },
|
|
260
|
+
{ title: "Multi-factor Authentication", links: ["Security Question & Answer", "Email Verification", "SMS Verification", "Google Authenticator", "Microsoft Authenticator", "Microsoft Entra ID MFA", "Duo Security", "RSA SecurID", "RADIUS Authentication", "Push Notification Authentication", "Biometric Authentication", "QR Code Based Authentication", "TOTP Authentication", "SAML Authentication", "AD Security Questions", "Yubikey Authenticator", "Zoho OneAuth TOTP", "Smart Card Authentication", "Custom TOTP Authenticator", "FIDO2 Passkeys"] },
|
|
261
|
+
{ title: "Other Features", links: ["Mobile App Deployment", "Employee Search/Org Chart", "Mail Group Subscription", "Self-Service Approval Workflow", "Update Cached Credential"] },
|
|
262
|
+
{ title: "Password Self-Service Modes", links: ["Via Web Portal", "Mobile Access", "GINA/Mac/Linux (Ctrl+Alt+Del)", "Automatic Reset & Unlock"] }
|
|
263
|
+
];
|
|
264
|
+
var DIRECTORY_REPORT_DATA = [
|
|
265
|
+
{ id: "2", label: "Locked Out Users", value: 0 },
|
|
266
|
+
{ id: "3", label: "Soon-To-Expire Users", value: 0 },
|
|
267
|
+
{ id: "4", label: "Password Expired Users", value: 62 }
|
|
268
|
+
];
|
|
269
|
+
var MFA_REPORT_DATA = [
|
|
270
|
+
{ id: "15", label: "Enrolled Users", value: 37, color: "#8864b4" },
|
|
271
|
+
{ id: "16", label: "Non-Enrolled Users", value: 38, color: "#397dd5" }
|
|
272
|
+
];
|
|
273
|
+
var SELF_SERVICE_REPORT_DATA = [
|
|
274
|
+
{ id: "6", label: "Reset Password", value: 35 },
|
|
275
|
+
{ id: "7", label: "Unlock Account", value: 0 },
|
|
276
|
+
{ id: "8", label: "Self Update", value: 0 },
|
|
277
|
+
{ id: "9", label: "Change Password", value: 0 },
|
|
278
|
+
{ id: "1210", label: "MFA Failures", value: 0 }
|
|
279
|
+
];
|
|
280
|
+
function MetricWidget({ title, value, caption, icon: Icon = Clock3, tone = "blue", iconSize = 43, onClick, className = "", ...props }) {
|
|
281
|
+
return /* @__PURE__ */ jsxs3("button", { type: "button", className: `dash-metric ${className}`, onClick, ...props, children: [
|
|
282
|
+
/* @__PURE__ */ jsx3("span", { className: "dash-metric-title", children: title }),
|
|
283
|
+
/* @__PURE__ */ jsx3("strong", { children: value }),
|
|
284
|
+
/* @__PURE__ */ jsx3("small", { children: caption }),
|
|
285
|
+
Icon && /* @__PURE__ */ jsx3(Icon, { className: `dash-metric-icon is-${tone}`, size: iconSize, strokeWidth: 1.05 })
|
|
286
|
+
] });
|
|
287
|
+
}
|
|
288
|
+
function WidgetFrame({ title, children, onExpand, onRefresh, onMore, tools, showTools = true, labels = {}, className = "" }) {
|
|
289
|
+
const [refreshing, setRefreshing] = useState3(false);
|
|
290
|
+
return /* @__PURE__ */ jsxs3("section", { className: `dash-widget ${className}`, "aria-label": title, children: [
|
|
291
|
+
/* @__PURE__ */ jsxs3("div", { className: "dash-widget-heading", children: [
|
|
292
|
+
/* @__PURE__ */ jsx3("strong", { children: title }),
|
|
293
|
+
showTools && /* @__PURE__ */ jsx3("div", { className: "dash-widget-tools", children: tools || /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
294
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `${labels.maximize || "Maximize"} ${title}`, onClick: onExpand, children: /* @__PURE__ */ jsx3(Maximize2, { size: 14 }) }),
|
|
295
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `${labels.refresh || "Refresh"} ${title}`, onClick: () => {
|
|
296
|
+
onRefresh?.();
|
|
297
|
+
setRefreshing(true);
|
|
298
|
+
window.setTimeout(() => setRefreshing(false), 500);
|
|
299
|
+
}, children: /* @__PURE__ */ jsx3(RefreshCw, { size: 14, className: refreshing ? "is-spinning" : "" }) }),
|
|
300
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `${labels.more || "More options for"} ${title}`, onClick: onMore, children: /* @__PURE__ */ jsx3(MoreHorizontal, { size: 16 }) })
|
|
301
|
+
] }) })
|
|
302
|
+
] }),
|
|
303
|
+
children
|
|
304
|
+
] });
|
|
305
|
+
}
|
|
306
|
+
function ActiveDirectoryChart({ data = DIRECTORY_REPORT_DATA, max = 80, ticks, axisLabel = "No. Of Users", unit = "users", color = "#46c0f2", onSelect }) {
|
|
307
|
+
const ceiling = Math.max(1, Number(max));
|
|
308
|
+
const marks = ticks || [ceiling, ceiling * 0.75, ceiling * 0.5, ceiling * 0.25, 0];
|
|
309
|
+
return /* @__PURE__ */ jsxs3("div", { className: "dash-column-chart", children: [
|
|
310
|
+
/* @__PURE__ */ jsx3("span", { className: "dash-axis-title", children: axisLabel }),
|
|
311
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-y-labels", children: marks.map((n, i) => /* @__PURE__ */ jsx3("span", { children: n }, i)) }),
|
|
312
|
+
/* @__PURE__ */ jsxs3("div", { className: "dash-plot", children: [
|
|
313
|
+
marks.map((_, i) => /* @__PURE__ */ jsx3("div", { className: "dash-gridline" }, i)),
|
|
314
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-columns", style: { gridTemplateColumns: `repeat(${Math.max(data.length, 1)},1fr)` }, children: data.map((item, i) => /* @__PURE__ */ jsxs3("button", { type: "button", "aria-label": `${item.label}: ${item.value} ${unit}`, onClick: () => onSelect?.(item.id, item), children: [
|
|
315
|
+
/* @__PURE__ */ jsx3("span", { className: "dash-column", style: { height: `${Math.min(100, Math.max(0, Number(item.value) / ceiling * 100))}%`, background: item.color || color } }),
|
|
316
|
+
/* @__PURE__ */ jsx3("span", { className: "dash-column-label", title: item.label, children: item.label })
|
|
317
|
+
] }, item.id ?? i)) })
|
|
318
|
+
] })
|
|
319
|
+
] });
|
|
320
|
+
}
|
|
321
|
+
function MfaChart({ data = MFA_REPORT_DATA, onSelect, ariaLabel }) {
|
|
322
|
+
const total = data.reduce((sum, item) => sum + Number(item.value || 0), 0);
|
|
323
|
+
let current = 0;
|
|
324
|
+
const palette = ["#8864b4", "#397dd5", "#46c0f2", "#226958"];
|
|
325
|
+
const gradient = data.map((item, i) => {
|
|
326
|
+
const start = current;
|
|
327
|
+
current += total ? Number(item.value || 0) / total * 100 : 0;
|
|
328
|
+
return `${item.color || palette[i % palette.length]} ${start}% ${current}%`;
|
|
329
|
+
}).join(",");
|
|
330
|
+
return /* @__PURE__ */ jsxs3("div", { className: "dash-mfa-chart", children: [
|
|
331
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "dash-pie", style: { background: total ? `conic-gradient(${gradient})` : "#e9edef" }, "aria-label": ariaLabel || data.map((item) => `${item.value} ${item.label}`).join(", "), onClick: () => data[0] && onSelect?.(data[0].id, data[0]) }),
|
|
332
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-legend", children: data.map((item, i) => /* @__PURE__ */ jsxs3("button", { type: "button", onClick: () => onSelect?.(item.id, item), children: [
|
|
333
|
+
/* @__PURE__ */ jsx3("i", { style: { background: item.color || palette[i % palette.length] } }),
|
|
334
|
+
item.label
|
|
335
|
+
] }, item.id ?? i)) })
|
|
336
|
+
] });
|
|
337
|
+
}
|
|
338
|
+
function SelfServiceChart({ data = SELF_SERVICE_REPORT_DATA, max = 35, ticks, axisLabel = "No. Of Users", unit = "users", color = "#226958", onSelect }) {
|
|
339
|
+
const ceiling = Math.max(1, Number(max));
|
|
340
|
+
const marks = ticks || Array.from({ length: 8 }, (_, i) => ceiling * i / 7);
|
|
341
|
+
const gridStep = 100 / Math.max(1, marks.length - 1);
|
|
342
|
+
return /* @__PURE__ */ jsxs3("div", { className: "dash-horizontal-chart", children: [
|
|
343
|
+
/* @__PURE__ */ jsx3("span", { className: "dash-horizontal-axis-title", children: axisLabel }),
|
|
344
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-horizontal-bars", style: { gridTemplateRows: `repeat(${Math.max(data.length, 1)},1fr)`, backgroundImage: `repeating-linear-gradient(90deg,transparent 0,transparent calc(${gridStep}% - 1px),#e5e9ea calc(${gridStep}% - 1px),#e5e9ea ${gridStep}%)` }, children: data.map((item, i) => /* @__PURE__ */ jsxs3("button", { type: "button", onClick: () => onSelect?.(item.id, item), "aria-label": `${item.label}: ${item.value} ${unit}`, children: [
|
|
345
|
+
/* @__PURE__ */ jsx3("span", { children: item.label }),
|
|
346
|
+
/* @__PURE__ */ jsx3("i", { style: { width: `${Math.min(100, Math.max(0, Number(item.value) / ceiling * 100))}%`, background: item.color || color } })
|
|
347
|
+
] }, item.id ?? i)) }),
|
|
348
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-horizontal-ticks", children: marks.map((n, i) => /* @__PURE__ */ jsx3("span", { children: Number.isInteger(n) ? n : Number(n.toFixed(1)) }, i)) })
|
|
349
|
+
] });
|
|
350
|
+
}
|
|
351
|
+
function ShortcutRail({ groups = DASHBOARD_SHORTCUTS, onSelect, ariaLabel = "Dashboard shortcuts" }) {
|
|
352
|
+
return /* @__PURE__ */ jsx3("aside", { className: "dash-shortcuts", "aria-label": ariaLabel, children: groups.map((group, index) => /* @__PURE__ */ jsxs3("section", { children: [
|
|
353
|
+
/* @__PURE__ */ jsx3("h3", { children: group.title }),
|
|
354
|
+
/* @__PURE__ */ jsx3("ul", { children: group.links.map((link, i) => {
|
|
355
|
+
const item = typeof link === "string" ? { id: link, label: link } : link;
|
|
356
|
+
return /* @__PURE__ */ jsx3("li", { children: item.href ? /* @__PURE__ */ jsx3("a", { href: item.href, onClick: (event) => {
|
|
357
|
+
if (onSelect) {
|
|
358
|
+
event.preventDefault();
|
|
359
|
+
onSelect(item.id, item);
|
|
360
|
+
}
|
|
361
|
+
}, children: item.label }) : /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => onSelect?.(item.id, item), children: item.label }) }, item.id ?? i);
|
|
362
|
+
}) })
|
|
363
|
+
] }, group.id ?? group.title ?? index)) });
|
|
364
|
+
}
|
|
365
|
+
function DashboardToolbar({ domains = ["ADSELFSERVICE"], domain, defaultDomain, onDomainChange, domainLabel = "Select Domain to View :", showShortcuts = true, onToggleShortcuts, onExpand, settingsLabel = "Dashboard settings", expandLabel = "Expand dashboard", menuItems, onMenuAction }) {
|
|
366
|
+
const [menu, setMenu] = useState3(false);
|
|
367
|
+
const actions = menuItems || [{ id: "embed", label: "Embed Dashboard" }, { id: "updater", label: "Dashboard Updater" }, { id: "shortcuts", label: `${showShortcuts ? "Hide" : "Show"} Shortcut Menu` }];
|
|
368
|
+
return /* @__PURE__ */ jsxs3("div", { className: "dash-toolbar", children: [
|
|
369
|
+
/* @__PURE__ */ jsx3("label", { htmlFor: "dash-domain", children: domainLabel }),
|
|
370
|
+
/* @__PURE__ */ jsx3("select", { id: "dash-domain", value: domain, defaultValue: domain === void 0 ? defaultDomain ?? (typeof domains[0] === "string" ? domains[0] : domains[0]?.value) : void 0, onChange: (event) => {
|
|
371
|
+
const item = domains.map((raw) => typeof raw === "string" ? { value: raw, label: raw } : raw).find((option) => option.value === event.target.value);
|
|
372
|
+
onDomainChange?.(event.target.value, item);
|
|
373
|
+
}, children: domains.map((option) => {
|
|
374
|
+
const item = typeof option === "string" ? { value: option, label: option } : option;
|
|
375
|
+
return /* @__PURE__ */ jsx3("option", { value: item.value, children: item.label }, item.value);
|
|
376
|
+
}) }),
|
|
377
|
+
/* @__PURE__ */ jsxs3("div", { className: "dash-toolbar-actions", children: [
|
|
378
|
+
/* @__PURE__ */ jsxs3("div", { className: "dash-menu-anchor", children: [
|
|
379
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": settingsLabel, "aria-expanded": menu, onClick: () => setMenu(!menu), children: /* @__PURE__ */ jsx3(Settings2, { size: 18 }) }),
|
|
380
|
+
menu && /* @__PURE__ */ jsx3("div", { className: "dash-menu", children: actions.map((item) => /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => {
|
|
381
|
+
if (item.id === "shortcuts") onToggleShortcuts?.();
|
|
382
|
+
item.onClick?.(item);
|
|
383
|
+
onMenuAction?.(item.id, item);
|
|
384
|
+
setMenu(false);
|
|
385
|
+
}, children: item.label }, item.id)) })
|
|
386
|
+
] }),
|
|
387
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": expandLabel, onClick: onExpand, children: /* @__PURE__ */ jsx3(Maximize2, { size: 17 }) })
|
|
388
|
+
] })
|
|
389
|
+
] });
|
|
390
|
+
}
|
|
391
|
+
function DashboardLayout({ metrics, charts, shortcuts, showShortcuts = true }) {
|
|
392
|
+
return /* @__PURE__ */ jsxs3("div", { className: `dash-layout ${showShortcuts ? "" : "without-shortcuts"}`, children: [
|
|
393
|
+
/* @__PURE__ */ jsxs3("div", { className: "dash-content", children: [
|
|
394
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-metrics", children: metrics }),
|
|
395
|
+
/* @__PURE__ */ jsx3("div", { className: "dash-chart-grid", children: charts })
|
|
396
|
+
] }),
|
|
397
|
+
showShortcuts && shortcuts
|
|
398
|
+
] });
|
|
399
|
+
}
|
|
400
|
+
function ExpandedWidget({ title, onClose, children, closeLabel = "Close expanded widget" }) {
|
|
401
|
+
if (!title) return null;
|
|
402
|
+
return /* @__PURE__ */ jsx3("div", { className: "dash-overlay", role: "presentation", onMouseDown: onClose, children: /* @__PURE__ */ jsxs3("div", { className: "dash-expanded", role: "dialog", "aria-modal": "true", "aria-label": title, onMouseDown: (e) => e.stopPropagation(), children: [
|
|
403
|
+
/* @__PURE__ */ jsxs3("div", { className: "dash-expanded-heading", children: [
|
|
404
|
+
/* @__PURE__ */ jsx3("strong", { children: title }),
|
|
405
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx3(X2, { size: 18 }) })
|
|
406
|
+
] }),
|
|
407
|
+
children
|
|
408
|
+
] }) });
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/widgets/ReportWidgets.jsx
|
|
412
|
+
import React4, { useEffect as useEffect2, useMemo, useState as useState4 } from "react";
|
|
413
|
+
import { AlarmClock, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2, CircleHelp as CircleHelp2, Info as Info2, Search as Search2 } from "lucide-react";
|
|
414
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
415
|
+
var REPORT_GROUPS = [
|
|
416
|
+
{ label: "Active Directory Reports", items: [["2", "Locked Out Users Report"], ["3", "Soon-To-Expire Password Users Report"], ["4", "Password Expired Users Report"]] },
|
|
417
|
+
{ label: "Password Self-Service Reports", items: [["6", "Reset Password Audit Report"], ["7", "Unlock Account Audit Report"], ["1202", "GINA/Mac/Linux Agent Reset Password Audit Report"], ["1203", "GINA/Mac/Linux Agent Unlock Account Audit Report"], ["8", "Self-Update Audit Report"], ["9", "Change Password Audit Report"], ["1204", "Password/Account Expiry Notifications Delivery Report"]] },
|
|
418
|
+
{ label: "MFA Reports", items: [["15", "MFA Enrolled Users Report"], ["16", "MFA Non-Enrolled Users Report"], ["1206", "MFA Enrollment Audit Report"], ["1207", "MFA Usage Audit Report"], ["1208", "MFA Usage for Machines/VPN/OWA"], ["1209", "MFA Usage from Mobile Devices"], ["1210", "MFA Failures Audit Report"], ["1211", "MFA Trusted Browser Report"], ["1212", "MFA Trusted Machines Report"], ["18", "Security Questions Report"], ["1213", "Backup Code Usage Report"], ["301", "Offline MFA Enrolled Machines Report"], ["601", "FIDO2 Passkeys Report"], ["13", "Blocked Users Report"]] },
|
|
419
|
+
{ label: "GINA/Mac/Linux Agent Reports", items: [["1215", "Agent Installed Machines Report"], ["1216", "Agent Installation Failures Report"]] },
|
|
420
|
+
{ label: "Other Reports", items: [["12", "User Attempts Audit Report"], ["17", "Licensed Users Report"], ["10", "Notification Delivery Report"], ["19", "Push Registered Devices Report"], ["901", "Application Access Audit Report"], ["902", "JIT Provisioning Audit Report"]] }
|
|
421
|
+
];
|
|
422
|
+
var normalizeReport = (item) => Array.isArray(item) ? { id: item[0], label: item[1] } : item;
|
|
423
|
+
function ReportNavigation({ groups = REPORT_GROUPS, selected, defaultSelected, onSelect, searchPlaceholder = "Search Report", searchLabel = "Search Report", emptyLabel = "No matching reports", ariaLabel = "Report categories", onSearchChange }) {
|
|
424
|
+
const [query, setQuery] = useState4("");
|
|
425
|
+
const [localSelected, setLocalSelected] = useState4(defaultSelected ?? (groups[0]?.items[0] && normalizeReport(groups[0].items[0]).id));
|
|
426
|
+
const currentSelected = selected ?? localSelected;
|
|
427
|
+
const selectedGroup = groups.find((group) => group.items.some((item) => normalizeReport(item).id === currentSelected))?.label || groups[0]?.label;
|
|
428
|
+
const [open, setOpen] = useState4(selectedGroup);
|
|
429
|
+
useEffect2(() => setOpen(selectedGroup), [selectedGroup]);
|
|
430
|
+
const visibleGroups = useMemo(() => groups.map((group) => ({ ...group, items: group.items.map(normalizeReport).filter((item) => item.label.toLowerCase().includes(query.toLowerCase())) })).filter((group) => !query || group.items.length), [groups, query]);
|
|
431
|
+
return /* @__PURE__ */ jsxs4("div", { className: "report-navigation", children: [
|
|
432
|
+
/* @__PURE__ */ jsxs4("label", { className: "report-search", children: [
|
|
433
|
+
/* @__PURE__ */ jsx4(Search2, { size: 15 }),
|
|
434
|
+
/* @__PURE__ */ jsx4("input", { "aria-label": searchLabel, placeholder: searchPlaceholder, value: query, onChange: (e) => {
|
|
435
|
+
setQuery(e.target.value);
|
|
436
|
+
onSearchChange?.(e.target.value);
|
|
437
|
+
} })
|
|
438
|
+
] }),
|
|
439
|
+
/* @__PURE__ */ jsx4("nav", { "aria-label": ariaLabel, children: visibleGroups.map((group) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
440
|
+
/* @__PURE__ */ jsxs4("button", { type: "button", className: "report-nav-group", "aria-expanded": query ? true : open === group.label, onClick: () => setOpen(open === group.label ? "" : group.label), children: [
|
|
441
|
+
group.label,
|
|
442
|
+
query || open === group.label ? /* @__PURE__ */ jsx4(ChevronDown2, { size: 12 }) : /* @__PURE__ */ jsx4(ChevronRight2, { size: 12 })
|
|
443
|
+
] }),
|
|
444
|
+
(query || open === group.label) && group.items.map((item) => /* @__PURE__ */ jsx4("button", { type: "button", className: `report-nav-item ${currentSelected === item.id ? "is-active" : ""}`, onClick: () => {
|
|
445
|
+
if (selected === void 0) setLocalSelected(item.id);
|
|
446
|
+
onSelect?.(item.id, item);
|
|
447
|
+
}, children: item.label }, item.id))
|
|
448
|
+
] }, group.id ?? group.label)) }),
|
|
449
|
+
query && !visibleGroups.length && /* @__PURE__ */ jsx4("div", { className: "report-search-empty", children: emptyLabel })
|
|
450
|
+
] });
|
|
451
|
+
}
|
|
452
|
+
function ReportCategoryBar({ groups = REPORT_GROUPS, selected, defaultSelected, onSelect, ariaLabel = "Report group menu" }) {
|
|
453
|
+
const [open, setOpen] = useState4("");
|
|
454
|
+
const [localSelected, setLocalSelected] = useState4(defaultSelected ?? (groups[0]?.items[0] && normalizeReport(groups[0].items[0]).id));
|
|
455
|
+
const currentSelected = selected ?? localSelected;
|
|
456
|
+
return /* @__PURE__ */ jsx4("nav", { className: "report-category-bar", "aria-label": ariaLabel, children: groups.map((group) => /* @__PURE__ */ jsxs4("div", { className: "report-category", children: [
|
|
457
|
+
/* @__PURE__ */ jsxs4("button", { type: "button", "aria-expanded": open === group.label, onClick: () => setOpen(open === group.label ? "" : group.label), children: [
|
|
458
|
+
group.label,
|
|
459
|
+
/* @__PURE__ */ jsx4(ChevronDown2, { size: 10 })
|
|
460
|
+
] }),
|
|
461
|
+
open === group.label && /* @__PURE__ */ jsx4("div", { className: "report-category-menu", children: group.items.map((raw, i) => {
|
|
462
|
+
const item = normalizeReport(raw);
|
|
463
|
+
return /* @__PURE__ */ jsx4("button", { type: "button", className: currentSelected === item.id ? "is-active" : "", onClick: () => {
|
|
464
|
+
if (selected === void 0) setLocalSelected(item.id);
|
|
465
|
+
onSelect?.(item.id, item);
|
|
466
|
+
setOpen("");
|
|
467
|
+
}, children: item.label }, item.id ?? i);
|
|
468
|
+
}) })
|
|
469
|
+
] }, group.id ?? group.label)) });
|
|
470
|
+
}
|
|
471
|
+
function ReportFilters({ domains = ["ADSELFSERVICE"], domain, defaultDomain, onDomainChange, ouOptions = ["All OU", "Users"], ou, defaultOu, onOuChange, labels = {}, onGenerate, onStop, generating = false }) {
|
|
472
|
+
const [ouOpen, setOuOpen] = useState4(false);
|
|
473
|
+
const [localOu, setLocalOu] = useState4(defaultOu ?? (typeof ouOptions[0] === "string" ? ouOptions[0] : ouOptions[0]?.value));
|
|
474
|
+
const selectedOu = ou ?? localOu;
|
|
475
|
+
return /* @__PURE__ */ jsxs4("div", { className: "report-filters", children: [
|
|
476
|
+
/* @__PURE__ */ jsxs4("div", { className: "report-filter-row", children: [
|
|
477
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: "report-domain", children: labels.domain || "Select Domain" }),
|
|
478
|
+
/* @__PURE__ */ jsx4("select", { id: "report-domain", value: domain, defaultValue: domain === void 0 ? defaultDomain ?? (typeof domains[0] === "string" ? domains[0] : domains[0]?.value) : void 0, onChange: (event) => {
|
|
479
|
+
const value = event.target.value;
|
|
480
|
+
const item = domains.map((raw) => typeof raw === "string" ? { value: raw, label: raw } : raw).find((option) => option.value === value);
|
|
481
|
+
onDomainChange?.(value, item);
|
|
482
|
+
}, children: domains.map((raw) => {
|
|
483
|
+
const item = typeof raw === "string" ? { value: raw, label: raw } : raw;
|
|
484
|
+
return /* @__PURE__ */ jsx4("option", { value: item.value, children: item.label }, item.value);
|
|
485
|
+
}) }),
|
|
486
|
+
/* @__PURE__ */ jsxs4("button", { type: "button", className: "report-ou-current", onClick: () => setOuOpen(!ouOpen), children: [
|
|
487
|
+
selectedOu,
|
|
488
|
+
/* @__PURE__ */ jsx4(ChevronDown2, { size: 11 })
|
|
489
|
+
] }),
|
|
490
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "report-ou-link", onClick: () => setOuOpen(!ouOpen), children: labels.selectOu || "Select OU" })
|
|
491
|
+
] }),
|
|
492
|
+
ouOpen && /* @__PURE__ */ jsxs4("div", { className: "report-ou-picker", children: [
|
|
493
|
+
/* @__PURE__ */ jsx4("strong", { children: labels.selectOu || "Select OU" }),
|
|
494
|
+
ouOptions.map((raw) => {
|
|
495
|
+
const item = typeof raw === "string" ? { value: raw, label: raw } : raw;
|
|
496
|
+
return /* @__PURE__ */ jsxs4("label", { children: [
|
|
497
|
+
/* @__PURE__ */ jsx4("input", { type: "radio", name: "report-ou", checked: selectedOu === item.value, onChange: () => {
|
|
498
|
+
setLocalOu(item.value);
|
|
499
|
+
onOuChange?.(item.value, item);
|
|
500
|
+
setOuOpen(false);
|
|
501
|
+
} }),
|
|
502
|
+
" ",
|
|
503
|
+
item.label
|
|
504
|
+
] }, item.value);
|
|
505
|
+
})
|
|
506
|
+
] }),
|
|
507
|
+
/* @__PURE__ */ jsxs4("div", { className: "report-filter-actions", children: [
|
|
508
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "report-generate", onClick: onGenerate, disabled: generating, children: labels.generate || "Generate" }),
|
|
509
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "report-stop", onClick: onStop, disabled: !generating, children: labels.stop || "Stop" })
|
|
510
|
+
] })
|
|
511
|
+
] });
|
|
512
|
+
}
|
|
513
|
+
function ReportResults({ status = "empty", emptyMessage = "No Data Available", loadingMessage = "Generating report\u2026", children }) {
|
|
514
|
+
return /* @__PURE__ */ jsx4("div", { className: "report-results", role: "status", children: children !== void 0 ? children : status === "loading" ? /* @__PURE__ */ jsx4("span", { children: loadingMessage }) : /* @__PURE__ */ jsxs4("span", { children: [
|
|
515
|
+
/* @__PURE__ */ jsx4(Info2, { size: 13 }),
|
|
516
|
+
" ",
|
|
517
|
+
emptyMessage
|
|
518
|
+
] }) });
|
|
519
|
+
}
|
|
520
|
+
function ReportPageHeading({ title, onSchedule, scheduleLabel = "Schedule Reports", helpText, action }) {
|
|
521
|
+
return /* @__PURE__ */ jsxs4("header", { className: "report-page-heading", children: [
|
|
522
|
+
/* @__PURE__ */ jsxs4("h1", { children: [
|
|
523
|
+
title,
|
|
524
|
+
" ",
|
|
525
|
+
helpText !== null && /* @__PURE__ */ jsx4(CircleHelp2, { size: 12, strokeWidth: 1.3, "aria-label": helpText || `Help for ${title}` })
|
|
526
|
+
] }),
|
|
527
|
+
action || /* @__PURE__ */ jsxs4("button", { type: "button", onClick: onSchedule, children: [
|
|
528
|
+
/* @__PURE__ */ jsx4(AlarmClock, { size: 13 }),
|
|
529
|
+
" ",
|
|
530
|
+
scheduleLabel
|
|
531
|
+
] })
|
|
532
|
+
] });
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// src/widgets/ConfigurationWidgets.jsx
|
|
536
|
+
import React5, { useState as useState5 } from "react";
|
|
537
|
+
import { ChevronDown as ChevronDown3, ChevronLeft, ChevronRight as ChevronRight3, ChevronsLeft, ChevronsRight, Copy, KeyRound, LockKeyhole, Pencil, Plus, Search as Search3, Settings as Settings3, Trash2, UserRoundPen } from "lucide-react";
|
|
538
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
539
|
+
var CONFIG_GROUPS = [
|
|
540
|
+
{ label: "Self-Service", items: [{ id: "policy", label: "Policy Configuration" }, { id: "mfa", label: "Multi-factor Authentication" }, { id: "expiry", label: "Password Expiration Notification" }, { id: "enforcer", label: "Password Policy Enforcer" }, { id: "sync", label: "Password Sync/Single Sign On" }, { id: "conditional", label: "Conditional Access" }, { id: "directory", label: "Directory Self Service" }] },
|
|
541
|
+
{ label: "Administrative Tools", items: [{ id: "enrollment", label: "Quick Enrollment" }, { id: "agent", label: "GINA/Mac/Linux (Ctrl+Alt+Del)" }, { id: "mobile", label: "Mobile App Deployment" }, { id: "approval", label: "Approval Workflow" }, { id: "technician", label: "Technician" }] },
|
|
542
|
+
{ label: "Security Center", items: [{ id: "hardening", label: "Security Hardening" }, { id: "strengtheners", label: "Password Strengtheners" }, { id: "questions", label: "Security Q&A Strengtheners" }, { id: "anti-hacking", label: "Anti-Hacking System" }] }
|
|
543
|
+
];
|
|
544
|
+
var POLICY_FEATURES = [
|
|
545
|
+
{ label: "Reset Password", icon: KeyRound },
|
|
546
|
+
{ label: "Unlock Account", icon: LockKeyhole },
|
|
547
|
+
{ label: "Change Password", icon: Settings3 },
|
|
548
|
+
{ label: "Self Update", icon: UserRoundPen }
|
|
549
|
+
];
|
|
550
|
+
var DEMO_POLICIES = [
|
|
551
|
+
{ name: "Selfservice Users", permissions: "Reset Password, Unlock Account, Self Update, Change Password", modifiedBy: "admin (ADSelfService Plus Authentication)", modified: "2025/04/05 01:43 PM" },
|
|
552
|
+
{ name: "Endpoint MFA Users", permissions: "Reset Password, Unlock Account, Change Password", modifiedBy: "operator (ADSelfService Plus Authentication)", modified: "2025/07/08 07:28 AM" },
|
|
553
|
+
{ name: "OWA MFA Users", permissions: "Reset Password, Unlock Account", modifiedBy: "admin (ADSelfService Plus Authentication)", modified: "2025/04/05 11:38 AM" },
|
|
554
|
+
{ name: "VPN MFA Users", permissions: "Unlock Account, Self Update, Change Password", modifiedBy: "operator (ADSelfService Plus Authentication)", modified: "2025/07/08 07:28 AM" },
|
|
555
|
+
{ name: "Remote Users", permissions: "Reset Password, Self Update, Change Password", modifiedBy: "admin (ADSelfService Plus Authentication)", modified: "2025/04/05 11:39 AM" },
|
|
556
|
+
{ name: "System Admins", permissions: "Reset Password", modifiedBy: "operator (ADSelfService Plus Authentication)", modified: "2025/07/08 07:28 AM" },
|
|
557
|
+
{ name: "Technical Support", permissions: "Self Update, Change Password", modifiedBy: "admin (ADSelfService Plus Authentication)", modified: "2025/04/05 11:40 AM" }
|
|
558
|
+
];
|
|
559
|
+
var POLICY_COLUMNS = [
|
|
560
|
+
{ key: "actions", label: "Actions" },
|
|
561
|
+
{ key: "advanced", label: "Advanced" },
|
|
562
|
+
{ key: "name", label: "Policy Name" },
|
|
563
|
+
{ key: "permissions", label: "Permissions" },
|
|
564
|
+
{ key: "domain", label: "Domain Name" },
|
|
565
|
+
{ key: "modifiedBy", label: "Last Modified By" },
|
|
566
|
+
{ key: "modified", label: "Last Modified Time" }
|
|
567
|
+
];
|
|
568
|
+
function ConfigurationSidebar({ groups = CONFIG_GROUPS, selected, defaultSelected, onSelect, initialOpen }) {
|
|
569
|
+
return /* @__PURE__ */ jsx5(CollapsibleSidebar, { groups, selected, defaultSelected, onSelect, initialOpen });
|
|
570
|
+
}
|
|
571
|
+
function ConfigurationHeader({ title, mode = "Password Self-Service Modes", onModeChange, helpText, action }) {
|
|
572
|
+
return /* @__PURE__ */ jsxs5("div", { className: "config-heading", children: [
|
|
573
|
+
/* @__PURE__ */ jsxs5("h1", { children: [
|
|
574
|
+
title,
|
|
575
|
+
" ",
|
|
576
|
+
helpText !== null && /* @__PURE__ */ jsx5("span", { title: helpText || `Help for ${title}`, children: "\u24D8" })
|
|
577
|
+
] }),
|
|
578
|
+
action || /* @__PURE__ */ jsxs5("button", { type: "button", onClick: () => onModeChange?.(mode), children: [
|
|
579
|
+
mode,
|
|
580
|
+
/* @__PURE__ */ jsx5(ChevronDown3, { size: 11 })
|
|
581
|
+
] })
|
|
582
|
+
] });
|
|
583
|
+
}
|
|
584
|
+
function PolicyFeatureStrip({ title = "Self-Service Features", features = POLICY_FEATURES, instruction, onFeatureSelect }) {
|
|
585
|
+
return /* @__PURE__ */ jsxs5("section", { className: "config-feature-strip", "aria-label": title, children: [
|
|
586
|
+
/* @__PURE__ */ jsx5("h2", { children: title }),
|
|
587
|
+
/* @__PURE__ */ jsx5("div", { className: "config-features", children: features.map(({ id, label, icon: Icon = Settings3 }, index) => /* @__PURE__ */ jsx5("div", { children: onFeatureSelect ? /* @__PURE__ */ jsxs5("button", { type: "button", onClick: () => onFeatureSelect(id ?? label, { id, label, icon: Icon }), children: [
|
|
588
|
+
/* @__PURE__ */ jsx5(Icon, { size: 20, strokeWidth: 2 }),
|
|
589
|
+
/* @__PURE__ */ jsx5("span", { children: label })
|
|
590
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
591
|
+
/* @__PURE__ */ jsx5(Icon, { size: 20, strokeWidth: 2 }),
|
|
592
|
+
/* @__PURE__ */ jsx5("span", { children: label })
|
|
593
|
+
] }) }, id ?? label ?? index)) }),
|
|
594
|
+
/* @__PURE__ */ jsx5("p", { children: instruction === void 0 ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
595
|
+
'Click "Add New Policy" Button to add a new policy. To edit an existing policy, click on ',
|
|
596
|
+
/* @__PURE__ */ jsx5(Pencil, { size: 12 }),
|
|
597
|
+
" icon in the Actions column."
|
|
598
|
+
] }) : instruction })
|
|
599
|
+
] });
|
|
600
|
+
}
|
|
601
|
+
function PolicyToolbar({ title = "Available Policies", addLabel = "Add New Policy", searchLabel = "Search policies", count = 0, page, defaultPage = 1, pageSize = 25, onPageChange, onAdd, query, defaultQuery = "", onQueryChange, labels = {} }) {
|
|
602
|
+
const [localPage, setLocalPage] = useState5(defaultPage);
|
|
603
|
+
const [localQuery, setLocalQuery] = useState5(defaultQuery);
|
|
604
|
+
const currentPage = page ?? localPage;
|
|
605
|
+
const currentQuery = query ?? localQuery;
|
|
606
|
+
const pages = Math.max(1, Math.ceil(count / pageSize));
|
|
607
|
+
const first = count ? (currentPage - 1) * pageSize + 1 : 0;
|
|
608
|
+
const last = Math.min(currentPage * pageSize, count);
|
|
609
|
+
const changePage = (next) => {
|
|
610
|
+
if (page === void 0) setLocalPage(next);
|
|
611
|
+
onPageChange?.(next);
|
|
612
|
+
};
|
|
613
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
614
|
+
/* @__PURE__ */ jsxs5("div", { className: "config-table-title", children: [
|
|
615
|
+
/* @__PURE__ */ jsx5("h2", { children: title }),
|
|
616
|
+
/* @__PURE__ */ jsxs5("button", { type: "button", onClick: onAdd, children: [
|
|
617
|
+
/* @__PURE__ */ jsx5(Plus, { size: 13 }),
|
|
618
|
+
" ",
|
|
619
|
+
addLabel
|
|
620
|
+
] })
|
|
621
|
+
] }),
|
|
622
|
+
/* @__PURE__ */ jsxs5("div", { className: "config-table-tools", children: [
|
|
623
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
624
|
+
/* @__PURE__ */ jsx5(Search3, { size: 15 }),
|
|
625
|
+
/* @__PURE__ */ jsx5("input", { "aria-label": searchLabel, value: currentQuery, onChange: (event) => {
|
|
626
|
+
if (query === void 0) setLocalQuery(event.target.value);
|
|
627
|
+
onQueryChange?.(event.target.value);
|
|
628
|
+
} })
|
|
629
|
+
] }),
|
|
630
|
+
/* @__PURE__ */ jsxs5("div", { className: "config-page-controls", children: [
|
|
631
|
+
/* @__PURE__ */ jsx5("button", { type: "button", disabled: currentPage <= 1, "aria-label": labels.first || "First page", onClick: () => changePage(1), children: /* @__PURE__ */ jsx5(ChevronsLeft, { size: 12 }) }),
|
|
632
|
+
/* @__PURE__ */ jsx5("button", { type: "button", disabled: currentPage <= 1, "aria-label": labels.previous || "Previous page", onClick: () => changePage(currentPage - 1), children: /* @__PURE__ */ jsx5(ChevronLeft, { size: 12 }) }),
|
|
633
|
+
/* @__PURE__ */ jsx5("span", { children: labels.range ? labels.range(first, last, count) : `${first}-${last} of ${count}` }),
|
|
634
|
+
/* @__PURE__ */ jsx5("button", { type: "button", disabled: currentPage >= pages, "aria-label": labels.next || "Next page", onClick: () => changePage(currentPage + 1), children: /* @__PURE__ */ jsx5(ChevronRight3, { size: 12 }) }),
|
|
635
|
+
/* @__PURE__ */ jsx5("button", { type: "button", disabled: currentPage >= pages, "aria-label": labels.last || "Last page", onClick: () => changePage(pages), children: /* @__PURE__ */ jsx5(ChevronsRight, { size: 12 }) })
|
|
636
|
+
] })
|
|
637
|
+
] })
|
|
638
|
+
] });
|
|
639
|
+
}
|
|
640
|
+
function PolicyTable({ policies = DEMO_POLICIES, columns = POLICY_COLUMNS, defaultDomain = "ADSELFSERVICE", emptyMessage = "No Data Available", actionLabels = {}, onEdit, onDelete, onCopy, renderCell, getRowId = (policy) => policy.id ?? policy.name }) {
|
|
641
|
+
const cell = (policy, key) => {
|
|
642
|
+
if (renderCell) {
|
|
643
|
+
const custom = renderCell(policy, key);
|
|
644
|
+
if (custom !== void 0) return custom;
|
|
645
|
+
}
|
|
646
|
+
if (key === "actions") return /* @__PURE__ */ jsxs5("div", { className: "config-actions", children: [
|
|
647
|
+
/* @__PURE__ */ jsx5("button", { type: "button", "aria-label": `${actionLabels.edit || "Edit"} ${policy.name}`, onClick: () => onEdit?.(policy), children: /* @__PURE__ */ jsx5(Pencil, { size: 12 }) }),
|
|
648
|
+
/* @__PURE__ */ jsx5("button", { type: "button", "aria-label": `${actionLabels.delete || "Delete"} ${policy.name}`, onClick: () => onDelete?.(policy), children: /* @__PURE__ */ jsx5(Trash2, { size: 12 }) }),
|
|
649
|
+
/* @__PURE__ */ jsx5("button", { type: "button", "aria-label": `${actionLabels.copy || "Copy"} ${policy.name}`, onClick: () => onCopy?.(policy), children: /* @__PURE__ */ jsx5(Copy, { size: 12 }) })
|
|
650
|
+
] });
|
|
651
|
+
if (key === "advanced") return /* @__PURE__ */ jsx5("button", { type: "button", "aria-label": `${actionLabels.advanced || "Advanced settings for"} ${policy.name}`, onClick: () => onEdit?.(policy), children: /* @__PURE__ */ jsx5(Settings3, { size: 17 }) });
|
|
652
|
+
return key === "domain" ? policy.domain ?? defaultDomain : policy[key];
|
|
653
|
+
};
|
|
654
|
+
return /* @__PURE__ */ jsx5("div", { className: "config-policy-table-wrap", children: /* @__PURE__ */ jsxs5("table", { className: `config-policy-table ${columns.length === 7 ? "is-reference" : ""}`, children: [
|
|
655
|
+
/* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsx5("tr", { children: columns.map((column) => /* @__PURE__ */ jsx5("th", { children: column.label }, column.key)) }) }),
|
|
656
|
+
/* @__PURE__ */ jsx5("tbody", { children: policies.length ? policies.map((policy) => /* @__PURE__ */ jsx5("tr", { children: columns.map((column) => /* @__PURE__ */ jsx5("td", { title: column.key === "modifiedBy" ? policy.modifiedBy : void 0, children: cell(policy, column.key) }, column.key)) }, getRowId(policy))) : /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: columns.length, className: "config-empty", children: emptyMessage }) }) })
|
|
657
|
+
] }) });
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// src/widgets/SettingsWidgets.jsx
|
|
661
|
+
import React6, { useState as useState6 } from "react";
|
|
662
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
663
|
+
function Frame({ title, tabs, activeTab, defaultTab, onTabChange, children, action, help, className = "" }) {
|
|
664
|
+
const [localTab, setLocalTab] = useState6(defaultTab ?? (typeof tabs?.[0] === "string" ? tabs[0] : tabs?.[0]?.id));
|
|
665
|
+
const active = activeTab ?? localTab;
|
|
666
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
667
|
+
/* @__PURE__ */ jsx6(PageHeader, { title, action, help }),
|
|
668
|
+
/* @__PURE__ */ jsxs6(Panel, { className, children: [
|
|
669
|
+
tabs && /* @__PURE__ */ jsx6(Tabs, { tabs, active, onChange: (tab) => {
|
|
670
|
+
if (activeTab === void 0) setLocalTab(tab);
|
|
671
|
+
onTabChange?.(tab);
|
|
672
|
+
} }),
|
|
673
|
+
" ",
|
|
674
|
+
typeof children === "function" ? children(active) : children
|
|
675
|
+
] })
|
|
676
|
+
] });
|
|
677
|
+
}
|
|
678
|
+
function SaveBar({ saveLabel = "Save", cancel = true, cancelLabel = "Cancel", successMessage = "Settings saved in this demo.", onSave, onCancel, status: controlledStatus }) {
|
|
679
|
+
const [status, setStatus] = useState6("");
|
|
680
|
+
return /* @__PURE__ */ jsx6(ActionBar, { saveLabel, cancelLabel, onSave: () => {
|
|
681
|
+
onSave?.();
|
|
682
|
+
if (controlledStatus === void 0) {
|
|
683
|
+
setStatus(successMessage);
|
|
684
|
+
window.setTimeout(() => setStatus(""), 4e3);
|
|
685
|
+
}
|
|
686
|
+
}, onCancel: cancel ? () => {
|
|
687
|
+
onCancel?.();
|
|
688
|
+
if (controlledStatus === void 0) setStatus("");
|
|
689
|
+
} : void 0, status: controlledStatus ?? status });
|
|
690
|
+
}
|
|
691
|
+
function InlineSelect({ options = [], initial, value, onChange, width, ...props }) {
|
|
692
|
+
const [localValue, setLocalValue] = useState6(initial ?? (typeof options[0] === "string" ? options[0] : options[0]?.value));
|
|
693
|
+
return /* @__PURE__ */ jsx6("select", { className: "ad-select", style: { width }, value: value ?? localValue, onChange: (event) => {
|
|
694
|
+
if (value === void 0) setLocalValue(event.target.value);
|
|
695
|
+
onChange?.(event.target.value);
|
|
696
|
+
}, ...props, children: options.map((raw) => {
|
|
697
|
+
const item = typeof raw === "string" ? { value: raw, label: raw } : raw;
|
|
698
|
+
return /* @__PURE__ */ jsx6("option", { value: item.value, children: item.label }, item.value);
|
|
699
|
+
}) });
|
|
700
|
+
}
|
|
701
|
+
export {
|
|
702
|
+
ActionBar,
|
|
703
|
+
ActiveDirectoryChart,
|
|
704
|
+
AdminShell,
|
|
705
|
+
AppShell,
|
|
706
|
+
Button,
|
|
707
|
+
CONFIG_GROUPS,
|
|
708
|
+
CheckRow,
|
|
709
|
+
CollapsibleSidebar,
|
|
710
|
+
ConfigurationHeader,
|
|
711
|
+
ConfigurationSidebar,
|
|
712
|
+
DASHBOARD_METRICS,
|
|
713
|
+
DASHBOARD_SHORTCUTS,
|
|
714
|
+
DEMO_POLICIES,
|
|
715
|
+
DIRECTORY_REPORT_DATA,
|
|
716
|
+
DashboardLayout,
|
|
717
|
+
DashboardToolbar,
|
|
718
|
+
DataTable,
|
|
719
|
+
ExpandedWidget,
|
|
720
|
+
FOOTER_LINKS,
|
|
721
|
+
FormRow,
|
|
722
|
+
Frame,
|
|
723
|
+
HelpTip,
|
|
724
|
+
IconButton,
|
|
725
|
+
InlineSelect,
|
|
726
|
+
MAIN_SECTIONS,
|
|
727
|
+
MFA_REPORT_DATA,
|
|
728
|
+
MetricWidget,
|
|
729
|
+
MfaChart,
|
|
730
|
+
Modal,
|
|
731
|
+
Notice,
|
|
732
|
+
POLICY_COLUMNS,
|
|
733
|
+
POLICY_FEATURES,
|
|
734
|
+
PageHeader,
|
|
735
|
+
Panel,
|
|
736
|
+
PolicyFeatureStrip,
|
|
737
|
+
PolicyTable,
|
|
738
|
+
PolicyToolbar,
|
|
739
|
+
REPORT_GROUPS,
|
|
740
|
+
RadioRow,
|
|
741
|
+
ReportCategoryBar,
|
|
742
|
+
ReportFilters,
|
|
743
|
+
ReportNavigation,
|
|
744
|
+
ReportPageHeading,
|
|
745
|
+
ReportResults,
|
|
746
|
+
SELF_SERVICE_REPORT_DATA,
|
|
747
|
+
SaveBar,
|
|
748
|
+
SectionTitle,
|
|
749
|
+
SelectField,
|
|
750
|
+
SelfServiceChart,
|
|
751
|
+
ShellFooter,
|
|
752
|
+
ShellHeader,
|
|
753
|
+
ShortcutRail,
|
|
754
|
+
Tabs,
|
|
755
|
+
TextField,
|
|
756
|
+
TextLink,
|
|
757
|
+
TopNavigation,
|
|
758
|
+
WidgetFrame,
|
|
759
|
+
normalizeReport
|
|
760
|
+
};
|