Skip to content

Commit

Permalink
feat(activeannotation): apply activeId to existing annotation (#435)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conrad Chan authored Apr 17, 2020
1 parent ef9ceb2 commit 990a6ac
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 8 deletions.
7 changes: 4 additions & 3 deletions src/@types/model.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/* eslint-disable flowtype/no-types-missing-file-annotation, no-use-before-define */
import { Permissions } from './api';

// New Data Model Types
export interface Annotation {
created_at: Date;
created_at: string;
created_by: User;
description?: Reply;
id: string;
modified_at: Date;
modified_at: string;
modified_by: User;
permissions: Permissions;
replies?: Array<Reply>;
Expand Down Expand Up @@ -37,7 +38,7 @@ export interface Rect {
}

export interface Reply {
created_at: Date;
created_at: string;
created_by: User;
id: string;
message: string;
Expand Down
4 changes: 3 additions & 1 deletion src/region/RegionAnnotations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CreatorItem, CreatorStatus } from '../store/creator';
import './RegionAnnotations.scss';

type Props = {
activeAnnotationId: string | null;
annotations: Annotation[];
createRegion: (arg: { location: number; message: string; shape: Rect }) => void;
isCreating: boolean;
Expand Down Expand Up @@ -91,7 +92,7 @@ export default class RegionAnnotations extends React.Component<Props, State> {
}

render(): JSX.Element {
const { annotations, isCreating, staged, status } = this.props;
const { activeAnnotationId, annotations, isCreating, staged, status } = this.props;
const { targetRef } = this.state;
const canDraw = !staged || !staged.message;
const canReply = status === CreatorStatus.staged;
Expand All @@ -104,6 +105,7 @@ export default class RegionAnnotations extends React.Component<Props, State> {
<RegionAnnotation
key={id}
annotationId={id}
isActive={!isCreating && activeAnnotationId === id}
shape={this.scaleShape((target as TargetRegion).shape)}
/>
))}
Expand Down
3 changes: 3 additions & 0 deletions src/region/RegionContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ApplicationState,
CreatorItem,
CreatorStatus,
getActiveAnnotationId,
getAnnotationMode,
getAnnotationsForLocation,
getCreatorStagedForLocation,
Expand All @@ -16,13 +17,15 @@ import RegionAnnotations from './RegionAnnotations';
import withProviders from '../common/withProviders';

export type Props = {
activeAnnotationId: string | null;
annotations: Annotation[];
isCreating: boolean;
staged: CreatorItem | null;
status: CreatorStatus;
};

export const mapStateToProps = (state: ApplicationState, { page }: { page: number }): Props => ({
activeAnnotationId: getActiveAnnotationId(state),
annotations: getAnnotationsForLocation(state, page),
isCreating: getAnnotationMode(state) === 'region',
staged: getCreatorStagedForLocation(state, page),
Expand Down
26 changes: 26 additions & 0 deletions src/region/__mocks__/data.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/camelcase */
export const annotations = [
{ id: 'anno_1', target: { shape: { height: 10, width: 10, x: 10, y: 10, type: 'rect' }, type: 'region' } },
{ id: 'anno_2', target: { shape: { height: 20, width: 20, x: 20, y: 20, type: 'rect' }, type: 'region' } },
Expand All @@ -16,6 +17,31 @@ export const rect = {

export const target = {
id: 'target_1',
location: {
type: 'page' as const,
value: 1,
},
shape: rect,
type: 'region' as const,
};

export const user = {
id: '1',
login: 'johndoe',
name: 'John Doe',
type: 'user' as const,
};

export const annotation = {
created_at: '2020-01-01T00:00:00Z',
created_by: user,
id: '123',
modified_at: '2020-01-02T00:00:00Z',
modified_by: user,
permissions: {
can_delete: true,
can_edit: true,
},
target,
type: 'annotation' as const,
};
14 changes: 14 additions & 0 deletions src/region/__tests__/RegionAnnotations-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jest.mock('../RegionCreator');

describe('RegionAnnotations', () => {
const defaults = {
activeAnnotationId: null,
createRegion: jest.fn(),
page: 1,
scale: 1,
Expand Down Expand Up @@ -179,5 +180,18 @@ describe('RegionAnnotations', () => {
expect(wrapper.exists(RegionAnnotation)).toBe(false);
expect(wrapper.exists(RegionCreator)).toBe(false);
});

test('should render the specified annotation based on activeAnnotationId', () => {
const wrapper = getWrapper({ activeAnnotationId: 'anno_1', annotations });
const renderedAnnotations = wrapper.find(RegionAnnotation);

expect(wrapper.exists('.ba-RegionAnnotations-list')).toBe(true);
expect(renderedAnnotations.length).toBe(3);

for (let i = 0; i < 3; i += 1) {
expect(renderedAnnotations.get(i).key).toBe(annotations[i].id);
expect(renderedAnnotations.get(i).props.isActive).toBe(i === 0);
}
});
});
});
1 change: 1 addition & 0 deletions src/region/__tests__/RegionContainer-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('RegionContainer', () => {

expect(wrapper.exists('RootProvider')).toBe(true);
expect(wrapper.find(RegionAnnotations).props()).toMatchObject({
activeAnnotationId: null,
annotations: [],
createRegion: expect.any(Function),
isCreating: false,
Expand Down
6 changes: 4 additions & 2 deletions src/store/eventing/__tests__/create-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Action } from '@reduxjs/toolkit';
import { handleCreateErrorEvents, handleCreatePendingEvents, handleCreateSuccessEvents } from '../create';
import eventManager from '../../../common/EventManager';
import { ApplicationState } from '../../types';
import { annotation as payload } from '../../../region/__mocks__/data';

jest.mock('../../../common/EventManager');

Expand Down Expand Up @@ -51,10 +52,11 @@ describe('store/eventing/create', () => {

describe('handleCreateSuccessEvents()', () => {
test('should emit create event with success status', () => {
handleCreateSuccessEvents(prevState, nextState, action);
const actionWithPayload = { ...action, payload };
handleCreateSuccessEvents(prevState, nextState, actionWithPayload);

expect(eventManager.emit).toHaveBeenLastCalledWith('annotations_create', {
annotation,
annotation: payload,
meta: {
status: 'success',
},
Expand Down
4 changes: 2 additions & 2 deletions src/store/eventing/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { ApplicationState } from '../types';
import { Event } from '../../@types';

const emitCreateEvent = (action: AsyncAction, status: Status): void => {
const { error, meta: { arg: annotation } = {} } = action;
const { error, meta: { arg } = {}, payload } = action;
eventManager.emit(Event.ANNOTATION_CREATE, {
annotation,
annotation: payload || arg,
error,
meta: {
status,
Expand Down

0 comments on commit 990a6ac

Please sign in to comment.