Skip to content

Commit 8d9e7d7

Browse files
committed
Start Work Page: Default Transition is "Closed" for Projects Without "In Progress"
Fixes #502
1 parent 1d6aaca commit 8d9e7d7

File tree

10 files changed

+149
-10
lines changed

10 files changed

+149
-10
lines changed

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,18 @@
11161116
"description": "Custom prefixes for branch names on start work screen",
11171117
"scope": "window"
11181118
},
1119+
"atlascode.jira.startWorkBranchTemplate.enableIssueTransition": {
1120+
"type": "boolean",
1121+
"default": true,
1122+
"description": "Enables the issue transition toggle on start work screen",
1123+
"scope": "window"
1124+
},
1125+
"atlascode.jira.startWorkBranchTemplate.defaultTransitionName": {
1126+
"type": "string",
1127+
"default": "",
1128+
"description": "The default transition name to use when starting work on an issue",
1129+
"scope": "window"
1130+
},
11191131
"atlascode.jira.showCreateIssueProblems": {
11201132
"type": "boolean",
11211133
"default": false,

src/config/model.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export interface JiraExplorer {
9090
export interface StartWorkBranchTemplate {
9191
customPrefixes: string[];
9292
customTemplate: string;
93+
enableIssueTransition: boolean;
94+
defaultTransitionName: string;
9395
}
9496

9597
export interface JiraHover {
@@ -202,6 +204,8 @@ const emptyTodoIssues: TodoIssues = {
202204
const emptyStartWorkBranchTemplate: StartWorkBranchTemplate = {
203205
customPrefixes: [],
204206
customTemplate: '{{prefix}}/{{issueKey}}-{{summary}}',
207+
enableIssueTransition: true,
208+
defaultTransitionName: '',
205209
};
206210

207211
const emptyJiraConfig: JiraConfig = {

src/lib/ipc/toUI/startWork.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export interface StartWorkInitMessage {
2626
customTemplate: string;
2727
customPrefixes: string[];
2828
isRovoDevEnabled: boolean;
29+
enableIssueTransition: boolean;
30+
defaultTransitionName: string;
2931
}
3032

3133
export interface StartWorkResponseMessage {

src/lib/webview/controller/startwork/startWorkWebviewController.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ describe('StartWorkWebviewController', () => {
120120
customTemplate: '{issueKey}',
121121
customPrefixes: ['feature/', 'bugfix/'],
122122
isRovoDevEnabled: true,
123+
enableIssueTransition: true,
124+
defaultTransitionName: '',
123125
};
124126

125127
beforeEach(() => {
@@ -501,6 +503,8 @@ describe('StartWorkWebviewController', () => {
501503
mockApi.getStartWorkConfig.mockReturnValue({
502504
customTemplate: '{issueKey}',
503505
customPrefixes: ['feature/', 'bugfix/'],
506+
enableIssueTransition: true,
507+
defaultTransitionName: '',
504508
});
505509
});
506510

@@ -534,6 +538,8 @@ describe('StartWorkWebviewController', () => {
534538
]),
535539
customTemplate: '{issueKey}',
536540
customPrefixes: ['feature/', 'bugfix/'],
541+
enableIssueTransition: true,
542+
defaultTransitionName: '',
537543
});
538544
});
539545

@@ -566,6 +572,8 @@ describe('StartWorkWebviewController', () => {
566572
]),
567573
customTemplate: '{issueKey}',
568574
customPrefixes: ['feature/', 'bugfix/'],
575+
enableIssueTransition: true,
576+
defaultTransitionName: '',
569577
});
570578
});
571579

@@ -582,6 +590,8 @@ describe('StartWorkWebviewController', () => {
582590
repoData: [],
583591
customTemplate: '{issueKey}',
584592
customPrefixes: ['feature/', 'bugfix/'],
593+
enableIssueTransition: true,
594+
defaultTransitionName: '',
585595
});
586596
});
587597

@@ -679,6 +689,8 @@ describe('StartWorkWebviewController', () => {
679689
mockApi.getStartWorkConfig.mockReturnValue({
680690
customTemplate: '{issueKey}',
681691
customPrefixes: [],
692+
enableIssueTransition: true,
693+
defaultTransitionName: '',
682694
});
683695

684696
await controller.onMessageReceived({ type: CommonActionType.Refresh });
@@ -693,6 +705,8 @@ describe('StartWorkWebviewController', () => {
693705
]),
694706
customTemplate: '{issueKey}',
695707
customPrefixes: [],
708+
enableIssueTransition: true,
709+
defaultTransitionName: '',
696710
});
697711
});
698712

@@ -729,6 +743,8 @@ describe('StartWorkWebviewController', () => {
729743
mockApi.getStartWorkConfig.mockReturnValue({
730744
customTemplate: '{issueKey}',
731745
customPrefixes: [],
746+
enableIssueTransition: true,
747+
defaultTransitionName: '',
732748
});
733749

734750
await controller.onMessageReceived({ type: CommonActionType.Refresh });
@@ -743,6 +759,8 @@ describe('StartWorkWebviewController', () => {
743759
]),
744760
customTemplate: '{issueKey}',
745761
customPrefixes: [],
762+
enableIssueTransition: true,
763+
defaultTransitionName: '',
746764
});
747765
});
748766
});

