box-ui-elements 23.4.0-beta.14 → 23.4.0-beta.16
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/explorer.js +1 -1
- package/dist/picker.js +1 -1
- package/dist/preview.js +1 -1
- package/dist/preview.js.LICENSE.txt +10 -0
- package/dist/sharing.js +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/sidebar.js.LICENSE.txt +10 -0
- package/dist/uploader.js +1 -1
- package/es/api/Metadata.js +0 -1
- package/es/api/Metadata.js.flow +1 -1
- package/es/api/Metadata.js.map +1 -1
- package/es/elements/common/annotator-context/types.js.flow +2 -2
- package/es/elements/common/annotator-context/types.js.map +1 -1
- package/es/elements/common/annotator-context/withAnnotations.js +29 -10
- package/es/elements/common/annotator-context/withAnnotations.js.flow +10 -3
- package/es/elements/common/annotator-context/withAnnotations.js.map +1 -1
- package/es/elements/common/annotator-context/withAnnotatorContext.js +47 -23
- package/es/elements/common/annotator-context/withAnnotatorContext.js.flow +1 -0
- package/es/elements/common/annotator-context/withAnnotatorContext.js.map +1 -1
- package/es/elements/common/types/SidebarNavigation.flow.js +14 -0
- package/es/elements/common/types/SidebarNavigation.flow.js.flow +52 -0
- package/es/elements/common/types/SidebarNavigation.flow.js.map +1 -0
- package/es/elements/common/types/SidebarNavigation.js +16 -0
- package/es/elements/common/types/SidebarNavigation.js.map +1 -0
- package/es/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.js +4 -13
- package/es/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.js.map +1 -1
- package/es/src/elements/common/annotator-context/types.d.ts +2 -2
- package/es/src/elements/common/annotator-context/withAnnotations.d.ts +5 -0
- package/es/src/elements/common/annotator-context/withAnnotatorContext.d.ts +4 -1
- package/es/src/elements/common/types/SidebarNavigation.d.ts +37 -0
- package/package.json +35 -37
- package/src/api/Metadata.js +1 -1
- package/src/elements/common/annotator-context/__tests__/withAnnotations.test.tsx +46 -0
- package/src/elements/common/annotator-context/__tests__/withAnnotatorContext.test.tsx +116 -20
- package/src/elements/common/annotator-context/types.js.flow +2 -2
- package/src/elements/common/annotator-context/types.ts +2 -2
- package/src/elements/common/annotator-context/withAnnotations.js.flow +10 -3
- package/src/elements/common/annotator-context/withAnnotations.tsx +35 -6
- package/src/elements/common/annotator-context/withAnnotatorContext.js.flow +1 -0
- package/src/elements/common/annotator-context/withAnnotatorContext.tsx +61 -29
- package/src/elements/common/types/SidebarNavigation.flow.js +52 -0
- package/src/elements/common/types/SidebarNavigation.ts +47 -0
- package/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx +5 -13
- package/i18n.config.js +0 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { render } from '../../../../test-utils/testing-library';
|
|
3
3
|
import withAnnotatorContext, { WithAnnotatorContextProps } from '../withAnnotatorContext';
|
|
4
4
|
import { Action } from '../types';
|
|
5
5
|
|
|
@@ -13,18 +13,59 @@ describe('elements/common/annotator-context/withAnnotatorContext', () => {
|
|
|
13
13
|
className?: string | undefined;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
type WrappedComponentProps<T> = ComponentProps & WithAnnotatorContextProps; // T is supposed to be allowed component props
|
|
16
|
+
type WrappedComponentProps = ComponentProps & WithAnnotatorContextProps;
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
beforeEach(() => jest.resetAllMocks());
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
test('should apply the annotator context to the wrapped component as a prop', () => {
|
|
21
|
+
const annotatorState = {
|
|
22
|
+
annotation: { foo: 'bar' },
|
|
23
|
+
action: Action.CREATE_START,
|
|
24
|
+
};
|
|
25
|
+
const mockEmitActiveAnnotationChangeEvent = jest.fn();
|
|
26
|
+
const mockEmitAnnotationRemoveEvent = jest.fn();
|
|
27
|
+
const mockEmitAnnotationReplyCreateEvent = jest.fn();
|
|
28
|
+
const mockEmitAnnotationReplyDeleteEvent = jest.fn();
|
|
29
|
+
const mockMmitAnnotationReplyUpdateEvent = jest.fn();
|
|
30
|
+
const mockEmitAnnotationUpdateEvent = jest.fn();
|
|
31
|
+
const mockGetAnnotationsMatchPath = jest.fn();
|
|
32
|
+
const mockGetAnnotationsPath = jest.fn();
|
|
22
33
|
|
|
23
|
-
|
|
34
|
+
mockContext.mockReturnValue({
|
|
35
|
+
state: annotatorState,
|
|
36
|
+
emitActiveAnnotationChangeEvent: mockEmitActiveAnnotationChangeEvent,
|
|
37
|
+
emitAnnotationRemoveEvent: mockEmitAnnotationRemoveEvent,
|
|
38
|
+
emitAnnotationReplyCreateEvent: mockEmitAnnotationReplyCreateEvent,
|
|
39
|
+
emitAnnotationReplyDeleteEvent: mockEmitAnnotationReplyDeleteEvent,
|
|
40
|
+
emitAnnotationReplyUpdateEvent: mockMmitAnnotationReplyUpdateEvent,
|
|
41
|
+
emitAnnotationUpdateEvent: mockEmitAnnotationUpdateEvent,
|
|
42
|
+
getAnnotationsMatchPath: mockGetAnnotationsMatchPath,
|
|
43
|
+
getAnnotationsPath: mockGetAnnotationsPath,
|
|
44
|
+
});
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
const MockComponent = jest.fn<JSX.Element | null, [WrappedComponentProps]>(() => null);
|
|
47
|
+
const WrappedWithMockComponent = withAnnotatorContext(MockComponent);
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
render(<WrappedWithMockComponent />);
|
|
50
|
+
|
|
51
|
+
expect(MockComponent).toHaveBeenCalledTimes(1);
|
|
52
|
+
const props = MockComponent.mock.calls[0][0];
|
|
53
|
+
|
|
54
|
+
expect(props.annotatorState).toEqual({
|
|
55
|
+
annotation: { foo: 'bar' },
|
|
56
|
+
action: Action.CREATE_START,
|
|
57
|
+
});
|
|
58
|
+
expect(props.emitActiveAnnotationChangeEvent).toBe(mockEmitActiveAnnotationChangeEvent);
|
|
59
|
+
expect(props.emitAnnotationRemoveEvent).toBe(mockEmitAnnotationRemoveEvent);
|
|
60
|
+
expect(props.emitAnnotationReplyCreateEvent).toBe(mockEmitAnnotationReplyCreateEvent);
|
|
61
|
+
expect(props.emitAnnotationReplyDeleteEvent).toBe(mockEmitAnnotationReplyDeleteEvent);
|
|
62
|
+
expect(props.emitAnnotationReplyUpdateEvent).toBe(mockMmitAnnotationReplyUpdateEvent);
|
|
63
|
+
expect(props.emitAnnotationUpdateEvent).toBe(mockEmitAnnotationUpdateEvent);
|
|
64
|
+
expect(props.getAnnotationsMatchPath).toBe(mockGetAnnotationsMatchPath);
|
|
65
|
+
expect(props.getAnnotationsPath).toBe(mockGetAnnotationsPath);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('should apply the annotator context to the wrapped component without router props when routerDisabled is true', () => {
|
|
28
69
|
const annotatorState = {
|
|
29
70
|
annotation: { foo: 'bar' },
|
|
30
71
|
action: Action.CREATE_START,
|
|
@@ -50,22 +91,77 @@ describe('elements/common/annotator-context/withAnnotatorContext', () => {
|
|
|
50
91
|
getAnnotationsPath: mockGetAnnotationsPath,
|
|
51
92
|
});
|
|
52
93
|
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
94
|
+
const MockComponent = jest.fn<JSX.Element | null, [WrappedComponentProps]>(() => null);
|
|
95
|
+
const WrappedWithMockComponent = withAnnotatorContext(MockComponent);
|
|
96
|
+
|
|
97
|
+
render(<WrappedWithMockComponent routerDisabled={true} />);
|
|
98
|
+
|
|
99
|
+
expect(MockComponent).toHaveBeenCalledTimes(1);
|
|
100
|
+
const props = MockComponent.mock.calls[0][0];
|
|
56
101
|
|
|
57
|
-
expect(wrappedComponent.exists()).toBeTruthy();
|
|
58
102
|
expect(props.annotatorState).toEqual({
|
|
59
103
|
annotation: { foo: 'bar' },
|
|
60
104
|
action: Action.CREATE_START,
|
|
61
105
|
});
|
|
62
|
-
expect(props.emitActiveAnnotationChangeEvent).
|
|
63
|
-
expect(props.emitAnnotationRemoveEvent).
|
|
64
|
-
expect(props.emitAnnotationReplyCreateEvent).
|
|
65
|
-
expect(props.emitAnnotationReplyDeleteEvent).
|
|
66
|
-
expect(props.emitAnnotationReplyUpdateEvent).
|
|
67
|
-
expect(props.emitAnnotationUpdateEvent).
|
|
68
|
-
|
|
69
|
-
|
|
106
|
+
expect(props.emitActiveAnnotationChangeEvent).toBe(mockEmitActiveAnnotationChangeEvent);
|
|
107
|
+
expect(props.emitAnnotationRemoveEvent).toBe(mockEmitAnnotationRemoveEvent);
|
|
108
|
+
expect(props.emitAnnotationReplyCreateEvent).toBe(mockEmitAnnotationReplyCreateEvent);
|
|
109
|
+
expect(props.emitAnnotationReplyDeleteEvent).toBe(mockEmitAnnotationReplyDeleteEvent);
|
|
110
|
+
expect(props.emitAnnotationReplyUpdateEvent).toBe(mockMmitAnnotationReplyUpdateEvent);
|
|
111
|
+
expect(props.emitAnnotationUpdateEvent).toBe(mockEmitAnnotationUpdateEvent);
|
|
112
|
+
|
|
113
|
+
// Router-related props should not be passed when routerDisabled is true
|
|
114
|
+
expect(props.getAnnotationsMatchPath).toBeUndefined();
|
|
115
|
+
expect(props.getAnnotationsPath).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('should apply the annotator context to the wrapped component without router props when routerDisabled in feature flags is true', () => {
|
|
119
|
+
const annotatorState = {
|
|
120
|
+
annotation: { foo: 'bar' },
|
|
121
|
+
action: Action.CREATE_START,
|
|
122
|
+
};
|
|
123
|
+
const mockEmitActiveAnnotationChangeEvent = jest.fn();
|
|
124
|
+
const mockEmitAnnotationRemoveEvent = jest.fn();
|
|
125
|
+
const mockEmitAnnotationReplyCreateEvent = jest.fn();
|
|
126
|
+
const mockEmitAnnotationReplyDeleteEvent = jest.fn();
|
|
127
|
+
const mockMmitAnnotationReplyUpdateEvent = jest.fn();
|
|
128
|
+
const mockEmitAnnotationUpdateEvent = jest.fn();
|
|
129
|
+
const mockGetAnnotationsMatchPath = jest.fn();
|
|
130
|
+
const mockGetAnnotationsPath = jest.fn();
|
|
131
|
+
|
|
132
|
+
mockContext.mockReturnValue({
|
|
133
|
+
state: annotatorState,
|
|
134
|
+
emitActiveAnnotationChangeEvent: mockEmitActiveAnnotationChangeEvent,
|
|
135
|
+
emitAnnotationRemoveEvent: mockEmitAnnotationRemoveEvent,
|
|
136
|
+
emitAnnotationReplyCreateEvent: mockEmitAnnotationReplyCreateEvent,
|
|
137
|
+
emitAnnotationReplyDeleteEvent: mockEmitAnnotationReplyDeleteEvent,
|
|
138
|
+
emitAnnotationReplyUpdateEvent: mockMmitAnnotationReplyUpdateEvent,
|
|
139
|
+
emitAnnotationUpdateEvent: mockEmitAnnotationUpdateEvent,
|
|
140
|
+
getAnnotationsMatchPath: mockGetAnnotationsMatchPath,
|
|
141
|
+
getAnnotationsPath: mockGetAnnotationsPath,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const MockComponent = jest.fn<JSX.Element | null, [WrappedComponentProps]>(() => null);
|
|
145
|
+
const WrappedWithMockComponent = withAnnotatorContext(MockComponent);
|
|
146
|
+
|
|
147
|
+
render(<WrappedWithMockComponent features={{ routerDisabled: { value: true } }} />);
|
|
148
|
+
|
|
149
|
+
expect(MockComponent).toHaveBeenCalledTimes(1);
|
|
150
|
+
const props = MockComponent.mock.calls[0][0];
|
|
151
|
+
|
|
152
|
+
expect(props.annotatorState).toEqual({
|
|
153
|
+
annotation: { foo: 'bar' },
|
|
154
|
+
action: Action.CREATE_START,
|
|
155
|
+
});
|
|
156
|
+
expect(props.emitActiveAnnotationChangeEvent).toBe(mockEmitActiveAnnotationChangeEvent);
|
|
157
|
+
expect(props.emitAnnotationRemoveEvent).toBe(mockEmitAnnotationRemoveEvent);
|
|
158
|
+
expect(props.emitAnnotationReplyCreateEvent).toBe(mockEmitAnnotationReplyCreateEvent);
|
|
159
|
+
expect(props.emitAnnotationReplyDeleteEvent).toBe(mockEmitAnnotationReplyDeleteEvent);
|
|
160
|
+
expect(props.emitAnnotationReplyUpdateEvent).toBe(mockMmitAnnotationReplyUpdateEvent);
|
|
161
|
+
expect(props.emitAnnotationUpdateEvent).toBe(mockEmitAnnotationUpdateEvent);
|
|
162
|
+
|
|
163
|
+
// Router-related props should not be passed when routerDisabled is true
|
|
164
|
+
expect(props.getAnnotationsMatchPath).toBeUndefined();
|
|
165
|
+
expect(props.getAnnotationsPath).toBeUndefined();
|
|
70
166
|
});
|
|
71
167
|
});
|
|
@@ -74,8 +74,8 @@ export interface AnnotatorContext {
|
|
|
74
74
|
annotation: Object,
|
|
75
75
|
isStartEvent?: boolean
|
|
76
76
|
) => void;
|
|
77
|
-
getAnnotationsMatchPath
|
|
78
|
-
getAnnotationsPath
|
|
77
|
+
getAnnotationsMatchPath?: GetMatchPath;
|
|
78
|
+
getAnnotationsPath?: (fileVersionId?: string, annotationId?: string) => string;
|
|
79
79
|
state: AnnotatorState;
|
|
80
80
|
}
|
|
81
81
|
declare export var Status: {|
|
|
@@ -53,8 +53,8 @@ export interface AnnotatorContext {
|
|
|
53
53
|
emitAnnotationReplyDeleteEvent?: (id: string, annotationId: string, isStartEvent?: boolean) => void;
|
|
54
54
|
emitAnnotationReplyUpdateEvent?: (reply: Object, annotationId: string, isStartEvent?: boolean) => void;
|
|
55
55
|
emitAnnotationUpdateEvent?: (annotation: Object, isStartEvent?: boolean) => void;
|
|
56
|
-
getAnnotationsMatchPath
|
|
57
|
-
getAnnotationsPath
|
|
56
|
+
getAnnotationsMatchPath?: GetMatchPath;
|
|
57
|
+
getAnnotationsPath?: (fileVersionId?: string, annotationId?: string) => string;
|
|
58
58
|
state: AnnotatorState;
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -18,6 +18,10 @@ import {
|
|
|
18
18
|
MatchParams,
|
|
19
19
|
Status
|
|
20
20
|
} from "./types";
|
|
21
|
+
import { SidebarNavigation } from '../types/SidebarNavigation';
|
|
22
|
+
import { type FeatureConfig } from '../feature-checking';
|
|
23
|
+
|
|
24
|
+
|
|
21
25
|
export type ActiveChangeEvent = {
|
|
22
26
|
annotationId: string | null,
|
|
23
27
|
fileVersionId: string,
|
|
@@ -48,11 +52,11 @@ export type ComponentWithAnnotations = {
|
|
|
48
52
|
isStartEvent?: boolean
|
|
49
53
|
) => void,
|
|
50
54
|
getAction: (eventData: AnnotationActionEvent) => Action,
|
|
51
|
-
getAnnotationsPath
|
|
55
|
+
getAnnotationsPath?: (
|
|
52
56
|
fileVersionId?: string,
|
|
53
57
|
annotationId?: string | null
|
|
54
58
|
) => string,
|
|
55
|
-
getMatchPath
|
|
59
|
+
getMatchPath?: GetMatchPath,
|
|
56
60
|
handleActiveChange: ActiveChangeEventHandler,
|
|
57
61
|
handleAnnotationChangeEvent: (id: string | null) => void,
|
|
58
62
|
handleAnnotationCreate: (eventData: AnnotationActionEvent) => void,
|
|
@@ -70,6 +74,7 @@ export type ComponentWithAnnotations = {
|
|
|
70
74
|
...
|
|
71
75
|
};
|
|
72
76
|
export type WithAnnotationsProps = {
|
|
77
|
+
features?: FeatureConfig;
|
|
73
78
|
location?: Location,
|
|
74
79
|
onAnnotator: (annotator: Annotator) => void,
|
|
75
80
|
onError?: (
|
|
@@ -78,7 +83,9 @@ export type WithAnnotationsProps = {
|
|
|
78
83
|
contextInfo?: { [key: string]: mixed, ... }
|
|
79
84
|
) => void,
|
|
80
85
|
onPreviewDestroy: (shouldReset?: boolean) => void,
|
|
81
|
-
|
|
86
|
+
routerDisabled?: boolean;
|
|
87
|
+
sidebarNavigation?: SidebarNavigation;
|
|
88
|
+
...
|
|
82
89
|
};
|
|
83
90
|
export type WithAnnotationsComponent<P> = React.ComponentClass<
|
|
84
91
|
P & WithAnnotationsProps
|
|
@@ -3,7 +3,9 @@ import getProp from 'lodash/get';
|
|
|
3
3
|
import { generatePath, match as matchType, matchPath } from 'react-router-dom';
|
|
4
4
|
import { Location } from 'history';
|
|
5
5
|
import AnnotatorContext from './AnnotatorContext';
|
|
6
|
+
import { isFeatureEnabled, type FeatureConfig } from '../feature-checking';
|
|
6
7
|
import { Action, Annotator, AnnotationActionEvent, AnnotatorState, GetMatchPath, MatchParams, Status } from './types';
|
|
8
|
+
import { FeedEntryType, SidebarNavigation } from '../types/SidebarNavigation';
|
|
7
9
|
|
|
8
10
|
export type ActiveChangeEvent = {
|
|
9
11
|
annotationId: string | null;
|
|
@@ -41,10 +43,13 @@ export type ComponentWithAnnotations = {
|
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
export type WithAnnotationsProps = {
|
|
46
|
+
features?: FeatureConfig;
|
|
44
47
|
location?: Location;
|
|
45
48
|
onAnnotator: (annotator: Annotator) => void;
|
|
46
49
|
onError?: (error: Error, code: string, contextInfo?: Record<string, unknown>) => void;
|
|
47
50
|
onPreviewDestroy: (shouldReset?: boolean) => void;
|
|
51
|
+
routerDisabled?: boolean;
|
|
52
|
+
sidebarNavigation?: SidebarNavigation;
|
|
48
53
|
};
|
|
49
54
|
|
|
50
55
|
export type WithAnnotationsComponent<P> = React.ComponentClass<P & WithAnnotationsProps>;
|
|
@@ -71,10 +76,26 @@ export default function withAnnotations<P extends object>(
|
|
|
71
76
|
constructor(props: P & WithAnnotationsProps) {
|
|
72
77
|
super(props);
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
79
|
+
const { routerDisabled, sidebarNavigation } = props;
|
|
80
|
+
let activeAnnotationId = null;
|
|
81
|
+
|
|
82
|
+
const isRouterDisabled = routerDisabled || isFeatureEnabled(props?.features, 'routerDisabled.value');
|
|
83
|
+
|
|
84
|
+
if (isRouterDisabled) {
|
|
85
|
+
if (
|
|
86
|
+
sidebarNavigation &&
|
|
87
|
+
'activeFeedEntryType' in sidebarNavigation &&
|
|
88
|
+
sidebarNavigation.activeFeedEntryType === FeedEntryType.ANNOTATIONS &&
|
|
89
|
+
'activeFeedEntryId' in sidebarNavigation
|
|
90
|
+
) {
|
|
91
|
+
activeAnnotationId = sidebarNavigation.activeFeedEntryId;
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
// Determine by url if there is already a deeply linked annotation
|
|
95
|
+
const { location } = props;
|
|
96
|
+
const match = this.getMatchPath(location);
|
|
97
|
+
activeAnnotationId = getProp(match, 'params.annotationId', null);
|
|
98
|
+
}
|
|
78
99
|
|
|
79
100
|
// Seed the initial state with the activeAnnotationId if any from the location path
|
|
80
101
|
this.state = { ...defaultState, activeAnnotationId };
|
|
@@ -192,6 +213,7 @@ export default function withAnnotations<P extends object>(
|
|
|
192
213
|
});
|
|
193
214
|
}
|
|
194
215
|
|
|
216
|
+
// remove this method with routerDisabled switch
|
|
195
217
|
getMatchPath(location?: Location): matchType<MatchParams> | null {
|
|
196
218
|
const pathname = getProp(location, 'pathname', '');
|
|
197
219
|
return matchPath<MatchParams>(pathname, {
|
|
@@ -319,6 +341,14 @@ export default function withAnnotations<P extends object>(
|
|
|
319
341
|
};
|
|
320
342
|
|
|
321
343
|
render(): JSX.Element {
|
|
344
|
+
const isRouterDisabled =
|
|
345
|
+
this.props?.routerDisabled || isFeatureEnabled(this.props?.features, 'routerDisabled.value');
|
|
346
|
+
const annotationsRouterProps = isRouterDisabled
|
|
347
|
+
? {}
|
|
348
|
+
: {
|
|
349
|
+
getAnnotationsMatchPath: this.getMatchPath,
|
|
350
|
+
getAnnotationsPath: this.getAnnotationsPath,
|
|
351
|
+
};
|
|
322
352
|
return (
|
|
323
353
|
<AnnotatorContext.Provider
|
|
324
354
|
value={{
|
|
@@ -328,8 +358,7 @@ export default function withAnnotations<P extends object>(
|
|
|
328
358
|
emitAnnotationReplyDeleteEvent: this.emitAnnotationReplyDeleteEvent,
|
|
329
359
|
emitAnnotationReplyUpdateEvent: this.emitAnnotationReplyUpdateEvent,
|
|
330
360
|
emitAnnotationUpdateEvent: this.emitAnnotationUpdateEvent,
|
|
331
|
-
|
|
332
|
-
getAnnotationsPath: this.getAnnotationsPath,
|
|
361
|
+
...annotationsRouterProps,
|
|
333
362
|
state: this.state,
|
|
334
363
|
}}
|
|
335
364
|
>
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import AnnotatorContext from "./AnnotatorContext";
|
|
9
9
|
import { AnnotatorState, GetMatchPath } from "./types";
|
|
10
|
+
|
|
10
11
|
export interface WithAnnotatorContextProps {
|
|
11
12
|
annotatorState?: AnnotatorState;
|
|
12
13
|
emitActiveAnnotationChangeEvent?: (id: string) => void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import AnnotatorContext from './AnnotatorContext';
|
|
3
|
+
import { isFeatureEnabled, type FeatureConfig } from '../feature-checking';
|
|
3
4
|
import { AnnotatorState, GetMatchPath } from './types';
|
|
4
5
|
|
|
5
6
|
export interface WithAnnotatorContextProps {
|
|
@@ -20,33 +21,64 @@ export interface WithAnnotatorContextProps {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export default function withAnnotatorContext<P extends {}>(WrappedComponent: React.ComponentType<P>) {
|
|
23
|
-
return React.forwardRef<React.ComponentType<P>, P
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
24
|
+
return React.forwardRef<React.ComponentType<P>, P & { routerDisabled?: boolean; features?: FeatureConfig }>(
|
|
25
|
+
(props, ref) => {
|
|
26
|
+
if (props?.routerDisabled === true || isFeatureEnabled(props?.features, 'routerDisabled.value')) {
|
|
27
|
+
return (
|
|
28
|
+
<AnnotatorContext.Consumer>
|
|
29
|
+
{({
|
|
30
|
+
emitActiveAnnotationChangeEvent,
|
|
31
|
+
emitAnnotationRemoveEvent,
|
|
32
|
+
emitAnnotationReplyCreateEvent,
|
|
33
|
+
emitAnnotationReplyDeleteEvent,
|
|
34
|
+
emitAnnotationReplyUpdateEvent,
|
|
35
|
+
emitAnnotationUpdateEvent,
|
|
36
|
+
state,
|
|
37
|
+
}) => (
|
|
38
|
+
<WrappedComponent
|
|
39
|
+
ref={ref}
|
|
40
|
+
{...props}
|
|
41
|
+
annotatorState={state}
|
|
42
|
+
emitActiveAnnotationChangeEvent={emitActiveAnnotationChangeEvent}
|
|
43
|
+
emitAnnotationRemoveEvent={emitAnnotationRemoveEvent}
|
|
44
|
+
emitAnnotationReplyCreateEvent={emitAnnotationReplyCreateEvent}
|
|
45
|
+
emitAnnotationReplyDeleteEvent={emitAnnotationReplyDeleteEvent}
|
|
46
|
+
emitAnnotationReplyUpdateEvent={emitAnnotationReplyUpdateEvent}
|
|
47
|
+
emitAnnotationUpdateEvent={emitAnnotationUpdateEvent}
|
|
48
|
+
/>
|
|
49
|
+
)}
|
|
50
|
+
</AnnotatorContext.Consumer>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return (
|
|
54
|
+
<AnnotatorContext.Consumer>
|
|
55
|
+
{({
|
|
56
|
+
emitActiveAnnotationChangeEvent,
|
|
57
|
+
emitAnnotationRemoveEvent,
|
|
58
|
+
emitAnnotationReplyCreateEvent,
|
|
59
|
+
emitAnnotationReplyDeleteEvent,
|
|
60
|
+
emitAnnotationReplyUpdateEvent,
|
|
61
|
+
emitAnnotationUpdateEvent,
|
|
62
|
+
getAnnotationsMatchPath,
|
|
63
|
+
getAnnotationsPath,
|
|
64
|
+
state,
|
|
65
|
+
}) => (
|
|
66
|
+
<WrappedComponent
|
|
67
|
+
ref={ref}
|
|
68
|
+
{...props}
|
|
69
|
+
annotatorState={state}
|
|
70
|
+
emitActiveAnnotationChangeEvent={emitActiveAnnotationChangeEvent}
|
|
71
|
+
emitAnnotationRemoveEvent={emitAnnotationRemoveEvent}
|
|
72
|
+
emitAnnotationReplyCreateEvent={emitAnnotationReplyCreateEvent}
|
|
73
|
+
emitAnnotationReplyDeleteEvent={emitAnnotationReplyDeleteEvent}
|
|
74
|
+
emitAnnotationReplyUpdateEvent={emitAnnotationReplyUpdateEvent}
|
|
75
|
+
emitAnnotationUpdateEvent={emitAnnotationUpdateEvent}
|
|
76
|
+
getAnnotationsMatchPath={getAnnotationsMatchPath}
|
|
77
|
+
getAnnotationsPath={getAnnotationsPath}
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
80
|
+
</AnnotatorContext.Consumer>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
);
|
|
52
84
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
export const ViewType = Object.freeze({
|
|
4
|
+
BOXAI: 'boxai',
|
|
5
|
+
SKILLS: 'skills',
|
|
6
|
+
ACTIVITY: 'activity',
|
|
7
|
+
DETAILS: 'details',
|
|
8
|
+
METADATA: 'metadata',
|
|
9
|
+
DOCGEN: 'docgen',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const FeedEntryType = Object.freeze({
|
|
13
|
+
ANNOTATIONS: 'annotations',
|
|
14
|
+
COMMENTS: 'comments',
|
|
15
|
+
TASKS: 'tasks',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export type ViewTypeValues = $Values<typeof ViewType>;
|
|
19
|
+
export type FeedEntryTypeValues = $Values<typeof FeedEntryType>;
|
|
20
|
+
|
|
21
|
+
type VersionSidebarView = {
|
|
22
|
+
sidebar: 'activity' | 'details',
|
|
23
|
+
versionId: string,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type ActivityAnnotationsSidebarView = {
|
|
27
|
+
sidebar: 'activity',
|
|
28
|
+
activeFeedEntryType: 'annotations',
|
|
29
|
+
fileVersionId: string,
|
|
30
|
+
activeFeedEntryId: string,
|
|
31
|
+
};
|
|
32
|
+
type ActivityCommentsSidebarView = {
|
|
33
|
+
sidebar: 'activity',
|
|
34
|
+
activeFeedEntryType: 'comments' | 'tasks',
|
|
35
|
+
activeFeedEntryId: string,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type SidebarNavigation =
|
|
39
|
+
| {|
|
|
40
|
+
sidebar: ViewTypeValues,
|
|
41
|
+
|}
|
|
42
|
+
| VersionSidebarView
|
|
43
|
+
| ActivityCommentsSidebarView
|
|
44
|
+
| ActivityAnnotationsSidebarView;
|
|
45
|
+
|
|
46
|
+
export type InternalSidebarNavigation = SidebarNavigation & {
|
|
47
|
+
open: boolean,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type SidebarNavigationHandler = (sidebar: SidebarNavigation, replace?: boolean) => void;
|
|
51
|
+
|
|
52
|
+
export type InternalSidebarNavigationHandler = (sidebar: InternalSidebarNavigation, replace?: boolean) => void;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export enum ViewType {
|
|
2
|
+
BOXAI = 'boxai',
|
|
3
|
+
SKILLS = 'skills',
|
|
4
|
+
ACTIVITY = 'activity',
|
|
5
|
+
DETAILS = 'details',
|
|
6
|
+
METADATA = 'metadata',
|
|
7
|
+
DOCGEN = 'docgen',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export enum FeedEntryType {
|
|
11
|
+
ANNOTATIONS = 'annotations',
|
|
12
|
+
COMMENTS = 'comments',
|
|
13
|
+
TASKS = 'tasks',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type VersionSidebarView = {
|
|
17
|
+
sidebar: ViewType.ACTIVITY | ViewType.DETAILS;
|
|
18
|
+
versionId: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type ActivityAnnotationsSidebarView = {
|
|
22
|
+
sidebar: ViewType.ACTIVITY;
|
|
23
|
+
activeFeedEntryType: FeedEntryType.ANNOTATIONS;
|
|
24
|
+
fileVersionId: string;
|
|
25
|
+
activeFeedEntryId: string;
|
|
26
|
+
};
|
|
27
|
+
type ActivityCommentsSidebarView = {
|
|
28
|
+
sidebar: ViewType.ACTIVITY;
|
|
29
|
+
activeFeedEntryType: FeedEntryType.COMMENTS | FeedEntryType.TASKS;
|
|
30
|
+
activeFeedEntryId: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type SidebarNavigation =
|
|
34
|
+
| {
|
|
35
|
+
sidebar: ViewType;
|
|
36
|
+
}
|
|
37
|
+
| VersionSidebarView
|
|
38
|
+
| ActivityCommentsSidebarView
|
|
39
|
+
| ActivityAnnotationsSidebarView;
|
|
40
|
+
|
|
41
|
+
export type InternalSidebarNavigation = SidebarNavigation & {
|
|
42
|
+
open: boolean;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type SidebarNavigationHandler = (sidebar: SidebarNavigation, replace?: boolean) => void;
|
|
46
|
+
|
|
47
|
+
export type InternalSidebarNavigationHandler = (sidebar: InternalSidebarNavigation, replace?: boolean) => void;
|
package/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ComponentProps } from 'react';
|
|
2
2
|
import { http, HttpResponse } from 'msw';
|
|
3
3
|
import { expect, userEvent, waitFor, within, fn, screen } from '@storybook/test';
|
|
4
4
|
import { type StoryObj, Meta } from '@storybook/react';
|
|
@@ -239,14 +239,10 @@ export const MetadataInstanceEditorWithCustomTemplate: StoryObj<typeof MetadataS
|
|
|
239
239
|
const canvas = within(canvasElement);
|
|
240
240
|
|
|
241
241
|
const addTemplateButton = await canvas.findByRole('button', { name: 'Add template' }, { timeout: 2000 });
|
|
242
|
-
await
|
|
243
|
-
await userEvent.click(addTemplateButton);
|
|
244
|
-
});
|
|
242
|
+
await userEvent.click(addTemplateButton);
|
|
245
243
|
|
|
246
244
|
const customMetadataOption = canvas.getByRole('option', { name: 'Custom Metadata' });
|
|
247
|
-
await
|
|
248
|
-
await userEvent.click(customMetadataOption);
|
|
249
|
-
});
|
|
245
|
+
await userEvent.click(customMetadataOption);
|
|
250
246
|
},
|
|
251
247
|
};
|
|
252
248
|
|
|
@@ -289,15 +285,11 @@ export const DeleteButtonIsDisabledWhenAddingNewMetadataTemplate: StoryObj<typeo
|
|
|
289
285
|
|
|
290
286
|
const addTemplateButton = await canvas.findByRole('button', { name: 'Add template' });
|
|
291
287
|
expect(addTemplateButton).toBeInTheDocument();
|
|
292
|
-
await
|
|
293
|
-
await userEvent.click(addTemplateButton);
|
|
294
|
-
});
|
|
288
|
+
await userEvent.click(addTemplateButton);
|
|
295
289
|
|
|
296
290
|
const customMetadataOption = canvas.getByRole('option', { name: 'Virus Scan' });
|
|
297
291
|
expect(customMetadataOption).toBeInTheDocument();
|
|
298
|
-
await
|
|
299
|
-
await userEvent.click(customMetadataOption);
|
|
300
|
-
});
|
|
292
|
+
await userEvent.click(customMetadataOption);
|
|
301
293
|
|
|
302
294
|
const deleteButton = await canvas.findByRole('button', { name: 'Delete' });
|
|
303
295
|
expect(deleteButton).toBeDisabled();
|