box-annotations 5.3.1-beta.1 → 5.3.1-beta.2
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/i18n/ja-JP.js +24 -1
- package/package.json +4 -4
- package/src/api/types.ts +5 -0
- package/src/components/ReplyForm/ReplyFormContainer.tsx +7 -4
- package/src/store/annotations/actions.ts +30 -6
- package/src/store/options/selectors.ts +5 -0
package/i18n/ja-JP.js
CHANGED
|
@@ -1,2 +1,25 @@
|
|
|
1
1
|
// THIS IS A GENERATED FILE. DO NOT EDIT MANUALLY OR YOUR CHANGES WILL BE OVERWRITTEN
|
|
2
|
-
export default {
|
|
2
|
+
export default {
|
|
3
|
+
"ba.annotationsClose": "閉じる",
|
|
4
|
+
"ba.annotationsCreateError": "注釈を作成できませんでした。",
|
|
5
|
+
"ba.annotationsLoadError": "このファイルの注釈を読み込めませんでした。",
|
|
6
|
+
"ba.annotationsPost": "投稿",
|
|
7
|
+
"ba.annotationsSave": "保存",
|
|
8
|
+
"ba.boundingBoxHighlight.viewNextReference": "次の参照を表示",
|
|
9
|
+
"ba.boundingBoxHighlight.viewPrevReference": "前の参照を表示",
|
|
10
|
+
"ba.popup.reply.comment": "コメント",
|
|
11
|
+
"ba.popup.reply.field": "コメントを入力する",
|
|
12
|
+
"ba.popup.reply.mentionLoading": "ユーザーを読み込み中…",
|
|
13
|
+
"ba.popup.reply.mentionSelector": "コラボレータにコメントする",
|
|
14
|
+
"ba.popups.cancel": "キャンセル",
|
|
15
|
+
"ba.popups.drawing.addComment": "コメントを追加",
|
|
16
|
+
"ba.popups.drawing.delete": "削除",
|
|
17
|
+
"ba.popups.drawing.redo": "やり直す",
|
|
18
|
+
"ba.popups.drawing.undo": "元に戻す",
|
|
19
|
+
"ba.popups.popupCursor.regionPrompt": "四角を描いてコメントする",
|
|
20
|
+
"ba.popups.popupHighlight.promoter": "ハイライトとコメント",
|
|
21
|
+
"ba.popups.popupHighlight.restrictedPrompt": "コメントは1つのページに制限されています",
|
|
22
|
+
"ba.popups.popupList.prompt": "ユーザーにメンションして知らせます",
|
|
23
|
+
"ba.popups.post": "投稿",
|
|
24
|
+
"ba.popups.replyField.placeholder": "コメントを入力…"
|
|
25
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "box-annotations",
|
|
3
|
-
"version": "5.3.1-beta.
|
|
3
|
+
"version": "5.3.1-beta.2",
|
|
4
4
|
"description": "Box Annotations",
|
|
5
5
|
"author": "Box (https://www.box.com/)",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@box/item-icon": "^3.2.0",
|
|
41
41
|
"@box/languages": "^1.1.0",
|
|
42
42
|
"@box/readable-time": "^2.1.32",
|
|
43
|
-
"@box/threaded-annotations": "^4.
|
|
43
|
+
"@box/threaded-annotations": "^4.14.0",
|
|
44
44
|
"@box/types": "^2.1.8",
|
|
45
45
|
"@box/user-selector": "^2.1.35",
|
|
46
46
|
"@cfaester/enzyme-adapter-react-18": "^0.8.0",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"babel-loader": "^9.2.1",
|
|
72
72
|
"babel-plugin-istanbul": "^6.0.0",
|
|
73
73
|
"babel-plugin-transform-require-ignore": "^0.1.1",
|
|
74
|
-
"box-ui-elements": "^
|
|
74
|
+
"box-ui-elements": "^28.0.0-beta.2",
|
|
75
75
|
"circular-dependency-plugin": "^5.2.0",
|
|
76
76
|
"classnames": "^2.2.5",
|
|
77
77
|
"clsx": "^2.1.1",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"@box/combobox-with-api": "^1.42.22",
|
|
143
143
|
"@box/item-icon": "^3.2.0",
|
|
144
144
|
"@box/readable-time": "^2.1.32",
|
|
145
|
-
"@box/threaded-annotations": "^4.
|
|
145
|
+
"@box/threaded-annotations": "^4.14.0",
|
|
146
146
|
"@box/types": "^2.1.8",
|
|
147
147
|
"@box/user-selector": "^2.1.35",
|
|
148
148
|
"axios": "^0.33.0"
|
package/src/api/types.ts
CHANGED
|
@@ -31,6 +31,7 @@ export interface AnnotationsAPI {
|
|
|
31
31
|
permissions: Permissions,
|
|
32
32
|
successCallback: (result: Annotation) => void,
|
|
33
33
|
errorCallback: (error: APIError) => void,
|
|
34
|
+
shouldEnableRichText?: boolean,
|
|
34
35
|
): Promise<void>;
|
|
35
36
|
|
|
36
37
|
createAnnotationReply(
|
|
@@ -40,6 +41,7 @@ export interface AnnotationsAPI {
|
|
|
40
41
|
message: string,
|
|
41
42
|
successCallback: (result: Reply) => void,
|
|
42
43
|
errorCallback: (error: APIError) => void,
|
|
44
|
+
shouldEnableRichText?: boolean,
|
|
43
45
|
): Promise<void>;
|
|
44
46
|
|
|
45
47
|
deleteAnnotation(
|
|
@@ -59,6 +61,7 @@ export interface AnnotationsAPI {
|
|
|
59
61
|
limit?: number,
|
|
60
62
|
shouldFetchAll?: boolean,
|
|
61
63
|
shouldFetchReplies?: boolean,
|
|
64
|
+
shouldEnableRichText?: boolean,
|
|
62
65
|
): Promise<void>;
|
|
63
66
|
|
|
64
67
|
updateAnnotation(
|
|
@@ -68,6 +71,7 @@ export interface AnnotationsAPI {
|
|
|
68
71
|
payload: { message?: string; status?: string },
|
|
69
72
|
successCallback: (result: Annotation) => void,
|
|
70
73
|
errorCallback: (error: APIError) => void,
|
|
74
|
+
shouldEnableRichText?: boolean,
|
|
71
75
|
): Promise<void>;
|
|
72
76
|
|
|
73
77
|
destroy(): void;
|
|
@@ -88,6 +92,7 @@ export interface ThreadedCommentsAPI {
|
|
|
88
92
|
fileId: string | null;
|
|
89
93
|
message?: string;
|
|
90
94
|
permissions: ReplyPermissions;
|
|
95
|
+
shouldEnableRichText?: boolean;
|
|
91
96
|
status?: string;
|
|
92
97
|
successCallback: (reply: Reply) => void;
|
|
93
98
|
}): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import createMentionTimestampSelectorState from 'box-ui-elements/es/components/form-elements/draft-js-mention-selector/createMentionTimestampSelectorState';
|
|
2
2
|
import { getFormattedCommentText } from 'box-ui-elements/es/components/form-elements/draft-js-mention-selector/utils';
|
|
3
3
|
import { EditorState, SelectionState } from 'draft-js';
|
|
4
4
|
import { FormikBag, withFormik } from 'formik';
|
|
@@ -30,13 +30,16 @@ export const mapStateToProps = (state: AppState): PropsFromState => ({
|
|
|
30
30
|
export const mapPropsToErrors = (): FormErrors => ({ editorState: 'initial' });
|
|
31
31
|
|
|
32
32
|
export const mapPropsToValues = ({ cursorPosition: prevCursorPosition, value = '' }: Props): FormValues => {
|
|
33
|
-
const mentionState = withMentionDecorator(
|
|
34
|
-
const
|
|
33
|
+
const mentionState = withMentionDecorator(createMentionTimestampSelectorState(value));
|
|
34
|
+
const selection = mentionState.getSelection();
|
|
35
|
+
const blockLength = mentionState.getCurrentContent().getBlockForKey(selection.getAnchorKey()).getLength();
|
|
36
|
+
// The saved message is trimmed, so the saved cursor can sit past the end of the rebuilt text
|
|
37
|
+
const cursorPosition = value ? Math.min(prevCursorPosition, blockLength) : 0;
|
|
35
38
|
|
|
36
39
|
return {
|
|
37
40
|
editorState: EditorState.forceSelection(
|
|
38
41
|
mentionState,
|
|
39
|
-
|
|
42
|
+
selection.merge({
|
|
40
43
|
anchorOffset: cursorPosition,
|
|
41
44
|
focusOffset: cursorPosition,
|
|
42
45
|
hasFocus: true,
|
|
@@ -3,7 +3,7 @@ import { Annotation, NewAnnotation, Reply } from '../../@types';
|
|
|
3
3
|
import { APICollection } from '../../api';
|
|
4
4
|
import { AppThunkAPI } from '../types';
|
|
5
5
|
import { getAnnotation } from './selectors';
|
|
6
|
-
import { getFileId, getFileVersionId, getPermissions, isFeatureEnabled } from '../options';
|
|
6
|
+
import { getFileId, getFileVersionId, getIsRichTextEnabled, getPermissions, isFeatureEnabled } from '../options';
|
|
7
7
|
|
|
8
8
|
export const createAnnotationAction = createAsyncThunk<Annotation, NewAnnotation, AppThunkAPI>(
|
|
9
9
|
'CREATE_ANNOTATION',
|
|
@@ -14,13 +14,22 @@ export const createAnnotationAction = createAsyncThunk<Annotation, NewAnnotation
|
|
|
14
14
|
const fileId = getFileId(state);
|
|
15
15
|
const fileVersionId = getFileVersionId(state);
|
|
16
16
|
const permissions = getPermissions(state);
|
|
17
|
+
const shouldEnableRichText = getIsRichTextEnabled(state);
|
|
17
18
|
|
|
18
19
|
signal.addEventListener('abort', () => {
|
|
19
20
|
client.destroy();
|
|
20
21
|
});
|
|
21
22
|
|
|
22
23
|
return new Promise<Annotation>((resolve, reject) => {
|
|
23
|
-
client.createAnnotation(
|
|
24
|
+
client.createAnnotation(
|
|
25
|
+
fileId,
|
|
26
|
+
fileVersionId,
|
|
27
|
+
newAnnotation,
|
|
28
|
+
permissions,
|
|
29
|
+
resolve,
|
|
30
|
+
reject,
|
|
31
|
+
shouldEnableRichText,
|
|
32
|
+
);
|
|
24
33
|
});
|
|
25
34
|
},
|
|
26
35
|
);
|
|
@@ -40,11 +49,22 @@ export const fetchAnnotationsAction = createAsyncThunk<APICollection<Annotation>
|
|
|
40
49
|
client.destroy();
|
|
41
50
|
});
|
|
42
51
|
|
|
43
|
-
const shouldFetchReplies = isFeatureEnabled(
|
|
52
|
+
const shouldFetchReplies = isFeatureEnabled(state, 'isThreadedAnnotation');
|
|
53
|
+
const shouldEnableRichText = getIsRichTextEnabled(state);
|
|
44
54
|
|
|
45
55
|
// Wrap the client request in a promise to allow it to be returned and cancelled
|
|
46
56
|
return new Promise<APICollection<Annotation>>((resolve, reject) => {
|
|
47
|
-
client.getAnnotations(
|
|
57
|
+
client.getAnnotations(
|
|
58
|
+
fileId,
|
|
59
|
+
fileVersionId,
|
|
60
|
+
permissions,
|
|
61
|
+
resolve,
|
|
62
|
+
reject,
|
|
63
|
+
1000,
|
|
64
|
+
false,
|
|
65
|
+
shouldFetchReplies,
|
|
66
|
+
shouldEnableRichText,
|
|
67
|
+
);
|
|
48
68
|
});
|
|
49
69
|
},
|
|
50
70
|
);
|
|
@@ -60,13 +80,14 @@ export const createReplyAction = createAsyncThunk<
|
|
|
60
80
|
const filePermissions = getPermissions(state);
|
|
61
81
|
const annotation = getAnnotation(state, annotationId);
|
|
62
82
|
const permissions = { ...filePermissions, ...annotation?.permissions };
|
|
83
|
+
const shouldEnableRichText = getIsRichTextEnabled(state);
|
|
63
84
|
|
|
64
85
|
signal.addEventListener('abort', () => {
|
|
65
86
|
client.destroy();
|
|
66
87
|
});
|
|
67
88
|
|
|
68
89
|
const reply = await new Promise<Reply>((resolve, reject) => {
|
|
69
|
-
client.createAnnotationReply(fileId, annotationId, permissions, message, resolve, reject);
|
|
90
|
+
client.createAnnotationReply(fileId, annotationId, permissions, message, resolve, reject, shouldEnableRichText);
|
|
70
91
|
});
|
|
71
92
|
|
|
72
93
|
return { annotationId, reply };
|
|
@@ -105,13 +126,14 @@ export const updateAnnotationAction = createAsyncThunk<
|
|
|
105
126
|
const filePermissions = getPermissions(state);
|
|
106
127
|
const existingAnnotation = getAnnotation(state, annotationId);
|
|
107
128
|
const permissions = { ...filePermissions, ...existingAnnotation?.permissions };
|
|
129
|
+
const shouldEnableRichText = getIsRichTextEnabled(state);
|
|
108
130
|
|
|
109
131
|
signal.addEventListener('abort', () => {
|
|
110
132
|
client.destroy();
|
|
111
133
|
});
|
|
112
134
|
|
|
113
135
|
return new Promise<Annotation>((resolve, reject) => {
|
|
114
|
-
client.updateAnnotation(fileId, annotationId, permissions, payload, resolve, reject);
|
|
136
|
+
client.updateAnnotation(fileId, annotationId, permissions, payload, resolve, reject, shouldEnableRichText);
|
|
115
137
|
});
|
|
116
138
|
});
|
|
117
139
|
|
|
@@ -125,6 +147,7 @@ export const updateReplyAction = createAsyncThunk<
|
|
|
125
147
|
const fileId = getFileId(state);
|
|
126
148
|
const annotation = getAnnotation(state, annotationId);
|
|
127
149
|
const reply = annotation?.replies?.find(r => r.id === replyId);
|
|
150
|
+
const shouldEnableRichText = getIsRichTextEnabled(state);
|
|
128
151
|
|
|
129
152
|
if (!reply) {
|
|
130
153
|
throw new Error(`updateReplyAction: reply ${replyId} not found on annotation ${annotationId}`);
|
|
@@ -141,6 +164,7 @@ export const updateReplyAction = createAsyncThunk<
|
|
|
141
164
|
fileId,
|
|
142
165
|
message: payload.message,
|
|
143
166
|
permissions: reply.permissions ?? {},
|
|
167
|
+
shouldEnableRichText,
|
|
144
168
|
status: payload.status,
|
|
145
169
|
successCallback: resolve,
|
|
146
170
|
});
|
|
@@ -18,3 +18,8 @@ export const getScale = (state: State): number => state.options.scale;
|
|
|
18
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);
|
|
21
|
+
|
|
22
|
+
// Rich text is only rendered and authored in the threaded popup (PopupV2). The legacy popup editor
|
|
23
|
+
// is plain text, so the flag only applies when threaded annotations are on.
|
|
24
|
+
export const getIsRichTextEnabled = (state: State): boolean =>
|
|
25
|
+
isFeatureEnabled(state, 'isThreadedAnnotation') && isFeatureEnabled(state, 'isRichTextEnabled');
|