Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion web/src/api/hooks/annotations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { CategoryDataAttrType, MutationHookType, PageInfo, QueryHookType } from 'api/typings';
import {
AnnotationUserRevision,
CategoryDataAttrType,
MutationHookType,
PageInfo,
QueryHookType
} from 'api/typings';
import { Task } from 'api/typings/tasks';
import { useMutation, useQuery } from 'react-query';
import { useBadgerFetch } from './api';
Expand Down Expand Up @@ -70,6 +76,15 @@ export type AnnotationsByUserObj = PageInfo & {
export type AnnotationsByUserResponse = {
[page_num: number]: AnnotationsByUserObj[];
};

export type AnnotationAllUsersObject = {
[key: number]: AnnotationUserRevision[];
};

type AnnotationAllUsersRequest = {
data: AnnotationAllUsersObject;
};

export const useLatestAnnotations: QueryHookType<LatestAnnotationsParams, AnnotationsResponse> = (
{ jobId, fileId, revisionId, pageNumbers, userId },
options
Expand All @@ -81,6 +96,15 @@ export const useLatestAnnotations: QueryHookType<LatestAnnotationsParams, Annota
);
};

export const useAnnotationsAllUsers: QueryHookType<
LatestAnnotationsParams,
AnnotationAllUsersRequest
> = ({ jobId, fileId, pageNumbers }) => {
return useQuery([jobId, fileId], async () =>
fetchAnnotationAllUsers(jobId, fileId, pageNumbers)
);
};

export const useLatestAnnotationsByUser: QueryHookType<
LatestAnnotationsParamsByUser,
AnnotationsByUserResponse
Expand Down Expand Up @@ -109,6 +133,18 @@ async function fetchLatestAnnotations(
})();
}

async function fetchAnnotationAllUsers(jobId?: number, fileId?: number, pageNumbers?: number[]) {
if (!jobId || !fileId) {
return;
}
const pageNums = pageNumbers?.map((pageNumber) => `page_numbers=${pageNumber}`);
return useBadgerFetch({
url: `${namespace}/annotation/${jobId}/${fileId}?${pageNums?.join('&')}`,
method: 'get',
withCredentials: true
})();
}

