diff --git a/src/scenes/Dashboard/Dashboard.tsx b/src/scenes/Dashboard/Dashboard.tsx index c0eb926d6..9a50290e1 100644 --- a/src/scenes/Dashboard/Dashboard.tsx +++ b/src/scenes/Dashboard/Dashboard.tsx @@ -3,6 +3,7 @@ import { Route, Routes } from 'react-router-dom'; import { NotFoundRoute } from '~/components/Error'; import { WidgetGrid } from '~/components/Widgets/WidgetGrid'; import { DashboardLayout } from './DashboardLayout'; +import { EngagementsUsingAIWidget } from './EngagementsUsingAIWidget/EngagementsUsingAIWidget'; import { PnpProblemsWidget } from './PnpProblemsWidget/PnpProblemsWidget'; import { ProgressReportsWidget } from './ProgressReportsWidget/ProgressReportsWidget'; @@ -12,6 +13,10 @@ export const DashboardRoutes = () => ( } /> } /> } /> + } + /> {NotFoundRoute} @@ -20,6 +25,7 @@ export const DashboardRoutes = () => ( const MainDashboard = () => ( + ); @@ -40,3 +46,14 @@ const ExpandedPnpProblems = () => ( ); + +const ExpandedEngagementsUsingAI = () => ( + + + +); diff --git a/src/scenes/Dashboard/EngagementsUsingAIWidget/EngagementsUsingAIGrid.tsx b/src/scenes/Dashboard/EngagementsUsingAIWidget/EngagementsUsingAIGrid.tsx new file mode 100644 index 000000000..f6c13f62d --- /dev/null +++ b/src/scenes/Dashboard/EngagementsUsingAIWidget/EngagementsUsingAIGrid.tsx @@ -0,0 +1,239 @@ +import { + DataGridPro, + DataGridProProps as DataGridProps, + GridColDef, + GridToolbarColumnsButton, + GridToolbarFilterButton, +} from '@mui/x-data-grid-pro'; +import { merge } from 'lodash'; +import { useMemo } from 'react'; +import { SetOptional } from 'type-fest'; +import { + AiAssistedTranslationLabels, + AiAssistedTranslationList, + EngagementFilters, + EngagementListInput, +} from '~/api/schema.graphql'; +import { CalendarDate, extendSx } from '~/common'; +import { + booleanColumn, + DefaultDataGridStyles, + enumColumn, + getInitialVisibility, + noHeaderFilterButtons, + QuickFilterButton, + QuickFilterResetButton, + QuickFilters, + textColumn, + Toolbar, + useDataGridSource, + useFilterToggle, +} from '~/components/Grid'; +import { LinkColumn } from '~/components/Grid/Columns/LinkColumn'; +import { ProjectNameColumn } from '~/components/Grid/Columns/ProjectNameColumn'; +import { Link } from '~/components/Routing'; +import { + EngagementUsingAiDataGridRowFragment as EngagementUsingAI, + EngagementUsingAiListDocument, +} from './engagementsUsingAIDataGridRow.graphql'; + +export type EngagementUsingAIColumnMapShape = Record< + string, + SetOptional, 'field'> +>; + +export const EngagementUsingAIColumnMap = { + project: ProjectNameColumn({ + field: 'project.name', + valueGetter: (_, engagement) => engagement.project, + }), + language: { + headerName: 'Language / Intern', + field: 'nameProjectLast', + ...textColumn(), + width: 200, + valueGetter: (_, row) => { + return row.__typename === 'LanguageEngagement' + ? row.language.value?.name.value + : row.__typename === 'InternshipEngagement' + ? row.intern.value?.fullName + : null; + }, + renderCell: ({ value, row }) => { + return row.__typename === 'LanguageEngagement' ? ( + {value} + ) : row.__typename === 'InternshipEngagement' ? ( + {value} + ) : null; + }, + hideable: false, + serverFilter: (value): EngagementFilters => ({ engagedName: value }), + }, + viewEngagement: LinkColumn({ + field: 'Engagement', + headerName: '', + valueGetter: (_, engagement) => engagement, + destination: (id) => `/engagements/${id}`, + }), + usingAIAssistedTranslation: { + headerName: 'AI Assistance', + description: 'Is using AI assistance in translation?', + field: 'usingAIAssistedTranslation', + width: 130, + ...enumColumn(AiAssistedTranslationList, AiAssistedTranslationLabels), + valueGetter: (_, row) => + row.__typename === 'LanguageEngagement' + ? row.usingAIAssistedTranslation.value + : null, + filterable: true, + editable: true, + isEditable: ({ row }) => + row.__typename === 'LanguageEngagement' && + row.usingAIAssistedTranslation.canEdit, + valueSetter: (value, row) => + row.__typename === 'LanguageEngagement' + ? { + ...row, + usingAIAssistedTranslation: { + ...row.usingAIAssistedTranslation, + value, + }, + } + : row, + }, + isMember: { + headerName: 'Mine', + field: 'project.isMember', + ...booleanColumn(), + valueGetter: (_, engagement) => engagement.project.isMember, + }, + pinned: { + headerName: 'Pinned', + field: 'project.pinned', + ...booleanColumn(), + valueGetter: (_, engagement) => engagement.project.pinned, + }, +} satisfies EngagementUsingAIColumnMapShape; + +const columns = Object.values(EngagementUsingAIColumnMap); + +export interface EngagementsUsingAIGridProps extends DataGridProps { + quarter: CalendarDate; + expanded: boolean; +} + +export const EngagementsUsingAIGrid = ({ + quarter, + expanded, + ...props +}: Omit) => { + const source = useMemo(() => { + return { + query: EngagementUsingAiListDocument, + variables: { + input: { + filter: { + // project: { + // status: ['Active'], + // }, + usingAIAssistedTranslation: ['Check', 'Draft', 'DraftAndCheck'], + }, + } satisfies EngagementListInput, + }, + listAt: 'engagements', + initialInput: { + sort: 'project.name', + order: 'ASC', + }, + } as const; + }, []); + + const [dataGridProps] = useDataGridSource({ + ...source, + apiRef: props.apiRef, + }); + + const initialState = { + columns: { + columnVisibilityModel: { + ...getInitialVisibility(columns), + viewReport: expanded, + 'project.isMember': false, + 'project.pinned': false, + }, + }, + } satisfies DataGridProps['initialState']; + + const toolbarSlot = { + toolbar: EngagementsUsingAIToolbar, + } satisfies DataGridProps['slots']; + + const slots = useMemo( + () => + merge( + {}, + DefaultDataGridStyles.slots, + dataGridProps.slots, + props.slots, + expanded && toolbarSlot + ), + [dataGridProps.slots, props.slots, toolbarSlot, expanded] + ); + + const slotProps = useMemo( + () => + merge( + {}, + DefaultDataGridStyles.slotProps, + dataGridProps.slotProps, + props.slotProps + ), + [dataGridProps.slotProps, props.slotProps] + ); + + return ( + ({ + '.MuiDataGrid-main': { + borderTop: `thin solid ${theme.palette.divider}`, + }, + })), + ...extendSx(props.sx), + ]} + /> + ); +}; + +const EngagementsUsingAIToolbar = () => ( + + + + + + + Mine + + + Pinned + + + +); diff --git a/src/scenes/Dashboard/EngagementsUsingAIWidget/EngagementsUsingAIWidget.tsx b/src/scenes/Dashboard/EngagementsUsingAIWidget/EngagementsUsingAIWidget.tsx new file mode 100644 index 000000000..4df768db9 --- /dev/null +++ b/src/scenes/Dashboard/EngagementsUsingAIWidget/EngagementsUsingAIWidget.tsx @@ -0,0 +1,50 @@ +import { useLocation } from 'react-router-dom'; +import { flexLayout } from '~/components/Grid'; +import { + ExpanderButton, + TableWidget, + Widget, + WidgetHeader, + WidgetProps, +} from '~/components/Widgets'; +import { useQuarterState } from '../ProgressReportsWidget/useQuarterState'; +import { EngagementsUsingAIGrid } from './EngagementsUsingAIGrid'; + +export const EngagementsUsingAIWidget = ({ + expanded, + ...props +}: WidgetProps & { expanded: boolean }) => { + const quarter = useQuarterState(); + const location = useLocation(); + + return ( + + + } + /> + + + + + ); +}; diff --git a/src/scenes/Dashboard/EngagementsUsingAIWidget/engagementsUsingAIDataGridRow.graphql b/src/scenes/Dashboard/EngagementsUsingAIWidget/engagementsUsingAIDataGridRow.graphql new file mode 100644 index 000000000..112674018 --- /dev/null +++ b/src/scenes/Dashboard/EngagementsUsingAIWidget/engagementsUsingAIDataGridRow.graphql @@ -0,0 +1,13 @@ +query EngagementUsingAIList($input: EngagementListInput) { + engagements(input: $input) { + items { + ...engagementDataGridRow + } + total + hasMore + } +} + +fragment engagementUsingAIDataGridRow on Engagement { + ...engagementDataGridRow +} diff --git a/src/scenes/Dashboard/ProgressReportsWidget/progressReportsDataGridRow.graphql b/src/scenes/Dashboard/ProgressReportsWidget/progressReportsDataGridRow.graphql index 1401aa726..889396179 100644 --- a/src/scenes/Dashboard/ProgressReportsWidget/progressReportsDataGridRow.graphql +++ b/src/scenes/Dashboard/ProgressReportsWidget/progressReportsDataGridRow.graphql @@ -6,6 +6,7 @@ query ProgressReports($input: ProgressReportListInput) { ...progressReportsDataGridRow } total + hasMore } }