@nice2dev/ui-bi 1.1.9 → 1.1.10

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 CHANGED
@@ -1,5 +1,74 @@
1
1
  # @nice2dev/ui-bi
2
2
 
3
+ ## 1.1.10
4
+
5
+ ### Patch Changes
6
+
7
+ - The package description on npm shows a dash instead of the mis-encoded "—".
8
+ - 1.1.10 — the additive part of OmniVerk's 1.2.0 list: ui-audio builds without optional packages, one
9
+ i18n context, dictionaries per language, data props optional. No breaking changes.
10
+
11
+ **`@nice2dev/ui-audio` no longer breaks the consumer's build.** It imported `react-bootstrap`,
12
+ `recharts`, `react-window`, `react-youtube` and `pitchy` statically while declaring none of them
13
+ (only optional entries in `peerDependenciesMeta`), so a Vite app without them failed with "failed to
14
+ resolve import". Loading them with `import()` is no way out: Vite 8 (Rolldown) resolves dynamic
15
+ imports at build time and fails the same way, which made `hls.js` and `phaser` mandatory too.
16
+ `react-bootstrap`, `recharts`, `react-window` and `phaser` are now gone from the code
17
+ (`NiceBarFillEditor` uses Nice controls, `NiceVocalPerformanceReport` uses `NiceChart` /
18
+ `NicePieChart`, the karaoke editor list uses `NiceVirtualScroller`, `NiceKaraokePhaserRenderer`
19
+ renders with the DOM and keeps its name); `pitchy`, `react-youtube` and `hls.js` are regular
20
+ `dependencies`. Found on the way: in live mode the vocal performance report subtracted UltraStar note
21
+ numbers from MIDI pitch, so every singer got thousands of cents of deviation and 0 % accuracy — it now
22
+ compares pitch within the octave, as the scoring does; `NiceBarFillEditor` put a colour into a
23
+ percentage slider.
24
+
25
+ **Every package declares what its bundle imports.** A new CI gate checks every `import`, `import()`
26
+ and `require()` in the published `dist` against `dependencies` and non-optional `peerDependencies`.
27
+ To reach zero: `@nice2dev/licensing` no longer has `require('webpack')` in its main bundle (the webpack
28
+ plugin uses `compiler.webpack`; webpack 4 gets a warning instead of feature flags) and `react` is a
29
+ required peer; `@nice2dev/erp-adapter` lists `@microsoft/signalr` in `dependencies` (still loaded on
30
+ first use); `@nice2dev/icons-cursor` declares its `react-dom` peer; `@nice2dev/ui-printing` treats
31
+ `@nice2dev/ui` as a required peer.
32
+
33
+ **One copy of each package, one i18n context.** `@nice2dev/ui` carried its own copy of
34
+ `@nice2dev/ui-core` and `@nice2dev/i18n`, and `ui-forms`, `ui-api`, `ui-bi`, `ui-designers`, `ui-math`
35
+ and `ui-video` each carried a copy of all of `@nice2dev/ui` (about 4.4 MB each). Every copy had its own
36
+ React contexts: a `NiceI18nProvider` imported from `@nice2dev/i18n` did not reach the controls of
37
+ `@nice2dev/ui`, which kept their English defaults and `lang` `'en'`, and the dictionaries ended up in
38
+ an app several times. These packages now import `@nice2dev/*` instead (`ui-forms` 4.4 MB → 82 kB).
39
+ Keep every `@nice2dev/*` package on the same version.
40
+
41
+ **Dictionaries per language.** `NiceI18nLazyProvider` takes the same props as `NiceI18nProvider`
42
+ (`t`, `lang`, `overrides`, plus `fallback` and `onError`) but loads only the active language's
43
+ dictionary, with `import()`; until it arrives the controls show their built-in English (or
44
+ `fallback`), and with `t` nothing is loaded at all. Also `loadNiceDictionary(lang)`, to start in a
45
+ language without a flash of English, and `getLoadedNiceDictionary(lang)`. Exported from
46
+ `@nice2dev/i18n`, `@nice2dev/ui-core` and `@nice2dev/ui`; in the `i18n` build every language is its own
47
+ file. `NiceI18nProvider` and `NICE_I18N_DICTIONARIES` are unchanged and still bring all 30 dictionaries.
48
+ `NiceTestWrapper` (ui-core) and `NiceShowcase` (ui) use the lazy provider now, so they no longer pull
49
+ every dictionary into the apps that bundle them.
50
+
51
+ **Data props are optional.** These controls threw a `TypeError` without data and now render empty:
52
+ `NiceTreeView.nodes`, `NiceAccordion.items`, `NiceCascadeSelect.options`, `NiceAutocomplete.options`,
53
+ `NiceAuditLog.entries`, `NiceDocumentVersionList.versions`, `NicePermissionMatrix.roles` / `actions`,
54
+ `WizardStep.content`, `NiceDiagramViewer.document`, `NiceOrgChartVisualizer.data`,
55
+ `NiceSpatialViewer.document`, and in `@nice2dev/events` the lists of `NiceGiftRegistry`,
56
+ `NiceParticipantList`, `NiceExpenseSplit`, `NiceSeatingChart`, `NiceMediaCollage` and `NiceEventMedia`.
57
+ `NiceMap` without `center` centres on its markers (the whole world without markers), `NiceCountdown`
58
+ without `targetDate` shows zero and never calls `onComplete`, `NiceChat` without `onSend` is read-only
59
+ (no input), and `NiceInvitationDesigner` gains `defaultTemplate`. A CI ratchet counts the required
60
+ array props that remain.
61
+
62
+ **Smaller fixes.** `NicePieChart` draws a 100 % slice as a full circle instead of nothing. In
63
+ development `NiceThemeProvider` warns when `--nice-primary` / `--nice-color-primary` (or another linked
64
+ pair) resolves to nothing on `:root` — usually an alias cycle in the app's CSS; the theming guides say
65
+ which side to set. `@nice2dev/game-engine` exports `createAnimationClip`, `AnimatorController` and
66
+ `createAnimatorController` (two modules exported each name, so `export *` dropped all three); the other
67
+ implementations are `StateMachineAnimatorController`, `createStateMachineAnimatorController`,
68
+ `createTimelineAnimationClip` and `createRetargetingAnimationClip`.
69
+
70
+ Nothing was renamed or removed.
71
+
3
72
  ## 1.1.9
4
73
 
