From b39a14a14014ff78209d636f3edc93507b443fd2 Mon Sep 17 00:00:00 2001 From: Sean Erik Scully Date: Mon, 18 Nov 2024 19:23:06 +0100 Subject: [PATCH] fix: fixing selecting current account and simplify API for Header (#58) --- lib/components/GlobalMenu/AccountButton.tsx | 3 +- lib/components/GlobalMenu/AccountMenu.tsx | 17 +++++++-- .../GlobalMenu/GlobalMenu.stories.tsx | 12 +++--- lib/components/GlobalMenu/GlobalMenu.tsx | 37 +++++++++++-------- lib/components/Header/Header.stories.tsx | 32 ++++++++++++---- lib/components/Header/Header.tsx | 20 +++++----- lib/components/Layout/Layout.stories.tsx | 9 ++++- lib/stories/Inbox/InboxLayout.tsx | 1 + lib/stories/Inbox/InboxProvider.tsx | 1 - 9 files changed, 86 insertions(+), 46 deletions(-) diff --git a/lib/components/GlobalMenu/AccountButton.tsx b/lib/components/GlobalMenu/AccountButton.tsx index 28fd031..586d811 100644 --- a/lib/components/GlobalMenu/AccountButton.tsx +++ b/lib/components/GlobalMenu/AccountButton.tsx @@ -1,6 +1,7 @@ import { MenuItemBase, MenuItemLabel, MenuItemMedia } from '../Menu'; -type Account = { +export type Account = { + id: string; type: 'person' | 'company'; name: string; description?: string; diff --git a/lib/components/GlobalMenu/AccountMenu.tsx b/lib/components/GlobalMenu/AccountMenu.tsx index 6638d9b..67c385f 100644 --- a/lib/components/GlobalMenu/AccountMenu.tsx +++ b/lib/components/GlobalMenu/AccountMenu.tsx @@ -10,7 +10,7 @@ export interface AccountSearch extends MenuSearchProps { export interface AccountMenuItem { type: 'person' | 'company'; name: string; - id?: string; + id: string; groupId?: string; selected?: boolean; } @@ -19,20 +19,29 @@ export interface AccountMenuProps { accounts?: AccountMenuItem[]; accountGroups?: MenuItemGroups; accountSearch?: AccountSearch; + currentAccount?: AccountMenuItem; + onSelectAccount?: (id: string) => void; } const defaultResultLabel = (hits: number) => `${hits} hits`; -export const AccountMenu = ({ accounts = [], accountGroups = {}, accountSearch }: AccountMenuProps) => { +export const AccountMenu = ({ + accounts = [], + accountGroups = {}, + accountSearch, + onSelectAccount, + currentAccount, +}: AccountMenuProps) => { const accountMenu: MenuItemProps[] = accounts.map((account) => ({ - id: account.name, + id: account.id || account.name, groupId: account.groupId || 'search', - selected: account.selected, + selected: account.selected ?? currentAccount?.id === account.id, title: account.name, avatar: { type: account.type, name: account.name, }, + onClick: () => onSelectAccount?.(account.id || account.name), })); const [filterString, setFilterString] = useState(''); diff --git a/lib/components/GlobalMenu/GlobalMenu.stories.tsx b/lib/components/GlobalMenu/GlobalMenu.stories.tsx index a0dd34b..46eb5a3 100644 --- a/lib/components/GlobalMenu/GlobalMenu.stories.tsx +++ b/lib/components/GlobalMenu/GlobalMenu.stories.tsx @@ -23,40 +23,40 @@ const meta = { }, accounts: [ { + id: 'party:mathias', groupId: 'primary', type: 'person', name: 'Mathias Dyngeland', - selected: true, }, { + id: 'party:bergerbar', groupId: 'favourites', type: 'company', name: 'Bergen bar', - selected: false, }, { + id: 'party:keeperhansker', groupId: 'secondary', type: 'company', name: 'Keeperhansker AS', - selected: false, }, { + id: 'party:stadiondrift', groupId: 'secondary', type: 'company', name: 'Stadion drift AS', - selected: false, }, { + id: 'party:brann', groupId: 'favourites', type: 'company', name: 'Sportsklubben Brann', - selected: false, }, { + id: 'party:landslaget', groupId: 'secondary', type: 'company', name: 'Landslaget', - selected: false, }, ], groups: { diff --git a/lib/components/GlobalMenu/GlobalMenu.tsx b/lib/components/GlobalMenu/GlobalMenu.tsx index 6e3c064..bee0093 100644 --- a/lib/components/GlobalMenu/GlobalMenu.tsx +++ b/lib/components/GlobalMenu/GlobalMenu.tsx @@ -1,20 +1,13 @@ 'use client'; import { type MouseEventHandler, useState } from 'react'; import { Menu, type MenuItemGroups, type MenuItemProps } from '../Menu'; -import { AccountButton } from './AccountButton'; +import { type Account, AccountButton } from './AccountButton'; import { AccountMenu, type AccountMenuProps } from './AccountMenu'; import { BackButton } from './BackButton'; import { GlobalMenuBase, GlobalMenuFooter, GlobalMenuHeader } from './GlobalMenuBase'; import { LogoutButton } from './LogoutButton'; -export interface CurrentAccount { - type: 'person' | 'company'; - name: string; - description?: string; -} - export interface GlobalMenuProps extends AccountMenuProps { - currentEndUser?: CurrentAccount; expanded: boolean; onToggle: MouseEventHandler; items: MenuItemProps[]; @@ -24,10 +17,11 @@ export interface GlobalMenuProps extends AccountMenuProps { changeLabel?: string; logoutLabel?: string; className?: string; + currentAccount?: Account; + changeCurrentAccount?: (id: string) => void; } export const GlobalMenu = ({ - currentEndUser, accounts = [], accountGroups = {}, accountSearch, @@ -36,27 +30,40 @@ export const GlobalMenu = ({ changeLabel = 'Change', logoutLabel = 'Logout', backLabel = 'Back', + currentAccount, + changeCurrentAccount, }: GlobalMenuProps) => { - const [selectAccount, setSelectAccount] = useState(false); + const [selectingAccount, setSelectingAccount] = useState(false); const onToggleAccounts = () => { - setSelectAccount((prevState) => !prevState); + setSelectingAccount((prevState) => !prevState); + }; + + const onSelectAccount = (id: string) => { + onToggleAccounts(); + changeCurrentAccount?.(id); }; - if (selectAccount) { + if (selectingAccount) { return ( - + ); } - if (currentEndUser) { + if (currentAccount) { return ( - + diff --git a/lib/components/Header/Header.stories.tsx b/lib/components/Header/Header.stories.tsx index 0baeffd..b61d7de 100644 --- a/lib/components/Header/Header.stories.tsx +++ b/lib/components/Header/Header.stories.tsx @@ -25,46 +25,46 @@ const meta = { }, accounts: [ { + id: 'party:aurora', groupId: 'primary', type: 'person', name: 'Aurora Mikalsen', - selected: true, }, { + id: 'party:rakel', groupId: 'favourites', type: 'person', name: 'Rakel Engelsvik', - selected: false, }, { + id: 'party:auroraskeeperskole', groupId: 'favourites', type: 'company', name: 'Auroras keeperskole', - selected: false, }, { + id: 'party:aurorashandsker', groupId: 'secondary', type: 'company', name: 'Keeperhansker AS', - selected: false, }, { + id: 'party:aurorasfotballskole', groupId: 'secondary', type: 'company', name: 'Stadion drift AS', - selected: false, }, { + id: 'party:aurorasfotballskole', groupId: 'secondary', type: 'company', name: 'Sportsklubben Brann', - selected: false, }, { + id: 'party:aurorasfotballskole', groupId: 'secondary', type: 'company', name: 'Landslaget', - selected: false, }, ], items: [ @@ -94,10 +94,20 @@ const meta = { export default meta; type Story = StoryObj; -export const Default: Story = {}; +export const Default: Story = { + args: { + currentAccount: { + id: 'party:aurora', + type: 'person', + name: 'Aurora Mikalsen', + }, + }, +}; export const ControlledState = (args) => { const [q, setQ] = useState(''); + const currentEndUserId = 'party:aurora'; + const [selectedAccountId, setSelectedAccountId] = useState(currentEndUserId); const onChange = (event) => { setQ(event.target.value); }; @@ -160,6 +170,12 @@ export const ControlledState = (args) => { return (
account.id === selectedAccountId)} + menu={{ + ...args.menu, + ...args.menu.accounts, + changeCurrentAccount: setSelectedAccountId, + }} search={{ ...args.search, value: q, diff --git a/lib/components/Header/Header.tsx b/lib/components/Header/Header.tsx index 93294d9..f931677 100644 --- a/lib/components/Header/Header.tsx +++ b/lib/components/Header/Header.tsx @@ -2,6 +2,7 @@ import { useEscapeKey } from '../../hooks'; import { DrawerBase, DropdownBase } from '../Dropdown'; import { GlobalMenu, type GlobalMenuProps } from '../GlobalMenu'; +import type { Account } from '../GlobalMenu/AccountButton.tsx'; import { useRootContext } from '../RootProvider'; import { Searchbar, type SearchbarProps } from '../Searchbar'; import { HeaderBase } from './HeaderBase'; @@ -13,15 +14,11 @@ import styles from './header.module.css'; export interface HeaderProps { menu: GlobalMenuProps; search?: SearchbarProps; + currentAccount?: Account; } -export const Header = ({ search, menu }: HeaderProps) => { +export const Header = ({ search, menu, currentAccount }: HeaderProps) => { const { currentId, toggleId, openId, closeAll } = useRootContext(); - const selectedAccount = menu.accounts?.find((account) => account.selected); - const selectedAvatar = selectedAccount && { - type: selectedAccount.type, - name: selectedAccount.name, - }; useEscapeKey(closeAll); @@ -42,14 +39,19 @@ export const Header = ({ search, menu }: HeaderProps) => { {menu && ( - + )} @@ -64,7 +66,7 @@ export const Header = ({ search, menu }: HeaderProps) => { )} {menu && ( - + )} diff --git a/lib/components/Layout/Layout.stories.tsx b/lib/components/Layout/Layout.stories.tsx index 1f95d9c..1ce8487 100644 --- a/lib/components/Layout/Layout.stories.tsx +++ b/lib/components/Layout/Layout.stories.tsx @@ -9,12 +9,17 @@ const header: HeaderProps = { name: 'search', placeholder: 'Søk i Altinn', }, + currentAccount: { + id: 'party:aurora', + type: 'person', + name: 'Aurora Mikalsen', + }, menu: { accounts: [ { + id: 'party:aurora', type: 'person', name: 'Aurora Mikalsen', - selected: true, }, ], }, @@ -197,7 +202,7 @@ export const ControlledStateSearch = (args) => { }; export const InboxBulkMode = (args) => { - const [snackbars, setSnacbars] = useState([]); + const [snackbars, setSnackbars] = useState([]); const [itemsById, setItemsById] = useState({ 1: { diff --git a/lib/stories/Inbox/InboxLayout.tsx b/lib/stories/Inbox/InboxLayout.tsx index dc657f3..ea575f7 100644 --- a/lib/stories/Inbox/InboxLayout.tsx +++ b/lib/stories/Inbox/InboxLayout.tsx @@ -19,6 +19,7 @@ export const InboxLayout = ({ children }: InboxLayoutProps) => { footer={footer} header={{ ...header, + currentAccount: accounts?.[0], menu: { accounts, }, diff --git a/lib/stories/Inbox/InboxProvider.tsx b/lib/stories/Inbox/InboxProvider.tsx index 6809218..b1b4cd1 100644 --- a/lib/stories/Inbox/InboxProvider.tsx +++ b/lib/stories/Inbox/InboxProvider.tsx @@ -5,7 +5,6 @@ interface AccountProps { id?: string; type?: string; name?: string; - selected?: boolean; } export interface InboxDefaultValue {