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

Shell 219 enhance primary bar component to include common customizations #483

21 changes: 9 additions & 12 deletions api-extractor/carbonio-shell-ui.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ type AppActions = {
setRouteVisibility: (id: string, visible: boolean) => void;
removeRoute: (id: string) => void;
updatePrimaryBadge: (badge: Partial<BadgeInfo>, id: string) => void;
updateUtilityBadge: (badge: Partial<BadgeInfo>, id: string) => void;
addBoardView: (data: BoardView) => string;
removeBoardView: (id: string) => void;
addSettingsView: (data: SettingsView) => string;
Expand Down Expand Up @@ -315,6 +314,7 @@ export type AudioNotificationConfig = {
// @public (undocumented)
export type BadgeInfo = {
show: boolean;
icon?: string;
count?: number;
showCount?: boolean;
color?: keyof DefaultTheme['palette'];
Expand Down Expand Up @@ -1014,6 +1014,7 @@ export type PrimaryAccessoryViewProps = {};
// @public (undocumented)
export type PrimaryBarComponentProps = {
active: boolean;
onClick: () => void;
};

// @public (undocumented)
Expand Down Expand Up @@ -1521,9 +1522,6 @@ type UpdateSettingsParams = {
}>;
};

// @public (undocumented)
export const updateUtilityBadge: (badge: Partial<BadgeInfo_2>, id: string) => void;

// @public (undocumented)
export const useAction: <T>(type: string, id: string, target?: T | undefined) => [Action | undefined, boolean];

Expand Down Expand Up @@ -1661,7 +1659,6 @@ export type UtilityBarComponentProps = {
type UtilityView = CarbonioAccessoryView<UtilityBarComponentProps> & {
button: string | ComponentType<UtilityBarComponentProps>;
component: ComponentType<UtilityBarComponentProps>;
badge: BadgeInfo;
label: string;
};

Expand Down Expand Up @@ -1718,12 +1715,12 @@ interface ZimletProp {
// lib/settings/components/settings-header.d.ts:5:5 - (ae-forgotten-export) The symbol "RouteLeavingGuardProps" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:23:5 - (ae-forgotten-export) The symbol "CarbonioModule" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:24:5 - (ae-forgotten-export) The symbol "AppRouteDescriptor" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:29:5 - (ae-forgotten-export) The symbol "BoardView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:31:5 - (ae-forgotten-export) The symbol "SettingsView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:33:5 - (ae-forgotten-export) The symbol "SearchView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:35:5 - (ae-forgotten-export) The symbol "UtilityView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:37:5 - (ae-forgotten-export) The symbol "PrimaryAccessoryView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:39:5 - (ae-forgotten-export) The symbol "SecondaryAccessoryView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:28:5 - (ae-forgotten-export) The symbol "BoardView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:30:5 - (ae-forgotten-export) The symbol "SettingsView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:32:5 - (ae-forgotten-export) The symbol "SearchView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:34:5 - (ae-forgotten-export) The symbol "UtilityView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:36:5 - (ae-forgotten-export) The symbol "PrimaryAccessoryView" needs to be exported by the entry point lib.d.ts
// lib/store/app/store.d.ts:38:5 - (ae-forgotten-export) The symbol "SecondaryAccessoryView" needs to be exported by the entry point lib.d.ts
// lib/store/context-bridge.d.ts:4:5 - (ae-forgotten-export) The symbol "PackageDependentFunction" needs to be exported by the entry point lib.d.ts
// lib/store/context-bridge.d.ts:5:5 - (ae-forgotten-export) The symbol "AnyFunction" needs to be exported by the entry point lib.d.ts
// lib/store/integrations/store.d.ts:26:9 - (ae-forgotten-export) The symbol "Action_2" needs to be exported by the entry point lib.d.ts
Expand All @@ -1736,7 +1733,7 @@ interface ZimletProp {
// lib/types/account/index.d.ts:138:5 - (ae-forgotten-export) The symbol "AccountRightTargetEmail" needs to be exported by the entry point lib.d.ts
// lib/types/account/index.d.ts:143:9 - (ae-forgotten-export) The symbol "AccountRightName" needs to be exported by the entry point lib.d.ts
// lib/types/account/index.d.ts:144:9 - (ae-forgotten-export) The symbol "AccountRightTarget" needs to be exported by the entry point lib.d.ts
// lib/types/apps/index.d.ts:66:5 - (ae-forgotten-export) The symbol "PanelMode" needs to be exported by the entry point lib.d.ts
// lib/types/apps/index.d.ts:68:5 - (ae-forgotten-export) The symbol "PanelMode" needs to be exported by the entry point lib.d.ts
// lib/types/misc/index.d.ts:75:9 - (ae-forgotten-export) The symbol "SoapPolicy" needs to be exported by the entry point lib.d.ts
// lib/types/misc/index.d.ts:94:5 - (ae-forgotten-export) The symbol "FolderView" needs to be exported by the entry point lib.d.ts
// lib/types/misc/index.d.ts:110:5 - (ae-forgotten-export) The symbol "Meta" needs to be exported by the entry point lib.d.ts
Expand Down
1 change: 0 additions & 1 deletion src/boot/app/app-direct-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ export { useLocalStorage } from '../../shell/hooks/useLocalStorage';

export const {
updatePrimaryBadge,
updateUtilityBadge,
setRouteVisibility,
removeRoute,
removeBoardView,
Expand Down
30 changes: 21 additions & 9 deletions src/shell/badge-wrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import type { FC } from 'react';
import React, { forwardRef } from 'react';

import { Container, Badge } from '@zextras/carbonio-design-system';
import { Container, Badge, Icon } from '@zextras/carbonio-design-system';
import styled from 'styled-components';

import type { BadgeInfo } from '../types/apps';
Expand All @@ -28,18 +28,30 @@ const MiniBadge = styled(Badge)`
}
`;

const MiniIcon = styled(Icon)`
position: absolute;
bottom: 25%;
right: 25%;
transform: translate(30%, 30%);
user-select: none;
cursor: pointer;
pointer-events: none;
z-index: 99;
`;

const BadgeWrap: FC<{ badge: BadgeInfo }> = forwardRef<HTMLDivElement, { badge: BadgeInfo }>(
function BadgeWrapFn({ badge, children }, ref): JSX.Element {
return (
<Container width={'3rem'} height={'3rem'} style={{ position: 'relative' }} ref={ref}>
{badge.show && (
<MiniBadge
color={'gray6'}
backgroundColor={badge.color ?? 'primary'}
data-testid={'badge-counter'}
value={badge.showCount ? badge.count ?? 0 : ''}
/>
)}
{(badge.show && badge.icon && <MiniIcon icon={badge.icon} color={badge.color} />) ||
CataldoMazzilli marked this conversation as resolved.
Show resolved Hide resolved
(badge.show && (
<MiniBadge
color={'gray6'}
backgroundColor={badge.color ?? 'primary'}
data-testid={'badge-counter'}
value={badge.showCount ? badge.count ?? 0 : ''}
/>
))}
{children}
</Container>
);
Expand Down
21 changes: 21 additions & 0 deletions src/shell/shell-primary-bar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -538,5 +538,26 @@ describe('Shell primary bar', () => {
expect(counterBadge).toBeVisible();
expect(counterBadge).toHaveTextContent('');
});

it('should render icon instead of badge when icon is provided in badge info', () => {
const primaryBarViews: PrimaryBarView[] = [
{
id: 'pbv-1',
app: 'app1',
label: 'App One',
route: 'app1',
position: 1,
badge: { show: true, icon: ICONS.search, showCount: true },
visible: true,
component: 'People'
}
];
useAppStore.setState((state) => ({
views: { ...state.views, primaryBar: primaryBarViews }
}));
setup(<ShellPrimaryBar />);
expect(screen.queryByTestId('badge-counter')).not.toBeInTheDocument();
expect(screen.getByTestId(`icon: ${ICONS.search}`)).toBeVisible();
});
});
});
2 changes: 1 addition & 1 deletion src/shell/shell-primary-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const PrimaryBarElement = ({ view, active, onClick }: PrimaryBarItemProps): Reac
size="large"
/>
) : (
<view.component active={active} />
<view.component active={active} onClick={onClick} />
)}
</BadgeWrap>
</Tooltip>
Expand Down
14 changes: 0 additions & 14 deletions src/store/app/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export type AppActions = {
setRouteVisibility: (id: string, visible: boolean) => void;
removeRoute: (id: string) => void;
updatePrimaryBadge: (badge: Partial<BadgeInfo>, id: string) => void;
updateUtilityBadge: (badge: Partial<BadgeInfo>, id: string) => void;
addBoardView: (data: BoardView) => string;
removeBoardView: (id: string) => void;
addSettingsView: (data: SettingsView) => string;
Expand Down Expand Up @@ -365,18 +364,5 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
}
})
);
},
updateUtilityBadge: (badge, id): void => {
set(
produce<AppState>((state) => {
const idx = findIndex(state.views.utilityBar, (bar) => bar.id === id);
if (idx >= 0) {
state.views.utilityBar[idx].badge = {
...state.views.utilityBar[idx].badge,
...badge
};
}
})
);
}
}));
2 changes: 1 addition & 1 deletion src/store/app/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const normalizeApp = (app: Partial<CarbonioModule>): CarbonioModule => ({
const FallbackView: FC = () => <p>Missing Component</p>;

export const normalizeBadgeInfo = (badge: Partial<BadgeInfo>): BadgeInfo => ({
...badge,
show: badge.show ?? false,
count: badge.count ?? 0,
showCount: badge.showCount ?? false,
Expand Down Expand Up @@ -103,7 +104,6 @@ export const normalizeUtilityView = (
blacklistRoutes: data?.blacklistRoutes,
component: data?.component ?? FallbackView,
button: data?.button ?? 'Cube',
badge: normalizeBadgeInfo(data?.badge ?? {}),
position: data?.position ?? app.priority,
label: data?.label ?? app.display
});
Expand Down
4 changes: 2 additions & 2 deletions src/types/apps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type AppRoute = {

export type BadgeInfo = {
show: boolean;
icon?: string;
count?: number;
showCount?: boolean;
color?: keyof DefaultTheme['palette'];
Expand All @@ -55,7 +56,7 @@ export type CarbonioAccessoryView<P> = {
position: number;
component: ComponentType<P>;
};
export type PrimaryBarComponentProps = { active: boolean };
export type PrimaryBarComponentProps = { active: boolean; onClick: () => void };
export type SecondaryBarComponentProps = { expanded: boolean };
export type AppViewComponentProps = {};
export type BoardViewComponentProps = {};
Expand Down Expand Up @@ -87,7 +88,6 @@ export type BoardView = Omit<CarbonioView<BoardViewComponentProps>, 'route'>;
export type UtilityView = CarbonioAccessoryView<UtilityBarComponentProps> & {
button: string | ComponentType<UtilityBarComponentProps>;
component: ComponentType<UtilityBarComponentProps>;
badge: BadgeInfo;
label: string;
};
export type SettingsSubSection = { label: string; id: string };
Expand Down