1 package org.argeo.tracker.ui.dialogs;
2
3 import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty;
4
5 import java.util.ArrayList;
6 import java.util.Calendar;
7 import java.util.List;
8
9 import javax.jcr.Node;
10 import javax.jcr.Property;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.Value;
13
14 import org.argeo.activities.ActivitiesNames;
15 import org.argeo.connect.UserAdminService;
16 import org.argeo.connect.core.OfficeRole;
17 import org.argeo.connect.ui.ConnectUiUtils;
18 import org.argeo.connect.ui.widgets.DateText;
19 import org.argeo.connect.ui.widgets.GroupDropDown;
20 import org.argeo.connect.util.ConnectJcrUtils;
21 import org.argeo.eclipse.ui.EclipseUiUtils;
22 import org.argeo.tracker.TrackerException;
23 import org.argeo.tracker.TrackerNames;
24 import org.argeo.tracker.TrackerService;
25 import org.argeo.tracker.core.TrackerUtils;
26 import org.argeo.tracker.ui.controls.MilestoneDropDown;
27 import org.argeo.tracker.ui.controls.ProjectDropDown;
28 import org.argeo.tracker.ui.controls.TagListWithDropDownComposite;
29 import org.eclipse.jface.dialogs.MessageDialog;
30 import org.eclipse.jface.wizard.Wizard;
31 import org.eclipse.jface.wizard.WizardPage;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.FocusAdapter;
34 import org.eclipse.swt.events.FocusEvent;
35 import org.eclipse.swt.layout.GridData;
36 import org.eclipse.swt.layout.GridLayout;
37 import org.eclipse.swt.widgets.Combo;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Text;
41
42
43
44
45
46
47
48
49 public class ConfigureIssueWizard extends Wizard {
50
51
52 private final UserAdminService userAdminService;
53 private final TrackerService trackerService;
54 private final Node project;
55 private final Node issue;
56
57
58 private Node chosenProject;
59 private List<String> versionIds;
60 private List<String> componentIds;
61
62
63 private Text projectTxt;
64 private ProjectDropDown projectDD;
65 private MilestoneDropDown milestoneDD;
66 private Text titleTxt;
67 private GroupDropDown assignedToDD;
68 private DateText dueDateCmp;
69
70 private Combo importanceCmb;
71 private Combo priorityCmb;
72 private TagListWithDropDownComposite versionsCmp;
73 private TagListWithDropDownComposite componentsCmp;
74 private Text descTxt;
75
76 public ConfigureIssueWizard(UserAdminService userAdminService, TrackerService trackerService, Node issue) {
77 this.userAdminService = userAdminService;
78 this.trackerService = trackerService;
79 this.issue = issue;
80 project = TrackerUtils.getRelatedProject(trackerService, issue);
81 chosenProject = project;
82
83 try {
84 if (issue.hasProperty(TrackerNames.TRACKER_VERSION_IDS)) {
85 Value[] values = issue.getProperty(TrackerNames.TRACKER_VERSION_IDS).getValues();
86 versionIds = new ArrayList<>();
87 for (Value value : values)
88 versionIds.add(value.getString());
89 }
90 if (issue.hasProperty(TrackerNames.TRACKER_COMPONENT_IDS)) {
91 Value[] values = issue.getProperty(TrackerNames.TRACKER_COMPONENT_IDS).getValues();
92 componentIds = new ArrayList<>();
93 for (Value value : values)
94 componentIds.add(value.getString());
95 }
96 } catch (RepositoryException e) {
97 throw new TrackerException("Cannot retrieve info on " + issue, e);
98 }
99 }
100
101 @Override
102 public void addPages() {
103 setWindowTitle("Issue configuration");
104 addPage(new ConfigureIssuePage("Main page"));
105 }
106
107 @Override
108 public boolean performFinish() {
109
110 String msg = null;
111 String title = titleTxt.getText();
112 if (chosenProject == null)
113 msg = "Please pick up a project";
114 else if (isEmpty(title))
115 msg = "Please give at least a title";
116
117 if (msg != null) {
118 MessageDialog.openError(getShell(), "Uncomplete information", msg);
119 return false;
120 }
121
122 try {
123 String importanceStr = TrackerUtils.getKeyByValue(TrackerUtils.MAPS_ISSUE_IMPORTANCES,
124 importanceCmb.getText());
125 int importance = new Integer(importanceStr).intValue();
126 String priorityStr = TrackerUtils.getKeyByValue(TrackerUtils.MAPS_ISSUE_PRIORITIES, priorityCmb.getText());
127 int priority = new Integer(priorityStr).intValue();
128
129 trackerService.configureIssue(issue, chosenProject, milestoneDD.getChosenMilestone(), title,
130 descTxt.getText(), versionsCmp.getChosenValues(), componentsCmp.getChosenValues(), priority,
131 importance, assignedToDD.getText());
132
133 Calendar dueDate = dueDateCmp.getCalendar();
134 if (dueDate != null)
135 issue.setProperty(ActivitiesNames.ACTIVITIES_DUE_DATE, dueDate);
136
137 } catch (RepositoryException e) {
138 throw new TrackerException("Unable to create issue on project " + project, e);
139 }
140 return true;
141 }
142
143 @Override
144 public boolean performCancel() {
145 return true;
146 }
147
148 @Override
149 public boolean canFinish() {
150 return true;
151 }
152
153 protected class ConfigureIssuePage extends WizardPage {
154 private static final long serialVersionUID = 4546838571499571513L;
155
156 public ConfigureIssuePage(String pageName) {
157 super(pageName);
158 setMessage("Please complete below information.");
159 }
160
161 public void createControl(Composite parent) {
162 parent.setLayout(new GridLayout(4, false));
163
164
165 ConnectUiUtils.createBoldLabel(parent, "Project");
166 projectTxt = new Text(parent, SWT.BORDER);
167 projectTxt.setMessage("Choose relevant project");
168 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
169 gd.horizontalSpan = 3;
170 projectTxt.setLayoutData(gd);
171
172 if (project == null) {
173 projectDD = new ProjectDropDown(ConnectJcrUtils.getSession(issue), projectTxt, false);
174
175 projectTxt.addFocusListener(new FocusAdapter() {
176 private static final long serialVersionUID = 1719432159240562984L;
177
178 @Override
179 public void focusLost(FocusEvent event) {
180 Node project = projectDD.getChosenProject();
181 if (project == null)
182 setErrorMessage("Choose a valid project");
183 else {
184 setErrorMessage(null);
185 chosenProject = project;
186 milestoneDD.setProject(chosenProject);
187 }
188 }
189 });
190 } else
191 projectTxt.setEditable(false);
192
193
194 ConnectUiUtils.createBoldLabel(parent, "Milestone");
195 Text milestoneTxt = new Text(parent, SWT.BORDER);
196 gd = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1);
197 milestoneTxt.setLayoutData(gd);
198 milestoneDD = new MilestoneDropDown(ConnectJcrUtils.getSession(issue), milestoneTxt, false);
199 if (project != null)
200 milestoneDD.setProject(project);
201
202
203 ConnectUiUtils.createBoldLabel(parent, "Title");
204 titleTxt = new Text(parent, SWT.BORDER);
205 titleTxt.setMessage("To be shown in the various lists");
206 titleTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
207
208
209 Text assignedToTxt = createBoldLT(parent, "Assigned to", "",
210 "Choose a group or person to manage this issue", 1);
211 assignedToDD = new GroupDropDown(assignedToTxt, userAdminService, OfficeRole.coworker.dn());
212
213
214 ConnectUiUtils.createBoldLabel(parent, "Due date");
215 dueDateCmp = new DateText(parent, SWT.NO_FOCUS);
216
217
218 ConnectUiUtils.createBoldLabel(parent, "Importance");
219 importanceCmb = new Combo(parent, SWT.READ_ONLY);
220 gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
221 importanceCmb.setLayoutData(gd);
222 importanceCmb.setItems(TrackerUtils.MAPS_ISSUE_IMPORTANCES.values().toArray(new String[0]));
223 importanceCmb.select(0);
224
225
226 ConnectUiUtils.createBoldLabel(parent, "Priority");
227 priorityCmb = new Combo(parent, SWT.READ_ONLY);
228 gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
229 priorityCmb.setLayoutData(gd);
230 priorityCmb.setItems(TrackerUtils.MAPS_ISSUE_PRIORITIES.values().toArray(new String[0]));
231 priorityCmb.select(0);
232
233
234 ConnectUiUtils.createBoldLabel(parent, "Impacted Version");
235 versionsCmp = new TagListWithDropDownComposite(parent, SWT.NO_FOCUS, versionIds) {
236 private static final long serialVersionUID = -3852824835081771001L;
237
238 @Override
239 protected List<String> getFilteredValues(String filter) {
240 if (chosenProject == null)
241 return new ArrayList<>();
242 else
243 return TrackerUtils.getVersionIds(chosenProject, filter);
244 }
245 };
246 versionsCmp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
247
248
249 ConnectUiUtils.createBoldLabel(parent, "Components");
250 componentsCmp = new TagListWithDropDownComposite(parent, SWT.NO_FOCUS, componentIds) {
251 private static final long serialVersionUID = 2356778978317806935L;
252
253 @Override
254 protected List<String> getFilteredValues(String filter) {
255 if (chosenProject == null)
256 return new ArrayList<>();
257 else
258 return TrackerUtils.getComponentIds(chosenProject, filter);
259 }
260 };
261 componentsCmp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
262
263
264 Label label = new Label(parent, SWT.LEAD | SWT.TOP);
265 label.setText("Description");
266 label.setFont(EclipseUiUtils.getBoldFont(parent));
267 gd = new GridData(SWT.LEAD, SWT.TOP, false, false);
268 label.setLayoutData(gd);
269 descTxt = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP);
270 descTxt.setMessage("A longer description");
271 gd = EclipseUiUtils.fillAll();
272 gd.horizontalSpan = 3;
273 gd.heightHint = 150;
274 descTxt.setLayoutData(gd);
275
276
277 Node milestone = null;
278 try {
279 if (issue.hasProperty(Property.JCR_TITLE))
280 titleTxt.setText(issue.getProperty(Property.JCR_TITLE).getString());
281 if (issue.hasProperty(Property.JCR_DESCRIPTION))
282 descTxt.setText(issue.getProperty(Property.JCR_DESCRIPTION).getString());
283 if (project != null)
284 projectTxt.setText(ConnectJcrUtils.get(project, Property.JCR_TITLE));
285
286 String muid = ConnectJcrUtils.get(issue, TrackerNames.TRACKER_MILESTONE_UID);
287 if (EclipseUiUtils.notEmpty(muid)) {
288 milestone = trackerService.getEntityByUid(ConnectJcrUtils.getSession(issue), null, muid);
289 milestoneDD.resetMilestone(milestone);
290 }
291
292 if (issue.hasProperty(ActivitiesNames.ACTIVITIES_ASSIGNED_TO))
293 assignedToDD.resetDN(issue.getProperty(ActivitiesNames.ACTIVITIES_ASSIGNED_TO).getString());
294 else if (milestone != null && milestone.hasProperty(TrackerNames.TRACKER_DEFAULT_ASSIGNEE))
295 assignedToDD.resetDN(milestone.getProperty(TrackerNames.TRACKER_DEFAULT_ASSIGNEE).getString());
296
297 if (issue.hasProperty(ActivitiesNames.ACTIVITIES_DUE_DATE))
298 dueDateCmp.setText(issue.getProperty(ActivitiesNames.ACTIVITIES_DUE_DATE).getDate());
299 else if (milestone != null && milestone.hasProperty(TrackerNames.TRACKER_TARGET_DATE))
300 dueDateCmp.setText(milestone.getProperty(TrackerNames.TRACKER_TARGET_DATE).getDate());
301
302
303
304
305
306 Long importance = ConnectJcrUtils.getLongValue(issue, TrackerNames.TRACKER_IMPORTANCE);
307 if (importance != null) {
308 String iv = TrackerUtils.MAPS_ISSUE_IMPORTANCES.get(importance.toString());
309 importanceCmb.setText(iv);
310 }
311 Long priority = ConnectJcrUtils.getLongValue(issue, TrackerNames.TRACKER_PRIORITY);
312 if (priority != null) {
313 String iv = TrackerUtils.MAPS_ISSUE_PRIORITIES.get(priority.toString());
314 priorityCmb.setText(iv);
315 }
316
317 } catch (RepositoryException e) {
318 throw new TrackerException("Cannot initialise widgets with existing data on " + issue, e);
319 }
320
321 milestoneTxt.addFocusListener(new FocusAdapter() {
322 private static final long serialVersionUID = -5599617250726559371L;
323
324 @Override
325 public void focusLost(FocusEvent event) {
326 Node milestone = milestoneDD.getChosenMilestone();
327 if (milestone != null) {
328 try {
329 if (EclipseUiUtils.isEmpty(assignedToDD.getText())
330 && milestone.hasProperty(TrackerNames.TRACKER_DEFAULT_ASSIGNEE))
331 assignedToDD.resetDN(
332 milestone.getProperty(TrackerNames.TRACKER_DEFAULT_ASSIGNEE).getString());
333 if (dueDateCmp.getCalendar() == null
334 && milestone.hasProperty(TrackerNames.TRACKER_TARGET_DATE))
335 dueDateCmp.setText(milestone.getProperty(TrackerNames.TRACKER_TARGET_DATE).getDate());
336 } catch (RepositoryException e) {
337 throw new TrackerException("Cannot set default values for milestone " + milestone, e);
338 }
339 }
340 }
341 });
342
343
344 if (project == null) {
345 setControl(projectTxt);
346 projectTxt.setFocus();
347 } else if (milestone == null) {
348 setControl(milestoneTxt);
349 milestoneTxt.setFocus();
350 } else {
351 setControl(titleTxt);
352 titleTxt.setFocus();
353 }
354 }
355 }
356
357 private Text createBoldLT(Composite parent, String title, String message, String tooltip, int colspan) {
358 ConnectUiUtils.createBoldLabel(parent, title);
359 Text text = new Text(parent, SWT.BOTTOM | SWT.BORDER);
360 text.setLayoutData(EclipseUiUtils.fillAll(colspan, 1));
361 text.setMessage(message);
362 text.setToolTipText(tooltip);
363 return text;
364 }
365 }