@nice2dev/admin 0.1.0 → 1.0.3
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/CHANGELOG.md +32 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +123 -0
- package/dist/index.mjs +644 -423
- package/package.json +25 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,41 @@
|
|
|
1
|
-
# Changelog
|
|
1
|
+
# @nice2dev/admin — Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.0] — 2026-03-25
|
|
4
|
+
|
|
5
|
+
### Added (FAZA 7.6)
|
|
6
|
+
|
|
7
|
+
- **DashboardGrid** — configurable dashboard with draggable widgets
|
|
8
|
+
- **UserTable** — user management table with CRUD
|
|
9
|
+
- **RoleEditor** — role/permission assignment matrix
|
|
10
|
+
- **AuditLog** — searchable audit trail with filters
|
|
11
|
+
- **SettingsPanel** — app settings with categories
|
|
12
|
+
- **FeatureFlagManager** — toggle features with % rollout, user targeting
|
|
13
|
+
- **SystemHealth** — real-time system status dashboard
|
|
14
|
+
- **BackupManager** — backup/restore with scheduling
|
|
15
|
+
- **HoneyTokenDashboard** — intrusion detection tokens
|
|
16
|
+
- **ImportExport** — data import/export wizard
|
|
17
|
+
- 10 unit tests
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## [0.1.0] — 2025-06-01
|
|
22
|
+
|
|
23
|
+
Initial beta scaffolding.
|
|
2
24
|
|
|
3
25
|
All notable changes to **@nice2dev/admin** will be documented in this file.
|
|
4
26
|
|
|
5
27
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
28
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
29
|
|
|
30
|
+
## [0.2.0] — 2026-06-16
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- `NiceHoneyTokenDashboard` — honey token security dashboard for detecting unauthorized access via decoy resources
|
|
35
|
+
- `useFeatureGate` — React hook for feature flag gating with fallback rendering
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
8
39
|
## [0.1.0] — 2025-06-01
|
|
9
40
|
|
|
10
41
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("react"),D=a.forwardRef(function(C,y){const{widgets:u,columns:g=4,title:p="Dashboard",headerActions:j,onWidgetClick:h,className:N,style:v}=C;return e.jsxs("div",{ref:y,className:`nice-admin-dashboard ${N??""}`,style:v,children:[e.jsxs("div",{className:"nice-admin-dashboard__header",children:[e.jsx("h2",{children:p}),j&&e.jsx("div",{className:"nice-admin-dashboard__actions",children:j})]}),e.jsx("div",{className:"nice-admin-dashboard__grid",style:{display:"grid",gridTemplateColumns:`repeat(${g}, 1fr)`,gap:16},children:u.map(l=>e.jsxs("div",{className:`nice-admin-dashboard__widget nice-admin-dashboard__widget--${l.type}`,style:{gridColumn:l.colSpan?`span ${l.colSpan}`:void 0,gridRow:l.rowSpan?`span ${l.rowSpan}`:void 0},onClick:()=>h==null?void 0:h(l),role:h?"button":void 0,tabIndex:h?0:void 0,children:[e.jsxs("div",{className:"nice-admin-dashboard__widget-header",children:[l.icon&&e.jsx("span",{className:"nice-admin-dashboard__widget-icon",children:l.icon}),e.jsx("span",{className:"nice-admin-dashboard__widget-title",children:l.title})]}),l.type==="stat"&&e.jsxs("div",{className:"nice-admin-dashboard__stat",children:[e.jsx("span",{className:"nice-admin-dashboard__stat-value",children:l.value}),l.change&&e.jsx("span",{className:`nice-admin-dashboard__stat-change ${l.changePositive?"nice-admin-dashboard__stat-change--positive":"nice-admin-dashboard__stat-change--negative"}`,children:l.change})]}),l.type==="custom"&&l.render&&e.jsx("div",{className:"nice-admin-dashboard__custom",children:l.render()}),(l.type==="chart"||l.type==="table"||l.type==="list")&&l.render&&e.jsx("div",{className:"nice-admin-dashboard__content",children:l.render()})]},l.id))})]})}),I={active:"#22c55e",inactive:"#9ca3af",suspended:"#ef4444",pending:"#eab308"},$=a.forwardRef(function(C,y){const{users:u,availableRoles:g=[],onCreate:p,onEdit:j,onDelete:h,onToggleStatus:N,onChangeRoles:v,searchable:l=!0,title:S="User Management",className:b,style:x}=C,[_,f]=a.useState(""),[i,s]=a.useState(""),n=a.useMemo(()=>{let t=u;if(i&&(t=t.filter(m=>m.status===i)),_.trim()){const m=_.toLowerCase();t=t.filter(A=>A.name.toLowerCase().includes(m)||A.email.toLowerCase().includes(m)||A.roles.some(L=>L.toLowerCase().includes(m)))}return t},[u,i,_]),o=a.useCallback(t=>{if(!N)return;const m=t.status==="active"?"suspended":"active";N(t.id,m)},[N]);return e.jsxs("div",{ref:y,className:`nice-admin-users ${b??""}`,style:x,children:[e.jsxs("div",{className:"nice-admin-users__header",children:[e.jsx("h3",{children:S}),e.jsxs("span",{className:"nice-admin-users__count",children:[u.length," users"]}),p&&e.jsx("button",{className:"nice-admin-users__create-btn",onClick:p,children:"+ Add User"})]}),e.jsxs("div",{className:"nice-admin-users__toolbar",children:[l&&e.jsx("input",{type:"text",value:_,onChange:t=>f(t.target.value),placeholder:"Search users…",className:"nice-admin-users__search"}),e.jsxs("select",{value:i,onChange:t=>s(t.target.value),className:"nice-admin-users__status-filter",children:[e.jsx("option",{value:"",children:"All statuses"}),e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"inactive",children:"Inactive"}),e.jsx("option",{value:"suspended",children:"Suspended"}),e.jsx("option",{value:"pending",children:"Pending"})]})]}),n.length===0?e.jsx("p",{className:"nice-admin-users__empty",children:"No users found."}):e.jsxs("table",{className:"nice-admin-users__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"User"}),e.jsx("th",{children:"Email"}),e.jsx("th",{children:"Roles"}),e.jsx("th",{children:"Status"}),e.jsx("th",{children:"Created"}),e.jsx("th",{children:"Last Login"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:n.map(t=>e.jsxs("tr",{children:[e.jsxs("td",{className:"nice-admin-users__user-cell",children:[t.avatarUrl&&e.jsx("img",{src:t.avatarUrl,alt:"",className:"nice-admin-users__avatar"}),e.jsx("span",{children:t.name})]}),e.jsx("td",{children:t.email}),e.jsx("td",{children:v?e.jsx("select",{multiple:!0,value:t.roles,onChange:m=>{const A=Array.from(m.target.selectedOptions,L=>L.value);v(t.id,A)},className:"nice-admin-users__roles-select",children:g.map(m=>e.jsx("option",{value:m,children:m},m))}):t.roles.join(", ")}),e.jsx("td",{children:e.jsx("span",{className:"nice-admin-users__status-badge",style:{backgroundColor:I[t.status]},onClick:()=>o(t),role:N?"button":void 0,children:t.status})}),e.jsx("td",{children:t.createdAt}),e.jsx("td",{children:t.lastLoginAt??"—"}),e.jsxs("td",{className:"nice-admin-users__actions",children:[j&&e.jsx("button",{onClick:()=>j(t),children:"Edit"}),h&&e.jsx("button",{onClick:()=>h(t.id),children:"Delete"})]})]},t.id))})]})]})}),M=a.forwardRef(function(C,y){var d;const{roles:u,actions:g,resources:p,onPermissionChange:j,onCreate:h,onDelete:N,onRename:v,title:l="Role Management",className:S,style:b}=C,[x,_]=a.useState(((d=u[0])==null?void 0:d.id)??null),[f,i]=a.useState(!1),[s,n]=a.useState(""),[o,t]=a.useState(""),m=u.find(r=>r.id===x),A=a.useCallback(()=>{!s.trim()||!h||(h(s.trim(),o.trim()),n(""),t(""),i(!1))},[s,o,h]),L=(r,c,k)=>{var R;return((R=r.permissions[c])==null?void 0:R.includes(k))??!1};return e.jsxs("div",{ref:y,className:`nice-admin-roles ${S??""}`,style:b,children:[e.jsxs("div",{className:"nice-admin-roles__header",children:[e.jsx("h3",{children:l}),h&&e.jsx("button",{onClick:()=>i(!f),children:"+ New Role"})]}),f&&e.jsxs("div",{className:"nice-admin-roles__create-form",children:[e.jsx("input",{type:"text",value:s,onChange:r=>n(r.target.value),placeholder:"Role name"}),e.jsx("input",{type:"text",value:o,onChange:r=>t(r.target.value),placeholder:"Description"}),e.jsx("button",{onClick:A,disabled:!s.trim(),children:"Create"}),e.jsx("button",{onClick:()=>i(!1),children:"Cancel"})]}),e.jsx("div",{className:"nice-admin-roles__tabs",children:u.map(r=>e.jsxs("button",{className:`nice-admin-roles__tab ${r.id===x?"nice-admin-roles__tab--active":""}`,onClick:()=>_(r.id),style:r.color?{borderColor:r.color}:void 0,children:[r.name,r.userCount!=null&&e.jsxs("span",{className:"nice-admin-roles__tab-count",children:["(",r.userCount,")"]}),r.isSystem&&e.jsx("span",{className:"nice-admin-roles__tab-system",children:"🔒"})]},r.id))}),m&&e.jsxs("div",{className:"nice-admin-roles__matrix-wrap",children:[m.description&&e.jsx("p",{className:"nice-admin-roles__description",children:m.description}),e.jsxs("table",{className:"nice-admin-roles__matrix",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Resource"}),g.map(r=>e.jsx("th",{title:r.description,children:r.label},r.id))]})}),e.jsx("tbody",{children:p.map(r=>e.jsxs("tr",{children:[e.jsx("td",{children:r.label}),g.map(c=>{const k=L(m,r.id,c.id);return e.jsx("td",{children:e.jsx("input",{type:"checkbox",checked:k,onChange:()=>j==null?void 0:j(m.id,r.id,c.id,!k),disabled:m.isSystem})},c.id)})]},r.id))})]}),!m.isSystem&&e.jsxs("div",{className:"nice-admin-roles__role-actions",children:[v&&e.jsx("button",{onClick:()=>{const r=prompt("New role name:",m.name);r&&v(m.id,r)},children:"Rename"}),N&&e.jsx("button",{onClick:()=>N(m.id),children:"Delete Role"})]})]})]})}),T={info:{color:"#3b82f6",label:"INFO"},warning:{color:"#eab308",label:"WARN"},error:{color:"#ef4444",label:"ERROR"},critical:{color:"#dc2626",label:"CRIT"}},U=a.forwardRef(function(C,y){const{entries:u,onEntryClick:g,onLoadMore:p,hasMore:j=!1,searchable:h=!0,showSeverityFilter:N=!0,title:v="Audit Log",className:l,style:S}=C,[b,x]=a.useState(""),[_,f]=a.useState(""),i=a.useMemo(()=>{let s=u;if(_&&(s=s.filter(n=>n.severity===_)),b.trim()){const n=b.toLowerCase();s=s.filter(o=>{var t;return o.actorName.toLowerCase().includes(n)||o.action.toLowerCase().includes(n)||o.resource.toLowerCase().includes(n)||((t=o.details)==null?void 0:t.toLowerCase().includes(n))})}return s},[u,_,b]);return e.jsxs("div",{ref:y,className:`nice-admin-audit-log ${l??""}`,style:S,children:[e.jsxs("div",{className:"nice-admin-audit-log__header",children:[e.jsx("h3",{children:v}),e.jsxs("span",{className:"nice-admin-audit-log__count",children:[u.length," entries"]})]}),e.jsxs("div",{className:"nice-admin-audit-log__toolbar",children:[h&&e.jsx("input",{type:"text",value:b,onChange:s=>x(s.target.value),placeholder:"Search audit log…",className:"nice-admin-audit-log__search"}),N&&e.jsxs("select",{value:_,onChange:s=>f(s.target.value),className:"nice-admin-audit-log__severity-filter",children:[e.jsx("option",{value:"",children:"All severities"}),e.jsx("option",{value:"info",children:"Info"}),e.jsx("option",{value:"warning",children:"Warning"}),e.jsx("option",{value:"error",children:"Error"}),e.jsx("option",{value:"critical",children:"Critical"})]})]}),i.length===0?e.jsx("p",{className:"nice-admin-audit-log__empty",children:"No audit log entries found."}):e.jsxs("table",{className:"nice-admin-audit-log__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Timestamp"}),e.jsx("th",{children:"Severity"}),e.jsx("th",{children:"Actor"}),e.jsx("th",{children:"Action"}),e.jsx("th",{children:"Resource"}),e.jsx("th",{children:"IP"}),e.jsx("th",{children:"Details"})]})}),e.jsx("tbody",{children:i.map(s=>{const n=T[s.severity];return e.jsxs("tr",{className:"nice-admin-audit-log__row",onClick:()=>g==null?void 0:g(s),role:g?"button":void 0,tabIndex:g?0:void 0,children:[e.jsx("td",{children:s.timestamp}),e.jsx("td",{children:e.jsx("span",{className:"nice-admin-audit-log__severity",style:{color:n.color},children:n.label})}),e.jsx("td",{children:s.actorName}),e.jsx("td",{children:s.action}),e.jsxs("td",{children:[s.resource,s.resourceId?` #${s.resourceId}`:""]}),e.jsx("td",{children:s.ipAddress??"—"}),e.jsx("td",{className:"nice-admin-audit-log__details",children:s.details??"—"})]},s.id)})})]}),j&&p&&e.jsx("button",{className:"nice-admin-audit-log__load-more",onClick:p,children:"Load more"})]})}),q=a.forwardRef(function(C,y){const{settings:u,onSave:g,onChange:p,onReset:j,saving:h=!1,title:N="Settings",className:v,style:l}=C,[S,b]=a.useState(()=>{const s={};for(const n of u)s[n.key]=n.value;return s}),x=a.useCallback((s,n)=>{b(o=>({...o,[s]:n})),p==null||p(s,n)},[p]),_=a.useCallback(()=>{g==null||g(S)},[g,S]),f=new Map;for(const s of u){const n=s.section??"General";f.has(n)||f.set(n,[]),f.get(n).push(s)}const i=s=>{var o;const n=S[s.key];switch(s.type){case"boolean":return e.jsxs("label",{className:"nice-admin-settings__toggle",children:[e.jsx("input",{type:"checkbox",checked:!!n,onChange:t=>x(s.key,t.target.checked)}),s.label]});case"select":return e.jsx("select",{value:String(n??""),onChange:t=>x(s.key,t.target.value),className:"nice-admin-settings__select",children:(o=s.options)==null?void 0:o.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value))});case"textarea":return e.jsx("textarea",{value:String(n??""),onChange:t=>x(s.key,t.target.value),placeholder:s.placeholder,className:"nice-admin-settings__textarea",rows:4});case"number":return e.jsx("input",{type:"number",value:n!=null?Number(n):"",onChange:t=>x(s.key,parseFloat(t.target.value)||0),placeholder:s.placeholder,className:"nice-admin-settings__input"});case"color":return e.jsx("input",{type:"color",value:String(n??"#000000"),onChange:t=>x(s.key,t.target.value),className:"nice-admin-settings__color"});case"password":return e.jsx("input",{type:"password",value:String(n??""),onChange:t=>x(s.key,t.target.value),placeholder:s.placeholder,className:"nice-admin-settings__input",autoComplete:"new-password"});default:return e.jsx("input",{type:"text",value:String(n??""),onChange:t=>x(s.key,t.target.value),placeholder:s.placeholder,className:"nice-admin-settings__input"})}};return e.jsxs("div",{ref:y,className:`nice-admin-settings ${v??""}`,style:l,children:[e.jsx("div",{className:"nice-admin-settings__header",children:e.jsx("h3",{children:N})}),Array.from(f.entries()).map(([s,n])=>e.jsxs("fieldset",{className:"nice-admin-settings__section",children:[e.jsx("legend",{children:s}),n.map(o=>e.jsxs("div",{className:"nice-admin-settings__field",children:[o.type!=="boolean"&&e.jsxs("label",{className:"nice-admin-settings__label",children:[o.label,o.required&&e.jsx("span",{className:"nice-admin-settings__required",children:"*"})]}),o.description&&e.jsx("p",{className:"nice-admin-settings__description",children:o.description}),i(o)]},o.key))]},s)),e.jsxs("div",{className:"nice-admin-settings__actions",children:[e.jsx("button",{className:"nice-admin-settings__save-btn",onClick:_,disabled:h,children:h?"Saving…":"Save Settings"}),j&&e.jsx("button",{className:"nice-admin-settings__reset-btn",onClick:j,children:"Reset to Defaults"})]})]})}),O=a.forwardRef(function(C,y){const{notifications:u,availableChannels:g=["email","push","sms","in-app","webhook"],onToggle:p,onEdit:j,onTest:h,onCreate:N,onDelete:v,title:l="Notification Management",className:S,style:b}=C,[x,_]=a.useState(""),f=a.useMemo(()=>{if(!x.trim())return u;const i=x.toLowerCase();return u.filter(s=>{var n;return s.name.toLowerCase().includes(i)||s.event.toLowerCase().includes(i)||((n=s.description)==null?void 0:n.toLowerCase().includes(i))})},[u,x]);return e.jsxs("div",{ref:y,className:`nice-admin-notifications ${S??""}`,style:b,children:[e.jsxs("div",{className:"nice-admin-notifications__header",children:[e.jsx("h3",{children:l}),N&&e.jsx("button",{onClick:N,children:"+ New Notification"})]}),e.jsx("input",{type:"text",value:x,onChange:i=>_(i.target.value),placeholder:"Search notifications…",className:"nice-admin-notifications__search"}),f.length===0?e.jsx("p",{className:"nice-admin-notifications__empty",children:"No notifications found."}):e.jsxs("table",{className:"nice-admin-notifications__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Enabled"}),e.jsx("th",{children:"Name"}),e.jsx("th",{children:"Event"}),e.jsx("th",{children:"Channels"}),e.jsx("th",{children:"Last Sent"}),e.jsx("th",{children:"Sent"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:f.map(i=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("input",{type:"checkbox",checked:i.enabled,onChange:()=>p==null?void 0:p(i.id,!i.enabled)})}),e.jsxs("td",{children:[e.jsx("strong",{children:i.name}),i.description&&e.jsx("br",{}),i.description&&e.jsx("small",{children:i.description})]}),e.jsx("td",{children:e.jsx("code",{children:i.event})}),e.jsx("td",{children:i.channels.join(", ")}),e.jsx("td",{children:i.lastSentAt??"—"}),e.jsx("td",{children:i.sentCount??0}),e.jsxs("td",{className:"nice-admin-notifications__actions",children:[j&&e.jsx("button",{onClick:()=>j(i),children:"Edit"}),h&&e.jsx("button",{onClick:()=>h(i.id),children:"Test"}),v&&e.jsx("button",{onClick:()=>v(i.id),children:"Delete"})]})]},i.id))})]})]})}),P=a.forwardRef(function(C,y){const{flags:u,environmentNames:g=["development","staging","production"],onToggle:p,onPercentageChange:j,onCreate:h,onDelete:N,onEdit:v,title:l="Feature Flags",className:S,style:b}=C,[x,_]=a.useState(""),[f,i]=a.useState(!1),[s,n]=a.useState(""),[o,t]=a.useState(""),[m,A]=a.useState(""),L=a.useMemo(()=>{if(!x.trim())return u;const c=x.toLowerCase();return u.filter(k=>{var R,w;return k.key.toLowerCase().includes(c)||k.name.toLowerCase().includes(c)||((R=k.description)==null?void 0:R.toLowerCase().includes(c))||((w=k.tags)==null?void 0:w.some(F=>F.toLowerCase().includes(c)))})},[u,x]),d=a.useCallback(()=>{!s.trim()||!o.trim()||!h||(h(s.trim(),o.trim(),m.trim()),n(""),t(""),A(""),i(!1))},[s,o,m,h]),r=(c,k)=>c.environments.find(R=>R.name===k);return e.jsxs("div",{ref:y,className:`nice-feature-flags ${S??""}`,style:b,children:[e.jsxs("div",{className:"nice-feature-flags__header",children:[e.jsx("h3",{children:l}),e.jsxs("span",{className:"nice-feature-flags__count",children:[u.length," flags"]}),h&&e.jsx("button",{onClick:()=>i(!f),children:"+ New Flag"})]}),f&&e.jsxs("div",{className:"nice-feature-flags__create-form",children:[e.jsx("input",{type:"text",value:s,onChange:c=>n(c.target.value),placeholder:"flag_key"}),e.jsx("input",{type:"text",value:o,onChange:c=>t(c.target.value),placeholder:"Display name"}),e.jsx("input",{type:"text",value:m,onChange:c=>A(c.target.value),placeholder:"Description"}),e.jsx("button",{onClick:d,disabled:!s.trim()||!o.trim(),children:"Create"}),e.jsx("button",{onClick:()=>i(!1),children:"Cancel"})]}),e.jsx("input",{type:"text",value:x,onChange:c=>_(c.target.value),placeholder:"Search flags…",className:"nice-feature-flags__search"}),L.length===0?e.jsx("p",{className:"nice-feature-flags__empty",children:"No feature flags found."}):e.jsxs("table",{className:"nice-feature-flags__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Flag"}),g.map(c=>e.jsx("th",{children:c},c)),e.jsx("th",{children:"Tags"}),e.jsx("th",{children:"Updated"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:L.map(c=>{var k;return e.jsxs("tr",{children:[e.jsx("td",{children:e.jsxs("div",{className:"nice-feature-flags__flag-info",children:[e.jsx("strong",{children:c.name}),e.jsx("code",{className:"nice-feature-flags__key",children:c.key}),c.description&&e.jsx("small",{children:c.description})]})}),g.map(R=>{const w=r(c,R);return e.jsxs("td",{className:"nice-feature-flags__env-cell",children:[e.jsx("input",{type:"checkbox",checked:(w==null?void 0:w.enabled)??!1,onChange:()=>p==null?void 0:p(c.id,R,!((w==null?void 0:w.enabled)??!1))}),(w==null?void 0:w.percentage)!=null&&e.jsx("input",{type:"number",min:0,max:100,value:w.percentage,onChange:F=>j==null?void 0:j(c.id,R,parseInt(F.target.value,10)||0),className:"nice-feature-flags__percentage",title:"Rollout %"})]},R)}),e.jsx("td",{children:((k=c.tags)==null?void 0:k.join(", "))||"—"}),e.jsx("td",{children:c.updatedAt??c.createdAt}),e.jsxs("td",{className:"nice-feature-flags__actions",children:[v&&e.jsx("button",{onClick:()=>v(c),children:"Edit"}),N&&e.jsx("button",{onClick:()=>N(c.id),children:"Delete"})]})]},c.id)})})]})]})}),G=a.forwardRef(function(C,y){var L;const{entities:u,formats:g=["json","csv","xlsx"],jobs:p=[],onImport:j,onExport:h,onDownload:N,title:v="Import / Export",className:l,style:S}=C,[b,x]=a.useState("export"),[_,f]=a.useState(((L=u[0])==null?void 0:L.id)??""),[i,s]=a.useState(g[0]??"json"),[n,o]=a.useState(null),t=a.useCallback(()=>{!j||!n||!_||(j(_,i,n),o(null))},[j,_,i,n]),m=a.useCallback(()=>{!h||!_||h(_,i)},[h,_,i]),A=d=>{var r;o(((r=d.target.files)==null?void 0:r[0])??null)};return e.jsxs("div",{ref:y,className:`nice-import-export ${l??""}`,style:S,children:[e.jsx("div",{className:"nice-import-export__header",children:e.jsx("h3",{children:v})}),e.jsxs("div",{className:"nice-import-export__tabs",children:[e.jsx("button",{className:`nice-import-export__tab ${b==="import"?"nice-import-export__tab--active":""}`,onClick:()=>x("import"),children:"Import"}),e.jsx("button",{className:`nice-import-export__tab ${b==="export"?"nice-import-export__tab--active":""}`,onClick:()=>x("export"),children:"Export"})]}),e.jsxs("div",{className:"nice-import-export__form",children:[e.jsxs("label",{children:["Entity",e.jsx("select",{value:_,onChange:d=>f(d.target.value),children:u.map(d=>e.jsx("option",{value:d.id,children:d.label},d.id))})]}),e.jsxs("label",{children:["Format",e.jsx("select",{value:i,onChange:d=>s(d.target.value),children:g.map(d=>e.jsx("option",{value:d,children:d.toUpperCase()},d))})]}),b==="import"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{children:["File",e.jsx("input",{type:"file",onChange:A,accept:`.${i}`})]}),e.jsx("button",{className:"nice-import-export__action-btn",onClick:t,disabled:!n,children:"Start Import"})]}),b==="export"&&e.jsx("button",{className:"nice-import-export__action-btn",onClick:m,children:"Start Export"})]}),p.length>0&&e.jsxs("div",{className:"nice-import-export__jobs",children:[e.jsx("h4",{children:"Recent Jobs"}),e.jsxs("table",{className:"nice-import-export__jobs-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Type"}),e.jsx("th",{children:"Format"}),e.jsx("th",{children:"Status"}),e.jsx("th",{children:"Progress"}),e.jsx("th",{children:"Errors"}),e.jsx("th",{children:"Created"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:p.map(d=>e.jsxs("tr",{children:[e.jsx("td",{children:d.type}),e.jsx("td",{children:d.format.toUpperCase()}),e.jsx("td",{children:e.jsx("span",{className:`nice-import-export__status nice-import-export__status--${d.status}`,children:d.status})}),e.jsx("td",{children:d.processedRows!=null&&d.totalRows?`${d.processedRows} / ${d.totalRows}`:"—"}),e.jsx("td",{children:d.errorCount??0}),e.jsx("td",{children:d.createdAt}),e.jsx("td",{children:d.type==="export"&&d.status==="completed"&&N&&e.jsx("button",{onClick:()=>N(d.id),children:"Download"})})]},d.id))})]})]})]})});exports.NiceAdminAuditLog=U;exports.NiceAdminDashboard=D;exports.NiceAdminNotifications=O;exports.NiceAdminRoles=M;exports.NiceAdminSettings=q;exports.NiceAdminUsers=$;exports.NiceFeatureFlags=P;exports.NiceImportExport=G;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("react"),G=a.forwardRef(function(p,_){const{widgets:u,columns:b=4,title:g="Dashboard",headerActions:v,onWidgetClick:x,className:f,style:y}=p;return e.jsxs("div",{ref:_,className:`nice-admin-dashboard ${f??""}`,style:y,children:[e.jsxs("div",{className:"nice-admin-dashboard__header",children:[e.jsx("h2",{children:g}),v&&e.jsx("div",{className:"nice-admin-dashboard__actions",children:v})]}),e.jsx("div",{className:"nice-admin-dashboard__grid",style:{display:"grid",gridTemplateColumns:`repeat(${b}, 1fr)`,gap:16},children:u.map(r=>e.jsxs("div",{className:`nice-admin-dashboard__widget nice-admin-dashboard__widget--${r.type}`,style:{gridColumn:r.colSpan?`span ${r.colSpan}`:void 0,gridRow:r.rowSpan?`span ${r.rowSpan}`:void 0},onClick:()=>x==null?void 0:x(r),role:x?"button":void 0,tabIndex:x?0:void 0,children:[e.jsxs("div",{className:"nice-admin-dashboard__widget-header",children:[r.icon&&e.jsx("span",{className:"nice-admin-dashboard__widget-icon",children:r.icon}),e.jsx("span",{className:"nice-admin-dashboard__widget-title",children:r.title})]}),r.type==="stat"&&e.jsxs("div",{className:"nice-admin-dashboard__stat",children:[e.jsx("span",{className:"nice-admin-dashboard__stat-value",children:r.value}),r.change&&e.jsx("span",{className:`nice-admin-dashboard__stat-change ${r.changePositive?"nice-admin-dashboard__stat-change--positive":"nice-admin-dashboard__stat-change--negative"}`,children:r.change})]}),r.type==="custom"&&r.render&&e.jsx("div",{className:"nice-admin-dashboard__custom",children:r.render()}),(r.type==="chart"||r.type==="table"||r.type==="list")&&r.render&&e.jsx("div",{className:"nice-admin-dashboard__content",children:r.render()})]},r.id))})]})}),O={active:"#22c55e",inactive:"#9ca3af",suspended:"#ef4444",pending:"#eab308"},q=a.forwardRef(function(p,_){const{users:u,availableRoles:b=[],onCreate:g,onEdit:v,onDelete:x,onToggleStatus:f,onChangeRoles:y,searchable:r=!0,title:k="User Management",className:S,style:j}=p,[N,C]=a.useState(""),[i,s]=a.useState(""),c=a.useMemo(()=>{let n=u;if(i&&(n=n.filter(m=>m.status===i)),N.trim()){const m=N.toLowerCase();n=n.filter(R=>R.name.toLowerCase().includes(m)||R.email.toLowerCase().includes(m)||R.roles.some(F=>F.toLowerCase().includes(m)))}return n},[u,i,N]),h=a.useCallback(n=>{if(!f)return;const m=n.status==="active"?"suspended":"active";f(n.id,m)},[f]);return e.jsxs("div",{ref:_,className:`nice-admin-users ${S??""}`,style:j,children:[e.jsxs("div",{className:"nice-admin-users__header",children:[e.jsx("h3",{children:k}),e.jsxs("span",{className:"nice-admin-users__count",children:[u.length," users"]}),g&&e.jsx("button",{className:"nice-admin-users__create-btn",onClick:g,children:"+ Add User"})]}),e.jsxs("div",{className:"nice-admin-users__toolbar",children:[r&&e.jsx("input",{type:"text",value:N,onChange:n=>C(n.target.value),placeholder:"Search users…",className:"nice-admin-users__search"}),e.jsxs("select",{value:i,onChange:n=>s(n.target.value),className:"nice-admin-users__status-filter",children:[e.jsx("option",{value:"",children:"All statuses"}),e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"inactive",children:"Inactive"}),e.jsx("option",{value:"suspended",children:"Suspended"}),e.jsx("option",{value:"pending",children:"Pending"})]})]}),c.length===0?e.jsx("p",{className:"nice-admin-users__empty",children:"No users found."}):e.jsxs("table",{className:"nice-admin-users__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"User"}),e.jsx("th",{children:"Email"}),e.jsx("th",{children:"Roles"}),e.jsx("th",{children:"Status"}),e.jsx("th",{children:"Created"}),e.jsx("th",{children:"Last Login"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:c.map(n=>e.jsxs("tr",{children:[e.jsxs("td",{className:"nice-admin-users__user-cell",children:[n.avatarUrl&&e.jsx("img",{src:n.avatarUrl,alt:"",className:"nice-admin-users__avatar"}),e.jsx("span",{children:n.name})]}),e.jsx("td",{children:n.email}),e.jsx("td",{children:y?e.jsx("select",{multiple:!0,value:n.roles,onChange:m=>{const R=Array.from(m.target.selectedOptions,F=>F.value);y(n.id,R)},className:"nice-admin-users__roles-select",children:b.map(m=>e.jsx("option",{value:m,children:m},m))}):n.roles.join(", ")}),e.jsx("td",{children:e.jsx("span",{className:"nice-admin-users__status-badge",style:{backgroundColor:O[n.status]},onClick:()=>h(n),role:f?"button":void 0,children:n.status})}),e.jsx("td",{children:n.createdAt}),e.jsx("td",{children:n.lastLoginAt??"—"}),e.jsxs("td",{className:"nice-admin-users__actions",children:[v&&e.jsx("button",{onClick:()=>v(n),children:"Edit"}),x&&e.jsx("button",{onClick:()=>x(n.id),children:"Delete"})]})]},n.id))})]})]})}),P=a.forwardRef(function(p,_){var o;const{roles:u,actions:b,resources:g,onPermissionChange:v,onCreate:x,onDelete:f,onRename:y,title:r="Role Management",className:k,style:S}=p,[j,N]=a.useState(((o=u[0])==null?void 0:o.id)??null),[C,i]=a.useState(!1),[s,c]=a.useState(""),[h,n]=a.useState(""),m=u.find(l=>l.id===j),R=a.useCallback(()=>{!s.trim()||!x||(x(s.trim(),h.trim()),c(""),n(""),i(!1))},[s,h,x]),F=(l,d,t)=>{var w;return((w=l.permissions[d])==null?void 0:w.includes(t))??!1};return e.jsxs("div",{ref:_,className:`nice-admin-roles ${k??""}`,style:S,children:[e.jsxs("div",{className:"nice-admin-roles__header",children:[e.jsx("h3",{children:r}),x&&e.jsx("button",{onClick:()=>i(!C),children:"+ New Role"})]}),C&&e.jsxs("div",{className:"nice-admin-roles__create-form",children:[e.jsx("input",{type:"text",value:s,onChange:l=>c(l.target.value),placeholder:"Role name"}),e.jsx("input",{type:"text",value:h,onChange:l=>n(l.target.value),placeholder:"Description"}),e.jsx("button",{onClick:R,disabled:!s.trim(),children:"Create"}),e.jsx("button",{onClick:()=>i(!1),children:"Cancel"})]}),e.jsx("div",{className:"nice-admin-roles__tabs",children:u.map(l=>e.jsxs("button",{className:`nice-admin-roles__tab ${l.id===j?"nice-admin-roles__tab--active":""}`,onClick:()=>N(l.id),style:l.color?{borderColor:l.color}:void 0,children:[l.name,l.userCount!=null&&e.jsxs("span",{className:"nice-admin-roles__tab-count",children:["(",l.userCount,")"]}),l.isSystem&&e.jsx("span",{className:"nice-admin-roles__tab-system",children:"🔒"})]},l.id))}),m&&e.jsxs("div",{className:"nice-admin-roles__matrix-wrap",children:[m.description&&e.jsx("p",{className:"nice-admin-roles__description",children:m.description}),e.jsxs("table",{className:"nice-admin-roles__matrix",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Resource"}),b.map(l=>e.jsx("th",{title:l.description,children:l.label},l.id))]})}),e.jsx("tbody",{children:g.map(l=>e.jsxs("tr",{children:[e.jsx("td",{children:l.label}),b.map(d=>{const t=F(m,l.id,d.id);return e.jsx("td",{children:e.jsx("input",{type:"checkbox",checked:t,onChange:()=>v==null?void 0:v(m.id,l.id,d.id,!t),disabled:m.isSystem})},d.id)})]},l.id))})]}),!m.isSystem&&e.jsxs("div",{className:"nice-admin-roles__role-actions",children:[y&&e.jsx("button",{onClick:()=>{const l=prompt("New role name:",m.name);l&&y(m.id,l)},children:"Rename"}),f&&e.jsx("button",{onClick:()=>f(m.id),children:"Delete Role"})]})]})]})}),H={info:{color:"#3b82f6",label:"INFO"},warning:{color:"#eab308",label:"WARN"},error:{color:"#ef4444",label:"ERROR"},critical:{color:"#dc2626",label:"CRIT"}},Y=a.forwardRef(function(p,_){const{entries:u,onEntryClick:b,onLoadMore:g,hasMore:v=!1,searchable:x=!0,showSeverityFilter:f=!0,title:y="Audit Log",className:r,style:k}=p,[S,j]=a.useState(""),[N,C]=a.useState(""),i=a.useMemo(()=>{let s=u;if(N&&(s=s.filter(c=>c.severity===N)),S.trim()){const c=S.toLowerCase();s=s.filter(h=>{var n;return h.actorName.toLowerCase().includes(c)||h.action.toLowerCase().includes(c)||h.resource.toLowerCase().includes(c)||((n=h.details)==null?void 0:n.toLowerCase().includes(c))})}return s},[u,N,S]);return e.jsxs("div",{ref:_,className:`nice-admin-audit-log ${r??""}`,style:k,children:[e.jsxs("div",{className:"nice-admin-audit-log__header",children:[e.jsx("h3",{children:y}),e.jsxs("span",{className:"nice-admin-audit-log__count",children:[u.length," entries"]})]}),e.jsxs("div",{className:"nice-admin-audit-log__toolbar",children:[x&&e.jsx("input",{type:"text",value:S,onChange:s=>j(s.target.value),placeholder:"Search audit log…",className:"nice-admin-audit-log__search"}),f&&e.jsxs("select",{value:N,onChange:s=>C(s.target.value),className:"nice-admin-audit-log__severity-filter",children:[e.jsx("option",{value:"",children:"All severities"}),e.jsx("option",{value:"info",children:"Info"}),e.jsx("option",{value:"warning",children:"Warning"}),e.jsx("option",{value:"error",children:"Error"}),e.jsx("option",{value:"critical",children:"Critical"})]})]}),i.length===0?e.jsx("p",{className:"nice-admin-audit-log__empty",children:"No audit log entries found."}):e.jsxs("table",{className:"nice-admin-audit-log__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Timestamp"}),e.jsx("th",{children:"Severity"}),e.jsx("th",{children:"Actor"}),e.jsx("th",{children:"Action"}),e.jsx("th",{children:"Resource"}),e.jsx("th",{children:"IP"}),e.jsx("th",{children:"Details"})]})}),e.jsx("tbody",{children:i.map(s=>{const c=H[s.severity];return e.jsxs("tr",{className:"nice-admin-audit-log__row",onClick:()=>b==null?void 0:b(s),role:b?"button":void 0,tabIndex:b?0:void 0,children:[e.jsx("td",{children:s.timestamp}),e.jsx("td",{children:e.jsx("span",{className:"nice-admin-audit-log__severity",style:{color:c.color},children:c.label})}),e.jsx("td",{children:s.actorName}),e.jsx("td",{children:s.action}),e.jsxs("td",{children:[s.resource,s.resourceId?` #${s.resourceId}`:""]}),e.jsx("td",{children:s.ipAddress??"—"}),e.jsx("td",{className:"nice-admin-audit-log__details",children:s.details??"—"})]},s.id)})})]}),v&&g&&e.jsx("button",{className:"nice-admin-audit-log__load-more",onClick:g,children:"Load more"})]})}),V=a.forwardRef(function(p,_){const{settings:u,onSave:b,onChange:g,onReset:v,saving:x=!1,title:f="Settings",className:y,style:r}=p,[k,S]=a.useState(()=>{const s={};for(const c of u)s[c.key]=c.value;return s}),j=a.useCallback((s,c)=>{S(h=>({...h,[s]:c})),g==null||g(s,c)},[g]),N=a.useCallback(()=>{b==null||b(k)},[b,k]),C=new Map;for(const s of u){const c=s.section??"General";C.has(c)||C.set(c,[]),C.get(c).push(s)}const i=s=>{var h;const c=k[s.key];switch(s.type){case"boolean":return e.jsxs("label",{className:"nice-admin-settings__toggle",children:[e.jsx("input",{type:"checkbox",checked:!!c,onChange:n=>j(s.key,n.target.checked)}),s.label]});case"select":return e.jsx("select",{value:String(c??""),onChange:n=>j(s.key,n.target.value),className:"nice-admin-settings__select",children:(h=s.options)==null?void 0:h.map(n=>e.jsx("option",{value:n.value,children:n.label},n.value))});case"textarea":return e.jsx("textarea",{value:String(c??""),onChange:n=>j(s.key,n.target.value),placeholder:s.placeholder,className:"nice-admin-settings__textarea",rows:4});case"number":return e.jsx("input",{type:"number",value:c!=null?Number(c):"",onChange:n=>j(s.key,parseFloat(n.target.value)||0),placeholder:s.placeholder,className:"nice-admin-settings__input"});case"color":return e.jsx("input",{type:"color",value:String(c??"#000000"),onChange:n=>j(s.key,n.target.value),className:"nice-admin-settings__color"});case"password":return e.jsx("input",{type:"password",value:String(c??""),onChange:n=>j(s.key,n.target.value),placeholder:s.placeholder,className:"nice-admin-settings__input",autoComplete:"new-password"});default:return e.jsx("input",{type:"text",value:String(c??""),onChange:n=>j(s.key,n.target.value),placeholder:s.placeholder,className:"nice-admin-settings__input"})}};return e.jsxs("div",{ref:_,className:`nice-admin-settings ${y??""}`,style:r,children:[e.jsx("div",{className:"nice-admin-settings__header",children:e.jsx("h3",{children:f})}),Array.from(C.entries()).map(([s,c])=>e.jsxs("fieldset",{className:"nice-admin-settings__section",children:[e.jsx("legend",{children:s}),c.map(h=>e.jsxs("div",{className:"nice-admin-settings__field",children:[h.type!=="boolean"&&e.jsxs("label",{className:"nice-admin-settings__label",children:[h.label,h.required&&e.jsx("span",{className:"nice-admin-settings__required",children:"*"})]}),h.description&&e.jsx("p",{className:"nice-admin-settings__description",children:h.description}),i(h)]},h.key))]},s)),e.jsxs("div",{className:"nice-admin-settings__actions",children:[e.jsx("button",{className:"nice-admin-settings__save-btn",onClick:N,disabled:x,children:x?"Saving…":"Save Settings"}),v&&e.jsx("button",{className:"nice-admin-settings__reset-btn",onClick:v,children:"Reset to Defaults"})]})]})}),K=a.forwardRef(function(p,_){const{notifications:u,availableChannels:b=["email","push","sms","in-app","webhook"],onToggle:g,onEdit:v,onTest:x,onCreate:f,onDelete:y,title:r="Notification Management",className:k,style:S}=p,[j,N]=a.useState(""),C=a.useMemo(()=>{if(!j.trim())return u;const i=j.toLowerCase();return u.filter(s=>{var c;return s.name.toLowerCase().includes(i)||s.event.toLowerCase().includes(i)||((c=s.description)==null?void 0:c.toLowerCase().includes(i))})},[u,j]);return e.jsxs("div",{ref:_,className:`nice-admin-notifications ${k??""}`,style:S,children:[e.jsxs("div",{className:"nice-admin-notifications__header",children:[e.jsx("h3",{children:r}),f&&e.jsx("button",{onClick:f,children:"+ New Notification"})]}),e.jsx("input",{type:"text",value:j,onChange:i=>N(i.target.value),placeholder:"Search notifications…",className:"nice-admin-notifications__search"}),C.length===0?e.jsx("p",{className:"nice-admin-notifications__empty",children:"No notifications found."}):e.jsxs("table",{className:"nice-admin-notifications__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Enabled"}),e.jsx("th",{children:"Name"}),e.jsx("th",{children:"Event"}),e.jsx("th",{children:"Channels"}),e.jsx("th",{children:"Last Sent"}),e.jsx("th",{children:"Sent"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:C.map(i=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("input",{type:"checkbox",checked:i.enabled,onChange:()=>g==null?void 0:g(i.id,!i.enabled)})}),e.jsxs("td",{children:[e.jsx("strong",{children:i.name}),i.description&&e.jsx("br",{}),i.description&&e.jsx("small",{children:i.description})]}),e.jsx("td",{children:e.jsx("code",{children:i.event})}),e.jsx("td",{children:i.channels.join(", ")}),e.jsx("td",{children:i.lastSentAt??"—"}),e.jsx("td",{children:i.sentCount??0}),e.jsxs("td",{className:"nice-admin-notifications__actions",children:[v&&e.jsx("button",{onClick:()=>v(i),children:"Edit"}),x&&e.jsx("button",{onClick:()=>x(i.id),children:"Test"}),y&&e.jsx("button",{onClick:()=>y(i.id),children:"Delete"})]})]},i.id))})]})]})}),B=a.forwardRef(function(p,_){const{flags:u,environmentNames:b=["development","staging","production"],onToggle:g,onPercentageChange:v,onCreate:x,onDelete:f,onEdit:y,title:r="Feature Flags",className:k,style:S}=p,[j,N]=a.useState(""),[C,i]=a.useState(!1),[s,c]=a.useState(""),[h,n]=a.useState(""),[m,R]=a.useState(""),F=a.useMemo(()=>{if(!j.trim())return u;const d=j.toLowerCase();return u.filter(t=>{var w,L;return t.key.toLowerCase().includes(d)||t.name.toLowerCase().includes(d)||((w=t.description)==null?void 0:w.toLowerCase().includes(d))||((L=t.tags)==null?void 0:L.some(E=>E.toLowerCase().includes(d)))})},[u,j]),o=a.useCallback(()=>{!s.trim()||!h.trim()||!x||(x(s.trim(),h.trim(),m.trim()),c(""),n(""),R(""),i(!1))},[s,h,m,x]),l=(d,t)=>d.environments.find(w=>w.name===t);return e.jsxs("div",{ref:_,className:`nice-feature-flags ${k??""}`,style:S,children:[e.jsxs("div",{className:"nice-feature-flags__header",children:[e.jsx("h3",{children:r}),e.jsxs("span",{className:"nice-feature-flags__count",children:[u.length," flags"]}),x&&e.jsx("button",{onClick:()=>i(!C),children:"+ New Flag"})]}),C&&e.jsxs("div",{className:"nice-feature-flags__create-form",children:[e.jsx("input",{type:"text",value:s,onChange:d=>c(d.target.value),placeholder:"flag_key"}),e.jsx("input",{type:"text",value:h,onChange:d=>n(d.target.value),placeholder:"Display name"}),e.jsx("input",{type:"text",value:m,onChange:d=>R(d.target.value),placeholder:"Description"}),e.jsx("button",{onClick:o,disabled:!s.trim()||!h.trim(),children:"Create"}),e.jsx("button",{onClick:()=>i(!1),children:"Cancel"})]}),e.jsx("input",{type:"text",value:j,onChange:d=>N(d.target.value),placeholder:"Search flags…",className:"nice-feature-flags__search"}),F.length===0?e.jsx("p",{className:"nice-feature-flags__empty",children:"No feature flags found."}):e.jsxs("table",{className:"nice-feature-flags__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Flag"}),b.map(d=>e.jsx("th",{children:d},d)),e.jsx("th",{children:"Tags"}),e.jsx("th",{children:"Updated"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:F.map(d=>{var t;return e.jsxs("tr",{children:[e.jsx("td",{children:e.jsxs("div",{className:"nice-feature-flags__flag-info",children:[e.jsx("strong",{children:d.name}),e.jsx("code",{className:"nice-feature-flags__key",children:d.key}),d.description&&e.jsx("small",{children:d.description})]})}),b.map(w=>{const L=l(d,w);return e.jsxs("td",{className:"nice-feature-flags__env-cell",children:[e.jsx("input",{type:"checkbox",checked:(L==null?void 0:L.enabled)??!1,onChange:()=>g==null?void 0:g(d.id,w,!((L==null?void 0:L.enabled)??!1))}),(L==null?void 0:L.percentage)!=null&&e.jsx("input",{type:"number",min:0,max:100,value:L.percentage,onChange:E=>v==null?void 0:v(d.id,w,parseInt(E.target.value,10)||0),className:"nice-feature-flags__percentage",title:"Rollout %"})]},w)}),e.jsx("td",{children:((t=d.tags)==null?void 0:t.join(", "))||"—"}),e.jsx("td",{children:d.updatedAt??d.createdAt}),e.jsxs("td",{className:"nice-feature-flags__actions",children:[y&&e.jsx("button",{onClick:()=>y(d),children:"Edit"}),f&&e.jsx("button",{onClick:()=>f(d.id),children:"Delete"})]})]},d.id)})})]})]})}),J=a.forwardRef(function(p,_){var F;const{entities:u,formats:b=["json","csv","xlsx"],jobs:g=[],onImport:v,onExport:x,onDownload:f,title:y="Import / Export",className:r,style:k}=p,[S,j]=a.useState("export"),[N,C]=a.useState(((F=u[0])==null?void 0:F.id)??""),[i,s]=a.useState(b[0]??"json"),[c,h]=a.useState(null),n=a.useCallback(()=>{!v||!c||!N||(v(N,i,c),h(null))},[v,N,i,c]),m=a.useCallback(()=>{!x||!N||x(N,i)},[x,N,i]),R=o=>{var l;h(((l=o.target.files)==null?void 0:l[0])??null)};return e.jsxs("div",{ref:_,className:`nice-import-export ${r??""}`,style:k,children:[e.jsx("div",{className:"nice-import-export__header",children:e.jsx("h3",{children:y})}),e.jsxs("div",{className:"nice-import-export__tabs",children:[e.jsx("button",{className:`nice-import-export__tab ${S==="import"?"nice-import-export__tab--active":""}`,onClick:()=>j("import"),children:"Import"}),e.jsx("button",{className:`nice-import-export__tab ${S==="export"?"nice-import-export__tab--active":""}`,onClick:()=>j("export"),children:"Export"})]}),e.jsxs("div",{className:"nice-import-export__form",children:[e.jsxs("label",{children:["Entity",e.jsx("select",{value:N,onChange:o=>C(o.target.value),children:u.map(o=>e.jsx("option",{value:o.id,children:o.label},o.id))})]}),e.jsxs("label",{children:["Format",e.jsx("select",{value:i,onChange:o=>s(o.target.value),children:b.map(o=>e.jsx("option",{value:o,children:o.toUpperCase()},o))})]}),S==="import"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{children:["File",e.jsx("input",{type:"file",onChange:R,accept:`.${i}`})]}),e.jsx("button",{className:"nice-import-export__action-btn",onClick:n,disabled:!c,children:"Start Import"})]}),S==="export"&&e.jsx("button",{className:"nice-import-export__action-btn",onClick:m,children:"Start Export"})]}),g.length>0&&e.jsxs("div",{className:"nice-import-export__jobs",children:[e.jsx("h4",{children:"Recent Jobs"}),e.jsxs("table",{className:"nice-import-export__jobs-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Type"}),e.jsx("th",{children:"Format"}),e.jsx("th",{children:"Status"}),e.jsx("th",{children:"Progress"}),e.jsx("th",{children:"Errors"}),e.jsx("th",{children:"Created"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:g.map(o=>e.jsxs("tr",{children:[e.jsx("td",{children:o.type}),e.jsx("td",{children:o.format.toUpperCase()}),e.jsx("td",{children:e.jsx("span",{className:`nice-import-export__status nice-import-export__status--${o.status}`,children:o.status})}),e.jsx("td",{children:o.processedRows!=null&&o.totalRows?`${o.processedRows} / ${o.totalRows}`:"—"}),e.jsx("td",{children:o.errorCount??0}),e.jsx("td",{children:o.createdAt}),e.jsx("td",{children:o.type==="export"&&o.status==="completed"&&f&&e.jsx("button",{onClick:()=>f(o.id),children:"Download"})})]},o.id))})]})]})]})}),I=a.createContext({flags:{}});function W({config:A,children:p}){return e.jsx(I.Provider,{value:A,children:p})}function $(A){const p=a.useContext(I);return a.useMemo(()=>{const _=p.flags[A];return _===void 0?{enabled:!1}:typeof _=="boolean"?{enabled:_}:{enabled:_>0,percentage:_}},[p.flags,A])}function M({flag:A,fallback:p=null,children:_}){const{enabled:u}=$(A);return e.jsx(e.Fragment,{children:u?_:p})}const T={low:"#2196f3",medium:"#ff9800",high:"#f44336",critical:"#9c27b0"},D={field:"Hidden Field",endpoint:"Decoy Endpoint",file:"Canary File",credential:"Fake Credential",cookie:"Tracking Cookie"},z=a.forwardRef(function({tokens:p,events:_,onCreate:u,onToggle:b,onDelete:g,onDismissEvent:v,title:x="Honey Tokens",className:f,style:y},r){const[k,S]=a.useState(""),[j,N]=a.useState(!1),[C,i]=a.useState(""),[s,c]=a.useState("field"),[h,n]=a.useState("medium"),[m,R]=a.useState(""),F=a.useMemo(()=>p.filter(t=>t.name.toLowerCase().includes(k.toLowerCase())||t.location.toLowerCase().includes(k.toLowerCase())),[p,k]),o=a.useMemo(()=>[..._].sort((t,w)=>new Date(w.timestamp).getTime()-new Date(t.timestamp).getTime()),[_]),l=a.useMemo(()=>{const t=p.filter(E=>E.active).length,w=p.reduce((E,U)=>E+U.tripCount,0),L=_.filter(E=>E.severity==="critical").length;return{activeCount:t,totalCount:p.length,totalTrips:w,criticalEvents:L}},[p,_]),d=()=>{C.trim()&&m.trim()&&u&&(u(C.trim(),s,h,m.trim()),i(""),R(""),N(!1))};return e.jsxs("div",{ref:r,className:`nice-honey-token-dashboard${f?` ${f}`:""}`,style:y,children:[e.jsxs("div",{className:"nice-honey-token-dashboard__header",children:[e.jsx("h2",{children:x}),e.jsxs("div",{className:"nice-honey-token-dashboard__stats",children:[e.jsxs("span",{className:"nice-honey-token-dashboard__stat",children:["Active: ",l.activeCount,"/",l.totalCount]}),e.jsxs("span",{className:"nice-honey-token-dashboard__stat",children:["Trips: ",l.totalTrips]}),l.criticalEvents>0&&e.jsxs("span",{className:"nice-honey-token-dashboard__stat nice-honey-token-dashboard__stat--critical",children:["Critical: ",l.criticalEvents]})]})]}),e.jsxs("div",{className:"nice-honey-token-dashboard__toolbar",children:[e.jsx("input",{type:"text",className:"nice-honey-token-dashboard__search",placeholder:"Search tokens...",value:k,onChange:t=>S(t.target.value)}),u&&e.jsx("button",{className:"nice-honey-token-dashboard__btn",onClick:()=>N(!j),children:j?"Cancel":"+ New Token"})]}),j&&e.jsxs("div",{className:"nice-honey-token-dashboard__create",children:[e.jsx("input",{type:"text",placeholder:"Token name",value:C,onChange:t=>i(t.target.value)}),e.jsx("select",{value:s,onChange:t=>c(t.target.value),children:Object.entries(D).map(([t,w])=>e.jsx("option",{value:t,children:w},t))}),e.jsxs("select",{value:h,onChange:t=>n(t.target.value),children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"critical",children:"Critical"})]}),e.jsx("input",{type:"text",placeholder:"Location (e.g. /api/admin/secret)",value:m,onChange:t=>R(t.target.value)}),e.jsx("button",{onClick:d,children:"Create"})]}),e.jsxs("div",{className:"nice-honey-token-dashboard__tokens",children:[e.jsxs("h3",{children:["Tokens (",F.length,")"]}),e.jsxs("table",{className:"nice-honey-token-dashboard__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Name"}),e.jsx("th",{children:"Type"}),e.jsx("th",{children:"Severity"}),e.jsx("th",{children:"Location"}),e.jsx("th",{children:"Trips"}),e.jsx("th",{children:"Last Tripped"}),e.jsx("th",{children:"Status"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:F.map(t=>e.jsxs("tr",{className:t.tripCount>0?"nice-honey-token-dashboard__row--tripped":"",children:[e.jsx("td",{children:t.name}),e.jsx("td",{children:D[t.type]}),e.jsx("td",{children:e.jsx("span",{className:"nice-honey-token-dashboard__severity",style:{color:T[t.severity]},children:t.severity})}),e.jsx("td",{children:e.jsx("code",{children:t.location})}),e.jsx("td",{children:t.tripCount}),e.jsx("td",{children:t.lastTripped??"—"}),e.jsx("td",{children:e.jsx("span",{className:`nice-honey-token-dashboard__status--${t.active?"active":"inactive"}`,children:t.active?"Active":"Inactive"})}),e.jsxs("td",{children:[b&&e.jsx("button",{onClick:()=>b(t.id,!t.active),children:t.active?"Disable":"Enable"}),g&&e.jsx("button",{onClick:()=>g(t.id),children:"Delete"})]})]},t.id))})]})]}),o.length>0&&e.jsxs("div",{className:"nice-honey-token-dashboard__events",children:[e.jsxs("h3",{children:["Recent Events (",o.length,")"]}),e.jsx("div",{className:"nice-honey-token-dashboard__event-list",children:o.map(t=>e.jsxs("div",{className:`nice-honey-token-dashboard__event nice-honey-token-dashboard__event--${t.severity}`,children:[e.jsxs("div",{className:"nice-honey-token-dashboard__event-header",children:[e.jsx("strong",{children:t.tokenName}),e.jsx("span",{className:"nice-honey-token-dashboard__severity",style:{color:T[t.severity]},children:t.severity}),e.jsx("time",{children:t.timestamp})]}),e.jsxs("div",{className:"nice-honey-token-dashboard__event-details",children:[e.jsxs("span",{children:["IP: ",t.sourceIp]}),t.userId&&e.jsxs("span",{children:["User: ",t.userId]}),t.details&&e.jsx("span",{children:t.details})]}),v&&e.jsx("button",{className:"nice-honey-token-dashboard__dismiss",onClick:()=>v(t.id),children:"Dismiss"})]},t.id))})]})]})});exports.FeatureGate=M;exports.NiceAdminAuditLog=Y;exports.NiceAdminDashboard=G;exports.NiceAdminNotifications=K;exports.NiceAdminRoles=P;exports.NiceAdminSettings=V;exports.NiceAdminUsers=q;exports.NiceFeatureFlags=B;exports.NiceFeatureGate=M;exports.NiceFeatureGateProvider=W;exports.NiceHoneyTokenDashboard=z;exports.NiceImportExport=J;exports.useFeatureGate=$;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { default as default_2 } from 'react';
|
|
2
|
+
import { JSX as JSX_2 } from 'react/jsx-runtime';
|
|
2
3
|
|
|
3
4
|
/** Admin notification template. */
|
|
4
5
|
export declare interface AdminNotification {
|
|
@@ -98,6 +99,45 @@ export declare interface FeatureFlag {
|
|
|
98
99
|
tags?: string[];
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Declarative feature gate component.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* <FeatureGate flag="beta-ui" fallback={<OldUI />}>
|
|
108
|
+
* <NewUI />
|
|
109
|
+
* </FeatureGate>
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
declare function FeatureGate({ flag, fallback, children }: FeatureGateProps): JSX_2.Element;
|
|
113
|
+
export { FeatureGate }
|
|
114
|
+
export { FeatureGate as NiceFeatureGate }
|
|
115
|
+
|
|
116
|
+
/** Configuration for the feature gate provider. */
|
|
117
|
+
export declare interface FeatureGateConfig {
|
|
118
|
+
/** Map of flag key → enabled status (or percentage 0–100). */
|
|
119
|
+
flags: Record<string, boolean | number>;
|
|
120
|
+
/** Current environment name (e.g. 'production'). */
|
|
121
|
+
environment?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Props for {@link FeatureGate}. */
|
|
125
|
+
export declare interface FeatureGateProps {
|
|
126
|
+
/** Feature flag key to check. */
|
|
127
|
+
flag: string;
|
|
128
|
+
/** Content to render when the flag is disabled. */
|
|
129
|
+
fallback?: default_2.ReactNode;
|
|
130
|
+
children: default_2.ReactNode;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Result returned by {@link useFeatureGate}. */
|
|
134
|
+
export declare interface FeatureGateResult {
|
|
135
|
+
/** Whether the feature is enabled. */
|
|
136
|
+
enabled: boolean;
|
|
137
|
+
/** Rollout percentage (0–100), if applicable. */
|
|
138
|
+
percentage?: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
101
141
|
/** Feature flag environment. */
|
|
102
142
|
export declare interface FlagEnvironment {
|
|
103
143
|
name: string;
|
|
@@ -105,6 +145,39 @@ export declare interface FlagEnvironment {
|
|
|
105
145
|
percentage?: number;
|
|
106
146
|
}
|
|
107
147
|
|
|
148
|
+
/** Honey token definition. */
|
|
149
|
+
export declare interface HoneyToken {
|
|
150
|
+
id: string;
|
|
151
|
+
name: string;
|
|
152
|
+
type: HoneyTokenType;
|
|
153
|
+
severity: HoneyTokenSeverity;
|
|
154
|
+
location: string;
|
|
155
|
+
active: boolean;
|
|
156
|
+
tripCount: number;
|
|
157
|
+
lastTripped?: string;
|
|
158
|
+
createdAt: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** A single honey token trip event. */
|
|
162
|
+
export declare interface HoneyTokenEvent {
|
|
163
|
+
id: string;
|
|
164
|
+
tokenId: string;
|
|
165
|
+
tokenName: string;
|
|
166
|
+
type: HoneyTokenType;
|
|
167
|
+
severity: HoneyTokenSeverity;
|
|
168
|
+
sourceIp: string;
|
|
169
|
+
userAgent?: string;
|
|
170
|
+
userId?: string;
|
|
171
|
+
timestamp: string;
|
|
172
|
+
details?: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Honey token severity level. */
|
|
176
|
+
export declare type HoneyTokenSeverity = 'low' | 'medium' | 'high' | 'critical';
|
|
177
|
+
|
|
178
|
+
/** Honey token type. */
|
|
179
|
+
export declare type HoneyTokenType = 'field' | 'endpoint' | 'file' | 'credential' | 'cookie';
|
|
180
|
+
|
|
108
181
|
/** Import/export job status. */
|
|
109
182
|
export declare interface ImportExportJob {
|
|
110
183
|
id: string;
|
|
@@ -299,6 +372,41 @@ export declare interface NiceFeatureFlagsProps {
|
|
|
299
372
|
style?: default_2.CSSProperties;
|
|
300
373
|
}
|
|
301
374
|
|
|
375
|
+
/** Provides feature flag configuration to descendant components. */
|
|
376
|
+
export declare function NiceFeatureGateProvider({ config, children }: NiceFeatureGateProviderProps): JSX_2.Element;
|
|
377
|
+
|
|
378
|
+
/** Props for {@link NiceFeatureGateProvider}. */
|
|
379
|
+
export declare interface NiceFeatureGateProviderProps {
|
|
380
|
+
/** Feature gate configuration. */
|
|
381
|
+
config: FeatureGateConfig;
|
|
382
|
+
children: default_2.ReactNode;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** Dashboard for monitoring honey tokens (deceptive security traps). */
|
|
386
|
+
export declare const NiceHoneyTokenDashboard: default_2.ForwardRefExoticComponent<NiceHoneyTokenDashboardProps & default_2.RefAttributes<HTMLDivElement>>;
|
|
387
|
+
|
|
388
|
+
/** Props for {@link NiceHoneyTokenDashboard}. */
|
|
389
|
+
export declare interface NiceHoneyTokenDashboardProps {
|
|
390
|
+
/** Configured honey tokens. */
|
|
391
|
+
tokens: HoneyToken[];
|
|
392
|
+
/** Recent trip events. */
|
|
393
|
+
events: HoneyTokenEvent[];
|
|
394
|
+
/** Called when creating a new honey token. */
|
|
395
|
+
onCreate?: (name: string, type: HoneyTokenType, severity: HoneyTokenSeverity, location: string) => void;
|
|
396
|
+
/** Called when toggling a honey token on/off. */
|
|
397
|
+
onToggle?: (tokenId: string, active: boolean) => void;
|
|
398
|
+
/** Called when deleting a honey token. */
|
|
399
|
+
onDelete?: (tokenId: string) => void;
|
|
400
|
+
/** Called when dismissing an event. */
|
|
401
|
+
onDismissEvent?: (eventId: string) => void;
|
|
402
|
+
/** Panel title. */
|
|
403
|
+
title?: string;
|
|
404
|
+
/** Additional CSS class. */
|
|
405
|
+
className?: string;
|
|
406
|
+
/** Inline styles. */
|
|
407
|
+
style?: default_2.CSSProperties;
|
|
408
|
+
}
|
|
409
|
+
|
|
302
410
|
/**
|
|
303
411
|
* {@link NiceImportExport} — Data import/export with format selection, file upload, and job tracking.
|
|
304
412
|
*/
|
|
@@ -365,4 +473,19 @@ export declare interface SettingItem {
|
|
|
365
473
|
/** Setting value type. */
|
|
366
474
|
export declare type SettingType = 'text' | 'number' | 'boolean' | 'select' | 'textarea' | 'color' | 'password';
|
|
367
475
|
|
|
476
|
+
/**
|
|
477
|
+
* Runtime hook for conditional rendering based on feature flags.
|
|
478
|
+
*
|
|
479
|
+
* @param flag - The feature flag key to check.
|
|
480
|
+
* @returns `{ enabled, percentage }` for the given flag.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```tsx
|
|
484
|
+
* const { enabled } = useFeatureGate('new-dashboard');
|
|
485
|
+
* if (!enabled) return null;
|
|
486
|
+
* return <NewDashboard />;
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
489
|
+
export declare function useFeatureGate(flag: string): FeatureGateResult;
|
|
490
|
+
|
|
368
491
|
export { }
|