Skip to content

Commit 1c6ab4c

Browse files
committed
Merge branch 'dev' into diazz-admin-f2f-30376659
2 parents 2d3c37e + 9d945ef commit 1c6ab4c

File tree

8 files changed

+81
-27
lines changed

8 files changed

+81
-27
lines changed

src/apps/copilots/src/copilots.routes.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ export const childRoutes = [
2323
route: '/',
2424
},
2525
{
26+
authRequired: true,
2627
element: <CopilotsRequests />,
2728
id: 'CopilotRequests',
2829
route: '/requests',
2930
},
3031
{
32+
authRequired: true,
3133
element: <CopilotsRequestForm />,
3234
id: 'CopilotRequestForm',
3335
route: '/requests/new',
3436
},
3537
{
38+
authRequired: true,
3639
element: <CopilotsRequests />,
3740
id: 'CopilotRequestDetails',
3841
route: '/requests/:requestId',
@@ -54,10 +57,8 @@ export const copilotRoutesMap = childRoutes.reduce((allRoutes, route) => (
5457

5558
export const copilotsRoutes: ReadonlyArray<PlatformRoute> = [
5659
{
57-
authRequired: true,
5860
children: [
5961
...childRoutes,
60-
6162
],
6263
domain: AppSubdomain.copilots,
6364
element: <CopilotsApp />,

src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { FC, useEffect, useState } from 'react'
22
import { useNavigate, useParams } from 'react-router-dom'
3+
import moment from 'moment'
34

45
import {
56
ContentLayout,
@@ -60,6 +61,17 @@ const CopilotOpportunityDetails: FC<{}> = () => {
6061
<span className={styles.infoValue}>{opportunity?.status}</span>
6162
</div>
6263
</div>
64+
<div className={styles.infoColumn}>
65+
<IconOutline.PlayIcon className={styles.icon} />
66+
<div className={styles.infoText}>
67+
<span className={styles.infoHeading}>Start Date</span>
68+
<span className={styles.infoValue}>
69+
{moment(opportunity?.startDate)
70+
.format('MMM D, YYYY')}
71+
72+
</span>
73+
</div>
74+
</div>
6375
<div className={styles.infoColumn}>
6476
<IconOutline.CalendarIcon className={styles.icon} />
6577
<div className={styles.infoText}>

src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx

+43-13
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ import {
1313
import { CopilotOpportunity } from '../../models/CopilotOpportunity'
1414
import { copilotRoutesMap } from '../../copilots.routes'
1515
import { CopilotOpportunitiesResponse, useCopilotOpportunities } from '../../services/copilot-opportunities'
16+
import { ProjectTypeLabels } from '../../constants'
1617

1718
import styles from './styles.module.scss'
1819

1920
const tableColumns: TableColumn<CopilotOpportunity>[] = [
2021
{
2122
label: 'Title',
2223
propertyName: 'projectName',
23-
type: 'text',
24+
renderer: (copilotOpportunity: CopilotOpportunity) => (
25+
<div className={styles.title}>
26+
{copilotOpportunity.projectName}
27+
</div>
28+
),
29+
type: 'element',
2430
},
2531
{
2632
label: 'Status',
@@ -33,23 +39,43 @@ const tableColumns: TableColumn<CopilotOpportunity>[] = [
3339
type: 'element',
3440
},
3541
{
42+
isSortable: false,
3643
label: 'Skills Required',
3744
propertyName: 'skills',
38-
renderer: (copilotOpportunity: CopilotOpportunity) => (
39-
<div className={styles.skillsContainer}>
40-
{copilotOpportunity.skills.map((skill: any) => (
41-
<div key={skill.id} className={styles.skillPill}>
42-
{skill.name}
43-
</div>
44-
))}
45-
</div>
46-
),
45+
renderer: (copilotOpportunity: CopilotOpportunity) => {
46+
const visibleSkills = copilotOpportunity.skills.slice(0, 3)
47+
const remainingSkills = copilotOpportunity.skills.slice(3)
48+
return (
49+
<div className={styles.skillsContainer}>
50+
{visibleSkills.map((skill: { id: string | number; name: string }) => (
51+
<div key={skill.id} className={styles.skillPill}>
52+
{skill.name}
53+
</div>
54+
))}
55+
{remainingSkills.length > 0 && (
56+
<div
57+
className={styles.skillPill}
58+
title={remainingSkills.map(skill => skill.name)
59+
.join(', ')}
60+
>
61+
+
62+
{remainingSkills.length}
63+
</div>
64+
)}
65+
</div>
66+
)
67+
},
4768
type: 'element',
4869
},
4970
{
5071
label: 'Type',
5172
propertyName: 'type',
52-
type: 'text',
73+
renderer: (copilotOpportunity: CopilotOpportunity) => (
74+
<div className={styles.type}>
75+
{ProjectTypeLabels[copilotOpportunity.projectType]}
76+
</div>
77+
),
78+
type: 'element',
5379
},
5480
{
5581
label: 'Starting Date',
@@ -62,7 +88,7 @@ const tableColumns: TableColumn<CopilotOpportunity>[] = [
6288
type: 'text',
6389
},
6490
{
65-
label: 'Hours per week needed',
91+
label: 'Hours/Week',
6692
propertyName: 'numHoursPerWeek',
6793
type: 'number',
6894
},
@@ -80,7 +106,10 @@ const CopilotOpportunityList: FC<{}> = () => {
80106
data: opportunities, isValidating, size, setSize,
81107
}: CopilotOpportunitiesResponse = useCopilotOpportunities()
82108

83-
const tableData = useMemo(() => opportunities, [opportunities])
109+
const tableData = useMemo(() => opportunities.map(opportunity => ({
110+
...opportunity,
111+
type: ProjectTypeLabels[opportunity.projectType] ?? '',
112+
})), [opportunities])
84113

85114
function loadMore(): void {
86115
setSize(size + 1)
@@ -103,6 +132,7 @@ const CopilotOpportunityList: FC<{}> = () => {
103132
moreToLoad={isValidating || opportunities.length > 0}
104133
onLoadMoreClick={loadMore}
105134
onRowClick={handleRowClick}
135+
removeDefaultSort
106136
/>
107137
{opportunitiesLoading && (
108138
<LoadingSpinner overlay />

src/apps/copilots/src/pages/copilot-opportunity-list/styles.module.scss

+9-4
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
.skillsContainer {
44
display: flex;
55
flex-wrap: wrap;
6+
overflow: auto;
67
gap: 8px;
78
}
89

910
.skillPill {
10-
background-color: #aaaaaa;
11+
background-color: #d6d6d6;
1112
color: #333;
1213
padding: 4px 8px;
1314
border-radius: 10px;
14-
white-space: nowrap;
15-
font-size: 14px;
15+
white-space: break-spaces;
16+
font-size: 11px;
1617
}
1718

1819
.status {
@@ -26,4 +27,8 @@
2627

2728
.activeStatus {
2829
color: green;
29-
}
30+
}
31+
32+
.type {
33+
white-space: nowrap;
34+
}

src/apps/copilots/src/services/copilot-opportunities.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export type CopilotOpportunityResponse = SWRResponse<CopilotOpportunity, Copilot
7171
* @returns {CopilotOpportunityResponse} - The response containing the copilot request data.
7272
*/
7373
export const useCopilotOpportunity = (opportunityId?: string): CopilotOpportunityResponse => {
74-
const url = opportunityId ? buildUrl(`${baseUrl}/copilots/opportunities/${opportunityId}`) : undefined
74+
const url = opportunityId ? buildUrl(`${baseUrl}/copilot/opportunity/${opportunityId}`) : undefined
7575

7676
const fetcher = (urlp: string): Promise<CopilotOpportunity> => xhrGetAsync<CopilotOpportunity>(urlp)
7777
.then(copilotOpportunityFactory)

src/libs/ui/lib/components/table/Table.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ const Table: <T extends { [propertyName: string]: any }>(props: TableProps<T>) =
102102

103103
function toggleSort(fieldName: string): void {
104104

105+
const col = props.columns.find(c => c.propertyName === fieldName)
106+
107+
// if sortable is false, we return
108+
if (col?.isSortable === false) return
109+
105110
// if we don't have anything to sort by, we shouldn't be here
106111
if (!sort && !props.removeDefaultSort) {
107112
return
@@ -129,7 +134,7 @@ const Table: <T extends { [propertyName: string]: any }>(props: TableProps<T>) =
129134

130135
const headerRow: Array<JSX.Element> = displayColumns
131136
.map((col, index) => {
132-
const isSortable: boolean = !!col.propertyName
137+
const isSortable: boolean = !!col.propertyName && col.isSortable !== false
133138
const isCurrentlySorted: boolean = isSortable && col.propertyName === sort?.fieldName
134139
const colorClass: string = isCurrentlySorted ? 'black-100' : 'black-60'
135140
const sortableClass: string | undefined = isSortable ? styles.sortable : undefined
@@ -151,7 +156,7 @@ const Table: <T extends { [propertyName: string]: any }>(props: TableProps<T>) =
151156
</Tooltip>
152157
</div>
153158
)}
154-
{!props.disableSorting && (
159+
{!props.disableSorting && isSortable && (
155160
<TableSort
156161
iconClass={colorClass}
157162
isCurrentlySorted={isCurrentlySorted}

src/libs/ui/lib/components/table/table-column.model.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export interface TableColumn<T> {
1111
readonly isExpand?: boolean
1212
readonly colSpan?: number
1313
readonly type: TableCellType
14+
readonly isSortable?: boolean
1415
}

src/libs/ui/lib/components/table/table-functions/table.functions.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ export function getSorted<T extends { [propertyName: string]: any }>(
5353

5454
if (sortColumn.type === 'date') {
5555
return sortedData
56-
.sort((a: T, b: T) => sortNumbers(
57-
(a[sort.fieldName] as Date).getTime(),
58-
(b[sort.fieldName] as Date).getTime(),
59-
sort.direction,
60-
))
56+
.sort((a: T, b: T) => {
57+
const aDate = new Date(a[sort.fieldName])
58+
const bDate = new Date(b[sort.fieldName])
59+
return sortNumbers(aDate.getTime(), bDate.getTime(), sort.direction)
60+
})
6161
}
6262

6363
return sortedData

0 commit comments

Comments
 (0)