Skip to content

Commit 533eae3

Browse files
authored
Migration owner settings (#528)
* Add useLazyLoadQuery to OwnerSettingsRenderer * Add useFragment to OwnerSettings * Error occurs * Add useFragment to OwnerComputeCredits * Add useFragment to ComputeCreditsBase * Add useFragment to BillingSettingsButton * Add useFragment to BillingSettingsDialog * Add useMutation to BillingSettingsDialog * Add useMutation to ComputeCreditsStripeDialog * Add useFragment to TaskDurationChip * Memorized isFinalStatus value
1 parent 1a2ea85 commit 533eae3

File tree

8 files changed

+186
-227
lines changed

8 files changed

+186
-227
lines changed

src/components/chips/TaskDurationChip.tsx

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import Avatar from '@mui/material/Avatar';
22
import Chip from '@mui/material/Chip';
33
import Icon from '@mui/material/Icon';
44
import { graphql } from 'babel-plugin-relay/macro';
5-
import React, { useEffect } from 'react';
6-
import { createFragmentContainer, requestSubscription } from 'react-relay';
5+
import React, { useEffect, useMemo } from 'react';
6+
import { useFragment, requestSubscription } from 'react-relay';
77
import environment from '../../createRelayEnvironment';
88
import { useTaskStatusColor } from '../../utils/colors';
99
import { isTaskFinalStatus, isTaskInProgressStatus, taskStatusIconName } from '../../utils/status';
1010
import { formatDuration } from '../../utils/time';
11-
import { TaskDurationChip_task } from './__generated__/TaskDurationChip_task.graphql';
11+
import { TaskDurationChip_task$key } from './__generated__/TaskDurationChip_task.graphql';
1212
import { useTheme } from '@mui/material';
1313

1414
const taskSubscription = graphql`
@@ -20,19 +20,34 @@ const taskSubscription = graphql`
2020
`;
2121

2222
interface Props {
23-
task: TaskDurationChip_task;
23+
task: TaskDurationChip_task$key;
2424
className?: string;
2525
}
2626

27-
function TaskDurationChip(props: Props) {
27+
export default function TaskDurationChip(props: Props) {
28+
let task = useFragment(
29+
graphql`
30+
fragment TaskDurationChip_task on Task {
31+
id
32+
status
33+
creationTimestamp
34+
scheduledTimestamp
35+
executingTimestamp
36+
durationInSeconds
37+
}
38+
`,
39+
props.task,
40+
);
41+
2842
let theme = useTheme();
2943

44+
const isFinalStatus = useMemo(() => isTaskFinalStatus(task.status), [task.status]);
3045
useEffect(() => {
31-
if (isTaskFinalStatus(props.task.status)) {
46+
if (isFinalStatus) {
3247
return;
3348
}
3449

35-
let variables = { taskID: props.task.id };
50+
let variables = { taskID: task.id };
3651

3752
const subscription = requestSubscription(environment, {
3853
subscription: taskSubscription,
@@ -41,26 +56,26 @@ function TaskDurationChip(props: Props) {
4156
return () => {
4257
subscription.dispose();
4358
};
44-
}, [props.task.id, props.task.status]);
59+
}, [task.id, isFinalStatus]);
4560

4661
const [now, setNow] = React.useState(Date.now());
4762

4863
useEffect(() => {
49-
if (isTaskFinalStatus(props.task.status)) {
64+
if (isFinalStatus) {
5065
return;
5166
}
5267
const timeoutId = setInterval(() => {
5368
setNow(Date.now());
5469
}, 1_000);
5570
return () => clearInterval(timeoutId);
56-
}, [now, props.task.status]);
71+
}, [now, isFinalStatus]);
5772

58-
let { task, className } = props;
73+
let { className } = props;
5974

6075
let durationInSeconds = task.durationInSeconds;
61-
if (!isTaskInProgressStatus(task.status) && !isTaskFinalStatus(task.status)) {
76+
if (!isTaskInProgressStatus(task.status) && !isFinalStatus) {
6277
durationInSeconds = 0;
63-
} else if (!isTaskFinalStatus(task.status)) {
78+
} else if (!isFinalStatus) {
6479
let timestamp = Math.max(task.creationTimestamp, task.scheduledTimestamp, task.executingTimestamp);
6580
durationInSeconds = (Date.now() - timestamp) / 1000;
6681
}
@@ -77,16 +92,3 @@ function TaskDurationChip(props: Props) {
7792
/>
7893
);
7994
}
80-
81-
export default createFragmentContainer(TaskDurationChip, {
82-
task: graphql`
83-
fragment TaskDurationChip_task on Task {
84-
id
85-
status
86-
creationTimestamp
87-
scheduledTimestamp
88-
executingTimestamp
89-
durationInSeconds
90-
}
91-
`,
92-
});
Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
import React, { useState } from 'react';
2-
import { createFragmentContainer } from 'react-relay';
2+
import { useFragment } from 'react-relay';
33
import { graphql } from 'babel-plugin-relay/macro';
44
import AlarmOffIcon from '@mui/icons-material/AlarmOff';
55
import AlarmOnIcon from '@mui/icons-material/AlarmOn';
66
import Button from '@mui/material/Button';
77
import BillingSettingsDialog from './BillingSettingsDialog';
8-
import { BillingSettingsButton_info } from './__generated__/BillingSettingsButton_info.graphql';
8+
import { BillingSettingsButton_info$key } from './__generated__/BillingSettingsButton_info.graphql';
99

1010
interface Props {
11-
info: BillingSettingsButton_info;
11+
info: BillingSettingsButton_info$key;
1212
className?: string;
1313
}
1414

15-
function BillingSettingsButton(props: Props) {
15+
export default function BillingSettingsButton(props: Props) {
16+
let info = useFragment(
17+
graphql`
18+
fragment BillingSettingsButton_info on OwnerInfo {
19+
billingSettings {
20+
enabled
21+
...BillingSettingsDialog_billingSettings
22+
}
23+
}
24+
`,
25+
props.info,
26+
);
1627
let [openDialog, setOpenDialog] = useState(false);
17-
let { info, className } = props;
28+
let { className } = props;
1829
if (!info) return null;
1930

2031
let { billingSettings } = info;
@@ -37,14 +48,3 @@ function BillingSettingsButton(props: Props) {
3748
</div>
3849
);
3950
}
40-
41-
export default createFragmentContainer(BillingSettingsButton, {
42-
info: graphql`
43-
fragment BillingSettingsButton_info on OwnerInfo {
44-
billingSettings {
45-
enabled
46-
...BillingSettingsDialog_billingSettings
47-
}
48-
}
49-
`,
50-
});

src/components/compute-credits/BillingSettingsDialog.tsx

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import Switch from '@mui/material/Switch';
1313
import Typography from '@mui/material/Typography';
1414
import { graphql } from 'babel-plugin-relay/macro';
1515
import React, { useState } from 'react';
16-
import { commitMutation, createFragmentContainer } from 'react-relay';
17-
import environment from '../../createRelayEnvironment';
16+
import { useMutation, useFragment } from 'react-relay';
1817
import {
18+
BillingSettingsDialogMutation,
1919
BillingSettingsDialogMutationResponse,
2020
BillingSettingsDialogMutationVariables,
2121
} from './__generated__/BillingSettingsDialogMutation.graphql';
22-
import { BillingSettingsDialog_billingSettings } from './__generated__/BillingSettingsDialog_billingSettings.graphql';
22+
import { BillingSettingsDialog_billingSettings$key } from './__generated__/BillingSettingsDialog_billingSettings.graphql';
2323
import { Link } from '@mui/material';
2424

2525
const useStyles = makeStyles(theme => {
@@ -33,31 +33,28 @@ const useStyles = makeStyles(theme => {
3333
};
3434
});
3535

36-
const saveBillingSettingsMutation = graphql`
37-
mutation BillingSettingsDialogMutation($input: BillingSettingsInput!) {
38-
saveBillingSettings(input: $input) {
39-
settings {
40-
ownerUid
41-
enabled
42-
billingCreditsLimit
43-
billingEmailAddress
44-
invoiceTemplate
45-
}
46-
}
47-
}
48-
`;
49-
5036
interface Props {
51-
billingSettings: BillingSettingsDialog_billingSettings;
37+
billingSettings: BillingSettingsDialog_billingSettings$key;
5238

5339
onClose(...args: any[]): void;
5440

5541
open: boolean;
5642
}
5743

58-
function BillingSettingsDialog(props: Props) {
44+
export default function BillingSettingsDialog(props: Props) {
45+
let billingSettings = useFragment(
46+
graphql`
47+
fragment BillingSettingsDialog_billingSettings on BillingSettings {
48+
ownerUid
49+
enabled
50+
billingCreditsLimit
51+
billingEmailAddress
52+
invoiceTemplate
53+
}
54+
`,
55+
props.billingSettings,
56+
);
5957
let classes = useStyles();
60-
const { billingSettings, ...other } = props;
6158
let [enabled, setEnabled] = useState(billingSettings.enabled);
6259
let [billingEmailAddress, setBillingEmailAddress] = useState(billingSettings.billingEmailAddress);
6360
let [invoiceTemplate, setInvoiceTemplate] = useState(billingSettings.invoiceTemplate);
@@ -67,18 +64,30 @@ function BillingSettingsDialog(props: Props) {
6764
billingSettings.billingEmailAddress === billingEmailAddress &&
6865
billingSettings.invoiceTemplate === invoiceTemplate;
6966

67+
const [commitSaveBillingSettingsMutation] = useMutation<BillingSettingsDialogMutation>(graphql`
68+
mutation BillingSettingsDialogMutation($input: BillingSettingsInput!) {
69+
saveBillingSettings(input: $input) {
70+
settings {
71+
ownerUid
72+
enabled
73+
billingCreditsLimit
74+
billingEmailAddress
75+
invoiceTemplate
76+
}
77+
}
78+
}
79+
`);
7080
function updateSettings() {
7181
const variables: BillingSettingsDialogMutationVariables = {
7282
input: {
73-
clientMutationId: 'save-billing-settings-' + props.billingSettings.ownerUid,
74-
ownerUid: props.billingSettings.ownerUid,
83+
clientMutationId: 'save-billing-settings-' + billingSettings.ownerUid,
84+
ownerUid: billingSettings.ownerUid,
7585
enabled: enabled,
7686
billingEmailAddress: billingEmailAddress,
7787
invoiceTemplate: invoiceTemplate,
7888
},
7989
};
80-
commitMutation(environment, {
81-
mutation: saveBillingSettingsMutation,
90+
commitSaveBillingSettingsMutation({
8291
variables: variables,
8392
onCompleted: (response: BillingSettingsDialogMutationResponse, errors) => {
8493
if (errors) {
@@ -95,7 +104,7 @@ function BillingSettingsDialog(props: Props) {
95104
}
96105

97106
return (
98-
<Dialog {...other}>
107+
<Dialog onClose={props.onClose} open={props.open}>
99108
<DialogTitle>Compute Credits Auto Pay</DialogTitle>
100109
<DialogContent>
101110
<FormControl fullWidth>
@@ -147,15 +156,3 @@ function BillingSettingsDialog(props: Props) {
147156
</Dialog>
148157
);
149158
}
150-
151-
export default createFragmentContainer(BillingSettingsDialog, {
152-
billingSettings: graphql`
153-
fragment BillingSettingsDialog_billingSettings on BillingSettings {
154-
ownerUid
155-
enabled
156-
billingCreditsLimit
157-
billingEmailAddress
158-
invoiceTemplate
159-
}
160-
`,
161-
});

src/components/compute-credits/ComputeCreditsBase.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { makeStyles } from '@mui/styles';
1313
import classNames from 'classnames';
1414
import React, { useState } from 'react';
1515
import BillingSettingsButton from './BillingSettingsButton';
16-
import { createFragmentContainer } from 'react-relay';
16+
import { useFragment } from 'react-relay';
1717
import { graphql } from 'babel-plugin-relay/macro';
18-
import { ComputeCreditsBase_info } from './__generated__/ComputeCreditsBase_info.graphql';
18+
import { ComputeCreditsBase_info$key } from './__generated__/ComputeCreditsBase_info.graphql';
1919
import { Helmet as Head } from 'react-helmet';
2020
import ComputeCreditsStripeDialog from './ComputeCreditsStripeDialog';
2121
import { Link } from '@mui/material';
@@ -58,12 +58,21 @@ const useStyles = makeStyles(theme => {
5858

5959
interface Props {
6060
transactionsComponent: JSX.Element;
61-
info?: ComputeCreditsBase_info;
61+
info?: ComputeCreditsBase_info$key;
6262
balanceInCredits?: string;
6363
ownerUid: string;
6464
}
6565

66-
function ComputeCreditsBase(props: Props) {
66+
export default function ComputeCreditsBase(props: Props) {
67+
let info = useFragment(
68+
graphql`
69+
fragment ComputeCreditsBase_info on OwnerInfo {
70+
...BillingSettingsButton_info
71+
}
72+
`,
73+
props.info,
74+
);
75+
6776
let [expanded, setExpanded] = useState(false);
6877
let [openBuyCredits, setOpenBuyCredits] = useState(false);
6978
let classes = useStyles();
@@ -102,7 +111,7 @@ function ComputeCreditsBase(props: Props) {
102111
<AttachMoneyIcon />
103112
Add More Credits
104113
</Button>
105-
<BillingSettingsButton info={props.info} />
114+
<BillingSettingsButton info={info} />
106115
<IconButton
107116
className={classNames(classes.expand, {
108117
[classes.expandOpen]: expanded,
@@ -126,11 +135,3 @@ function ComputeCreditsBase(props: Props) {
126135
</Card>
127136
);
128137
}
129-
130-
export default createFragmentContainer(ComputeCreditsBase, {
131-
info: graphql`
132-
fragment ComputeCreditsBase_info on OwnerInfo {
133-
...BillingSettingsButton_info
134-
}
135-
`,
136-
});

0 commit comments

Comments
 (0)