-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Update the domain admins table to the new style #93749
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
base: main
Are you sure you want to change the base?
Changes from all commits
8118fc2
d7cc44f
7ef944c
b81298e
f87774d
c55a2be
c01f24b
8141398
aadde1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| import React from 'react'; | ||
| import {View} from 'react-native'; | ||
| import Badge from '@components/Badge'; | ||
| import Icon from '@components/Icon'; | ||
| import ReportActionAvatars from '@components/ReportActionAvatars'; | ||
| import Table from '@components/Table'; | ||
| import TextWithTooltip from '@components/TextWithTooltip'; | ||
| import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; | ||
| import useLocalize from '@hooks/useLocalize'; | ||
| import useStyleUtils from '@hooks/useStyleUtils'; | ||
| import useTheme from '@hooks/useTheme'; | ||
| import useThemeStyles from '@hooks/useThemeStyles'; | ||
| import variables from '@styles/variables'; | ||
| import CONST from '@src/CONST'; | ||
| import type {DomainAdminRowData} from '.'; | ||
|
|
||
| type DomainAdminsTableRowProps = { | ||
| /** Data about the domain admin */ | ||
| item: DomainAdminRowData; | ||
|
|
||
| /** The index of the row relative to all other rows */ | ||
| rowIndex: number; | ||
|
|
||
| /** Whether to use narrow table row layout */ | ||
| shouldUseNarrowTableLayout: boolean; | ||
| }; | ||
|
|
||
| export default function DomainAdminsTableRow({item, rowIndex, shouldUseNarrowTableLayout}: DomainAdminsTableRowProps) { | ||
| const theme = useTheme(); | ||
| const styles = useThemeStyles(); | ||
| const styleUtils = useStyleUtils(); | ||
| const {translate} = useLocalize(); | ||
| const icons = useMemoizedLazyExpensifyIcons(['ArrowRight']); | ||
|
|
||
| const avatarSize = shouldUseNarrowTableLayout ? CONST.AVATAR_SIZE.DEFAULT : CONST.AVATAR_SIZE.SMALL; | ||
| const primaryContactLabel = item.isPrimaryContact ? translate('domain.admins.primaryContact') : ''; | ||
| const accessibilityLabel = [item.name, item.email, primaryContactLabel].filter(Boolean).join(', '); | ||
|
|
||
| const getSecondaryAvatarContainerStyle = (hovered: boolean) => [ | ||
| styleUtils.getBackgroundAndBorderStyle(theme.sidebar), | ||
| hovered ? styleUtils.getBackgroundAndBorderStyle(styles.sidebarLinkHover?.backgroundColor ?? theme.sidebar) : undefined, | ||
| ]; | ||
|
|
||
| return ( | ||
| <Table.Row | ||
| interactive | ||
| rowIndex={rowIndex} | ||
| disabled={item.disabled} | ||
| accessibilityLabel={accessibilityLabel} | ||
| skeletonReasonAttributes={{context: 'domainAdminsTableRow'}} | ||
| sentryLabel={CONST.SENTRY_LABEL.DOMAIN.ADMINS.ROW} | ||
| offlineWithFeedback={{ | ||
| errors: item.errors, | ||
| pendingAction: item.pendingAction, | ||
| onClose: item.dismissError, | ||
| }} | ||
| onPress={item.action} | ||
| > | ||
| {({hovered}) => ( | ||
| <> | ||
| <View style={[styles.flex1, styles.flexRow, styles.alignItemsCenter]}> | ||
| <ReportActionAvatars | ||
| size={avatarSize} | ||
| accountIDs={[item.accountID]} | ||
| fallbackDisplayName={item.name ?? item.email} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| shouldShowTooltip | ||
| secondaryAvatarContainerStyle={getSecondaryAvatarContainerStyle(!!hovered)} | ||
| /> | ||
| <View style={[shouldUseNarrowTableLayout && styles.gap1, styles.flex1]}> | ||
| <TextWithTooltip | ||
| shouldShowTooltip | ||
| text={item.name} | ||
| style={[styles.optionDisplayName, styles.pre]} | ||
| /> | ||
| <TextWithTooltip | ||
| shouldShowTooltip | ||
| text={item.email} | ||
| style={[styles.textLabelSupporting, styles.lh16, styles.pre]} | ||
| /> | ||
| </View> | ||
| </View> | ||
|
|
||
| <View style={[styles.flexRow, styles.alignItemsCenter, styles.justifyContentEnd, styles.gap3]}> | ||
| {item.isPrimaryContact && ( | ||
| <Badge | ||
| text={translate('domain.admins.primaryContact')} | ||
| badgeStyles={styles.ml0} | ||
| isCondensed={shouldUseNarrowTableLayout} | ||
| /> | ||
| )} | ||
| <Icon | ||
| src={icons.ArrowRight} | ||
| fill={theme.icon} | ||
| additionalStyles={[styles.alignSelfCenter, (!hovered || item.disabled) && styles.opacitySemiTransparent]} | ||
| width={variables.iconSizeNormal} | ||
| height={variables.iconSizeNormal} | ||
| /> | ||
| </View> | ||
| </> | ||
| )} | ||
| </Table.Row> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| import type {ListRenderItemInfo} from '@shopify/flash-list'; | ||
| import React from 'react'; | ||
| import type {CompareItemsCallback, IsItemInSearchCallback, TableColumn, TableData} from '@components/Table'; | ||
| import Table from '@components/Table'; | ||
| import useLocalize from '@hooks/useLocalize'; | ||
| import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||
| import tokenizedSearch from '@libs/tokenizedSearch'; | ||
| import variables from '@styles/variables'; | ||
| import CONST from '@src/CONST'; | ||
| import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; | ||
| import DomainAdminsTableRow from './DomainAdminsTableRow'; | ||
|
|
||
| type DomainAdminsTableColumnKey = 'admin' | 'actions'; | ||
|
|
||
| type DomainAdminRowData = TableData & { | ||
| accountID: number; | ||
| login: string; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this used? I see we use the name and email, but I can't see where it is being referenced. |
||
| name: string; | ||
| email: string; | ||
| isPrimaryContact: boolean; | ||
| errors?: OnyxCommon.Errors; | ||
| pendingAction?: OnyxCommon.PendingAction; | ||
| action: () => void; | ||
| dismissError: () => void; | ||
| }; | ||
|
|
||
| type DomainAdminsTableProps = { | ||
| admins: DomainAdminRowData[]; | ||
| }; | ||
|
|
||
| export default function DomainAdminsTable({admins}: DomainAdminsTableProps) { | ||
| const {translate, localeCompare} = useLocalize(); | ||
| const {shouldUseNarrowLayout, isMediumScreenWidth} = useResponsiveLayout(); | ||
|
|
||
| const shouldUseNarrowTableLayout = shouldUseNarrowLayout || isMediumScreenWidth; | ||
|
|
||
| const domainAdminsTableColumns: Array<TableColumn<DomainAdminsTableColumnKey>> = [ | ||
| { | ||
| key: 'admin', | ||
| label: translate('domain.admins.title'), | ||
| sortable: true, | ||
| }, | ||
| { | ||
| key: 'actions', | ||
| label: '', | ||
| sortable: false, | ||
| width: variables.domainAdminsTableActionColumnWidth, | ||
| }, | ||
| ]; | ||
|
|
||
| const compareTableItems: CompareItemsCallback<DomainAdminRowData> = (item1, item2, activeSorting) => { | ||
| const orderMultiplier = activeSorting.order === 'asc' ? 1 : -1; | ||
| return localeCompare(item1.name, item2.name) * orderMultiplier; | ||
| }; | ||
|
|
||
| const isTableItemInSearch: IsItemInSearchCallback<DomainAdminRowData> = (item, searchValue) => { | ||
| const results = tokenizedSearch([item], searchValue, (option) => [option.name, option.email]); | ||
| return results.length > 0; | ||
| }; | ||
|
|
||
| const renderTableItem = ({item, index}: ListRenderItemInfo<DomainAdminRowData>) => ( | ||
| <DomainAdminsTableRow | ||
| item={item} | ||
| rowIndex={index} | ||
| shouldUseNarrowTableLayout={shouldUseNarrowTableLayout} | ||
| /> | ||
| ); | ||
|
|
||
| return ( | ||
| <Table | ||
| data={admins} | ||
| columns={domainAdminsTableColumns} | ||
| renderItem={renderTableItem} | ||
| compareItems={compareTableItems} | ||
| isItemInSearch={isTableItemInSearch} | ||
| initialSortColumn="admin" | ||
| title={translate('domain.admins.title')} | ||
| keyExtractor={(item) => item.keyForList} | ||
| > | ||
| {admins.length >= CONST.STANDARD_LIST_ITEM_LIMIT && <Table.SearchBar label={translate('domain.admins.findAdmin')} />} | ||
| <Table.Header /> | ||
| <Table.Body /> | ||
| </Table> | ||
| ); | ||
| } | ||
|
|
||
| export type {DomainAdminRowData, DomainAdminsTableColumnKey}; | ||
Uh oh!
There was an error while loading. Please reload this page.