Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';

import { take } from 'rxjs/operators';
import { filter, take } from 'rxjs/operators';

import {
DotGlobalMessageService,
DotHttpErrorManagerService,
DotMessageService,
DotPropertiesService,
DotUiColorsService
} from '@dotcms/data-access';
import { LoggerService, LoginService } from '@dotcms/dotcms-js';
Expand Down Expand Up @@ -66,6 +67,13 @@ describe('DotToolbarUserComponent', () => {
provide: DotReportIssueService,
useValue: { reportIssue: jest.fn(() => of('')) }
},
{
provide: DotPropertiesService,
useValue: {
getKey: jest.fn(() => of('true')),
getFeatureFlagWithDefault: jest.fn(() => of(true))
}
},
Comment thread
fmontes marked this conversation as resolved.
{ provide: DotUiColorsService, useClass: MockDotUiColorsService },
DotToolbarUserStore
],
Expand Down Expand Up @@ -241,20 +249,60 @@ describe('DotToolbarUserComponent', () => {
});

it('should open the report issue dialog from the menu item command', fakeAsync(() => {
jest.spyOn(loginService, 'watchUser').mockImplementation((callback) => {
callback({
user: {
emailAddress: 'admin@dotcms.com',
name: 'Admin User',
fullName: 'Admin User'
},
loginAsUser: null,
isLoginAs: false
} as any);
});

fixture.detectChanges();

let reportIssueCommand: (() => void) | undefined;

fixture.componentInstance.vm$.pipe(take(1)).subscribe((vm) => {
reportIssueCommand = vm.items.find(
(item) => item.id === 'dot-toolbar-user-link-report-issue'
)?.command as (() => void) | undefined;
});
// filter skips the startWith(false) emission where the item is absent.
fixture.componentInstance.vm$
.pipe(
filter((vm) =>
vm.items.some((item) => item.id === 'dot-toolbar-user-link-report-issue')
),
take(1)
)
.subscribe((vm) => {
reportIssueCommand = vm.items.find(
(item) => item.id === 'dot-toolbar-user-link-report-issue'
)?.command as (() => void) | undefined;
});

tick();
reportIssueCommand?.();
fixture.detectChanges();

expect(fixture.componentInstance.$showReportIssue()).toBe(true);
}));

it('should hide the report issue menu item when the feature flag is disabled', fakeAsync(() => {
const dotPropertiesService = TestBed.inject(DotPropertiesService);
(dotPropertiesService.getFeatureFlagWithDefault as jest.Mock).mockReturnValue(of(false));

// Rebuild the component so the new mock value is what vm$ sees.
fixture = TestBed.createComponent(DotToolbarUserComponent);
fixture.detectChanges();

let reportIssueItem: { id?: string } | undefined;
fixture.componentInstance.vm$.pipe(take(1)).subscribe((vm) => {
reportIssueItem = vm.items.find(
(item) => item.id === 'dot-toolbar-user-link-report-issue'
);
});

tick();

expect(reportIssueItem).toBeUndefined();
}));
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { map } from 'rxjs';
import { combineLatest, map, of } from 'rxjs';

import { AsyncPipe } from '@angular/common';
import {
Expand All @@ -14,6 +14,10 @@ import { MenuItem } from 'primeng/api';
import { AvatarModule } from 'primeng/avatar';
import { Menu, MenuModule } from 'primeng/menu';

import { catchError, startWith } from 'rxjs/operators';

import { DotPropertiesService } from '@dotcms/data-access';
import { FeaturedFlags } from '@dotcms/dotcms-models';
import { DotGravatarDirective } from '@dotcms/ui';

import { DotToolbarUserStore } from './store/dot-toolbar-user.store';
Expand All @@ -39,12 +43,30 @@ import { DotMyAccountComponent } from '../dot-my-account/dot-my-account.componen
})
export class DotToolbarUserComponent implements OnInit {
readonly store = inject(DotToolbarUserStore);
readonly #dotPropertiesService = inject(DotPropertiesService);

readonly $showReportIssue = signal(false);
readonly vm$ = this.store.vm$.pipe(
map((vm) => ({
// Flag check lives here (not in the store) because this is meant to be
// removed after launch — easier to rip out from the component than to
// unwind from the store wiring.
readonly vm$ = combineLatest([
this.store.vm$,
this.#dotPropertiesService
.getFeatureFlagWithDefault(FeaturedFlags.FEATURE_FLAG_REPORT_ISSUE_ENABLED, false)
// startWith renders the toolbar immediately at flag=off; catchError keeps it
// visible if /api/v1/configuration/config errors instead of taking it down.
.pipe(
startWith(false),
catchError(() => of(false))
)
]).pipe(
map(([vm, reportIssueEnabled]) => ({
...vm,
items: this.withReportIssueCommand(vm.items)
items: this.withReportIssueCommand(
reportIssueEnabled
Comment thread
fmontes marked this conversation as resolved.
? vm.items
: vm.items.filter((item) => item.id !== 'dot-toolbar-user-link-report-issue')
)
}))
);
$menu = viewChild<Menu>('menu');
Expand Down
3 changes: 2 additions & 1 deletion core-web/libs/dotcms-models/src/lib/shared-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export const enum FeaturedFlags {
FEATURE_FLAG_UVE_STYLE_EDITOR = 'FEATURE_FLAG_UVE_STYLE_EDITOR',
FEATURE_FLAG_PAGE_SCANNER = 'FEATURE_FLAG_PAGE_SCANNER',
FEATURE_FLAG_UVE_LEGACY_SCRIPT_INJECTION = 'FEATURE_FLAG_UVE_LEGACY_SCRIPT_INJECTION',
FEATURE_FLAG_NEW_BLOCK_EDITOR = 'FEATURE_FLAG_NEW_BLOCK_EDITOR'
FEATURE_FLAG_NEW_BLOCK_EDITOR = 'FEATURE_FLAG_NEW_BLOCK_EDITOR',
FEATURE_FLAG_REPORT_ISSUE_ENABLED = 'FEATURE_FLAG_REPORT_ISSUE_ENABLED'
}

export const enum DotConfigurationVariables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ public interface FeatureFlagName {
String FEATURE_FLAG_OPEN_SEARCH_PHASE = "FEATURE_FLAG_OPEN_SEARCH_PHASE";

String FEATURE_FLAG_NEW_BLOCK_EDITOR = "FEATURE_FLAG_NEW_BLOCK_EDITOR";

String FEATURE_FLAG_REPORT_ISSUE_ENABLED = "FEATURE_FLAG_REPORT_ISSUE_ENABLED";
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public class ConfigurationResource implements Serializable {
PageScannerResource.API_URL_PROPERTY,
FeatureFlagName.FEATURE_FLAG_UVE_LEGACY_SCRIPT_INJECTION,
FeatureFlagName.FEATURE_FLAG_NEW_BLOCK_EDITOR,
"REPORT_ISSUE_INCLUDE_USER_PII" }));
REPORT_ISSUE_INCLUDE_USER_PII,
FeatureFlagName.FEATURE_FLAG_REPORT_ISSUE_ENABLED }));

private boolean isOnBlackList(final String key) {
return null != JVMInfoResource.obfuscatePattern ? JVMInfoResource.obfuscatePattern.matcher(key).find() : false;
Expand Down
3 changes: 3 additions & 0 deletions dotCMS/src/main/resources/dotmarketing-config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,9 @@ FEATURE_FLAG_UVE_LEGACY_SCRIPT_INJECTION=false
## New TipTap-v3 Block Editor (rollback safety: legacy editor renders by default)
FEATURE_FLAG_NEW_BLOCK_EDITOR=false

## Report Issue entry in the toolbar user menu (opt-in)
FEATURE_FLAG_REPORT_ISSUE_ENABLED=false

STARTER_BUILD_VERSION=${starter.deploy.version}

##LTS properties to show EOL message
Expand Down
Loading