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
7d32073b
Commit
7d32073b
authored
Sep 02, 2025
by
Ooh-Ao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ดาต้า source
parent
fafd66a2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
95 additions
and
168 deletions
+95
-168
dashboard-management.component.ts
...ge/dashboard-management/dashboard-management.component.ts
+21
-32
widget-config.component.html
...ard-management/widget-config/widget-config.component.html
+0
-0
widget-config.component.ts
...board-management/widget-config/widget-config.component.ts
+73
-123
dashboard-viewer.component.ts
...tal-manage/dashboard-viewer/dashboard-viewer.component.ts
+1
-13
No files found.
src/app/portal-manage/dashboard-management/dashboard-management.component.ts
View file @
7d32073b
...
...
@@ -683,43 +683,32 @@ export class DashboardManagementComponent implements OnInit {
}
saveLayout
():
void
{
console
.
log
(
'saveLayout called. Dashboard data to save:'
,
this
.
dashboardData
);
if
(
!
this
.
dashboardData
)
return
;
const
dataFetchTasks
:
Observable
<
any
>
[]
=
this
.
dashboardData
.
widgets
.
filter
(
widget
=>
widget
.
component
===
'NewDataTableWidget'
&&
widget
.
config
?.
source
?.
url
)
.
map
(
widget
=>
this
.
widgetDataService
.
fetchDataForWidget
(
widget
.
config
).
pipe
(
tap
(
data
=>
{
// Mutate the config object to include the fetched data
widget
.
config
.
data
=
data
;
})
)
);
// Create a deep copy to avoid mutating the component's state
const
dashboardToSave
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
dashboardData
));
if
(
dataFetchTasks
.
length
>
0
)
{
forkJoin
(
dataFetchTasks
).
subscribe
(()
=>
{
console
.
log
(
'All data fetched, now saving dashboard...'
);
this
.
dashboardDataService
.
saveDashboard
(
this
.
dashboardData
!
).
pipe
(
catchError
(
error
=>
{
this
.
notificationService
.
error
(
'Error'
,
'Failed to save dashboard layout.'
);
return
throwError
(()
=>
error
);
})
).
subscribe
(()
=>
{
this
.
notificationService
.
success
(
'Success'
,
'Dashboard layout saved successfully!'
);
});
});
}
else
{
console
.
log
(
'No data to fetch, saving dashboard directly...'
);
this
.
dashboardDataService
.
saveDashboard
(
this
.
dashboardData
).
pipe
(
catchError
(
error
=>
{
this
.
notificationService
.
error
(
'Error'
,
'Failed to save dashboard layout.'
);
return
throwError
(()
=>
error
);
})
).
subscribe
(()
=>
{
this
.
notificationService
.
success
(
'Success'
,
'Dashboard layout saved successfully!'
);
// Stringify all widget configs before saving
if
(
dashboardToSave
.
widgets
)
{
dashboardToSave
.
widgets
.
forEach
((
widget
:
WidgetModel
)
=>
{
if
(
widget
.
config
&&
typeof
widget
.
config
===
'object'
)
{
widget
.
config
=
JSON
.
stringify
(
widget
.
config
);
}
});
}
console
.
log
(
'Saving dashboard with stringified configs:'
,
dashboardToSave
);
this
.
dashboardDataService
.
saveDashboard
(
dashboardToSave
).
pipe
(
catchError
(
error
=>
{
this
.
notificationService
.
error
(
'Error'
,
'Failed to save dashboard layout.'
);
return
throwError
(()
=>
error
);
})
).
subscribe
(()
=>
{
this
.
notificationService
.
success
(
'Success'
,
'Dashboard layout saved successfully!'
);
// Optionally, reload the dashboard to ensure UI is consistent with saved state
this
.
loadSelectedDashboard
();
});
}
// Kept for compatibility with the sidebar, which is not the focus of this refactor
...
...
src/app/portal-manage/dashboard-management/widget-config/widget-config.component.html
View file @
7d32073b
This diff is collapsed.
Click to expand it.
src/app/portal-manage/dashboard-management/widget-config/widget-config.component.ts
View file @
7d32073b
...
...
@@ -6,6 +6,8 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import
{
MatSelectModule
}
from
'@angular/material/select'
;
import
{
MatInputModule
}
from
'@angular/material/input'
;
import
{
MatButtonModule
}
from
'@angular/material/button'
;
import
{
MatIconModule
}
from
'@angular/material/icon'
;
import
{
MatCheckboxModule
}
from
'@angular/material/checkbox'
;
import
{
FormsModule
}
from
'@angular/forms'
;
export
interface
WidgetConfigDialogData
{
...
...
@@ -24,7 +26,9 @@ export interface WidgetConfigDialogData {
MatInputModule
,
MatSelectModule
,
MatButtonModule
,
MatDialogModule
// Add MatDialogModule
MatDialogModule
,
MatIconModule
,
MatCheckboxModule
],
templateUrl
:
'./widget-config.component.html'
,
styleUrls
:
[
'./widget-config.component.scss'
]
...
...
@@ -33,6 +37,7 @@ export class WidgetConfigComponent implements OnInit {
currentConfig
:
any
;
availableColumns
:
string
[];
widgetType
:
string
;
comboChartTypes
:
string
[]
=
[
'Line'
,
'Column'
,
'Area'
,
'Spline'
];
constructor
(
public
dialogRef
:
MatDialogRef
<
WidgetConfigComponent
>
,
...
...
@@ -40,140 +45,85 @@ export class WidgetConfigComponent implements OnInit {
)
{
}
ngOnInit
():
void
{
this
.
currentConfig
=
{
...
this
.
data
.
config
};
// Create a copy to avoid direct mutation
this
.
availableColumns
=
this
.
data
.
availableColumns
;
this
.
widgetType
=
this
.
data
.
widgetType
;
// Special handling for ChartWidgetComponent's yFields
if
(
this
.
widgetType
===
'ChartWidgetComponent'
&&
this
.
currentConfig
.
yFields
)
{
this
.
currentConfig
.
yFieldsJson
=
JSON
.
stringify
(
this
.
currentConfig
.
yFields
,
null
,
2
);
}
// Special handling for SyncfusionDatagridWidgetComponent's columns
if
(
this
.
widgetType
===
'SyncfusionDatagridWidgetComponent'
&&
this
.
currentConfig
.
columns
)
{
this
.
currentConfig
.
columnsJson
=
JSON
.
stringify
(
this
.
currentConfig
.
columns
,
null
,
2
);
}
// Special handling for SyncfusionPivotWidgetComponent's properties
if
(
this
.
widgetType
===
'SyncfusionPivotWidgetComponent'
)
{
if
(
this
.
currentConfig
.
rows
)
{
this
.
currentConfig
.
rowsJson
=
JSON
.
stringify
(
this
.
currentConfig
.
rows
,
null
,
2
);
}
if
(
this
.
currentConfig
.
columns
)
{
this
.
currentConfig
.
columnsJson
=
JSON
.
stringify
(
this
.
currentConfig
.
columns
,
null
,
2
);
}
if
(
this
.
currentConfig
.
values
)
{
this
.
currentConfig
.
valuesJson
=
JSON
.
stringify
(
this
.
currentConfig
.
values
,
null
,
2
);
}
if
(
this
.
currentConfig
.
filters
)
{
this
.
currentConfig
.
filtersJson
=
JSON
.
stringify
(
this
.
currentConfig
.
filters
,
null
,
2
);
// Handle config whether it is a string or an object
try
{
if
(
typeof
this
.
data
.
config
===
'string'
)
{
this
.
currentConfig
=
JSON
.
parse
(
this
.
data
.
config
);
}
else
{
// Deep copy config to avoid direct mutation of the original object
this
.
currentConfig
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
data
.
config
||
{}));
}
}
catch
(
e
)
{
console
.
error
(
'Error parsing widget config:'
,
e
);
this
.
currentConfig
=
{};
// Default to empty object on error
}
// Special handling for NewDataTableWidget's columns
if
(
this
.
widgetType
===
'NewDataTableWidget'
&&
this
.
currentConfig
.
columns
)
{
this
.
currentConfig
.
columnsJson
=
JSON
.
stringify
(
this
.
currentConfig
.
columns
,
null
,
2
);
}
}
onSave
():
void
{
// Special handling for ChartWidgetComponent's yFields
if
(
this
.
widgetType
===
'ChartWidgetComponent'
&&
this
.
currentConfig
.
yFieldsJson
)
{
try
{
this
.
currentConfig
.
yFields
=
JSON
.
parse
(
this
.
currentConfig
.
yFieldsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for yFields:'
,
e
);
alert
(
'Invalid JSON format for Y-Axis Fields. Please correct it.'
);
return
;
// Prevent closing dialog with invalid data
}
// Initialize arrays if they don't exist
const
gridLikeWidgets
=
[
'SyncfusionDatagridWidgetComponent'
,
'NewDataTableWidget'
,
'MatrixWidgetComponent'
];
if
(
gridLikeWidgets
.
includes
(
this
.
widgetType
)
&&
!
this
.
currentConfig
.
columns
)
{
this
.
currentConfig
.
columns
=
[];
}
// Special handling for SyncfusionDatagridWidgetComponent's columns
if
(
this
.
widgetType
===
'SyncfusionDatagridWidgetComponent'
&&
this
.
currentConfig
.
columnsJson
)
{
try
{
this
.
currentConfig
.
columns
=
JSON
.
parse
(
this
.
currentConfig
.
columnsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for columns:'
,
e
);
alert
(
'Invalid JSON format for Columns. Please correct it.'
);
return
;
// Prevent closing dialog with invalid data
}
}
// Special handling for SyncfusionPivotWidgetComponent's properties
if
(
this
.
widgetType
===
'SyncfusionPivotWidgetComponent'
)
{
if
(
this
.
currentConfig
.
rowsJson
)
{
try
{
this
.
currentConfig
.
rows
=
JSON
.
parse
(
this
.
currentConfig
.
rowsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for rows:'
,
e
);
alert
(
'Invalid JSON format for Rows. Please correct it.'
);
return
;
}
}
if
(
this
.
currentConfig
.
columnsJson
)
{
try
{
this
.
currentConfig
.
columns
=
JSON
.
parse
(
this
.
currentConfig
.
columnsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for columns:'
,
e
);
alert
(
'Invalid JSON format for Columns. Please correct it.'
);
return
;
}
}
if
(
this
.
currentConfig
.
valuesJson
)
{
try
{
this
.
currentConfig
.
values
=
JSON
.
parse
(
this
.
currentConfig
.
valuesJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for values:'
,
e
);
alert
(
'Invalid JSON format for Values. Please correct it.'
);
return
;
}
}
if
(
this
.
currentConfig
.
filtersJson
)
{
try
{
this
.
currentConfig
.
filters
=
JSON
.
parse
(
this
.
currentConfig
.
filtersJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for filters:'
,
e
);
alert
(
'Invalid JSON format for Filters. Please correct it.'
);
return
;
}
}
if
(
!
this
.
currentConfig
.
rows
)
this
.
currentConfig
.
rows
=
[];
if
(
!
this
.
currentConfig
.
columns
)
this
.
currentConfig
.
columns
=
[];
if
(
!
this
.
currentConfig
.
values
)
this
.
currentConfig
.
values
=
[];
if
(
!
this
.
currentConfig
.
filters
)
this
.
currentConfig
.
filters
=
[];
}
// Special handling for NewDataTableWidget's columns
if
(
this
.
widgetType
===
'NewDataTableWidget'
&&
this
.
currentConfig
.
columnsJson
)
{
try
{
this
.
currentConfig
.
columns
=
JSON
.
parse
(
this
.
currentConfig
.
columnsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for columns:'
,
e
);
alert
(
'Invalid JSON format for Columns. Please correct it.'
);
return
;
// Prevent closing dialog with invalid data
}
if
(
this
.
widgetType
===
'ChartWidgetComponent'
&&
!
this
.
currentConfig
.
yFields
)
{
this
.
currentConfig
.
yFields
=
[];
}
// Special handling for ComboChartWidgetComponent's yFields and series
if
(
this
.
widgetType
===
'ComboChartWidgetComponent'
)
{
if
(
this
.
currentConfig
.
yFieldsJson
)
{
try
{
this
.
currentConfig
.
yFields
=
JSON
.
parse
(
this
.
currentConfig
.
yFieldsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for yFields:'
,
e
);
alert
(
'Invalid JSON format for Y-Axis Fields. Please correct it.'
);
return
;
}
}
if
(
this
.
currentConfig
.
seriesJson
)
{
try
{
this
.
currentConfig
.
series
=
JSON
.
parse
(
this
.
currentConfig
.
seriesJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for series:'
,
e
);
alert
(
'Invalid JSON format for Series. Please correct it.'
);
return
;
}
}
}
// Special handling for MatrixWidgetComponent's columns
if
(
this
.
widgetType
===
'MatrixWidgetComponent'
&&
this
.
currentConfig
.
columnsJson
)
{
try
{
this
.
currentConfig
.
columns
=
JSON
.
parse
(
this
.
currentConfig
.
columnsJson
);
}
catch
(
e
)
{
console
.
error
(
'Invalid JSON for columns:'
,
e
);
alert
(
'Invalid JSON format for Columns. Please correct it.'
);
return
;
// Prevent closing dialog with invalid data
}
if
(
!
this
.
currentConfig
.
yFields
)
this
.
currentConfig
.
yFields
=
[];
if
(
!
this
.
currentConfig
.
series
)
this
.
currentConfig
.
series
=
[];
}
}
// Methods for Grid-like Widgets
addGridColumn
()
{
this
.
currentConfig
.
columns
.
push
({
field
:
''
,
headerText
:
''
,
width
:
100
,
isPrimary
:
false
});
}
removeGridColumn
(
index
:
number
)
{
this
.
currentConfig
.
columns
.
splice
(
index
,
1
);
}
// Methods for ChartWidgetComponent & ComboChartWidgetComponent yFields
addChartYField
()
{
this
.
currentConfig
.
yFields
.
push
(
''
);
}
removeChartYField
(
index
:
number
)
{
this
.
currentConfig
.
yFields
.
splice
(
index
,
1
);
}
// Methods for ComboChartWidgetComponent series
addComboSeries
()
{
this
.
currentConfig
.
series
.
push
({
name
:
''
,
type
:
'Line'
,
xName
:
''
,
yName
:
''
});
}
removeComboSeries
(
index
:
number
)
{
this
.
currentConfig
.
series
.
splice
(
index
,
1
);
}
// Methods for SyncfusionPivotWidgetComponent
addPivotRow
()
{
this
.
currentConfig
.
rows
.
push
({
name
:
''
});
}
removePivotRow
(
index
:
number
)
{
this
.
currentConfig
.
rows
.
splice
(
index
,
1
);
}
addPivotColumn
()
{
this
.
currentConfig
.
columns
.
push
({
name
:
''
});
}
removePivotColumn
(
index
:
number
)
{
this
.
currentConfig
.
columns
.
splice
(
index
,
1
);
}
addPivotValue
()
{
this
.
currentConfig
.
values
.
push
({
name
:
''
,
caption
:
''
});
}
removePivotValue
(
index
:
number
)
{
this
.
currentConfig
.
values
.
splice
(
index
,
1
);
}
addPivotFilter
()
{
this
.
currentConfig
.
filters
.
push
({
name
:
''
});
}
removePivotFilter
(
index
:
number
)
{
this
.
currentConfig
.
filters
.
splice
(
index
,
1
);
}
onSave
():
void
{
// No more JSON parsing needed for the refactored widgets
this
.
dialogRef
.
close
(
this
.
currentConfig
);
}
...
...
src/app/portal-manage/dashboard-viewer/dashboard-viewer.component.ts
View file @
7d32073b
...
...
@@ -129,18 +129,6 @@ export class DashboardViewerComponent implements OnInit {
mapWidgetsToPanels
(
widgets
:
WidgetModel
[]):
DashboardPanel
[]
{
return
widgets
.
map
(
widget
=>
{
let
widgetConfig
:
any
=
{};
if
(
typeof
widget
.
config
===
'string'
)
{
try
{
widgetConfig
=
JSON
.
parse
(
widget
.
config
);
}
catch
(
e
)
{
console
.
error
(
'Error parsing widget config string:'
,
widget
.
config
,
e
);
widgetConfig
=
{};
// Default to empty object on error
}
}
else
{
widgetConfig
=
widget
.
config
||
{};
}
return
{
id
:
widget
.
widgetId
,
header
:
widget
.
thName
,
...
...
@@ -149,7 +137,7 @@ export class DashboardViewerComponent implements OnInit {
row
:
widget
.
y
,
col
:
widget
.
x
,
componentType
:
this
.
widgetComponentMap
[
widget
.
component
],
componentInputs
:
{
config
:
widget
Config
},
componentInputs
:
{
config
:
widget
.
config
||
{}
},
};
});
}
...
...
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