Skip to content

Commit

Permalink
Refactor pages (#88)
Browse files Browse the repository at this point in the history
* Refactor Tab properties across pages

* Refactor TeamDetail Tab properties

* Destructure prepData across all pages
Add conditional rendering to FormattedTableColumn

* More refactoring in TeamDetail and TODO comments

* .
  • Loading branch information
johnnadeluy authored Mar 5, 2024
1 parent 1282b68 commit a36e0e3
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 138 deletions.
16 changes: 9 additions & 7 deletions src/components/FormattedTableColumn.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Text, Link } from '@statisticsnorway/ssb-component-library'

interface FormattedTableColumnProps {
href: string
linkText: string
text: string
href?: string
linkText?: string
text?: string
}

const FormattedTableColumn = (props: FormattedTableColumnProps) => {
Expand All @@ -12,11 +12,13 @@ const FormattedTableColumn = (props: FormattedTableColumnProps) => {
return (
<>
<span>
<Link href={href}>
<b>{linkText}</b>
</Link>
{href && linkText && (
<Link href={href}>
<b>{linkText}</b>
</Link>
)}
</span>
<Text>{text}</Text>
{text && <Text>{text}</Text>}
</>
)
}
Expand Down
70 changes: 37 additions & 33 deletions src/pages/TeamDetail/TeamDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,34 @@ import PageSkeleton from '../../components/PageSkeleton/PageSkeleton'
import { Skeleton } from '@mui/material'
import FormattedTableColumn from '../../components/FormattedTableColumn'

const TeamDetail = () => {
const defaultActiveTab = {
title: 'Teammedlemmer',
path: 'team',
}
const TEAM_USERS_TAB = {
title: 'Teammedlemmer',
path: 'team',
}

const [activeTab, setActiveTab] = useState<TabProps | string>(defaultActiveTab)
const SHARED_BUCKETS_TAB = {
title: 'Delte data',
path: 'sharedBuckets',
}

const TeamDetail = () => {
const [activeTab, setActiveTab] = useState<TabProps | string>(TEAM_USERS_TAB)

const { setBreadcrumbTeamDetailDisplayName } = useContext(DaplaCtrlContext)
const [error, setError] = useState<ApiError | undefined>()
const [loadingTeamData, setLoadingTeamData] = useState<boolean>(true)
const [teamDetailData, setTeamDetailData] = useState<TeamDetailData>()
const [teamDetailTableTitle, setTeamDetailTableTitle] = useState<string>(defaultActiveTab.title)
const [teamDetailTableTitle, setTeamDetailTableTitle] = useState<string>(TEAM_USERS_TAB.title)
const [teamDetailTableData, setTeamDetailTableData] = useState<TableData['data']>()

const { teamId } = useParams<{ teamId: string }>()

const prepTeamData = useCallback(
(response: TeamDetailData): TableData['data'] => {
const teamDetailTab = (activeTab as TabProps)?.path ?? activeTab
if (teamDetailTab === 'sharedBuckets') {
const sharedBuckets = (response['sharedBuckets'] as SharedBuckets).items
const sharedBucketsTab = SHARED_BUCKETS_TAB.path
if (teamDetailTab === sharedBucketsTab) {
const sharedBuckets = (response[sharedBucketsTab] as SharedBuckets).items
if (!sharedBuckets) return []

return sharedBuckets.map(({ short_name, bucket_name, metrics }) => {
Expand All @@ -52,25 +58,25 @@ const TeamDetail = () => {
}
})
} else {
const teamUsers = (response['team'] as Team).users
const teamUsers = (response[TEAM_USERS_TAB.path] as Team).users
if (!teamUsers) return []

return teamUsers.map((user) => {
return teamUsers.map(({ display_name, principal_name, section_name, groups }) => {
return {
id: formatDisplayName(user.display_name),
id: formatDisplayName(display_name),
navn: (
<FormattedTableColumn
href={`/teammedlemmer/${user.principal_name}`}
linkText={formatDisplayName(user.display_name)}
text={user.section_name ? user.section_name : 'Mangler seksjon'}
href={`/teammedlemmer/${principal_name}`}
linkText={formatDisplayName(display_name)}
text={section_name ?? 'Mangler seksjon'} // TODO: Should be handled in services
/>
),
seksjon: user.section_name, // Makes section name searchable and sortable in table by including the field
gruppe: user.groups
seksjon: section_name, // Makes section name searchable and sortable in table by including the field
gruppe: groups
?.filter((group) => group.uniform_name.startsWith((response.team as Team).uniform_name))
.map((group) => getGroupType(group.uniform_name))
.join(', '),
epost: user?.principal_name,
epost: principal_name,
}
})
}
Expand Down Expand Up @@ -101,10 +107,10 @@ const TeamDetail = () => {

const handleTabClick = (tab: string) => {
setActiveTab(tab)
if (tab === defaultActiveTab.path) {
setTeamDetailTableTitle(defaultActiveTab.title)
if (tab === TEAM_USERS_TAB.path) {
setTeamDetailTableTitle(TEAM_USERS_TAB.title)
} else {
setTeamDetailTableTitle('Delte data')
setTeamDetailTableTitle(SHARED_BUCKETS_TAB.title)
}
}

Expand All @@ -120,9 +126,9 @@ const TeamDetail = () => {
if (error) return renderErrorAlert()
if (loadingTeamData) return <PageSkeleton hasDescription />

if (teamDetailTableData) {
if (teamDetailData && teamDetailTableData) {
const teamOverviewTableHeaderColumns =
activeTab === 'sharedBuckets'
activeTab === SHARED_BUCKETS_TAB.path
? [
{
id: 'navn',
Expand Down Expand Up @@ -154,24 +160,22 @@ const TeamDetail = () => {
<>
<LeadParagraph className={styles.userProfileDescription}>
<Text medium className={styles.uniformName}>
{teamDetailData ? (teamDetailData.team as Team).uniform_name : ''}
</Text>
<Text medium>
{teamDetailData ? formatDisplayName((teamDetailData.team as Team).manager?.display_name ?? '') : ''}
{(teamDetailData.team as Team).uniform_name ?? ''}
</Text>
<Text medium>{teamDetailData ? (teamDetailData.team as Team).section_name : ''}</Text>
<Text medium>{formatDisplayName((teamDetailData.team as Team).manager?.display_name ?? '')}</Text>
<Text medium>{(teamDetailData.team as Team).section_name ?? ''}</Text>
</LeadParagraph>
<Tabs
onClick={handleTabClick}
activeOnInit={defaultActiveTab.path}
activeOnInit={TEAM_USERS_TAB.path}
items={[
{
title: `${defaultActiveTab.title} (${(teamDetailData?.team as Team).users?.length ?? 0})`,
path: defaultActiveTab.path,
title: `${TEAM_USERS_TAB.title} (${(teamDetailData?.team as Team).users?.length ?? 0})`,
path: TEAM_USERS_TAB.path,
},
{
title: `Delte data (${(teamDetailData?.sharedBuckets as SharedBuckets).items?.length ?? 0})`,
path: 'sharedBuckets',
title: `${SHARED_BUCKETS_TAB.title} (${(teamDetailData?.sharedBuckets as SharedBuckets).items?.length ?? 0})`,
path: SHARED_BUCKETS_TAB.path,
},
]}
/>
Expand Down
88 changes: 46 additions & 42 deletions src/pages/TeamMembers/TeamMembers.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,60 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useCallback, useEffect, useState } from 'react'
import { Dialog, Text, Link, Tabs, Divider } from '@statisticsnorway/ssb-component-library'
import { Dialog, Tabs, Divider } from '@statisticsnorway/ssb-component-library'

import { TabProps } from '../../@types/pageTypes'
import PageLayout from '../../components/PageLayout/PageLayout'
import Table, { TableData } from '../../components/Table/Table'
import PageSkeleton from '../../components/PageSkeleton/PageSkeleton'

import { fetchAllTeamMembersData, TeamMembersData, User } from '../../services/teamMembers'
import { fetchAllTeamMembersData, TeamMembersData } from '../../services/teamMembers'
import { formatDisplayName } from '../../utils/utils'
import { ApiError, fetchUserInformationFromAuthToken } from '../../utils/services'
import FormattedTableColumn from '../../components/FormattedTableColumn'

const TeamMembers = () => {
const defaultActiveTab = {
title: 'Mine teammedlemmer',
path: 'myUsers',
}
const MY_USERS_TAB = {
title: 'Mine teammedlemmer',
path: 'myUsers',
}

const [activeTab, setActiveTab] = useState<TabProps | string>(defaultActiveTab)
const ALL_USERS_TAB = {
title: 'Alle teammedlemmer',
path: 'allUsers',
}

const TeamMembers = () => {
const [activeTab, setActiveTab] = useState<TabProps | string>(MY_USERS_TAB)
const [teamMembersData, setTeamMembersData] = useState<TeamMembersData>()
const [teamMembersTableData, setTeamMembersTableData] = useState<TableData['data']>()
const [teamMembersTableTitle, setTeamMembersTableTitle] = useState<string>(defaultActiveTab.title)
const [teamMembersTableTitle, setTeamMembersTableTitle] = useState<string>(MY_USERS_TAB.title)
const [error, setError] = useState<ApiError | undefined>()
const [loading, setLoading] = useState<boolean>(true)

const prepUserData = useCallback(
(response: TeamMembersData): TableData['data'] => {
const teamMember = (activeTab as TabProps)?.path ?? activeTab

return response[teamMember].users.map((teamMember) => ({
id: formatDisplayName(teamMember.display_name),
navn: renderUserNameColumn(teamMember),
team: teamMember.teams.length,
epost: teamMember.principal_name,
data_admin_roller: teamMember.groups.filter((group) => group.uniform_name.endsWith('data-admins')).length,
seksjon: teamMember.section_name, // Makes section name searchable and sortable in table by including the field
seksjonsleder: formatDisplayName(
teamMember.section_manager && teamMember.section_manager.length > 0
? teamMember.section_manager[0].display_name
: 'Seksjonsleder ikke funnet'
),
}))
return response[teamMember].users.map(
({ display_name, principal_name, section_name, section_manager, teams, groups }) => ({
id: formatDisplayName(display_name),
navn: (
<FormattedTableColumn
href={`/teammedlemmer/${principal_name}`}
linkText={formatDisplayName(display_name)}
text={section_name}
/>
),
team: teams.length,
epost: principal_name,
data_admin_roller: groups.filter((group) => group.uniform_name.endsWith('data-admins')).length,
seksjon: section_name, // Makes section name searchable and sortable in table by including the field
seksjonsleder: formatDisplayName(
section_manager && section_manager.length > 0
? section_manager[0].display_name
: 'Seksjonsleder ikke funnet' // TODO: Should be handled in services
),
})
)
},
[activeTab]
)
Expand Down Expand Up @@ -72,26 +86,13 @@ const TeamMembers = () => {

const handleTabClick = (tab: string) => {
setActiveTab(tab)
if (tab === defaultActiveTab.path) {
setTeamMembersTableTitle(defaultActiveTab.title)
if (tab === MY_USERS_TAB.path) {
setTeamMembersTableTitle(MY_USERS_TAB.title)
} else {
setTeamMembersTableTitle('Alle teammedlemmer')
setTeamMembersTableTitle(ALL_USERS_TAB.title)
}
}

const renderUserNameColumn = (user: User) => {
return (
<>
<span>
<Link href={`/teammedlemmer/${user.principal_name}`}>
<b>{user.display_name}</b>
</Link>
</span>
{user.section_name && <Text>{user.section_name}</Text>}
</>
)
}

const renderErrorAlert = () => {
return (
<Dialog type='warning' title='Could not fetch users'>
Expand Down Expand Up @@ -128,13 +129,16 @@ const TeamMembers = () => {
<>
<Tabs
onClick={handleTabClick}
activeOnInit={defaultActiveTab.path}
activeOnInit={MY_USERS_TAB.path}
items={[
{
title: `${defaultActiveTab.title} (${teamMembersData?.myUsers.users.length ?? 0})`,
path: defaultActiveTab.path,
title: `${MY_USERS_TAB.title} (${teamMembersData?.myUsers.users.length ?? 0})`,
path: MY_USERS_TAB.path,
},
{
title: `${ALL_USERS_TAB.title} (${teamMembersData?.allUsers.users.length ?? 0})`,
path: ALL_USERS_TAB.path,
},
{ title: `Alle teammedlemmer (${teamMembersData?.allUsers.users.length ?? 0})`, path: 'allUsers' },
]}
/>
<Divider dark />
Expand Down
Loading

0 comments on commit a36e0e3

Please sign in to comment.