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(ui/dashboard): improvement tags and table cell view with tooltip #1452

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f969972
feat: improve table list
steveninhle Jan 9, 2025
9a015ab
feat: improve table list
steveninhle Jan 9, 2025
642e08d
feat: improve table list
steveninhle Jan 16, 2025
5a7b501
feat: update tags column to members list page
steveninhle Jan 17, 2025
bd5786e
feat: update tags column to members list page
steveninhle Jan 17, 2025
058ba37
build: fix embed.go not found (#1439)
cre8ivejp Jan 9, 2025
e3d3624
build(deps): bump golang.org/x/net from 0.28.0 to 0.33.0 (#1434)
dependabot[bot] Jan 9, 2025
880e82a
chore: implement tag name (#1438)
cre8ivejp Jan 9, 2025
e999df0
test: fix feature e2e test (#1442)
cre8ivejp Jan 9, 2025
e79fc73
Fix code scanning alert no. 7: Clear-text logging of sensitive inform…
kentakozuka Jan 9, 2025
8c9ac26
feat: implement rest update and delete segment REST (#1441)
hvn2k1 Jan 10, 2025
4c01ea5
feat(ui/dashboard): slack management (#1402)
steveninhle Jan 10, 2025
ce57b62
feat: implement create, list, get goal REST api no command (#1445)
hvn2k1 Jan 10, 2025
6d8812e
build: fix ui/dashboard deleting necessary file (#1446)
cre8ivejp Jan 10, 2025
3f92570
ci: fix warning when setting the yarn cache (#1447)
cre8ivejp Jan 11, 2025
620d48b
feat: implement REST bulk download segment users (#1448)
hvn2k1 Jan 14, 2025
5cc50a4
chore: add order by feature_ids in segment list api (#1449)
cre8ivejp Jan 14, 2025
84c0dee
feat: add tag service (#1443)
cre8ivejp Jan 14, 2025
24a79f3
chore: add order by users in segment list api (#1450)
cre8ivejp Jan 14, 2025
96aa92a
feat(ui/dashboard): user segments management (#1426)
steveninhle Jan 15, 2025
4f28aec
fix(ui): debugger results text overflow (#1453)
bimalgrg519 Jan 15, 2025
0a93593
chore: add tags column to account table (#1454)
cre8ivejp Jan 15, 2025
a5317f8
chore: remove environment_namesapce column from db (#1444)
Ubisoft-potato Jan 16, 2025
8d23ed8
chore: remove mau table alter sql in migration (#1458)
Ubisoft-potato Jan 16, 2025
32c989d
chore: add tags field to account api proto file (#1455)
cre8ivejp Jan 17, 2025
5d24df4
feat(ui/dashboard): user segments management (#1426)
steveninhle Jan 15, 2025
e279f8f
Merge branch 'main' into feat-table-list-improvement
steveninhle Jan 17, 2025
ded28fc
feat: update tooltip members form
steveninhle Jan 17, 2025
9212ae9
feat: update tooltip members form
steveninhle Jan 17, 2025
ee49fe8
feat: update tags label
steveninhle Jan 18, 2025
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 ui/dashboard/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"organization-subtitle": "You can see all your clients data",
"setting-subtitle": "Manage settings about the current organization",
"project-subtitle": "Manage all projects for this environment.",
"member-subtitle": "Manage all members for this environment.",
"member-subtitle": "Manage all members in your organization. Select a member to manage the role settings and tags, or invite a new one.",
"organization-settings": "Organization settings",
"navigation": {
"my-projects": "My projects",
Expand Down
4 changes: 3 additions & 1 deletion ui/dashboard/public/locales/en/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,7 @@
"update-user-segment": "Updating this field will replace the current list with the new one.",
"update-user-segment-warning": "<p>The user ID list can't be updated because {{count}} flag is using it. Remove the segment from the flag before updating it.</p>",
"placeholder-enter-user-ids": "Enter IDs separated by commas (E.g., userId1, userId2, userId3,...)",
"accept-file-types": "{{type}}"
"accept-file-types": "{{type}}",
"member-tags-tooltip": "Tags can be used to group members making it easier when listing them on the list page",
"feature-flag-tags": "Feature Flag Tags"
}
2 changes: 1 addition & 1 deletion ui/dashboard/public/locales/ja/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"organization-subtitle": "You can see all your clients data",
"setting-subtitle": "Manage settings about the current organization",
"project-subtitle": "Manage all projects for this environment.",
"member-subtitle": "Manage all members for this environment.",
"member-subtitle": "Manage all members in your organization. Select a member to manage the role settings and tags, or invite a new one.",
"organization-settings": "Organization settings",
"navigation": {
"my-projects": "My projects",
Expand Down
4 changes: 3 additions & 1 deletion ui/dashboard/public/locales/ja/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,7 @@
"update-user-segment": "Updating this field will replace the current list with the new one.",
"update-user-segment-warning": "<p>The user ID list can't be updated because {{count}} flag is using it. Remove the segment from the flag before updating it.</p>",
"placeholder-enter-user-ids": "Enter IDs separated by commas (E.g., userId1, userId2, userId3,...)",
"accept-file-types": "{{type}}"
"accept-file-types": "{{type}}",
"member-tags-tooltip": "Tags can be used to group members making it easier when listing them on the list page",
"feature-flag-tags": "Feature Flag Tags"
}
1 change: 1 addition & 0 deletions ui/dashboard/src/@api/account/account-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface AccountCreatorCommand {
email: string;
organizationRole: OrganizationRole;
environmentRoles: EnvironmentRoleItem[];
tags: string[];
}

export interface AccountCreatorParams {
Expand Down
3 changes: 3 additions & 0 deletions ui/dashboard/src/@api/account/account-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export interface AccountUpdaterParams {
avatarImage: string;
avatarFileType: string;
};
changeTagsCommand?: {
tags: string[];
};
}

export const accountUpdater = async (params?: AccountUpdaterParams) => {
Expand Down
3 changes: 3 additions & 0 deletions ui/dashboard/src/@icons/customized-icons/angle-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions ui/dashboard/src/@icons/customized-icons/chevron-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions ui/dashboard/src/@icons/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import IconAngleDown from './customized-icons/angle-down.svg?react';
import IconBackspace from './customized-icons/backspace.svg?react';
import IconChecked from './customized-icons/checked.svg?react';
import IconChevronDown from './customized-icons/chevron-down.svg?react';
import IconChevronRight from './customized-icons/chevron-right.svg?react';
import IconClose from './customized-icons/close.svg?react';
import IconCopy from './customized-icons/copy.svg?react';
Expand Down Expand Up @@ -77,6 +79,8 @@ export {
IconDisable,
IconCopy,
IconUpload,
IconChevronDown,
IconAngleDown,
// Special icons
IconGoal,
IconGoogle,
Expand Down
1 change: 1 addition & 0 deletions ui/dashboard/src/@types/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface Account {
defaultFilter: boolean;
}
];
tags: string[];
}

export interface AccountCollection {
Expand Down
3 changes: 2 additions & 1 deletion ui/dashboard/src/@types/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export type OrderBy =
| 'CREATOR_EMAIL'
| 'ENVIRONMENT'
| 'CONNECTIONS'
| 'USERS';
| 'USERS'
| 'TAGS';

export type OrderDirection = 'ASC' | 'DESC';

Expand Down
32 changes: 27 additions & 5 deletions ui/dashboard/src/components/tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import { cn } from 'utils/style';

export type TooltipProps = {
align?: 'start' | 'center' | 'end';
delayDuration?: number;
hidden?: boolean;
content?: string;
trigger: ReactNode;
className?: string;
alignOffset?: number;
};

const TooltipProvider = TooltipPrimitive.Provider;
Expand All @@ -25,7 +29,7 @@ const TooltipContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
'data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade select-none rounded-md px-3 py-1.5 text-para-medium will-change-[transform,opacity] bg-additional-gray-150 text-white',
'data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade select-none rounded px-3 py-1.5 text-para-medium will-change-[transform,opacity] bg-gray-700 text-white',
className
)}
{...props}
Expand All @@ -35,17 +39,35 @@ const TooltipContent = React.forwardRef<
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

const Tooltip = forwardRef(
({ content, trigger, className }: TooltipProps, ref: Ref<HTMLDivElement>) => {
(
{
delayDuration = 700,
align = 'center',
hidden,
content,
trigger,
className,
alignOffset = 0
}: TooltipProps,
ref: Ref<HTMLDivElement>
) => {
return (
<TooltipProvider>
<TooltipProvider delayDuration={delayDuration}>
<TooltipRoot>
<TooltipTrigger type="button" asChild>
{trigger}
</TooltipTrigger>
{content && (
<TooltipContent ref={ref} className={className} sideOffset={5}>
<TooltipContent
hidden={hidden}
ref={ref}
className={className}
sideOffset={5}
alignOffset={alignOffset}
align={align}
>
{content}
<TooltipArrow className="fill-additional-gray-150" />
<TooltipArrow className="fill-gray-700" />
</TooltipContent>
)}
</TooltipRoot>
Expand Down
3 changes: 2 additions & 1 deletion ui/dashboard/src/constants/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export const sortingListFields: SortingListFields = {
lastSeen: 'LAST_SEEN',
environment: 'ENVIRONMENT',
connections: 'CONNECTIONS',
users: 'USERS'
users: 'USERS',
tags: 'TAGS'
};
5 changes: 4 additions & 1 deletion ui/dashboard/src/elements/data-table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ export const DataTable = <TData, TValue>({
{row.getVisibleCells().map(cell => (
<Table.Cell
key={cell.id}
style={{ width: cell.column.columnDef.size }}
style={{
width: cell.column.columnDef.size,
maxWidth: cell.column.columnDef.maxSize
}}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</Table.Cell>
Expand Down
94 changes: 94 additions & 0 deletions ui/dashboard/src/elements/expandable-tag/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { useCallback, useMemo, useState } from 'react';
import { cn } from 'utils/style';
import { IconChevronDown } from '@icons';
import Icon from 'components/icon';
import TruncationWithTooltip from 'elements/truncation-with-tooltip';

export const Tag = ({
tagId,
value,
className
}: {
tagId?: string;
value: string;
className?: string;
}) => (
<TruncationWithTooltip
elementId={tagId || ''}
content={value}
maxSize={250}
className="!w-fit"
>
<div
id={tagId}
className={cn(
'px-2 py-1.5 bg-primary-100/70 text-primary-500 typo-para-small !w-fit leading-[14px] rounded whitespace-nowrap',
className
)}
>
{value}
</div>
</TruncationWithTooltip>
);

const ExpandableTag = ({
rowId,
tags,
className
}: {
rowId: string;
tags: string[];
className?: string;
}) => {
const [expandedTags, setExpandedTags] = useState<string[]>([]);

const isExpanded = useMemo(
() => expandedTags.includes(rowId),
[expandedTags, rowId]
);

const handleExpandTag = useCallback(() => {
setExpandedTags(
isExpanded
? expandedTags.filter(item => item !== rowId)
: [...expandedTags, rowId]
);
}, [expandedTags, rowId, isExpanded]);

return (
<div
className={cn('flex items-center w-full gap-x-2', {
'items-start': isExpanded
})}
>
<div className="flex w-fit items-center flex-wrap gap-2">
{(isExpanded ? tags : tags.slice(0, 3))?.map((tag, index) => (
<Tag
tagId={`${tag}-${index}`}
key={index}
value={tag}
className={className}
/>
))}
{tags.length > 3 && !isExpanded && (
<Tag value={`+${tags.length - 3}`} />
)}
</div>
{tags.length > 3 && (
<div
className={cn('flex-center cursor-pointer hover:bg-gray-200 rounded')}
onClick={handleExpandTag}
>
<Icon
icon={IconChevronDown}
size={'sm'}
className={cn('flex-center rotate-0', {
'rotate-180': isExpanded
})}
/>
</div>
)}
</div>
);
};
export default ExpandableTag;
79 changes: 79 additions & 0 deletions ui/dashboard/src/elements/tag/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { cn } from 'utils/style';
import { IconChevronDown } from '@icons';
import Icon from 'components/icon';
import TruncationWithTooltip from 'elements/truncation-with-tooltip';

export const Tag = ({
tagId,
value,
className
}: {
tagId?: string;
value: string;
className?: string;
}) => (
<TruncationWithTooltip
elementId={tagId || ''}
content={value}
maxSize={250}
className="!w-fit"
>
<div
id={tagId}
className={cn(
'px-2 py-1.5 bg-primary-100/70 text-primary-500 typo-para-small !w-fit leading-[14px] rounded whitespace-nowrap',
className
)}
>
{value}
</div>
</TruncationWithTooltip>
);

export const renderTag = ({
tags,
isExpanded,
className,
onExpand
}: {
tags: string[];
isExpanded: boolean;
className?: string;
onExpand: () => void;
}) => {
return (
<div
className={cn('flex items-center w-full gap-x-2', {
'items-start': isExpanded
})}
>
<div className="flex w-fit items-center flex-wrap gap-2">
{(isExpanded ? tags : tags.slice(0, 3))?.map((tag, index) => (
<Tag
tagId={`${tag}-${index}`}
key={index}
value={tag}
className={className}
/>
))}
{tags.length > 3 && !isExpanded && (
<Tag value={`+${tags.length - 3}`} />
)}
</div>
{tags.length > 3 && (
<div
className={cn('flex-center cursor-pointer hover:bg-gray-200 rounded')}
onClick={onExpand}
>
<Icon
icon={IconChevronDown}
size={'sm'}
className={cn('flex-center rotate-0', {
'rotate-180': isExpanded
})}
/>
</div>
)}
</div>
);
};
Loading
Loading