Skip to content

Commit a1942a2

Browse files
committed
Add configurable channel clone dialog
Signed-off-by: DESKTOP-9AKG4SL\ecomeau <ecomeau@caredx.com>
1 parent 776690e commit a1942a2

4 files changed

Lines changed: 422 additions & 24 deletions

File tree

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/*
2+
* Copyright (c) Mirth Corporation. All rights reserved.
3+
*
4+
* The software in this package is published under the terms of the MPL license.
5+
*/
6+
7+
package com.mirth.connect.client.ui;
8+
9+
import java.awt.Dimension;
10+
import java.awt.Window;
11+
import java.awt.event.ActionEvent;
12+
import java.awt.event.ActionListener;
13+
import java.util.ArrayList;
14+
import java.util.Collection;
15+
import java.util.HashSet;
16+
import java.util.List;
17+
import java.util.Set;
18+
19+
import javax.swing.DefaultComboBoxModel;
20+
import javax.swing.DefaultListModel;
21+
import javax.swing.JButton;
22+
import javax.swing.JCheckBox;
23+
import javax.swing.JComboBox;
24+
import javax.swing.JLabel;
25+
import javax.swing.JList;
26+
import javax.swing.JOptionPane;
27+
import javax.swing.JPanel;
28+
import javax.swing.JScrollPane;
29+
import javax.swing.JTextField;
30+
import javax.swing.ListSelectionModel;
31+
32+
import com.mirth.connect.model.Channel;
33+
import com.mirth.connect.model.ChannelDependency;
34+
import com.mirth.connect.model.ChannelGroup;
35+
import com.mirth.connect.model.ChannelTag;
36+
37+
import net.miginfocom.swing.MigLayout;
38+
39+
/** Dialog for selecting which channel associations should be copied during a clone. */
40+
public class ChannelCloneDialog extends MirthDialog {
41+
42+
public interface ChannelNameValidator {
43+
boolean isValid(String name);
44+
}
45+
46+
public static class Option {
47+
private final String id;
48+
private final String name;
49+
50+
public Option(String id, String name) {
51+
this.id = id;
52+
this.name = name;
53+
}
54+
55+
public String getId() {
56+
return id;
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return name == null ? id : name;
62+
}
63+
}
64+
65+
private final List<Option> allTags;
66+
private final List<Option> allDependencies;
67+
private final Set<String> sourceTagIds;
68+
private final String sourceId;
69+
private final ChannelNameValidator channelNameValidator;
70+
private boolean confirmed;
71+
72+
private JTextField nameField;
73+
private JCheckBox pruneCheckBox;
74+
private JCheckBox codeTemplateCheckBox;
75+
private JCheckBox resourcesCheckBox;
76+
private JComboBox<GroupOption> groupComboBox;
77+
private DefaultListModel<Option> tagModel;
78+
private DefaultListModel<Option> dependencyModel;
79+
private JList<Option> tagList;
80+
private JList<Option> dependencyList;
81+
82+
public ChannelCloneDialog(Window owner, Channel channel, Collection<ChannelTag> tags, Collection<ChannelDependency> dependencies,
83+
List<GroupOption> groups, String selectedGroupId, boolean hasCodeTemplates, boolean hasResources, ChannelNameValidator channelNameValidator) {
84+
super(owner, true);
85+
sourceId = channel.getId();
86+
this.channelNameValidator = channelNameValidator;
87+
allTags = new ArrayList<Option>();
88+
allDependencies = new ArrayList<Option>();
89+
sourceTagIds = new HashSet<String>();
90+
91+
for (ChannelTag tag : tags) {
92+
allTags.add(new Option(tag.getId(), tag.getName()));
93+
if (tag.getChannelIds().contains(sourceId)) {
94+
sourceTagIds.add(tag.getId());
95+
}
96+
}
97+
98+
for (ChannelDependency dependency : dependencies) {
99+
if (sourceId.equals(dependency.getDependentId())) {
100+
allDependencies.add(new Option(dependency.getDependencyId(), dependency.getDependencyId()));
101+
}
102+
}
103+
104+
initComponents(channel, groups, selectedGroupId, hasCodeTemplates, hasResources);
105+
setTitle("Clone channel \"" + channel.getName() + "\"");
106+
setPreferredSize(new Dimension(650, 540));
107+
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
108+
pack();
109+
setLocationRelativeTo(owner);
110+
setVisible(true);
111+
}
112+
113+
private void initComponents(Channel channel, List<GroupOption> groups, String selectedGroupId, boolean hasCodeTemplates, boolean hasResources) {
114+
nameField = new JTextField(channel.getName() + "1");
115+
pruneCheckBox = new JCheckBox("Include prune settings", true);
116+
codeTemplateCheckBox = new JCheckBox("Include code template libraries", hasCodeTemplates);
117+
resourcesCheckBox = new JCheckBox("Include resources", hasResources);
118+
groupComboBox = new JComboBox<GroupOption>(new DefaultComboBoxModel<GroupOption>(groups.toArray(new GroupOption[groups.size()])));
119+
for (int i = 0; i < groupComboBox.getItemCount(); i++) {
120+
if (selectedGroupId != null && selectedGroupId.equals(groupComboBox.getItemAt(i).getId())) {
121+
groupComboBox.setSelectedIndex(i);
122+
break;
123+
}
124+
}
125+
126+
tagModel = new DefaultListModel<Option>();
127+
for (Option option : allTags) {
128+
if (channelHasTag(channel, option.getId())) {
129+
tagModel.addElement(option);
130+
}
131+
}
132+
tagList = createList(tagModel);
133+
134+
dependencyModel = new DefaultListModel<Option>();
135+
for (Option option : allDependencies) {
136+
dependencyModel.addElement(option);
137+
}
138+
dependencyList = createList(dependencyModel);
139+
140+
JPanel content = new JPanel(new MigLayout("insets 12, fill, wrap 2", "[][grow]", "[]10[]10[]10[grow]10[grow]10[]"));
141+
content.add(new JLabel("New Name:"));
142+
content.add(nameField, "growx");
143+
content.add(pruneCheckBox, "span 2");
144+
content.add(new JLabel("Group:"));
145+
content.add(groupComboBox, "growx");
146+
content.add(new JLabel("Tags:"));
147+
content.add(createListPanel(tagList, tagModel, allTags), "grow, push");
148+
content.add(new JLabel("Channel Dependencies:"));
149+
content.add(createListPanel(dependencyList, dependencyModel, allDependencies), "grow, push");
150+
content.add(codeTemplateCheckBox, "span 2");
151+
content.add(resourcesCheckBox, "span 2");
152+
153+
JButton cancelButton = new JButton("Cancel");
154+
cancelButton.addActionListener(e -> dispose());
155+
JButton okButton = new JButton("OK");
156+
okButton.addActionListener(new ActionListener() {
157+
@Override
158+
public void actionPerformed(ActionEvent e) {
159+
String name = nameField.getText().trim();
160+
if (name.isEmpty()) {
161+
JOptionPane.showMessageDialog(ChannelCloneDialog.this, "A channel name is required.", "Invalid Name", JOptionPane.WARNING_MESSAGE);
162+
return;
163+
}
164+
if (channelNameValidator != null && !channelNameValidator.isValid(name)) {
165+
return;
166+
}
167+
confirmed = true;
168+
dispose();
169+
}
170+
});
171+
172+
JPanel buttons = new JPanel(new MigLayout("insets 0, right"));
173+
buttons.add(cancelButton, "w 80!");
174+
buttons.add(okButton, "w 80!");
175+
getContentPane().setLayout(new MigLayout("insets 0, fill, wrap"));
176+
getContentPane().add(content, "grow, push");
177+
getContentPane().add(buttons, "growx");
178+
}
179+
180+
private JList<Option> createList(DefaultListModel<Option> model) {
181+
JList<Option> list = new JList<Option>(model);
182+
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
183+
return list;
184+
}
185+
186+
private JPanel createListPanel(JList<Option> list, DefaultListModel<Option> model, List<Option> allOptions) {
187+
JPanel panel = new JPanel(new MigLayout("fill, insets 0", "[grow][]", "[grow][]"));
188+
panel.add(new JScrollPane(list), "grow, push");
189+
JButton addButton = new JButton("Add");
190+
JButton removeButton = new JButton("Remove");
191+
addButton.addActionListener(e -> {
192+
List<Option> available = new ArrayList<Option>();
193+
Set<String> selected = new HashSet<String>();
194+
for (int i = 0; i < model.size(); i++) {
195+
selected.add(model.get(i).getId());
196+
}
197+
for (Option option : allOptions) {
198+
if (!selected.contains(option.getId())) {
199+
available.add(option);
200+
}
201+
}
202+
if (!available.isEmpty()) {
203+
Option option = (Option) JOptionPane.showInputDialog(this, "Select an item to add:", "Add", JOptionPane.PLAIN_MESSAGE, null,
204+
available.toArray(), available.get(0));
205+
if (option != null) {
206+
model.addElement(option);
207+
}
208+
}
209+
});
210+
removeButton.addActionListener(e -> {
211+
for (Option option : list.getSelectedValuesList()) {
212+
model.removeElement(option);
213+
}
214+
});
215+
JPanel controls = new JPanel(new MigLayout("insets 0, wrap"));
216+
controls.add(addButton, "w 80!");
217+
controls.add(removeButton, "w 80!");
218+
panel.add(controls, "top");
219+
return panel;
220+
}
221+
222+
private boolean channelHasTag(Channel channel, String tagId) {
223+
return sourceTagIds.contains(tagId);
224+
}
225+
226+
public boolean isConfirmed() {
227+
return confirmed;
228+
}
229+
230+
public String getChannelName() {
231+
return nameField.getText().trim();
232+
}
233+
234+
public boolean isIncludePruneSettings() {
235+
return pruneCheckBox.isSelected();
236+
}
237+
238+
public boolean isIncludeCodeTemplateLibraries() {
239+
return codeTemplateCheckBox.isSelected();
240+
}
241+
242+
public boolean isIncludeResources() {
243+
return resourcesCheckBox.isSelected();
244+
}
245+
246+
public String getGroupId() {
247+
GroupOption group = (GroupOption) groupComboBox.getSelectedItem();
248+
return group == null ? ChannelGroup.DEFAULT_ID : group.getId();
249+
}
250+
251+
public Set<String> getTagIds() {
252+
return getIds(tagModel);
253+
}
254+
255+
public Set<String> getDependencyIds() {
256+
return getIds(dependencyModel);
257+
}
258+
259+
private Set<String> getIds(DefaultListModel<Option> model) {
260+
Set<String> ids = new HashSet<String>();
261+
for (int i = 0; i < model.size(); i++) {
262+
ids.add(model.get(i).getId());
263+
}
264+
return ids;
265+
}
266+
267+
public static class GroupOption {
268+
private final String id;
269+
private final String name;
270+
271+
public GroupOption(String id, String name) {
272+
this.id = id;
273+
this.name = name;
274+
}
275+
276+
public String getId() {
277+
return id;
278+
}
279+
280+
@Override
281+
public String toString() {
282+
return name;
283+
}
284+
}
285+
}

0 commit comments

Comments
 (0)