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: LSDV-5520: Project Creation Wizard Tip (Label Studio Community) #4652

Merged
merged 35 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3d75811
Introduce Heidi tips
nicholasrq Aug 18, 2023
0d476b0
ci: Build frontend
robot-ci-heartex Aug 18, 2023
7fccd38
Fix random tip selection
nicholasrq Aug 18, 2023
a64c491
ci: Build frontend
robot-ci-heartex Aug 18, 2023
28b33c9
Cookie to dismiss tips
nicholasrq Aug 18, 2023
bbf2053
ci: Build frontend
robot-ci-heartex Aug 18, 2023
3930386
Caption component
nicholasrq Aug 18, 2023
a0bcf03
Fix caption styles
nicholasrq Aug 18, 2023
7608135
Use caption in project creation
nicholasrq Aug 18, 2023
e0d4967
ci: Build frontend
robot-ci-heartex Aug 18, 2023
6befd25
Option to add URL params to the links
nicholasrq Aug 18, 2023
3c4c39d
ci: Build frontend
robot-ci-heartex Aug 18, 2023
3402ae6
Add feature flag
nicholasrq Aug 18, 2023
6bd4046
ci: Build frontend
robot-ci-heartex Aug 18, 2023
000e0cf
fix some lint issues
juliosgarbi Aug 18, 2023
1cbbfe8
ci: Build frontend
robot-ci-heartex Aug 18, 2023
8808c08
add new GA params
juliosgarbi Aug 18, 2023
c0ed516
add new GA params
juliosgarbi Aug 18, 2023
6139eae
ci: Build frontend
robot-ci-heartex Aug 18, 2023
a4a5eb5
move the code to be defined before HeidiTip
juliosgarbi Aug 18, 2023
b14eb35
ci: Build frontend
robot-ci-heartex Aug 18, 2023
1a9c48d
add link to workspace dropdown
juliosgarbi Aug 18, 2023
1422c8e
ci: Build frontend
robot-ci-heartex Aug 18, 2023
92e0d70
Fix typo
nicholasrq Aug 21, 2023
a50d7c3
Fix link behavior
nicholasrq Aug 21, 2023
9c05939
ci: Build frontend
robot-ci-heartex Aug 21, 2023
0f426ce
Add server_id and user_id to createURL
nicholasrq Aug 21, 2023
0da64e0
Remove unnecessary server_id from content
nicholasrq Aug 21, 2023
ef06110
Remove unnecessary server and user ids from project creation tip
nicholasrq Aug 21, 2023
8ce005a
ci: Build frontend
robot-ci-heartex Aug 21, 2023
6194adf
Support SERVER_ID
nicholasrq Aug 21, 2023
5d8cb27
Remove placeholder
nicholasrq Aug 21, 2023
2018b7d
ci: Build frontend
robot-ci-heartex Aug 21, 2023
1082e01
Move server_id assignment
nicholasrq Aug 21, 2023
80f6a1c
Merge remote-tracking branch 'origin/develop' into fb-lsdv-5520/proje…
juliosgarbi Aug 22, 2023
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
2 changes: 1 addition & 1 deletion label_studio/frontend/dist/react-app/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/react-app/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/react-app/main.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/react-app/main.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@sentry/browser": "^6.8.0",
"@sentry/react": "^6.8.0",
"@sentry/tracing": "^6.8.0",
"@svgr/webpack": "^8.0.1",
"@svgr/webpack": "^8.1.0",
"@types/chroma-js": "^2.1.3",
"@types/enzyme": "^3.10.8",
"@types/expect-puppeteer": "^4.4.5",
Expand Down
3 changes: 2 additions & 1 deletion label_studio/frontend/src/assets/icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export { default as LsThumbsDown } from './thumbs-down.svg';
export { default as LsThumbsUp } from './thumbs-up.svg';
export { default as IconUpload } from './upload.svg';
export { default as LsPencil } from './pencil.svg';
export { default as IconInfoOutline } from './info-outline.svg';
export { default as IconInfoOutline } from './info-outline.svg';
export { default as IconSpark } from './spark.svg'
12 changes: 12 additions & 0 deletions label_studio/frontend/src/assets/icons/spark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions label_studio/frontend/src/assets/images/heidi-speaking.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions label_studio/frontend/src/assets/images/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as HeidiSpeaking } from "./heidi-speaking.svg";
24 changes: 24 additions & 0 deletions label_studio/frontend/src/components/Badges/Enterprise.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.enterprise-badge
display inline-block
border-radius 4px
background linear-gradient(135deg, #FFA663 0%, #FF7557 51.56%, #E37BD3 100%)
vertical-align middle
margin 0 8px

&__label
margin 1px
background #FFF1EE
color #FF7557
border-radius 3px
font 11px Roboto
padding 2px 5px 2px 3px
display flex
gap 4px
align-items center

&_filled &__label
background none
color #FFF1EE

&_filled &__icon path
fill #FFF1EE
19 changes: 19 additions & 0 deletions label_studio/frontend/src/components/Badges/Enterprise.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FC } from "react";
import { IconSpark } from "../../assets/icons";
import { Block, Elem } from "../../utils/bem";
import "./Enterprise.styl";

