{{x?.label}}
-
The selected project need to have atleast one sprint available for the KPI's to show up
+ The selected project need to have atleast one ACTIVE sprint available for the KPI's to show up
diff --git a/UI/src/app/dashboardv2/filter-v2/filter-new.component.html b/UI/src/app/dashboardv2/filter-v2/filter-new.component.html
index ef8b6657a8..6c27381211 100644
--- a/UI/src/app/dashboardv2/filter-v2/filter-new.component.html
+++ b/UI/src/app/dashboardv2/filter-v2/filter-new.component.html
@@ -24,7 +24,7 @@
-
+
diff --git a/UI/src/app/dashboardv2/filter-v2/filter-new.component.ts b/UI/src/app/dashboardv2/filter-v2/filter-new.component.ts
index 596c726811..53a857ff4d 100644
--- a/UI/src/app/dashboardv2/filter-v2/filter-new.component.ts
+++ b/UI/src/app/dashboardv2/filter-v2/filter-new.component.ts
@@ -22,7 +22,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
selectedType: string = '';
subscriptions: any[] = [];
selectedFilterData: {};
- selectedLevel: any = 'project';
+ selectedLevel: any = 'Project';
kanban: boolean = false;
boardData: object = {};
kanbanRequired: any = {};
@@ -60,6 +60,8 @@ export class FilterNewComponent implements OnInit, OnDestroy {
iterationConfigData = {};
isRecommendationsEnabled: boolean = false;
selectedBoard: any;
+ hierarchies: any;
+ noSprint: boolean = false;
constructor(
private httpService: HttpService,
@@ -114,11 +116,11 @@ export class FilterNewComponent implements OnInit, OnDestroy {
this.selectedTab = data.selectedTab;
this.selectedType = data.selectedType;
-
+
this.selectedDayType = 'Weeks';
this.selectedDateValue = this.dateRangeFilter?.counts?.[0];
this.selectedDateFilter = `${this.selectedDateValue} ${this.selectedDayType}`;
-
+
if (this.selectedType.toLowerCase() === 'kanban') {
this.kanban = true;
@@ -152,6 +154,31 @@ export class FilterNewComponent implements OnInit, OnDestroy {
);
}
+ /**create dynamic hierarchy levels for filter dropdown */
+ setHierarchyLevels() {
+ if (!this.hierarchies) {
+ this.httpService.getAllHierarchyLevels().subscribe((res) => {
+ if (res.data) {
+ this.hierarchies = res.data;
+ localStorage.setItem('completeHierarchyData', JSON.stringify(this.hierarchies));
+ this.getFiltersData();
+ }
+ });
+ } else {
+ this.getFiltersData();
+ }
+ }
+
+ setSelectedMapLevels() {
+ const selectedType = this.kanban ? 'kanban' : 'scrum';
+ const levelDetails = JSON.parse(localStorage.getItem('completeHierarchyData'))[selectedType];
+ let dataCopy = {};
+ levelDetails.forEach(level => {
+ dataCopy[level.hierarchyLevelId] = this.filterApplyData['selectedMap'][level.hierarchyLevelName];
+ });
+ this.filterApplyData['selectedMap'] = dataCopy;
+ }
+
// unsubscribing all Kpi Request
ngOnDestroy() {
this.subscriptions?.forEach(subscription => subscription?.unsubscribe());
@@ -190,7 +217,8 @@ export class FilterNewComponent implements OnInit, OnDestroy {
this.setSelectedType(this.selectedType);
}
- this.getFiltersData();
+ this.setHierarchyLevels();
+
this.masterData['kpiList'] = this.selectedBoard.kpis;
let newMasterData = {
'kpiList': []
@@ -240,12 +268,23 @@ export class FilterNewComponent implements OnInit, OnDestroy {
result[category].push(currentItem);
return result;
}, {});
+ this.setCategories();
}
}
+ setCategories() {
+ const selectedType = this.kanban ? 'kanban' : 'scrum';
+ const levelDetails = JSON.parse(localStorage.getItem('completeHierarchyData'))[selectedType];
+ let dataCopy = {};
+ levelDetails.forEach(level => {
+ dataCopy[level.hierarchyLevelName] = this.filterDataArr[this.selectedType][level.hierarchyLevelId];
+ });
+ this.filterDataArr[this.selectedType] = dataCopy;
+ }
+
handleParentFilterChange(event) {
if (typeof event === 'string') {
- this.selectedLevel = event?.toLowerCase();
+ this.selectedLevel = event;
} else {
this.selectedLevel = event;
}
@@ -305,7 +344,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
delete stateFilters['additional_level'];
}
- this.filterApplyData['selectedMap']['project'] = stateFilters['primary_level'].map((proj) => proj.nodeId);
+ this.filterApplyData['selectedMap']['Project'] = stateFilters['primary_level'].map((proj) => proj.nodeId);
this.service.setSelectedTrends(stateFilters['primary_level']);
if (!stateFilters['additional_level'] && stateFilters['primary_level']) {
this.handlePrimaryFilterChange(stateFilters['primary_level']);
@@ -371,7 +410,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
}
if (event && !event['additional_level'] && event?.length) { // && Object.keys(event[0]).length) {
-
+
this.selectedDayType = 'Weeks';
this.selectedDateValue = this.dateRangeFilter?.counts?.[0];
this.selectedDateFilter = `${this.selectedDateValue} ${this.selectedDayType}`;
@@ -412,7 +451,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
if (typeof this.selectedLevel === 'string') {
Object.keys(this.filterDataArr[this.selectedType]).forEach((filterLevel) => {
- if (filterLevel !== this.selectedLevel.toLowerCase()) {
+ if (filterLevel !== this.selectedLevel) {
this.filterApplyData['selectedMap'][filterLevel] = [];
} else {
this.filterApplyData['selectedMap'][filterLevel] = [...new Set(event.map((item) => item.nodeId))];
@@ -420,7 +459,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
});
} else if (this.selectedLevel) {
Object.keys(this.filterDataArr[this.selectedType]).forEach((filterLevel) => {
- if (filterLevel !== this.selectedLevel.emittedLevel.toLowerCase()) {
+ if (filterLevel !== this.selectedLevel.emittedLevel) {
this.filterApplyData['selectedMap'][filterLevel] = [];
} else {
this.filterApplyData['selectedMap'][filterLevel] = [...new Set(event.map((item) => item.nodeId))];
@@ -428,14 +467,14 @@ export class FilterNewComponent implements OnInit, OnDestroy {
});
} else {
Object.keys(this.filterDataArr[this.selectedType]).forEach((filterLevel) => {
- if (filterLevel !== 'project') {
+ if (filterLevel !== 'Project') {
this.filterApplyData['selectedMap'][filterLevel] = [];
} else {
this.filterApplyData['selectedMap'][filterLevel] = [...new Set(event.map((item) => item.nodeId))];
}
});
}
-
+ this.setSelectedMapLevels();
if (!this.kanban) {
if (this.selectedTab.toLocaleLowerCase() !== 'developer') {
this.filterApplyData['ids'] = [...new Set(event.map((proj) => proj.nodeId))];
@@ -455,7 +494,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
}
if (this.selectedTab?.toLowerCase() === 'backlog') {
- this.filterApplyData['selectedMap']['sprint'].push(...this.filterDataArr[this.selectedType]['sprint']?.filter((x) => x['parentId']?.includes(event[0].nodeId) && x['sprintState']?.toLowerCase() == 'closed').map(de => de.nodeId));
+ this.filterApplyData['selectedMap']['sprint'].push(...this.filterDataArr[this.selectedType]['Sprint']?.filter((x) => x['parentId']?.includes(event[0].nodeId) && x['sprintState']?.toLowerCase() == 'closed').map(de => de.nodeId));
}
if (this.selectedTab?.toLowerCase() === 'iteration' || this.selectedTab?.toLowerCase() === 'release') {
@@ -471,10 +510,10 @@ export class FilterNewComponent implements OnInit, OnDestroy {
if (typeof this.selectedLevel === 'string') {
this.service.select(this.masterData, this.filterDataArr[this.selectedType][this.selectedLevel], this.filterApplyData, this.selectedTab, false, true, this.boardData['configDetails'], true, this.dashConfigData);
} else {
- this.service.select(this.masterData, this.filterDataArr[this.selectedType][this.selectedLevel.emittedLevel.toLowerCase()], this.filterApplyData, this.selectedTab, false, true, this.boardData['configDetails'], true, this.dashConfigData);
+ this.service.select(this.masterData, this.filterDataArr[this.selectedType][this.selectedLevel.emittedLevel], this.filterApplyData, this.selectedTab, false, true, this.boardData['configDetails'], true, this.dashConfigData);
}
} else {
- this.service.select(this.masterData, this.filterDataArr[this.selectedType]['project'], this.filterApplyData, this.selectedTab, false, true, this.boardData['configDetails'], true, this.dashConfigData);
+ this.service.select(this.masterData, this.filterDataArr[this.selectedType]['Project'], this.filterApplyData, this.selectedTab, false, true, this.boardData['configDetails'], true, this.dashConfigData);
}
// });
}
@@ -497,6 +536,10 @@ export class FilterNewComponent implements OnInit, OnDestroy {
this.handleAdditionalChange({ [key]: event['additional_level'][key] })
});
}
+ } else if (!event.length) {
+ if (this.primaryFilterConfig['defaultLevel'].labelName.toLowerCase() === 'sprint') {
+ this.noSprint = true;
+ }
}
if (this.filterDataArr && this.filterDataArr?.[this.selectedType] && this.filterDataArr[this.selectedType]?.['sprint'] && event && event[0]?.labelName === 'project') {
@@ -505,6 +548,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
if (currentProjectSprints?.length) {
currentProjectSprints.sort((a, b) => new Date(a.sprintEndDate).getTime() - new Date(b.sprintEndDate).getTime());
this.service.setSprintForRnR(currentProjectSprints[currentProjectSprints?.length - 1])
+ this.noSprint = false;
}
}
this.compileGAData(event);
@@ -615,7 +659,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
}
if (event?.length && event[0]) {
let selectedProjectIds;
- if (event[0].labelName === 'project') {
+ if (event[0].labelName?.toLowerCase() === 'project') {
selectedProjectIds = [...new Set(event.map((item) => item.nodeId))];
} else if (event[0] && typeof event[0] !== 'string') {
selectedProjectIds = [...new Set(event.map((item) => item.parentId))];
@@ -630,7 +674,7 @@ export class FilterNewComponent implements OnInit, OnDestroy {
if (allFilters?.length) {
this.additionalFiltersArr['filter' + (index + 1)].push(...allFilters?.filter((filterItem) => {
let parentId = '';
- if (addtnlFilter.defaultLevel.labelName === 'sqd' && !this.kanban) {
+ if (addtnlFilter.defaultLevel.labelName === 'Squad' && !this.kanban) {
parentId = filterItem.parentId.substring(filterItem.parentId.indexOf('_') + 1, filterItem.parentId.length)
} else {
parentId = filterItem.parentId;
diff --git a/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.spec.ts b/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.spec.ts
index 59de366fd9..16b25120a3 100644
--- a/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.spec.ts
+++ b/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.spec.ts
@@ -85,7 +85,7 @@ describe('ParentFilterComponent', () => {
}
});
- expect(component.filterLevels).toEqual(['LEVEL1']);
+ expect(component.filterLevels).toEqual(['Level1']);
// expect(component.selectedLevel).toEqual('LEVEL1');
expect(helperService.getBackupOfFilterSelectionState).toHaveBeenCalledWith('parent_level');
// expect(helperService.setBackupOfFilterSelectionState).toHaveBeenCalledWith({ 'parent_level': 'LEVEL1' });
@@ -150,19 +150,19 @@ describe('ParentFilterComponent', () => {
it('should emit selectedNode when parentFilterConfig labelName is not Organization Level', () => {
component.parentFilterConfig = { labelName: 'Level1' };
- component.filterData = { level1: [{ nodeId: 1, nodeName: 'Node 1' }] };
+ component.filterData = { Level1: [{ nodeId: 1, nodeName: 'Node 1' }] };
component.selectedLevel = 'Node 1';
spyOn(component.onSelectedLevelChange, 'emit');
spyOn(helperService, 'setBackupOfFilterSelectionState');
component.handleSelectedLevelChange();
- expect(helperService.setBackupOfFilterSelectionState).toHaveBeenCalledWith({ 'parent_level': component.selectedLevel.toLowerCase(), 'primary_level': null });
+ expect(helperService.setBackupOfFilterSelectionState).toHaveBeenCalledWith({ 'parent_level': component.selectedLevel, 'primary_level': null });
});
it('should fill additionalFilterLevels with keys that have a higher level than project', () => {
component.filterData = {
- project: [{ level: 2 }],
+ Project: [{ level: 2 }],
department: [{ level: 3 }],
team: [{ level: 4 }],
};
diff --git a/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.ts b/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.ts
index 24438b3ba3..466954dbf1 100644
--- a/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.ts
+++ b/UI/src/app/dashboardv2/filter-v2/parent-filter/parent-filter.component.ts
@@ -28,7 +28,7 @@ export class ParentFilterComponent implements OnChanges {
this.fillAdditionalFilterLevels();
this.filterLevels = Object.keys(this.filterData);
this.filterLevels = this.filterLevels.filter((level) => !this.additionalFilterLevels.includes(level));
- this.filterLevels = this.filterLevels.map(level => level.toUpperCase());
+
this.stringToObject();
this.stateFilters = this.helperService.getBackupOfFilterSelectionState('parent_level');
Promise.resolve().then(() => {
@@ -46,13 +46,13 @@ export class ParentFilterComponent implements OnChanges {
this.helperService.setBackupOfFilterSelectionState({ 'parent_level': this.selectedLevel })
}
- this.onSelectedLevelChange.emit(this.selectedLevel.toLowerCase());
+ this.onSelectedLevelChange.emit(this.selectedLevel);
});
} else if (changes['parentFilterConfig'].previousValue?.labelName === 'Organization Level' && changes['parentFilterConfig'].currentValue?.labelName?.toLowerCase() === 'project' ||
changes['parentFilterConfig'].previousValue?.labelName.toLowerCase() === 'project' && changes['parentFilterConfig'].currentValue?.labelName === 'Organization Level' ||
(changes['parentFilterConfig'].previousValue?.labelName.toLowerCase() === 'project' && changes['parentFilterConfig'].currentValue?.labelName?.toLowerCase() === 'project') ||
changes['parentFilterConfig'].firstChange) {
- this.filterLevels = this.filterData[this['parentFilterConfig']['labelName'].toLowerCase()]?.map((item) => item.nodeName);
+ this.filterLevels = this.filterData[this['parentFilterConfig']['labelName']]?.map((item) => item.nodeName);
this.filterLevels = this.helperService.sortAlphabetically(this.filterLevels);
this.stringToObject();
@@ -70,12 +70,12 @@ export class ParentFilterComponent implements OnChanges {
this.selectedLevel = this.filterLevels[0];
}
this.helperService.setBackupOfFilterSelectionState({ 'parent_level': this.selectedLevel })
- let selectedNode = this.filterData[this['parentFilterConfig']['labelName'].toLowerCase()].filter((filter) => filter.nodeName === this.selectedLevel);
+ let selectedNode = this.filterData[this['parentFilterConfig']['labelName']].filter((filter) => filter.nodeName === this.selectedLevel);
this.onSelectedLevelChange.emit({ nodeId: selectedNode[0].nodeId, nodeType: this['parentFilterConfig']['labelName'], emittedLevel: this.parentFilterConfig['emittedLevel'], fullNodeDetails: selectedNode });
});
}
else if (this.filterData && Object.keys(this.filterData).length) {
- this.filterLevels = this.filterData[this['parentFilterConfig']['labelName'].toLowerCase()]?.map((item) => item.nodeName);
+ this.filterLevels = this.filterData[this['parentFilterConfig']['labelName']]?.map((item) => item.nodeName);
this.filterLevels = this.helperService.sortAlphabetically(this.filterLevels);
this.stringToObject();
this.stateFilters = this.helperService.getBackupOfFilterSelectionState('parent_level');
@@ -101,8 +101,8 @@ export class ParentFilterComponent implements OnChanges {
}
fillAdditionalFilterLevels() {
- if (this.filterData['project']?.length) {
- let projectLevel = this.filterData['project'][0].level;
+ if (this.filterData['Project']?.length) {
+ let projectLevel = this.filterData['Project'][0].level;
Object.keys(this.filterData).forEach((key) => {
if (this.filterData[key][0].level > projectLevel) {
this.additionalFilterLevels.push(key);
@@ -113,12 +113,12 @@ export class ParentFilterComponent implements OnChanges {
handleSelectedLevelChange() {
if (this['parentFilterConfig']['labelName'] === 'Organization Level') {
- this.onSelectedLevelChange.emit(this.selectedLevel.toLowerCase());
+ this.onSelectedLevelChange.emit(this.selectedLevel);
} else {
- let selectedNode = this.filterData[this['parentFilterConfig']['labelName']?.toLowerCase()].filter((filter) => filter.nodeName === this.selectedLevel);
+ let selectedNode = this.filterData[this['parentFilterConfig']['labelName']].filter((filter) => filter.nodeName === this.selectedLevel);
this.onSelectedLevelChange.emit({ nodeId: selectedNode[0].nodeId, nodeType: this['parentFilterConfig']['labelName'], emittedLevel: this.parentFilterConfig['emittedLevel'], fullNodeDetails: selectedNode });
}
- this.helperService.setBackupOfFilterSelectionState({ 'parent_level': this.selectedLevel.toLowerCase(), 'primary_level': null });
+ this.helperService.setBackupOfFilterSelectionState({ 'parent_level': this.selectedLevel, 'primary_level': null });
}
stringToObject() {
diff --git a/UI/src/app/dashboardv2/filter-v2/primary-filter/primary-filter.component.html b/UI/src/app/dashboardv2/filter-v2/primary-filter/primary-filter.component.html
index 59036cb469..98ace2df7b 100644
--- a/UI/src/app/dashboardv2/filter-v2/primary-filter/primary-filter.component.html
+++ b/UI/src/app/dashboardv2/filter-v2/primary-filter/primary-filter.component.html
@@ -29,7 +29,7 @@
placeholder="Select" optionLabel="nodeName"
[style]="{'width':'300px', 'max-width': '100%', 'height': '40px'}" (onChange)="applyPrimaryFilters($event)"
[panelStyle]="{ 'min-width': 'min(100vw, 400px)' }" [appendTo]="filterDiv"
- [filter]="true">
+ [filter]="true" [hidden]="selectedTab === 'iteration'">
{{ selectedFilters[0].nodeName }}
@@ -44,7 +44,7 @@
-