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] Redesign the selection popover of the tags #2248

Merged
merged 14 commits into from
Oct 6, 2022
Merged
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
20 changes: 18 additions & 2 deletions aim/web/ui/src/components/AttachedTagsList/AttachedTagsList.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
align-items: baseline;
font-size: $text-sm;
line-height: 15px;
position: relative;
margin-top: $space-xs;

&__title {
Expand All @@ -24,16 +25,20 @@
&__tags {
display: flex;
flex-wrap: wrap;
overflow: auto;
overflow: hidden;
&__tagWrapper {
max-width: 100%;
}

.Badge {
margin-bottom: $space-xs;
margin-right: $space-xs;
max-width: unset;
max-width: 100%;
}
}

&__ControlPopover__anchor {
max-width: 100%;
.icon-edit {
width: 1.5rem;
height: 1.5rem;
Expand All @@ -55,13 +60,24 @@
margin-right: $space-xs;
}
}

&__ControlPopover__editPopoverButton {
position: absolute;
top: toRem(-26px);
right: 0;
}
}

.InlineAttachedTagsList {
margin-top: 0;
align-items: center;
max-width: 100%;
width: 100%;
.AttachedTagsList__ControlPopover__anchor {
max-width: 100%;
width: 100%;
cursor: text;
}
.AttachedTagsList__tags {
align-items: center;
flex-wrap: unset;
Expand Down
166 changes: 43 additions & 123 deletions aim/web/ui/src/components/AttachedTagsList/AttachedTagsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ function AttachedTagsList({
addTagButtonSize = 'xSmall',
onTagsChange,
onRunsTagsChange,
hasAttachedTagsPopup = false,
inlineAttachedTagsList = false,
}: IAttachedTagsListProps) {
const [attachedTags, setAttachedTags] = React.useState<ITagInfo[]>(
tags ?? initialTags ?? [],
);
const [selectTagsPopoverKey, setSelectTagPopoverKey] = React.useState(
`${Date.now()}`,
);
const getRunInfoRef = React.useRef<any>(null);
const deleteRunsTagRef = React.useRef<any>(null);

const getRunInfo = React.useCallback((runHash: string): void => {
getRunInfoRef.current = runsService?.getRunInfo(runHash);
Expand All @@ -39,29 +41,6 @@ function AttachedTagsList({
});
}, []);

const deleteRunsTag = React.useCallback(
(run_id: string, tag: ITagInfo): void => {
deleteRunsTagRef.current = runsService?.deleteRunsTag(run_id, tag.id);
deleteRunsTagRef.current.call();
},
[],
);

const onAttachedTagDelete = React.useCallback(
(label: string): void => {
const tag = attachedTags.find((tag) => tag.name === label);
if (tag) {
const resultTags: ITagInfo[] = attachedTags.filter(
(t) => tag.id !== t.id,
);
setAttachedTags(resultTags);
deleteRunsTag(runHash, tag);
onRunsTagsChange && onRunsTagsChange(runHash, resultTags);
}
},
[onRunsTagsChange, attachedTags, deleteRunsTag, runHash],
);

React.useEffect(() => {
if (runHash) {
if (!initialTags && !tags) {
Expand All @@ -87,82 +66,43 @@ function AttachedTagsList({

const renderTagsBadges = React.useCallback(() => {
if (!_.isEmpty(attachedTags)) {
if (hasAttachedTagsPopup) {
return (
<div className='AttachedTagsList__tags ScrollBar__hidden'>
<ControlPopover
title={`Attached Tags (${attachedTags?.length})`}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
anchor={({ onAnchorClick }) => (
<div
className='AttachedTagsList__tags ScrollBar__hidden'
onClick={onAnchorClick}
>
{attachedTags.map((tag: ITagInfo) => (
<Badge
size='xSmall'
key={tag.id}
color={tag.color}
label={tag.name}
id={tag.id}
onDelete={onAttachedTagDelete}
/>
))}
</div>
)}
component={
<div className='InlineAttachedTagsList__tagsContainer'>
<div className='InlineAttachedTagsList__tagsContainer__tags'>
{attachedTags.map((tag: ITagInfo) => {
return (
<div
key={tag.id}
className='InlineAttachedTagsList__tagsContainer__tags__badge'
>
<Badge
size='xSmall'
color={tag.color}
label={tag.name}
id={tag.id}
onDelete={onAttachedTagDelete}
/>
</div>
);
})}
</div>
</div>
}
/>
</div>
);
}
return (
<div className='AttachedTagsList__tags ScrollBar__hidden'>
{attachedTags.map((tag: ITagInfo) => (
<Badge
size='xSmall'
key={tag.id}
color={tag.color}
label={tag.name}
id={tag.id}
onDelete={onAttachedTagDelete}
/>
<Tooltip key={tag.id} title={tag.name}>
<div className='AttachedTagsList__tags__tagWrapper'>
<Badge
size='xSmall'
color={tag.color}
label={tag.name}
id={tag.id}
/>
</div>
</Tooltip>
))}
</div>
);
}

return (
<div className='AttachedTagsList__noAttachedTags'>No attached tags</div>
<div className='AttachedTagsList__noAttachedTags'>
{inlineAttachedTagsList ? 'Click to edit tags' : 'No attached tags'}
</div>
);
}, [attachedTags]);

const renderAddTagsButton = React.useCallback(() => {
return (
<Button
withOnlyIcon
size={addTagButtonSize}
color='secondary'
className='AttachedTagsList__ControlPopover__editPopoverButton'
>
<Icon name='edit'></Icon>
</Button>
);
}, [attachedTags, onAttachedTagDelete, hasAttachedTagsPopup]);
}, [attachedTags, addTagButtonSize]);

return (
<ErrorBoundary>
Expand All @@ -176,12 +116,12 @@ function AttachedTagsList({
)}
<Box
className={classNames('AttachedTagsList', {
InlineAttachedTagsList: hasAttachedTagsPopup,
InlineAttachedTagsList: inlineAttachedTagsList,
})}
>
{renderTagsBadges()}
{!inlineAttachedTagsList && renderTagsBadges()}
<ControlPopover
title='Select Tag'
title='Tags'
titleClassName='AttachedTagsList__ControlPopover__title'
anchorOrigin={{
vertical: 'bottom',
Expand All @@ -192,43 +132,23 @@ function AttachedTagsList({
horizontal: 'right',
}}
anchor={({ onAnchorClick, opened }) => (
<Tooltip
title={`${!_.isEmpty(attachedTags) ? 'Select' : 'Attach'} Tag`}
<div
onClick={onAnchorClick}
className={`AttachedTagsList__ControlPopover__anchor ${
opened ? 'active' : ''
}`}
>
<div
onClick={onAnchorClick}
className={`AttachedTagsList__ControlPopover__anchor ${
opened ? 'active' : ''
}`}
>
{!_.isEmpty(attachedTags) ? (
<Button
withOnlyIcon
size={addTagButtonSize}
color='secondary'
>
<Icon name='edit'></Icon>
</Button>
) : (
<Button
size={addTagButtonSize}
color='primary'
variant='outlined'
className='AttachedTagsList__ControlPopover__attach'
>
<Icon name='plus' />
<span>Attach</span>
</Button>
)}
</div>
</Tooltip>
{inlineAttachedTagsList && renderTagsBadges()}
{!inlineAttachedTagsList && renderAddTagsButton()}
</div>
)}
component={
<SelectTag
runHash={runHash}
attachedTags={attachedTags}
setAttachedTags={setAttachedTags}
onRunsTagsChange={onRunsTagsChange}
updatePopover={setSelectTagPopoverKey}
/>
}
/>
Expand Down
81 changes: 67 additions & 14 deletions aim/web/ui/src/components/SelectTag/SelectTag.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,83 @@
.SelectTag {
max-width: 20rem;
width: 20rem;

max-height: 240px;
display: flex;
flex-direction: column;
&__searchBarContainer {
padding: $space-xs;
}
&__tags {
padding: $space-xs $space-unit;
overflow: auto;
display: flex;
flex-wrap: wrap;
max-height: 50vh;
.Badge {
margin: 0;
max-width: unset;
cursor: pointer;
}

max-height: 200px;
flex: 1 1;
.icon-check {
padding: 0;
}

&__badge {
&__item {
display: flex;
margin-bottom: $space-xs;
margin-right: $space-xs;
width: 100%;
max-width: 100%;
border-bottom: $border-main;
padding: $space-xs toRem(25px) $space-xs toRem(30px);
position: relative;
cursor: pointer;
&:hover {
background-color: $cuddle-20;
}
&:last-child {
border-bottom: $border-transparent;
}
&__checkedIcon {
position: absolute;
left: toRem(10px);
top: $space-xs;
}
&__deleteButton {
position: absolute;
right: toRem(10px);
top: $space-xxs;
}
&__content {
display: flex;
max-width: 100%;
flex-direction: column;
width: 100%;
padding-right: $space-xxxs;

&__nameWrapper {
display: flex;
align-items: flex-start;
&__name {
word-break: break-all;
}
&__colorBadge {
width: toRem(14px);
min-width: toRem(14px);
height: toRem(14px);
display: block;
border-radius: $border-radius-circle;
margin-right: $space-xxxs;
}
}

&__description {
margin-top: $space-xxxxs;
word-break: break-all;
}
}
}
}

&__noTags {
padding: 1rem 0;
display: flex;
justify-content: center;
flex: 1;
align-items: center;
}

&__createTag__container {
padding: $space-xs $space-unit;
text-align: center;
Expand Down
Loading