5
74
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-CiIML9tH.cjs");exports.NiceETLBuilder=e.NiceETLBuilder;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),_=require("@nice2dev/ui"),g=require("@nice2dev/ui-core"),p=require("react"),H=[{target:".nice-etl-builder",titleKey:"tutorial.etlBuilder.intro.title",title:"ETL builder",contentKey:"tutorial.etlBuilder.intro.content",content:"Wire sources → transformations → destinations into a pipeline, switch the views, then run it and save the configuration.",placement:"auto"}],q={id:"",name:"New Pipeline",sources:[],transformations:[],destinations:[],version:1},E=d=>/^[a-z][a-z0-9-]*$/.test(d)?e.jsx(_.NiceIcon,{name:d,size:16}):d,T=[{type:"filter",label:"Filter",icon:"filter"},{type:"map",label:"Map",icon:"shuffle"},{type:"aggregate",label:"Aggregate",icon:"∑"},{type:"join",label:"Join",icon:"link"},{type:"union",label:"Union",icon:"∪"},{type:"sort",label:"Sort",icon:"sort"},{type:"deduplicate",label:"Deduplicate",icon:"copy"},{type:"pivot",label:"Pivot",icon:"expand"},{type:"unpivot",label:"Unpivot",icon:"collapse"},{type:"split",label:"Split",icon:"scissors"},{type:"merge",label:"Merge",icon:"git-branch"},{type:"lookup",label:"Lookup",icon:"book"},{type:"derive",label:"Derive Column",icon:"plus"},{type:"validate",label:"Validate",icon:"check"},{type:"cleanse",label:"Cleanse",icon:"wand"},{type:"custom",label:"Custom",icon:"ƒ"}];function K({pipeline:d,dataSources:l=[],onChange:c,onRun:t,onSchedule:h,className:r="",tutorial:m}){const{t:n}=g.useNiceTranslation(),[u,L]=p.useState(d||{...q,id:crypto.randomUUID()}),[o,b]=p.useState(null),[f,U]=p.useState("design"),[N,w]=p.useState(!1),[P,A]=p.useState([]),[v,B]=p.useState(null),I=p.useRef(null),x=p.useCallback(i=>{L(s=>{const a=i(s);return c==null||c(a),a})},[c]),k=p.useCallback(i=>{var a;const s={id:crypto.randomUUID(),type:i.type,name:i.name,config:i.config,schema:(a=i.schema)==null?void 0:a.tables[0]};x(j=>({...j,sources:[...j.sources,s]}))},[x]),D=p.useCallback((i,s)=>{var j;const a={id:crypto.randomUUID(),type:i,name:((j=T.find(y=>y.type===i))==null?void 0:j.label)||i,input:[],output:crypto.randomUUID(),config:V(i)};x(y=>({...y,transformations:[...y.transformations,a]})),b({type:"transformation",id:a.id})},[x]),F=p.useCallback(()=>{const i={id:crypto.randomUUID(),type:"database",name:"New Destination",config:{},writeMode:"append"};x(s=>({...s,destinations:[...s.destinations,i]})),b({type:"destination",id:i.id})},[x]),C=p.useCallback((i,s)=>{x(a=>{switch(i){case"source":return{...a,sources:a.sources.filter(j=>j.id!==s)};case"transformation":return{...a,transformations:a.transformations.filter(j=>j.id!==s)};case"destination":return{...a,destinations:a.destinations.filter(j=>j.id!==s)};default:return a}}),b(null)},[x]),R=p.useCallback(async()=>{if(t){w(!0);try{const i=await t(u);A(s=>[i,...s].slice(0,50))}finally{w(!1)}}},[u,t]),M=p.useCallback(i=>{x(s=>({...s,schedule:i})),h==null||h(u,i)},[u,x,h]),z=p.useCallback(i=>{if(i.preventDefault(),!!v){if(v.startsWith("transform:")){const s=v.replace("transform:","");D(s)}B(null)}},[v,D]),O=()=>{if(!o)return null;switch(o.type){case"source":return u.sources.find(i=>i.id===o.id);case"transformation":return u.transformations.find(i=>i.id===o.id);case"destination":return u.destinations.find(i=>i.id===o.id);default:return null}},W=f==="design"?e.jsxs("div",{className:"nice-etl-builder__palette",children:[e.jsx("h4",{children:n("etlBuilder.sources","Sources")}),l.map(i=>e.jsxs("div",{className:"nice-etl-builder__palette-item",onClick:()=>k(i),children:[e.jsx("span",{className:"nice-etl-builder__palette-icon",children:e.jsx(_.NiceIcon,{name:"database",size:14})}),e.jsx("span",{children:i.name})]},i.id)),e.jsx("button",{onClick:()=>k({id:"",name:"New Source",type:"database",config:{}}),children:"+ Add Source"}),e.jsx("h4",{children:n("etlBuilder.transformations","Transformations")}),T.map(i=>e.jsxs("div",{className:"nice-etl-builder__palette-item",draggable:!0,onDragStart:()=>B(`transform:${i.type}`),onDragEnd:()=>B(null),children:[e.jsx("span",{className:"nice-etl-builder__palette-icon",children:E(i.icon)}),e.jsx("span",{children:i.label})]},i.type)),e.jsx("h4",{children:n("etlBuilder.destinations","Destinations")}),e.jsx("button",{onClick:F,children:"+ Add Destination"})]}):void 0,$=o&&f==="design"?e.jsx(Y,{nodeType:o.type,node:O()??null,dataSources:l,onChange:i=>{x(s=>{switch(o.type){case"source":return{...s,sources:s.sources.map(a=>a.id===o.id?{...a,...i}:a)};case"transformation":return{...s,transformations:s.transformations.map(a=>a.id===o.id?{...a,...i}:a)};case"destination":return{...s,destinations:s.destinations.map(a=>a.id===o.id?{...a,...i}:a)};default:return s}})},onClose:()=>b(null)}):void 0;return e.jsxs(_.NiceAppShell,{flush:!0,className:`nice-etl-builder ${r}`,height:"100%",style:{minHeight:600},sidebar:W,rightSidebar:$,toolbar:e.jsxs("div",{className:"nice-etl-builder__toolbar",children:[e.jsx("input",{type:"text",value:u.name,onChange:i=>x(s=>({...s,name:i.target.value})),className:"nice-etl-builder__name-input"}),e.jsx("div",{className:"nice-etl-builder__tabs",children:["design","code","schedule","history"].map(i=>e.jsx("button",{className:`nice-etl-builder__tab ${f===i?"nice-etl-builder__tab--active":""}`,onClick:()=>U(i),children:i.charAt(0).toUpperCase()+i.slice(1)},i))}),e.jsxs("div",{className:"nice-etl-builder__actions",children:[e.jsxs("button",{onClick:R,disabled:N,className:"nice-etl-builder__run-btn",children:[e.jsx(_.NiceIcon,{name:N?"clock":"play",size:14})," ",N?"Running...":"Run"]}),e.jsxs("button",{className:"nice-etl-builder__save-btn",children:[e.jsx(_.NiceIcon,{name:"save",size:14})," Save"]}),e.jsx(g.NiceTutorialButton,{steps:g.resolveTutorial(m,H)})]})]}),children:[f==="design"&&e.jsx("div",{ref:I,className:"nice-etl-builder__canvas",onDragOver:i=>i.preventDefault(),onDrop:z,onClick:()=>b(null),children:e.jsxs("div",{className:"nice-etl-builder__flow",children:[e.jsxs("div",{className:"nice-etl-builder__column",children:[e.jsx("h5",{children:n("etlBuilder.sources","Sources")}),u.sources.map(i=>e.jsx(S,{node:i,nodeType:"source",icon:"database",isSelected:(o==null?void 0:o.id)===i.id,onSelect:()=>b({type:"source",id:i.id}),onDelete:()=>C("source",i.id)},i.id))]}),e.jsx("div",{className:"nice-etl-builder__arrow",children:"→"}),e.jsxs("div",{className:"nice-etl-builder__column nice-etl-builder__column--transforms",children:[e.jsx("h5",{children:n("etlBuilder.transformations","Transformations")}),u.transformations.map(i=>{const s=T.find(a=>a.type===i.type);return e.jsx(S,{node:i,nodeType:"transformation",icon:(s==null?void 0:s.icon)||"shuffle",isSelected:(o==null?void 0:o.id)===i.id,onSelect:()=>b({type:"transformation",id:i.id}),onDelete:()=>C("transformation",i.id)},i.id)}),u.transformations.length===0&&e.jsx("div",{className:"nice-etl-builder__empty-column",children:n("etlBuilder.dragTransformationsHere","Drag transformations here")})]}),e.jsx("div",{className:"nice-etl-builder__arrow",children:"→"}),e.jsxs("div",{className:"nice-etl-builder__column",children:[e.jsx("h5",{children:n("etlBuilder.destinations","Destinations")}),u.destinations.map(i=>e.jsx(S,{node:i,nodeType:"destination",icon:"download",isSelected:(o==null?void 0:o.id)===i.id,onSelect:()=>b({type:"destination",id:i.id}),onDelete:()=>C("destination",i.id)},i.id))]})]})}),f==="code"&&e.jsx("div",{className:"nice-etl-builder__code-view",children:e.jsx("pre",{children:JSON.stringify(u,null,2)})}),f==="schedule"&&e.jsx(J,{schedule:u.schedule,monitoring:u.monitoring,onChange:M}),f==="history"&&e.jsx(G,{runs:P})]})}function V(d){switch(d){case"filter":return{condition:""};case"map":return{mappings:[]};case"aggregate":return{groupBy:[],aggregations:[]};case"join":return{joinType:"inner",leftKey:"",rightKey:""};case"union":return{inputs:[]};case"sort":return{columns:[],directions:[]};case"deduplicate":return{columns:[],keepFirst:!0};case"pivot":return{pivotColumn:"",valueColumn:"",aggregation:"sum"};case"unpivot":return{columns:[],nameColumn:"name",valueColumn:"value"};case"derive":return{name:"",expression:""};case"validate":return{rules:[]};case"cleanse":return{operations:[]};case"custom":return{code:`// Custom transformation
2
+ return data;`};default:return{}}}function S({node:d,nodeType:l,icon:c,isSelected:t,onSelect:h,onDelete:r}){return e.jsxs("div",{className:`nice-etl-builder__node nice-etl-builder__node--${l} ${t?"nice-etl-builder__node--selected":""}`,onClick:m=>{m.stopPropagation(),h()},children:[e.jsx("span",{className:"nice-etl-builder__node-icon",children:E(c)}),e.jsx("span",{className:"nice-etl-builder__node-name",children:d.name}),e.jsx("button",{className:"nice-etl-builder__node-delete",onClick:m=>{m.stopPropagation(),r()},children:"×"})]})}function Y({nodeType:d,node:l,dataSources:c,onChange:t,onClose:h}){var m;const{t:r}=g.useNiceTranslation();return l?e.jsxs("div",{className:"nice-etl-builder__properties",children:[e.jsxs("div",{className:"nice-etl-builder__properties-header",children:[e.jsxs("h4",{children:[d.charAt(0).toUpperCase()+d.slice(1)," Properties"]}),e.jsx("button",{onClick:h,children:"×"})]}),e.jsxs("div",{className:"nice-etl-builder__properties-content",children:[e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.name","Name")}),e.jsx("input",{type:"text",value:l.name,onChange:n=>t({name:n.target.value})})]}),d==="source"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.type","Type")}),e.jsxs("select",{value:l.type,onChange:n=>t({type:n.target.value}),children:[e.jsx("option",{value:"database",children:r("etlBuilder.database","Database")}),e.jsx("option",{value:"api",children:"API"}),e.jsx("option",{value:"file",children:r("etlBuilder.file","File")}),e.jsx("option",{value:"stream",children:r("etlBuilder.stream","Stream")})]})]}),e.jsx("div",{className:"nice-etl-builder__field",children:e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:((m=l.incremental)==null?void 0:m.enabled)||!1,onChange:n=>{var u;return t({incremental:{...l.incremental,enabled:n.target.checked,column:((u=l.incremental)==null?void 0:u.column)||""}})}}),r("etlBuilder.incrementalLoad","Incremental Load")]})})]}),d==="transformation"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.type","Type")}),e.jsx("span",{children:l.type})]}),l.type==="filter"&&e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.condition","Condition")}),e.jsx("textarea",{value:String(l.config.condition||""),onChange:n=>t({config:{...l.config,condition:n.target.value}}),placeholder:r("etlBuilder.conditionPlaceholder","e.g., age > 18 AND status = 'active'"),rows:3})]}),l.type==="derive"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.columnName","Column Name")}),e.jsx("input",{type:"text",value:String(l.config.name||""),onChange:n=>t({config:{...l.config,name:n.target.value}})})]}),e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.expression","Expression")}),e.jsx("input",{type:"text",value:String(l.config.expression||""),onChange:n=>t({config:{...l.config,expression:n.target.value}}),placeholder:r("etlBuilder.expressionPlaceholder","e.g., price * quantity")})]})]}),l.type==="custom"&&e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.code","Code")}),e.jsx("textarea",{value:String(l.config.code||""),onChange:n=>t({config:{...l.config,code:n.target.value}}),rows:10,className:"nice-etl-builder__code-input"})]})]}),d==="destination"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.type","Type")}),e.jsxs("select",{value:l.type,onChange:n=>t({type:n.target.value}),children:[e.jsx("option",{value:"database",children:r("etlBuilder.database","Database")}),e.jsx("option",{value:"file",children:r("etlBuilder.file","File")}),e.jsx("option",{value:"api",children:"API"}),e.jsx("option",{value:"warehouse",children:r("etlBuilder.dataWarehouse","Data Warehouse")})]})]}),e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:r("etlBuilder.writeMode","Write Mode")}),e.jsxs("select",{value:l.writeMode,onChange:n=>t({writeMode:n.target.value}),children:[e.jsx("option",{value:"append",children:r("etlBuilder.append","Append")}),e.jsx("option",{value:"overwrite",children:r("etlBuilder.overwrite","Overwrite")}),e.jsx("option",{value:"upsert",children:r("etlBuilder.upsert","Upsert")}),e.jsx("option",{value:"merge",children:r("etlBuilder.merge","Merge")})]})]})]})]})]}):e.jsx(e.Fragment,{})}function J({schedule:d,monitoring:l,onChange:c}){const{t}=g.useNiceTranslation(),[h,r]=p.useState(d||{enabled:!1});return e.jsxs("div",{className:"nice-etl-builder__schedule-editor",children:[e.jsx("h4",{children:t("etlBuilder.scheduleConfiguration","Schedule Configuration")}),e.jsx("div",{className:"nice-etl-builder__field",children:e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:h.enabled,onChange:m=>{const n={...h,enabled:m.target.checked};r(n),c(n)}}),t("etlBuilder.enableScheduledExecution","Enable scheduled execution")]})}),h.enabled&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:t("etlBuilder.cronExpression","Cron Expression")}),e.jsx("input",{type:"text",value:h.cron||"",onChange:m=>{const n={...h,cron:m.target.value};r(n)},placeholder:t("etlBuilder.cronPlaceholder","0 0 * * * (every hour)")}),e.jsx("small",{children:"Format: minute hour day month weekday"})]}),e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:t("etlBuilder.timezone","Timezone")}),e.jsxs("select",{value:h.timezone||"UTC",onChange:m=>{const n={...h,timezone:m.target.value};r(n)},children:[e.jsx("option",{value:"UTC",children:"UTC"}),e.jsx("option",{value:"America/New_York",children:t("etlBuilder.easternTime","Eastern Time")}),e.jsx("option",{value:"America/Chicago",children:t("etlBuilder.centralTime","Central Time")}),e.jsx("option",{value:"America/Los_Angeles",children:t("etlBuilder.pacificTime","Pacific Time")}),e.jsx("option",{value:"Europe/London",children:t("etlBuilder.london","London")}),e.jsx("option",{value:"Europe/Warsaw",children:t("etlBuilder.warsaw","Warsaw")})]})]}),e.jsx("button",{onClick:()=>c(h),children:t("etlBuilder.saveSchedule","Save Schedule")})]}),e.jsx("h4",{children:t("etlBuilder.monitoring","Monitoring")}),e.jsx("div",{className:"nice-etl-builder__field",children:e.jsxs("label",{children:[e.jsx("input",{type:"checkbox",checked:(l==null?void 0:l.alertOnFailure)||!1,disabled:!0}),t("etlBuilder.alertOnFailure","Alert on failure")]})}),e.jsxs("div",{className:"nice-etl-builder__field",children:[e.jsx("label",{children:t("etlBuilder.logLevel","Log Level")}),e.jsxs("select",{value:(l==null?void 0:l.logLevel)||"info",disabled:!0,children:[e.jsx("option",{value:"error",children:t("etlBuilder.error","Error")}),e.jsx("option",{value:"warn",children:t("etlBuilder.warning","Warning")}),e.jsx("option",{value:"info",children:t("etlBuilder.info","Info")}),e.jsx("option",{value:"debug",children:t("etlBuilder.debug","Debug")})]})]})]})}function G({runs:d}){const{t:l}=g.useNiceTranslation();return e.jsxs("div",{className:"nice-etl-builder__history-view",children:[e.jsx("h4",{children:l("etlBuilder.runHistory","Run History")}),d.length===0?e.jsx("div",{className:"nice-etl-builder__no-history",children:l("etlBuilder.noRunsYet","No runs yet")}):e.jsxs("table",{className:"nice-etl-builder__history-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:l("etlBuilder.status","Status")}),e.jsx("th",{children:l("etlBuilder.startTime","Start Time")}),e.jsx("th",{children:l("etlBuilder.duration","Duration")}),e.jsx("th",{children:l("etlBuilder.rows","Rows")}),e.jsx("th",{children:l("etlBuilder.errors","Errors")})]})}),e.jsx("tbody",{children:d.map(c=>e.jsxs("tr",{className:`nice-etl-builder__run nice-etl-builder__run--${c.status}`,children:[e.jsx("td",{children:e.jsxs("span",{className:`nice-etl-builder__status nice-etl-builder__status--${c.status}`,children:[e.jsx(_.NiceIcon,{name:c.status==="success"?"check":c.status==="failed"?"close":"clock",size:12}),c.status]})}),e.jsx("td",{children:c.startTime.toLocaleString()}),e.jsx("td",{children:c.endTime?`${Math.round((c.endTime.getTime()-c.startTime.getTime())/1e3)}s`:"-"}),e.jsxs("td",{children:[c.rowsProcessed.toLocaleString()," / ",c.rowsWritten.toLocaleString()]}),e.jsx("td",{children:c.errors.length})]},c.id))})]})]})}exports.NiceETLBuilder=K;
package/dist/index.mjs CHANGED
@@ -1,4 +1,714 @@
1
- import { N as i } from "./index-BbAnSU3F.js";
1
+ import { jsxs as l, jsx as e, Fragment as N } from "react/jsx-runtime";
2
+ import { NiceIcon as B, NiceAppShell as Y } from "@nice2dev/ui";
3
+ import { useNiceTranslation as C, NiceTutorialButton as J, resolveTutorial as q } from "@nice2dev/ui-core";
4
+ import { useState as y, useRef as G, useCallback as v } from "react";
5
+ const Q = [
6
+ {
7
+ target: ".nice-etl-builder",
8
+ titleKey: "tutorial.etlBuilder.intro.title",
9
+ title: "ETL builder",
10
+ contentKey: "tutorial.etlBuilder.intro.content",
11
+ content: "Wire sources → transformations → destinations into a pipeline, switch the views, then run it and save the configuration.",
12
+ placement: "auto"
13
+ }
14
+ ], X = {
15
+ id: "",
16
+ name: "New Pipeline",
17
+ sources: [],
18
+ transformations: [],
19
+ destinations: [],
20
+ version: 1
21
+ }, A = (o) => /^[a-z][a-z0-9-]*$/.test(o) ? /* @__PURE__ */ e(B, { name: o, size: 16 }) : o, x = [
22
+ { type: "filter", label: "Filter", icon: "filter" },
23
+ { type: "map", label: "Map", icon: "shuffle" },
24
+ { type: "aggregate", label: "Aggregate", icon: "∑" },
25
+ { type: "join", label: "Join", icon: "link" },
26
+ { type: "union", label: "Union", icon: "∪" },
27
+ { type: "sort", label: "Sort", icon: "sort" },
28
+ { type: "deduplicate", label: "Deduplicate", icon: "copy" },
29
+ { type: "pivot", label: "Pivot", icon: "expand" },
30
+ { type: "unpivot", label: "Unpivot", icon: "collapse" },
31
+ { type: "split", label: "Split", icon: "scissors" },
32
+ { type: "merge", label: "Merge", icon: "git-branch" },
33
+ { type: "lookup", label: "Lookup", icon: "book" },
34
+ { type: "derive", label: "Derive Column", icon: "plus" },
35
+ { type: "validate", label: "Validate", icon: "check" },
36
+ { type: "cleanse", label: "Cleanse", icon: "wand" },
37
+ { type: "custom", label: "Custom", icon: "ƒ" }
38
+ ];
39
+ function ce({
40
+ pipeline: o,
41
+ dataSources: t = [],
42
+ onChange: s,
43
+ onRun: n,
44
+ onSchedule: p,
45
+ className: c = "",
46
+ tutorial: m
47
+ }) {
48
+ const { t: r } = C(), [h, I] = y(
49
+ o || { ...X, id: crypto.randomUUID() }
50
+ ), [u, _] = y(null), [g, R] = y("design"), [S, L] = y(!1), [z, M] = y([]), [w, D] = y(null), F = G(null), b = v(
51
+ (i) => {
52
+ I((a) => {
53
+ const d = i(a);
54
+ return s == null || s(d), d;
55
+ });
56
+ },
57
+ [s]
58
+ ), U = v(
59
+ (i) => {
60
+ var d;
61
+ const a = {
62
+ id: crypto.randomUUID(),
63
+ type: i.type,
64
+ name: i.name,
65
+ config: i.config,
66
+ schema: (d = i.schema) == null ? void 0 : d.tables[0]
67
+ };
68
+ b((f) => ({
69
+ ...f,
70
+ sources: [...f.sources, a]
71
+ }));
72
+ },
73
+ [b]
74
+ ), P = v(
75
+ (i, a) => {
76
+ var f;
77
+ const d = {
78
+ id: crypto.randomUUID(),
79
+ type: i,
80
+ name: ((f = x.find((T) => T.type === i)) == null ? void 0 : f.label) || i,
81
+ input: [],
82
+ output: crypto.randomUUID(),
83
+ config: Z(i)
84
+ };
85
+ b((T) => ({
86
+ ...T,
87
+ transformations: [...T.transformations, d]
88
+ })), _({ type: "transformation", id: d.id });
89
+ },
90
+ [b]
91
+ ), W = v(() => {
92
+ const i = {
93
+ id: crypto.randomUUID(),
94
+ type: "database",
95
+ name: "New Destination",
96
+ config: {},
97
+ writeMode: "append"
98
+ };
99
+ b((a) => ({
100
+ ...a,
101
+ destinations: [...a.destinations, i]
102
+ })), _({ type: "destination", id: i.id });
103
+ }, [b]), k = v(
104
+ (i, a) => {
105
+ b((d) => {
106
+ switch (i) {
107
+ case "source":
108
+ return { ...d, sources: d.sources.filter((f) => f.id !== a) };
109
+ case "transformation":
110
+ return {
111
+ ...d,
112
+ transformations: d.transformations.filter((f) => f.id !== a)
113
+ };
114
+ case "destination":
115
+ return { ...d, destinations: d.destinations.filter((f) => f.id !== a) };
116
+ default:
117
+ return d;
118
+ }
119
+ }), _(null);
120
+ },
121
+ [b]
122
+ ), $ = v(async () => {
123
+ if (n) {
124
+ L(!0);
125
+ try {
126
+ const i = await n(h);
127
+ M((a) => [i, ...a].slice(0, 50));
128
+ } finally {
129
+ L(!1);
130
+ }
131
+ }
132
+ }, [h, n]), O = v(
133
+ (i) => {
134
+ b((a) => ({ ...a, schedule: i })), p == null || p(h, i);
135
+ },
136
+ [h, b, p]
137
+ ), H = v(
138
+ (i) => {
139
+ if (i.preventDefault(), !!w) {
140
+ if (w.startsWith("transform:")) {
141
+ const a = w.replace("transform:", "");
142
+ P(a);
143
+ }
144
+ D(null);
145
+ }
146
+ },
147
+ [w, P]
148
+ ), j = () => {
149
+ if (!u)
150
+ return null;
151
+ switch (u.type) {
152
+ case "source":
153
+ return h.sources.find((i) => i.id === u.id);
154
+ case "transformation":
155
+ return h.transformations.find((i) => i.id === u.id);
156
+ case "destination":
157
+ return h.destinations.find((i) => i.id === u.id);
158
+ default:
159
+ return null;
160
+ }
161
+ }, K = g === "design" ? /* @__PURE__ */ l("div", { className: "nice-etl-builder__palette", children: [
162
+ /* @__PURE__ */ e("h4", { children: r("etlBuilder.sources", "Sources") }),
163
+ t.map((i) => /* @__PURE__ */ l("div", { className: "nice-etl-builder__palette-item", onClick: () => U(i), children: [
164
+ /* @__PURE__ */ e("span", { className: "nice-etl-builder__palette-icon", children: /* @__PURE__ */ e(B, { name: "database", size: 14 }) }),
165
+ /* @__PURE__ */ e("span", { children: i.name })
166
+ ] }, i.id)),
167
+ /* @__PURE__ */ e(
168
+ "button",
169
+ {
170
+ onClick: () => U({ id: "", name: "New Source", type: "database", config: {} }),
171
+ children: "+ Add Source"
172
+ }
173
+ ),
174
+ /* @__PURE__ */ e("h4", { children: r("etlBuilder.transformations", "Transformations") }),
175
+ x.map((i) => /* @__PURE__ */ l(
176
+ "div",
177
+ {
178
+ className: "nice-etl-builder__palette-item",
179
+ draggable: !0,
180
+ onDragStart: () => D(`transform:${i.type}`),
181
+ onDragEnd: () => D(null),
182
+ children: [
183
+ /* @__PURE__ */ e("span", { className: "nice-etl-builder__palette-icon", children: A(i.icon) }),
184
+ /* @__PURE__ */ e("span", { children: i.label })
185
+ ]
186
+ },
187
+ i.type
188
+ )),
189
+ /* @__PURE__ */ e("h4", { children: r("etlBuilder.destinations", "Destinations") }),
190
+ /* @__PURE__ */ e("button", { onClick: W, children: "+ Add Destination" })
191
+ ] }) : void 0, V = u && g === "design" ? /* @__PURE__ */ e(
192
+ ee,
193
+ {
194
+ nodeType: u.type,
195
+ node: j() ?? null,
196
+ dataSources: t,
197
+ onChange: (i) => {
198
+ b((a) => {
199
+ switch (u.type) {
200
+ case "source":
201
+ return {
202
+ ...a,
203
+ sources: a.sources.map(
204
+ (d) => d.id === u.id ? { ...d, ...i } : d
205
+ )
206
+ };
207
+ case "transformation":
208
+ return {
209
+ ...a,
210
+ transformations: a.transformations.map(
211
+ (d) => d.id === u.id ? { ...d, ...i } : d
212
+ )
213
+ };
214
+ case "destination":
215
+ return {
216
+ ...a,
217
+ destinations: a.destinations.map(
218
+ (d) => d.id === u.id ? { ...d, ...i } : d
219
+ )
220
+ };
221
+ default:
222
+ return a;
223
+ }
224
+ });
225
+ },
226
+ onClose: () => _(null)
227
+ }
228
+ ) : void 0;
229
+ return /* @__PURE__ */ l(
230
+ Y,
231
+ {
232
+ flush: !0,
233
+ className: `nice-etl-builder ${c}`,
234
+ height: "100%",
235
+ style: { minHeight: 600 },
236
+ sidebar: K,
237
+ rightSidebar: V,
238
+ toolbar: /* @__PURE__ */ l("div", { className: "nice-etl-builder__toolbar", children: [
239
+ /* @__PURE__ */ e(
240
+ "input",
241
+ {
242
+ type: "text",
243
+ value: h.name,
244
+ onChange: (i) => b((a) => ({ ...a, name: i.target.value })),
245
+ className: "nice-etl-builder__name-input"
246
+ }
247
+ ),
248
+ /* @__PURE__ */ e("div", { className: "nice-etl-builder__tabs", children: ["design", "code", "schedule", "history"].map((i) => /* @__PURE__ */ e(
249
+ "button",
250
+ {
251
+ className: `nice-etl-builder__tab ${g === i ? "nice-etl-builder__tab--active" : ""}`,
252
+ onClick: () => R(i),
253
+ children: i.charAt(0).toUpperCase() + i.slice(1)
254
+ },
255
+ i
256
+ )) }),
257
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__actions", children: [
258
+ /* @__PURE__ */ l("button", { onClick: $, disabled: S, className: "nice-etl-builder__run-btn", children: [
259
+ /* @__PURE__ */ e(B, { name: S ? "clock" : "play", size: 14 }),
260
+ " ",
261
+ S ? "Running..." : "Run"
262
+ ] }),
263
+ /* @__PURE__ */ l("button", { className: "nice-etl-builder__save-btn", children: [
264
+ /* @__PURE__ */ e(B, { name: "save", size: 14 }),
265
+ " Save"
266
+ ] }),
267
+ /* @__PURE__ */ e(J, { steps: q(m, Q) })
268
+ ] })
269
+ ] }),
270
+ children: [
271
+ g === "design" && /* @__PURE__ */ e(
272
+ "div",
273
+ {
274
+ ref: F,
275
+ className: "nice-etl-builder__canvas",
276
+ onDragOver: (i) => i.preventDefault(),
277
+ onDrop: H,
278
+ onClick: () => _(null),
279
+ children: /* @__PURE__ */ l("div", { className: "nice-etl-builder__flow", children: [
280
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__column", children: [
281
+ /* @__PURE__ */ e("h5", { children: r("etlBuilder.sources", "Sources") }),
282
+ h.sources.map((i) => /* @__PURE__ */ e(
283
+ E,
284
+ {
285
+ node: i,
286
+ nodeType: "source",
287
+ icon: "database",
288
+ isSelected: (u == null ? void 0 : u.id) === i.id,
289
+ onSelect: () => _({ type: "source", id: i.id }),
290
+ onDelete: () => k("source", i.id)
291
+ },
292
+ i.id
293
+ ))
294
+ ] }),
295
+ /* @__PURE__ */ e("div", { className: "nice-etl-builder__arrow", children: "→" }),
296
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__column nice-etl-builder__column--transforms", children: [
297
+ /* @__PURE__ */ e("h5", { children: r("etlBuilder.transformations", "Transformations") }),
298
+ h.transformations.map((i) => {
299
+ const a = x.find((d) => d.type === i.type);
300
+ return /* @__PURE__ */ e(
301
+ E,
302
+ {
303
+ node: i,
304
+ nodeType: "transformation",
305
+ icon: (a == null ? void 0 : a.icon) || "shuffle",
306
+ isSelected: (u == null ? void 0 : u.id) === i.id,
307
+ onSelect: () => _({ type: "transformation", id: i.id }),
308
+ onDelete: () => k("transformation", i.id)
309
+ },
310
+ i.id
311
+ );
312
+ }),
313
+ h.transformations.length === 0 && /* @__PURE__ */ e("div", { className: "nice-etl-builder__empty-column", children: r("etlBuilder.dragTransformationsHere", "Drag transformations here") })
314
+ ] }),
315
+ /* @__PURE__ */ e("div", { className: "nice-etl-builder__arrow", children: "→" }),
316
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__column", children: [
317
+ /* @__PURE__ */ e("h5", { children: r("etlBuilder.destinations", "Destinations") }),
318
+ h.destinations.map((i) => /* @__PURE__ */ e(
319
+ E,
320
+ {
321
+ node: i,
322
+ nodeType: "destination",
323
+ icon: "download",
324
+ isSelected: (u == null ? void 0 : u.id) === i.id,
325
+ onSelect: () => _({ type: "destination", id: i.id }),
326
+ onDelete: () => k("destination", i.id)
327
+ },
328
+ i.id
329
+ ))
330
+ ] })
331
+ ] })
332
+ }
333
+ ),
334
+ g === "code" && /* @__PURE__ */ e("div", { className: "nice-etl-builder__code-view", children: /* @__PURE__ */ e("pre", { children: JSON.stringify(h, null, 2) }) }),
335
+ g === "schedule" && /* @__PURE__ */ e(
336
+ ie,
337
+ {
338
+ schedule: h.schedule,
339
+ monitoring: h.monitoring,
340
+ onChange: O
341
+ }
342
+ ),
343
+ g === "history" && /* @__PURE__ */ e(le, { runs: z })
344
+ ]
345
+ }
346
+ );
347
+ }
348
+ function Z(o) {
349
+ switch (o) {
350
+ case "filter":
351
+ return { condition: "" };
352
+ case "map":
353
+ return { mappings: [] };
354
+ case "aggregate":
355
+ return { groupBy: [], aggregations: [] };
356
+ case "join":
357
+ return { joinType: "inner", leftKey: "", rightKey: "" };
358
+ case "union":
359
+ return { inputs: [] };
360
+ case "sort":
361
+ return { columns: [], directions: [] };
362
+ case "deduplicate":
363
+ return { columns: [], keepFirst: !0 };
364
+ case "pivot":
365
+ return { pivotColumn: "", valueColumn: "", aggregation: "sum" };
366
+ case "unpivot":
367
+ return { columns: [], nameColumn: "name", valueColumn: "value" };
368
+ case "derive":
369
+ return { name: "", expression: "" };
370
+ case "validate":
371
+ return { rules: [] };
372
+ case "cleanse":
373
+ return { operations: [] };
374
+ case "custom":
375
+ return { code: `// Custom transformation
376
+ return data;` };
377
+ default:
378
+ return {};
379
+ }
380
+ }
381
+ function E({
382
+ node: o,
383
+ nodeType: t,
384
+ icon: s,
385
+ isSelected: n,
386
+ onSelect: p,
387
+ onDelete: c
388
+ }) {
389
+ return /* @__PURE__ */ l(
390
+ "div",
391
+ {
392
+ className: `nice-etl-builder__node nice-etl-builder__node--${t} ${n ? "nice-etl-builder__node--selected" : ""}`,
393
+ onClick: (m) => {
394
+ m.stopPropagation(), p();
395
+ },
396
+ children: [
397
+ /* @__PURE__ */ e("span", { className: "nice-etl-builder__node-icon", children: A(s) }),
398
+ /* @__PURE__ */ e("span", { className: "nice-etl-builder__node-name", children: o.name }),
399
+ /* @__PURE__ */ e(
400
+ "button",
401
+ {
402
+ className: "nice-etl-builder__node-delete",
403
+ onClick: (m) => {
404
+ m.stopPropagation(), c();
405
+ },
406
+ children: "×"
407
+ }
408
+ )
409
+ ]
410
+ }
411
+ );
412
+ }
413
+ function ee({
414
+ nodeType: o,
415
+ node: t,
416
+ dataSources: s,
417
+ onChange: n,
418
+ onClose: p
419
+ }) {
420
+ var m;
421
+ const { t: c } = C();
422
+ return t ? /* @__PURE__ */ l("div", { className: "nice-etl-builder__properties", children: [
423
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__properties-header", children: [
424
+ /* @__PURE__ */ l("h4", { children: [
425
+ o.charAt(0).toUpperCase() + o.slice(1),
426
+ " Properties"
427
+ ] }),
428
+ /* @__PURE__ */ e("button", { onClick: p, children: "×" })
429
+ ] }),
430
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__properties-content", children: [
431
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
432
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.name", "Name") }),
433
+ /* @__PURE__ */ e(
434
+ "input",
435
+ {
436
+ type: "text",
437
+ value: t.name,
438
+ onChange: (r) => n({ name: r.target.value })
439
+ }
440
+ )
441
+ ] }),
442
+ o === "source" && /* @__PURE__ */ l(N, { children: [
443
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
444
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.type", "Type") }),
445
+ /* @__PURE__ */ l(
446
+ "select",
447
+ {
448
+ value: t.type,
449
+ onChange: (r) => n({ type: r.target.value }),
450
+ children: [
451
+ /* @__PURE__ */ e("option", { value: "database", children: c("etlBuilder.database", "Database") }),
452
+ /* @__PURE__ */ e("option", { value: "api", children: "API" }),
453
+ /* @__PURE__ */ e("option", { value: "file", children: c("etlBuilder.file", "File") }),
454
+ /* @__PURE__ */ e("option", { value: "stream", children: c("etlBuilder.stream", "Stream") })
455
+ ]
456
+ }
457
+ )
458
+ ] }),
459
+ /* @__PURE__ */ e("div", { className: "nice-etl-builder__field", children: /* @__PURE__ */ l("label", { children: [
460
+ /* @__PURE__ */ e(
461
+ "input",
462
+ {
463
+ type: "checkbox",
464
+ checked: ((m = t.incremental) == null ? void 0 : m.enabled) || !1,
465
+ onChange: (r) => {
466
+ var h;
467
+ return n({
468
+ incremental: {
469
+ ...t.incremental,
470
+ enabled: r.target.checked,
471
+ column: ((h = t.incremental) == null ? void 0 : h.column) || ""
472
+ }
473
+ });
474
+ }
475
+ }
476
+ ),
477
+ c("etlBuilder.incrementalLoad", "Incremental Load")
478
+ ] }) })
479
+ ] }),
480
+ o === "transformation" && /* @__PURE__ */ l(N, { children: [
481
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
482
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.type", "Type") }),
483
+ /* @__PURE__ */ e("span", { children: t.type })
484
+ ] }),
485
+ t.type === "filter" && /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
486
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.condition", "Condition") }),
487
+ /* @__PURE__ */ e(
488
+ "textarea",
489
+ {
490
+ value: String(t.config.condition || ""),
491
+ onChange: (r) => n({
492
+ config: { ...t.config, condition: r.target.value }
493
+ }),
494
+ placeholder: c(
495
+ "etlBuilder.conditionPlaceholder",
496
+ "e.g., age > 18 AND status = 'active'"
497
+ ),
498
+ rows: 3
499
+ }
500
+ )
501
+ ] }),
502
+ t.type === "derive" && /* @__PURE__ */ l(N, { children: [
503
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
504
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.columnName", "Column Name") }),
505
+ /* @__PURE__ */ e(
506
+ "input",
507
+ {
508
+ type: "text",
509
+ value: String(t.config.name || ""),
510
+ onChange: (r) => n({
511
+ config: { ...t.config, name: r.target.value }
512
+ })
513
+ }
514
+ )
515
+ ] }),
516
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
517
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.expression", "Expression") }),
518
+ /* @__PURE__ */ e(
519
+ "input",
520
+ {
521
+ type: "text",
522
+ value: String(t.config.expression || ""),
523
+ onChange: (r) => n({
524
+ config: {
525
+ ...t.config,
526
+ expression: r.target.value
527
+ }
528
+ }),
529
+ placeholder: c("etlBuilder.expressionPlaceholder", "e.g., price * quantity")
530
+ }
531
+ )
532
+ ] })
533
+ ] }),
534
+ t.type === "custom" && /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
535
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.code", "Code") }),
536
+ /* @__PURE__ */ e(
537
+ "textarea",
538
+ {
539
+ value: String(t.config.code || ""),
540
+ onChange: (r) => n({
541
+ config: { ...t.config, code: r.target.value }
542
+ }),
543
+ rows: 10,
544
+ className: "nice-etl-builder__code-input"
545
+ }
546
+ )
547
+ ] })
548
+ ] }),
549
+ o === "destination" && /* @__PURE__ */ l(N, { children: [
550
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
551
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.type", "Type") }),
552
+ /* @__PURE__ */ l(
553
+ "select",
554
+ {
555
+ value: t.type,
556
+ onChange: (r) => n({ type: r.target.value }),
557
+ children: [
558
+ /* @__PURE__ */ e("option", { value: "database", children: c("etlBuilder.database", "Database") }),
559
+ /* @__PURE__ */ e("option", { value: "file", children: c("etlBuilder.file", "File") }),
560
+ /* @__PURE__ */ e("option", { value: "api", children: "API" }),
561
+ /* @__PURE__ */ e("option", { value: "warehouse", children: c("etlBuilder.dataWarehouse", "Data Warehouse") })
562
+ ]
563
+ }
564
+ )
565
+ ] }),
566
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
567
+ /* @__PURE__ */ e("label", { children: c("etlBuilder.writeMode", "Write Mode") }),
568
+ /* @__PURE__ */ l(
569
+ "select",
570
+ {
571
+ value: t.writeMode,
572
+ onChange: (r) => n({ writeMode: r.target.value }),
573
+ children: [
574
+ /* @__PURE__ */ e("option", { value: "append", children: c("etlBuilder.append", "Append") }),
575
+ /* @__PURE__ */ e("option", { value: "overwrite", children: c("etlBuilder.overwrite", "Overwrite") }),
576
+ /* @__PURE__ */ e("option", { value: "upsert", children: c("etlBuilder.upsert", "Upsert") }),
577
+ /* @__PURE__ */ e("option", { value: "merge", children: c("etlBuilder.merge", "Merge") })
578
+ ]
579
+ }
580
+ )
581
+ ] })
582
+ ] })
583
+ ] })
584
+ ] }) : /* @__PURE__ */ e(N, {});
585
+ }
586
+ function ie({
587
+ schedule: o,
588
+ monitoring: t,
589
+ onChange: s
590
+ }) {
591
+ const { t: n } = C(), [p, c] = y(o || { enabled: !1 });
592
+ return /* @__PURE__ */ l("div", { className: "nice-etl-builder__schedule-editor", children: [
593
+ /* @__PURE__ */ e("h4", { children: n("etlBuilder.scheduleConfiguration", "Schedule Configuration") }),
594
+ /* @__PURE__ */ e("div", { className: "nice-etl-builder__field", children: /* @__PURE__ */ l("label", { children: [
595
+ /* @__PURE__ */ e(
596
+ "input",
597
+ {
598
+ type: "checkbox",
599
+ checked: p.enabled,
600
+ onChange: (m) => {
601
+ const r = { ...p, enabled: m.target.checked };
602
+ c(r), s(r);
603
+ }
604
+ }
605
+ ),
606
+ n("etlBuilder.enableScheduledExecution", "Enable scheduled execution")
607
+ ] }) }),
608
+ p.enabled && /* @__PURE__ */ l(N, { children: [
609
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
610
+ /* @__PURE__ */ e("label", { children: n("etlBuilder.cronExpression", "Cron Expression") }),
611
+ /* @__PURE__ */ e(
612
+ "input",
613
+ {
614
+ type: "text",
615
+ value: p.cron || "",
616
+ onChange: (m) => {
617
+ const r = { ...p, cron: m.target.value };
618
+ c(r);
619
+ },
620
+ placeholder: n("etlBuilder.cronPlaceholder", "0 0 * * * (every hour)")
621
+ }
622
+ ),
623
+ /* @__PURE__ */ e("small", { children: "Format: minute hour day month weekday" })
624
+ ] }),
625
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
626
+ /* @__PURE__ */ e("label", { children: n("etlBuilder.timezone", "Timezone") }),
627
+ /* @__PURE__ */ l(
628
+ "select",
629
+ {
630
+ value: p.timezone || "UTC",
631
+ onChange: (m) => {
632
+ const r = { ...p, timezone: m.target.value };
633
+ c(r);
634
+ },
635
+ children: [
636
+ /* @__PURE__ */ e("option", { value: "UTC", children: "UTC" }),
637
+ /* @__PURE__ */ e("option", { value: "America/New_York", children: n("etlBuilder.easternTime", "Eastern Time") }),
638
+ /* @__PURE__ */ e("option", { value: "America/Chicago", children: n("etlBuilder.centralTime", "Central Time") }),
639
+ /* @__PURE__ */ e("option", { value: "America/Los_Angeles", children: n("etlBuilder.pacificTime", "Pacific Time") }),
640
+ /* @__PURE__ */ e("option", { value: "Europe/London", children: n("etlBuilder.london", "London") }),
641
+ /* @__PURE__ */ e("option", { value: "Europe/Warsaw", children: n("etlBuilder.warsaw", "Warsaw") })
642
+ ]
643
+ }
644
+ )
645
+ ] }),
646
+ /* @__PURE__ */ e("button", { onClick: () => s(p), children: n("etlBuilder.saveSchedule", "Save Schedule") })
647
+ ] }),
648
+ /* @__PURE__ */ e("h4", { children: n("etlBuilder.monitoring", "Monitoring") }),
649
+ /* @__PURE__ */ e("div", { className: "nice-etl-builder__field", children: /* @__PURE__ */ l("label", { children: [
650
+ /* @__PURE__ */ e("input", { type: "checkbox", checked: (t == null ? void 0 : t.alertOnFailure) || !1, disabled: !0 }),
651
+ n("etlBuilder.alertOnFailure", "Alert on failure")
652
+ ] }) }),
653
+ /* @__PURE__ */ l("div", { className: "nice-etl-builder__field", children: [
654
+ /* @__PURE__ */ e("label", { children: n("etlBuilder.logLevel", "Log Level") }),
655
+ /* @__PURE__ */ l("select", { value: (t == null ? void 0 : t.logLevel) || "info", disabled: !0, children: [
656
+ /* @__PURE__ */ e("option", { value: "error", children: n("etlBuilder.error", "Error") }),
657
+ /* @__PURE__ */ e("option", { value: "warn", children: n("etlBuilder.warning", "Warning") }),
658
+ /* @__PURE__ */ e("option", { value: "info", children: n("etlBuilder.info", "Info") }),
659
+ /* @__PURE__ */ e("option", { value: "debug", children: n("etlBuilder.debug", "Debug") })
660
+ ] })
661
+ ] })
662
+ ] });
663
+ }
664
+ function le({ runs: o }) {
665
+ const { t } = C();
666
+ return /* @__PURE__ */ l("div", { className: "nice-etl-builder__history-view", children: [
667
+ /* @__PURE__ */ e("h4", { children: t("etlBuilder.runHistory", "Run History") }),
668
+ o.length === 0 ? /* @__PURE__ */ e("div", { className: "nice-etl-builder__no-history", children: t("etlBuilder.noRunsYet", "No runs yet") }) : /* @__PURE__ */ l("table", { className: "nice-etl-builder__history-table", children: [
669
+ /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ l("tr", { children: [
670
+ /* @__PURE__ */ e("th", { children: t("etlBuilder.status", "Status") }),
671
+ /* @__PURE__ */ e("th", { children: t("etlBuilder.startTime", "Start Time") }),
672
+ /* @__PURE__ */ e("th", { children: t("etlBuilder.duration", "Duration") }),
673
+ /* @__PURE__ */ e("th", { children: t("etlBuilder.rows", "Rows") }),
674
+ /* @__PURE__ */ e("th", { children: t("etlBuilder.errors", "Errors") })
675
+ ] }) }),
676
+ /* @__PURE__ */ e("tbody", { children: o.map((s) => /* @__PURE__ */ l(
677
+ "tr",
678
+ {
679
+ className: `nice-etl-builder__run nice-etl-builder__run--${s.status}`,
680
+ children: [
681
+ /* @__PURE__ */ e("td", { children: /* @__PURE__ */ l(
682
+ "span",
683
+ {
684
+ className: `nice-etl-builder__status nice-etl-builder__status--${s.status}`,
685
+ children: [
686
+ /* @__PURE__ */ e(
687
+ B,
688
+ {
689
+ name: s.status === "success" ? "check" : s.status === "failed" ? "close" : "clock",
690
+ size: 12
691
+ }
692
+ ),
693
+ s.status
694
+ ]
695
+ }
696
+ ) }),
697
+ /* @__PURE__ */ e("td", { children: s.startTime.toLocaleString() }),
698
+ /* @__PURE__ */ e("td", { children: s.endTime ? `${Math.round((s.endTime.getTime() - s.startTime.getTime()) / 1e3)}s` : "-" }),
699
+ /* @__PURE__ */ l("td", { children: [
700
+ s.rowsProcessed.toLocaleString(),
701
+ " / ",
702
+ s.rowsWritten.toLocaleString()
703
+ ] }),
704
+ /* @__PURE__ */ e("td", { children: s.errors.length })
705
+ ]
706
+ },
707
+ s.id
708
+ )) })
709
+ ] })
710
+ ] });
711
+ }
2
712
  export {
3
- i as NiceETLBuilder
713
+ ce as NiceETLBuilder
4
714
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nice2dev/ui-bi",
3
- "version": "1.1.9",
4
- "description": "Nice2Dev Business Intelligence — Report builder, dashboard studio, ETL pipeline builder",
3
+ "version": "1.1.10",
4
+ "description": "Nice2Dev Business Intelligence — Report builder, dashboard studio, ETL pipeline builder",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.mjs",
@@ -39,8 +39,8 @@
39
39
  "react-dom": ">=17.0.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@nice2dev/ui": "^1.1.9",
43
- "@nice2dev/ui-core": "^1.1.9",
42
+ "@nice2dev/ui": "^1.1.10",
43
+ "@nice2dev/ui-core": "^1.1.10",
44
44
  "@testing-library/jest-dom": "^7.0.1",
45
45
  "@testing-library/react": "^16.3.3",
46
46
  "@types/react": "^19.2.18",