Skip to content

Commit 1e302ac

Browse files
authored
Merge pull request #661 from opendatalab/fix/default-option
Fix/default option
2 parents 5ba904b + 72ba586 commit 1e302ac

File tree

8 files changed

+57
-59
lines changed

8 files changed

+57
-59
lines changed

apps/frontend/src/pages/tasks.[id].samples.[id]/components/annotationRightCorner/index.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { updateSampleState, updateSampleAnnotationResult } from '@/api/services/
1818
import { message } from '@/StaticAnt';
1919
import useMe from '@/hooks/useMe';
2020
import { UserAvatar } from '@/components/UserAvatar';
21+
import { generateDefaultValues } from '@/utils/generateGlobalToolDefaultValues';
2122

2223
import AnnotationContext from '../../annotation.context';
2324

@@ -247,6 +248,23 @@ const AnnotationRightCorner = ({ noSave, fetchNext, totalSize }: AnnotationRight
247248
innerSample = await audioAnnotationRef?.current?.getSample();
248249
}
249250

251+
// 全局标注没有值的话,填充默认值
252+
if (!result.tagTool?.result?.length) {
253+
const tagConfig = task.config.tools.find((tool) => tool.tool === 'tagTool');
254+
result.tagTool = {
255+
toolName: 'tagTool',
256+
result: generateDefaultValues(tagConfig?.config.attributes),
257+
};
258+
}
259+
260+
if (!result.textTool?.result?.length) {
261+
const textConfig = task.config.tools.find((tool) => tool.tool === 'textTool');
262+
result.textTool = {
263+
toolName: 'textTool',
264+
result: generateDefaultValues(textConfig?.config.attributes),
265+
};
266+
}
267+
250268
// 防止sampleid保存错乱,使用标注时传入的sampleid
251269
const body = set('data.result')(JSON.stringify(result))(currentSample);
252270

@@ -255,7 +273,7 @@ const AnnotationRightCorner = ({ noSave, fetchNext, totalSize }: AnnotationRight
255273
annotated_count: getAnnotationCount(body.data!.result),
256274
state: SampleState.DONE,
257275
});
258-
}, [currentSample, isMeTheCurrentUser, noSave, task.media_type, taskId]);
276+
}, [currentSample, isMeTheCurrentUser, noSave, task?.config.tools, task?.media_type, taskId]);
259277

260278
const handleComplete = useCallback(async () => {
261279
await saveCurrentSample();

apps/frontend/src/pages/tasks.[id].samples.[id]/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ const AnnotationPage = () => {
101101
}
102102

103103
if (task?.media_type === MediaType.IMAGE) {
104-
return convertImageAnnotations(_annotations, preAnnotationConfig);
104+
return convertImageAnnotations(_annotations);
105105
} else if (task?.media_type === MediaType.VIDEO || task?.media_type === MediaType.AUDIO) {
106-
return convertMediaAnnotations(task.media_type, _annotations, preAnnotationConfig);
106+
return convertMediaAnnotations(task.media_type, _annotations);
107107
}
108108

109109
return {};
110-
}, [preAnnotation, preAnnotationConfig, task?.media_type]);
110+
}, [preAnnotation, task?.media_type]);
111111

112112
const [searchParams] = useSearchParams();
113113
const taskConfig = _.get(task, 'config');
@@ -204,11 +204,11 @@ const AnnotationPage = () => {
204204

205205
const editingSample = useMemo(() => {
206206
if (task?.media_type === MediaType.IMAGE) {
207-
return convertImageSample(sample?.data, editorConfig);
207+
return convertImageSample(sample?.data);
208208
} else if (task?.media_type === MediaType.VIDEO || task?.media_type === MediaType.AUDIO) {
209-
return convertAudioAndVideoSample(sample?.data, editorConfig, task.media_type);
209+
return convertAudioAndVideoSample(sample?.data, task.media_type);
210210
}
211-
}, [editorConfig, sample?.data, task?.media_type]);
211+
}, [sample?.data, task?.media_type]);
212212

