Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
cef8273
feat: table groups
fdewas-aneo Feb 6, 2025
02d8f8a
feat: group fetching data
fdewas-aneo Feb 7, 2025
77630f5
chore: update display in table
fdewas-aneo Feb 7, 2025
922e2ed
feat: working groups
fdewas-aneo Feb 10, 2025
87a8d40
feat: group settings button
fdewas-aneo Feb 10, 2025
333c5ed
chore: better ui
fdewas-aneo Feb 10, 2025
4caa8c2
feat: group change page
fdewas-aneo Feb 10, 2025
4f230cc
chore: better html
fdewas-aneo Feb 10, 2025
e49b265
chore: update animations location
fdewas-aneo Feb 10, 2025
f2a89ef
chore: moved group components location
fdewas-aneo Feb 11, 2025
85eb0e3
feat: manage groups dialog component
fdewas-aneo Feb 11, 2025
ed7aeaf
feat: click settings button to edit group
fdewas-aneo Feb 11, 2025
5d5b56e
feat: dialog close buttons
fdewas-aneo Feb 11, 2025
3b28b94
chore: handle manage group result
fdewas-aneo Feb 11, 2025
6bd2d56
fix: informations update on groups
fdewas-aneo Feb 12, 2025
4cd68a8
feat: added groups everywhere
fdewas-aneo Feb 12, 2025
784b771
fix: better refresh control
fdewas-aneo Feb 12, 2025
0640cc0
added groups to tables
fdewas-aneo Feb 12, 2025
b13802f
chore: removed duplicates
fdewas-aneo Feb 12, 2025
564f253
fix: inverted filters
fdewas-aneo Feb 12, 2025
5441c4c
feat: handle no conditions for groups
fdewas-aneo Feb 12, 2025
0c410be
fix: filters and multiple groups are now filtering as wanted.
fdewas-aneo Feb 13, 2025
d729f38
chore: address sonarcloud issues
fdewas-aneo Feb 13, 2025
6fe9d3e
tests: group tasks by status component
fdewas-aneo Feb 13, 2025
f39084f
tests: group component
fdewas-aneo Feb 13, 2025
1c8a127
chore: tests and docs on manage groups dialog
fdewas-aneo Feb 13, 2025
c469913
docs: Group tasks by status
fdewas-aneo Feb 13, 2025
9bcaf87
docs: group component
fdewas-aneo Feb 13, 2025
d55555a
tests: table component
fdewas-aneo Feb 13, 2025
de6f208
tests: added invert filters
fdewas-aneo Feb 14, 2025
c46ed7a
Merge branch 'main' into feat/table-groups
fdewas-aneo Feb 14, 2025
b082967
tests: invert filter service
fdewas-aneo Feb 14, 2025
939d48a
tests: index update
fdewas-aneo Feb 14, 2025
d30f58a
tests: lines components
fdewas-aneo Feb 14, 2025
830da2d
test: data table services
fdewas-aneo Feb 14, 2025
11f4e8f
tests: table components
fdewas-aneo Feb 17, 2025
fa756b1
tests: view tasks by status
fdewas-aneo Feb 17, 2025
ee215ad
tests: dashboard index
fdewas-aneo Feb 17, 2025
fe23c8c
chore: renamed preparefilters to prepareFilters
fdewas-aneo Feb 17, 2025
0889a6f
tests: sessions data service
fdewas-aneo Feb 17, 2025
612f556
tests: table service
fdewas-aneo Feb 17, 2025
90844e7
tests: components
fdewas-aneo Feb 17, 2025
adb2f39
chore: layout changes on group tasks by status
fdewas-aneo Feb 17, 2025
0f88838
chore: update code for a better readability
fdewas-aneo Feb 17, 2025
5e8f86a
chore: address sonarQube issues
fdewas-aneo Feb 17, 2025
4b08fcf
chore: added initial values to reduce
fdewas-aneo Feb 17, 2025
7db6a1b
feat: number of groups displayed as a badge
fdewas-aneo Mar 5, 2025
58a1e87
fix: groups now overflow
fdewas-aneo Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export default tseslint.config(
"^@components/",
"^@services/",
"^@angular/",
"^@pipes/"
"^@pipes/",
"^@shared/",
]
}
],
Expand Down
3 changes: 2 additions & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ const config: Config = {
'@components/(.*)': '<rootDir>/src/app/components/$1',
'@services/(.*)': '<rootDir>/src/app/services/$1',
'@pipes/(.*)': '<rootDir>/src/app/pipes/$1',
'@app/(.*)': '<rootDir>/src/app/$1'
'@app/(.*)': '<rootDir>/src/app/$1',
'@shared/(.*)': '<rootDir>/src/app/shared/$1',
},

// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
Expand Down
10 changes: 7 additions & 3 deletions src/app/applications/components/table.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<app-table [trackBy]="trackBy" [columns]="columns" [data]="data()" [total]="total()" [options]="options"
[lockColumns]="lockColumns" [actions]="actions" [statusesGroups]="statusesGroups" (optionsChange)="onOptionsChange()"
(personnalizeTasksByStatus)="personalizeTasksByStatus()" (columnDrop)="onDrop($event)" />
<app-table
[trackBy]="trackBy" [columns]="columns" [data]="data()" [total]="total()"
[options]="options" [lockColumns]="lockColumns" [actions]="actions" [groups]="tableDataService.groups"
[statusesGroups]="statusesGroups" (optionsChange)="onOptionsChange()"
(personnalizeTasksByStatus)="personalizeTasksByStatus()" (columnDrop)="onDrop($event)"
(groupPageChange)="updateGroupPage($event)" (groupSettings)="openGroupSettings($event)"
/>
62 changes: 56 additions & 6 deletions src/app/applications/components/table.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { TaskStatus } from '@aneoconsultingfr/armonik.api.angular';
import { Clipboard } from '@angular/cdk/clipboard';
import { ViewContainerRef, signal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { ManageGroupsDialogResult, TasksStatusesGroup } from '@app/dashboard/types';
import { TableColumn } from '@app/types/column.type';
import { ApplicationData, ColumnKey } from '@app/types/data';
import { Group } from '@app/types/groups';
import { IconsService } from '@services/icons.service';
import { NotificationService } from '@services/notification.service';
import { TasksByStatusService } from '@services/tasks-by-status.service';
import { of } from 'rxjs';
import { Observable, of } from 'rxjs';
import { ApplicationsTableComponent } from './table.component';
import ApplicationsDataService from '../services/applications-data.service';
import { ApplicationsFiltersService } from '../services/applications-filters.service';
import { ApplicationRaw } from '../types';

describe('TasksTableComponent', () => {
Expand Down Expand Up @@ -82,10 +85,11 @@ describe('TasksTableComponent', () => {
]
};

const afterClosedMocked = jest.fn((): Observable<unknown> => of(mockDialogReturn));
const mockMatDialog = {
open: jest.fn(() => {
return {
afterClosed: jest.fn(() => of(mockDialogReturn))
afterClosed: afterClosedMocked,
};
})
};
Expand All @@ -108,6 +112,13 @@ describe('TasksTableComponent', () => {
refresh$: {
next: jest.fn()
},
refreshGroup: jest.fn(),
groupsConditions: [],
manageGroupDialogResult: jest.fn(),
};

const mockApplicationsFilterService = {
saveGroups: jest.fn(),
};

beforeEach(() => {
Expand All @@ -120,7 +131,9 @@ describe('TasksTableComponent', () => {
{ provide: MatDialog, useValue: mockMatDialog },
{ provide: TasksByStatusService, useValue: mockTasksByStatusService },
IconsService,
{ provide: Router, useValue: mockRouter }
{ provide: Router, useValue: mockRouter },
{ provide: ViewContainerRef, useValue: {} },
{ provide: ApplicationsFiltersService, useValue: mockApplicationsFilterService },
]
}).inject(ApplicationsTableComponent);

Expand Down Expand Up @@ -207,9 +220,16 @@ describe('TasksTableComponent', () => {
});
});

it('should track an application by its name and version', () => {
const application = {raw: { name: 'application', version: '0.1.2'}} as ApplicationData;
expect(component.trackBy(0, application)).toEqual(`${application.raw.name}-${application.raw.version}`);
describe('track By', () => {
it('should track an application by its name and version', () => {
const application = {raw: { name: 'application', version: '0.1.2'}} as ApplicationData;
expect(component.trackBy(0, application)).toEqual(`${application.raw.name}-${application.raw.version}`);
});

it('should track group by its name', () => {
const group = { name: signal('some-name') } as unknown as Group<ApplicationRaw>;
expect(component.trackBy(0, group)).toEqual(group.name());
});
});

it('should get data', () => {
Expand All @@ -235,4 +255,34 @@ describe('TasksTableComponent', () => {
it('should get displayedColumns', () => {
expect(component.columns).toEqual(displayedColumns);
});

describe('UpdateGroupPage', () => {
const groupName = 'group 1';

beforeEach(() => {
component.updateGroupPage(groupName);
});

it('should refresh the selected group', () => {
expect(mockApplicationsDataService.refreshGroup).toHaveBeenCalledWith(groupName);
});
});

describe('openGroupSettings', () => {
const groupName = 'Group 1';
const result = [{name: 'Renamed Group', conditions: []}];

beforeEach(() => {
afterClosedMocked.mockReturnValueOnce(of(result));
component.openGroupSettings(groupName);
});

it('should manage the group dialog result', () => {
expect(mockApplicationsDataService.manageGroupDialogResult).toHaveBeenCalledWith(result);
});

it('should update the groups in the local storage', () => {
expect(mockApplicationsFilterService.saveGroups).toHaveBeenCalledWith(mockApplicationsDataService.groupsConditions);
});
});
});
11 changes: 9 additions & 2 deletions src/app/applications/components/table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { AbstractTaskByStatusTableComponent } from '@app/types/components/table';
import { ArmonikData } from '@app/types/data';
import { Group } from '@app/types/groups';
import { ActionTable } from '@app/types/table';
import { TableComponent } from '@components/table/table.component';
import { FiltersService } from '@services/filters.service';
import { IconsService } from '@services/icons.service';
import { TableTasksByStatus, TasksByStatusService } from '@services/tasks-by-status.service';
import { Subject } from 'rxjs';
import ApplicationsDataService from '../services/applications-data.service';
import { ApplicationsFiltersService } from '../services/applications-filters.service';
import { ApplicationRaw } from '../types';

@Component({
Expand All @@ -31,6 +33,7 @@ export class ApplicationsTableComponent extends AbstractTaskByStatusTableCompone
table: TableTasksByStatus = 'applications';

readonly tableDataService = inject(ApplicationsDataService);
readonly filtersService = inject(ApplicationsFiltersService);
readonly iconsService = inject(IconsService);
readonly router = inject(Router);

Expand Down Expand Up @@ -65,7 +68,11 @@ export class ApplicationsTableComponent extends AbstractTaskByStatusTableCompone
};
}

trackBy(index: number, item: ArmonikData<ApplicationRaw>) {
return `${item.raw.name}-${item.raw.version}`;
trackBy(index: number, item: ArmonikData<ApplicationRaw> | Group<ApplicationRaw>) {
if ((item as ArmonikData<ApplicationRaw>).raw !== undefined) {
return `${(item as ArmonikData<ApplicationRaw>).raw.name}-${(item as ArmonikData<ApplicationRaw>).raw.version}`;
} else {
return (item as Group<ApplicationRaw>).name();
}
}
}
2 changes: 2 additions & 0 deletions src/app/applications/index.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
[displayedColumns]="displayedColumnsKeys"
[availableColumns]="availableColumns"
[lockColumns]="lockColumns"
[groupsLength]="tableDataService.groupsConditions.length"
(refresh)="refresh()"
(intervalValueChange)="onIntervalValueChange($event)"
(displayedColumnsChange)="onColumnsChange($event)"
(resetColumns)="onColumnsReset()"
(resetFilters)="onFiltersReset()"
(lockColumnsChange)="onLockColumnsChange()"
(addToDashboard)="onAddToDashboard()"
(groupSettings)="openGroupsSettings()"
>
</app-table-index-actions-toolbar>
</mat-toolbar-row>
Expand Down
54 changes: 42 additions & 12 deletions src/app/applications/index.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ApplicationRawEnumField, FilterStringOperator } from '@aneoconsultingfr/armonik.api.angular';
import { ViewContainerRef } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { MatDialog } from '@angular/material/dialog';
import { DashboardIndexService } from '@app/dashboard/services/dashboard-index.service';
Expand Down Expand Up @@ -129,7 +130,10 @@ describe('Application component', () => {
saveFilters: jest.fn(),
resetFilters: jest.fn(() => defaultFilters),
saveShowFilters: jest.fn(),
restoreShowFilters: jest.fn(() => defaultShowFilters)
restoreShowFilters: jest.fn(() => defaultShowFilters),
restoreGroups: jest.fn(() => []),
saveGroups: jest.fn(),
resetGroups: jest.fn()
};


Expand All @@ -152,6 +156,21 @@ describe('Application component', () => {
refresh$: {
next: jest.fn()
},
groups: [],
groupsConditions: [],
initGroups: jest.fn(),
manageGroupDialogResult: jest.fn(),
};

const dialogResult: unknown[] = [];
const mockmatDialog = {
open: () => {
return {
afterClosed: () => {
return of(dialogResult);
}
};
}
};

beforeEach(() => {
Expand All @@ -164,19 +183,10 @@ describe('Application component', () => {
{ provide: ShareUrlService, useValue: mockShareUrlService },
{ provide: ApplicationsIndexService, useValue: mockApplicationIndexService },
{ provide: AutoRefreshService, useValue: mockAutoRefreshService },
{ provide: MatDialog, useValue:
{
open: () => {
return {
afterClosed: () => {
return of([]);
}
};
}
}
},
{ provide: MatDialog, useValue: mockmatDialog },
{ provide: DashboardIndexService, useValue: mockDashboardIndexService },
DefaultConfigService,
{ provide: ViewContainerRef, useValue: {} },
]
}).inject(IndexComponent);

Expand All @@ -201,6 +211,11 @@ describe('Application component', () => {
expect(component.availableColumns).toEqual(displayedColumns.map(col => col.key));
});

it('should init groups on init', () => {
expect(mockApplicationsDataService.groupsConditions).toEqual(mockApplicationsFilterService.restoreGroups());
expect(mockApplicationsDataService.initGroups).toHaveBeenCalled();
});

it('should get page icon', () => {
expect(component.getIcon('applications')).toEqual('apps');
});
Expand Down Expand Up @@ -409,6 +424,7 @@ describe('Application component', () => {
displayedColumns: component.displayedColumnsKeys,
options: defaultOptions,
filters: component.filters,
groups: mockApplicationsDataService.groupsConditions,
});
});
});
Expand All @@ -426,4 +442,18 @@ describe('Application component', () => {
expect(mockApplicationsFilterService.saveShowFilters).toHaveBeenCalledWith(newShowFilters);
});
});

describe('openGroupsSettings', () => {
beforeEach(() => {
component.openGroupsSettings();
});

it('should manage the group dialogResult', () => {
expect(mockApplicationsDataService.manageGroupDialogResult).toHaveBeenCalledWith(dialogResult);
});

it('should save the groups', () => {
expect(mockApplicationsFilterService.saveGroups).toHaveBeenCalledWith(mockApplicationsDataService.groupsConditions);
});
});
});
2 changes: 2 additions & 0 deletions src/app/applications/index.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { CacheService } from '@services/cache.service';
import { FiltersService } from '@services/filters.service';
import { GrpcSortFieldService } from '@services/grpc-sort-field.service';
import { IconsService } from '@services/icons.service';
import { InvertFilterService } from '@services/invert-filter.service';
import { NotificationService } from '@services/notification.service';
import { QueryParamsService } from '@services/query-params.service';
import { ShareUrlService } from '@services/share-url.service';
Expand Down Expand Up @@ -63,6 +64,7 @@ import { ApplicationRaw } from './types';
NotificationService,
FiltersService,
GrpcSortFieldService,
InvertFilterService,
],
imports: [
PageHeaderComponent,
Expand Down
Loading