diff --git a/src/components/artifacts/TaskArtifacts.tsx b/src/components/artifacts/TaskArtifacts.tsx
index ff2e88df0..d8d60041c 100644
--- a/src/components/artifacts/TaskArtifacts.tsx
+++ b/src/components/artifacts/TaskArtifacts.tsx
@@ -1,24 +1,25 @@
import React from 'react';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
import ArtifactsView from './ArtifactsView';
-function TaskArtifacts(props) {
- if (!props.task.artifacts || props.task.artifacts.length === 0) return
;
- return ;
-}
-
-export default createFragmentContainer(TaskArtifacts, {
- task: graphql`
- fragment TaskArtifacts_task on Task {
- id
- artifacts {
- name
- files {
- path
- size
+export default function TaskArtifacts(props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskArtifacts_task on Task {
+ id
+ artifacts {
+ name
+ files {
+ path
+ size
+ }
}
}
- }
- `,
-});
+ `,
+ props.task,
+ );
+
+ if (!task.artifacts || task.artifacts.length === 0) return ;
+ return ;
+}
diff --git a/src/components/builds/BuildsTable.tsx b/src/components/builds/BuildsTable.tsx
index 64e80a0ee..399d8e4ab 100644
--- a/src/components/builds/BuildsTable.tsx
+++ b/src/components/builds/BuildsTable.tsx
@@ -21,6 +21,7 @@ import InfoIcon from '@mui/icons-material/Info';
import CommitIcon from '@mui/icons-material/Commit';
import Typography from '@mui/material/Typography';
import CallSplitIcon from '@mui/icons-material/CallSplit';
+import BookOutlinedIcon from '@mui/icons-material/BookOutlined';
import UnarchiveIcon from '@mui/icons-material/UnarchiveOutlined';
import BuildStatusChipNew from '../chips/BuildStatusChipNew';
@@ -33,8 +34,6 @@ import { navigateBuildHelper } from '../../utils/navigateHelper';
import { BuildsTable_builds } from './__generated__/BuildsTable_builds.graphql';
-import BookOutlinedIcon from '@mui/icons-material/BookOutlined';
-
// todo: move custom values to mui theme adjustments
const useStyles = makeStyles(theme => {
return {
diff --git a/src/components/chips/TaskCancellerChip.tsx b/src/components/chips/TaskCancellerChip.tsx
index 9a3761fc2..6e68be7a4 100644
--- a/src/components/chips/TaskCancellerChip.tsx
+++ b/src/components/chips/TaskCancellerChip.tsx
@@ -3,17 +3,28 @@ import React from 'react';
import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskCancellerChip_task } from './__generated__/TaskCancellerChip_task.graphql';
+import { TaskCancellerChip_task$key } from './__generated__/TaskCancellerChip_task.graphql';
interface Props {
- task: TaskCancellerChip_task;
+ task: TaskCancellerChip_task$key;
className?: string;
}
-function TaskCancellerChip(props: Props) {
- let { cancelledBy } = props.task;
+export default function TaskCancellerChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskCancellerChip_task on Task {
+ cancelledBy {
+ avatarURL
+ }
+ }
+ `,
+ props.task,
+ );
+
+ let { cancelledBy } = task;
if (!cancelledBy) return <>>;
@@ -21,13 +32,3 @@ function TaskCancellerChip(props: Props) {
} />
);
}
-
-export default createFragmentContainer(TaskCancellerChip, {
- task: graphql`
- fragment TaskCancellerChip_task on Task {
- cancelledBy {
- avatarURL
- }
- }
- `,
-});
diff --git a/src/components/chips/TaskCreatedChip.tsx b/src/components/chips/TaskCreatedChip.tsx
index 98e3ce4b1..d8de0559a 100644
--- a/src/components/chips/TaskCreatedChip.tsx
+++ b/src/components/chips/TaskCreatedChip.tsx
@@ -4,21 +4,30 @@ import Icon from '@mui/material/Icon';
import Tooltip from '@mui/material/Tooltip';
import { graphql } from 'babel-plugin-relay/macro';
import React, { useEffect } from 'react';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { useTaskStatusColor } from '../../utils/colors';
import { taskStatusIconName } from '../../utils/status';
import { roundAndPresentDuration } from '../../utils/time';
-import { TaskCreatedChip_task } from './__generated__/TaskCreatedChip_task.graphql';
+import { TaskCreatedChip_task$key } from './__generated__/TaskCreatedChip_task.graphql';
import { useTheme } from '@mui/material';
interface Props {
- task: TaskCreatedChip_task;
+ task: TaskCreatedChip_task$key;
className?: string;
}
-let TaskCreatedChip = (props: Props) => {
+export default function TaskCreatedChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskCreatedChip_task on Task {
+ creationTimestamp
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
- const creationTimestamp = props.task.creationTimestamp;
+ const creationTimestamp = task.creationTimestamp;
const [durationAgoInSeconds, setDurationAgoInSeconds] = React.useState((Date.now() - creationTimestamp) / 1000);
@@ -51,12 +60,4 @@ let TaskCreatedChip = (props: Props) => {
/>
);
-};
-
-export default createFragmentContainer(TaskCreatedChip, {
- task: graphql`
- fragment TaskCreatedChip_task on Task {
- creationTimestamp
- }
- `,
-});
+}
diff --git a/src/components/chips/TaskExperimentalChip.tsx b/src/components/chips/TaskExperimentalChip.tsx
index 33a16bb90..16ac06d19 100644
--- a/src/components/chips/TaskExperimentalChip.tsx
+++ b/src/components/chips/TaskExperimentalChip.tsx
@@ -4,19 +4,27 @@ import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
import CasinoIcon from '@mui/icons-material/Casino';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskExperimentalChip_task } from './__generated__/TaskExperimentalChip_task.graphql';
+import { TaskExperimentalChip_task$key } from './__generated__/TaskExperimentalChip_task.graphql';
import { useTheme } from '@mui/material';
interface Props {
className?: string;
- task: TaskExperimentalChip_task;
+ task: TaskExperimentalChip_task$key;
}
-let TaskExperimentalChip = (props: Props) => {
+export default function TaskExperimentalChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskExperimentalChip_task on Task {
+ experimental
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
- const { task } = props;
const { experimental } = task;
if (!experimental) return ;
@@ -32,12 +40,4 @@ let TaskExperimentalChip = (props: Props) => {
}
/>
);
-};
-
-export default createFragmentContainer(TaskExperimentalChip, {
- task: graphql`
- fragment TaskExperimentalChip_task on Task {
- experimental
- }
- `,
-});
+}
diff --git a/src/components/chips/TaskOptionalChip.tsx b/src/components/chips/TaskOptionalChip.tsx
index 3fc840dd4..0c43a8a6a 100644
--- a/src/components/chips/TaskOptionalChip.tsx
+++ b/src/components/chips/TaskOptionalChip.tsx
@@ -4,20 +4,29 @@ import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
import Report from '@mui/icons-material/Report';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskOptionalChip_task } from './__generated__/TaskOptionalChip_task.graphql';
+import { TaskOptionalChip_task$key } from './__generated__/TaskOptionalChip_task.graphql';
import { useTheme } from '@mui/material';
interface Props {
- task: TaskOptionalChip_task;
+ task: TaskOptionalChip_task$key;
className?: string;
}
-function TaskOptionalChip(props: Props) {
+export default function TaskOptionalChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskOptionalChip_task on Task {
+ optional
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
- let { optional } = props.task;
+ let { optional } = task;
if (!optional) return ;
return (
@@ -32,11 +41,3 @@ function TaskOptionalChip(props: Props) {
/>
);
}
-
-export default createFragmentContainer(TaskOptionalChip, {
- task: graphql`
- fragment TaskOptionalChip_task on Task {
- optional
- }
- `,
-});
diff --git a/src/components/chips/TaskRerunnerChip.tsx b/src/components/chips/TaskRerunnerChip.tsx
index 611101b37..646381433 100644
--- a/src/components/chips/TaskRerunnerChip.tsx
+++ b/src/components/chips/TaskRerunnerChip.tsx
@@ -3,29 +3,30 @@ import React from 'react';
import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskRerunnerChip_task } from './__generated__/TaskRerunnerChip_task.graphql';
+import { TaskRerunnerChip_task$key } from './__generated__/TaskRerunnerChip_task.graphql';
interface Props {
- task: TaskRerunnerChip_task;
+ task: TaskRerunnerChip_task$key;
className?: string;
}
-function TaskRerunnerChip(props: Props) {
- let { reranBy } = props.task;
+export default function TaskRerunnerChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskRerunnerChip_task on Task {
+ reranBy {
+ avatarURL
+ }
+ }
+ `,
+ props.task,
+ );
+
+ let { reranBy } = task;
if (!reranBy) return <>>;
return } />;
}
-
-export default createFragmentContainer(TaskRerunnerChip, {
- task: graphql`
- fragment TaskRerunnerChip_task on Task {
- reranBy {
- avatarURL
- }
- }
- `,
-});
diff --git a/src/components/chips/TaskResourcesChip.tsx b/src/components/chips/TaskResourcesChip.tsx
index c27241619..d25b108a1 100644
--- a/src/components/chips/TaskResourcesChip.tsx
+++ b/src/components/chips/TaskResourcesChip.tsx
@@ -4,10 +4,10 @@ import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
import Tooltip from '@mui/material/Tooltip';
import Memory from '@mui/icons-material/Memory';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
import { makeStyles } from '@mui/styles';
-import { TaskResourcesChip_task } from './__generated__/TaskResourcesChip_task.graphql';
+import { TaskResourcesChip_task$key } from './__generated__/TaskResourcesChip_task.graphql';
const useStyles = makeStyles(theme => {
return {
@@ -21,13 +21,25 @@ const useStyles = makeStyles(theme => {
});
interface Props {
- task: TaskResourcesChip_task;
+ task: TaskResourcesChip_task$key;
className?: string;
}
-function TaskResourcesChip(props: Props) {
+export default function TaskResourcesChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskResourcesChip_task on Task {
+ instanceResources {
+ cpu
+ memory
+ }
+ }
+ `,
+ props.task,
+ );
+
let classes = useStyles();
- let { task, className } = props;
+ let { className } = props;
let resources = task.instanceResources;
if (!resources) {
return null;
@@ -48,14 +60,3 @@ function TaskResourcesChip(props: Props) {
);
}
-
-export default createFragmentContainer(TaskResourcesChip, {
- task: graphql`
- fragment TaskResourcesChip_task on Task {
- instanceResources {
- cpu
- memory
- }
- }
- `,
-});
diff --git a/src/components/chips/TaskScheduledChip.tsx b/src/components/chips/TaskScheduledChip.tsx
index 56ccd4ecf..7b8025275 100644
--- a/src/components/chips/TaskScheduledChip.tsx
+++ b/src/components/chips/TaskScheduledChip.tsx
@@ -7,19 +7,32 @@ import Tooltip from '@mui/material/Tooltip';
import { useTaskStatusColor } from '../../utils/colors';
import { taskStatusIconName } from '../../utils/status';
import { formatDuration } from '../../utils/time';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskScheduledChip_task } from './__generated__/TaskScheduledChip_task.graphql';
+import { TaskScheduledChip_task$key } from './__generated__/TaskScheduledChip_task.graphql';
import { useTheme } from '@mui/material';
interface Props {
- task: TaskScheduledChip_task;
+ task: TaskScheduledChip_task$key;
className?: string;
}
-function TaskScheduledChip(props: Props) {
+export default function TaskScheduledChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskScheduledChip_task on Task {
+ status
+ statusDurations {
+ status
+ durationInSeconds
+ }
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
- let { task, className } = props;
+ let { className } = props;
let scheduledColor = useTaskStatusColor('SCHEDULED');
let scheduledStatusDuration = task.statusDurations.find(it => it.status === 'SCHEDULED');
@@ -40,15 +53,3 @@ function TaskScheduledChip(props: Props) {
}
return ;
}
-
-export default createFragmentContainer(TaskScheduledChip, {
- task: graphql`
- fragment TaskScheduledChip_task on Task {
- status
- statusDurations {
- status
- durationInSeconds
- }
- }
- `,
-});
diff --git a/src/components/chips/TaskStatefulChip.tsx b/src/components/chips/TaskStatefulChip.tsx
index c77f94866..1ca75e99d 100644
--- a/src/components/chips/TaskStatefulChip.tsx
+++ b/src/components/chips/TaskStatefulChip.tsx
@@ -4,19 +4,27 @@ import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
import SecurityIcon from '@mui/icons-material/Security';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskStatefulChip_task } from './__generated__/TaskStatefulChip_task.graphql';
-import { createFragmentContainer } from 'react-relay';
+import { TaskStatefulChip_task$key } from './__generated__/TaskStatefulChip_task.graphql';
+import { useFragment } from 'react-relay';
import { useTheme } from '@mui/material';
interface Props {
- task: TaskStatefulChip_task;
+ task: TaskStatefulChip_task$key;
className?: string;
}
-function TaskStatefulChip(props: Props) {
+export default function TaskStatefulChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskStatefulChip_task on Task {
+ stateful
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
- let { task } = props;
let { stateful } = task;
if (!stateful) return ;
@@ -32,11 +40,3 @@ function TaskStatefulChip(props: Props) {
/>
);
}
-
-export default createFragmentContainer(TaskStatefulChip, {
- task: graphql`
- fragment TaskStatefulChip_task on Task {
- stateful
- }
- `,
-});
diff --git a/src/components/chips/TaskStatusChip.tsx b/src/components/chips/TaskStatusChip.tsx
index 917ecf59f..ddcc4945b 100644
--- a/src/components/chips/TaskStatusChip.tsx
+++ b/src/components/chips/TaskStatusChip.tsx
@@ -6,18 +6,29 @@ import Icon from '@mui/material/Icon';
import Tooltip from '@mui/material/Tooltip';
import { useTaskStatusColor } from '../../utils/colors';
import { taskStatusIconName, taskStatusMessage } from '../../utils/status';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskStatusChip_task } from './__generated__/TaskStatusChip_task.graphql';
+import { TaskStatusChip_task$key } from './__generated__/TaskStatusChip_task.graphql';
import { useTheme } from '@mui/material';
interface Props {
- task: TaskStatusChip_task;
+ task: TaskStatusChip_task$key;
className?: string;
}
-function TaskStatusChip(props: Props) {
- let { task, className } = props;
+export default function TaskStatusChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskStatusChip_task on Task {
+ status
+ durationInSeconds
+ executingTimestamp
+ }
+ `,
+ props.task,
+ );
+
+ let { className } = props;
let theme = useTheme();
let chip = (
;
@@ -36,11 +45,3 @@ function TaskTimeoutChip(props: Props) {
);
}
-
-export default createFragmentContainer(TaskTimeoutChip, {
- task: graphql`
- fragment TaskTimeoutChip_task on Task {
- timeoutInSeconds
- }
- `,
-});
diff --git a/src/components/chips/TaskTransactionChip.tsx b/src/components/chips/TaskTransactionChip.tsx
index 95c100023..b63e05b49 100644
--- a/src/components/chips/TaskTransactionChip.tsx
+++ b/src/components/chips/TaskTransactionChip.tsx
@@ -6,19 +6,32 @@ import Star from '@mui/icons-material/Star';
import Tooltip from '@mui/material/Tooltip';
import { graphql } from 'babel-plugin-relay/macro';
import { isTaskFinalStatus } from '../../utils/status';
-import { createFragmentContainer } from 'react-relay';
-import { TaskTransactionChip_task } from './__generated__/TaskTransactionChip_task.graphql';
+import { useFragment } from 'react-relay';
+import { TaskTransactionChip_task$key } from './__generated__/TaskTransactionChip_task.graphql';
import { useTheme } from '@mui/material';
interface Props {
- task: TaskTransactionChip_task;
+ task: TaskTransactionChip_task$key;
className?: string;
}
-function TaskTransactionChip(props: Props) {
+export default function TaskTransactionChip(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskTransactionChip_task on Task {
+ status
+ usedComputeCredits
+ transaction {
+ creditsAmount
+ initialCreditsAmount
+ }
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
- let task = props.task;
let { transaction, usedComputeCredits } = task;
if (!usedComputeCredits) {
return ;
@@ -49,16 +62,3 @@ function TaskTransactionChip(props: Props) {
);
}
-
-export default createFragmentContainer(TaskTransactionChip, {
- task: graphql`
- fragment TaskTransactionChip_task on Task {
- status
- usedComputeCredits
- transaction {
- creditsAmount
- initialCreditsAmount
- }
- }
- `,
-});
diff --git a/src/components/common/AppBreadcrumbs.tsx b/src/components/common/AppBreadcrumbs.tsx
index ea38972e7..a312b62fd 100644
--- a/src/components/common/AppBreadcrumbs.tsx
+++ b/src/components/common/AppBreadcrumbs.tsx
@@ -1,4 +1,6 @@
import * as React from 'react';
+import { useFragment } from 'react-relay';
+import { graphql } from 'babel-plugin-relay/macro';
import { makeStyles } from '@mui/styles';
import Link from '@mui/material/Link';
@@ -14,15 +16,13 @@ import BookmarkBorderIcon from '@mui/icons-material/BookmarkBorder';
import { absoluteLink } from '../../utils/link';
import RepositoryIcon from './RepositoryIcon';
-import { createFragmentContainer } from 'react-relay';
-import { graphql } from 'babel-plugin-relay/macro';
import AccountSwitch from './AccountSwitch';
-import { AppBreadcrumbs_build } from './__generated__/AppBreadcrumbs_build.graphql';
-import { AppBreadcrumbs_repository } from './__generated__/AppBreadcrumbs_repository.graphql';
-import { AppBreadcrumbs_task } from './__generated__/AppBreadcrumbs_task.graphql';
-import { AppBreadcrumbs_info } from './__generated__/AppBreadcrumbs_info.graphql';
-import { AppBreadcrumbs_viewer } from './__generated__/AppBreadcrumbs_viewer.graphql';
+import { AppBreadcrumbs_build$key } from './__generated__/AppBreadcrumbs_build.graphql';
+import { AppBreadcrumbs_repository$key } from './__generated__/AppBreadcrumbs_repository.graphql';
+import { AppBreadcrumbs_task$key } from './__generated__/AppBreadcrumbs_task.graphql';
+import { AppBreadcrumbs_info$key } from './__generated__/AppBreadcrumbs_info.graphql';
+import { AppBreadcrumbs_viewer$key } from './__generated__/AppBreadcrumbs_viewer.graphql';
const useStyles = makeStyles(theme => {
return {
@@ -51,21 +51,86 @@ const useStyles = makeStyles(theme => {
});
interface Props {
- info?: AppBreadcrumbs_info;
- repository?: AppBreadcrumbs_repository;
- build?: AppBreadcrumbs_build;
- task?: AppBreadcrumbs_task;
+ info?: AppBreadcrumbs_info$key;
+ repository?: AppBreadcrumbs_repository$key;
+ build?: AppBreadcrumbs_build$key;
+ task?: AppBreadcrumbs_task$key;
branch?: string;
extraCrumbs?: Array<{
name: string;
href?: string;
Icon: typeof SvgIcon | React.ElementType;
}>;
- viewer?: AppBreadcrumbs_viewer;
+ viewer?: AppBreadcrumbs_viewer$key;
}
-const AppBreadcrumbs = (props: Props) => {
- let { branch, extraCrumbs, info, repository, build, task, viewer } = props;
+export default function AppBreadcrumbs(props: Props) {
+ let info = useFragment(
+ graphql`
+ fragment AppBreadcrumbs_info on OwnerInfo {
+ platform
+ name
+ }
+ `,
+ props.info,
+ );
+ let repository = useFragment(
+ graphql`
+ fragment AppBreadcrumbs_repository on Repository {
+ id
+ platform
+ owner
+ name
+ }
+ `,
+ props.repository,
+ );
+ let build = useFragment(
+ graphql`
+ fragment AppBreadcrumbs_build on Build {
+ id
+ branch
+ changeIdInRepo
+ repository {
+ id
+ platform
+ owner
+ name
+ }
+ }
+ `,
+ props.build,
+ );
+ let task = useFragment(
+ graphql`
+ fragment AppBreadcrumbs_task on Task {
+ id
+ name
+ build {
+ id
+ branch
+ changeIdInRepo
+ repository {
+ id
+ platform
+ owner
+ name
+ }
+ }
+ }
+ `,
+ props.task,
+ );
+ let viewer = useFragment(
+ graphql`
+ fragment AppBreadcrumbs_viewer on User {
+ ...AccountSwitch_viewer
+ }
+ `,
+ props.viewer,
+ );
+
+ let { branch, extraCrumbs } = props;
let classes = useStyles();
let ownerName = task?.build?.repository?.owner || build?.repository?.owner || repository?.owner || info?.name;
@@ -130,7 +195,7 @@ const AppBreadcrumbs = (props: Props) => {
);
-};
+}
interface CrumbProps {
active: boolean;
@@ -161,55 +226,3 @@ const Crumb = ({ active, name, href, Icon }: CrumbProps) => {
);
};
-
-export default createFragmentContainer(AppBreadcrumbs, {
- info: graphql`
- fragment AppBreadcrumbs_info on OwnerInfo {
- platform
- name
- }
- `,
- repository: graphql`
- fragment AppBreadcrumbs_repository on Repository {
- id
- platform
- owner
- name
- }
- `,
- build: graphql`
- fragment AppBreadcrumbs_build on Build {
- id
- branch
- changeIdInRepo
- repository {
- id
- platform
- owner
- name
- }
- }
- `,
- task: graphql`
- fragment AppBreadcrumbs_task on Task {
- id
- name
- build {
- id
- branch
- changeIdInRepo
- repository {
- id
- platform
- owner
- name
- }
- }
- }
- `,
- viewer: graphql`
- fragment AppBreadcrumbs_viewer on User {
- ...AccountSwitch_viewer
- }
- `,
-});
diff --git a/src/components/common/Notification.tsx b/src/components/common/Notification.tsx
index d0ea24914..8725c76c2 100644
--- a/src/components/common/Notification.tsx
+++ b/src/components/common/Notification.tsx
@@ -1,21 +1,31 @@
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
import React from 'react';
import { useNotificationColor } from '../../utils/colors';
import IconButton from '@mui/material/IconButton';
import Icon from '@mui/material/Icon';
import { navigateHelper } from '../../utils/navigateHelper';
-import { Notification_notification } from './__generated__/Notification_notification.graphql';
+import { Notification_notification$key } from './__generated__/Notification_notification.graphql';
import { useNavigate } from 'react-router-dom';
import { ListItem, ListItemText } from '@mui/material';
interface Props {
- notification: Notification_notification;
+ notification: Notification_notification$key;
}
-function Notification(props: Props) {
+export default function Notification(props: Props) {
+ let notification = useFragment(
+ graphql`
+ fragment Notification_notification on Notification {
+ level
+ message
+ link
+ }
+ `,
+ props.notification,
+ );
+
let navigate = useNavigate();
- let { notification } = props;
return (
);
}
-
-export default createFragmentContainer(Notification, {
- notification: graphql`
- fragment Notification_notification on Notification {
- level
- message
- link
- }
- `,
-});
diff --git a/src/components/common/TaskExecutionInfo.tsx b/src/components/common/TaskExecutionInfo.tsx
index 084ab2b0c..dd6d2cbcf 100644
--- a/src/components/common/TaskExecutionInfo.tsx
+++ b/src/components/common/TaskExecutionInfo.tsx
@@ -1,11 +1,11 @@
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
import React from 'react';
import { makeStyles } from '@mui/styles';
import Chip from '@mui/material/Chip';
import Typography from '@mui/material/Typography';
import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip, YAxis } from 'recharts';
-import { TaskExecutionInfo_task } from './__generated__/TaskExecutionInfo_task.graphql';
+import { TaskExecutionInfo_task$key } from './__generated__/TaskExecutionInfo_task.graphql';
import { formatDuration } from '../../utils/time';
import { Box, useTheme } from '@mui/material';
import { useRecoilState } from 'recoil';
@@ -22,13 +22,41 @@ const useStyles = makeStyles(theme => {
});
interface Props {
- task: TaskExecutionInfo_task;
+ task: TaskExecutionInfo_task$key;
}
-function TaskExecutionInfo(props: Props) {
+export default function TaskExecutionInfo(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskExecutionInfo_task on Task {
+ instanceResources {
+ cpu
+ memory
+ }
+ executionInfo {
+ labels
+ cpuChart {
+ maxValue
+ points {
+ value
+ secondsFromStart
+ }
+ }
+ memoryChart {
+ maxValue
+ points {
+ value
+ secondsFromStart
+ }
+ }
+ }
+ }
+ `,
+ props.task,
+ );
+
let theme = useTheme();
const [prefersDarkMode] = useRecoilState(prefersDarkModeState);
- let { task } = props;
let classes = useStyles();
if (!task.executionInfo) return null;
@@ -132,31 +160,3 @@ function TaskExecutionInfo(props: Props) {
);
}
-
-export default createFragmentContainer(TaskExecutionInfo, {
- task: graphql`
- fragment TaskExecutionInfo_task on Task {
- instanceResources {
- cpu
- memory
- }
- executionInfo {
- labels
- cpuChart {
- maxValue
- points {
- value
- secondsFromStart
- }
- }
- memoryChart {
- maxValue
- points {
- value
- secondsFromStart
- }
- }
- }
- }
- `,
-});
diff --git a/src/components/tasks/TaskCommandList.tsx b/src/components/tasks/TaskCommandList.tsx
index 585c6b01c..a92b45fc1 100644
--- a/src/components/tasks/TaskCommandList.tsx
+++ b/src/components/tasks/TaskCommandList.tsx
@@ -10,10 +10,10 @@ import Accordion from '@mui/material/Accordion';
import AccordionDetails from '@mui/material/AccordionDetails';
import AccordionSummary from '@mui/material/AccordionSummary';
import Typography from '@mui/material/Typography';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
import * as queryString from 'query-string';
-import { TaskCommandList_task } from './__generated__/TaskCommandList_task.graphql';
+import { TaskCommandList_task, TaskCommandList_task$key } from './__generated__/TaskCommandList_task.graphql';
import { ItemOfArray } from '../../utils/utility-types';
import { useLocation } from 'react-router-dom';
import { makeStyles } from '@mui/styles';
@@ -30,12 +30,28 @@ const useStyles = makeStyles(theme => {
});
interface Props {
- task: TaskCommandList_task;
+ task: TaskCommandList_task$key;
}
-function TaskCommandList(props: Props) {
+export default function TaskCommandList(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskCommandList_task on Task {
+ id
+ status
+ executingTimestamp
+ commands {
+ name
+ type
+ status
+ durationInSeconds
+ }
+ }
+ `,
+ props.task,
+ );
+
let classes = useStyles();
- let task = props.task;
let commands = task.commands;
let commandComponents = [];
@@ -107,7 +123,7 @@ function TaskCommandList(props: Props) {
-
+
@@ -121,19 +137,3 @@ function TaskCommandList(props: Props) {
}
return {commandComponents}
;
}
-
-export default createFragmentContainer(TaskCommandList, {
- task: graphql`
- fragment TaskCommandList_task on Task {
- id
- status
- executingTimestamp
- commands {
- name
- type
- status
- durationInSeconds
- }
- }
- `,
-});
diff --git a/src/components/tasks/TaskCommandsProgress.tsx b/src/components/tasks/TaskCommandsProgress.tsx
index edb311a7b..71c58a49f 100644
--- a/src/components/tasks/TaskCommandsProgress.tsx
+++ b/src/components/tasks/TaskCommandsProgress.tsx
@@ -4,9 +4,9 @@ import { useTaskStatusColorMapping } from '../../utils/colors';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
import { formatDuration } from '../../utils/time';
-import { createFragmentContainer } from 'react-relay';
+import { useFragment } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
-import { TaskCommandsProgress_task } from './__generated__/TaskCommandsProgress_task.graphql';
+import { TaskCommandsProgress_task$key } from './__generated__/TaskCommandsProgress_task.graphql';
import { Box } from '@mui/material';
import { makeStyles } from '@mui/styles';
@@ -24,12 +24,25 @@ const useStyles = makeStyles(theme => {
});
interface Props {
- task: TaskCommandsProgress_task;
+ task: TaskCommandsProgress_task$key;
className?: string;
}
-function TaskCommandsProgress(props: Props) {
- let { task } = props;
+export default function TaskCommandsProgress(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskCommandsProgress_task on Task {
+ status
+ creationTimestamp
+ statusDurations {
+ status
+ durationInSeconds
+ }
+ }
+ `,
+ props.task,
+ );
+
let classes = useStyles();
let [totalDuration, setTotalDuration] = useState(
task.statusDurations.reduce((sum, statusDuration) => sum + statusDuration.durationInSeconds, 0),
@@ -98,16 +111,3 @@ function TaskCommandsProgress(props: Props) {
);
}
-
-export default createFragmentContainer(TaskCommandsProgress, {
- task: graphql`
- fragment TaskCommandsProgress_task on Task {
- status
- creationTimestamp
- statusDurations {
- status
- durationInSeconds
- }
- }
- `,
-});
diff --git a/src/components/tasks/TaskDebuggingInformation.tsx b/src/components/tasks/TaskDebuggingInformation.tsx
index 6a8bec392..ef0cd4966 100644
--- a/src/components/tasks/TaskDebuggingInformation.tsx
+++ b/src/components/tasks/TaskDebuggingInformation.tsx
@@ -1,11 +1,10 @@
import React from 'react';
import { CardContent, List } from '@mui/material';
-import { QueryRenderer } from 'react-relay';
+import { useLazyLoadQuery } from 'react-relay';
import { graphql } from 'babel-plugin-relay/macro';
import Typography from '@mui/material/Typography';
import Card from '@mui/material/Card';
import InlineLogs from '../logs/InlineLogs';
-import environment from '../../createRelayEnvironment';
import { TaskDebuggingInformationQuery } from './__generated__/TaskDebuggingInformationQuery.graphql';
import Notification from '../common/Notification';
@@ -14,66 +13,64 @@ interface Props {
}
function TaskDebuggingInformation(props: Props) {
- return (
-
- environment={environment}
- variables={{ taskId: props.taskId }}
- query={graphql`
- query TaskDebuggingInformationQuery($taskId: ID!) {
- task(id: $taskId) {
- executionInfo {
- events {
- timestamp
- message
- }
- agentNotifications {
- message
- ...Notification_notification
- }
+ const response = useLazyLoadQuery(
+ graphql`
+ query TaskDebuggingInformationQuery($taskId: ID!) {
+ task(id: $taskId) {
+ executionInfo {
+ events {
+ timestamp
+ message
+ }
+ agentNotifications {
+ message
+ ...Notification_notification
}
- commandLogsTail(name: "cirrus-agent-logs")
}
+ commandLogsTail(name: "cirrus-agent-logs")
}
- `}
- render={response => {
- if (!response.props) {
- return null;
- }
- let task = response.props.task;
- let events =
- task.executionInfo?.events?.map(event => {
- let prettyTime = new Date(event.timestamp).toLocaleTimeString();
- return `${prettyTime} ${event.message}`;
- }) || [];
+ }
+ `,
+ { taskId: props.taskId },
+ );
- const agentNotificationsComponent =
- !task.executionInfo ||
- !task.executionInfo.agentNotifications ||
- task.executionInfo.agentNotifications.length === 0 ? null : (
- <>
-
- Agent notifications
-
-
- {task.executionInfo.agentNotifications.map(notification => (
-
- ))}
-
- >
- );
+ if (!response.task) {
+ return null;
+ }
- return (
-
-
- Debugging Information
-
- {agentNotificationsComponent}
-
-
-
- );
- }}
- />
+ let task = response.task;
+
+ let events =
+ task.executionInfo?.events?.map(event => {
+ let prettyTime = new Date(event.timestamp).toLocaleTimeString();
+ return `${prettyTime} ${event.message}`;
+ }) || [];
+
+ const agentNotificationsComponent =
+ !task.executionInfo ||
+ !task.executionInfo.agentNotifications ||
+ task.executionInfo.agentNotifications.length === 0 ? null : (
+ <>
+
+ Agent notifications
+
+
+ {task.executionInfo.agentNotifications.map(notification => (
+
+ ))}
+
+ >
+ );
+
+ return (
+
+
+ Debugging Information
+
+ {agentNotificationsComponent}
+
+
+
);
}
diff --git a/src/components/tasks/TaskDetails.tsx b/src/components/tasks/TaskDetails.tsx
index 4ca7cb117..99b4eed17 100644
--- a/src/components/tasks/TaskDetails.tsx
+++ b/src/components/tasks/TaskDetails.tsx
@@ -1,4 +1,5 @@
import { makeStyles } from '@mui/styles';
+import environment from '../../createRelayEnvironment';
import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
import CardActions from '@mui/material/CardActions';
@@ -8,10 +9,9 @@ import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import { graphql } from 'babel-plugin-relay/macro';
import classNames from 'classnames';
-import React, { Suspense, useEffect, useState } from 'react';
-import { commitMutation, createFragmentContainer, requestSubscription } from 'react-relay';
+import React, { Suspense, useEffect, useState, useMemo } from 'react';
+import { useFragment, useMutation, requestSubscription } from 'react-relay';
import { useLocation, useNavigate } from 'react-router-dom';
-import environment from '../../createRelayEnvironment';
import { navigateBuildHelper, navigateTaskHelper } from '../../utils/navigateHelper';
import { hasWritePermissions } from '../../utils/permissions';
import { isTaskFinalStatus } from '../../utils/status';
@@ -26,8 +26,9 @@ import CirrusFavicon from '../common/CirrusFavicon';
import TaskCommandList from './TaskCommandList';
import TaskCommandsProgress from './TaskCommandsProgress';
import TaskList from './TaskList';
-import { TaskDetails_task } from './__generated__/TaskDetails_task.graphql';
+import { TaskDetails_task, TaskDetails_task$key } from './__generated__/TaskDetails_task.graphql';
import {
+ TaskDetailsReRunMutation,
TaskDetailsReRunMutationResponse,
TaskDetailsReRunMutationVariables,
} from './__generated__/TaskDetailsReRunMutation.graphql';
@@ -44,7 +45,8 @@ import TaskTimeoutChip from '../chips/TaskTimeoutChip';
import Notification from '../common/Notification';
import HookList from '../hooks/HookList';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
-import { TabContext, TabList, TabPanel, ToggleButton } from '@mui/lab';
+import { TabContext, TabList, TabPanel } from '@mui/lab';
+import { ToggleButton } from '@mui/material';
import {
Badge,
ButtonGroup,
@@ -78,47 +80,6 @@ import TaskDebuggingInformation from './TaskDebuggingInformation';
import CirrusLinearProgress from '../common/CirrusLinearProgress';
import CommitMessage from '../common/CommitMessage';
-const taskReRunMutation = graphql`
- mutation TaskDetailsReRunMutation($input: TaskReRunInput!) {
- rerun(input: $input) {
- newTask {
- id
- }
- }
- }
-`;
-
-const taskTriggerMutation = graphql`
- mutation TaskDetailsTriggerMutation($input: TaskTriggerInput!) {
- trigger(input: $input) {
- task {
- id
- status
- triggerType
- }
- }
- }
-`;
-
-const taskCancelMutation = graphql`
- mutation TaskDetailsCancelMutation($input: TaskAbortInput!) {
- abortTask(input: $input) {
- abortedTask {
- id
- status
- }
- }
- }
-`;
-
-const invalidateCachesMutation = graphql`
- mutation TaskDetailsInvalidateCachesMutation($input: InvalidateCacheEntriesInput!) {
- invalidateCacheEntries(input: $input) {
- clientMutationId
- }
- }
-`;
-
const taskSubscription = graphql`
subscription TaskDetailsSubscription($taskID: ID!) {
task(id: $taskID) {
@@ -172,29 +133,166 @@ const useStyles = makeStyles(theme => {
});
interface Props {
- task: TaskDetails_task;
+ task: TaskDetails_task$key;
}
-function TaskDetails(props: Props) {
+export default function TaskDetails(props: Props) {
+ let task = useFragment(
+ graphql`
+ fragment TaskDetails_task on Task {
+ id
+ name
+ buildId
+ status
+ triggerType
+ automaticReRun
+ ...TaskNameChip_task
+ ...TaskCreatedChip_task
+ ...TaskScheduledChip_task
+ ...TaskStatusChip_task
+ commands {
+ name
+ }
+ ...TaskCommandsProgress_task
+ ...TaskCommandList_task
+ ...TaskArtifacts_task
+ ...TaskTransactionChip_task
+ ...TaskOptionalChip_task
+ ...TaskResourcesChip_task
+ ...TaskExperimentalChip_task
+ ...TaskTimeoutChip_task
+ ...TaskStatefulChip_task
+ ...TaskOptionalChip_task
+ ...TaskRerunnerChip_task
+ ...TaskCancellerChip_task
+ labels
+ artifacts {
+ name
+ }
+ notifications {
+ message
+ ...Notification_notification
+ }
+ build {
+ branch
+ changeIdInRepo
+ changeMessageTitle
+ viewerPermission
+ ...BuildBranchNameChip_build
+ ...BuildChangeChip_build
+ }
+ repository {
+ cloneUrl
+ ...RepositoryOwnerChip_repository
+ ...RepositoryNameChip_repository
+ }
+ allOtherRuns {
+ id
+ localGroupId
+ requiredGroups
+ scheduledTimestamp
+ executingTimestamp
+ finalStatusTimestamp
+ ...TaskListRow_task
+ }
+ dependencies {
+ id
+ localGroupId
+ requiredGroups
+ scheduledTimestamp
+ executingTimestamp
+ finalStatusTimestamp
+ ...TaskListRow_task
+ }
+ ...TaskExecutionInfo_task
+ hooks {
+ timestamp
+ ...HookListRow_hook
+ }
+ executionInfo {
+ cacheRetrievalAttempts {
+ hits {
+ key
+ valid
+ }
+ }
+ agentNotifications {
+ message
+ }
+ }
+ terminalCredential {
+ locator
+ trustedSecret
+ }
+ }
+ `,
+ props.task,
+ );
let navigate = useNavigate();
+
+ const isFinalStatus = useMemo(() => isTaskFinalStatus(task.status), [task.status]);
useEffect(() => {
- if (isTaskFinalStatus(props.task.status)) {
+ if (isFinalStatus) {
return;
}
- let variables = { taskID: props.task.id };
+ let variables = { taskID: task.id };
let subscription = requestSubscription(environment, {
subscription: taskSubscription,
variables: variables,
});
return () => subscription.dispose();
- }, [props.task.id, props.task.status]);
+ }, [task.id, isFinalStatus]);
- let { task } = props;
let classes = useStyles();
let build = task.build;
let repository = task.repository;
+ const [commitTaskReRunMutation] = useMutation(graphql`
+ mutation TaskDetailsReRunMutation($input: TaskReRunInput!) {
+ rerun(input: $input) {
+ newTask {
+ id
+ }
+ }
+ }
+ `);
+
+ const [commitTaskTriggerMutation] = useMutation(
+ graphql`
+ mutation TaskDetailsTriggerMutation($input: TaskTriggerInput!) {
+ trigger(input: $input) {
+ task {
+ id
+ status
+ triggerType
+ }
+ }
+ }
+ `,
+ );
+
+ const [commitTaskCancelMutation] = useMutation(
+ graphql`
+ mutation TaskDetailsCancelMutation($input: TaskAbortInput!) {
+ abortTask(input: $input) {
+ abortedTask {
+ id
+ status
+ }
+ }
+ }
+ `,
+ );
+
+ const [commitInvalidateCachesMutation] = useMutation(graphql`
+ mutation TaskDetailsInvalidateCachesMutation($input: InvalidateCacheEntriesInput!) {
+ invalidateCacheEntries(input: $input) {
+ clientMutationId
+ }
+ }
+ `);
+
function trigger(taskId) {
const variables: TaskDetailsTriggerMutationVariables = {
input: {
@@ -203,8 +301,7 @@ function TaskDetails(props: Props) {
},
};
- commitMutation(environment, {
- mutation: taskTriggerMutation,
+ commitTaskTriggerMutation({
variables: variables,
onError: err => console.error(err),
});
@@ -218,8 +315,7 @@ function TaskDetails(props: Props) {
},
};
- commitMutation(environment, {
- mutation: taskCancelMutation,
+ commitTaskCancelMutation({
variables: variables,
onError: err => console.error(err),
});
@@ -265,8 +361,7 @@ function TaskDetails(props: Props) {
},
};
- commitMutation(environment, {
- mutation: taskReRunMutation,
+ commitTaskReRunMutation({
variables: variables,
onCompleted: (response: TaskDetailsReRunMutationResponse, errors) => {
if (errors) {
@@ -280,7 +375,7 @@ function TaskDetails(props: Props) {
}
let reRunButton =
- !hasWritePermissions(build.viewerPermission) || !isTaskFinalStatus(task.status) ? null : (
+ !hasWritePermissions(build.viewerPermission) || !isFinalStatus ? null : (
<>