Browse code

BM-15038, BM-15033, BM-15034, BM-15031 Fix: various fixes around the resource type template edition: - now can use resource type variables with accents in the template - now delete selected tab in resource type template edition - replace '-' by a red 'x' in resource type template edition - highlight fixed variables in resource type template edition - add resource type template preview in AC

Vincent Vignaud authored on 10/07/2019 12:21:53
Showing 8 changed files
... ...
@@ -73,7 +73,9 @@ public final class ResourceTemplateHandler {
73 73
 	private static final String PROPERTIES_SEPARATOR = "\n";
74 74
 	private static final String PROPERTIES_LOCALIZATION_SEPARATOR = "::";
75 75
 	private static final Logger LOGGER = LoggerFactory.getLogger(ResourceTemplateHandler.class);
76
-	private static final Pattern TEMPLATE_VARIABLES_PATTERN = Pattern.compile("\\$\\{([\\w\\s]+)\\}");
76
+	// note: '[\p{L}\p{N}_]' is the unicode alternative of '\w' (matches characters
77
+	// with accents)
78
+	private static final Pattern TEMPLATE_VARIABLES_PATTERN = Pattern.compile("\\$\\{([\\p{L}\\p{N}_\\s]+)\\}");
77 79
 	private static final String DEFAULT_LANGUAGE_TAG = "fr";
78 80
 
79 81
 	/**
... ...
@@ -80,3 +80,6 @@ defaultGroup=Default group
80 80
 externalUser=External user
81 81
 template=Template
82 82
 templateInfo=This HTML template will be added to the event description. The template may contain variables. These variables are defined above, in the "Custom Properties" section. The usage is: $&#123MyVariable&#125. Some variables are always available, such as $&#123ResourceName&#125 or $&#123Organizer&#125. When displaying the template, this is the organizer's language that is used.
83
+templateInfoVar=Always available variables:
84
+templateInfoVar1=$&#123ResourceName&#125 : the resource's name defined in Directory Browser (do not mistake with resource type Label)
85
+templateInfoVar2=$&#123Organizer&#125 : the name of the person who creates the event in the Agenda
... ...
@@ -81,3 +81,6 @@ defaultGroup=Groupe par d\u00e9faut
81 81
 externalUser=Utilisateur externe
82 82
 template=Patron
83 83
 templateInfo=Le patron, qui est au format HTML, sera ajout\u00e9 \u00e0 la description de l&#39\u00e9v\u00e8nement. Des variables peuvent \u00eatres utilis\u00e9es pour le rendre dynamique. Ces variables sont d\u00e9finies plus haut dans la partie "Propri\u00e9t\u00e9s personnalis\u00e9es". Le format pour int\u00e9grer une variable est: $&#123MaVariable&#125. Certaines variables sont toujours disponibles, c&#39est le cas de $&#123NomRessource&#125 et $&#123Organisateur&#125. La langue utilis\u00e9e sera celle de l&#39organisateur.
84
+templateInfoVar=Variables toujours disponibles:
85
+templateInfoVar1=$&#123NomRessource&#125 : le nom de la ressource d\u00e9finie dans Entr\u00e9e d&#39Annuaire (ne pas confondre avec le Libell\u00e9 du type de ressource)
86
+templateInfoVar2=$&#123Organisateur&#125 : le nom de la personne cr\u00e9ant l&#39\u00e9v\u00e8nement dans le Calendrier
... ...
@@ -92,6 +92,13 @@
92 92
 				</td>
93 93
 				<td class="form">
94 94
 					<p align="justify" style="width:32.7rem;"><i><ui:msg key="templateInfo">Template info</ui:msg></i></p>
95
+					<p>
96
+						<ui:msg key="templateInfoVar">Variables:</ui:msg>
97
+						<ul>
98
+							<li style="width:32.7rem;"><ui:msg key="templateInfoVar1">var1</ui:msg></li>
99
+							<li style="width:32.7rem;"><ui:msg key="templateInfoVar2">var2</ui:msg></li>
100
+						</ul>
101
+					</p>
95 102
 					<rt:TemplateContainer ui:field="templateContainer"></rt:TemplateContainer>
96 103
 				</td>
97 104
 			</tr>
... ...
@@ -25,31 +25,48 @@ import java.util.List;
25 25
 import java.util.Map;
26 26
 import java.util.Map.Entry;
27 27
 
28
+import com.google.gwt.dom.client.Style.FontWeight;
29
+import com.google.gwt.event.dom.client.ClickEvent;
30
+import com.google.gwt.event.dom.client.ClickHandler;
28 31
 import com.google.gwt.event.logical.shared.SelectionEvent;
29 32
 import com.google.gwt.event.logical.shared.SelectionHandler;
30 33
 import com.google.gwt.uibinder.client.UiConstructor;
34
+import com.google.gwt.user.client.ui.Button;
31 35
 import com.google.gwt.user.client.ui.Composite;
32 36
 import com.google.gwt.user.client.ui.Label;
33 37
 import com.google.gwt.user.client.ui.ListBox;
38
+import com.google.gwt.user.client.ui.RichTextArea;
34 39
 import com.google.gwt.user.client.ui.TabPanel;
35 40
 import com.google.gwt.user.client.ui.TextArea;
36 41
 import com.google.gwt.user.client.ui.VerticalPanel;
37 42
 
43
+import net.bluemind.ui.adminconsole.directory.resourcetype.l10n.ResourceTypeConstants;
44
+
38 45
 public class TemplateContainer extends Composite {
39 46
 	private static final String WIDTH = "32.7rem";
40 47
 	private static final String NEW_BUTTON = "New";
41
-	private static final String MINUS_BUTTON = "-";
42
-	private static final String PLUS_BUTTON = "+";
43 48
 	private static final List<String> SUPPORTED_LANGUAGES = Arrays
44 49
 			.asList(new String[] { "de", "en", "es", "fr", "hu", "it", "nl", "pl", "pt", "ru", "sk", "uk", "zh" });
45 50
 	private TabPanel tabPanel = new TabPanel();
46 51
 	private List<TemplatePanel> templatePanels = new ArrayList<>();
52
+	private Integer previouslySelected = -1;
53
+	private Label removeTabTitle;
54
+	private Label addTabTitle;
47 55
 
48 56
 	@UiConstructor
49 57
 	public TemplateContainer() {
50
-		// add listeners for the '+' and '-' buttons
58
+		// initialize 'x' and '-' tab titles
59
+		this.removeTabTitle = new Label("x");
60
+		this.removeTabTitle.getElement().getStyle().setFontWeight(FontWeight.BOLD);
61
+		this.removeTabTitle.getElement().getStyle().setColor("red");
62
+		this.addTabTitle = new Label("+");
63
+		this.addTabTitle.getElement().getStyle().setFontWeight(FontWeight.BOLD);
64
+		this.addTabTitle.getElement().getStyle().setColor("green");
65
+
66
+		// add listeners for the 'x' and '-' buttons
51 67
 		this.tabPanel.addSelectionHandler(new SelectionHandler<Integer>() {
52 68
 
69
+
53 70
 			@Override
54 71
 			public void onSelection(SelectionEvent<Integer> event) {
55 72
 				if (event.getSelectedItem() == tabPanel.getWidgetCount() - 1) {
... ...
@@ -61,18 +78,19 @@ public class TemplateContainer extends Composite {
61 78
 
62 79
 					if (tabPanel.getWidgetCount() == 2) {
63 80
 						// add 'delete' button
64
-						tabPanel.insert(new Label(), MINUS_BUTTON, 0);
81
+						tabPanel.insert(new Label(), removeTabTitle, 0);
65 82
 					}
66
-				} else if (tabPanel.getWidgetCount() > 2 && event.getSelectedItem() == 0) {
67
-					// delete last template
68
-					tabPanel.remove(tabPanel.getWidgetCount() - 2);
69
-					templatePanels.remove(templatePanels.size() - 1);
83
+				} else if (previouslySelected != 0 && tabPanel.getWidgetCount() > 2 && event.getSelectedItem() == 0) {
84
+					// delete previously selected template
85
+					tabPanel.remove(previouslySelected);
86
+					templatePanels.remove(previouslySelected - 1);
70 87
 
71 88
 					if (tabPanel.getWidgetCount() == 2) {
72 89
 						// remove 'delete' button
73 90
 						tabPanel.remove(0);
74 91
 					}
75 92
 				}
93
+				previouslySelected = event.getSelectedItem();
76 94
 			}
77 95
 		});
78 96
 
... ...
@@ -100,10 +118,10 @@ public class TemplateContainer extends Composite {
100 118
 			this.tabPanel.add(templatePanel, entry.getKey());
101 119
 			this.templatePanels.add(templatePanel);
102 120
 		}
103
-		this.tabPanel.add(new Label(), PLUS_BUTTON);
121
+		this.tabPanel.add(new Label(), this.addTabTitle);
104 122
 
105 123
 		if (this.tabPanel.getWidgetCount() > 1) {
106
-			this.tabPanel.insert(new Label(), MINUS_BUTTON, 0);
124
+			this.tabPanel.insert(new Label(), this.removeTabTitle, 0);
107 125
 			this.tabPanel.selectTab(1);
108 126
 		}
109 127
 	}
... ...
@@ -127,8 +145,12 @@ public class TemplateContainer extends Composite {
127 145
 	private class TemplatePanel extends VerticalPanel {
128 146
 		private ListBox languageBox;
129 147
 		private TextArea templateArea;
148
+		private RichTextArea previewArea;
149
+		private Button previewButton;
150
+		private boolean isPreview = false;
130 151
 
131 152
 		public TemplatePanel(final List<String> languages, final String selectedLanguage) {
153
+			// language combo-box
132 154
 			languageBox = new ListBox();
133 155
 			int index = 0;
134 156
 			for (final String language : languages) {
... ...
@@ -138,11 +160,46 @@ public class TemplateContainer extends Composite {
138 160
 				}
139 161
 				index++;
140 162
 			}
163
+
164
+			// template edition area
141 165
 			templateArea = new TextArea();
142 166
 			templateArea.setWidth("98%");
143 167
 			templateArea.getElement().getStyle().setProperty("marginTop", "2px");
168
+
169
+			// template preview area
170
+			previewArea = new RichTextArea();
171
+			previewArea.setWidth("98%");
172
+			previewArea.getElement().getStyle().setProperty("marginTop", "2px");
173
+			previewArea.setVisible(false);
174
+
175
+			// edition/preview toggle button
176
+			previewButton = new Button(ResourceTypeConstants.INST.templatePreviewButtonOn(), new ClickHandler() {
177
+
178
+				@Override
179
+				public void onClick(ClickEvent event) {
180
+					if (isPreview) {
181
+						// hide preview
182
+						previewArea.setVisible(false);
183
+						templateArea.setVisible(true);
184
+						previewButton.setText(ResourceTypeConstants.INST.templatePreviewButtonOn());
185
+					} else {
186
+						// show preview
187
+						previewArea.setWidth(String.valueOf(templateArea.getElement().getOffsetWidth() - 5) + "px");
188
+						previewArea.setHeight(String.valueOf(templateArea.getElement().getOffsetHeight() - 7) + "px");
189
+						previewArea.setHTML(templateArea.getText());
190
+						previewArea.setVisible(true);
191
+						templateArea.setVisible(false);
192
+						previewButton.setText(ResourceTypeConstants.INST.templatePreviewButtonOff());
193
+					}
194
+					// toggle
195
+					isPreview = !isPreview;
196
+				}
197
+			});
198
+
144 199
 			this.add(languageBox);
145 200
 			this.add(templateArea);
201
+			this.add(previewArea);
202
+			this.add(previewButton);
146 203
 		}
147 204
 
148 205
 		public TemplatePanel(final List<String> languages) {
... ...
@@ -77,4 +77,7 @@ public interface ResourceTypeConstants extends Constants {
77 77
 
78 78
 	String emptyLabel();
79 79
 
80
+	String templatePreviewButtonOn();
81
+
82
+	String templatePreviewButtonOff();
80 83
 }
... ...
@@ -15,4 +15,6 @@ customPropBoolean=Checkbox
15 15
 customPropInteger=Numeric
16 16
 customPropText=Text
17 17
 deleteTypeUsedByResources=The type can not be deleted because it is referenced by a resource
18
-emptyLabel=Label cannot be empty
19 18
\ No newline at end of file
19
+emptyLabel=Label cannot be empty
20
+templatePreviewButtonOn=Preview
21
+templatePreviewButtonOff=Template
... ...
@@ -15,4 +15,6 @@ customPropBoolean=Case à cocher
15 15
 customPropInteger=Numérique
16 16
 customPropText=Texte
17 17
 deleteTypeUsedByResources=Le type de ressource ne peut être supprimé car il est référencé par une ressource
18
-emptyLabel=Le libellé ne peut pas être vide
19 18
\ No newline at end of file
19
+emptyLabel=Le libellé ne peut pas être vide
20
+templatePreviewButtonOn=Pr\u00e9visualisation
21
+templatePreviewButtonOff=Patron