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
76d68cec
Commit
76d68cec
authored
Aug 28, 2025
by
Ooh-Ao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard
parent
ef92555b
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
235 additions
and
35 deletions
+235
-35
dashboard-management.component.html
.../dashboard-management/dashboard-management.component.html
+201
-34
dashboard-management.component.ts
...PU/dashboard-management/dashboard-management.component.ts
+34
-1
No files found.
src/app/DPU/dashboard-management/dashboard-management.component.html
View file @
76d68cec
<div
class=
"dashboard-container"
>
<div
class=
"dashboard-container"
>
<!-- Widget Sidebar -->
<!-- Widget Sidebar -->
<div
class=
"widget-sidebar"
>
<div
class=
"widget-sidebar"
>
...
@@ -8,27 +5,67 @@
...
@@ -8,27 +5,67 @@
<!-- Widget Search -->
<!-- Widget Search -->
<div
class=
"relative mb-4"
>
<div
class=
"relative mb-4"
>
<input
type=
"text"
[(
ngModel
)]="
widgetSearchTerm
"
(
input
)="
filterWidgets
()"
placeholder=
"Search widgets..."
<input
class=
"w-full p-2 pl-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"
>
type=
"text"
<svg
class=
"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
xmlns=
"http://www.w3.org/2000/svg"
>
[(
ngModel
)]="
widgetSearchTerm
"
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
></path>
(
input
)="
filterWidgets
()"
placeholder=
"Search widgets..."
class=
"w-full p-2 pl-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"
/>
<svg
class=
"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
></path>
</svg>
</svg>
<button
*
ngIf=
"widgetSearchTerm"
(
click
)="
clearSearch
()"
class=
"absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-700"
>
<button
<svg
class=
"h-5 w-5"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
xmlns=
"http://www.w3.org/2000/svg"
>
*
ngIf=
"widgetSearchTerm"
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M6 18L18 6M6 6l12 12"
></path>
(
click
)="
clearSearch
()"
class=
"absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-700"
>
<svg
class=
"h-5 w-5"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M6 18L18 6M6 6l12 12"
></path>
</svg>
</svg>
</button>
</button>
</div>
</div>
<!-- Widget List -->
<!-- Widget List -->
<div
class=
"widget-list space-y-2"
>
<div
class=
"widget-list space-y-2"
>
<div
*
ngFor=
"let widget of filteredAvailableWidgets"
<div
class=
"widget-item"
*
ngFor=
"let widget of filteredAvailableWidgets"
(
click
)="
addWidgetToDashboard
(
widget
)"
>
class=
"widget-item"
(
click
)="
addWidgetToDashboard
(
widget
)"
>
<p
class=
"font-semibold text-gray-700"
>
{{ widget.name }}
</p>
<p
class=
"font-semibold text-gray-700"
>
{{ widget.name }}
</p>
<p
class=
"text-xs text-gray-500"
>
Size: {{widget.cols}}x{{widget.rows}}
</p>
<p
class=
"text-xs text-gray-500"
>
Size: {{ widget.cols }}x{{ widget.rows }}
</p>
</div>
</div>
<p
*
ngIf=
"filteredAvailableWidgets.length === 0"
class=
"text-gray-500 text-center mt-4"
>
No widgets found.
</p>
<p
*
ngIf=
"filteredAvailableWidgets.length === 0"
class=
"text-gray-500 text-center mt-4"
>
No widgets found.
</p>
</div>
</div>
</div>
</div>
...
@@ -38,44 +75,69 @@
...
@@ -38,44 +75,69 @@
<div
class=
"flex items-center space-x-4"
>
<div
class=
"flex items-center space-x-4"
>
<h1
class=
"text-xl font-bold text-gray-700"
>
Dashboard:
</h1>
<h1
class=
"text-xl font-bold text-gray-700"
>
Dashboard:
</h1>
<!-- Dashboard Selector -->
<!-- Dashboard Selector -->
<select
[(
ngModel
)]="
selectedDashboardId
"
(
change
)="
loadSelectedDashboard
()"
<select
class=
"p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white"
>
[(
ngModel
)]="
selectedDashboardId
"
<option
*
ngFor=
"let dash of userDashboards"
[
value
]="
dash
.
id
"
>
{{ dash.name }}
</option>
(
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.name }}
</option>
</select>
</select>
<app-dataset-picker
(
datasetSelected
)="
onDatasetSelected
($
event
)"
></app-dataset-picker>
<app-dataset-picker
(
datasetSelected
)="
onDatasetSelected
($
event
)"
></app-dataset-picker>
<div
*
ngIf=
"dashboardData"
class=
"relative flex items-center"
>
<div
*
ngIf=
"dashboardData"
class=
"relative flex items-center"
>
<input
type=
"text"
[(
ngModel
)]="
dashboardData
.
name
"
(
blur
)="
saveDashboardName
()"
<input
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"
>
type=
"text"
<button
(
click
)="
saveDashboardName
()"
[(
ngModel
)]="
dashboardData
.
name
"
class=
"ml-2 text-emerald-500 hover:text-emerald-700 focus:outline-none"
>
(
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"
/>
<button
(
click
)="
saveDashboardName
()"
class=
"ml-2 text-emerald-500 hover:text-emerald-700 focus:outline-none"
>
<i
class=
"bi bi-check-circle-fill text-2xl"
></i>
<i
class=
"bi bi-check-circle-fill text-2xl"
></i>
</button>
</button>
</div>
</div>
<button
(
click
)="
createNewDashboard
()"
<button
class=
"ti-btn ti-btn-primary-full flex items-center gap-2"
>
(
click
)="
createNewDashboard
()"
class=
"ti-btn ti-btn-primary-full flex items-center gap-2"
>
<i
class=
"bi bi-plus-circle-fill"
></i>
New Dashboard
<i
class=
"bi bi-plus-circle-fill"
></i>
New Dashboard
</button>
</button>
<button
(
click
)="
addDataDrivenWidget
()"
<button
class=
"ti-btn ti-btn-info-full flex items-center gap-2"
>
(
click
)="
addDataDrivenWidget
()"
class=
"ti-btn ti-btn-info-full flex items-center gap-2"
>
<i
class=
"bi bi-plus-circle-fill"
></i>
Add Data-Driven Widget (Test)
<i
class=
"bi bi-plus-circle-fill"
></i>
Add Data-Driven Widget (Test)
</button>
</button>
<button
*
ngIf=
"selectedDashboardId"
(
click
)="
deleteDashboard
()"
<button
class=
"ti-btn ti-btn-danger-full flex items-center gap-2"
>
*
ngIf=
"selectedDashboardId"
(
click
)="
deleteDashboard
()"
class=
"ti-btn ti-btn-danger-full flex items-center gap-2"
>
<i
class=
"bi bi-trash-fill"
></i>
Delete Dashboard
<i
class=
"bi bi-trash-fill"
></i>
Delete Dashboard
</button>
</button>
</div>
</div>
<button
(
click
)="
saveLayout
()"
<button
class=
"ti-btn ti-btn-success-full flex items-center gap-2"
>
(
click
)="
saveLayout
()"
class=
"ti-btn ti-btn-success-full flex items-center gap-2"
>
<i
class=
"bi bi-check-circle-fill"
></i>
Save Layout
<i
class=
"bi bi-check-circle-fill"
></i>
Save Layout
</button>
</button>
<button
*
ngIf=
"selectedDashboardId"
[
routerLink
]="['/
dpu
/
dashboard-viewer
',
selectedDashboardId
]"
<button
class=
"ti-btn ti-btn-secondary-full flex items-center gap-2 ml-2"
>
*
ngIf=
"selectedDashboardId"
[
routerLink
]="['/
dpu
/
dashboard-viewer
',
selectedDashboardId
]"
class=
"ti-btn ti-btn-secondary-full flex items-center gap-2 ml-2"
>
<i
class=
"bi bi-eye-fill"
></i>
View Dashboard
<i
class=
"bi bi-eye-fill"
></i>
View Dashboard
</button>
</button>
</div>
</div>
<div
class=
"dashboard-content"
>
<div
class=
"dashboard-content"
>
<ejs-dashboardlayout
id=
'dashboard_management'
#
managementLayout
[
cellSpacing
]="
cellSpacing
"
[
panels
]="
panels
"
[
columns
]="
6
"
[
allowResizing
]="
true
"
[
allowDragging
]="
true
"
>
<
!-- <
ejs-dashboardlayout id='dashboard_management' #managementLayout [cellSpacing]="cellSpacing" [panels]="panels" [columns]="6" [allowResizing]="true" [allowDragging]="true">
<e-panels>
<e-panels>
<e-panel *ngFor="let panel of panels" [row]="panel.row" [col]="panel.col" [sizeX]="panel.sizeX" [sizeY]="panel.sizeY" [id]="panel.id || ''">
<e-panel *ngFor="let panel of panels" [row]="panel.row" [col]="panel.col" [sizeX]="panel.sizeX" [sizeY]="panel.sizeY" [id]="panel.id || ''">
<ng-template [e-header]>
<ng-template [e-header]>
...
@@ -91,6 +153,111 @@
...
@@ -91,6 +153,111 @@
</ng-template>
</ng-template>
</e-panel>
</e-panel>
</e-panels>
</e-panels>
</ejs-dashboardlayout> -->
<ejs-dashboardlayout
[
columns
]="
6
"
#
editLayout
[
cellSpacing
]="
cellSpacing
"
>
<e-panels>
<e-panel
*
ngFor=
"let panel of panels"
[
id
]="
panel
.
id
"
[
sizeX
]="
panel
.
sizeX
"
[
sizeY
]="
panel
.
sizeY
"
[
row
]="
panel
.
row
"
[
col
]="
panel
.
col
"
>
<ng-template
#
header
>
<div>
{{ panel.header }}
</div>
</ng-template>
<ng-template
#
content
>
<ng-container
[
ngComponentOutlet
]="
panel
.
componentType
"
[
ngComponentOutletInputs
]="
panel
.
componentInputs
"
></ng-container>
</ng-template>
</e-panel>
<!-- <e-panel [sizeX]="3" [sizeY]="2" [row]="0" [col]="3">
<ng-template #header>
<div>Last year Sales Comparison</div>
</ng-template>
<ng-template #content>
<div id="line">
<ejs-chart
id="lineChart"
height="162px"
[primaryXAxis]="primaryXAxis"
>
<e-series-collection>
<e-series
[dataSource]="lineData"
xName="x"
yName="y"
type="Line"
>
</e-series>
</e-series-collection>
</ejs-chart>
</div>
</ng-template>
</e-panel>
<e-panel [sizeX]="3" [sizeY]="2" [row]="2" [col]="0">
<ng-template #header>
<div>Sales increase percentage 1</div>
</ng-template>
<ng-template #content>
<div id="pie">
<ejs-accumulationchart
id="pieChart"
height="162px"
[legendSettings]="legendSettings"
[tooltip]="tooltip"
>
<e-accumulation-series-collection>
<e-accumulation-series
[dataSource]="piechart"
xName="x"
yName="y"
innerRadius="20%"
name="Browser"
[dataLabel]="datalabel"
>
</e-accumulation-series>
</e-accumulation-series-collection>
</ejs-accumulationchart>
</div>
</ng-template>
</e-panel>
<e-panel [sizeX]="3" [sizeY]="2" [row]="2" [col]="3">
<ng-template #header>
<div>Sales increase percentage 2</div>
</ng-template>
<ng-template #content>
<div id="pie1">
<ejs-accumulationchart
id="pieChart1"
[enableAnimation]="false"
height="162px"
[tooltip]="tooltip"
[legendSettings]="legendSettings"
>
<e-accumulation-series-collection>
<e-accumulation-series
[dataSource]="piechart1"
xName="x"
yName="y"
radius="70%"
name="Browser"
[dataLabel]="datalabel"
>
</e-accumulation-series>
</e-accumulation-series-collection>
</ejs-accumulationchart>
</div>
</ng-template>
</e-panel> -->
</e-panels>
</ejs-dashboardlayout>
</ejs-dashboardlayout>
</div>
</div>
</div>
</div>
...
...
src/app/DPU/dashboard-management/dashboard-management.component.ts
View file @
76d68cec
...
@@ -29,6 +29,7 @@ import { SyncfusionPivotWidgetComponent } from '../widgets/syncfusion-pivot-widg
...
@@ -29,6 +29,7 @@ import { SyncfusionPivotWidgetComponent } from '../widgets/syncfusion-pivot-widg
import
{
SyncfusionChartWidgetComponent
}
from
'../widgets/syncfusion-chart-widget/syncfusion-chart-widget.component'
;
import
{
SyncfusionChartWidgetComponent
}
from
'../widgets/syncfusion-chart-widget/syncfusion-chart-widget.component'
;
import
{
DatasetPickerComponent
}
from
'./dataset-picker.component'
;
import
{
DatasetPickerComponent
}
from
'./dataset-picker.component'
;
import
{
DataTableWidgetComponent
}
from
'../widgets/dynamic-widgets/data-table-widget.component'
;
// Import new widget
import
{
DataTableWidgetComponent
}
from
'../widgets/dynamic-widgets/data-table-widget.component'
;
// Import new widget
import
{
AccumulationChartAllModule
,
ChartAllModule
}
from
'@syncfusion/ej2-angular-charts'
;
@
Component
({
@
Component
({
selector
:
'app-dashboard-management'
,
selector
:
'app-dashboard-management'
,
...
@@ -53,13 +54,45 @@ import { DataTableWidgetComponent } from '../widgets/dynamic-widgets/data-table-
...
@@ -53,13 +54,45 @@ import { DataTableWidgetComponent } from '../widgets/dynamic-widgets/data-table-
SyncfusionChartWidgetComponent
,
SyncfusionChartWidgetComponent
,
DatasetPickerComponent
,
DatasetPickerComponent
,
DataTableWidgetComponent
,
// Add new widget to imports
DataTableWidgetComponent
,
// Add new widget to imports
DashboardLayoutModule
// Add Syncfusion DashboardLayoutModule
DashboardLayoutModule
,
ChartAllModule
,
AccumulationChartAllModule
// Add Syncfusion DashboardLayoutModule
],
],
templateUrl
:
'./dashboard-management.component.html'
,
templateUrl
:
'./dashboard-management.component.html'
,
styleUrls
:
[
'./dashboard-management.component.scss'
],
styleUrls
:
[
'./dashboard-management.component.scss'
],
})
})
export
class
DashboardManagementComponent
implements
OnInit
{
export
class
DashboardManagementComponent
implements
OnInit
{
public
chartData
:
Object
[]
=
[
{
month
:
'Jan'
,
sales
:
35
},
{
month
:
'Feb'
,
sales
:
28
},
{
month
:
'Mar'
,
sales
:
34
},
{
month
:
'Apr'
,
sales
:
32
},
{
month
:
'May'
,
sales
:
40
},
{
month
:
'Jun'
,
sales
:
32
},
{
month
:
'Jul'
,
sales
:
35
},
{
month
:
'Aug'
,
sales
:
55
},
{
month
:
'Sep'
,
sales
:
38
},
{
month
:
'Oct'
,
sales
:
30
},
{
month
:
'Nov'
,
sales
:
25
},
{
month
:
'Dec'
,
sales
:
32
}
];
public
primaryXAxis
:
Object
=
{
valueType
:
'Category'
}
public
lineData
:
any
[]
=
[
{
x
:
2013
,
y
:
28
},
{
x
:
2014
,
y
:
25
},
{
x
:
2015
,
y
:
26
},
{
x
:
2016
,
y
:
27
},
{
x
:
2017
,
y
:
32
},
{
x
:
2018
,
y
:
35
}
];
public
piechart
:
any
[]
=
[{
x
:
'TypeScript'
,
y
:
13
,
text
:
'TS 13%'
},
{
x
:
'React'
,
y
:
12.5
,
text
:
'Reat 12.5%'
},
{
x
:
'MVC'
,
y
:
12
,
text
:
'MVC 12%'
},
{
x
:
'Core'
,
y
:
12.5
,
text
:
'Core 12.5%'
},
{
x
:
'Vue'
,
y
:
10
,
text
:
'Vue 10%'
},
{
x
:
'Angular'
,
y
:
40
,
text
:
'Angular 40%'
}];
public
piechart1
:
any
[]
=
[
{
'x'
:
'Chrome'
,
y
:
37
,
text
:
'37%'
},
{
'x'
:
'UC Browser'
,
y
:
17
,
text
:
'17%'
},
{
'x'
:
'iPhone'
,
y
:
19
,
text
:
'19%'
},
{
'x'
:
'Others'
,
y
:
4
,
text
:
'4%'
},
{
'x'
:
'Opera'
,
y
:
11
,
text
:
'11%'
},
{
'x'
:
'Android'
,
y
:
12
,
text
:
'12%'
}
];
public
legendSettings
:
Object
=
{
visible
:
false
};
tooltip
:
any
;
datalabel
:
any
;
public
panels
:
(
PanelModel
&
{
componentType
:
Type
<
any
>
,
componentInputs
?:
{
[
key
:
string
]:
any
}
})[]
=
[];
public
panels
:
(
PanelModel
&
{
componentType
:
Type
<
any
>
,
componentInputs
?:
{
[
key
:
string
]:
any
}
})[]
=
[];
public
cellSpacing
:
number
[]
=
[
10
,
10
];
public
cellSpacing
:
number
[]
=
[
10
,
10
];
...
...
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