async function fetchLatestAnnotationsByUser(
jobId?: number,
fileId?: number,
Expand Down
12 changes: 12 additions & 0 deletions web/src/api/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,15 @@ export type Report = {
to: string;
validationType: ValidationType | undefined;
};

export type AnnotationUserRevision = {
categories: string[];
date: string;
is_validated: boolean;
objs: PageInfoObjs;
page_num: number;
pipeline: number | null;
revision: string;
size: { width: number; height: number };
user_id?: string | null;
};
8 changes: 2 additions & 6 deletions web/src/components/split-labels-panel/split-labels-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC } from 'react';
import { Tag, Spinner } from '@epam/loveship';
import { Tag } from '@epam/loveship';
import styles from './split-labels-panel.module.scss';
import { Label } from 'api/typings';
import { useTaskAnnotatorContext } from 'connectors/task-annotator-connector/task-annotator-context';
Expand All @@ -11,18 +11,14 @@ type SplitLabelsPanelProps = {
export const SplitLabelsPanel: FC<SplitLabelsPanelProps> = ({ labels, selectedLabelsId }) => {
const { setTabValue, onLabelsSelected } = useTaskAnnotatorContext();

if (!labels) {
return <Spinner color="sky" />;
}

const onClick = (id: string) => () => {
setTabValue('Document');
onLabelsSelected(labels, [...selectedLabelsId, id]);
};

return (
<div className={styles.container}>
{labels.map(({ name, id }) => (
{labels?.map(({ name, id }) => (
<Tag size="24" caption={name} key={name} onClick={onClick(id)} cx={styles.tag} />
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ApiError } from 'api/api-error';
import {
DocumentLink,
useAddAnnotationsMutation,
useAnnotationsAllUsers,
useLatestAnnotations
} from 'api/hooks/annotations';
import { useSetTaskFinishedMutation, useSetTaskState, useTaskById } from 'api/hooks/tasks';
Expand Down Expand Up @@ -61,6 +62,7 @@ import {
getCategoryDataAttrs,
isValidCategoryType,
mapAnnDataAttrs,
mapAnnotationsByUsers,
mapAnnotationDataAttrsFromApi,
mapModifiedAnnotationPagesToApi,
mapTokenPagesFromApi
Expand Down Expand Up @@ -149,6 +151,7 @@ type ContextValue = SplitValidationValue &
isDocLabelsModified: boolean;
getJobId: () => number | undefined;
linksFromApi?: DocumentLink[];
allUsersAnnotation?: Map<number, string> | undefined;
};

type ProviderProps = {
Expand Down Expand Up @@ -328,6 +331,14 @@ export const TaskAnnotatorContextProvider: React.FC<ProviderProps> = ({
{ enabled: !!(task || job) }
);

const allUsersAnnotation = mapAnnotationsByUsers(
useAnnotationsAllUsers({
jobId: getJobId(),
fileId: getFileId(),
pageNumbers: pageNumbers
})?.data
);

const tokenRes = useTokens(
{
fileId: getFileId(),
Expand Down Expand Up @@ -1066,6 +1077,7 @@ export const TaskAnnotatorContextProvider: React.FC<ProviderProps> = ({
latestLabelsId,
setLatestLabelsId,
linksFromApi,
allUsersAnnotation,
...splitValidation,
...syncScroll,
...documentLinksValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ExternalViewerState,
Taxon
} from 'api/typings';
import { AnnotationAllUsersObject } from 'api/hooks/annotations';

import { Annotation, AnnotationBoundType, AnnotationTable, PageToken, TableApi } from 'shared';
import { isIntersected, isR2InsideR1 } from 'shared/components/annotator/utils/is-intersected';
Expand Down Expand Up @@ -341,3 +342,15 @@ export const mapTokenPagesFromApi = (
});
return res;
};

export const mapAnnotationsByUsers = (annotations?: AnnotationAllUsersObject) => {
if (annotations) {
const userAnnotationResult = new Map();
Object.values(annotations).map((annotationData) => {
annotationData?.map((annotation) => {
userAnnotationResult.set(annotation.page_num, annotation.user_id);
});
});
return userAnnotationResult;
}
};
29 changes: 20 additions & 9 deletions web/src/shared/components/document-pages/document-pages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ const DocumentPages: React.FC<DocumentPagesProps> = ({
documentLinks,
onLinkChanged,
selectedRelatedDoc,
sortedUsers
allUsersAnnotation,
job
} = useTaskAnnotatorContext();

const containerRef = useRef<HTMLDivElement>(null);
Expand All @@ -100,9 +101,8 @@ const DocumentPages: React.FC<DocumentPagesProps> = ({
const selectedLabelsId = selectedLabels?.map(({ id }) => id) || [];

const getAnnotatorName = useCallback(
(annotatorId: string): string =>
sortedUsers.current.annotators.find(({ id }) => id === annotatorId)?.username || '',
[sortedUsers]
(annotatorId: string): string => job?.annotators.find((el) => el === annotatorId) || '',
[job]
);

useEffect(() => {
Expand Down Expand Up @@ -157,6 +157,15 @@ const DocumentPages: React.FC<DocumentPagesProps> = ({
</div>
);

const displayAnnotatorInfo = (userId?: string) =>
task?.is_validation && (
<SplitAnnotatorInfo
annotatorName={getAnnotatorName(userId || '')}
labels={categoriesByUserId?.userId}
selectedLabelsId={selectedLabelsId}
/>
);

return (
<>
{selectedRelatedDoc ? (
Expand Down Expand Up @@ -200,11 +209,7 @@ const DocumentPages: React.FC<DocumentPagesProps> = ({
</SyncedContainer>
{userPages.map(({ user_id, page_num }) => (
<Fragment key={user_id}>
<SplitAnnotatorInfo
annotatorName={getAnnotatorName(user_id)}
labels={categoriesByUserId[user_id]}
selectedLabelsId={selectedLabelsId}
/>
{displayAnnotatorInfo(user_id)}
<SyncedContainer className={styles['split-document-page']}>
<DocumentSinglePage
annotations={annotationsByUserId[user_id]}
Expand Down Expand Up @@ -289,6 +294,9 @@ const DocumentPages: React.FC<DocumentPagesProps> = ({
{pageNumbers.map((pageNum) => {
return (
<Fragment key={pageNum}>
{displayAnnotatorInfo(
allUsersAnnotation?.get(pageNum)
)}
<DocumentSinglePage
scale={scale}
pageSize={apiPageSize}
Expand Down Expand Up @@ -322,6 +330,9 @@ const DocumentPages: React.FC<DocumentPagesProps> = ({
{pageNumbers.map((pageNum) => {
return (
<Fragment key={pageNum}>
{displayAnnotatorInfo(
allUsersAnnotation?.get(pageNum)
)}
<DocumentSinglePage
scale={scale}
pageSize={apiPageSize}
Expand Down