Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: LEAP-1515: Hide PII by condition #6544

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
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
4 changes: 4 additions & 0 deletions web/libs/datamanager/src/sdk/lsf-sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ export class LSFWrapper {
interfaces.push("annotations:deny-empty");
}

if (window.APP_SETTINGS.annotator_reviewer_firewall_enabled) {
interfaces.push("annotations:hide-info");
}

if (this.labelStream) {
interfaces.push("infobar");
if (!window.APP_SETTINGS.label_stream_navigation_disabled) interfaces.push("topbar:prevnext");
Expand Down
11 changes: 7 additions & 4 deletions web/libs/editor/src/components/AnnotationTabs/AnnotationTabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const EntityTab = observer(
forwardRef(
({ entity, selected, style, onClick, bordered = true, prediction = false, displayGroundTruth = false }, ref) => {
const isUnsaved = (entity.userGenerate && !entity.sentUserGenerate) || entity.draftSelected;
const infoIsHidden = entity.store.hasInterface("annotations:hide-info");

return (
<Block
Expand All @@ -29,15 +30,17 @@ export const EntityTab = observer(
tag={Userpic}
showUsername
username={prediction ? entity.createdBy : null}
user={entity.user ?? { email: entity.createdBy }}
user={infoIsHidden ? {} : (entity.user ?? { email: entity.createdBy })}
mod={{ prediction }}
>
{prediction && <LsSparks style={{ width: 16, height: 16 }} />}
</Elem>

<Elem name="identifier">
ID {entity.pk ?? entity.id} {isUnsaved && "*"}
</Elem>
{!infoIsHidden && (
<Elem name="identifier">
ID {entity.pk ?? entity.id} {isUnsaved && "*"}
</Elem>
)}

{displayGroundTruth && entity.ground_truth && <Elem name="ground-truth" tag={LsStar} />}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
&_selected {
background-color: var(--sand_0);
border-color: var(--sand_300);
transform: translate(0, 1px);

&:hover {
background-color: var(--sand_0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { Tooltip } from "./../../common/Tooltip/Tooltip";
// @ts-ignore
import { confirm } from "../../common/Modal/Modal";
import { observer } from "mobx-react";

interface AnnotationButtonInterface {
entity?: any;
capabilities?: any;
Expand Down Expand Up @@ -66,6 +67,10 @@ export const AnnotationButton = observer(
);
const [isGroundTruth, setIsGroundTruth] = useState<boolean>();
const [isContextMenuOpen, setIsContextMenuOpen] = useState<boolean>(false);
const currentUser = annotationStore.store.user;
const isCurrentUser = entity.user?.id === currentUser.id || entity.createdBy === currentUser.email;
const infoIsHidden = annotationStore.store.hasInterface("annotations:hide-info");
const hiddenUser = infoIsHidden ? { email: isCurrentUser ? "Me" : "User" } : null;

const CommentIcon = renderCommentIcon(entity);
// need to find a more reliable way to grab this value
Expand Down Expand Up @@ -176,7 +181,7 @@ export const AnnotationButton = observer(
tag={Userpic}
showUsername
username={isPrediction ? entity.createdBy : null}
user={entity.user ?? { email: entity.createdBy }}
user={hiddenUser ?? entity.user ?? { email: entity.createdBy }}
mod={{ prediction: isPrediction }}
size={24}
>
Expand All @@ -198,15 +203,19 @@ export const AnnotationButton = observer(
<Elem name="main">
<Elem name="user">
<Elem tag="span" name="name">
{username}
</Elem>
<Elem tag="span" name="entity-id">
#{entity.pk ?? entity.id}
{hiddenUser ? hiddenUser.email : username}
</Elem>
{!infoIsHidden && (
<Elem tag="span" name="entity-id">
#{entity.pk ?? entity.id}
</Elem>
)}
</Elem>
<Elem name="created">
<Elem name="date" component={TimeAgo} date={entity.createdDate} />
</Elem>
{!infoIsHidden && (
<Elem name="created">
<Elem name="date" component={TimeAgo} date={entity.createdDate} />
</Elem>
)}
</Elem>
{!isPrediction && (
<Elem name="icons">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export const CommentItem: FC<CommentItemProps> = observer(
const { startLinkingMode: _startLinkingMode, currentComment, globalLinking } = useContext(CommentsContext);
const currentUser = window.APP_SETTINGS?.user;
const isCreator = currentUser?.id === createdBy.id;
const infoIsHidden = comment.commentsStore?.store?.hasInterface("annotations:hide-info");
const hiddenUser = infoIsHidden ? { email: isCreator ? "Me" : "User" } : null;
const [text, setText] = useState(initialText);

const [linkingComment, setLinkingComment] = useState();
Expand Down Expand Up @@ -167,9 +169,9 @@ export const CommentItem: FC<CommentItemProps> = observer(
>
<Space spread size="medium" truncated>
<Space size="small" truncated>
<Elem tag={Userpic} user={createdBy} name="userpic" showUsername username={createdBy} />
<Elem tag={Userpic} user={hiddenUser ?? createdBy} name="userpic" showUsername username={createdBy} />
<Elem name="name" tag="span">
{userDisplayName(createdBy)}
{userDisplayName(hiddenUser ?? createdBy)}
</Elem>
</Space>

Expand All @@ -178,7 +180,7 @@ export const CommentItem: FC<CommentItemProps> = observer(
<Elem name="saving" mod={{ hide: isPersisted }}>
<Elem name="dot" />
</Elem>
<TimeTracker />
{!infoIsHidden && <TimeTracker />}
</Space>
</Space>

Expand Down
37 changes: 24 additions & 13 deletions web/libs/editor/src/components/CurrentEntity/AnnotationHistory.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { when } from "mobx";
import { inject, observer } from "mobx-react";
import { type FC, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { Tooltip } from "antd";
Expand All @@ -19,7 +20,6 @@ import { Userpic } from "../../common/Userpic/Userpic";
import { Block, Elem } from "../../utils/bem";
import { humanDateDiff, userDisplayName } from "../../utils/utilities";
import "./AnnotationHistory.scss";
import { when } from "mobx";

type HistoryItemType =
| "prediction"
Expand Down Expand Up @@ -55,6 +55,8 @@ const DraftState: FC<{
}> = observer(({ annotation, inline, isSelected }) => {
const hasChanges = annotation.history.hasChanges;
const store = annotation.list; // @todo weird name
const infoIsHidden = store.store.hasInterface("annotations:hide-info");
const hiddenUser = infoIsHidden ? { email: "Me" } : null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that the user who will be replaced by "Me" is not actually the current one?

Copy link
Collaborator

@Gondragos Gondragos Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nwm. Looks like with annotations:hide-info we are going to prevent such cases from appearing.


const [hasUnsavedChanges, setChanges] = useState(false);

Expand All @@ -67,7 +69,7 @@ const DraftState: FC<{
return (
<HistoryItem
key="draft"
user={annotation.user ?? { email: annotation.createdBy }}
user={hiddenUser ?? annotation.user ?? { email: annotation.createdBy }}
date={annotation.draftSaved}
extra={
annotation.isDraftSaving ? (
Expand All @@ -88,6 +90,7 @@ const DraftState: FC<{
comment=""
acceptedState="draft_created"
selected={isSelected}
hideInfo={infoIsHidden}
onClick={() => {
store.selectHistory(null);
annotation.toggleDraft(true);
Expand All @@ -107,6 +110,8 @@ const AnnotationHistoryComponent: FC<any> = ({
const annotation = annotationStore.selected;
const lastItem = history?.length ? history[0] : null;
const hasChanges = annotation.history.hasChanges;
const infoIsHidden = annotationStore.store.hasInterface("annotations:hide-info");
const currentUser = window.APP_SETTINGS?.user;

// if user makes changes at the first time there are no draft yet
const isDraftSelected =
Expand All @@ -123,17 +128,19 @@ const AnnotationHistoryComponent: FC<any> = ({
const isLastItem = lastItem?.id === item.id;
const isSelected =
isLastItem && !selectedHistory && showDraft ? !isDraftSelected : selectedHistory?.id === item.id;
const hiddenUser = infoIsHidden ? { email: currentUser?.id === user.id ? "Me" : "User" } : null;

return (
<HistoryItem
key={id}
inline={inline}
user={user ?? { email: item?.createdBy }}
user={hiddenUser ?? user ?? { email: item?.createdBy }}
date={createdDate}
comment={item.comment}
acceptedState={item.actionType}
selected={isSelected}
disabled={item.results.length === 0}
hideInfo={infoIsHidden}
onClick={async () => {
if (!showDraft) {
annotationStore.selectHistory(isSelected ? null : item);
Expand Down Expand Up @@ -171,6 +178,7 @@ const HistoryItemComponent: FC<{
selected?: boolean;
disabled?: boolean;
inline?: boolean;
hideInfo?: boolean;
onClick: any;
}> = ({
entity,
Expand All @@ -182,6 +190,7 @@ const HistoryItemComponent: FC<{
selected = false,
disabled = false,
inline = false,
hideInfo: infoIsHidden,
onClick,
}) => {
const isPrediction = entity?.type === "prediction";
Expand Down Expand Up @@ -243,16 +252,18 @@ const HistoryItemComponent: FC<{
</Elem>
</Space>

<Space size="small">
{extra && <Elem name="date">{extra}</Elem>}
{date && (
<Elem name="date">
<Tooltip placement="topRight" title={new Date(date).toLocaleString()}>
{humanDateDiff(date)}
</Tooltip>
</Elem>
)}
</Space>
{!infoIsHidden && (
<Space size="small">
{extra && <Elem name="date">{extra}</Elem>}
{date && (
<Elem name="date">
<Tooltip placement="topRight" title={new Date(date).toLocaleString()}>
{humanDateDiff(date)}
</Tooltip>
</Elem>
)}
</Space>
)}
</Space>
{(reason || comment) && (
<Elem name="action" tag={Space} size="small">
Expand Down
Loading