213213
const renderSidebar = useMemo(() => {
214214
return () => leftSiderContent;

apps/frontend/src/utils/convertAudioAndVideoSample.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import _ from 'lodash';
2-
import type { AnnotationsWithGlobal, MediaAnnotatorConfig, MediaSample } from '@labelu/audio-annotator-react';
2+
import type { AnnotationsWithGlobal, MediaSample } from '@labelu/audio-annotator-react';
33

44
import type { ParsedResult, SampleResponse } from '@/api/types';
55
import { MediaType } from '@/api/types';
66

77
import { jsonParse } from './index';
8-
import { generateDefaultValues } from './generateGlobalToolDefaultValues';
98

10-
export function convertMediaAnnotations(mediaType: MediaType, result: ParsedResult, config: MediaAnnotatorConfig) {
9+
export function convertMediaAnnotations(mediaType: MediaType, result: ParsedResult) {
1110
// annotation
1211
const pool = [
1312
['segment', MediaType.VIDEO === mediaType ? 'videoSegmentTool' : 'audioSegmentTool'],
@@ -20,11 +19,6 @@ export function convertMediaAnnotations(mediaType: MediaType, result: ParsedResu
2019
.map(([type, key]) => {
2120
const items = _.get(result, [key, 'result'], []);
2221

23-
if (!items.length && (type === 'tag' || type === 'text')) {
24-
// 生成全局工具的默认值
25-
return [type, generateDefaultValues(config?.[type])];
26-
}
27-
2822
return [
2923
type,
3024
_.map(items, (item) => {
@@ -39,11 +33,7 @@ export function convertMediaAnnotations(mediaType: MediaType, result: ParsedResu
3933
.value() as AnnotationsWithGlobal;
4034
}
4135

42-
export function convertAudioAndVideoSample(
43-
sample: SampleResponse,
44-
config: MediaAnnotatorConfig,
45-
mediaType?: MediaType,
46-
): MediaSample | undefined {
36+
export function convertAudioAndVideoSample(sample: SampleResponse, mediaType?: MediaType): MediaSample | undefined {
4737
if (!sample) {
4838
return;
4939
}
@@ -60,6 +50,6 @@ export function convertAudioAndVideoSample(
6050
url: [MediaType.VIDEO, MediaType.AUDIO].includes(mediaType as MediaType)
6151
? sample.file.url.replace('attachment', 'partial')
6252
: sample.file.url,
63-
data: convertMediaAnnotations(mediaType!, resultParsed, config),
53+
data: convertMediaAnnotations(mediaType!, resultParsed),
6454
};
6555
}

apps/frontend/src/utils/convertImageSample.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
import _ from 'lodash';
2-
import type { GlobalToolConfig, ImageAnnotatorOptions, ImageSample } from '@labelu/image-annotator-react';
2+
import type { ImageSample } from '@labelu/image-annotator-react';
33
import { omit } from 'lodash/fp';
44
import type { ToolName } from '@labelu/image';
55
import { TOOL_NAMES } from '@labelu/image';
66

77
import type { ParsedResult, SampleResponse } from '@/api/types';
88

99
import { jsonParse } from './index';
10-
import { generateDefaultValues } from './generateGlobalToolDefaultValues';
1110

12-
export function convertImageAnnotations(
13-
result: ParsedResult,
14-
config: Pick<ImageAnnotatorOptions, ToolName> & GlobalToolConfig,
15-
) {
11+
export function convertImageAnnotations(result: ParsedResult) {
1612
// annotation
1713
const pool = [
1814
['line', 'lineTool'],
@@ -31,10 +27,6 @@ export function convertImageAnnotations(
3127
}
3228

3329
const items = _.get(result, [key, 'result']) || _.get(result, [type, 'result'], []);
34-
if (!items.length && (type === 'tag' || type === 'text')) {
35-
// 生成全局工具的默认值
36-
return [type, generateDefaultValues(config?.[type])];
37-
}
3830

3931
return [
4032
type,
@@ -61,10 +53,7 @@ export function convertImageAnnotations(
6153
.value();
6254
}
6355

64-
export function convertImageSample(
65-
sample: SampleResponse | undefined,
66-
config: Pick<ImageAnnotatorOptions, ToolName> & GlobalToolConfig,
67-
): ImageSample | undefined {
56+
export function convertImageSample(sample: SampleResponse | undefined): ImageSample | undefined {
6857
if (!sample) {
6958
return;
7059
}
@@ -80,7 +69,7 @@ export function convertImageSample(
8069
return {
8170
id,
8271
url,
83-
data: convertImageAnnotations(resultParsed, config),
72+
data: convertImageAnnotations(resultParsed),
8473
meta: _.pick(resultParsed, ['width', 'height', 'rotate']),
8574
};
8675
}

packages/audio-annotator-react/src/AttributePanel/index.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export function AttributePanel() {
209209
} = useAnnotationCtx();
210210
const [collapsed, setCollapsed] = useState<boolean>(false);
211211
const { t } = useTranslation();
212+
const [modified, setModified] = useState<boolean>(false);
212213

213214
const { globalAnnotations, globalAnnotationsWithPreAnnotation, mediaAnnotationGroup, defaultActiveKeys } =
214215
useMemo(() => {
@@ -223,13 +224,12 @@ export function AttributePanel() {
223224
...(preAnnotationsWithGlobal?.frame ?? []),
224225
] as MediaAnnotationInUI[];
225226

226-
// 传入了预标注说明样本没有人工标注内容
227-
if (preAnnotationsWithGlobal?.tag?.length) {
228-
_globalAnnotationsWithPreAnnotation.push(...(preAnnotationsWithGlobal?.tag as GlobalAnnotation[]));
229-
}
230-
231-
if (preAnnotationsWithGlobal?.text?.length) {
232-
_globalAnnotationsWithPreAnnotation.push(...(preAnnotationsWithGlobal?.text as GlobalAnnotation[]));
227+
if (!_globalAnnotations.length && !modified) {
228+
[preAnnotationsWithGlobal?.tag, preAnnotationsWithGlobal?.text].forEach((values) => {
229+
if (values) {
230+
_globalAnnotationsWithPreAnnotation.push(...(values as GlobalAnnotation[]));
231+
}
232+
});
233233
}
234234

235235
for (const item of sortedMediaAnnotations) {
@@ -262,6 +262,7 @@ export function AttributePanel() {
262262
preAnnotationsWithGlobal?.tag,
263263
preAnnotationsWithGlobal?.text,
264264
sortedMediaAnnotations,
265+
modified,
265266
]);
266267

267268
const globals = useMemo(() => {
@@ -400,6 +401,8 @@ export function AttributePanel() {
400401
return;
401402
}
402403

404+
setModified(true);
405+
403406
onAnnotationClear();
404407
};
405408

packages/components-react/src/AttributeTree/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,13 @@ export function AttributeTree({ data, config, onChange, className, disabled }: A
194194
});
195195

196196
tagConfig?.forEach((item) => {
197+
const defaultValue = item.options.filter((option) => option.isDefault).map((option) => option.value);
197198
if (!_tagData[item.value]) {
198199
_tagData[item.value] = {
199200
id: uid(),
200201
type: 'tag',
201202
value: {
202-
[item.value]: [],
203+
[item.value]: defaultValue,
203204
},
204205
} as TagAnnotationEntity;
205206
}
@@ -211,7 +212,7 @@ export function AttributeTree({ data, config, onChange, className, disabled }: A
211212
id: uid(),
212213
type: 'text',
213214
value: {
214-
[item.value]: '',
215+
[item.value]: item.defaultValue,
215216
},
216217
} as TextAnnotationEntity;
217218
}

packages/image-annotator-react/src/AttributePanel/index.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ export function AttributePanel() {
213213
disabled,
214214
} = useAnnotationCtx();
215215
const [collapsed, setCollapsed] = useState<boolean>(false);
216+
const [modified, setModified] = useState<boolean>(false);
216217
const globalAnnotations = useMemo(() => {
217218
return Object.values(annotationsWithGlobal).filter((item) =>
218219
['text', 'tag'].includes((item as GlobalAnnotation).type),
219220
) as GlobalAnnotation[];
220221
}, [annotationsWithGlobal]);
222+
221223
// @ts-ignore
222224
const { t } = useTranslation();
223225

@@ -269,23 +271,17 @@ export function AttributePanel() {
269271

270272
const flatGlobalTagAnnotations = useMemo(() => {
271273
const result = globalAnnotations;
272-
const preResult = [] as GlobalAnnotation[];
273-
274-
// 传入了预标注说明样本没有人工标注内容
275-
if (preAnnotationsWithGlobal?.tag?.length) {
276-
preResult.push(...(preAnnotationsWithGlobal?.tag as GlobalAnnotation[]));
277-
}
278-
279-
if (preAnnotationsWithGlobal?.text?.length) {
280-
preResult.push(...(preAnnotationsWithGlobal?.text as GlobalAnnotation[]));
281-
}
282274

283-
if (preResult.length) {
284-
return preResult;
275+
if (globalAnnotations.length === 0 && !modified) {
276+
[preAnnotationsWithGlobal?.tag, preAnnotationsWithGlobal?.text].forEach((values) => {
277+
if (values) {
278+
result.push(...(values as GlobalAnnotation[]));
279+
}
280+
});
285281
}
286282

287283
return result;
288-
}, [globalAnnotations, preAnnotationsWithGlobal]);
284+
}, [globalAnnotations, preAnnotationsWithGlobal?.tag, preAnnotationsWithGlobal?.text, modified]);
289285

290286
const titles = useMemo(() => {
291287
const _titles = [];
@@ -392,6 +388,8 @@ export function AttributePanel() {
392388
return;
393389
}
394390

391+
setModified(true);
392+
395393
onAnnotationClear();
396394
if (activeKey === 'label') {
397395
engine?.clearData();

packages/image-annotator-react/src/ImageAnnotator.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,6 @@ function ForwardAnnotator(
593593
// 删除标记
594594
const handleDelete = (annotation: AnnotationData) => {
595595
const newAnnotations = omit(annotationsWithGlobal, annotation.id);
596-
console.log('newAnnotations', newAnnotations);
597596
updateAnnotationsWithGlobal(newAnnotations);
598597
setSelectedAnnotation((pre) => {
599598
if (pre?.id === annotation.id) {

0 commit comments

Comments
 (0)