const nextHotspot = allHotspots[Math.min(index, allHotspots.length - 1)];
- this.setState({
+ this.setState(({ selectedHotspot }) => ({
hotspots: allHotspots,
hotspotsPageIndex: paging.pageIndex,
hotspotsTotal: paging.total,
- selectedHotspot: nextHotspot
- });
+ selectedHotspot: selectedHotspot?.key === hotspotKey ? nextHotspot : selectedHotspot
+ }));
})
.then(this.fetchSecurityHotspotsReviewed);
};
onExpand={noop}
sourceViewerFile={sourceViewerFile}
/>
- <DeferredSpinner loading={loading}>
+ <DeferredSpinner className="big-spacer" loading={loading}>
{sourceLines.length > 0 && (
<SourceViewerContext.Provider /* Used by LineOptionsPopup */
value={{ branchLike, file: sourceViewerFile }}>
.catch(() => this.mounted && this.setState({ loading: false }));
};
- handleHotspotUpdate = () => {
- return this.fetchHotspot().then((hotspot?: Hotspot) => {
- if (hotspot) {
- return this.props.onUpdateHotspot(hotspot.key);
- }
- });
+ handleHotspotUpdate = async () => {
+ const { hotspotKey } = this.props;
+
+ await this.props.onUpdateHotspot(hotspotKey);
};
handleOpenComment = () => {
);
return (
- <DeferredSpinner loading={loading}>
+ <DeferredSpinner className="big-spacer-left big-spacer-top" loading={loading}>
{hotspot && (
<div className="big-padded hotspot-content">
<div className="huge-spacer-bottom display-flex-space-between">
expect(getSecurityHotspotDetails).toHaveBeenCalledWith(newHotspotKey);
});
-it('should update refresh hotspot on update', () => {
- const wrapper = shallowRender();
- const mockGetHostpot = getSecurityHotspotDetails as jest.Mock;
- mockGetHostpot.mockClear();
+it('should refresh hotspot on update', () => {
+ const onUpdateHotspot = jest.fn();
+ const wrapper = shallowRender({ onUpdateHotspot });
wrapper.find(HotspotViewerRenderer).simulate('updateHotspot');
- expect(mockGetHostpot).toHaveBeenCalledTimes(1);
+ expect(onUpdateHotspot).toHaveBeenCalled();
});
it('should open comment form when scroll to comment', () => {
}
/>
<DeferredSpinner
+ className="big-spacer"
loading={false}
/>
</div>
}
/>
<DeferredSpinner
+ className="big-spacer"
loading={false}
>
<ContextProvider
exports[`should render correctly 1`] = `
<DeferredSpinner
+ className="big-spacer-left big-spacer-top"
loading={false}
>
<div
exports[`should render correctly: anonymous user 1`] = `
<DeferredSpinner
+ className="big-spacer-left big-spacer-top"
loading={false}
>
<div
exports[`should render correctly: assignee without name 1`] = `
<DeferredSpinner
+ className="big-spacer-left big-spacer-top"
loading={false}
>
<div
exports[`should render correctly: deleted assignee 1`] = `
<DeferredSpinner
+ className="big-spacer-left big-spacer-top"
loading={false}
>
<div
exports[`should render correctly: no hotspot 1`] = `
<DeferredSpinner
+ className="big-spacer-left big-spacer-top"
loading={false}
/>
`;
exports[`should render correctly: unassigned 1`] = `
<DeferredSpinner
+ className="big-spacer-left big-spacer-top"
loading={false}
>
<div
currentUser: T.CurrentUser;
hotspot: Hotspot;
- onStatusChange: () => void;
+ onStatusChange: () => Promise<void>;
}
export function Status(props: StatusProps) {
<DropdownOverlay noPadding={true} placement={PopupPlacement.Bottom}>
<StatusSelection
hotspot={hotspot}
- onStatusOptionChange={() => {
+ onStatusOptionChange={async () => {
+ await props.onStatusChange();
setIsOpen(false);
- props.onStatusChange();
}}
/>
</DropdownOverlay>
interface Props {
hotspot: Hotspot;
- onStatusOptionChange: (statusOption: HotspotStatusOption) => void;
+ onStatusOptionChange: (statusOption: HotspotStatusOption) => Promise<void>;
}
interface State {
...getStatusAndResolutionFromStatusOption(selectedStatus),
comment: comment || undefined
})
- .then(() => {
+ .then(async () => {
+ await this.props.onStatusOptionChange(selectedStatus);
this.setState({ loading: false });
- this.props.onStatusOptionChange(selectedStatus);
})
.then(() =>
addGlobalSuccessMessage(