Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
portal-apps-manage
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
angular
portal-apps-manage
Commits
c9833196
Commit
c9833196
authored
Aug 31, 2025
by
Ooh-Ao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
config
parent
041bbcaf
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
96 additions
and
409 deletions
+96
-409
dashboard-management.component.html
.../dashboard-management/dashboard-management.component.html
+4
-4
dashboard-management.component.ts
...PU/dashboard-management/dashboard-management.component.ts
+29
-28
dataset-picker.component.html
...pp/DPU/dashboard-management/dataset-picker.component.html
+1
-1
dataset-picker.component.scss
...pp/DPU/dashboard-management/dataset-picker.component.scss
+0
-1
dashboard-viewer.component.ts
src/app/DPU/dashboard-viewer/dashboard-viewer.component.ts
+1
-1
widgets.model.ts
src/app/DPU/models/widgets.model.ts
+12
-6
dashboard-data.service.ts
src/app/DPU/services/dashboard-data.service.ts
+25
-38
mock-dashboard.service.ts
src/app/DPU/services/mock-dashboard.service.ts
+0
-75
dashboard.actions.ts
src/app/DPU/state/dashboard.actions.ts
+0
-26
dashboard.effects.ts
src/app/DPU/state/dashboard.effects.ts
+0
-69
dashboard.reducer.ts
src/app/DPU/state/dashboard.reducer.ts
+0
-39
dashboard.selectors.ts
src/app/DPU/state/dashboard.selectors.ts
+0
-30
widget-form.component.ts
src/app/DPU/widget-management/widget-form.component.ts
+2
-2
widget-list.component.ts
src/app/DPU/widget-management/widget-list.component.ts
+2
-4
app.config.ts
src/app/app.config.ts
+0
-4
dashboard-data.service.ts
src/app/shared/services/dashboard-data.service.ts
+20
-81
No files found.
src/app/DPU/dashboard-management/dashboard-management.component.html
View file @
c9833196
...
...
@@ -80,8 +80,8 @@
(
change
)="
loadSelectedDashboard
()"
class=
"p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white"
>
<option
*
ngFor=
"let dash of userDashboards"
[
value
]="
dash
.
id
"
>
{{ dash.
n
ame }}
<option
*
ngFor=
"let dash of userDashboards"
[
ngValue
]="
dash
"
>
{{ dash.
thN
ame }}
</option>
</select>
<app-dataset-picker
...
...
@@ -90,7 +90,7 @@
<div
*
ngIf=
"dashboardData"
class=
"relative flex items-center"
>
<input
type=
"text"
[(
ngModel
)]="
dashboardData
.
n
ame
"
[(
ngModel
)]="
dashboardData
.
thN
ame
"
(
blur
)="
saveDashboardName
()"
class=
"p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white text-gray-800 font-semibold"
/>
...
...
@@ -137,7 +137,7 @@
</div>
<div
class=
"dashboard-content"
>
<ejs-dashboardlayout
[
columns
]="
6
"
#
editLayout
...
...
src/app/DPU/dashboard-management/dashboard-management.component.ts
View file @
c9833196
...
...
@@ -111,7 +111,7 @@ export class DashboardManagementComponent implements OnInit {
public
dashboardData
:
DashboardModel
|
null
=
null
;
public
userDashboards
:
DashboardModel
[]
=
[];
public
selectedDashboardId
:
string
=
''
;
public
selectedDashboardId
:
DashboardModel
private
localWidgets
:
WidgetModel
[]
=
[
new
WidgetModel
({
...
...
@@ -212,6 +212,15 @@ export class DashboardManagementComponent implements OnInit {
component
:
'ScatterBubbleChartWidgetComponent'
,
cols
:
3
,
rows
:
2
,
config
:
{
title
:
'Employee Performance vs. Salary (Scatter)'
,
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
xField
:
'performanceScore'
,
yField
:
'salary'
,
xAxisTitle
:
'Performance Score'
,
yAxisTitle
:
'Salary'
,
type
:
'Scatter'
}
}),
new
WidgetModel
({
id
:
'local-multi-row-card'
,
...
...
@@ -377,10 +386,10 @@ export class DashboardManagementComponent implements OnInit {
ngOnInit
():
void
{
this
.
dashboardDataService
.
getDashboards
().
subscribe
(
dashboards
=>
{
this
.
userDashboards
=
dashboards
;
if
(
this
.
userDashboards
.
length
>
0
)
{
this
.
selectedDashboardId
=
this
.
userDashboards
[
0
].
id
;
this
.
loadSelectedDashboard
();
}
//
if (this.userDashboards.length > 0) {
// this.selectedDashboardId = this.userDashboards[0]
;
//
this.loadSelectedDashboard();
//
}
});
// Populate availableWidgets from WidgetService
...
...
@@ -410,8 +419,9 @@ export class DashboardManagementComponent implements OnInit {
}
loadSelectedDashboard
():
void
{
console
.
log
(
this
.
selectedDashboardId
)
if
(
this
.
selectedDashboardId
)
{
this
.
dashboardDataService
.
getDashboardById
(
this
.
selectedDashboardId
).
subscribe
(
dashboard
=>
{
this
.
dashboardDataService
.
getDashboardById
(
this
.
selectedDashboardId
.
dashboardId
).
subscribe
(
dashboard
=>
{
if
(
dashboard
)
{
this
.
dashboardData
=
dashboard
;
this
.
panels
=
this
.
mapWidgetsToPanels
(
dashboard
.
widgets
||
[]);
...
...
@@ -427,13 +437,13 @@ export class DashboardManagementComponent implements OnInit {
const
newDashboardName
=
prompt
(
'Enter a name for the new dashboard:'
);
if
(
newDashboardName
)
{
const
newDashboard
=
new
DashboardModel
({
i
d
:
`dash-
${
Date
.
now
()}
`
,
n
ame
:
newDashboardName
,
dashboardI
d
:
`dash-
${
Date
.
now
()}
`
,
thN
ame
:
newDashboardName
,
widgets
:
[]
});
this
.
dashboardDataService
.
add
Dashboard
(
newDashboard
).
subscribe
(
addedDashboard
=>
{
this
.
dashboardDataService
.
save
Dashboard
(
newDashboard
).
subscribe
(
addedDashboard
=>
{
this
.
userDashboards
.
push
(
addedDashboard
);
this
.
selectedDashboardId
=
addedDashboard
.
id
;
this
.
selectedDashboardId
=
addedDashboard
;
this
.
loadSelectedDashboard
();
});
}
...
...
@@ -441,7 +451,7 @@ export class DashboardManagementComponent implements OnInit {
saveDashboardName
():
void
{
if
(
this
.
dashboardData
)
{
this
.
dashboardDataService
.
updat
eDashboard
(
this
.
dashboardData
).
subscribe
();
this
.
dashboardDataService
.
sav
eDashboard
(
this
.
dashboardData
).
subscribe
();
}
}
...
...
@@ -451,7 +461,7 @@ export class DashboardManagementComponent implements OnInit {
// Ensure widget.config exists, initialize if not.
const
widgetConfig
=
widget
.
config
||
{};
return
{
id
:
widget
.
id
,
...
...
@@ -484,11 +494,11 @@ export class DashboardManagementComponent implements OnInit {
if
(
dataFetchTasks
.
length
>
0
)
{
forkJoin
(
dataFetchTasks
).
subscribe
(()
=>
{
console
.
log
(
'All data fetched, now saving dashboard...'
);
this
.
dashboardDataService
.
updat
eDashboard
(
this
.
dashboardData
!
).
subscribe
();
this
.
dashboardDataService
.
sav
eDashboard
(
this
.
dashboardData
!
).
subscribe
();
});
}
else
{
console
.
log
(
'No data to fetch, saving dashboard directly...'
);
this
.
dashboardDataService
.
updat
eDashboard
(
this
.
dashboardData
).
subscribe
();
this
.
dashboardDataService
.
sav
eDashboard
(
this
.
dashboardData
).
subscribe
();
}
}
...
...
@@ -538,18 +548,9 @@ export class DashboardManagementComponent implements OnInit {
deleteDashboard
():
void
{
if
(
this
.
selectedDashboardId
&&
confirm
(
'Are you sure you want to delete this dashboard?'
))
{
this
.
dashboardDataService
.
deleteDashboard
(
this
.
selectedDashboardId
).
subscribe
(()
=>
{
this
.
dashboardDataService
.
getDashboards
().
subscribe
(
dashboards
=>
{
this
.
userDashboards
=
dashboards
;
if
(
this
.
userDashboards
.
length
>
0
)
{
this
.
selectedDashboardId
=
this
.
userDashboards
[
0
].
id
;
this
.
loadSelectedDashboard
();
}
else
{
this
.
selectedDashboardId
=
''
;
this
.
dashboardData
=
null
;
this
.
panels
=
[];
}
});
this
.
dashboardDataService
.
deleteDashboard
(
this
.
selectedDashboardId
).
subscribe
(
result
=>
{
console
.
log
(
result
)
});
}
}
...
...
@@ -558,7 +559,7 @@ export class DashboardManagementComponent implements OnInit {
if
(
!
this
.
dashboardData
)
return
;
if
(
confirm
(
'Are you sure you want to remove this widget?'
))
{
const
updatedDashboard
=
{
...
this
.
dashboardData
,
widgets
:
this
.
dashboardData
.
widgets
.
filter
(
w
=>
w
.
id
!==
panelId
)
};
this
.
dashboardDataService
.
updat
eDashboard
(
updatedDashboard
).
subscribe
(
updated
=>
{
this
.
dashboardDataService
.
sav
eDashboard
(
updatedDashboard
).
subscribe
(
updated
=>
{
this
.
dashboardData
=
updated
;
this
.
panels
=
this
.
mapWidgetsToPanels
(
this
.
dashboardData
.
widgets
);
});
...
...
@@ -597,7 +598,7 @@ export class DashboardManagementComponent implements OnInit {
// Re-map panels to reflect changes
this
.
panels
=
this
.
mapWidgetsToPanels
(
this
.
dashboardData
.
widgets
);
// Save the updated dashboard
this
.
dashboardDataService
.
updat
eDashboard
(
this
.
dashboardData
).
subscribe
();
this
.
dashboardDataService
.
sav
eDashboard
(
this
.
dashboardData
).
subscribe
();
}
}
}
...
...
src/app/DPU/dashboard-management/dataset-picker.component.html
View file @
c9833196
...
...
@@ -2,7 +2,7 @@
<label
for=
"dataset-select"
>
Select Dataset:
</label>
<select
id=
"dataset-select"
(
change
)="
onDatasetChange
($
event
)"
>
<option
value=
""
>
-- Please choose a dataset --
</option>
<option
*
ngFor=
"let dataset of datasets$ | async"
[
value
]="
dataset
.
id
"
>
<option
*
ngFor=
"let dataset of datasets$ | async"
[
value
]="
dataset
"
>
{{ dataset.name }}
</option>
</select>
...
...
src/app/DPU/dashboard-management/dataset-picker.component.scss
View file @
c9833196
...
...
@@ -2,7 +2,6 @@
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
margin-bottom
:
20px
;
}
label
{
...
...
src/app/DPU/dashboard-viewer/dashboard-viewer.component.ts
View file @
c9833196
...
...
@@ -147,7 +147,7 @@ export class DashboardViewerComponent implements OnInit {
}
loadDashboard
(
dashboard
:
DashboardModel
):
void
{
this
.
dashboardName
=
dashboard
.
n
ame
;
this
.
dashboardName
=
dashboard
.
thN
ame
;
if
(
dashboard
.
datasetId
)
{
this
.
dashboardStateService
.
selectDataset
(
dashboard
.
datasetId
);
...
...
src/app/DPU/models/widgets.model.ts
View file @
c9833196
...
...
@@ -57,23 +57,29 @@ export class WidgetModel implements IWidget {
}
export
interface
IDashboard
{
id
:
string
;
name
:
string
;
dashboardId
:
string
;
thName
:
string
;
engName
:
string
;
application
:
string
;
description
:
string
;
datasetId
?:
string
;
widgets
:
IWidget
[];
}
export
class
DashboardModel
implements
IDashboard
{
id
:
string
;
name
:
string
;
dashboardId
:
string
;
thName
:
string
;
engName
:
string
;
application
:
string
;
description
:
string
;
datasetId
?:
string
;
widgets
:
IWidget
[];
constructor
(
data
:
Partial
<
IDashboard
>
)
{
this
.
id
=
data
.
id
??
''
;
this
.
name
=
data
.
name
??
''
;
this
.
dashboardId
=
data
.
dashboardId
??
''
;
this
.
thName
=
data
.
thName
??
''
;
this
.
engName
=
data
.
engName
??
''
;
this
.
application
=
data
.
application
??
''
;
this
.
description
=
data
.
description
??
''
;
this
.
datasetId
=
data
.
datasetId
;
this
.
widgets
=
data
.
widgets
?
data
.
widgets
.
map
(
w
=>
new
WidgetModel
(
w
))
:
[];
...
...
src/app/DPU/services/dashboard-data.service.ts
View file @
c9833196
import
{
Injectable
}
from
'@angular/core'
;
import
{
Observable
,
of
}
from
'rxjs'
;
import
{
DashboardModel
,
WidgetModel
}
from
'../models/widgets.model'
;
import
{
MockDashboardService
}
from
'./mock-dashboard.service'
;
import
{
HttpClient
,
HttpHeaders
,
HttpParams
}
from
'@angular/common/http'
;
import
{
environment
}
from
'../../../environments/environment'
;
@
Injectable
({
providedIn
:
'root'
})
export
class
DashboardDataService
{
constructor
(
private
mockDashboardService
:
MockDashboardService
)
{
}
getDashboards
():
Observable
<
DashboardModel
[]
>
{
// In a real application, this would call an API
return
this
.
mockDashboardService
.
getDashboards
();
apiBaseUrl
=
environment
.
url
+
"dashboard"
constructor
(
private
http
:
HttpClient
)
{
}
getDashboards
(
queryParams
?:
any
):
Observable
<
DashboardModel
[]
>
{
let
params
=
new
HttpParams
();
if
(
queryParams
)
{
Object
.
keys
(
queryParams
).
forEach
(
key
=>
{
params
=
params
.
set
(
key
,
queryParams
[
key
]);
});
}
return
this
.
http
.
get
<
DashboardModel
[]
>
(
`
${
this
.
apiBaseUrl
}
/lists/search`
,
{
params
})
}
getDashboardById
(
id
:
string
):
Observable
<
DashboardModel
|
undefined
>
{
// In a real application, this would call an API
return
this
.
mockDashboardService
.
getDashboardById
(
id
);
return
this
.
http
.
get
<
DashboardModel
>
(
this
.
apiBaseUrl
+
"/"
+
id
)
}
// For now, these methods will operate on the in-memory mock data
// In a real application, these would call API endpoints for CUD operations
addDashboard
(
dashboard
:
DashboardModel
):
Observable
<
DashboardModel
>
{
// Simulate adding to mock data (not persistent across app restarts)
const
currentDashboards
=
this
.
mockDashboardService
.
getDashboards
();
currentDashboards
.
subscribe
(
dashboards
=>
{
dashboards
.
push
(
dashboard
);
});
return
of
(
dashboard
);
}
updateDashboard
(
updatedDashboard
:
DashboardModel
):
Observable
<
DashboardModel
>
{
// Simulate updating mock data (not persistent across app restarts)
const
currentDashboards
=
this
.
mockDashboardService
.
getDashboards
();
currentDashboards
.
subscribe
(
dashboards
=>
{
const
index
=
dashboards
.
findIndex
(
d
=>
d
.
id
===
updatedDashboard
.
id
);
if
(
index
>
-
1
)
{
dashboards
[
index
]
=
updatedDashboard
;
}
});
return
of
(
updatedDashboard
);
saveDashboard
(
dashboard
:
DashboardModel
):
Observable
<
DashboardModel
>
{
return
this
.
http
.
post
<
any
>
(
this
.
apiBaseUrl
,
dashboard
);
}
deleteDashboard
(
id
:
string
):
Observable
<
void
>
{
// Simulate deleting from mock data (not persistent across app restarts)
const
currentDashboards
=
this
.
mockDashboardService
.
getDashboards
();
currentDashboards
.
subscribe
(
dashboards
=>
{
const
index
=
dashboards
.
findIndex
(
d
=>
d
.
id
===
id
);
if
(
index
>
-
1
)
{
dashboards
.
splice
(
index
,
1
);
}
});
return
of
(
undefined
);
deleteDashboard
(
dashboard
:
DashboardModel
):
Observable
<
void
>
{
const
options
=
{
headers
:
new
HttpHeaders
({
"Content-Type"
:
"application/json"
,
}),
body
:
{}
};
return
this
.
http
.
delete
<
any
>
(
this
.
apiBaseUrl
,
options
);
}
// Assuming widgets are managed as part of dashboards for now
...
...
src/app/DPU/services/mock-dashboard.service.ts
deleted
100644 → 0
View file @
041bbcaf
import
{
Injectable
}
from
'@angular/core'
;
import
{
Observable
,
of
}
from
'rxjs'
;
import
{
DashboardModel
,
WidgetModel
}
from
'../models/widgets.model'
;
export
const
MOCK_DASHBOARD_DATA
:
DashboardModel
[]
=
[
{
id
:
'1'
,
name
:
'Sales Dashboard'
,
description
:
'Dashboard showing sales performance over time.'
,
widgets
:
[
{
id
:
'101'
,
name
:
'Monthly Sales'
,
component
:
'ChartWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
0
,
y
:
0
,
data
:
{
type
:
'bar'
,
labels
:
[
'Jan'
,
'Feb'
,
'Mar'
],
datasets
:
[{
data
:
[
65
,
59
,
80
],
label
:
'Series A'
}]
},
config
:
{}
},
{
id
:
'102'
,
name
:
'Top Products'
,
component
:
'SyncfusionDatagridWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
2
,
y
:
0
,
data
:
{
columns
:
[
'Product'
,
'Sales'
],
data
:
[{
Product
:
'A'
,
Sales
:
100
},
{
Product
:
'B'
,
Sales
:
150
}]
},
config
:
{}
}
]
},
{
id
:
'2'
,
name
:
'Marketing Overview'
,
description
:
'Overview of marketing campaign performance.'
,
widgets
:
[
{
id
:
'201'
,
name
:
'Website Traffic'
,
component
:
'ChartWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
0
,
y
:
0
,
data
:
{
type
:
'line'
,
labels
:
[
'Week 1'
,
'Week 2'
,
'Week 3'
],
datasets
:
[{
data
:
[
120
,
150
,
130
],
label
:
'Visitors'
}]
},
config
:
{}
},
{
id
:
'202'
,
name
:
'Conversion Rate'
,
component
:
'KpiWidgetComponent'
,
cols
:
1
,
rows
:
1
,
x
:
2
,
y
:
0
,
data
:
{
value
:
'2.5%'
,
label
:
'Conversion'
},
config
:
{}
}
]
},
{
id
:
'3'
,
name
:
'All Widgets Test Dashboard'
,
description
:
'Dashboard for testing all available widgets.'
,
widgets
:
[
{
id
:
'301'
,
name
:
'Company Info'
,
component
:
'CompanyInfoWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
0
,
y
:
0
,
data
:
{
companyName
:
'Test Company'
,
address
:
'123 Test St.'
},
config
:
{}
},
{
id
:
'302'
,
name
:
'Headcount'
,
component
:
'HeadcountWidgetComponent'
,
cols
:
1
,
rows
:
1
,
x
:
2
,
y
:
0
,
data
:
{
count
:
150
},
config
:
{}
},
{
id
:
'303'
,
name
:
'Attendance Overview'
,
component
:
'AttendanceOverviewWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
3
,
y
:
0
,
data
:
{
present
:
140
,
absent
:
10
},
config
:
{}
},
{
id
:
'304'
,
name
:
'Payroll Summary'
,
component
:
'PayrollSummaryWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
0
,
y
:
1
,
data
:
{
totalPayroll
:
100000
,
currency
:
'USD'
},
config
:
{}
},
{
id
:
'305'
,
name
:
'Employee Directory'
,
component
:
'EmployeeDirectoryWidgetComponent'
,
cols
:
2
,
rows
:
2
,
x
:
2
,
y
:
1
,
data
:
{
employees
:
[{
name
:
'Alice'
,
dept
:
'HR'
},
{
name
:
'Bob'
,
dept
:
'IT'
}]
},
config
:
{}
},
{
id
:
'306'
,
name
:
'KPI Widget'
,
component
:
'KpiWidgetComponent'
,
cols
:
1
,
rows
:
1
,
x
:
4
,
y
:
1
,
data
:
{
value
:
'95%'
,
label
:
'Success Rate'
},
config
:
{}
},
{
id
:
'307'
,
name
:
'Welcome Widget'
,
component
:
'WelcomeWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
0
,
y
:
3
,
data
:
{
message
:
'Welcome to the Dashboard!'
},
config
:
{}
},
{
id
:
'308'
,
name
:
'Chart Widget'
,
component
:
'ChartWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
2
,
y
:
3
,
data
:
{
type
:
'bar'
,
labels
:
[
'A'
,
'B'
,
'C'
],
datasets
:
[{
data
:
[
10
,
20
,
30
],
label
:
'Data'
}]
},
config
:
{}
},
{
id
:
'309'
,
name
:
'Quick Links'
,
component
:
'QuickLinksWidgetComponent'
,
cols
:
1
,
rows
:
1
,
x
:
4
,
y
:
3
,
data
:
{
links
:
[{
name
:
'Google'
,
url
:
'https://google.com'
}]
},
config
:
{}
},
{
id
:
'310'
,
name
:
'Syncfusion Datagrid'
,
component
:
'SyncfusionDatagridWidgetComponent'
,
cols
:
3
,
rows
:
2
,
x
:
0
,
y
:
4
,
data
:
{
columns
:
[
'ID'
,
'Name'
],
data
:
[{
ID
:
1
,
Name
:
'Item 1'
},
{
ID
:
2
,
Name
:
'Item 2'
}]
},
config
:
{}
},
{
id
:
'311'
,
name
:
'Syncfusion Pivot'
,
component
:
'SyncfusionPivotWidgetComponent'
,
cols
:
3
,
rows
:
2
,
x
:
3
,
y
:
4
,
data
:
{
data
:
[{
year
:
'2023'
,
sales
:
100
},
{
year
:
'2024'
,
sales
:
120
}],
rows
:
[{
name
:
'year'
}],
columns
:
[{
name
:
'sales'
}]
},
config
:
{}
},
{
id
:
'312'
,
name
:
'Syncfusion Chart'
,
component
:
'SyncfusionChartWidgetComponent'
,
cols
:
2
,
rows
:
1
,
x
:
0
,
y
:
6
,
data
:
{
chartData
:
[{
x
:
'Jan'
,
y
:
10
},
{
x
:
'Feb'
,
y
:
20
}],
primaryXAxis
:
{
valueType
:
'Category'
},
series
:
[{
type
:
'Column'
,
xName
:
'x'
,
yName
:
'y'
}]
},
config
:
{}
},
{
id
:
'313'
,
name
:
'Employee Data (Pre-configured)'
,
component
:
'NewDataTableWidget'
,
cols
:
4
,
rows
:
3
,
x
:
0
,
y
:
7
,
data
:
{},
config
:
{
title
:
'Employee List (Pre-configured)'
,
source
:
{
type
:
'url'
,
url
:
'assets/data/sample1.json'
},
data
:
[],
// This will be populated by the service
columns
:
[
{
field
:
'EmployeeID'
,
headerText
:
'ID'
,
width
:
70
},
{
field
:
'FirstName'
,
headerText
:
'First Name'
,
width
:
120
},
{
field
:
'LastName'
,
headerText
:
'Last Name'
,
width
:
120
},
{
field
:
'Position'
,
headerText
:
'Position'
,
width
:
150
},
{
field
:
'Department'
,
headerText
:
'Department'
,
width
:
150
},
]
}
}
]
}
];
@
Injectable
({
providedIn
:
'root'
})
export
class
MockDashboardService
{
constructor
()
{
}
getDashboards
():
Observable
<
DashboardModel
[]
>
{
return
of
(
MOCK_DASHBOARD_DATA
);
}
getDashboardById
(
id
:
string
):
Observable
<
DashboardModel
|
undefined
>
{
const
dashboard
=
MOCK_DASHBOARD_DATA
.
find
(
d
=>
d
.
id
===
id
);
return
of
(
dashboard
);
}
}
src/app/DPU/state/dashboard.actions.ts
deleted
100644 → 0
View file @
041bbcaf
import
{
createAction
,
props
}
from
'@ngrx/store'
;
import
{
DashboardModel
,
WidgetModel
,
DatasetModel
}
from
'../models/widgets.model'
;
export
const
loadDashboards
=
createAction
(
'[Dashboard] Load Dashboards'
);
export
const
loadDashboardsSuccess
=
createAction
(
'[Dashboard] Load Dashboards Success'
,
props
<
{
dashboards
:
DashboardModel
[]
}
>
());
export
const
loadDashboardsFailure
=
createAction
(
'[Dashboard] Load Dashboards Failure'
,
props
<
{
error
:
any
}
>
());
export
const
loadWidgets
=
createAction
(
'[Dashboard] Load Widgets'
);
export
const
loadWidgetsSuccess
=
createAction
(
'[Dashboard] Load Widgets Success'
,
props
<
{
widgets
:
WidgetModel
[]
}
>
());
export
const
loadWidgetsFailure
=
createAction
(
'[Dashboard] Load Widgets Failure'
,
props
<
{
error
:
any
}
>
());
export
const
loadDatasets
=
createAction
(
'[Dashboard] Load Datasets'
);
export
const
loadDatasetsSuccess
=
createAction
(
'[Dashboard] Load Datasets Success'
,
props
<
{
datasets
:
DatasetModel
[]
}
>
());
export
const
loadDatasetsFailure
=
createAction
(
'[Dashboard] Load Datasets Failure'
,
props
<
{
error
:
any
}
>
());
export
const
addDashboard
=
createAction
(
'[Dashboard] Add Dashboard'
,
props
<
{
dashboard
:
DashboardModel
}
>
());
export
const
addDashboardSuccess
=
createAction
(
'[Dashboard] Add Dashboard Success'
,
props
<
{
dashboard
:
DashboardModel
}
>
());
export
const
addDashboardFailure
=
createAction
(
'[Dashboard] Add Dashboard Failure'
,
props
<
{
error
:
any
}
>
());
export
const
updateDashboard
=
createAction
(
'[Dashboard] Update Dashboard'
,
props
<
{
dashboard
:
DashboardModel
}
>
());
export
const
updateDashboardSuccess
=
createAction
(
'[Dashboard] Update Dashboard Success'
,
props
<
{
dashboard
:
DashboardModel
}
>
());
export
const
updateDashboardFailure
=
createAction
(
'[Dashboard] Update Dashboard Failure'
,
props
<
{
error
:
any
}
>
());
export
const
deleteDashboard
=
createAction
(
'[Dashboard] Delete Dashboard'
,
props
<
{
id
:
string
}
>
());
export
const
deleteDashboardSuccess
=
createAction
(
'[Dashboard] Delete Dashboard Success'
,
props
<
{
id
:
string
}
>
());
export
const
deleteDashboardFailure
=
createAction
(
'[Dashboard] Delete Dashboard Failure'
,
props
<
{
error
:
any
}
>
());
src/app/DPU/state/dashboard.effects.ts
deleted
100644 → 0
View file @
041bbcaf
import
{
Injectable
}
from
'@angular/core'
;
import
{
Actions
,
createEffect
,
ofType
}
from
'@ngrx/effects'
;
import
{
of
}
from
'rxjs'
;
import
{
catchError
,
map
,
mergeMap
}
from
'rxjs/operators'
;
import
{
DashboardDataService
}
from
'../../shared/services/dashboard-data.service'
;
import
*
as
DashboardActions
from
'./dashboard.actions'
;
@
Injectable
()
export
class
DashboardEffects
{
loadDashboards$
=
createEffect
(()
=>
this
.
actions$
.
pipe
(
ofType
(
DashboardActions
.
loadDashboards
),
mergeMap
(()
=>
this
.
dashboardDataService
.
getDashboards
()
.
pipe
(
map
(
dashboards
=>
DashboardActions
.
loadDashboardsSuccess
({
dashboards
})),
catchError
(
error
=>
of
(
DashboardActions
.
loadDashboardsFailure
({
error
})))
))
));
loadWidgets$
=
createEffect
(()
=>
this
.
actions$
.
pipe
(
ofType
(
DashboardActions
.
loadWidgets
),
mergeMap
(()
=>
this
.
dashboardDataService
.
getWidgets
()
.
pipe
(
map
(
widgets
=>
DashboardActions
.
loadWidgetsSuccess
({
widgets
})),
catchError
(
error
=>
of
(
DashboardActions
.
loadWidgetsFailure
({
error
})))
))
));
loadDatasets$
=
createEffect
(()
=>
this
.
actions$
.
pipe
(
ofType
(
DashboardActions
.
loadDatasets
),
mergeMap
(()
=>
this
.
dashboardDataService
.
getDatasets
()
.
pipe
(
map
(
datasets
=>
DashboardActions
.
loadDatasetsSuccess
({
datasets
})),
catchError
(
error
=>
of
(
DashboardActions
.
loadDatasetsFailure
({
error
})))
))
));
addDashboard$
=
createEffect
(()
=>
this
.
actions$
.
pipe
(
ofType
(
DashboardActions
.
addDashboard
),
mergeMap
(
action
=>
this
.
dashboardDataService
.
addDashboard
(
action
.
dashboard
)
.
pipe
(
map
(
dashboard
=>
DashboardActions
.
addDashboardSuccess
({
dashboard
})),
catchError
(
error
=>
of
(
DashboardActions
.
addDashboardFailure
({
error
})))
))
));
updateDashboard$
=
createEffect
(()
=>
this
.
actions$
.
pipe
(
ofType
(
DashboardActions
.
updateDashboard
),
mergeMap
(
action
=>
this
.
dashboardDataService
.
updateDashboard
(
action
.
dashboard
)
.
pipe
(
map
(
dashboard
=>
DashboardActions
.
updateDashboardSuccess
({
dashboard
})),
catchError
(
error
=>
of
(
DashboardActions
.
updateDashboardFailure
({
error
})))
))
));
deleteDashboard$
=
createEffect
(()
=>
this
.
actions$
.
pipe
(
ofType
(
DashboardActions
.
deleteDashboard
),
mergeMap
(
action
=>
this
.
dashboardDataService
.
deleteDashboard
(
action
.
id
)
.
pipe
(
map
(()
=>
DashboardActions
.
deleteDashboardSuccess
({
id
:
action
.
id
})),
catchError
(
error
=>
of
(
DashboardActions
.
deleteDashboardFailure
({
error
})))
))
));
constructor
(
private
actions$
:
Actions
,
private
dashboardDataService
:
DashboardDataService
)
{}
}
src/app/DPU/state/dashboard.reducer.ts
deleted
100644 → 0
View file @
041bbcaf
import
{
createReducer
,
on
}
from
'@ngrx/store'
;
import
{
DashboardModel
,
WidgetModel
,
DatasetModel
}
from
'../models/widgets.model'
;
import
*
as
DashboardActions
from
'./dashboard.actions'
;
export
interface
DashboardState
{
dashboards
:
DashboardModel
[];
widgets
:
WidgetModel
[];
datasets
:
DatasetModel
[];
error
:
any
;
}
export
const
initialState
:
DashboardState
=
{
dashboards
:
[],
widgets
:
[],
datasets
:
[],
error
:
null
,
};
export
const
dashboardReducer
=
createReducer
(
initialState
,
on
(
DashboardActions
.
loadDashboardsSuccess
,
(
state
,
{
dashboards
})
=>
({
...
state
,
dashboards
})),
on
(
DashboardActions
.
loadDashboardsFailure
,
(
state
,
{
error
})
=>
({
...
state
,
error
})),
on
(
DashboardActions
.
loadWidgetsSuccess
,
(
state
,
{
widgets
})
=>
({
...
state
,
widgets
})),
on
(
DashboardActions
.
loadWidgetsFailure
,
(
state
,
{
error
})
=>
({
...
state
,
error
})),
on
(
DashboardActions
.
loadDatasetsSuccess
,
(
state
,
{
datasets
})
=>
({
...
state
,
datasets
})),
on
(
DashboardActions
.
loadDatasetsFailure
,
(
state
,
{
error
})
=>
({
...
state
,
error
})),
on
(
DashboardActions
.
addDashboardSuccess
,
(
state
,
{
dashboard
})
=>
({
...
state
,
dashboards
:
[...
state
.
dashboards
,
dashboard
]
})),
on
(
DashboardActions
.
addDashboardFailure
,
(
state
,
{
error
})
=>
({
...
state
,
error
})),
on
(
DashboardActions
.
updateDashboardSuccess
,
(
state
,
{
dashboard
})
=>
({
...
state
,
dashboards
:
state
.
dashboards
.
map
(
d
=>
d
.
id
===
dashboard
.
id
?
dashboard
:
d
)
})),
on
(
DashboardActions
.
updateDashboardFailure
,
(
state
,
{
error
})
=>
({
...
state
,
error
})),
on
(
DashboardActions
.
deleteDashboardSuccess
,
(
state
,
{
id
})
=>
({
...
state
,
dashboards
:
state
.
dashboards
.
filter
(
d
=>
d
.
id
!==
id
)
})),
on
(
DashboardActions
.
deleteDashboardFailure
,
(
state
,
{
error
})
=>
({
...
state
,
error
}))
);
src/app/DPU/state/dashboard.selectors.ts
deleted
100644 → 0
View file @
041bbcaf
import
{
createFeatureSelector
,
createSelector
}
from
'@ngrx/store'
;
import
{
DashboardState
}
from
'./dashboard.reducer'
;
import
{
DashboardModel
}
from
'../models/widgets.model'
;
export
const
selectDashboardState
=
createFeatureSelector
<
DashboardState
>
(
'dashboard'
);
export
const
selectAllDashboards
=
createSelector
(
selectDashboardState
,
(
state
:
DashboardState
)
=>
state
.
dashboards
);
export
const
selectAllWidgets
=
createSelector
(
selectDashboardState
,
(
state
:
DashboardState
)
=>
state
.
widgets
);
export
const
selectAllDatasets
=
createSelector
(
selectDashboardState
,
(
state
:
DashboardState
)
=>
state
.
datasets
);
export
const
selectDashboardById
=
(
id
:
string
)
=>
createSelector
(
selectAllDashboards
,
(
dashboards
:
DashboardModel
[])
=>
dashboards
.
find
(
d
=>
d
.
id
===
id
)
);
export
const
selectError
=
createSelector
(
selectDashboardState
,
(
state
:
DashboardState
)
=>
state
.
error
);
src/app/DPU/widget-management/widget-form.component.ts
View file @
c9833196
...
...
@@ -5,7 +5,7 @@ import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import
{
CommonModule
}
from
'@angular/common'
;
import
{
NgComponentOutlet
}
from
'@angular/common'
;
import
{
Store
}
from
'@ngrx/store'
;
import
*
as
DashboardActions
from
'../state/dashboard.actions'
;
//
import * as DashboardActions from '../state/dashboard.actions';
import
{
WidgetModel
}
from
'../models/widgets.model'
;
// Import all the widget components
...
...
@@ -75,7 +75,7 @@ export class WidgetFormComponent implements OnInit {
if
(
this
.
widgetId
&&
this
.
widgetId
!==
'new'
)
{
this
.
isNew
=
false
;
this
.
store
.
dispatch
(
DashboardActions
.
loadWidgets
());
//
this.store.dispatch(DashboardActions.loadWidgets());
// this.store.select(DashboardSelectors.selectWidgetById(this.widgetId)).subscribe(widget => {
// if (widget) {
// this.widgetForm.patchValue(widget);
...
...
src/app/DPU/widget-management/widget-list.component.ts
View file @
c9833196
...
...
@@ -5,8 +5,6 @@ import { Observable } from 'rxjs';
import
{
CommonModule
,
TitleCasePipe
}
from
'@angular/common'
;
import
{
NgComponentOutlet
}
from
'@angular/common'
;
import
{
Store
}
from
'@ngrx/store'
;
import
*
as
DashboardActions
from
'../state/dashboard.actions'
;
import
*
as
DashboardSelectors
from
'../state/dashboard.selectors'
;
import
{
WidgetModel
}
from
'../models/widgets.model'
;
// Import all the widget components
...
...
@@ -56,8 +54,8 @@ export class WidgetListComponent implements OnInit {
)
{
}
ngOnInit
():
void
{
this
.
store
.
dispatch
(
DashboardActions
.
loadWidgets
());
this
.
widgets$
=
this
.
store
.
select
(
DashboardSelectors
.
selectAllWidgets
);
//
this.store.dispatch(DashboardActions.loadWidgets());
//
this.widgets$ = this.store.select(DashboardSelectors.selectAllWidgets);
}
getComponentType
(
componentName
:
string
):
Type
<
any
>
|
null
{
...
...
src/app/app.config.ts
View file @
c9833196
...
...
@@ -25,8 +25,6 @@ import { DashboardDataService } from './shared/services/dashboard-data.service';
import
{
provideStore
,
provideState
}
from
'@ngrx/store'
;
import
{
provideEffects
}
from
'@ngrx/effects'
;
import
{
provideStoreDevtools
}
from
'@ngrx/store-devtools'
;
import
{
dashboardReducer
}
from
'./DPU/state/dashboard.reducer'
;
import
{
DashboardEffects
}
from
'./DPU/state/dashboard.effects'
;
export
function
HttpLoaderFactory
(
http
:
HttpClient
)
{
return
new
TranslateHttpLoader
(
http
,
"./assets/i18n/"
,
".json"
);
...
...
@@ -84,8 +82,6 @@ export const appConfig: ApplicationConfig = {
httpInterceptorProviders
,
DashboardDataService
,
provideStore
(),
provideState
({
name
:
'dashboard'
,
reducer
:
dashboardReducer
}),
provideEffects
([
DashboardEffects
]),
provideStoreDevtools
({
maxAge
:
25
,
logOnly
:
environment
.
production
})
]
};
...
...
src/app/shared/services/dashboard-data.service.ts
View file @
c9833196
...
...
@@ -8,93 +8,32 @@ import { DashboardModel, WidgetModel, DatasetModel } from '../../DPU/models/widg
})
export
class
DashboardDataService
{
private
mockDatasets
:
DatasetModel
[]
=
[
new
DatasetModel
({
id
:
'ds-1'
,
name
:
'Sales Data'
,
url
:
'/api/data/sales'
}),
new
DatasetModel
({
id
:
'ds-2'
,
name
:
'HR Data'
,
url
:
'/api/data/hr'
}),
new
DatasetModel
({
id
:
'ds-3'
,
name
:
'Marketing Data'
,
url
:
'/api/data/marketing'
})
];
private
mockData
:
{
[
key
:
string
]:
any
[]
}
=
{
'ds-1'
:
[
{
OrderID
:
10248
,
CustomerID
:
'VINET'
,
EmployeeID
:
5
,
OrderDate
:
new
Date
(
8364186
e5
),
ShipName
:
'Vins et alcools Chevalier'
},
{
OrderID
:
10249
,
CustomerID
:
'TOMSP'
,
EmployeeID
:
6
,
OrderDate
:
new
Date
(
836505
e6
),
ShipName
:
'Toms Spezialitäten'
},
{
OrderID
:
10250
,
CustomerID
:
'HANAR'
,
EmployeeID
:
4
,
OrderDate
:
new
Date
(
8367642
e5
),
ShipName
:
'Hanari Carnes'
},
],
'ds-2'
:
[
{
Name
:
'John Doe'
,
Title
:
'CEO'
,
Country
:
'USA'
},
{
Name
:
'Jane Smith'
,
Title
:
'CFO'
,
Country
:
'USA'
},
{
Name
:
'Peter Jones'
,
Title
:
'CTO'
,
Country
:
'UK'
},
]
};
private
mockDashboards
:
DashboardModel
[]
=
[
new
DashboardModel
({
id
:
'dash-1'
,
name
:
'Sales Dashboard'
,
datasetId
:
'ds-1'
,
widgets
:
[
new
WidgetModel
({
id
:
'widget-1'
,
name
:
'Welcome Message'
,
component
:
'WelcomeWidgetComponent'
,
cols
:
2
,
rows
:
1
,
y
:
0
,
x
:
0
,
data
:
{
userName
:
'Jane Doe'
}
}),
new
WidgetModel
({
id
:
'widget-2'
,
name
:
'Sales Data Grid'
,
component
:
'SyncfusionDatagridWidgetComponent'
,
cols
:
4
,
rows
:
3
,
y
:
0
,
x
:
2
,
data
:
{}
})
]
}),
new
DashboardModel
({
id
:
'dash-2'
,
name
:
'HR Dashboard'
,
datasetId
:
'ds-2'
,
widgets
:
[
new
WidgetModel
({
id
:
'widget-1'
,
name
:
'Welcome Message'
,
component
:
'WelcomeWidgetComponent'
,
cols
:
2
,
rows
:
1
,
y
:
0
,
x
:
0
,
data
:
{
userName
:
'John Smith'
}
})
]
})
];
private
mockWidgets
:
WidgetModel
[]
=
[
new
WidgetModel
({
id
:
'widget-1'
,
name
:
'Welcome Message'
,
component
:
'WelcomeWidgetComponent'
,
cols
:
2
,
rows
:
1
,
y
:
0
,
x
:
0
,
data
:
{
userName
:
'Default User'
}
}),
new
WidgetModel
({
id
:
'widget-2'
,
name
:
'Sales Data Grid'
,
component
:
'SyncfusionDatagridWidgetComponent'
,
cols
:
4
,
rows
:
3
,
y
:
0
,
x
:
2
,
data
:
{}
}),
new
WidgetModel
({
id
:
'widget-3'
,
name
:
'Chart Widget'
,
component
:
'ChartWidgetComponent'
,
cols
:
3
,
rows
:
2
,
y
:
0
,
x
:
0
,
data
:
{}
})
];
constructor
()
{
}
// Dashboard methods
getDashboards
():
Observable
<
DashboardModel
[]
>
{
return
of
(
this
.
mockDashboards
).
pipe
(
catchError
(
this
.
handleError
));
}
getDashboardById
(
id
:
string
):
Observable
<
DashboardModel
|
undefined
>
{
return
of
(
this
.
mockDashboards
.
find
(
d
=>
d
.
id
===
id
)).
pipe
(
catchError
(
this
.
handleError
));
}
addDashboard
(
dashboard
:
DashboardModel
):
Observable
<
DashboardModel
>
{
this
.
mockDashboards
.
push
(
dashboard
);
return
of
(
dashboard
).
pipe
(
catchError
(
this
.
handleError
));
}
// // Dashboard methods
// getDashboards(): Observable<DashboardModel[]> {
// return of(this.mockDashboards).pipe(catchError(this.handleError));
// }
updateDashboard
(
dashboard
:
DashboardModel
):
Observable
<
DashboardModel
>
{
const
index
=
this
.
mockDashboards
.
findIndex
(
d
=>
d
.
id
===
dashboard
.
id
);
if
(
index
!==
-
1
)
{
this
.
mockDashboards
[
index
]
=
dashboard
;
}
return
of
(
dashboard
).
pipe
(
catchError
(
this
.
handleError
));
}
// addDashboard(dashboard: DashboardModel): Observable<DashboardModel> {
// this.mockDashboards.push(dashboard);
// return of(dashboard).pipe(catchError(this.handleError));
// }
deleteDashboard
(
id
:
string
):
Observable
<
void
>
{
this
.
mockDashboards
=
this
.
mockDashboards
.
filter
(
d
=>
d
.
id
!==
id
);
return
of
(
undefined
).
pipe
(
catchError
(
this
.
handleError
));
}
// Widget methods
getWidgets
():
Observable
<
WidgetModel
[]
>
{
return
of
(
this
.
mockWidgets
).
pipe
(
catchError
(
this
.
handleError
));
}
// Dataset methods
getDatasets
():
Observable
<
DatasetModel
[]
>
{
return
of
(
this
.
mockDatasets
).
pipe
(
catchError
(
this
.
handleError
));
}
getDatasetById
(
id
:
string
):
Observable
<
DatasetModel
|
undefined
>
{
return
of
(
this
.
mockDatasets
.
find
(
ds
=>
ds
.
id
===
id
)).
pipe
(
catchError
(
this
.
handleError
));
}
//
getWidgets(): Observable<WidgetModel[]> {
//
return of(this.mockWidgets).pipe(catchError(this.handleError));
//
}
//
//
Dataset methods
//
getDatasets(): Observable<DatasetModel[]> {
//
return of(this.mockDatasets).pipe(catchError(this.handleError));
//
}
//
getDatasetById(id: string): Observable<DatasetModel | undefined> {
//
return of(this.mockDatasets.find(ds => ds.id === id)).pipe(catchError(this.handleError));
//
}
private
handleError
(
error
:
any
)
{
console
.
error
(
error
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment