Skip to content

Commit

Permalink
fixeat(SFINT-3295): Improve UserActions interactivity (#81)
Browse files Browse the repository at this point in the history
* fix(SFINT-3295): Add useResponsiveManager option to UserActions

We want to be able to use the UserAction without him being tied to the ResponsiveComponentManager and without creating a ResponsiveHeaderButton.

* fix(SFINT-3295): Add events for show and hide of UserActionsPanel

* use optional chaining
  • Loading branch information
louis-bompart authored Jul 8, 2020
1 parent 5aa0813 commit b6a3a3a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 9 deletions.
46 changes: 37 additions & 9 deletions src/components/UserActions/UserActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ export interface IUserActionsOptions {
* Default: `False`
*/
hidden: Boolean;
/**
* Whether or not the UserAction component should use the CoveoSearchUI ResponsiveManager
* Inoperant if `hidden` is true.
*
* Default: `True`
*/
useResponsiveManager: Boolean;
}

/**
Expand All @@ -80,6 +87,10 @@ export class UserActions extends Component {
* Identifier of the Search-UI component.
*/
static readonly ID = 'UserActions';
static readonly Events = {
Hide: 'userActionsPanelHide',
Show: 'userActionsPanelShow',
};

/**
* Default initialization options of the **UserActions** class.
Expand All @@ -101,6 +112,9 @@ export class UserActions extends Component {
hidden: ComponentOptions.buildBooleanOption({
defaultValue: false,
}),
useResponsiveManager: ComponentOptions.buildBooleanOption({
defaultValue: true,
}),
};

private static readonly USER_ACTION_OPENED = 'coveo-user-actions-opened';
Expand Down Expand Up @@ -130,7 +144,9 @@ export class UserActions extends Component {
this.tagViewsOfUser();

if (!options.hidden) {
ResponsiveUserActions.init(this.root, this);
if (options.useResponsiveManager) {
ResponsiveUserActions.init(this.root, this);
}
this.bind.onRootElement(QueryEvents.newQuery, () => this.hide());
this.hide();
}
Expand All @@ -144,33 +160,45 @@ export class UserActions extends Component {
(get(this.root, UserProfileModel) as UserProfileModel).deleteActions(this.options.userId);
this.root.classList.remove(UserActions.USER_ACTION_OPENED);
this.isOpened = false;
this.element.dispatchEvent(new CustomEvent(UserActions.Events.Hide));
}
}

/**
* Open the panel.
*/
public show() {
public async show() {
if (!this.isOpened) {
(get(this.root, UserProfileModel) as UserProfileModel)
.getActions(this.options.userId)
.then((actions) => (actions.length > 0 ? this.render() : this.renderNoActions()))
.catch((e) => (e && e.statusCode === 404 ? this.renderEnablePrompt() : this.renderNoActions()));

this.element.dispatchEvent(new CustomEvent(UserActions.Events.Show));
this.bindings.usageAnalytics.logCustomEvent({ name: 'openUserActions', type: 'User Actions' }, {}, this.element);
this.root.classList.add(UserActions.USER_ACTION_OPENED);
this.isOpened = true;

try {
const userActions = await (get(this.root, UserProfileModel) as UserProfileModel).getActions(this.options.userId);
if (userActions.length > 0) {
this.render();
} else {
this.renderNoActions();
}
} catch (e) {
if (e?.statusCode === 404) {
this.renderEnablePrompt();
} else {
this.renderNoActions();
}
}
}
}

/**
* Toggle the visibility of the panel.
*/
public toggle() {
public async toggle() {
if (this.isOpened) {
this.hide();
} else {
this.show();
await this.show();
}
}

Expand Down
50 changes: 50 additions & 0 deletions tests/components/UserActions/UserActions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ describe('UserActions', () => {

it('should not be displayed if hidden option is true', () => {
const responsiveComponentStub = sandbox.stub(ResponsiveUserActions, 'init');
const hideSpy = sandbox.spy(UserActions.prototype, 'hide');

Mock.advancedComponentSetup<UserActions>(
UserActions,
Expand All @@ -85,6 +86,39 @@ describe('UserActions', () => {
})
);

return delay(() => {
expect(hideSpy.called).toBe(false);
expect(responsiveComponentStub.called).toBe(false);
});
});

it('should register to the ResponsiveComponentManager by default', () => {
const responsiveComponentStub = sandbox.stub(ResponsiveUserActions, 'init');

Mock.advancedComponentSetup<UserActions>(
UserActions,
new Mock.AdvancedComponentSetupOptions(null, { userId: 'testuserId' }, (env) => {
fakeUserProfileModel(env.root, sandbox).getActions.returns(Promise.resolve(ACTIONS));
return env;
})
);

return delay(() => {
expect(responsiveComponentStub.called).toBe(true);
});
});

it('should not register to the ResponsiveComponentManager when useResponsiveManager is false', () => {
const responsiveComponentStub = sandbox.stub(ResponsiveUserActions, 'init');

Mock.advancedComponentSetup<UserActions>(
UserActions,
new Mock.AdvancedComponentSetupOptions(null, { userId: 'testuserId', useResponsiveManager: false }, (env) => {
fakeUserProfileModel(env.root, sandbox).getActions.returns(Promise.resolve(ACTIONS));
return env;
})
);

return delay(() => {
expect(responsiveComponentStub.called).toBe(false);
});
Expand Down Expand Up @@ -452,6 +486,13 @@ describe('UserActions', () => {
expect(modelMock.getActions.calledWithExactly(someUserId)).toBe(true);
});
});

it('should trigger a userActionsShow event', () => {
const spyDispatchEvent = sandbox.spy(mock.cmp.element, 'dispatchEvent');
mock.cmp.show();

expect(spyDispatchEvent.calledOnceWith(new CustomEvent('userActionsPanelHide')));
});
});

describe('hide', () => {
Expand Down Expand Up @@ -510,6 +551,15 @@ describe('UserActions', () => {
expect(modelMock.deleteActions.calledWithExactly(someUserId)).toBe(true);
});
});

it('should trigger a userActionsHide event', () => {
mock.cmp.show();
const spyDispatchEvent = sandbox.spy(mock.cmp.element, 'dispatchEvent');

mock.cmp.hide();

expect(spyDispatchEvent.calledOnceWith(new CustomEvent('userActionsPanelHide')));
});
});

describe('tagViewsOfUser', () => {
Expand Down

0 comments on commit b6a3a3a

Please sign in to comment.