Skip to content

Commit 39502e0

Browse files
authored
Implement experiment exclude list table component (#2612)
* Implement experiment include list table component * Refine the inclusions table component * Implement Include All toggle feature * Fix the empty Type cell after disabling Include All toggle * remove redundant API call in updateFilterMode method * Implement experiment exclude list table component * Disable the slide toggle and action buttons on inclusion table when update permission is now allowed
1 parent 72f189a commit 39502e0

File tree

7 files changed

+108
-21
lines changed

7 files changed

+108
-21
lines changed

frontend/projects/upgrade/src/app/core/experiments/experiments.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import {
4343
selectExperimentsExportLoading,
4444
selectExperimentInclusions,
4545
selectExperimentInclusionsLength,
46+
selectExperimentExclusions,
47+
selectExperimentExclusionsLength,
4648
} from './store/experiments.selectors';
4749
import * as experimentAction from './store//experiments.actions';
4850
import { AppState } from '../core.state';
@@ -87,6 +89,8 @@ export class ExperimentService {
8789
isGraphLoading$ = this.store$.pipe(select(selectIsGraphLoading));
8890
selectExperimentInclusions$ = this.store$.pipe(select(selectExperimentInclusions));
8991
selectExperimentInclusionsLength$ = this.store$.pipe(select(selectExperimentInclusionsLength));
92+
selectExperimentExclusions$ = this.store$.pipe(select(selectExperimentExclusions));
93+
selectExperimentExclusionsLength$ = this.store$.pipe(select(selectExperimentExclusionsLength));
9094
experimentStatById$ = (experimentId) => this.store$.pipe(select(selectExperimentStatById, { experimentId }));
9195
contextMetaData$ = this.store$.pipe(select(selectContextMetaData));
9296
isLoadingContextMetaData$ = this.store$.pipe(select(selectIsLoadingContextMetaData));

frontend/projects/upgrade/src/app/core/experiments/store/experiments.selectors.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,24 @@ export const selectExperimentInclusionsLength = createSelector(
204204
selectExperimentInclusions,
205205
(inclusions) => inclusions.length
206206
);
207+
208+
export const selectExperimentExclusions = createSelector(
209+
selectSelectedExperiment,
210+
(experiment: Experiment): ParticipantListTableRow[] => {
211+
if (!experiment?.experimentSegmentExclusion?.length) {
212+
return [];
213+
}
214+
return experiment.experimentSegmentExclusion
215+
.filter((exclusion) => exclusion.segment)
216+
.sort((a, b) => new Date(a.segment.createdAt).getTime() - new Date(b.segment.createdAt).getTime())
217+
.map((exclusion) => ({
218+
segment: exclusion.segment,
219+
listType: exclusion.segment.listType,
220+
}));
221+
}
222+
);
223+
224+
export const selectExperimentExclusionsLength = createSelector(
225+
selectExperimentExclusions,
226+
(exclusions) => exclusions.length
227+
);

frontend/projects/upgrade/src/app/features/dashboard/experiments/pages/experiment-details-page/experiment-details-page-content/experiment-exclusions-section-card/experiment-exclusions-section-card.component.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
header-left
55
[title]="'experiments.details.exclusions.card.title.text' | translate"
66
[subtitle]="'experiments.details.exclusions.card.subtitle.text' | translate"
7-
[tableRowCount]="tableRowCount"
7+
[tableRowCount]="tableRowCount$ | async"
88
></app-common-section-card-title-header>
99

1010
<!-- header-right -->
@@ -15,7 +15,7 @@
1515
[showMenuButton]="(permissions$ | async)?.experiments.update"
1616
[menuButtonItems]="menuButtonItems"
1717
[isSectionCardExpanded]="isSectionCardExpanded"
18-
(primaryButtonClick)="onAddExclusionClick()"
18+
(primaryButtonClick)="onAddExcludeListClick(experiment.context[0], experiment.id)"
1919
(menuButtonItemClick)="onMenuButtonItemClick($event, experiment)"
2020
(sectionCardExpandChange)="onSectionCardExpandChange($event)"
2121
>
@@ -25,5 +25,7 @@
2525
<app-experiment-exclusions-table
2626
content
2727
*ngIf="isSectionCardExpanded"
28+
[actionsDisabled]="!(permissions$ | async)?.experiments.update"
29+
(rowAction)="onRowAction($event, experiment.id)"
2830
></app-experiment-exclusions-table>
2931
</app-common-section-card>

frontend/projects/upgrade/src/app/features/dashboard/experiments/pages/experiment-details-page/experiment-details-page-content/experiment-exclusions-section-card/experiment-exclusions-section-card.component.ts

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,25 @@ import { TranslateModule } from '@ngx-translate/core';
99
import { IMenuButtonItem } from 'upgrade_types';
1010
import { ExperimentExclusionsTableComponent } from './experiment-exclusions-table/experiment-exclusions-table.component';
1111
import { ExperimentService } from '../../../../../../../core/experiments/experiments.service';
12-
import { Observable } from 'rxjs';
13-
import { Experiment, EXPERIMENT_BUTTON_ACTION } from '../../../../../../../core/experiments/store/experiments.model';
12+
import { DialogService } from '../../../../../../../shared/services/common-dialog.service';
13+
import { EXPERIMENT_BUTTON_ACTION, Experiment } from '../../../../../../../core/experiments/store/experiments.model';
14+
import {
15+
PARTICIPANT_LIST_ROW_ACTION,
16+
ParticipantListRowActionEvent,
17+
ParticipantListTableRow,
18+
} from '../../../../../../../core/feature-flags/store/feature-flags.model';
19+
import { Segment } from '../../../../../../../core/segments/store/segments.model';
1420
import { UserPermission } from '../../../../../../../core/auth/store/auth.models';
21+
import { Observable } from 'rxjs';
1522
import { AuthService } from '../../../../../../../core/auth/auth.service';
1623

1724
@Component({
1825
selector: 'app-experiment-exclusions-section-card',
1926
imports: [
20-
CommonModule,
2127
CommonSectionCardComponent,
2228
CommonSectionCardTitleHeaderComponent,
2329
CommonSectionCardActionButtonsComponent,
30+
CommonModule,
2431
ExperimentExclusionsTableComponent,
2532
TranslateModule,
2633
],
@@ -30,13 +37,10 @@ import { AuthService } from '../../../../../../../core/auth/auth.service';
3037
})
3138
export class ExperimentExclusionsSectionCardComponent implements OnInit {
3239
@Input() isSectionCardExpanded = true;
33-
3440
permissions$: Observable<UserPermission>;
41+
tableRowCount$ = this.experimentService.selectExperimentExclusionsLength$;
3542
selectedExperiment$ = this.experimentService.selectedExperiment$;
3643

37-
// TODO: Add tableRowCount$ when experiment exclusions are implemented
38-
tableRowCount = 0;
39-
4044
menuButtonItems: IMenuButtonItem[] = [
4145
{
4246
label: 'experiments.details.import-exclude-list.menu-item.text',
@@ -50,15 +54,19 @@ export class ExperimentExclusionsSectionCardComponent implements OnInit {
5054
},
5155
];
5256

53-
constructor(private experimentService: ExperimentService, private authService: AuthService) {}
57+
constructor(
58+
private experimentService: ExperimentService,
59+
private dialogService: DialogService,
60+
private authService: AuthService
61+
) {}
5462

5563
ngOnInit() {
5664
this.permissions$ = this.authService.userPermissions$;
5765
}
5866

59-
onAddExclusionClick(): void {
60-
// TODO: Implement add exclusion functionality when dialog service is available
61-
console.log('Add exclusion clicked');
67+
onAddExcludeListClick(appContext: string, experimentId: string): void {
68+
// TODO: Implement add exclude list functionality when dialog service is available
69+
console.log('Add exclude list clicked for experiment:', experimentId, 'context:', appContext);
6270
}
6371

6472
onMenuButtonItemClick(event: string, experiment: Experiment): void {
@@ -80,8 +88,37 @@ export class ExperimentExclusionsSectionCardComponent implements OnInit {
8088
this.isSectionCardExpanded = isSectionCardExpanded;
8189
}
8290

83-
// TODO: Add row action methods when experiment exclusions table events are implemented
84-
// onRowAction(event: ExperimentParticipantListRowActionEvent, experimentId: string): void {}
85-
// onEditExcludeList(rowData: ExperimentParticipantListTableRow, experimentId: string): void {}
86-
// onDeleteExcludeList(segment: Segment): void {}
91+
// Participant list row action events
92+
onRowAction(event: ParticipantListRowActionEvent, experimentId: string): void {
93+
switch (event.action) {
94+
case PARTICIPANT_LIST_ROW_ACTION.EDIT:
95+
this.onEditExcludeList(event.rowData, experimentId);
96+
break;
97+
case PARTICIPANT_LIST_ROW_ACTION.DELETE:
98+
this.onDeleteExcludeList(event.rowData.segment);
99+
break;
100+
default:
101+
console.log('Unknown row action:', event.action);
102+
}
103+
}
104+
105+
onEditExcludeList(rowData: ParticipantListTableRow, experimentId: string): void {
106+
console.log('Edit exclude list for experiment:', rowData, experimentId);
107+
// TODO: Implement edit exclude list modal
108+
// this.dialogService.openEditExperimentExcludeListModal(experimentId, rowData.segment.id)
109+
// .afterClosed()
110+
}
111+
112+
onDeleteExcludeList(segment: Segment): void {
113+
console.log('Delete exclude list:', segment.name);
114+
// TODO: Implement delete exclude list modal
115+
// this.dialogService
116+
// .openDeleteExcludeListModal(segment.name)
117+
// .afterClosed()
118+
// .subscribe((confirmClicked) => {
119+
// if (confirmClicked) {
120+
// this.experimentService.deleteExperimentExclusionPrivateSegmentList(segment.id);
121+
// }
122+
// });
123+
}
87124
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
<div class="table-container">
2-
<p>experiment-exclusions-table works!</p>
2+
<app-common-details-participant-list-table
3+
[tableType]="tableType"
4+
[dataSource]="dataSource$ | async"
5+
[actionsDisabled]="actionsDisabled"
6+
[isLoading]="isLoading$ | async"
7+
noDataRowText="experiments.details.exclusions.card.no-data-row.text"
8+
(rowAction)="onRowAction($event)"
9+
></app-common-details-participant-list-table>
310
</div>
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
1-
import { ChangeDetectionStrategy, Component } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33
import { TranslateModule } from '@ngx-translate/core';
4+
import { ExperimentService } from '../../../../../../../../core/experiments/experiments.service';
5+
import { ParticipantListRowActionEvent } from '../../../../../../../../core/feature-flags/store/feature-flags.model';
6+
import { LIST_FILTER_MODE } from 'upgrade_types';
7+
import { CommonDetailsParticipantListTableComponent } from '../../../../../../../../shared-standalone-component-lib/components/common-details-participant-list-table/common-details-participant-list-table.component';
48

59
@Component({
610
selector: 'app-experiment-exclusions-table',
7-
imports: [CommonModule, TranslateModule],
11+
imports: [CommonDetailsParticipantListTableComponent, CommonModule, TranslateModule],
812
templateUrl: './experiment-exclusions-table.component.html',
913
styleUrl: './experiment-exclusions-table.component.scss',
1014
changeDetection: ChangeDetectionStrategy.OnPush,
1115
})
1216
export class ExperimentExclusionsTableComponent {
13-
// TODO: Implement exclusions table functionality using CommonDetailsParticipantListTableComponent
17+
@Input() actionsDisabled?: boolean = false;
18+
tableType = LIST_FILTER_MODE.EXCLUSION;
19+
dataSource$ = this.experimentService.selectExperimentExclusions$;
20+
isLoading$ = this.experimentService.isLoadingExperiment$;
21+
@Output() rowAction = new EventEmitter<ParticipantListRowActionEvent>();
22+
23+
constructor(private experimentService: ExperimentService) {}
24+
25+
onRowAction(event: ParticipantListRowActionEvent): void {
26+
this.rowAction.emit(event);
27+
}
1428
}

frontend/projects/upgrade/src/app/features/dashboard/experiments/pages/experiment-details-page/experiment-details-page-content/experiment-inclusions-section-card/experiment-inclusions-section-card.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
<app-experiment-inclusions-table
3333
content
3434
*ngIf="isSectionCardExpanded && experiment.filterMode !== FILTER_MODE.INCLUDE_ALL"
35+
[slideToggleDisabled]="!(permissions$ | async)?.experiments.update"
36+
[actionsDisabled]="!(permissions$ | async)?.experiments.update"
3537
(rowAction)="onRowAction($event, experiment.id)"
3638
></app-experiment-inclusions-table>
3739
</app-common-section-card>

0 commit comments

Comments
 (0)