Skip to content

Commit

Permalink
Merge pull request #559 from knowit/folk-504-org-struktur
Browse files Browse the repository at this point in the history
folk-504 Oppdatert org struktur grafen
  • Loading branch information
OliverKnowit committed Mar 7, 2024
2 parents 8ae086d + 2180abe commit a31f442
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 105 deletions.
2 changes: 1 addition & 1 deletion apps/web/src/components/sortableTable/MUITable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const MUITable = <T extends object>({
>
{(config || []).map((column, index) =>
column.header ? (
column.header()
column.header
) : (
<TableCellStyled key={index}>
<HeaderRoot>
Expand Down
44 changes: 16 additions & 28 deletions apps/web/src/components/sortableTable/SortableMUITable.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCallback } from 'react'
import { ArrowDownIcon, ArrowUpIcon } from '../../assets/Icons'
import useSort from './hooks/use-sort'

Expand Down Expand Up @@ -36,6 +37,19 @@ const SortableTable = <T extends object>(props: MUITableProps<T>) => {
config,
initialSort
)
const getIcon = useCallback(
(label: string, sortBy: string | null, sortOrder: SortOrder | null) => {
if (label === sortBy) {
if (sortOrder === SortOrder.Asc) {
return <ArrowDownIcon />
} else if (sortOrder === SortOrder.Desc) {
return <ArrowUpIcon />
}
}
return undefined
},
[]
)

const updatedConfig = config.map((column) => {
if (!column.sortValue) {
Expand All @@ -44,12 +58,12 @@ const SortableTable = <T extends object>(props: MUITableProps<T>) => {

return {
...column,
header: () => (
header: (
<TableCellStyled key={`head-${column.label}`}>
<HeaderRoot>
<HeaderTitle onClick={() => setSortColumn(column.label)}>
{column.label}
{getIcons(column.label, sortBy, sortOrder)}
{getIcon(column.label, sortBy, sortOrder)}
</HeaderTitle>

{column.checkBox ? <CellCheckbox {...column.checkBox} /> : null}
Expand All @@ -59,32 +73,6 @@ const SortableTable = <T extends object>(props: MUITableProps<T>) => {
}
})

const getIcons = (
label: string,
sortBy: string | null,
sortOrder: SortOrder | null
) => {
if (label !== sortBy) {
return <div></div>
}

if (sortOrder === null) {
return <div></div>
} else if (sortOrder === SortOrder.Asc) {
return (
<div>
<ArrowDownIcon />
</div>
)
} else if (sortOrder === SortOrder.Desc) {
return (
<div>
<ArrowUpIcon />
</div>
)
}
}

return (
<div>
<MUITable {...props} config={updatedConfig} data={sortedData}></MUITable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ export default function ConsultantCell({
</ButtonSubRoot>
<ButtonSubRoot>
{isExpanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
<Link to={'/ansatt/' + consultant.email} target="_blank">
<Link
to={'/ansatt/' + consultant.email}
target={'employee_' + consultant.email}
>
<OpenInNewIcon />
</Link>
</ButtonSubRoot>
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/sortableTable/tableTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ export interface MUITableConfig<T> {
) => ReactNode
width?: number
additionalCellStyle?: React.CSSProperties
header?: () => ReactNode
header?: ReactNode
checkBox?: CheckBoxHeader
sortValue?: sortValueFn<T>
searchValue?: GetColumnValueFn
sortFn?: (a: T, b: T) => number
}

export interface MUITableProps<T> {
export interface MUITableProps<T extends object> {
data: T[]
config: MUITableConfig<T>[]
keyFn: (rowData: T) => string
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/pages/employee/EmployeePage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react'
import { Grid } from '@mui/material'
import { EmployeeTable } from './table/EmployeeTable'
import { pageTitle } from '../../utils/pagetitle'
Expand Down
3 changes: 1 addition & 2 deletions apps/web/src/pages/employee/table/SortableEmployeeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ export const EmployeeTableForCustomer = (props: {
}

function transformEmployeeForCustomerList(row: EmployeeForCustomerList) {
const rowData = row['rowData']
const rowId = row['rowId']
const { rowId, rowData } = row

return {
rowId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ const FilterWrapper = styled('div')(({ theme }) => ({
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.25)',
borderRadius: '4px',
display: 'flex',
float: 'right',
position: 'absolute',
right: 0,
'z-index': 5,
}))

const StyledText = styled('p')({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import React from 'react'
import { Link } from '../../type'
import { linkColor } from '../../util'
import { useTheme } from '@mui/material'
import NameText from '../NameText'

interface Props {
link: Link
searchTerm: string
}

const LinkElement = ({ link, searchTerm }: Props) => {
const theme = useTheme()
const halo = theme.palette.background.paper // Stroke around the labels in case they overlap with a link
const haloWidth = 0.2
return (
<React.Fragment key={link.target.data.employee.email}>
<path
Expand All @@ -21,21 +18,7 @@ const LinkElement = ({ link, searchTerm }: Props) => {
id={link.target.data.employee.email}
/>
{link.innerLink && (
<text
stroke={halo}
strokeWidth={haloWidth}
paintOrder="stroke"
fill={theme.palette.text.primary}
opacity={
searchTerm.length < 0
? 1
: link.target.data.employee.name
.toLowerCase()
.includes(searchTerm)
? 1
: 0.3
}
>
<NameText employee={link.target.data.employee} searchTerm={searchTerm}>
<textPath
xlinkHref={'#' + link.target.data.employee.email}
startOffset={link.inverted ? '100%' : null}
Expand All @@ -45,7 +28,7 @@ const LinkElement = ({ link, searchTerm }: Props) => {
{link.target.children ? link.target.data.employee.name : ''}
</tspan>
</textPath>
</text>
</NameText>
)}
</React.Fragment>
)
Expand Down
43 changes: 43 additions & 0 deletions apps/web/src/pages/organizationStructure/Components/NameText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useTheme } from '@mui/material'
import { ReactNode } from 'react'
import { EmployeeProfileInformation } from 'server/routers/employees/employeesTypes'

interface Props {
children: ReactNode
employee: EmployeeProfileInformation
searchTerm: string
[k: string]: any
}
const NameText = ({ children, employee, searchTerm, ...rest }: Props) => {
const theme = useTheme()
const halo = theme.palette.background.paper // Stroke around the labels in case they overlap with a link
const haloWidth = 0.2

return (
<text
onClick={() =>
window.open(
window.location.origin + '/ansatt/' + employee.email,
'employee_' + employee.email
)
}
style={{ cursor: 'hand' }}
stroke={halo}
strokeWidth={haloWidth}
paintOrder="stroke"
fill={theme.palette.text.primary}
opacity={
searchTerm.length < 0
? 1
: employee.name.toLowerCase().includes(searchTerm)
? 1
: 0.3
}
{...rest}
>
{children}
</text>
)
}

export default NameText
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { Node } from '../../type'
import { useTheme } from '@mui/material'
import {
checkRotateDegree,
fill,
haloWidth,
nodeSizeNormal,
nodeStroke,
} from '../../util'
import { checkRotateDegree, fill, nodeSizeNormal, nodeStroke } from '../../util'
import NameText from '../NameText'

interface Props {
node: Node
Expand All @@ -23,9 +17,6 @@ const EmployeeTreeNode = ({
clickedParents,
searchTerm,
}: Props) => {
const theme = useTheme()
const halo = theme.palette.background.paper

const rotate =
!node.children && node.depth !== 0
? checkRotateDegree(degree, rotateValue)
Expand All @@ -48,25 +39,16 @@ const EmployeeTreeNode = ({
strokeWidth={1}
r={nodeSizeNormal(node)}
/>
<text
<NameText
employee={node.data.employee}
searchTerm={searchTerm}
transform={`rotate(${rotate ? 0 : 180})`}
dy={node.depth === 0 ? '10px' : '0.32em'}
x={rotate ? nodeSizeNormal(node) + 3 : -nodeSizeNormal(node) - 3}
textAnchor={rotate ? 'start' : 'end'}
paintOrder="stroke"
stroke={halo}
fill={theme.palette.text.primary}
strokeWidth={haloWidth}
opacity={
searchTerm.length < 0
? 1
: node.data.employee.name.toLowerCase().includes(searchTerm)
? 1
: 0.3
}
>
{node.data.employee.name}
</text>
</NameText>
</g>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { Node } from '../../type'
import { useTheme } from '@mui/material'
import {
checkRotateDegree,
fill,
haloWidth,
nodeSizeNormal,
nodeSizeBig,
nodeStroke,
} from '../../util'
import ChildrenCount from './ChildrenCount'
import { styled } from '@mui/material'
import NameText from '../NameText'

interface Props {
node: Node
Expand Down Expand Up @@ -45,9 +44,6 @@ const LeaderTreeNode = ({
rotateValue,
searchTerm,
}: Props) => {
const theme = useTheme()
const halo = theme.palette.background.paper

const showHiddenChildsCount = clickedParents.some(
(employee) => employee === node.data.employee.email
)
Expand All @@ -70,27 +66,18 @@ const LeaderTreeNode = ({
hasChildren={childrenOuterLayerCount() > 0}
/>
{node.depth === 0 && (
<text
<NameText
employee={node.data.employee}
searchTerm={searchTerm}
transform={`rotate(${
checkRotateDegree(degree, rotateValue) ? 0 : 180
})`}
dy={checkRotateDegree(degree, rotateValue) ? '10' : '-5'}
x={checkRotateDegree(degree, rotateValue) ? 22 : -22}
textAnchor={checkRotateDegree(degree, rotateValue) ? 'start' : 'end'}
paintOrder="stroke"
stroke={halo}
fill={theme.palette.text.primary}
strokeWidth={haloWidth}
opacity={
searchTerm.length < 0
? 1
: node.data.employee.name.toLowerCase().includes(searchTerm)
? 1
: 0.3
}
>
{node.data.employee.name}
</text>
</NameText>
)}
<ChildrenCount
node={node}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const OrganizationStructureTree = ({

return (
<>
<div>
<AbsolutelyPositionedBox>
<SearchFieldStyled>
<SearchInput
placeholder={'Søk i ansatte'}
Expand All @@ -114,10 +114,10 @@ const OrganizationStructureTree = ({
setZoomTransformValue={setZoomTransformValue}
rotateValue={rotateValue}
/>
</div>
</AbsolutelyPositionedBox>
<svg
viewBox={`${-margin - radius} ${-margin - radius} ${width} ${height}`}
style={{ maxWidth: '100%', height: 'auto' }}
style={{ maxWidth: '100%', height: 'auto', position: 'absolute' }}
fontFamily={'sans-serif'}
ref={svgRef}
fontSize={12}
Expand Down Expand Up @@ -159,3 +159,8 @@ const OrganizationStructureTree = ({
}

export default OrganizationStructureTree

const AbsolutelyPositionedBox = styled('div')({
position: 'absolute',
'z-index': '5',
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ interface Props {
rotateValue: number
}

const ButtonWrapper = styled('div')({
const ButtonWrapper = styled('div')(({ theme }) => ({
border: '1px solid',
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.25)',
borderRadius: '4px',
width: '200px',
display: 'flex',
justifyContent: 'center',
})
backgroundColor: theme.palette.background.default,
}))

const Percent = styled('div')({
fontSize: '24px',
Expand Down
Loading

0 comments on commit a31f442

Please sign in to comment.