Skip to content

Commit

Permalink
#3134: Reintroduce position tables in Organization page
Browse files Browse the repository at this point in the history
  • Loading branch information
VassilIordanov committed Aug 20, 2020
1 parent 46b17ff commit 1e0300c
Showing 1 changed file with 187 additions and 3 deletions.
190 changes: 187 additions & 3 deletions client/src/pages/organizations/Show.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import RelatedObjectNotes, {
import ReportCollection from "components/ReportCollection"
import { RECURSE_STRATEGY } from "components/SearchFilters"
import SubNav from "components/SubNav"
import { Organization, Report, Task } from "models"
import { Organization, Report, Task, Position, Person } from "models"
import { orgTour } from "pages/HopscotchTour"
import pluralize from "pluralize"
import React, { useContext, useState } from "react"
import { Button, Checkbox, Nav } from "react-bootstrap"
import { Button, Checkbox, Nav, Table } from "react-bootstrap"
import ContainerDimensions from "react-container-dimensions"
import { connect } from "react-redux"
import { useLocation, useParams } from "react-router-dom"
Expand Down Expand Up @@ -123,6 +123,7 @@ const OrganizationShow = ({ pageDispatchers }) => {
const routerLocation = useLocation()
const [filterPendingApproval, setFilterPendingApproval] = useState(false)
const [includeChildrenOrgs, setIncludeChildrenOrgs] = useState(false)
const [showInactivePositions, setShowInactivePositions] = useState(false)
const { uuid } = useParams()
const { loading, error, data } = API.useApiQuery(GQL_GET_ORGANIZATION, {
uuid
Expand Down Expand Up @@ -177,6 +178,138 @@ const OrganizationShow = ({ pageDispatchers }) => {
reportQueryParams.orgRecurseStrategy = RECURSE_STRATEGY.CHILDREN
}

function renderPositionTable(positions) {
let posNameHeader, posPersonHeader, otherNameHeader, otherPersonHeader
if (organization.isAdvisorOrg()) {
posNameHeader = Settings.fields.advisor.position.name
posPersonHeader = Settings.fields.advisor.person.name
otherNameHeader = Settings.fields.principal.position.name
otherPersonHeader = Settings.fields.principal.person.name
} else {
otherNameHeader = Settings.fields.advisor.position.name
otherPersonHeader = Settings.fields.advisor.person.name
posNameHeader = Settings.fields.principal.position.name
posPersonHeader = Settings.fields.principal.person.name
}
return (
<Table>
<thead>
<tr>
<th>{posNameHeader}</th>
<th>{posPersonHeader}</th>
<th>{otherPersonHeader}</th>
<th>{otherNameHeader}</th>
</tr>
</thead>
<tbody>
{Position.map(positions, position =>
position.associatedPositions.length
? Position.map(position.associatedPositions, (other, idx) =>
renderPositionRow(position, other, idx)
)
: renderPositionRow(position, null, 0)
)}
</tbody>
</Table>
)
}

function renderPositionRow(position, other, otherIndex) {
let key = position.uuid
let otherPersonCol, otherNameCol, positionPersonCol, positionNameCol
if (
position.status === Position.STATUS.INACTIVE &&
!showInactivePositions
) {
return
}

if (other) {
key += "." + other.uuid
otherNameCol = (
<td>
<LinkTo modelType="Position" model={other}>
{positionWithStatus(other)}
</LinkTo>
</td>
)

otherPersonCol = other.person ? (
<td>
<LinkTo modelType="Person" model={other.person}>
{personWithStatus(other.person)}
</LinkTo>
</td>
) : (
<td className="text-danger">Unfilled</td>
)
}

if (otherIndex === 0) {
positionNameCol = (
<td>
<LinkTo modelType="Position" model={position}>
{positionWithStatus(position)}
</LinkTo>
</td>
)
positionPersonCol =
position.person && position.person.uuid ? (
<td>
<LinkTo modelType="Person" model={position.person}>
{personWithStatus(position.person)}
</LinkTo>
</td>
) : (
<td className="text-danger">Unfilled</td>
)
}

otherPersonCol = otherPersonCol || <td />
otherNameCol = otherNameCol || <td />
positionPersonCol = positionPersonCol || <td />
positionNameCol = positionNameCol || <td />

return (
<tr key={key}>
{positionNameCol}
{positionPersonCol}
{otherPersonCol}
{otherNameCol}
</tr>
)
}

function personWithStatus(person) {
person = new Person(person)
if (person.status === Person.STATUS.INACTIVE) {
return <i>{person.toString() + " (Inactive)"}</i>
} else {
return person.toString()
}
}

function positionWithStatus(pos) {
const code = pos.code ? ` (${pos.code})` : ""
if (pos.status === Position.STATUS.INACTIVE) {
return <i>{`${pos.name}${code} (Inactive)`}</i>
} else {
return pos.name + code
}
}

const numInactivePos = organization.positions.filter(
p => p.status === Position.STATUS.INACTIVE
).length

const positionsNeedingAttention = organization.positions.filter(
position => !position.person
)

const supportedPositions = organization.positions.filter(
position => positionsNeedingAttention.indexOf(position) === -1
)

return (
<div>
{done && result}
Expand Down Expand Up @@ -247,7 +380,58 @@ const OrganizationShow = ({ pageDispatchers }) => {
<Tab
id="tab-positions"
title="Positions"
panel={<div style={{ width: `${width}px` }} />}
panel={
<div style={{ width: `${width}px` }}>
<Fieldset
id="supportedPositions"
title="Supported positions"
action={
<div>
{isSuperUser && (
<LinkTo
modelType="Position"
model={Position.pathForNew({
organizationUuid: organization.uuid
})}
button
>
Create position
</LinkTo>
)}
</div>
}
>
{renderPositionTable(supportedPositions)}
{supportedPositions.length === 0 && (
<em>There are no occupied positions</em>
)}
</Fieldset>

<Fieldset
id="vacantPositions"
title="Vacant positions"
action={
<div>
{numInactivePos > 0 && (
<Button
onClick={() =>
setShowInactivePositions(!showInactivePositions)}
>
{(showInactivePositions ? "Hide " : "Show ") +
numInactivePos +
" inactive position(s)"}
</Button>
)}
</div>
}
>
{renderPositionTable(positionsNeedingAttention)}
{positionsNeedingAttention.length === 0 && (
<em>There are no vacant positions</em>
)}
</Fieldset>
</div>
}
/>
{!isPrincipalOrg && (
<Tab
Expand Down

0 comments on commit 1e0300c

Please sign in to comment.