export const EnterpriseBadge: FC<{
filled?: boolean
}> = ({
filled,
}) => {
return (
<Block name="enterprise-badge" mod={{ filled }}>
<Elem name="label">
<Elem name="icon" tag={IconSpark} />
Enterprise
</Elem>
</Block>
);
};
2 changes: 1 addition & 1 deletion label_studio/frontend/src/components/Button/Button.styl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
font-weight 500
font-size 16px

&:hover:not(:disabled):not(&_waiting)
&:hover:not(:disabled):not(&_waiting):not(&_type_text):not(&_type_link)
color var(--button-color)
box-shadow 0px 2px 4px rgba(#000, 0.05), inset 0px -1px 0px rgba(#000, 0.1), inset 0px 0px 0px 1px rgba(#000, 0.2)

Expand Down
8 changes: 8 additions & 0 deletions label_studio/frontend/src/components/Caption/Caption.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.caption
font 12px Roboto

a
color #09f

a::before
content " "
11 changes: 11 additions & 0 deletions label_studio/frontend/src/components/Caption/Caption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { FC, ReactElement } from "react";
import { Block } from "../../utils/bem";
import "./Caption.styl";

export const Caption: FC<{ children: ReactElement }> = ({ children }) => {
return (
<Block name="caption" tag="p">
{children}
</Block>
);
};
61 changes: 61 additions & 0 deletions label_studio/frontend/src/components/HeidiTips/HeidiTip.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.heidy-tip
&__content
padding 16px
color #000
border 1px solid #BFBFBF
font-family Roboto
font-size 14px
border-radius 8px
box-shadow 0px 2px 6px 0px rgba(0, 0, 0, 0.10)
box-sizing border-box

&__header
display flex
width 100%
min-height 24px
margin-bottom 8px
flex-direction row
justify-content space-between

&__title
font-size 16px
font-weight 500

&__link
color #09F
font-family Roboto
font-weight 500

&:hover
text-decoration underline

&::before
content " "

&__dismiss
width 24px
height 24px
padding 0
border none
display flex
box-shadow none
justify-content center
align-items center

svg
width 14px
height 14px

svg > path
stroke #898098

&:hover
background rgba(#096DD9, 0.05)

svg > path
stroke #1f1f1f

&__heidi
margin-top -12px
padding-left 16px
pointer-events none
69 changes: 69 additions & 0 deletions label_studio/frontend/src/components/HeidiTips/HeidiTip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { FC, MouseEvent, useCallback, useMemo } from "react";
import { Block, Elem } from "../../utils/bem";
import { LsCross } from "../../assets/icons";
import "./HeidiTip.styl";
import { Button } from "../Button/Button";
import { HeidiSpeaking } from "../../assets/images";
import { HeidiTipProps, Tip } from "./types";
import { Tooltip } from "../Tooltip/Tooltip";

export const HeidiTip: FC<HeidiTipProps> = ({ tip, onDismiss }) => {
const handleClick = useCallback((event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
onDismiss();
}, []);

return (
<Block name="heidy-tip">
<Elem name="content">
<Elem name="header">
<Elem name="title">
{tip.title}
</Elem>
{tip.closable && (
/* @ts-ignore-next-line */
<Tooltip title="Don't show">
{ /* @ts-ignore-next-line */}
<Elem name="dismiss" tag={Button} type="text" onClick={handleClick}>
<LsCross />
</Elem>
</Tooltip>
)}
</Elem>
<Elem name="text">
{tip.content}
<HeidiLink link={tip.link} />
</Elem>
</Elem>
<Elem name="heidi">
<HeidiSpeaking />
</Elem>
</Block>
);
};

const HeidiLink: FC<{ link: Tip["link"] }> = ({
juliosgarbi marked this conversation as resolved.
Show resolved Hide resolved
link,
}) => {
const url = useMemo(() => {
const base = new URL(link.url);

Object.keys(link.params ?? {}).forEach((key) => {
const value = link.params?.[key];

if (value) base.searchParams.set(key, value);
});

/* if needed, add server ID here */

return base.toString();
}, [link]);

return (
/* @ts-ignore-next-line */
<Elem name="link" tag="a" href={url} target="_blank">
{link.label}
</Elem>
);
};
18 changes: 18 additions & 0 deletions label_studio/frontend/src/components/HeidiTips/HeidiTips.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { FC, memo, useCallback, useState } from "react";
import { HeidiTipsProps } from './types';
import { HeidiTip } from "./HeidiTip";
import { dismissTip, getRandomTip, isTipDismissed } from "./utils";

export const HeidiTips: FC<HeidiTipsProps> = memo(({
collection,
}) => {
const [tip, setTip] = useState(getRandomTip(collection));
const dismiss = useCallback(() => {
dismissTip(collection);
setTip(null);
}, []);

return tip && (
<HeidiTip tip={tip} onDismiss={dismiss} />
);
});
83 changes: 83 additions & 0 deletions label_studio/frontend/src/components/HeidiTips/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Tip } from "./types";

export const TipsCollection: Record<string, Tip[]> = {
projectCreation: [{
title: "Did you know?",
content: "It’s easier to find the projects when you organize them into workspaces using Label Studio Enterprise.",
closable: true,
link: {
label: "Learn more",
url: "https://docs.humansignal.com/guide/manage_projects#Create-workspaces-to-organize-projects",
params: {
experiment: "placeholder",
treatment: "placeholder",
server_id: "placeholder",
},
},
}, {
title: "Unlock faster access provisioning",
content: "Streamline assigning staff to multiple projects by assigning them to workspaces in Label Studio Enterprise.",
closable: true,
link: {
label: "Learn more",
url: "https://docs.humansignal.com/guide/manage_projects#Add-or-remove-members-to-a-workspace",
params: {
experiment: "placeholder",
treatment: "placeholder",
server_id: "placeholder",
},
},
}, {
title: "Did you know?",
content: "Users with the Manager role can supervise a set of projects by assigning them to workspaces in Label Studio Enterprise.",
closable: true,
link: {
label: "Learn more",
url: "https://docs.humansignal.com/guide/manage_users#Roles-in-Label-Studio-Enterprise",
params: {
experiment: "placeholder",
treatment: "placeholder",
server_id: "placeholder",
},
},
}, {
title: "Did you know?",
content: "You can control access to specific projects and workspaces for internal team members and external annotators using Label Studio Enterprise.",
closable: true,
link: {
label: "Learn more",
url: "https://docs.humansignal.com/guide/manage_users#Roles-in-Label-Studio-Enterprise",
params: {
experiment: "placeholder",
treatment: "placeholder",
server_id: "placeholder",
},
},
}, {
title: "Did you know?",
content: "You can use or modify dozens or templates to configure your labeling UI, or create a custom configuration from scratch using simple XML-like tag",
closable: true,
link: {
label: "Learn more",
url: "https://labelstud.io/guide/setup",
params: {
experiment: "placeholder",
treatment: "placeholder",
server_id: "placeholder",
},
},
}, {
title: "Did you know?",
content: "You can label tasks with collaborators by setting the minimum number of annotations to more than one. ",
closable: true,
link: {
label: "Learn more",
url: "https://labelstud.io/guide/labeling#Label-with-collaborators",
params: {
experiment: "placeholder",
treatment: "placeholder",
server_id: "placeholder",
},
},
}],
};
21 changes: 21 additions & 0 deletions label_studio/frontend/src/components/HeidiTips/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { TipsCollection } from "./content";

export type Tip = {
title: string,
content: string,
closable?: boolean,
link: {
url: string,
label: string,
params?: Record<string, string>
},
}

export type HeidiTipsProps = {
collection: keyof typeof TipsCollection
}

export type HeidiTipProps = {
tip: Tip,
onDismiss: () => void
}
Loading
Loading