Skip to content

Commit

Permalink
Merge branch 'main' into test/load-graph
Browse files Browse the repository at this point in the history
  • Loading branch information
asAlwaysZahra authored Sep 9, 2024
2 parents 66f0d09 + 3d4e7fe commit 47de7eb
Show file tree
Hide file tree
Showing 23 changed files with 429 additions and 117 deletions.
4 changes: 2 additions & 2 deletions api-config/api-url.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const environment = {
apiUrl: 'https://localhost:44322',
// apiUrl: 'http://localhost:8085',
// apiUrl: 'https://localhost:44322',
apiUrl: 'http://localhost:8085',
};
22 changes: 8 additions & 14 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { MainPageComponent } from './user/components/dashboard/main-page/main-pa
import { ManageAccountComponent } from './user/components/dashboard/manage-account/manage-account.component';
import { DataAnalysisComponent } from './graph/components/data-analysis/data-analysis.component';
import { ManageUsersComponent } from './user/components/dashboard/manage-users/manage-users.component';
import { AppComponent } from './app.component';
import { AuthGuard } from './guards/auth/auth.guard';
import { PermissionGuard } from './guards/permissions/permission.guard';
import { AddGraphComponent } from './graph/components/add-graph/add-graph.component';
Expand All @@ -15,11 +14,14 @@ import { CategoryComponent } from './graph/components/category/category.componen
import { RecoverPassFormComponent } from './user/components/login/recover-pass-form/recover-pass-form.component';
import { LoginFormComponent } from './user/components/login/login-form/login-form.component';
import { ResetPasswordComponent } from './user/components/login/reset-password/reset-password.component';
import { LoginGuard } from './guards/auth/login.guard';

const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{
path: '',
component: LoginComponent,
canActivate: [LoginGuard],
children: [
{
path: 'recover-password',
Expand All @@ -30,16 +32,9 @@ const routes: Routes = [
path: 'login',
component: LoginFormComponent,
title: 'StarData | Login',
// canActivate: [AuthGuard],
},
],
},
// {
// path: 'login',
// component: LoginComponent,
// title: 'StarData | Login',
// canActivate: [AuthGuard],
// },
{
path: 'dashboard',
component: DashboardComponent,
Expand All @@ -56,7 +51,7 @@ const routes: Routes = [
path: 'manage-users',
component: ManageUsersComponent,
title: 'StarData | Manage Users',
data: { permission: undefined },
data: { permission: 'Register' },
},
{
path: 'manage-account',
Expand All @@ -67,21 +62,25 @@ const routes: Routes = [
path: 'data-analysis',
component: DataAnalysisComponent,
title: 'StarData | Data Analysis',
data: { permission: 'GetNodesAsync' },
},
{
path: 'add-graph',
component: AddGraphComponent,
title: 'StarData | Add Graph',
data: { permission: 'UploadNodeFile' },
},
{
path: 'assign-file',
component: AssignFileComponent,
title: 'StarData | Assign File',
data: { permission: 'AccessFileToUser' },
},
{
path: 'manage-category',
component: CategoryComponent,
title: 'StarData | Manage Category',
data: { permission: 'GetCategories' },
},
],
},
Expand All @@ -90,11 +89,6 @@ const routes: Routes = [
component: ResetPasswordComponent,
title: 'StarData | Reset Password',
},
{
path: '',
component: AppComponent,
canActivate: [AuthGuard],
},
];

