@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 +69 -0
- package/dist/index.cjs +2 -1
- package/dist/index.mjs +712 -2
- package/package.json +4 -4
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("
|
|
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 {
|
|
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
|
-
|
|
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.
|
|
4
|
-
"description": "Nice2Dev Business Intelligence
|
|
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.
|
|
43
|
-
"@nice2dev/ui-core": "^1.1.
|
|
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",
|