Skip to content

Commit

Permalink
NEW GUI: Home page panels - add icons (#3780 #3781 #3782)
Browse files Browse the repository at this point in the history
NEW GUI: panels mode toggler for presentation, mode styles

NEW GUI: panels mode toggler for presentation, mode styles
  • Loading branch information
AleksandrGorodetskii authored and rodichenko committed Nov 29, 2024
1 parent ea9322b commit ce144e5
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 28 deletions.
19 changes: 16 additions & 3 deletions portals-ui/packages/components/lib/components/list/list-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ import classNames from 'classnames';
import { SearchInput } from '@epam/uui';
import type { ListHeaderProps } from './types';

const controlsCx = {
standard: 'px-3 py-3',
compact: 'p-2',
} as Record<string, string>;

const searchCx = {
standard: 'py-0.5 px-1',
compact: 'p-0.5',
} as Record<string, string>;

const ListHeader = (props: ListHeaderProps) => {
const {
className,
Expand All @@ -11,17 +21,20 @@ const ListHeader = (props: ListHeaderProps) => {
search,
onSearch,
searchPlaceholder,
mode = 'compact',
} = props;
return (
<div className={classNames(className, 'divide-y')} style={style}>
<div
className="flex items-center no-wrap p-2"
style={{ color: 'var(--uui-text-secondary)' }}>
className={classNames(
'flex text items-center no-wrap',
controlsCx[mode],
)}>
<b>{title}</b>
{controls ? <div className="ml-auto">{controls}</div> : null}
</div>
{onSearch ? (
<div className="p-0.5">
<div className={searchCx[mode]}>
<SearchInput
value={search}
onValueChange={onSearch}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export type ListHeaderProps = CommonProps & {
searchPlaceholder?: string;
onSearch?: (search: string) => void;
controls?: ReactNode;
mode: 'standard' | 'compact';
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ export const PipelineCard = ({
const { id, name, owner, description } = pipeline;

return (
<div
className={cn('px-3 py-2 bg-white w-full space-y-1', className)}
style={style}>
<div className={cn('bg-white w-full space-y-1', className)} style={style}>
{tags?.length && (
<FlexRow columnGap="6" size="24">
{tags.map((tag) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,47 @@ import { ItemsPanel } from '../../../widgets/items-panel/items-panel';
import { PipelineCard } from './pipeline-card';
import { memo } from 'react';
import cn from 'classnames';
import NavigationDependencyOutlineIcon from '@epam/assets/icons/navigation-dependency-outline.svg?react';

type Props = {
pipelines: Pipeline[] | undefined;
mode: 'standard' | 'compact';
};

export const PipelinesList = memo(({ pipelines }: Props) => {
const cardCx = {
standard: 'px-3 py-2',
compact: 'px-2 py-1',
};

export const PipelinesList = memo(({ pipelines, mode }: Props) => {
const renderItem = (item: Pipeline, search: string, i: number) => {
return (
<PipelineCard
key={item.id}
pipeline={item}
highlightedText={search}
className={cn({ ['border-t']: i !== 0 })}
className={cn(cardCx[mode], { ['border-t']: i !== 0 })}
/>
);
};

return (
<ItemsPanel
className="max-h-full list-container overflow-auto"
title="Pipelines"
title={
<div className="fill-current flex flex-nowrap gap-1">
<span className="rotate-90">
<NavigationDependencyOutlineIcon />
</span>
<span>Pipelines</span>
</div>
}
items={pipelines}
renderItem={renderItem}
sliced
search
itemKey="id"
mode={mode}
viewAll={{ title: 'View all pipelines', link: '/pipelines' }}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ export const ProjectCard = ({
const hasSomeRights = read || write || execute;

return (
<div
className={cn('px-3 py-2 bg-white w-full space-y-1', className)}
style={style}>
<div className={cn('bg-white w-full space-y-1', className)} style={style}>
{tags?.length && (
<FlexRow columnGap="6" size="24">
{tags.map((tag) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,53 @@ import { ProjectCard } from './project-card';
import { ItemsPanel } from '../../../widgets/items-panel/items-panel';
import cn from 'classnames';
import { memo } from 'react';
import ActionAddFillIcon from '@epam/assets/icons/action-add-outline.svg?react';
import ActionJobFunctionOutlineIcon from '@epam/assets/icons/action-job_function-outline.svg?react';

type Props = {
projects: Project[] | undefined;
mode: 'standard' | 'compact';
};

export const ProjectsList = memo(({ projects }: Props) => {
const cardCx = {
standard: 'px-3 py-2',
compact: 'px-2 py-1',
};

export const ProjectsList = memo(({ projects, mode }: Props) => {
console.log(mode)
const renderItem = (item: Project, search: string, i: number) => (
<ProjectCard
key={String(item.id)}
project={item}
highlightedText={search}
className={cn({ ['border-t']: i !== 0 })}
className={cn(cardCx[mode], { ['border-t']: i !== 0 })}
/>
);

return (
<ItemsPanel
className="max-h-full list-container overflow-auto"
title="Projects"
title={
<div className="fill-current flex flex-nowrap gap-1">
<ActionJobFunctionOutlineIcon />
<span>Projects</span>
</div>
}
actions={
<Button caption="Create project" size="24" onClick={() => null} />
<Button
icon={ActionAddFillIcon}
caption="Create project"
size="24"
onClick={() => null}
/>
}
items={projects}
renderItem={renderItem}
sliced
search
itemKey="id"
mode={mode}
viewAll={{ title: 'View all projects', link: '/projects' }}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ export const RunCard = ({ run, className, style }: Props) => {

return (
<div
className={cn(
'px-3 py-2 bg-white w-full space-y-1 flex flex-col gap-2',
className,
)}
className={cn('bg-white w-full space-y-1 flex flex-col gap-2', className)}
style={style}>
<FlexRow
columnGap="12"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,45 @@ import { ItemsPanel } from '../../../widgets/items-panel/items-panel.tsx';
import { useAuthenticatedUserRuns } from '../../../shared/hooks/use-runs-filter.ts';
import { RunCard } from './run-card.tsx';
import cn from 'classnames';
import MediaPlayOutlineOptIcon from '@epam/assets/icons/media-play-outline-opt.2.svg?react';

export const RunsList = () => {
const cardCx = {
standard: 'px-3 py-2',
compact: 'px-2 py-1',
};

type Props = {
mode: 'standard' | 'compact';
};

export const RunsList = (props: Props) => {
const { mode = 'compact' } = props;
const { runs } = useAuthenticatedUserRuns({ reloadIntervalMs: 5000 });

const renderItem = (item: Run, _: string, i: number) => {
return (
<RunCard
key={item.id}
run={item}
className={cn({ ['border-t']: i !== 0 })}
className={cn(cardCx[mode], { ['border-t']: i !== 0 })}
/>
);
};

return (
<ItemsPanel
className="max-h-full list-container overflow-auto"
title="Runs history"
renderItem={renderItem}
title={
<div className="fill-current flex flex-nowrap gap-1">
<MediaPlayOutlineOptIcon />
<span>Runs history</span>
</div>
}
items={runs}
sliced
itemKey="id"
mode={props.mode}
viewAll={{ title: 'View all runs', link: '/runs' }}
/>
);
Expand Down
30 changes: 25 additions & 5 deletions portals-ui/sites/ngs-portal/src/pages/home/home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useProjectsState } from '../../state/projects/hooks';
import { loadProjects } from '../../state/projects/load-projects';
import { usePipelinesState } from '../../state/pipelines/hooks.ts';
Expand All @@ -10,6 +10,8 @@ export const Home = () => {
const { projects } = useProjectsState();
const { pipelines } = usePipelinesState();

const [mode, setMode] = useState<'standard' | 'compact'>('compact');

useEffect(() => {
loadProjects()
.then(() => {})
Expand All @@ -20,18 +22,36 @@ export const Home = () => {
.catch(() => {});
}, []);

const toggleMode = () => {
const toggler = {
standard: 'compact',
compact: 'standard',
} as Record<string, 'standard' | 'compact'>;
setMode(toggler[mode]);
};

return (
<div className="flex h-full w-full gap-1 overflow-hidden flex-nowrap p-1">
<div className="relative flex h-full w-full gap-1 overflow-hidden flex-nowrap p-1">
<div className="flex-1 h-full overflow-auto p-2">
<ProjectsList projects={projects} />
<ProjectsList mode={mode} projects={projects} />
</div>

<div className="flex-1 h-full overflow-auto p-2">
<PipelinesList pipelines={pipelines} />
<PipelinesList mode={mode} pipelines={pipelines} />
</div>

<div className="flex-1 h-full overflow-auto p-2">
<RunsList />
<RunsList mode={mode} />
</div>
<div
onClick={toggleMode}
className="text-faded"
style={{
position: 'absolute',
cursor: 'pointer',
top: '97%',
}}>
+
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function ItemsPanel<Item>(props: ItemsPanelProps<Item>) {
virtualized,
sliced,
viewAll,
mode = 'compact',
} = props;
const searchEnabled = Boolean(searchConfig);
const searchOptions = useMemo<SearchOptions<Item>>(() => {
Expand All @@ -68,6 +69,7 @@ export function ItemsPanel<Item>(props: ItemsPanelProps<Item>) {
search={search}
onSearch={searchEnabled ? onSearchChange : undefined}
controls={actions}
mode={mode}
/>
{filtered.length > 0 && (
<List
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export type ItemsPanelProps<Item> = Omit<
? boolean | Omit<SearchOptions<Item>, 'items'>
: Omit<SearchOptions<Item>, 'items'>;
viewAll?: ViewAllItemsConfiguration;
mode: 'standard' | 'compact';
};

0 comments on commit ce144e5

Please sign in to comment.