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
1a7c08a5
Commit
1a7c08a5
authored
Sep 01, 2025
by
Ooh-Ao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard
parent
3ab688d0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
434 additions
and
431 deletions
+434
-431
dashboard-management.component.html
.../dashboard-management/dashboard-management.component.html
+1
-1
dashboard-management.component.ts
...ge/dashboard-management/dashboard-management.component.ts
+401
-401
dashboard-viewer.component.ts
...tal-manage/dashboard-viewer/dashboard-viewer.component.ts
+2
-2
widgets.model.ts
src/app/portal-manage/models/widgets.model.ts
+19
-12
widgets.service.ts
src/app/portal-manage/services/widgets.service.ts
+9
-13
widget-list.component.html
...ortal-manage/widget-management/widget-list.component.html
+2
-2
No files found.
src/app/portal-manage/dashboard-management/dashboard-management.component.html
View file @
1a7c08a5
...
@@ -55,7 +55,7 @@
...
@@ -55,7 +55,7 @@
(
click
)="
addWidgetToDashboard
(
widget
)"
(
click
)="
addWidgetToDashboard
(
widget
)"
class=
"widget-item p-3 rounded-lg hover:bg-gray-100 cursor-pointer transition-colors duration-200"
class=
"widget-item p-3 rounded-lg hover:bg-gray-100 cursor-pointer transition-colors duration-200"
>
>
<p
class=
"font-semibold text-gray-700"
>
{{ widget.
n
ame }}
</p>
<p
class=
"font-semibold text-gray-700"
>
{{ widget.
thN
ame }}
</p>
<p
class=
"text-xs text-gray-500"
>
<p
class=
"text-xs text-gray-500"
>
Size: {{ widget.cols }}x{{ widget.rows }}
Size: {{ widget.cols }}x{{ widget.rows }}
</p>
</p>
...
...
src/app/portal-manage/dashboard-management/dashboard-management.component.ts
View file @
1a7c08a5
...
@@ -114,397 +114,397 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -114,397 +114,397 @@ export class DashboardManagementComponent implements OnInit {
public
userDashboards
:
DashboardModel
[]
=
[];
public
userDashboards
:
DashboardModel
[]
=
[];
public
selectedDashboardId
:
DashboardModel
public
selectedDashboardId
:
DashboardModel
private
localWidgets
:
WidgetModel
[]
=
[
//
private localWidgets: WidgetModel[] = [
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-sync-pivot'
,
//
id: 'local-sync-pivot',
name
:
'Syncfusion Pivot Table (Local)'
,
//
name: 'Syncfusion Pivot Table (Local)',
component
:
'SyncfusionPivotWidgetComponent'
,
//
component: 'SyncfusionPivotWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
3
,
//
rows: 3,
config
:
{
//
config: {
title
:
'Employee Salary Pivot'
,
//
title: 'Employee Salary Pivot',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
rows
:
[{
name
:
'department'
}],
//
rows: [{ name: 'department' }],
columns
:
[{
name
:
'gender'
}],
//
columns: [{ name: 'gender' }],
values
:
[{
name
:
'salary'
,
caption
:
'Total Salary'
}],
//
values: [{ name: 'salary', caption: 'Total Salary' }],
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-sync-grid'
,
//
id: 'local-sync-grid',
name
:
'Syncfusion Data Grid (Local)'
,
//
name: 'Syncfusion Data Grid (Local)',
component
:
'SyncfusionDatagridWidgetComponent'
,
//
component: 'SyncfusionDatagridWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'All Employee Data'
,
//
title: 'All Employee Data',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
columns
:
[
//
columns: [
{
field
:
'id'
,
headerText
:
'ID'
,
width
:
70
},
//
{ field: 'id', headerText: 'ID', width: 70 },
{
field
:
'name'
,
headerText
:
'Name'
,
width
:
120
},
//
{ field: 'name', headerText: 'Name', width: 120 },
{
field
:
'department'
,
headerText
:
'Department'
,
width
:
120
},
//
{ field: 'department', headerText: 'Department', width: 120 },
{
field
:
'salary'
,
headerText
:
'Salary'
,
width
:
100
},
//
{ field: 'salary', headerText: 'Salary', width: 100 },
{
field
:
'performanceScore'
,
headerText
:
'Performance'
,
width
:
120
},
//
{ field: 'performanceScore', headerText: 'Performance', width: 120 },
]
//
]
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-sync-chart'
,
//
id: 'local-sync-chart',
name
:
'Syncfusion Chart (Local)'
,
//
name: 'Syncfusion Chart (Local)',
component
:
'SyncfusionChartWidgetComponent'
,
//
component: 'SyncfusionChartWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Performance'
,
//
title: 'Employee Performance',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'name'
,
//
xField: 'name',
yField
:
'performanceScore'
,
//
yField: 'performanceScore',
xAxisTitle
:
'Employee'
,
//
xAxisTitle: 'Employee',
yAxisTitle
:
'Score'
,
//
yAxisTitle: 'Score',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-area-chart'
,
//
id: 'local-area-chart',
name
:
'Area Chart (Local)'
,
//
name: 'Area Chart (Local)',
component
:
'AreaChartWidgetComponent'
,
//
component: 'AreaChartWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Monthly Sales by Employee'
,
//
title: 'Monthly Sales by Employee',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'name'
,
//
xField: 'name',
yField
:
'salesAmount'
,
//
yField: 'salesAmount',
xAxisTitle
:
'Employee'
,
//
xAxisTitle: 'Employee',
yAxisTitle
:
'Sales Amount'
,
//
yAxisTitle: 'Sales Amount',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-bar-chart'
,
//
id: 'local-bar-chart',
name
:
'Bar Chart (Local)'
,
//
name: 'Bar Chart (Local)',
component
:
'BarChartWidgetComponent'
,
//
component: 'BarChartWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Performance Score'
,
//
title: 'Employee Performance Score',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'name'
,
//
xField: 'name',
yField
:
'performanceScore'
,
//
yField: 'performanceScore',
xAxisTitle
:
'Employee'
,
//
xAxisTitle: 'Employee',
yAxisTitle
:
'Performance Score'
,
//
yAxisTitle: 'Performance Score',
type
:
'Column'
//
type: 'Column'
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-pie-chart'
,
//
id: 'local-pie-chart',
name
:
'Pie Chart (Local)'
,
//
name: 'Pie Chart (Local)',
component
:
'PieChartWidgetComponent'
,
//
component: 'PieChartWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Gender Distribution'
,
//
title: 'Gender Distribution',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'gender'
,
//
xField: 'gender',
yField
:
'id'
,
//
yField: 'id',
aggregation
:
'count'
,
//
aggregation: 'count',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-scatter-bubble-chart'
,
//
id: 'local-scatter-bubble-chart',
name
:
'Scatter/Bubble Chart (Local)'
,
//
name: 'Scatter/Bubble Chart (Local)',
component
:
'ScatterBubbleChartWidgetComponent'
,
//
component: 'ScatterBubbleChartWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Performance vs. Salary (Scatter)'
,
//
title: 'Employee Performance vs. Salary (Scatter)',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'performanceScore'
,
//
xField: 'performanceScore',
yField
:
'salary'
,
//
yField: 'salary',
xAxisTitle
:
'Performance Score'
,
//
xAxisTitle: 'Performance Score',
yAxisTitle
:
'Salary'
,
//
yAxisTitle: 'Salary',
type
:
'Scatter'
//
type: 'Scatter'
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-multi-row-card'
,
//
id: 'local-multi-row-card',
name
:
'Multi-Row Card (Local)'
,
//
name: 'Multi-Row Card (Local)',
component
:
'MultiRowCardWidgetComponent'
,
//
component: 'MultiRowCardWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Overview'
,
//
title: 'Employee Overview',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
labelField
:
'department'
,
//
labelField: 'department',
valueField
:
'salary'
,
//
valueField: 'salary',
unitField
:
'currency'
// Assuming 'currency' field exists in employee-data.json or can be added
//
unitField: 'currency' // Assuming 'currency' field exists in employee-data.json or can be added
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-combo-chart'
,
//
id: 'local-combo-chart',
name
:
'Combo Chart (Local)'
,
//
name: 'Combo Chart (Local)',
component
:
'ComboChartWidgetComponent'
,
//
component: 'ComboChartWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Sales and Performance'
,
//
title: 'Employee Sales and Performance',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'name'
,
//
xField: 'name',
yFields
:
[
'salesAmount'
,
'performanceScore'
],
//
yFields: ['salesAmount', 'performanceScore'],
xAxisTitle
:
'Employee'
,
//
xAxisTitle: 'Employee',
yAxisTitle
:
'Value'
,
//
yAxisTitle: 'Value',
series
:
[
//
series: [
{
type
:
'Column'
,
xName
:
'name'
,
yName
:
'salesAmount'
,
name
:
'Sales'
},
//
{ type: 'Column', xName: 'name', yName: 'salesAmount', name: 'Sales' },
{
type
:
'Line'
,
xName
:
'name'
,
yName
:
'performanceScore'
,
name
:
'Performance'
}
//
{ type: 'Line', xName: 'name', yName: 'performanceScore', name: 'Performance' }
]
//
]
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-doughnut-chart'
,
//
id: 'local-doughnut-chart',
name
:
'Doughnut Chart (Local)'
,
//
name: 'Doughnut Chart (Local)',
component
:
'DoughnutChartWidgetComponent'
,
//
component: 'DoughnutChartWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Department Distribution'
,
//
title: 'Department Distribution',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'department'
,
//
xField: 'department',
yField
:
'id'
,
//
yField: 'id',
aggregation
:
'count'
,
//
aggregation: 'count',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-funnel-chart'
,
//
id: 'local-funnel-chart',
name
:
'Funnel Chart (Local)'
,
//
name: 'Funnel Chart (Local)',
component
:
'FunnelChartWidgetComponent'
,
//
component: 'FunnelChartWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
3
,
//
rows: 3,
config
:
{
//
config: {
title
:
'Sales Funnel'
,
//
title: 'Sales Funnel',
xField
:
'stage'
,
//
xField: 'stage',
yField
:
'value'
,
//
yField: 'value',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-gauge-chart'
,
//
id: 'local-gauge-chart',
name
:
'Gauge Chart (Local)'
,
//
name: 'Gauge Chart (Local)',
component
:
'GaugeChartWidgetComponent'
,
//
component: 'GaugeChartWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Average Performance Score'
,
//
title: 'Average Performance Score',
valueField
:
'performanceScore'
,
// Assuming 'performanceScore' is a numeric field in employee-data.json
//
valueField: 'performanceScore', // Assuming 'performanceScore' is a numeric field in employee-data.json
ranges
:
[
//
ranges: [
{
start
:
0
,
end
:
60
,
color
:
'#E0B9B9'
},
//
{ start: 0, end: 60, color: '#E0B9B9' },
{
start
:
60
,
end
:
80
,
color
:
'#B9D7EA'
},
//
{ start: 60, end: 80, color: '#B9D7EA' },
{
start
:
80
,
end
:
100
,
color
:
'#B9EAB9'
}
//
{ start: 80, end: 100, color: '#B9EAB9' }
]
//
]
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-simple-kpi'
,
//
id: 'local-simple-kpi',
name
:
'Simple KPI (Local)'
,
//
name: 'Simple KPI (Local)',
component
:
'SimpleKpiWidgetComponent'
,
//
component: 'SimpleKpiWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Total Employees'
,
//
title: 'Total Employees',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
valueField
:
'id'
,
//
valueField: 'id',
aggregation
:
'count'
,
//
aggregation: 'count',
unit
:
'persons'
,
//
unit: 'persons',
trend
:
'up'
,
//
trend: 'up',
trendValue
:
'+10%'
//
trendValue: '+10%'
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-filled-map'
,
//
id: 'local-filled-map',
name
:
'Filled Map (Local)'
,
//
name: 'Filled Map (Local)',
component
:
'FilledMapWidgetComponent'
,
//
component: 'FilledMapWidgetComponent',
cols
:
4
,
//
cols: 4,
rows
:
3
,
//
rows: 3,
config
:
{
//
config: {
title
:
'Employee Distribution by Country'
,
//
title: 'Employee Distribution by Country',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
// Assuming employee-data.json has country and value
//
source: { type: 'url', url: 'assets/data/employee-data.json' }, // Assuming employee-data.json has country and value
countryField
:
'country'
,
// Assuming a 'country' field in employee-data.json
//
countryField: 'country', // Assuming a 'country' field in employee-data.json
valueField
:
'employeeCount'
,
// Assuming an 'employeeCount' field in employee-data.json
//
valueField: 'employeeCount', // Assuming an 'employeeCount' field in employee-data.json
colorMapping
:
[
//
colorMapping: [
{
value
:
0
,
color
:
'#C3E6CB'
},
//
{ value: 0, color: '#C3E6CB' },
{
value
:
50
,
color
:
'#FFECB5'
},
//
{ value: 50, color: '#FFECB5' },
{
value
:
100
,
color
:
'#F5C6CB'
}
//
{ value: 100, color: '#F5C6CB' }
]
//
]
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-matrix'
,
//
id: 'local-matrix',
name
:
'Matrix (Local)'
,
//
name: 'Matrix (Local)',
component
:
'MatrixWidgetComponent'
,
//
component: 'MatrixWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Skills Matrix'
,
//
title: 'Employee Skills Matrix',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
columns
:
[
//
columns: [
{
field
:
'name'
,
headerText
:
'Employee Name'
},
//
{ field: 'name', headerText: 'Employee Name' },
{
field
:
'department'
,
headerText
:
'Department'
},
//
{ field: 'department', headerText: 'Department' },
{
field
:
'skill1'
,
headerText
:
'Skill 1'
},
// Assuming these fields exist or can be added to employee-data.json
//
{ field: 'skill1', headerText: 'Skill 1' }, // Assuming these fields exist or can be added to employee-data.json
{
field
:
'skill2'
,
headerText
:
'Skill 2'
},
//
{ field: 'skill2', headerText: 'Skill 2' },
{
field
:
'skill3'
,
headerText
:
'Skill 3'
},
//
{ field: 'skill3', headerText: 'Skill 3' },
]
//
]
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-slicer'
,
//
id: 'local-slicer',
name
:
'Slicer (Local)'
,
//
name: 'Slicer (Local)',
component
:
'SlicerWidgetComponent'
,
//
component: 'SlicerWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Filter by Department'
,
//
title: 'Filter by Department',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
optionsField
:
'department'
,
// Assuming 'department' field exists in employee-data.json
//
optionsField: 'department', // Assuming 'department' field exists in employee-data.json
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-simple-table'
,
//
id: 'local-simple-table',
name
:
'Simple Table (Local)'
,
//
name: 'Simple Table (Local)',
component
:
'SimpleTableWidgetComponent'
,
//
component: 'SimpleTableWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Details'
,
//
title: 'Employee Details',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
columns
:
[
//
columns: [
{
field
:
'id'
,
headerText
:
'ID'
},
//
{ field: 'id', headerText: 'ID' },
{
field
:
'name'
,
headerText
:
'Name'
},
//
{ field: 'name', headerText: 'Name' },
{
field
:
'department'
,
headerText
:
'Department'
},
//
{ field: 'department', headerText: 'Department' },
{
field
:
'salary'
,
headerText
:
'Salary'
},
//
{ field: 'salary', headerText: 'Salary' },
]
//
]
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-waterfall-chart'
,
//
id: 'local-waterfall-chart',
name
:
'Waterfall Chart (Local)'
,
//
name: 'Waterfall Chart (Local)',
component
:
'WaterfallChartWidgetComponent'
,
//
component: 'WaterfallChartWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Salary Changes'
,
//
title: 'Employee Salary Changes',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'name'
,
//
xField: 'name',
yField
:
'salaryChange'
,
// Assuming 'salaryChange' field exists in employee-data.json
//
yField: 'salaryChange', // Assuming 'salaryChange' field exists in employee-data.json
xAxisTitle
:
'Employee'
,
//
xAxisTitle: 'Employee',
yAxisTitle
:
'Salary Change'
,
//
yAxisTitle: 'Salary Change',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-treemap'
,
//
id: 'local-treemap',
name
:
'Treemap (Local)'
,
//
name: 'Treemap (Local)',
component
:
'TreemapWidgetComponent'
,
//
component: 'TreemapWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Salary Progression'
,
//
title: 'Salary Progression',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
//
source: { type: 'url', url: 'assets/data/employee-data.json' },
xField
:
'name'
,
//
xField: 'name',
yField
:
'salary'
,
//
yField: 'salary',
xAxisTitle
:
'Employee'
,
//
xAxisTitle: 'Employee',
yAxisTitle
:
'Salary'
,
//
yAxisTitle: 'Salary',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-attendance-overview'
,
//
id: 'local-attendance-overview',
name
:
'Attendance Overview (Local)'
,
//
name: 'Attendance Overview (Local)',
component
:
'AttendanceOverviewWidgetComponent'
,
//
component: 'AttendanceOverviewWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Daily Attendance Summary'
,
//
title: 'Daily Attendance Summary',
source
:
{
type
:
'url'
,
url
:
'assets/data/sample1.json'
},
// Assuming sample1.json has attendance data
//
source: { type: 'url', url: 'assets/data/sample1.json' }, // Assuming sample1.json has attendance data
presentField
:
'present'
,
//
presentField: 'present',
onLeaveField
:
'onLeave'
,
//
onLeaveField: 'onLeave',
absentField
:
'absent'
,
//
absentField: 'absent',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-company-info'
,
//
id: 'local-company-info',
name
:
'Company Info (Local)'
,
//
name: 'Company Info (Local)',
component
:
'CompanyInfoWidgetComponent'
,
//
component: 'CompanyInfoWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Our Company Details'
,
//
title: 'Our Company Details',
source
:
{
type
:
'url'
,
url
:
'assets/data/sample1.json'
},
// Assuming sample1.json has company info
//
source: { type: 'url', url: 'assets/data/sample1.json' }, // Assuming sample1.json has company info
companyNameField
:
'companyName'
,
//
companyNameField: 'companyName',
addressField
:
'address'
,
//
addressField: 'address',
contactField
:
'contact'
,
//
contactField: 'contact',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-employee-directory'
,
//
id: 'local-employee-directory',
name
:
'Employee Directory (Local)'
,
//
name: 'Employee Directory (Local)',
component
:
'EmployeeDirectoryWidgetComponent'
,
//
component: 'EmployeeDirectoryWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'All Employees'
,
//
title: 'All Employees',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
// Assuming employee-data.json has employee info
//
source: { type: 'url', url: 'assets/data/employee-data.json' }, // Assuming employee-data.json has employee info
nameField
:
'name'
,
//
nameField: 'name',
positionField
:
'position'
,
//
positionField: 'position',
departmentField
:
'department'
,
//
departmentField: 'department',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-headcount'
,
//
id: 'local-headcount',
name
:
'Employee Headcount (Local)'
,
//
name: 'Employee Headcount (Local)',
component
:
'HeadcountWidgetComponent'
,
//
component: 'HeadcountWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Current Headcount'
,
//
title: 'Current Headcount',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
// Assuming employee-data.json has employee data
//
source: { type: 'url', url: 'assets/data/employee-data.json' }, // Assuming employee-data.json has employee data
categoryField
:
'department'
,
// Field to categorize headcount by
//
categoryField: 'department', // Field to categorize headcount by
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-payroll-summary'
,
//
id: 'local-payroll-summary',
name
:
'Payroll Summary (Local)'
,
//
name: 'Payroll Summary (Local)',
component
:
'PayrollSummaryWidgetComponent'
,
//
component: 'PayrollSummaryWidgetComponent',
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Latest Payroll Overview'
,
//
title: 'Latest Payroll Overview',
source
:
{
type
:
'url'
,
url
:
'assets/data/sample1.json'
},
// Assuming sample1.json has payroll data
//
source: { type: 'url', url: 'assets/data/sample1.json' }, // Assuming sample1.json has payroll data
totalPayrollField
:
'totalPayroll'
,
//
totalPayrollField: 'totalPayroll',
employeesPaidField
:
'employeesPaid'
,
//
employeesPaidField: 'employeesPaid',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-payroll-details'
,
//
id: 'local-payroll-details',
name
:
'Payroll Details (Local)'
,
//
name: 'Payroll Details (Local)',
component
:
'PayrollWidgetComponent'
,
//
component: 'PayrollWidgetComponent',
cols
:
3
,
//
cols: 3,
rows
:
2
,
//
rows: 2,
config
:
{
//
config: {
title
:
'Employee Payroll Details'
,
//
title: 'Employee Payroll Details',
source
:
{
type
:
'url'
,
url
:
'assets/data/employee-data.json'
},
// Assuming employee-data.json has payroll details
//
source: { type: 'url', url: 'assets/data/employee-data.json' }, // Assuming employee-data.json has payroll details
employeeNameField
:
'name'
,
//
employeeNameField: 'name',
payPeriodField
:
'payPeriod'
,
//
payPeriodField: 'payPeriod',
netPayField
:
'netPay'
,
//
netPayField: 'netPay',
}
//
}
}),
//
}),
new
WidgetModel
({
//
new WidgetModel({
id
:
'local-company-info-subfolder'
,
//
id: 'local-company-info-subfolder',
name
:
'Company Info (Subfolder Local)'
,
//
name: 'Company Info (Subfolder Local)',
component
:
'CompanyInfoSubfolderWidgetComponent'
,
// Use the new component name
//
component: 'CompanyInfoSubfolderWidgetComponent', // Use the new component name
cols
:
2
,
//
cols: 2,
rows
:
1
,
//
rows: 1,
config
:
{
//
config: {
title
:
'Our Company Details (Subfolder)'
,
//
title: 'Our Company Details (Subfolder)',
source
:
{
type
:
'url'
,
url
:
'assets/data/sample1.json'
},
// Assuming sample1.json has company info
//
source: { type: 'url', url: 'assets/data/sample1.json' }, // Assuming sample1.json has company info
companyNameField
:
'companyName'
,
//
companyNameField: 'companyName',
addressField
:
'address'
,
//
addressField: 'address',
contactField
:
'contact'
,
//
contactField: 'contact',
}
//
}
}),
//
}),
];
//
];
private
widgetComponentMap
:
{
[
key
:
string
]:
Type
<
any
>
}
=
{
private
widgetComponentMap
:
{
[
key
:
string
]:
Type
<
any
>
}
=
{
'CompanyInfoWidgetComponent'
:
CompanyInfoWidgetComponent
,
'CompanyInfoWidgetComponent'
:
CompanyInfoWidgetComponent
,
...
@@ -559,7 +559,7 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -559,7 +559,7 @@ export class DashboardManagementComponent implements OnInit {
// Populate availableWidgets from WidgetService
// Populate availableWidgets from WidgetService
this
.
widgetService
.
getListWidgets
().
subscribe
(
widgets
=>
{
this
.
widgetService
.
getListWidgets
().
subscribe
(
widgets
=>
{
this
.
availableWidgets
=
[...
widgets
,
...
this
.
localWidgets
].
map
(
widget
=>
({
this
.
availableWidgets
=
[...
widgets
].
map
(
widget
=>
({
...
widget
,
...
widget
,
config
:
widget
.
config
||
{}
// Ensure config property exists
config
:
widget
.
config
||
{}
// Ensure config property exists
}));
}));
...
@@ -572,7 +572,7 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -572,7 +572,7 @@ export class DashboardManagementComponent implements OnInit {
this
.
filteredAvailableWidgets
=
[...
this
.
availableWidgets
];
this
.
filteredAvailableWidgets
=
[...
this
.
availableWidgets
];
}
else
{
}
else
{
this
.
filteredAvailableWidgets
=
this
.
availableWidgets
.
filter
(
widget
=>
this
.
filteredAvailableWidgets
=
this
.
availableWidgets
.
filter
(
widget
=>
widget
.
n
ame
.
toLowerCase
().
includes
(
this
.
widgetSearchTerm
.
toLowerCase
())
widget
.
thN
ame
.
toLowerCase
().
includes
(
this
.
widgetSearchTerm
.
toLowerCase
())
);
);
}
}
console
.
log
(
this
.
filteredAvailableWidgets
)
console
.
log
(
this
.
filteredAvailableWidgets
)
...
@@ -629,8 +629,8 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -629,8 +629,8 @@ export class DashboardManagementComponent implements OnInit {
return
{
return
{
id
:
widget
.
i
d
,
id
:
widget
.
widgetI
d
,
header
:
widget
.
n
ame
,
header
:
widget
.
thN
ame
,
sizeX
:
widget
.
cols
,
sizeX
:
widget
.
cols
,
sizeY
:
widget
.
rows
,
sizeY
:
widget
.
rows
,
row
:
widget
.
y
,
row
:
widget
.
y
,
...
@@ -670,7 +670,7 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -670,7 +670,7 @@ export class DashboardManagementComponent implements OnInit {
// Kept for compatibility with the sidebar, which is not the focus of this refactor
// Kept for compatibility with the sidebar, which is not the focus of this refactor
addWidgetToDashboard
(
widget
:
WidgetModel
):
void
{
addWidgetToDashboard
(
widget
:
WidgetModel
):
void
{
if
(
!
this
.
dashboardData
)
return
;
if
(
!
this
.
dashboardData
)
return
;
if
(
this
.
dashboardData
.
widgets
.
find
(
w
=>
w
.
id
===
widget
.
i
d
))
{
if
(
this
.
dashboardData
.
widgets
.
find
(
w
=>
w
.
widgetId
===
widget
.
widgetI
d
))
{
alert
(
'Widget already exists in the dashboard.'
);
alert
(
'Widget already exists in the dashboard.'
);
return
;
return
;
}
}
...
@@ -684,8 +684,8 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -684,8 +684,8 @@ export class DashboardManagementComponent implements OnInit {
if
(
!
this
.
dashboardData
)
return
;
if
(
!
this
.
dashboardData
)
return
;
const
newWidget
=
new
WidgetModel
({
const
newWidget
=
new
WidgetModel
({
i
d
:
`widget-
${
Date
.
now
()}
`
,
widgetI
d
:
`widget-
${
Date
.
now
()}
`
,
n
ame
:
'Employee Data (New Arch)'
,
thN
ame
:
'Employee Data (New Arch)'
,
component
:
'NewDataTableWidget'
,
component
:
'NewDataTableWidget'
,
cols
:
4
,
cols
:
4
,
rows
:
3
,
rows
:
3
,
...
@@ -723,7 +723,7 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -723,7 +723,7 @@ export class DashboardManagementComponent implements OnInit {
removeWidgetFromDashboard
(
panelId
:
string
):
void
{
removeWidgetFromDashboard
(
panelId
:
string
):
void
{
if
(
!
this
.
dashboardData
)
return
;
if
(
!
this
.
dashboardData
)
return
;
if
(
confirm
(
'Are you sure you want to remove this widget?'
))
{
if
(
confirm
(
'Are you sure you want to remove this widget?'
))
{
const
updatedDashboard
=
{
...
this
.
dashboardData
,
widgets
:
this
.
dashboardData
.
widgets
.
filter
(
w
=>
w
.
i
d
!==
panelId
)
};
const
updatedDashboard
=
{
...
this
.
dashboardData
,
widgets
:
this
.
dashboardData
.
widgets
.
filter
(
w
=>
w
.
widgetI
d
!==
panelId
)
};
this
.
dashboardData
=
updatedDashboard
;
this
.
dashboardData
=
updatedDashboard
;
this
.
panels
=
this
.
mapWidgetsToPanels
(
updatedDashboard
.
widgets
);
this
.
panels
=
this
.
mapWidgetsToPanels
(
updatedDashboard
.
widgets
);
...
@@ -762,7 +762,7 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -762,7 +762,7 @@ export class DashboardManagementComponent implements OnInit {
// Update the widget's config with the new values
// Update the widget's config with the new values
const
updatedWidget
=
{
...
widget
,
config
:
result
};
const
updatedWidget
=
{
...
widget
,
config
:
result
};
if
(
this
.
dashboardData
)
{
if
(
this
.
dashboardData
)
{
const
widgetIndex
=
this
.
dashboardData
.
widgets
.
findIndex
(
w
=>
w
.
id
===
updatedWidget
.
i
d
);
const
widgetIndex
=
this
.
dashboardData
.
widgets
.
findIndex
(
w
=>
w
.
widgetId
===
updatedWidget
.
widgetI
d
);
if
(
widgetIndex
>
-
1
)
{
if
(
widgetIndex
>
-
1
)
{
this
.
dashboardData
.
widgets
[
widgetIndex
]
=
updatedWidget
;
this
.
dashboardData
.
widgets
[
widgetIndex
]
=
updatedWidget
;
// Re-map panels to reflect changes
// Re-map panels to reflect changes
...
@@ -779,7 +779,7 @@ export class DashboardManagementComponent implements OnInit {
...
@@ -779,7 +779,7 @@ export class DashboardManagementComponent implements OnInit {
onPanelChange
(
args
:
any
):
void
{
onPanelChange
(
args
:
any
):
void
{
if
(
this
.
dashboardData
&&
args
.
changedPanels
)
{
if
(
this
.
dashboardData
&&
args
.
changedPanels
)
{
args
.
changedPanels
.
forEach
((
changedPanel
:
PanelModel
)
=>
{
args
.
changedPanels
.
forEach
((
changedPanel
:
PanelModel
)
=>
{
const
widgetIndex
=
this
.
dashboardData
!
.
widgets
.
findIndex
(
w
=>
w
.
i
d
===
changedPanel
.
id
);
const
widgetIndex
=
this
.
dashboardData
!
.
widgets
.
findIndex
(
w
=>
w
.
widgetI
d
===
changedPanel
.
id
);
if
(
widgetIndex
>
-
1
)
{
if
(
widgetIndex
>
-
1
)
{
const
updatedWidget
=
{
...
this
.
dashboardData
!
.
widgets
[
widgetIndex
]
};
const
updatedWidget
=
{
...
this
.
dashboardData
!
.
widgets
[
widgetIndex
]
};
updatedWidget
.
cols
=
changedPanel
.
sizeX
!
;
updatedWidget
.
cols
=
changedPanel
.
sizeX
!
;
...
...
src/app/portal-manage/dashboard-viewer/dashboard-viewer.component.ts
View file @
1a7c08a5
...
@@ -157,12 +157,12 @@ export class DashboardViewerComponent implements OnInit {
...
@@ -157,12 +157,12 @@ export class DashboardViewerComponent implements OnInit {
const
widgetConfig
=
widget
.
config
||
{};
const
widgetConfig
=
widget
.
config
||
{};
return
{
return
{
id
:
widget
.
i
d
,
id
:
widget
.
widgetI
d
,
row
:
widget
.
y
,
row
:
widget
.
y
,
col
:
widget
.
x
,
col
:
widget
.
x
,
sizeX
:
widget
.
cols
,
sizeX
:
widget
.
cols
,
sizeY
:
widget
.
rows
,
sizeY
:
widget
.
rows
,
header
:
widget
.
n
ame
,
header
:
widget
.
thN
ame
,
componentName
:
widget
.
component
,
// Add componentName
componentName
:
widget
.
component
,
// Add componentName
componentType
:
this
.
widgetComponentMap
[
widget
.
component
],
// Attach the component Type
componentType
:
this
.
widgetComponentMap
[
widget
.
component
],
// Attach the component Type
componentInputs
:
{
config
:
widgetConfig
}
// Pass the config object as 'config' input
componentInputs
:
{
config
:
widgetConfig
}
// Pass the config object as 'config' input
...
...
src/app/portal-manage/models/widgets.model.ts
View file @
1a7c08a5
...
@@ -21,38 +21,45 @@ export class DatasetModel implements IDataset {
...
@@ -21,38 +21,45 @@ export class DatasetModel implements IDataset {
}
}
export
interface
IWidget
{
export
interface
IWidget
{
id
:
string
;
widgetId
:
string
;
name
:
string
;
thName
:
string
;
engName
:
string
;
component
:
string
;
component
:
string
;
cols
:
number
;
cols
:
number
;
rows
:
number
;
rows
:
number
;
x
:
number
;
x
:
number
;
y
:
number
;
y
:
number
;
data
:
any
;
// Legacy, to be phased out
data
:
any
;
config
:
any
;
// New: For data-driven configuration
config
:
any
;
perspective
:
any
;
}
}
export
class
WidgetModel
implements
IWidget
{
export
class
WidgetModel
implements
IWidget
{
id
:
string
;
widgetId
:
string
;
name
:
string
;
thName
:
string
;
engName
:
string
;
component
:
string
;
component
:
string
;
cols
:
number
;
cols
:
number
;
rows
:
number
;
rows
:
number
;
x
:
number
;
x
:
number
;
y
:
number
;
y
:
number
;
data
:
any
;
// Legacy, to be phased out
data
:
any
;
config
:
any
;
// New: For data-driven configuration
config
:
any
;
perspective
:
any
;
constructor
(
data
:
Partial
<
IWidget
>
)
{
constructor
(
data
:
Partial
<
IWidget
>
)
{
this
.
id
=
data
.
id
??
''
;
this
.
widgetId
=
data
.
widgetId
??
''
;
this
.
name
=
data
.
name
??
''
;
this
.
thName
=
data
.
thName
??
''
;
this
.
engName
=
data
.
engName
??
''
;
this
.
component
=
data
.
component
??
''
;
this
.
component
=
data
.
component
??
''
;
this
.
cols
=
data
.
cols
??
1
;
this
.
cols
=
data
.
cols
??
1
;
this
.
rows
=
data
.
rows
??
1
;
this
.
rows
=
data
.
rows
??
1
;
this
.
x
=
data
.
x
??
0
;
this
.
x
=
data
.
x
??
0
;
this
.
y
=
data
.
y
??
0
;
this
.
y
=
data
.
y
??
0
;
this
.
data
=
data
.
data
??
{};
// Keep for now for compatibility
this
.
data
=
data
.
data
??
{};
this
.
config
=
data
.
config
??
{};
// Initialize new config object
this
.
config
=
data
.
config
??
{};
this
.
perspective
=
data
.
perspective
??
{};
}
}
}
}
...
...
src/app/portal-manage/services/widgets.service.ts
View file @
1a7c08a5
...
@@ -15,28 +15,24 @@ export class WidgetService {
...
@@ -15,28 +15,24 @@ export class WidgetService {
createStatus
:
boolean
=
true
createStatus
:
boolean
=
true
constructor
(
private
http
:
HttpClient
)
{
}
constructor
(
private
http
:
HttpClient
)
{
}
getListWidgets
(
status
?:
string
):
Observable
<
WidgetModel
[]
>
{
getListWidgets
(
status
?:
string
):
Observable
<
WidgetModel
[]
>
{
if
(
status
)
{
return
this
.
http
.
get
<
WidgetModel
[]
>
(
this
.
url
+
"widget-registry/lists/search"
)
return
this
.
http
.
get
<
WidgetModel
[]
>
(
this
.
url
+
"widget/lists?status="
+
status
)
}
else
{
return
this
.
http
.
get
<
WidgetModel
[]
>
(
this
.
url
+
"widget/lists"
)
}
}
}
getListExcelContent
(
status
?:
string
):
Observable
<
DocumentContentModel
[]
>
{
getListExcelContent
(
status
?:
string
):
Observable
<
DocumentContentModel
[]
>
{
return
this
.
http
.
get
<
DocumentContentModel
[]
>
(
this
.
url
+
"document-center/content/lists"
)
return
this
.
http
.
get
<
DocumentContentModel
[]
>
(
this
.
url
+
"document-center/content/lists"
)
}
}
getWidgetById
(
widgetId
:
string
):
Observable
<
WidgetModel
>
{
getWidgetById
(
widgetId
:
string
):
Observable
<
WidgetModel
>
{
return
this
.
http
.
get
<
WidgetModel
>
(
this
.
url
+
"widget/"
+
widgetId
)
return
this
.
http
.
get
<
WidgetModel
>
(
this
.
url
+
"widget
-registry
/"
+
widgetId
)
}
}
downloadFile
(
logId
:
string
):
Observable
<
any
>
{
downloadFile
(
logId
:
string
):
Observable
<
any
>
{
return
this
.
http
.
get
(
this
.
url
+
"widget
/files/download/"
+
logId
,
{
responseType
:
'blob'
})
return
this
.
http
.
get
(
this
.
url
+
"widget
-registry/files/download/"
+
logId
,
{
responseType
:
'blob'
})
}
}
createWidget
(
model
:
WidgetModel
):
Observable
<
any
>
{
createWidget
(
model
:
WidgetModel
):
Observable
<
any
>
{
let
body
:
any
=
model
let
body
:
any
=
model
return
this
.
http
.
post
(
this
.
url
+
'widget'
,
body
)
return
this
.
http
.
post
(
this
.
url
+
'widget
-registry
'
,
body
)
}
}
deleteWidget
(
model
:
WidgetModel
):
Observable
<
any
>
{
deleteWidget
(
model
:
WidgetModel
):
Observable
<
any
>
{
let
body
=
{
let
body
=
{
widgetId
:
model
.
i
d
widgetId
:
model
.
widgetI
d
}
}
let
option
=
{
let
option
=
{
headers
:
new
HttpHeaders
({
headers
:
new
HttpHeaders
({
...
@@ -44,7 +40,7 @@ export class WidgetService {
...
@@ -44,7 +40,7 @@ export class WidgetService {
}),
}),
body
:
body
body
:
body
}
}
return
this
.
http
.
delete
<
any
>
(
this
.
url
+
'widget'
,
option
)
return
this
.
http
.
delete
<
any
>
(
this
.
url
+
'widget
-registry
'
,
option
)
}
}
deleteExcelContent
(
model
:
DocumentContentModel
):
Observable
<
any
>
{
deleteExcelContent
(
model
:
DocumentContentModel
):
Observable
<
any
>
{
let
body
=
{
let
body
=
{
...
@@ -61,7 +57,7 @@ export class WidgetService {
...
@@ -61,7 +57,7 @@ export class WidgetService {
getCount
(
status
?:
string
):
Observable
<
number
>
{
getCount
(
status
?:
string
):
Observable
<
number
>
{
return
this
.
http
.
get
<
number
>
(
this
.
url
+
"widget/count"
)
return
this
.
http
.
get
<
number
>
(
this
.
url
+
"widget
-registry
/count"
)
}
}
getCountContent
(
status
?:
string
):
Observable
<
number
>
{
getCountContent
(
status
?:
string
):
Observable
<
number
>
{
return
this
.
http
.
get
<
number
>
(
this
.
url
+
"document-center/content/count"
)
return
this
.
http
.
get
<
number
>
(
this
.
url
+
"document-center/content/count"
)
...
...
src/app/portal-manage/widget-management/widget-list.component.html
View file @
1a7c08a5
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
</thead>
</thead>
<tbody
class=
"bg-white divide-y divide-gray-200"
>
<tbody
class=
"bg-white divide-y divide-gray-200"
>
<tr
*
ngFor=
"let widget of widgets$ | async"
>
<tr
*
ngFor=
"let widget of widgets$ | async"
>
<td
class=
"px-6 py-4 whitespace-nowrap"
>
{{ widget.
n
ame }}
</td>
<td
class=
"px-6 py-4 whitespace-nowrap"
>
{{ widget.
thN
ame }}
</td>
<td
class=
"px-6 py-4 whitespace-nowrap"
>
{{ widget.component }}
</td>
<td
class=
"px-6 py-4 whitespace-nowrap"
>
{{ widget.component }}
</td>
<td
class=
"px-6 py-4 whitespace-nowrap"
>
{{ widget.cols }} x {{ widget.rows }}
</td>
<td
class=
"px-6 py-4 whitespace-nowrap"
>
{{ widget.cols }} x {{ widget.rows }}
</td>
<td
class=
"px-6 py-4"
>
<td
class=
"px-6 py-4"
>
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
</div>
</div>
</td>
</td>
<td
class=
"px-6 py-4 whitespace-nowrap text-right"
>
<td
class=
"px-6 py-4 whitespace-nowrap text-right"
>
<button
(
click
)="
editWidget
(
widget
.
i
d
)"
class=
"text-indigo-600 hover:text-indigo-900"
>
Edit
</button>
<button
(
click
)="
editWidget
(
widget
.
widgetI
d
)"
class=
"text-indigo-600 hover:text-indigo-900"
>
Edit
</button>
</td>
</td>
</tr>
</tr>
<!-- Show a message if there are no widgets -->
<!-- Show a message if there are no widgets -->
...
...
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