src/react/atlascode/common/StartWorkPanel.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,20 @@ import { PanelTitle } from './PanelTitle';
1313
type StartWorkPanelProps = CommonSubpanelProps & {
1414
customPrefixes: string[];
1515
customTemplate: string;
16+
enableIssueTransition: boolean;
17+
defaultTransitionName: string;
1618
};
1719

1820
export const StartWorkPanel: React.FunctionComponent<StartWorkPanelProps> = memo(
19-
({ visible, expanded, customPrefixes, customTemplate, onSubsectionChange }) => {
21+
({
22+
visible,
23+
expanded,
24+
customPrefixes,
25+
customTemplate,
26+
defaultTransitionName,
27+
enableIssueTransition,
28+
onSubsectionChange,
29+
}) => {
2030
const [internalExpanded, setInternalExpanded] = useState<boolean>(expanded);
2131

2232
const expansionHandler = useCallback(
@@ -47,7 +57,12 @@ export const StartWorkPanel: React.FunctionComponent<StartWorkPanelProps> = memo
4757
<PanelSubtitle>configure the start work screen</PanelSubtitle>
4858
</AccordionSummary>
4959
<AccordionDetails>
50-
<StartWorkSettings customPrefixes={customPrefixes} customTemplate={customTemplate} />
60+
<StartWorkSettings
61+
customPrefixes={customPrefixes}
62+
customTemplate={customTemplate}
63+
enableIssueTransition={enableIssueTransition}
64+
defaultTransitionName={defaultTransitionName}
65+
/>
5166
</AccordionDetails>
5267
</Accordion>
5368
);

src/react/atlascode/config/StartWorkSettings.tsx

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { InlineTextEditor, InlineTextEditorList } from '@atlassianlabs/guipi-core-components';
2-
import { Box, FormHelperText, Grid, Link, Typography } from '@mui/material';
2+
import { Box, FormHelperText, Grid, Link, Switch, Tooltip, Typography } from '@mui/material';
33
import Mustache from 'mustache';
44
import React, { useCallback, useContext, useEffect, useState } from 'react';
55

@@ -9,9 +9,16 @@ import { ConfigControllerContext } from './configController';
99
type StartWorkSettings = {
1010
customTemplate: string;
1111
customPrefixes: string[];
12+
enableIssueTransition: boolean;
13+
defaultTransitionName: string;
1214
};
1315

14-
export const StartWorkSettings: React.FunctionComponent<StartWorkSettings> = ({ customTemplate, customPrefixes }) => {
16+
export const StartWorkSettings: React.FunctionComponent<StartWorkSettings> = ({
17+
customTemplate,
18+
customPrefixes,
19+
enableIssueTransition,
20+
defaultTransitionName,
21+
}) => {
1522
const controller = useContext(ConfigControllerContext);
1623
const boxClass = useBorderBoxStyles();
1724
const [changes, setChanges] = useState<{ [key: string]: any }>({});
@@ -21,6 +28,10 @@ export const StartWorkSettings: React.FunctionComponent<StartWorkSettings> = ({
2128
setTemplate(customTemplate);
2229
}, [customTemplate]);
2330

31+
const stopProp = useCallback((event: React.MouseEvent<HTMLElement>) => {
32+
event.stopPropagation();
33+
}, []);
34+
2435
const handlePrefixesChange = useCallback((newOptions: string[]) => {
2536
const changes = Object.create(null);
2637
changes['jira.startWorkBranchTemplate.customPrefixes'] = newOptions;
@@ -34,6 +45,25 @@ export const StartWorkSettings: React.FunctionComponent<StartWorkSettings> = ({
3445
setChanges(changes);
3546
}, []);
3647

48+
const handleEnableIssueTransitionChange = useCallback((enable: boolean) => {
49+
const changes = Object.create(null);
50+
changes['jira.startWorkBranchTemplate.enableIssueTransition'] = enable;
51+
setChanges(changes);
52+
}, []);
53+
54+
const toggleIssueTransition = useCallback(
55+
(event: React.ChangeEvent<HTMLInputElement>) => {
56+
handleEnableIssueTransitionChange(event.target.checked);
57+
},
58+
[handleEnableIssueTransitionChange],
59+
);
60+
61+
const handleTransitionNameChange = useCallback((name: string) => {
62+
const changes = Object.create(null);
63+
changes['jira.startWorkBranchTemplate.defaultTransitionName'] = name;
64+
setChanges(changes);
65+
}, []);
66+
3767
useEffect(() => {
3868
if (Object.keys(changes).length > 0) {
3969
controller.updateConfig(changes);
@@ -145,6 +175,44 @@ export const StartWorkSettings: React.FunctionComponent<StartWorkSettings> = ({
145175
</Box>
146176
</Box>
147177
</Grid>
178+
<Grid item>
179+
<Box margin={2}>
180+
<Typography variant="h4">Enable Issue Transition</Typography>
181+
<Typography variant="caption">
182+
If enabled, the "Transition issue" dropdown on the Start Work page will be shown. This allows
183+
you to choose which status the issue should move to when starting work.
184+
</Typography>
185+
<Box marginTop={1} paddingBottom={2}>
186+
<Tooltip title={enableIssueTransition ? 'Disable issue transition' : 'Enable issue transition'}>
187+
<Switch
188+
color="primary"
189+
size="small"
190+
checked={enableIssueTransition}
191+
onClick={stopProp}
192+
onChange={toggleIssueTransition}
193+
/>
194+
</Tooltip>
195+
</Box>
196+
</Box>
197+
</Grid>
198+
<Grid item>
199+
<Box margin={2}>
200+
<Typography variant="h4">Default Issue Transition</Typography>
201+
<Typography variant="caption">
202+
The "Transition issue" dropdown on the Start Work page lets you choose which status the issue
203+
should move to. By default, it is set to "In Progress". To change the default selection in the
204+
dropdown, enter a transition name below.
205+
</Typography>
206+
<Box marginTop={1} paddingBottom={2}>
207+
<InlineTextEditor
208+
fullWidth
209+
label="Default Transition Name"
210+
defaultValue={defaultTransitionName}
211+
onSave={handleTransitionNameChange}
212+
/>
213+
</Box>
214+
</Box>
215+
</Grid>
148216
</Grid>
149217
);
150218
};

src/react/atlascode/config/jira/JiraPanel.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ export const JiraPanel: React.FunctionComponent<JiraPanelProps> = ({
9494
onSubsectionChange={onSubsectionChange}
9595
customPrefixes={config[`${ConfigSection.Jira}.startWorkBranchTemplate.customPrefixes`]}
9696
customTemplate={config[`${ConfigSection.Jira}.startWorkBranchTemplate.customTemplate`]}
97+
enableIssueTransition={
98+
config[`${ConfigSection.Jira}.startWorkBranchTemplate.enableIssueTransition`]
99+
}
100+
defaultTransitionName={
101+
config[`${ConfigSection.Jira}.startWorkBranchTemplate.defaultTransitionName`]
102+
}
97103
/>
98104
</Grid>
99105
<Grid item>

src/react/atlascode/startwork/StartWorkPage.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,25 @@ const StartWorkPage: React.FunctionComponent = () => {
353353
});
354354
}, [controller]);
355355

356+
useEffect(() => {
357+
setTransitionIssueEnabled(state.enableIssueTransition);
358+
}, [state.enableIssueTransition]);
359+
356360
useEffect(() => {
357361
// best effort to default to a transition that will move the issue to `In progress` state
358362
const inProgressTransitionGuess: Transition =
363+
(state.defaultTransitionName !== '' &&
364+
state.issue.transitions.find(
365+
(t) =>
366+
!t.isInitial &&
367+
t.to.name.toLocaleLowerCase() === state.defaultTransitionName.toLocaleLowerCase(),
368+
)) ||
359369
state.issue.transitions.find((t) => !t.isInitial && t.to.name.toLocaleLowerCase().includes('progress')) ||
360370
state.issue.transitions.find((t) => !t.isInitial) ||
361371
state.issue.transitions?.[0] ||
362372
emptyTransition;
363373
setTransition(inProgressTransitionGuess);
364-
}, [state.issue]);
374+
}, [state.defaultTransitionName, state.issue]);
365375

366376
useEffect(() => {
367377
if (state.rovoDevPreference !== undefined) {

src/react/atlascode/startwork/startWorkController.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ export interface StartWorkControllerApi {
4242
}
4343

4444
const emptyApi: StartWorkControllerApi = {
45-
postMessage: () => {},
46-
refresh: () => {},
47-
openLink: () => {},
45+
postMessage: () => { },
46+
refresh: () => { },
47+
openLink: () => { },
4848
startWork: async () => ({}),
49-
closePage: () => {},
50-
openJiraIssue: () => {},
49+
closePage: () => { },
50+
openJiraIssue: () => { },
5151
openSettings: (section?, subsection?): void => {
5252
return;
5353
},
@@ -66,6 +66,8 @@ const emptyState: StartWorkState = {
6666
customTemplate: '{{prefix}}/{{issueKey}}-{{summary}}',
6767
customPrefixes: [],
6868
rovoDevPreference: false,
69+
enableIssueTransition: true,
70+
defaultTransitionName: '',
6971
};
7072

7173
enum StartWorkUIActionType {

src/webview/startwork/vscStartWorkActionApi.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ export class VSCStartWorkActionApi implements StartWorkActionApi {
9494
return {
9595
customTemplate: Container.config.jira.startWorkBranchTemplate.customTemplate,
9696
customPrefixes: Container.config.jira.startWorkBranchTemplate.customPrefixes,
97+
enableIssueTransition: Container.config.jira.startWorkBranchTemplate.enableIssueTransition,
98+
defaultTransitionName: Container.config.jira.startWorkBranchTemplate.defaultTransitionName,
9799
};
98100
}
99101

0 commit comments

Comments
 (0)