box-annotations 5.2.1-beta.14 → 5.2.1-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/annotations.css +1 -1
- package/dist/annotations.js +1 -1
- package/package.json +13 -13
- package/src/@types/api.ts +3 -2
- package/src/@types/events.ts +27 -10
- package/src/@types/model.ts +1 -0
- package/src/adapters/threadedAnnotationsAdapters.ts +17 -1
- package/src/api/APIFactory.ts +6 -1
- package/src/api/types.ts +23 -1
- package/src/common/BaseAnnotator.scss +2 -1
- package/src/common/BaseAnnotator.ts +27 -2
- package/src/components/Popups/PopupV2.tsx +46 -10
- package/src/drawing/DrawingAnnotations.tsx +6 -5
- package/src/popup/PopupLayer.tsx +32 -4
- package/src/store/annotations/actions.ts +89 -0
- package/src/store/annotations/reducer.ts +48 -0
- package/src/store/eventing/create.ts +3 -3
- package/src/store/eventing/delete.ts +27 -0
- package/src/store/eventing/middleware.ts +40 -4
- package/src/store/eventing/replyCreate.ts +34 -0
- package/src/store/eventing/replyDelete.ts +35 -0
- package/src/store/eventing/replyUpdate.ts +39 -0
- package/src/store/eventing/types.ts +4 -4
- package/src/store/eventing/update.ts +29 -0
- package/src/store/options/selectors.ts +2 -2
- package/src/store/options/types.ts +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import eventManager from '../../common/EventManager';
|
|
2
2
|
import { AsyncAction, Status } from './types';
|
|
3
3
|
import { AppState } from '../types';
|
|
4
|
-
import { Event } from '../../@types';
|
|
4
|
+
import { Annotation, Event, NewAnnotation } from '../../@types';
|
|
5
5
|
|
|
6
|
-
const emitCreateEvent = (action: AsyncAction, status: Status): void => {
|
|
6
|
+
const emitCreateEvent = (action: AsyncAction<NewAnnotation, Annotation>, status: Status): void => {
|
|
7
7
|
const { error, meta: { arg, requestId } = {}, payload } = action;
|
|
8
8
|
eventManager.emit(Event.ANNOTATION_CREATE, {
|
|
9
9
|
annotation: payload || arg,
|
|
@@ -16,7 +16,7 @@ const emitCreateEvent = (action: AsyncAction, status: Status): void => {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const createHandler = (status: Status) => (prevState: AppState, nextState: AppState, action: AsyncAction): void =>
|
|
19
|
-
emitCreateEvent(action, status);
|
|
19
|
+
emitCreateEvent(action as AsyncAction<NewAnnotation, Annotation>, status);
|
|
20
20
|
|
|
21
21
|
const handleCreateErrorEvents = createHandler(Status.ERROR);
|
|
22
22
|
const handleCreatePendingEvents = createHandler(Status.PENDING);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { AsyncAction, Status } from './types';
|
|
4
|
+
import { Event } from '../../@types';
|
|
5
|
+
|
|
6
|
+
const emitDeleteEvent = (action: AsyncAction<string, string>, status: Status): void => {
|
|
7
|
+
const { error, meta: { arg, requestId } = {}, payload } = action;
|
|
8
|
+
if (status === Status.SUCCESS && !payload) return;
|
|
9
|
+
const id = payload ?? arg;
|
|
10
|
+
eventManager.emit(Event.ANNOTATION_DELETE, {
|
|
11
|
+
annotation: id ? { id } : undefined,
|
|
12
|
+
error,
|
|
13
|
+
meta: { requestId, status },
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const deleteHandler = (status: Status) => (
|
|
18
|
+
_prev: AppState,
|
|
19
|
+
_next: AppState,
|
|
20
|
+
action: AsyncAction,
|
|
21
|
+
): void => emitDeleteEvent(action as AsyncAction<string, string>, status);
|
|
22
|
+
|
|
23
|
+
const handleDeleteErrorEvents = deleteHandler(Status.ERROR);
|
|
24
|
+
const handleDeletePendingEvents = deleteHandler(Status.PENDING);
|
|
25
|
+
const handleDeleteSuccessEvents = deleteHandler(Status.SUCCESS);
|
|
26
|
+
|
|
27
|
+
export { handleDeleteErrorEvents, handleDeletePendingEvents, handleDeleteSuccessEvents };
|
|
@@ -2,28 +2,58 @@ import noop from 'lodash/noop';
|
|
|
2
2
|
import { Action, Dispatch, Middleware, MiddlewareAPI } from '@reduxjs/toolkit';
|
|
3
3
|
import {
|
|
4
4
|
createAnnotationAction,
|
|
5
|
+
createReplyAction,
|
|
6
|
+
deleteAnnotationAction,
|
|
7
|
+
deleteReplyAction,
|
|
5
8
|
fetchAnnotationsAction,
|
|
6
9
|
setActiveAnnotationIdAction,
|
|
7
10
|
setIsInitialized,
|
|
11
|
+
updateAnnotationAction,
|
|
12
|
+
updateReplyAction,
|
|
8
13
|
} from '../annotations/actions';
|
|
9
14
|
import { navigateBoundingBoxHighlightAction } from '../boundingBoxHighlights/actions';
|
|
10
15
|
import { EventHandlerMap } from './types';
|
|
11
16
|
import { handleActiveAnnotationEvents } from './active';
|
|
12
17
|
import { handleAnnotationsInitialized } from './init';
|
|
18
|
+
import { handleNavigateBoundingBoxHighlight } from './boundingBoxHighlightNav';
|
|
13
19
|
import { handleCreateErrorEvents, handleCreatePendingEvents, handleCreateSuccessEvents } from './create';
|
|
20
|
+
import { handleDeleteErrorEvents, handleDeletePendingEvents, handleDeleteSuccessEvents } from './delete';
|
|
14
21
|
import { handleFetchErrorEvents } from './fetch';
|
|
15
|
-
import {
|
|
22
|
+
import { handleToggleAnnotationModeAction } from './mode';
|
|
23
|
+
import {
|
|
24
|
+
handleReplyCreateErrorEvents,
|
|
25
|
+
handleReplyCreatePendingEvents,
|
|
26
|
+
handleReplyCreateSuccessEvents,
|
|
27
|
+
} from './replyCreate';
|
|
28
|
+
import {
|
|
29
|
+
handleReplyDeleteErrorEvents,
|
|
30
|
+
handleReplyDeletePendingEvents,
|
|
31
|
+
handleReplyDeleteSuccessEvents,
|
|
32
|
+
} from './replyDelete';
|
|
33
|
+
import {
|
|
34
|
+
handleReplyUpdateErrorEvents,
|
|
35
|
+
handleReplyUpdatePendingEvents,
|
|
36
|
+
handleReplyUpdateSuccessEvents,
|
|
37
|
+
} from './replyUpdate';
|
|
16
38
|
import { handleResetCreatorAction, handleSetStagedAction } from './staged';
|
|
17
39
|
import { handleSetStatusAction } from './status';
|
|
18
|
-
import {
|
|
40
|
+
import { handleUpdateErrorEvents, handleUpdatePendingEvents, handleUpdateSuccessEvents } from './update';
|
|
19
41
|
import { resetCreatorAction, setStagedAction, setStatusAction } from '../creator';
|
|
20
42
|
import { toggleAnnotationModeAction } from '../common/actions';
|
|
21
43
|
|
|
22
|
-
|
|
23
|
-
const eventHandlers: EventHandlerMap = {
|
|
44
|
+
export const eventHandlers: EventHandlerMap = {
|
|
24
45
|
[createAnnotationAction.fulfilled.toString()]: handleCreateSuccessEvents,
|
|
25
46
|
[createAnnotationAction.pending.toString()]: handleCreatePendingEvents,
|
|
26
47
|
[createAnnotationAction.rejected.toString()]: handleCreateErrorEvents,
|
|
48
|
+
[createReplyAction.fulfilled.toString()]: handleReplyCreateSuccessEvents,
|
|
49
|
+
[createReplyAction.pending.toString()]: handleReplyCreatePendingEvents,
|
|
50
|
+
[createReplyAction.rejected.toString()]: handleReplyCreateErrorEvents,
|
|
51
|
+
[deleteAnnotationAction.fulfilled.toString()]: handleDeleteSuccessEvents,
|
|
52
|
+
[deleteAnnotationAction.pending.toString()]: handleDeletePendingEvents,
|
|
53
|
+
[deleteAnnotationAction.rejected.toString()]: handleDeleteErrorEvents,
|
|
54
|
+
[deleteReplyAction.fulfilled.toString()]: handleReplyDeleteSuccessEvents,
|
|
55
|
+
[deleteReplyAction.pending.toString()]: handleReplyDeletePendingEvents,
|
|
56
|
+
[deleteReplyAction.rejected.toString()]: handleReplyDeleteErrorEvents,
|
|
27
57
|
[fetchAnnotationsAction.rejected.toString()]: handleFetchErrorEvents,
|
|
28
58
|
[navigateBoundingBoxHighlightAction.toString()]: handleNavigateBoundingBoxHighlight,
|
|
29
59
|
[resetCreatorAction.toString()]: handleResetCreatorAction,
|
|
@@ -32,6 +62,12 @@ const eventHandlers: EventHandlerMap = {
|
|
|
32
62
|
[setStagedAction.toString()]: handleSetStagedAction,
|
|
33
63
|
[setStatusAction.toString()]: handleSetStatusAction,
|
|
34
64
|
[toggleAnnotationModeAction.toString()]: handleToggleAnnotationModeAction,
|
|
65
|
+
[updateAnnotationAction.fulfilled.toString()]: handleUpdateSuccessEvents,
|
|
66
|
+
[updateAnnotationAction.pending.toString()]: handleUpdatePendingEvents,
|
|
67
|
+
[updateAnnotationAction.rejected.toString()]: handleUpdateErrorEvents,
|
|
68
|
+
[updateReplyAction.fulfilled.toString()]: handleReplyUpdateSuccessEvents,
|
|
69
|
+
[updateReplyAction.pending.toString()]: handleReplyUpdatePendingEvents,
|
|
70
|
+
[updateReplyAction.rejected.toString()]: handleReplyUpdateErrorEvents,
|
|
35
71
|
};
|
|
36
72
|
|
|
37
73
|
function getEventingMiddleware(handlers: EventHandlerMap = eventHandlers): Middleware {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { Reply , Event } from '../../@types';
|
|
3
|
+
import { AppState } from '../types';
|
|
4
|
+
import { AsyncAction, Status } from './types';
|
|
5
|
+
|
|
6
|
+
type ReplyCreateArg = { annotationId: string; message: string };
|
|
7
|
+
type ReplyCreatePayload = { annotationId: string; reply: Reply };
|
|
8
|
+
|
|
9
|
+
const emitReplyCreateEvent = (
|
|
10
|
+
action: AsyncAction<ReplyCreateArg, ReplyCreatePayload>,
|
|
11
|
+
status: Status,
|
|
12
|
+
): void => {
|
|
13
|
+
const { error, meta: { arg, requestId } = {}, payload } = action;
|
|
14
|
+
if (status === Status.SUCCESS && !payload?.reply) return;
|
|
15
|
+
const annotationId = payload?.annotationId ?? arg?.annotationId;
|
|
16
|
+
eventManager.emit(Event.ANNOTATION_REPLY_CREATE, {
|
|
17
|
+
annotation: annotationId ? { id: annotationId } : undefined,
|
|
18
|
+
annotationReply: payload?.reply,
|
|
19
|
+
error,
|
|
20
|
+
meta: { requestId, status },
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const replyCreateHandler = (status: Status) => (
|
|
25
|
+
_prev: AppState,
|
|
26
|
+
_next: AppState,
|
|
27
|
+
action: AsyncAction,
|
|
28
|
+
): void => emitReplyCreateEvent(action as AsyncAction<ReplyCreateArg, ReplyCreatePayload>, status);
|
|
29
|
+
|
|
30
|
+
const handleReplyCreateErrorEvents = replyCreateHandler(Status.ERROR);
|
|
31
|
+
const handleReplyCreatePendingEvents = replyCreateHandler(Status.PENDING);
|
|
32
|
+
const handleReplyCreateSuccessEvents = replyCreateHandler(Status.SUCCESS);
|
|
33
|
+
|
|
34
|
+
export { handleReplyCreateErrorEvents, handleReplyCreatePendingEvents, handleReplyCreateSuccessEvents };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { AppState } from '../types';
|
|
3
|
+
import { AsyncAction, Status } from './types';
|
|
4
|
+
import { Event } from '../../@types';
|
|
5
|
+
|
|
6
|
+
type ReplyDeleteArg = { annotationId: string; replyId: string };
|
|
7
|
+
type ReplyDeletePayload = { annotationId: string; replyId: string };
|
|
8
|
+
|
|
9
|
+
const emitReplyDeleteEvent = (
|
|
10
|
+
action: AsyncAction<ReplyDeleteArg, ReplyDeletePayload>,
|
|
11
|
+
status: Status,
|
|
12
|
+
): void => {
|
|
13
|
+
const { error, meta: { arg, requestId } = {}, payload } = action;
|
|
14
|
+
if (status === Status.SUCCESS && !payload) return;
|
|
15
|
+
const annotationId = payload?.annotationId ?? arg?.annotationId;
|
|
16
|
+
const replyId = payload?.replyId ?? arg?.replyId;
|
|
17
|
+
eventManager.emit(Event.ANNOTATION_REPLY_DELETE, {
|
|
18
|
+
annotation: annotationId ? { id: annotationId } : undefined,
|
|
19
|
+
annotationReply: replyId ? { id: replyId } : undefined,
|
|
20
|
+
error,
|
|
21
|
+
meta: { requestId, status },
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const replyDeleteHandler = (status: Status) => (
|
|
26
|
+
_prev: AppState,
|
|
27
|
+
_next: AppState,
|
|
28
|
+
action: AsyncAction,
|
|
29
|
+
): void => emitReplyDeleteEvent(action as AsyncAction<ReplyDeleteArg, ReplyDeletePayload>, status);
|
|
30
|
+
|
|
31
|
+
const handleReplyDeleteErrorEvents = replyDeleteHandler(Status.ERROR);
|
|
32
|
+
const handleReplyDeletePendingEvents = replyDeleteHandler(Status.PENDING);
|
|
33
|
+
const handleReplyDeleteSuccessEvents = replyDeleteHandler(Status.SUCCESS);
|
|
34
|
+
|
|
35
|
+
export { handleReplyDeleteErrorEvents, handleReplyDeletePendingEvents, handleReplyDeleteSuccessEvents };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { Reply , Event } from '../../@types';
|
|
3
|
+
import { AppState } from '../types';
|
|
4
|
+
import { AsyncAction, Status } from './types';
|
|
5
|
+
|
|
6
|
+
type ReplyUpdateArg = {
|
|
7
|
+
annotationId: string;
|
|
8
|
+
replyId: string;
|
|
9
|
+
payload: { message?: string; status?: string };
|
|
10
|
+
};
|
|
11
|
+
type ReplyUpdatePayload = { annotationId: string; reply: Reply };
|
|
12
|
+
|
|
13
|
+
const emitReplyUpdateEvent = (
|
|
14
|
+
action: AsyncAction<ReplyUpdateArg, ReplyUpdatePayload>,
|
|
15
|
+
status: Status,
|
|
16
|
+
): void => {
|
|
17
|
+
const { error, meta: { arg, requestId } = {}, payload } = action;
|
|
18
|
+
if (status === Status.SUCCESS && !payload?.reply) return;
|
|
19
|
+
const annotationId = payload?.annotationId ?? arg?.annotationId;
|
|
20
|
+
const annotationReply = payload?.reply ?? (arg ? { id: arg.replyId } : undefined);
|
|
21
|
+
eventManager.emit(Event.ANNOTATION_REPLY_UPDATE, {
|
|
22
|
+
annotation: annotationId ? { id: annotationId } : undefined,
|
|
23
|
+
annotationReply,
|
|
24
|
+
error,
|
|
25
|
+
meta: { requestId, status },
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const replyUpdateHandler = (status: Status) => (
|
|
30
|
+
_prev: AppState,
|
|
31
|
+
_next: AppState,
|
|
32
|
+
action: AsyncAction,
|
|
33
|
+
): void => emitReplyUpdateEvent(action as AsyncAction<ReplyUpdateArg, ReplyUpdatePayload>, status);
|
|
34
|
+
|
|
35
|
+
const handleReplyUpdateErrorEvents = replyUpdateHandler(Status.ERROR);
|
|
36
|
+
const handleReplyUpdatePendingEvents = replyUpdateHandler(Status.PENDING);
|
|
37
|
+
const handleReplyUpdateSuccessEvents = replyUpdateHandler(Status.SUCCESS);
|
|
38
|
+
|
|
39
|
+
export { handleReplyUpdateErrorEvents, handleReplyUpdatePendingEvents, handleReplyUpdateSuccessEvents };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Action, SerializedError } from '@reduxjs/toolkit';
|
|
2
2
|
import { AppState } from '../types';
|
|
3
|
-
import { Annotation
|
|
3
|
+
import { Annotation } from '../../@types';
|
|
4
4
|
|
|
5
5
|
export enum Status {
|
|
6
6
|
ERROR = 'error',
|
|
@@ -22,10 +22,10 @@ export interface ThunkMeta<M> {
|
|
|
22
22
|
requestId: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export interface AsyncAction extends Action {
|
|
25
|
+
export interface AsyncAction<TArg = unknown, TPayload = unknown> extends Action {
|
|
26
26
|
error?: SerializedError;
|
|
27
|
-
meta?: ThunkMeta<
|
|
28
|
-
payload?:
|
|
27
|
+
meta?: ThunkMeta<TArg>;
|
|
28
|
+
payload?: TPayload;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export type EventHandler = (prevState: AppState, nextState: AppState, action: Action | AsyncAction) => void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import eventManager from '../../common/EventManager';
|
|
2
|
+
import { Annotation , Event } from '../../@types';
|
|
3
|
+
import { AppState } from '../types';
|
|
4
|
+
import { AsyncAction, Status } from './types';
|
|
5
|
+
|
|
6
|
+
type UpdateArg = { annotationId: string; payload: { message?: string; status?: string } };
|
|
7
|
+
|
|
8
|
+
const emitUpdateEvent = (action: AsyncAction<UpdateArg, Annotation>, status: Status): void => {
|
|
9
|
+
const { error, meta: { arg, requestId } = {}, payload } = action;
|
|
10
|
+
if (status === Status.SUCCESS && !payload) return;
|
|
11
|
+
const annotation = payload ?? (arg ? { id: arg.annotationId } : undefined);
|
|
12
|
+
eventManager.emit(Event.ANNOTATION_UPDATE, {
|
|
13
|
+
annotation,
|
|
14
|
+
error,
|
|
15
|
+
meta: { requestId, status },
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const updateHandler = (status: Status) => (
|
|
20
|
+
_prev: AppState,
|
|
21
|
+
_next: AppState,
|
|
22
|
+
action: AsyncAction,
|
|
23
|
+
): void => emitUpdateEvent(action as AsyncAction<UpdateArg, Annotation>, status);
|
|
24
|
+
|
|
25
|
+
const handleUpdateErrorEvents = updateHandler(Status.ERROR);
|
|
26
|
+
const handleUpdatePendingEvents = updateHandler(Status.PENDING);
|
|
27
|
+
const handleUpdateSuccessEvents = updateHandler(Status.SUCCESS);
|
|
28
|
+
|
|
29
|
+
export { handleUpdateErrorEvents, handleUpdatePendingEvents, handleUpdateSuccessEvents };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import getProp from 'lodash/get';
|
|
2
2
|
import { AppState } from '../types';
|
|
3
|
-
import { Permissions } from '../../@types';
|
|
3
|
+
import { Permissions, Token } from '../../@types';
|
|
4
4
|
import { Features } from '../../BoxAnnotations';
|
|
5
5
|
import { ViewMode } from './types';
|
|
6
6
|
|
|
@@ -15,6 +15,6 @@ export const getIsCurrentFileVersion = (state: State): boolean => state.options.
|
|
|
15
15
|
export const getPermissions = (state: State): Permissions => state.options.permissions;
|
|
16
16
|
export const getRotation = (state: State): number => state.options.rotation;
|
|
17
17
|
export const getScale = (state: State): number => state.options.scale;
|
|
18
|
-
export const getToken = (state: State):
|
|
18
|
+
export const getToken = (state: State): Token => state.options.token;
|
|
19
19
|
export const isFeatureEnabled = (state: State, featurename: string): boolean =>
|
|
20
20
|
getProp(getFeatures(state), featurename, false);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Features } from '../../BoxAnnotations';
|
|
2
|
-
import { Permissions } from '../../@types';
|
|
2
|
+
import { Permissions, Token } from '../../@types';
|
|
3
3
|
|
|
4
4
|
/** View mode: annotations and bounding boxes are mutually exclusive. */
|
|
5
5
|
export type ViewMode = 'annotations' | 'boundingBoxes';
|
|
@@ -13,6 +13,6 @@ export type OptionsState = {
|
|
|
13
13
|
permissions: Permissions;
|
|
14
14
|
rotation: number;
|
|
15
15
|
scale: number;
|
|
16
|
-
token:
|
|
16
|
+
token: Token;
|
|
17
17
|
viewMode: ViewMode;
|
|
18
18
|
};
|