@NgModule({
Expand Down
9 changes: 9 additions & 0 deletions src/app/graph/components/category/category.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@
}
</div>
<table mat-table [dataSource]="categoriesData">
<tr class="mat-row" *matNoDataRow>
<td
class="mat-cell"
[attr.colspan]="displayedColumns.length"
style="padding: 1rem"
>
No category Found!
</td>
</tr>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef>id</th>
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@
></app-search-nodes>
</app-card>
<mat-menu #menu="matMenu" id="right-click-node-info">
<button mat-menu-item (click)="getInfo()">Show node information</button>
@if (isNode) {
<button mat-menu-item (click)="getNodeInfo()">Show node information</button>
<button mat-menu-item (click)="getGraph()">Show as graph</button>
} @else {
<button mat-menu-item (click)="getEdgeInfo()">Show edge information</button>
}
</mat-menu>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('DataAnalysisComponent', () => {
mockLoadGraphService = jasmine.createSpyObj<LoadGraphService>([
'getAllNodes',
'getNodeInfo',
'getEdgeInfo',
'nodesData$',
'getGraph',
]);
Expand Down Expand Up @@ -79,7 +80,7 @@ describe('DataAnalysisComponent', () => {
fixture.detectChanges();

spyOn(document, 'getElementById').and.returnValue({
dataset: { nodeid: '123' },
dataset: { nodeid: '123', edgeid: '123' },
} as unknown as HTMLElement);
});

Expand All @@ -93,13 +94,24 @@ describe('DataAnalysisComponent', () => {
expect(component.isDarkMode).toBeTrue();
});

it('getInfo SHOULD show info WHEN get data successfully', () => {
it('getNodeInfo SHOULD show info WHEN get data successfully', () => {
// Arrange
mockLoadGraphService.getNodeInfo
.withArgs('123')
.and.returnValue(of({ name: 'mamad', id: 1 }));
// Act
component.getInfo();
component.getNodeInfo();
// Assert
expect(mockMatDialog.open).toHaveBeenCalled();
});

it('getEdgeInfo SHOULD show info WHEN get data successfully', () => {
// Arrange
mockLoadGraphService.getEdgeInfo
.withArgs('123')
.and.returnValue(of({ name: 'mamad', id: 1 }));
// Act
component.getEdgeInfo();
// Assert
expect(mockMatDialog.open).toHaveBeenCalled();
});
Expand Down
46 changes: 39 additions & 7 deletions src/app/graph/components/data-analysis/data-analysis.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class DataAnalysisComponent implements AfterViewInit {
isDarkMode = false;
nodeColor!: string;
selectedNodeColor!: string;
isNode!: boolean;

nodes = new DataSet<Node>([] as unknown as Node[]);
edges = new DataSet<Edge>([] as Edge[]);
Expand Down Expand Up @@ -92,6 +93,7 @@ export class DataAnalysisComponent implements AfterViewInit {
const edgeId = this.networkInstance.getEdgeAt(params.pointer.DOM);

if (nodeId !== undefined) {
this.isNode = true;
this.menuTrigger.nativeElement.style.left = params.event.clientX + 'px';
this.menuTrigger.nativeElement.style.top = params.event.clientY + 'px';
this.menuTrigger.nativeElement.style.position = 'fixed';
Expand All @@ -103,14 +105,20 @@ export class DataAnalysisComponent implements AfterViewInit {
) as HTMLElement;

rightClickNodeInfoElem.dataset['nodeid'] = nodeId.toString();

// Custom logic for node right-click
} else if (edgeId !== undefined) {
this.isNode = false;
console.log('Right-clicked edge:', edgeId);
// Custom logic for edge right-click
} else {
console.log('Right-clicked on empty space');
// Custom logic for right-click on empty space
this.menuTrigger.nativeElement.style.left = params.event.clientX + 'px';
this.menuTrigger.nativeElement.style.top = params.event.clientY + 'px';
this.menuTrigger.nativeElement.style.position = 'fixed';
this.matMenuTrigger.openMenu();

this.changeDetector.detectChanges();
const rightClickNodeInfoElem = document.getElementById(
'right-click-node-info'
) as HTMLElement;

rightClickNodeInfoElem.dataset['edgeid'] = edgeId.toString();
}
});

Expand Down Expand Up @@ -180,7 +188,7 @@ export class DataAnalysisComponent implements AfterViewInit {
console.log('edge click: ', edgeId);
}

getInfo() {
getNodeInfo() {
const account = (
document.getElementById('right-click-node-info') as HTMLElement
).dataset['nodeid'];
Expand All @@ -204,6 +212,30 @@ export class DataAnalysisComponent implements AfterViewInit {
});
}

getEdgeInfo() {
const account = (
document.getElementById('right-click-node-info') as HTMLElement
).dataset['edgeid'];

this.loadGraphService.getEdgeInfo(account!).subscribe({
next: (data) => {
this.dialog.open(InfoDialogComponent, {
width: '105rem',
data,
});
this.loadingService.setLoading(false);
},
error: (error) => {
this._snackBar.openFromComponent(DangerSuccessNotificationComponent, {
data: error.error.message,
panelClass: ['notification-class-danger'],
duration: 2000,
});
this.loadingService.setLoading(false);
},
});
}

showAsGraph(account: Account) {
this.nodes.add({ id: account.id, label: account.entityName });
}
Expand Down
20 changes: 7 additions & 13 deletions src/app/graph/components/data-analysis/graph-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,15 @@ export function getOptions() {

const svgDataUrl =
'data:image/svg+xml;charset=UTF-8,' +
encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512l388.6 0c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304l-91.4 0z"
fill="${labelColor}"/>
</svg>
encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="${labelColor}" >
<path d="M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Z"/>
</svg>
`);

return {
physics: false,
edges: {
width: 0.7,
smooth: { enabled: false, type: 'vertical', roundness: 0 },
arrows: {
to: {
Expand All @@ -40,13 +38,11 @@ export function getOptions() {
color: textColor,
strokeWidth: 0,
face: 'MyCustomFont',
size: 6,
},
},
nodes: {
shape: 'image',
image: svgDataUrl,
size: 8,
color: {
background: labelColor,
border: labelBorder,
Expand All @@ -59,7 +55,6 @@ export function getOptions() {
align: 'center',
color: textColor,
face: 'MyCustomFont',
size: 6,
},
},
} as Options;
Expand All @@ -69,10 +64,9 @@ export function getSvg(color: string, borderColor = color) {
return (
'data:image/svg+xml;charset=UTF-8,' +
encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512l388.6 0c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304l-91.4 0z"
fill="${color}" stroke-width="2" stroke="${borderColor}"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="${color}" stroke-width="2" stroke="${borderColor}">
<path d="M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Z"/>
</svg>
`)
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
</form>
<mat-form-field appearance="outline" class="category">
<mat-label>Category</mat-label>
<mat-select
[(ngModel)]="category"
name="category"
(ngModelChange)="categoryChanged()"
>
<mat-option value="">All categories</mat-option>
@for (category of allCategories; track category) {
<mat-option [value]="category.id">{{ category.name }}</mat-option>
}
</mat-select>
</mat-form-field>
<div class="accounts">
@for (account of accounts; track $index) {
<div class="account-data">
Expand All @@ -43,7 +56,7 @@
</mat-icon>
</div>
</div>
}
}@empty { <p class="not-found">No nodes Found!</p> }
</div>
<mat-paginator
class="paginator"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
}
}

.category {
width: 100%;
}

.accounts {
display: flex;
flex-direction: column;
Expand Down
Loading

0 comments on commit 47de7eb

Please sign in to comment.