@nice2dev/ui-bi 1.0.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/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .nice-report-builder{display:flex;flex-direction:column;height:100%;font-family:system-ui,-apple-system,sans-serif;background:var(--nice-bg, #fff);color:var(--nice-text, #1a1a1a)}.nice-report-builder__toolbar{display:flex;align-items:center;gap:1rem;padding:.5rem 1rem;border-bottom:1px solid var(--nice-border, #e0e0e0);background:var(--nice-bg-secondary, #f8f9fa)}.nice-report-builder__name-input{padding:.375rem .75rem;border:1px solid var(--nice-border, #ddd);border-radius:4px;font-size:.9375rem;font-weight:500}.nice-report-builder__tabs{display:flex;gap:.25rem}.nice-report-builder__tab{padding:.375rem .75rem;border:none;background:transparent;cursor:pointer;font-size:.875rem;border-radius:4px}.nice-report-builder__tab:hover{background:var(--nice-hover, #e9ecef)}.nice-report-builder__tab--active{background:var(--nice-primary, #0066cc);color:#fff}.nice-report-builder__zoom{display:flex;align-items:center;gap:.5rem;margin-left:auto}.nice-report-builder__zoom button{width:28px;height:28px;border:1px solid var(--nice-border, #ddd);background:#fff;border-radius:4px;cursor:pointer}.nice-report-builder__actions{display:flex;gap:.5rem}.nice-report-builder__actions button{padding:.375rem .75rem;border:1px solid var(--nice-border, #ddd);background:#fff;border-radius:4px;cursor:pointer;font-size:.875rem}.nice-report-builder__main{display:flex;flex:1;overflow:hidden}.nice-report-builder__palette{width:200px;border-right:1px solid var(--nice-border, #ddd);padding:.5rem;overflow-y:auto;background:var(--nice-bg-secondary, #f8f9fa)}.nice-report-builder__palette h4,.nice-report-builder__palette h5{margin:.5rem 0;font-size:.75rem;color:var(--nice-text-muted, #6c757d);text-transform:uppercase}.nice-report-builder__palette-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;border-radius:4px;cursor:grab;font-size:.875rem}.nice-report-builder__palette-item:hover{background:var(--nice-hover, #e9ecef)}.nice-report-builder__palette-icon{font-size:1rem}.nice-report-builder__palette select{width:100%;padding:.375rem;border:1px solid var(--nice-border, #ddd);border-radius:4px;font-size:.875rem}.nice-report-builder__fields{margin-top:.5rem}.nice-report-builder__field{padding:.25rem .5rem;font-size:.8125rem;cursor:grab}.nice-report-builder__field:hover{background:var(--nice-hover, #e9ecef)}.nice-report-builder__canvas-container{flex:1;overflow:auto;background:#f0f0f0;padding:2rem}.nice-report-builder__canvas{position:relative;background:#fff;box-shadow:0 2px 8px #0000001a;min-height:100%}.nice-report-builder__canvas-empty{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--nice-text-muted, #6c757d)}.nice-report-builder__element{position:absolute;border:1px solid var(--nice-border, #ddd);background:#fff;cursor:move}.nice-report-builder__element--selected{border-color:var(--nice-primary, #0066cc);box-shadow:0 0 0 2px #06c3}.nice-report-builder__element-content{display:flex;align-items:center;justify-content:center;gap:.5rem;width:100%;height:100%;font-size:.875rem;color:var(--nice-text-muted, #6c757d)}.nice-report-builder__element-delete{position:absolute;top:-8px;right:-8px;width:20px;height:20px;border:none;background:#dc3545;color:#fff;border-radius:50%;cursor:pointer;font-size:.75rem}.nice-report-builder__resize-handle{position:absolute;width:8px;height:8px;background:var(--nice-primary, #0066cc);border-radius:2px}.nice-report-builder__resize-handle--se{right:-4px;bottom:-4px;cursor:se-resize}.nice-report-builder__resize-handle--e{right:-4px;top:50%;transform:translateY(-50%);cursor:e-resize}.nice-report-builder__resize-handle--s{bottom:-4px;left:50%;transform:translate(-50%);cursor:s-resize}.nice-report-builder__properties{width:280px;border-left:1px solid var(--nice-border, #ddd);display:flex;flex-direction:column;background:#fff}.nice-report-builder__properties-header{display:flex;justify-content:space-between;align-items:center;padding:.75rem 1rem;border-bottom:1px solid var(--nice-border, #ddd);background:var(--nice-bg-secondary, #f8f9fa)}.nice-report-builder__properties-header h4{margin:0;font-size:.875rem}.nice-report-builder__properties-content{flex:1;overflow-y:auto;padding:1rem}.nice-report-builder__field{margin-bottom:1rem}.nice-report-builder__field label{display:block;margin-bottom:.25rem;font-size:.8125rem;font-weight:500}.nice-report-builder__field input,.nice-report-builder__field select,.nice-report-builder__field textarea{width:100%;padding:.375rem .5rem;border:1px solid var(--nice-border, #ddd);border-radius:4px;font-size:.875rem}.nice-report-builder__position-inputs,.nice-report-builder__border-inputs{display:flex;gap:.25rem}.nice-report-builder__position-inputs input{width:25%}.nice-report-builder__query-builder,.nice-report-builder__parameters-editor,.nice-report-builder__formatting-editor{flex:1;padding:1rem;overflow:auto}.nice-report-builder__section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.5rem}.nice-report-builder__param-row,.nice-report-builder__calc-row{display:flex;gap:.5rem;margin-bottom:.5rem}.nice-report-builder__param-row input,.nice-report-builder__calc-row input{flex:1}.nice-dashboard-studio{display:flex;flex-direction:column;height:100%;font-family:system-ui,-apple-system,sans-serif;background:var(--nice-bg, #f4f5f7)}.nice-dashboard-studio__toolbar{display:flex;align-items:center;gap:1rem;padding:.5rem 1rem;border-bottom:1px solid var(--nice-border, #ddd);background:#fff}.nice-dashboard-studio__name-input{padding:.375rem .75rem;border:1px solid transparent;border-radius:4px;font-size:1rem;font-weight:600;background:transparent}.nice-dashboard-studio__name-input:focus{border-color:var(--nice-border, #ddd);background:#fff}.nice-dashboard-studio__actions{display:flex;gap:.5rem;margin-left:auto}.nice-dashboard-studio__actions button,.nice-dashboard-studio__action{padding:.375rem .75rem;border:1px solid var(--nice-border, #ddd);background:#fff;border-radius:4px;cursor:pointer;font-size:.875rem}.nice-dashboard-studio__action.active{background:var(--nice-primary, #0066cc);color:#fff;border-color:var(--nice-primary, #0066cc)}.nice-dashboard-studio__filters-bar{display:flex;gap:1rem;padding:.75rem 1rem;background:#fff;border-bottom:1px solid var(--nice-border, #ddd)}.nice-dashboard-studio__filter{display:flex;align-items:center;gap:.5rem;font-size:.875rem}.nice-dashboard-studio__filter label{font-weight:500}.nice-dashboard-studio__filter select,.nice-dashboard-studio__filter input{padding:.25rem .5rem;border:1px solid var(--nice-border, #ddd);border-radius:4px}.nice-dashboard-studio__main{display:flex;flex:1;overflow:hidden}.nice-dashboard-studio__palette{width:200px;border-right:1px solid var(--nice-border, #ddd);padding:.5rem;overflow-y:auto;background:#fff}.nice-dashboard-studio__palette h4,.nice-dashboard-studio__palette h5{margin:.5rem 0;font-size:.75rem;color:var(--nice-text-muted, #6c757d);text-transform:uppercase}.nice-dashboard-studio__category{margin-bottom:1rem}.nice-dashboard-studio__palette-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;border-radius:4px;cursor:grab;font-size:.875rem}.nice-dashboard-studio__palette-item:hover{background:var(--nice-hover, #e9ecef)}.nice-dashboard-studio__palette-icon{font-size:1rem}.nice-dashboard-studio__grid{flex:1;display:grid;grid-template-columns:repeat(var(--columns, 12),1fr);grid-auto-rows:var(--row-height, 50px);gap:var(--gap, 8px);padding:1rem;overflow:auto}.nice-dashboard-studio__grid--editing{background:repeating-linear-gradient(0deg,transparent,transparent calc(var(--row-height, 50px) - 1px),#e0e0e0 calc(var(--row-height, 50px) - 1px),#e0e0e0 var(--row-height, 50px))}.nice-dashboard-studio__empty{grid-column:1 / -1;display:flex;align-items:center;justify-content:center;color:var(--nice-text-muted, #6c757d)}.nice-dashboard-studio__widget{background:#fff;border-radius:8px;box-shadow:0 1px 3px #0000001a;display:flex;flex-direction:column;overflow:hidden}.nice-dashboard-studio__widget--selected{box-shadow:0 0 0 2px var(--nice-primary, #0066cc)}.nice-dashboard-studio__widget-header{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--nice-border, #eee);background:var(--nice-bg-secondary, #f8f9fa);cursor:move}.nice-dashboard-studio__widget-icon{font-size:.875rem}.nice-dashboard-studio__widget-title{flex:1;font-size:.8125rem;font-weight:500}.nice-dashboard-studio__widget-delete{padding:0;width:20px;height:20px;border:none;background:transparent;cursor:pointer;opacity:.5}.nice-dashboard-studio__widget-delete:hover{opacity:1;color:#dc3545}.nice-dashboard-studio__widget-content{flex:1;padding:.75rem;display:flex;align-items:center;justify-content:center}.nice-dashboard-studio__card{text-align:center}.nice-dashboard-studio__card-value{font-size:2rem;font-weight:700;color:var(--nice-primary, #0066cc)}.nice-dashboard-studio__card-label{font-size:.875rem;color:var(--nice-text-muted, #6c757d)}.nice-dashboard-studio__gauge svg{width:100%;height:100%}.nice-dashboard-studio__chart-placeholder,.nice-dashboard-studio__table-placeholder,.nice-dashboard-studio__map-placeholder,.nice-dashboard-studio__widget-placeholder{display:flex;flex-direction:column;align-items:center;gap:.5rem;color:var(--nice-text-muted, #6c757d)}.nice-dashboard-studio__properties{width:280px;border-left:1px solid var(--nice-border, #ddd);display:flex;flex-direction:column;background:#fff}.nice-dashboard-studio__properties-header{display:flex;justify-content:space-between;align-items:center;padding:.75rem 1rem;border-bottom:1px solid var(--nice-border, #ddd);background:var(--nice-bg-secondary, #f8f9fa)}.nice-dashboard-studio__properties-header h4{margin:0;font-size:.875rem}.nice-dashboard-studio__properties-content{flex:1;overflow-y:auto;padding:1rem}.nice-dashboard-studio__field{margin-bottom:1rem}.nice-dashboard-studio__field label{display:block;margin-bottom:.25rem;font-size:.8125rem;font-weight:500}.nice-dashboard-studio__field input,.nice-dashboard-studio__field select,.nice-dashboard-studio__field textarea{width:100%;padding:.375rem .5rem;border:1px solid var(--nice-border, #ddd);border-radius:4px;font-size:.875rem}.nice-dashboard-studio__size-inputs{display:flex;align-items:center;gap:.5rem}.nice-dashboard-studio__size-inputs input{width:60px}.nice-etl-builder{display:flex;flex-direction:column;height:100%;font-family:system-ui,-apple-system,sans-serif;background:var(--nice-bg, #fff)}.nice-etl-builder__toolbar{display:flex;align-items:center;gap:1rem;padding:.5rem 1rem;border-bottom:1px solid var(--nice-border, #ddd);background:var(--nice-bg-secondary, #f8f9fa)}.nice-etl-builder__name-input{padding:.375rem .75rem;border:1px solid var(--nice-border, #ddd);border-radius:4px;font-size:.9375rem;font-weight:500}.nice-etl-builder__tabs{display:flex;gap:.25rem;flex:1}.nice-etl-builder__tab{padding:.375rem .75rem;border:none;background:transparent;cursor:pointer;font-size:.875rem;border-radius:4px}.nice-etl-builder__tab:hover{background:var(--nice-hover, #e9ecef)}.nice-etl-builder__tab--active{background:var(--nice-primary, #0066cc);color:#fff}.nice-etl-builder__actions{display:flex;gap:.5rem}.nice-etl-builder__run-btn{padding:.5rem 1rem;background:#28a745;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500}.nice-etl-builder__run-btn:disabled{background:#6c757d;cursor:not-allowed}.nice-etl-builder__save-btn{padding:.5rem 1rem;background:var(--nice-primary, #0066cc);color:#fff;border:none;border-radius:4px;cursor:pointer}.nice-etl-builder__main{display:flex;flex:1;overflow:hidden}.nice-etl-builder__palette{width:200px;border-right:1px solid var(--nice-border, #ddd);padding:.5rem;overflow-y:auto;background:var(--nice-bg-secondary, #f8f9fa)}.nice-etl-builder__palette h4{margin:.5rem 0;font-size:.75rem;color:var(--nice-text-muted, #6c757d);text-transform:uppercase}.nice-etl-builder__palette-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;border-radius:4px;cursor:grab;font-size:.875rem}.nice-etl-builder__palette-item:hover{background:var(--nice-hover, #e9ecef)}.nice-etl-builder__palette-icon{font-size:1rem}.nice-etl-builder__palette button{width:100%;padding:.5rem;border:1px dashed var(--nice-border, #ddd);background:transparent;border-radius:4px;cursor:pointer;font-size:.875rem;margin-top:.5rem}.nice-etl-builder__canvas{flex:1;overflow:auto;padding:1rem}.nice-etl-builder__flow{display:flex;gap:1rem;align-items:flex-start;min-height:100%}.nice-etl-builder__column{min-width:200px;max-width:300px}.nice-etl-builder__column h5{margin:0 0 .5rem;font-size:.75rem;color:var(--nice-text-muted, #6c757d);text-transform:uppercase}.nice-etl-builder__column--transforms{flex:1;min-width:300px}.nice-etl-builder__arrow{display:flex;align-items:center;font-size:1.5rem;color:var(--nice-text-muted, #6c757d);padding-top:2rem}.nice-etl-builder__empty-column{padding:2rem 1rem;border:2px dashed var(--nice-border, #ddd);border-radius:8px;text-align:center;color:var(--nice-text-muted, #6c757d)}.nice-etl-builder__node{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;background:#fff;border:1px solid var(--nice-border, #ddd);border-radius:8px;margin-bottom:.5rem;cursor:pointer;box-shadow:0 1px 3px #0000000d}.nice-etl-builder__node:hover{border-color:var(--nice-primary, #0066cc)}.nice-etl-builder__node--selected{border-color:var(--nice-primary, #0066cc);box-shadow:0 0 0 2px #06c3}.nice-etl-builder__node-icon{font-size:1.125rem}.nice-etl-builder__node-name{flex:1;font-size:.875rem;font-weight:500}.nice-etl-builder__node-delete{padding:0;width:20px;height:20px;border:none;background:transparent;cursor:pointer;opacity:0;transition:opacity .2s}.nice-etl-builder__node:hover .nice-etl-builder__node-delete{opacity:.5}.nice-etl-builder__node-delete:hover{opacity:1;color:#dc3545}.nice-etl-builder__properties{width:300px;border-left:1px solid var(--nice-border, #ddd);display:flex;flex-direction:column;background:#fff}.nice-etl-builder__properties-header{display:flex;justify-content:space-between;align-items:center;padding:.75rem 1rem;border-bottom:1px solid var(--nice-border, #ddd);background:var(--nice-bg-secondary, #f8f9fa)}.nice-etl-builder__properties-header h4{margin:0;font-size:.875rem}.nice-etl-builder__properties-content{flex:1;overflow-y:auto;padding:1rem}.nice-etl-builder__field{margin-bottom:1rem}.nice-etl-builder__field label{display:block;margin-bottom:.25rem;font-size:.8125rem;font-weight:500}.nice-etl-builder__field input,.nice-etl-builder__field select,.nice-etl-builder__field textarea{width:100%;padding:.375rem .5rem;border:1px solid var(--nice-border, #ddd);border-radius:4px;font-size:.875rem}.nice-etl-builder__code-input{font-family:Fira Code,monospace;font-size:.8125rem}.nice-etl-builder__code-view,.nice-etl-builder__schedule-editor,.nice-etl-builder__history-view{flex:1;padding:1rem;overflow:auto}.nice-etl-builder__code-view pre{margin:0;font-family:Fira Code,monospace;font-size:.8125rem}.nice-etl-builder__schedule-editor h4{margin:0 0 1rem}.nice-etl-builder__schedule-editor small{display:block;color:var(--nice-text-muted, #6c757d);font-size:.75rem;margin-top:.25rem}.nice-etl-builder__history-table{width:100%;border-collapse:collapse}.nice-etl-builder__history-table th,.nice-etl-builder__history-table td{padding:.75rem;text-align:left;border-bottom:1px solid var(--nice-border, #ddd)}.nice-etl-builder__history-table th{background:var(--nice-bg-secondary, #f8f9fa);font-weight:500;font-size:.8125rem}.nice-etl-builder__status{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:4px;font-size:.8125rem}.nice-etl-builder__status--success{background:#d4edda;color:#155724}.nice-etl-builder__status--failed{background:#f8d7da;color:#721c24}.nice-etl-builder__status--running{background:#fff3cd;color:#856404}.nice-etl-builder__no-history{text-align:center;color:var(--nice-text-muted, #6c757d);padding:2rem}
@@ -0,0 +1,448 @@
1
+ /**
2
+ * @package @nice2dev/ui-bi
3
+ * Business Intelligence Types
4
+ */
5
+ export interface DataSource {
6
+ id: string;
7
+ name: string;
8
+ type: 'database' | 'api' | 'file' | 'spreadsheet' | 'custom';
9
+ connectionString?: string;
10
+ config: DataSourceConfig;
11
+ schema?: DataSchema;
12
+ }
13
+ export interface DataSourceConfig {
14
+ host?: string;
15
+ port?: number;
16
+ database?: string;
17
+ username?: string;
18
+ password?: string;
19
+ ssl?: boolean;
20
+ apiUrl?: string;
21
+ apiKey?: string;
22
+ filePath?: string;
23
+ fileType?: 'csv' | 'json' | 'excel' | 'parquet';
24
+ }
25
+ export interface DataSchema {
26
+ tables: TableSchema[];
27
+ relationships: Relationship[];
28
+ }
29
+ export interface TableSchema {
30
+ name: string;
31
+ columns: ColumnSchema[];
32
+ primaryKey?: string;
33
+ }
34
+ export interface ColumnSchema {
35
+ name: string;
36
+ type: 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'object' | 'array';
37
+ nullable?: boolean;
38
+ format?: string;
39
+ description?: string;
40
+ }
41
+ export interface Relationship {
42
+ id: string;
43
+ sourceTable: string;
44
+ sourceColumn: string;
45
+ targetTable: string;
46
+ targetColumn: string;
47
+ type: 'one-to-one' | 'one-to-many' | 'many-to-many';
48
+ }
49
+ export interface Report {
50
+ id: string;
51
+ name: string;
52
+ description?: string;
53
+ dataSource: string;
54
+ query?: ReportQuery;
55
+ layout: ReportLayout;
56
+ parameters: ReportParameter[];
57
+ filters: ReportFilter[];
58
+ sorting: ReportSorting[];
59
+ grouping: ReportGrouping[];
60
+ calculations: CalculatedField[];
61
+ formatting: ReportFormatting;
62
+ drillDown?: DrillDownConfig;
63
+ }
64
+ export interface ReportQuery {
65
+ type: 'sql' | 'builder' | 'dax';
66
+ text?: string;
67
+ tables?: string[];
68
+ joins?: QueryJoin[];
69
+ columns?: QueryColumn[];
70
+ conditions?: QueryCondition[];
71
+ }
72
+ export interface QueryJoin {
73
+ table: string;
74
+ type: 'inner' | 'left' | 'right' | 'full';
75
+ on: {
76
+ left: string;
77
+ right: string;
78
+ };
79
+ }
80
+ export interface QueryColumn {
81
+ table: string;
82
+ column: string;
83
+ alias?: string;
84
+ aggregate?: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'distinct';
85
+ }
86
+ export interface QueryCondition {
87
+ column: string;
88
+ operator: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'like' | 'between' | 'null';
89
+ value: unknown;
90
+ logicalOperator?: 'and' | 'or';
91
+ }
92
+ export interface ReportLayout {
93
+ type: 'table' | 'matrix' | 'chart' | 'card' | 'mixed';
94
+ elements: ReportElement[];
95
+ pageSize?: 'A4' | 'Letter' | 'Legal' | 'custom';
96
+ orientation?: 'portrait' | 'landscape';
97
+ margins?: {
98
+ top: number;
99
+ right: number;
100
+ bottom: number;
101
+ left: number;
102
+ };
103
+ }
104
+ export interface ReportElement {
105
+ id: string;
106
+ type: ReportElementType;
107
+ position: {
108
+ x: number;
109
+ y: number;
110
+ width: number;
111
+ height: number;
112
+ };
113
+ config: Record<string, unknown>;
114
+ binding?: DataBinding;
115
+ style?: ElementStyle;
116
+ }
117
+ export type ReportElementType = 'table' | 'chart' | 'text' | 'image' | 'shape' | 'barcode' | 'qrcode' | 'subreport' | 'page-break';
118
+ export interface DataBinding {
119
+ field?: string;
120
+ expression?: string;
121
+ format?: string;
122
+ aggregate?: 'sum' | 'avg' | 'count' | 'min' | 'max';
123
+ }
124
+ export interface ElementStyle {
125
+ backgroundColor?: string;
126
+ borderColor?: string;
127
+ borderWidth?: number;
128
+ fontFamily?: string;
129
+ fontSize?: number;
130
+ fontWeight?: 'normal' | 'bold';
131
+ color?: string;
132
+ textAlign?: 'left' | 'center' | 'right';
133
+ padding?: number | {
134
+ top: number;
135
+ right: number;
136
+ bottom: number;
137
+ left: number;
138
+ };
139
+ }
140
+ export interface ReportParameter {
141
+ id: string;
142
+ name: string;
143
+ label: string;
144
+ type: 'text' | 'number' | 'date' | 'daterange' | 'select' | 'multiselect';
145
+ defaultValue?: unknown;
146
+ required?: boolean;
147
+ options?: Array<{
148
+ value: unknown;
149
+ label: string;
150
+ }>;
151
+ dataSource?: string;
152
+ }
153
+ export interface ReportFilter {
154
+ id: string;
155
+ field: string;
156
+ operator: string;
157
+ value: unknown;
158
+ enabled: boolean;
159
+ }
160
+ export interface ReportSorting {
161
+ field: string;
162
+ direction: 'asc' | 'desc';
163
+ }
164
+ export interface ReportGrouping {
165
+ field: string;
166
+ showHeader?: boolean;
167
+ showFooter?: boolean;
168
+ pageBreakAfter?: boolean;
169
+ }
170
+ export interface CalculatedField {
171
+ id: string;
172
+ name: string;
173
+ expression: string;
174
+ format?: string;
175
+ description?: string;
176
+ }
177
+ export interface ReportFormatting {
178
+ conditionalFormats: ConditionalFormat[];
179
+ alternateRowColors?: boolean;
180
+ gridLines?: boolean;
181
+ headerStyle?: ElementStyle;
182
+ footerStyle?: ElementStyle;
183
+ }
184
+ export interface ConditionalFormat {
185
+ id: string;
186
+ condition: QueryCondition;
187
+ style: ElementStyle;
188
+ scope: 'row' | 'cell' | 'column';
189
+ }
190
+ export interface DrillDownConfig {
191
+ enabled: boolean;
192
+ levels: DrillDownLevel[];
193
+ }
194
+ export interface DrillDownLevel {
195
+ field: string;
196
+ label: string;
197
+ targetReport?: string;
198
+ }
199
+ export interface Dashboard {
200
+ id: string;
201
+ name: string;
202
+ description?: string;
203
+ layout: DashboardLayout;
204
+ widgets: DashboardWidget[];
205
+ filters: DashboardFilter[];
206
+ refreshInterval?: number;
207
+ theme?: DashboardTheme;
208
+ sharing?: SharingConfig;
209
+ }
210
+ export interface DashboardLayout {
211
+ type: 'grid' | 'freeform' | 'responsive';
212
+ columns?: number;
213
+ rowHeight?: number;
214
+ gap?: number;
215
+ }
216
+ export interface DashboardWidget {
217
+ id: string;
218
+ type: WidgetType;
219
+ title?: string;
220
+ position: GridPosition;
221
+ config: WidgetConfig;
222
+ dataSource?: string;
223
+ query?: ReportQuery;
224
+ refreshInterval?: number;
225
+ interactions?: WidgetInteraction[];
226
+ }
227
+ export type WidgetType = 'chart' | 'table' | 'card' | 'gauge' | 'map' | 'text' | 'image' | 'filter' | 'slicer' | 'timeline' | 'treemap' | 'funnel' | 'sankey' | 'heatmap';
228
+ export interface GridPosition {
229
+ x: number;
230
+ y: number;
231
+ width: number;
232
+ height: number;
233
+ }
234
+ export interface WidgetConfig {
235
+ chartType?: ChartType;
236
+ series?: ChartSeries[];
237
+ axes?: ChartAxis[];
238
+ legend?: LegendConfig;
239
+ tooltips?: boolean;
240
+ animation?: boolean;
241
+ colorScheme?: string;
242
+ value?: string | DataBinding;
243
+ label?: string;
244
+ target?: number;
245
+ format?: string;
246
+ columns?: TableColumn[];
247
+ mapConfig?: MapConfig;
248
+ [key: string]: unknown;
249
+ }
250
+ export type ChartType = 'line' | 'bar' | 'column' | 'area' | 'pie' | 'donut' | 'scatter' | 'bubble' | 'radar' | 'polar' | 'waterfall' | 'candlestick';
251
+ export interface ChartSeries {
252
+ name: string;
253
+ field: string;
254
+ type?: ChartType;
255
+ color?: string;
256
+ stack?: string;
257
+ }
258
+ export interface ChartAxis {
259
+ type: 'x' | 'y' | 'y2';
260
+ field?: string;
261
+ label?: string;
262
+ format?: string;
263
+ min?: number;
264
+ max?: number;
265
+ gridLines?: boolean;
266
+ }
267
+ export interface LegendConfig {
268
+ show: boolean;
269
+ position: 'top' | 'bottom' | 'left' | 'right';
270
+ }
271
+ export interface TableColumn {
272
+ field: string;
273
+ header: string;
274
+ width?: number;
275
+ format?: string;
276
+ sortable?: boolean;
277
+ filterable?: boolean;
278
+ }
279
+ export interface MapConfig {
280
+ type: 'choropleth' | 'bubble' | 'heatmap';
281
+ geoField: string;
282
+ valueField: string;
283
+ colorScale?: string[];
284
+ }
285
+ export interface WidgetInteraction {
286
+ type: 'filter' | 'drilldown' | 'link';
287
+ targetWidgets?: string[];
288
+ field?: string;
289
+ url?: string;
290
+ }
291
+ export interface DashboardFilter {
292
+ id: string;
293
+ type: 'dropdown' | 'slider' | 'daterange' | 'checkbox' | 'search';
294
+ field: string;
295
+ label: string;
296
+ defaultValue?: unknown;
297
+ dataSource?: string;
298
+ affectedWidgets: string[];
299
+ }
300
+ export interface DashboardTheme {
301
+ name: string;
302
+ primaryColor: string;
303
+ secondaryColor: string;
304
+ backgroundColor: string;
305
+ textColor: string;
306
+ fontFamily: string;
307
+ }
308
+ export interface SharingConfig {
309
+ isPublic: boolean;
310
+ allowEmbed: boolean;
311
+ embedCode?: string;
312
+ sharedWith: SharedUser[];
313
+ }
314
+ export interface SharedUser {
315
+ email: string;
316
+ role: 'viewer' | 'editor' | 'admin';
317
+ }
318
+ export interface ETLPipeline {
319
+ id: string;
320
+ name: string;
321
+ description?: string;
322
+ sources: ETLSource[];
323
+ transformations: ETLTransformation[];
324
+ destinations: ETLDestination[];
325
+ schedule?: ETLSchedule;
326
+ monitoring?: ETLMonitoring;
327
+ version: number;
328
+ }
329
+ export interface ETLSource {
330
+ id: string;
331
+ type: 'database' | 'api' | 'file' | 'stream';
332
+ name: string;
333
+ config: DataSourceConfig;
334
+ schema?: TableSchema;
335
+ incremental?: {
336
+ enabled: boolean;
337
+ column: string;
338
+ lastValue?: unknown;
339
+ };
340
+ }
341
+ export interface ETLTransformation {
342
+ id: string;
343
+ type: ETLTransformationType;
344
+ name: string;
345
+ input: string[];
346
+ output: string;
347
+ config: Record<string, unknown>;
348
+ }
349
+ export type ETLTransformationType = 'filter' | 'map' | 'aggregate' | 'join' | 'union' | 'sort' | 'deduplicate' | 'pivot' | 'unpivot' | 'split' | 'merge' | 'lookup' | 'derive' | 'validate' | 'cleanse' | 'custom';
350
+ export interface ETLDestination {
351
+ id: string;
352
+ type: 'database' | 'file' | 'api' | 'warehouse';
353
+ name: string;
354
+ config: DataSourceConfig;
355
+ schema?: TableSchema;
356
+ writeMode: 'append' | 'overwrite' | 'upsert' | 'merge';
357
+ upsertKeys?: string[];
358
+ }
359
+ export interface ETLSchedule {
360
+ enabled: boolean;
361
+ cron?: string;
362
+ interval?: number;
363
+ timezone?: string;
364
+ startDate?: string;
365
+ endDate?: string;
366
+ }
367
+ export interface ETLMonitoring {
368
+ alertOnFailure: boolean;
369
+ alertEmail?: string;
370
+ logLevel: 'error' | 'warn' | 'info' | 'debug';
371
+ retryConfig?: {
372
+ maxRetries: number;
373
+ retryDelay: number;
374
+ };
375
+ }
376
+ export interface ETLRun {
377
+ id: string;
378
+ pipelineId: string;
379
+ status: 'pending' | 'running' | 'success' | 'failed' | 'cancelled';
380
+ startTime: Date;
381
+ endTime?: Date;
382
+ rowsProcessed: number;
383
+ rowsWritten: number;
384
+ errors: ETLError[];
385
+ }
386
+ export interface ETLError {
387
+ timestamp: Date;
388
+ stage: string;
389
+ message: string;
390
+ row?: Record<string, unknown>;
391
+ }
392
+ export interface Cube {
393
+ id: string;
394
+ name: string;
395
+ description?: string;
396
+ dimensions: CubeDimension[];
397
+ measures: CubeMeasure[];
398
+ hierarchies: CubeHierarchy[];
399
+ dataSource: string;
400
+ }
401
+ export interface CubeDimension {
402
+ name: string;
403
+ table: string;
404
+ column: string;
405
+ type: 'standard' | 'date' | 'geography';
406
+ hierarchy?: string;
407
+ }
408
+ export interface CubeMeasure {
409
+ name: string;
410
+ column: string;
411
+ aggregate: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'distinctcount';
412
+ format?: string;
413
+ }
414
+ export interface CubeHierarchy {
415
+ name: string;
416
+ dimension: string;
417
+ levels: string[];
418
+ }
419
+ export interface NiceReportBuilderProps {
420
+ report?: Report;
421
+ dataSources?: DataSource[];
422
+ onChange?: (report: Report) => void;
423
+ onPreview?: (report: Report) => void;
424
+ onExport?: (report: Report, format: 'pdf' | 'excel' | 'csv') => void;
425
+ className?: string;
426
+ }
427
+ export interface NiceDashboardStudioProps {
428
+ dashboard?: Dashboard;
429
+ dataSources?: DataSource[];
430
+ widgets?: DashboardWidget[];
431
+ onChange?: (dashboard: Dashboard) => void;
432
+ onWidgetAdd?: (type: WidgetType) => void;
433
+ onRefresh?: () => void;
434
+ className?: string;
435
+ }
436
+ export interface NiceETLBuilderProps {
437
+ pipeline?: ETLPipeline;
438
+ dataSources?: DataSource[];
439
+ onChange?: (pipeline: ETLPipeline) => void;
440
+ onRun?: (pipeline: ETLPipeline) => Promise<ETLRun>;
441
+ onSchedule?: (pipeline: ETLPipeline, schedule: ETLSchedule) => void;
442
+ className?: string;
443
+ }
444
+ export interface NiceCubeBrowserProps {
445
+ cube?: Cube;
446
+ onQuery?: (dimensions: string[], measures: string[], filters: ReportFilter[]) => Promise<unknown[]>;
447
+ className?: string;
448
+ }
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@nice2dev/ui-bi",
3
+ "version": "1.0.10",
4
+ "description": "Nice2Dev Business Intelligence — Report builder, dashboard studio, ETL pipeline builder",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.mjs",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./style.css": "./dist/style.css"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "LICENSE",
20
+ "CHANGELOG.md",
21
+ "README.md"
22
+ ],
23
+ "sideEffects": [
24
+ "*.css"
25
+ ],
26
+ "scripts": {
27
+ "dev": "vite",
28
+ "build": "tsc -p tsconfig.build.json && vite build",
29
+ "test": "vitest run --passWithNoTests",
30
+ "test:watch": "vitest",
31
+ "test:coverage": "vitest run --coverage",
32
+ "typecheck": "tsc --noEmit",
33
+ "prepublishOnly": "npm run build"
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=17.0.0",
37
+ "react-dom": ">=17.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@testing-library/jest-dom": "^6.9.1",
41
+ "@testing-library/react": "^14.0.0",
42
+ "@types/react": "^18.2.0",
43
+ "@types/react-dom": "^18.2.0",
44
+ "@vitejs/plugin-react": "^4.2.0",
45
+ "react": "^18.2.0",
46
+ "react-dom": "^18.2.0",
47
+ "typescript": "^5.3.0",
48
+ "vite": "^5.0.0",
49
+ "vite-plugin-dts": "^3.7.0",
50
+ "vitest": "^4.1.0"
51
+ },
52
+ "keywords": [
53
+ "nice2dev",
54
+ "bi",
55
+ "business-intelligence",
56
+ "dashboard",
57
+ "reports",
58
+ "analytics",
59
+ "react"
60
+ ],
61
+ "author": "Nice2Dev Team",
62
+ "license": "SEE LICENSE IN LICENSE"
63
+ }