1 package org.argeo.tracker.e4.parts;
2
3 import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
4
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import javax.jcr.Node;
9 import javax.jcr.NodeIterator;
10 import javax.jcr.Property;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.Session;
13
14 import org.argeo.activities.ActivitiesNames;
15 import org.argeo.activities.ui.AssignedToLP;
16 import org.argeo.cms.ui.eclipse.forms.AbstractFormPart;
17 import org.argeo.cms.ui.eclipse.forms.IManagedForm;
18 import org.argeo.connect.AppService;
19 import org.argeo.connect.ConnectNames;
20 import org.argeo.connect.ui.ConnectColumnDefinition;
21 import org.argeo.connect.ui.ConnectImages;
22 import org.argeo.connect.ui.IJcrTableViewer;
23 import org.argeo.connect.ui.util.JcrRowLabelProvider;
24 import org.argeo.connect.ui.util.UserNameLP;
25 import org.argeo.connect.util.ConnectJcrUtils;
26 import org.argeo.eclipse.ui.ColumnDefinition;
27 import org.argeo.eclipse.ui.EclipseUiUtils;
28 import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider;
29 import org.argeo.jcr.JcrUtils;
30 import org.argeo.tracker.TrackerException;
31 import org.argeo.tracker.TrackerNames;
32 import org.argeo.tracker.TrackerTypes;
33 import org.argeo.tracker.core.TrackerUtils;
34 import org.argeo.tracker.ui.TrackerLps;
35 import org.argeo.tracker.ui.dialogs.ConfigureIssueWizard;
36 import org.eclipse.jface.viewers.DoubleClickEvent;
37 import org.eclipse.jface.viewers.IDoubleClickListener;
38 import org.eclipse.jface.viewers.IStructuredSelection;
39 import org.eclipse.jface.viewers.TableViewer;
40 import org.eclipse.jface.window.Window;
41 import org.eclipse.jface.wizard.WizardDialog;
42 import org.eclipse.swt.SWT;
43 import org.eclipse.swt.custom.ScrolledComposite;
44 import org.eclipse.swt.events.ModifyEvent;
45 import org.eclipse.swt.events.ModifyListener;
46 import org.eclipse.swt.events.SelectionAdapter;
47 import org.eclipse.swt.events.SelectionEvent;
48 import org.eclipse.swt.layout.GridData;
49 import org.eclipse.swt.layout.GridLayout;
50 import org.eclipse.swt.widgets.Button;
51 import org.eclipse.swt.widgets.Composite;
52 import org.eclipse.swt.widgets.Text;
53
54
55
56
57
58
59
60 public class CategoryEditor extends AbstractTrackerEditor implements IJcrTableViewer {
61
62
63
64
65
66
67 private Node project;
68 private Node category;
69 private String relevantPropName;
70 private String officeID;
71
72
73 private Text filterTxt;
74 private AbstractFormPart issueListPart;
75
76 @Override
77 protected void addPages() {
78
79 category = getNode();
80 project = TrackerUtils.getProjectFromChild(category);
81 officeID = ConnectJcrUtils.get(category, TrackerNames.TRACKER_ID);
82 relevantPropName = TrackerUtils.getRelevantPropName(category);
83 try {
84 addPage(new MainPage(this));
85
86
87
88 } catch (Exception e) {
89 throw new TrackerException("Cannot add pages for editor of " + getNode(), e);
90 }
91 }
92
93 protected void updatePartName() {
94 String name = getCategoryTitle();
95 if (notEmpty(name))
96 setPartName(name);
97 else
98 super.updatePartName();
99 }
100
101 private class MainPage extends AbstractEditorPage {
102 public final static String PAGE_ID = "mainPage";
103
104 private TableViewer tableViewer;
105
106 public MainPage(AbstractTrackerEditor editor) {
107 super(editor, PAGE_ID, "Overview");
108 }
109
110 protected void createFormContent(final IManagedForm mf) {
111
112
113 ScrolledComposite form = mf.getForm();
114 Composite body = new Composite(form, SWT.NONE);
115
116 GridLayout mainLayout = new GridLayout();
117 body.setLayout(mainLayout);
118 Composite filterCmp = new Composite(body, SWT.NO_FOCUS);
119 createFilterPart(filterCmp);
120 filterCmp.setLayoutData(EclipseUiUtils.fillWidth());
121 Composite tableCmp = new Composite(body, SWT.NO_FOCUS);
122 appendIssuesPart(tableCmp, mf);
123 tableCmp.setLayoutData(EclipseUiUtils.fillAll());
124
125 }
126
127
128 private void appendIssuesPart(Composite parent, IManagedForm mf) {
129 List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
130 columnDefs.add(new ColumnDefinition(new SimpleJcrNodeLabelProvider(TrackerNames.TRACKER_ID), "ID", 40));
131 columnDefs.add(new ColumnDefinition(new SimpleJcrNodeLabelProvider(Property.JCR_TITLE), "Title", 300));
132 columnDefs.add(new ColumnDefinition(new SimpleJcrNodeLabelProvider(ActivitiesNames.ACTIVITIES_TASK_STATUS),
133 "Status", 100));
134 columnDefs.add(new ColumnDefinition(new TrackerLps().new ImportanceLabelProvider(), "Importance", 100));
135 columnDefs.add(new ColumnDefinition(new TrackerLps().new PriorityLabelProvider(), "Priority", 100));
136
137
138 tableViewer = TrackerUiUtils.createTableViewer(parent, SWT.SINGLE, columnDefs);
139 tableViewer.addDoubleClickListener(new IDoubleClickListener() {
140
141 @Override
142 public void doubleClick(DoubleClickEvent event) {
143 Object element = ((IStructuredSelection) event.getSelection()).getFirstElement();
144
145
146
147 getAppWorkbenchService().openEntityEditor((Node) element);
148 }
149 });
150
151 issueListPart = new AbstractFormPart() {
152 @Override
153 public void refresh() {
154 refreshViewer(filterTxt.getText());
155 super.refresh();
156 }
157 };
158 mf.addPart(issueListPart);
159 refreshViewer(null);
160 }
161
162 public void setActive(boolean active) {
163 issueListPart.markStale();
164 super.setActive(active);
165 }
166
167 private void refreshViewer(String filter) {
168 NodeIterator nit = TrackerUtils.getIssues(project, filter, relevantPropName, officeID);
169 tableViewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray(new Node[0]));
170 tableViewer.refresh();
171 }
172
173
174 private void createFilterPart(Composite parent) {
175 GridLayout layout = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false));
176 layout.horizontalSpacing = 5;
177 parent.setLayout(layout);
178 parent.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
179
180 filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
181 filterTxt.setLayoutData(EclipseUiUtils.fillWidth());
182
183 final Button addBtn = new Button(parent, SWT.PUSH);
184 addBtn.setToolTipText("Create a new issue");
185 addBtn.setImage(ConnectImages.ADD);
186
187 filterTxt.addModifyListener(new ModifyListener() {
188 private static final long serialVersionUID = 8130545587125370689L;
189
190 public void modifyText(ModifyEvent event) {
191 refreshViewer(filterTxt.getText());
192 }
193 });
194
195 addBtn.addSelectionListener(new SelectionAdapter() {
196 private static final long serialVersionUID = -7249705366574519524L;
197
198 @Override
199 public void widgetSelected(SelectionEvent e) {
200
201 Session tmpSession = null;
202 Session targetSession = null;
203 try {
204 AppService as = getAppService();
205 tmpSession = project.getSession().getRepository().login();
206 Node draftIssue = as.createDraftEntity(tmpSession, TrackerTypes.TRACKER_ISSUE);
207 draftIssue.setProperty(TrackerNames.TRACKER_PROJECT_UID,
208 ConnectJcrUtils.get(project, ConnectNames.CONNECT_UID));
209
210 if (ConnectJcrUtils.isNodeType(category, TrackerTypes.TRACKER_COMPONENT))
211 ConnectJcrUtils.setMultiValueStringPropFromString(draftIssue,
212 TrackerNames.TRACKER_COMPONENT_IDS, officeID, "; ");
213 else if (ConnectJcrUtils.isNodeType(category, TrackerTypes.TRACKER_VERSION))
214 ConnectJcrUtils.setMultiValueStringPropFromString(draftIssue,
215 TrackerNames.TRACKER_VERSION_IDS, officeID, "; ");
216
217 ConfigureIssueWizard wizard = new ConfigureIssueWizard(getUserAdminService(),
218 getTrackerService(), draftIssue);
219
220 WizardDialog dialog = new WizardDialog(addBtn.getShell(), wizard);
221 if (dialog.open() == Window.OK) {
222 targetSession = category.getSession().getRepository().login();
223 String issueBasePath = as.getBaseRelPath(TrackerTypes.TRACKER_ISSUE);
224 Node parent = targetSession.getNode("/" + issueBasePath);
225 Node issue = as.publishEntity(parent, TrackerTypes.TRACKER_ISSUE, draftIssue);
226 issue = as.saveEntity(issue, false);
227 project.getSession().refresh(true);
228 refreshViewer(filterTxt.getText());
229 }
230 } catch (RepositoryException e1) {
231 throw new TrackerException("Unable to create issue on " + project, e1);
232 } finally {
233 JcrUtils.logoutQuietly(tmpSession);
234 JcrUtils.logoutQuietly(targetSession);
235 }
236 }
237 });
238 }
239 }
240
241 private String getCategoryTitle() {
242 String name = ConnectJcrUtils.get(getNode(), Property.JCR_TITLE);
243 if (notEmpty(name)) {
244 Node project = TrackerUtils.getProjectFromChild(getNode());
245 String pname = ConnectJcrUtils.get(project, Property.JCR_TITLE);
246 name = name + (notEmpty(pname) ? " (" + pname + ")" : "");
247 }
248 return name;
249 }
250
251 @Override
252 public Object[] getElements(String extractId) {
253 String filter = "";
254 if (filterTxt != null && !filterTxt.isDisposed())
255 filter = filterTxt.getText();
256 NodeIterator nit = TrackerUtils.getIssues(project, filter, relevantPropName, officeID);
257 return JcrUtils.nodeIteratorToList(nit).toArray(new Node[0]);
258 }
259
260 @Override
261 public List<ConnectColumnDefinition> getColumnDefinition(String extractId) {
262 List<ConnectColumnDefinition> columns = new ArrayList<ConnectColumnDefinition>();
263 columns.add(new ConnectColumnDefinition("ID", new SimpleJcrNodeLabelProvider(TrackerNames.TRACKER_ID)));
264 columns.add(
265 new ConnectColumnDefinition("Status", new JcrRowLabelProvider(ActivitiesNames.ACTIVITIES_TASK_STATUS)));
266 columns.add(new ConnectColumnDefinition("Title", new JcrRowLabelProvider(Property.JCR_TITLE)));
267 columns.add(new ConnectColumnDefinition("Description", new JcrRowLabelProvider(Property.JCR_DESCRIPTION)));
268 columns.add(new ConnectColumnDefinition("Assigned To",
269 new AssignedToLP(getActivitiesService(), null, Property.JCR_DESCRIPTION)));
270 columns.add(
271 new ConnectColumnDefinition("Due Date", new JcrRowLabelProvider(ActivitiesNames.ACTIVITIES_DUE_DATE)));
272 columns.add(new ConnectColumnDefinition("Importance", new TrackerLps().new ImportanceLabelProvider()));
273 columns.add(new ConnectColumnDefinition("Priority", new TrackerLps().new PriorityLabelProvider()));
274 columns.add(new ConnectColumnDefinition("Components",
275 new SimpleJcrNodeLabelProvider(TrackerNames.TRACKER_COMPONENT_IDS)));
276
277
278
279 columns.add(new ConnectColumnDefinition("Wake-Up Date",
280 new JcrRowLabelProvider(ActivitiesNames.ACTIVITIES_WAKE_UP_DATE)));
281 columns.add(
282 new ConnectColumnDefinition("Close Date", new JcrRowLabelProvider(ConnectNames.CONNECT_CLOSE_DATE)));
283 columns.add(new ConnectColumnDefinition("Closed by",
284 new UserNameLP(getUserAdminService(), null, ConnectNames.CONNECT_CLOSED_BY)));
285 return columns;
286 }
287 }