-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[AGNT-366][C2-20895] add room selector component (#384)
* [AGNT-366][C2-20895] add room selector component * [AGNT-366][C2-20895] consider value attribute as string * [AGNT-366][C2-20895] use declared variable * [AGNT-366][C2-20895] fix exception message
- Loading branch information
1 parent
bda0f94
commit fe22652
Showing
5 changed files
with
606 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
234 changes: 234 additions & 0 deletions
234
src/main/java/org/symphonyoss/symphony/messageml/elements/RoomSelector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
package org.symphonyoss.symphony.messageml.elements; | ||
|
||
import com.fasterxml.jackson.core.JsonParser; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.commonmark.node.Node; | ||
import org.symphonyoss.symphony.messageml.MessageMLContext; | ||
import org.symphonyoss.symphony.messageml.MessageMLParser; | ||
import org.symphonyoss.symphony.messageml.bi.BiContext; | ||
import org.symphonyoss.symphony.messageml.bi.BiFields; | ||
import org.symphonyoss.symphony.messageml.bi.BiItem; | ||
import org.symphonyoss.symphony.messageml.exceptions.InvalidInputException; | ||
import org.symphonyoss.symphony.messageml.exceptions.ProcessingException; | ||
import org.symphonyoss.symphony.messageml.markdown.nodes.form.PersonSelectorNode; | ||
import org.symphonyoss.symphony.messageml.markdown.nodes.form.RoomSelectorNode; | ||
import org.symphonyoss.symphony.messageml.util.XmlPrintStream; | ||
import org.w3c.dom.NamedNodeMap; | ||
import org.w3c.dom.NodeList; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* Class representing a room selector inside a Symphony Elements form. | ||
*/ | ||
public class RoomSelector extends FormElement implements LabelableElement, TooltipableElement { | ||
public static final String MESSAGEML_TAG = "room-selector"; | ||
|
||
private static final String PLACEHOLDER_ATTR = "placeholder"; | ||
private static final String REQUIRED_ATTR = "required"; | ||
private static final Set<String> VALID_VALUES_FOR_REQUIRED_ATTR = | ||
new HashSet<>(Arrays.asList("true", "false")); | ||
private static final String VALUE_ATTR = "value"; | ||
|
||
private static final String PRESENTATIONML_TAG = "div"; | ||
private static final String PRESENTATIONML_PLACEHOLDER_ATTR = "data-placeholder"; | ||
private static final String PRESENTATIONML_REQUIRED_ATTR = "data-required"; | ||
private static final String PRESENTATIONML_VALUE_ATTR = "data-value"; | ||
|
||
private final static String MARKDOWN = "Room Selector"; | ||
private static final String CLASS_ATTR = "class"; | ||
private static final String PRESENTATIONML_NAME_ATTR = "data-name"; | ||
|
||
private static final ObjectMapper MAPPER = new ObjectMapper(); | ||
|
||
public RoomSelector(Element parent, FormatEnum messageFormat) { | ||
super(parent, MESSAGEML_TAG, messageFormat); | ||
} | ||
|
||
static { | ||
MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); | ||
} | ||
|
||
@Override | ||
public void buildAll(MessageMLParser parser, org.w3c.dom.Element element) | ||
throws InvalidInputException, ProcessingException { | ||
switch (getFormat()) { | ||
case MESSAGEML: | ||
super.buildAll(parser, element); | ||
break; | ||
case PRESENTATIONML: | ||
buildElementFromDiv(parser, element); | ||
this.validate(); | ||
break; | ||
default: | ||
throw new InvalidInputException( | ||
String.format("Invalid message format for \"%s\" element", MESSAGEML_TAG)); | ||
} | ||
} | ||
|
||
@Override | ||
public void validate() throws InvalidInputException { | ||
super.validate(); | ||
|
||
if (getAttribute(NAME_ATTR) == null) { | ||
throw new InvalidInputException("The attribute \"name\" is required"); | ||
} | ||
|
||
if (getAttribute(REQUIRED_ATTR) != null) { | ||
assertAttributeValue(REQUIRED_ATTR, VALID_VALUES_FOR_REQUIRED_ATTR); | ||
} | ||
|
||
if (getAttribute(VALUE_ATTR) != null) { | ||
String attribute = getAttribute(VALUE_ATTR); | ||
try { | ||
MAPPER.readValue(attribute, | ||
MAPPER.getTypeFactory().constructCollectionType(List.class, String.class)); | ||
} catch (JsonProcessingException e) { | ||
throw new InvalidInputException( | ||
String.format( | ||
"Attribute \"%s\" contains an unsupported format, should be an array of room ids", | ||
VALUE_ATTR) | ||
); | ||
} | ||
} | ||
|
||
assertNoContent(); | ||
assertAttributeNotBlank(NAME_ATTR); | ||
} | ||
|
||
@Override | ||
public void asPresentationML(XmlPrintStream out, | ||
MessageMLContext context) { | ||
Map<String, String> presentationAttrs = buildRoomSelectorInputAttributes(); | ||
if (isSplittable()) { | ||
// open div + adding splittable elements | ||
presentationAttrs.put("id", splittableAsPresentationML(out, context)); | ||
// render element | ||
innerAsPresentationML(out, presentationAttrs); | ||
// close div | ||
out.closeElement(); | ||
} else { | ||
innerAsPresentationML(out, presentationAttrs); | ||
} | ||
} | ||
|
||
private void innerAsPresentationML(XmlPrintStream out, Map<String, String> presentationAttrs) { | ||
out.openElement(PRESENTATIONML_TAG, presentationAttrs); | ||
out.closeElement(); | ||
} | ||
|
||
@Override | ||
public Node asMarkdown() { | ||
return new RoomSelectorNode(getAttribute(PLACEHOLDER_ATTR), getAttribute(LABEL), | ||
getAttribute(TITLE)); | ||
} | ||
|
||
@Override | ||
protected void buildAttribute(MessageMLParser parser, | ||
org.w3c.dom.Node item) throws InvalidInputException { | ||
switch (item.getNodeName()) { | ||
case NAME_ATTR: | ||
case PLACEHOLDER_ATTR: | ||
case REQUIRED_ATTR: | ||
case LABEL: | ||
case TITLE: | ||
case VALUE_ATTR: | ||
setAttribute(item.getNodeName(), getStringAttribute(item)); | ||
break; | ||
case ID_ATTR: | ||
if (format != FormatEnum.PRESENTATIONML) { | ||
throwInvalidInputException(item); | ||
} | ||
fillAttributes(parser, item); | ||
break; | ||
default: | ||
throwInvalidInputException(item); | ||
} | ||
} | ||
|
||
private Map<String, String> buildRoomSelectorInputAttributes() { | ||
Map<String, String> presentationAttrs = new LinkedHashMap<>(); | ||
|
||
presentationAttrs.put(CLASS_ATTR, MESSAGEML_TAG); | ||
presentationAttrs.put(PRESENTATIONML_NAME_ATTR, getAttribute(NAME_ATTR)); | ||
|
||
if (getAttribute(PLACEHOLDER_ATTR) != null) { | ||
presentationAttrs.put(PRESENTATIONML_PLACEHOLDER_ATTR, getAttribute(PLACEHOLDER_ATTR)); | ||
} | ||
|
||
if (getAttribute(REQUIRED_ATTR) != null) { | ||
presentationAttrs.put(PRESENTATIONML_REQUIRED_ATTR, getAttribute(REQUIRED_ATTR)); | ||
} | ||
|
||
if (getAttribute(VALUE_ATTR) != null) { | ||
presentationAttrs.put(PRESENTATIONML_VALUE_ATTR, getAttribute(VALUE_ATTR)); | ||
} | ||
|
||
return presentationAttrs; | ||
} | ||
|
||
private void buildElementFromDiv(MessageMLParser parser, org.w3c.dom.Element element) | ||
throws InvalidInputException, ProcessingException { | ||
|
||
element.setAttribute(NAME_ATTR, element.getAttribute(PRESENTATIONML_NAME_ATTR)); | ||
element.removeAttribute(PRESENTATIONML_NAME_ATTR); | ||
|
||
if (element.hasAttribute(PRESENTATIONML_PLACEHOLDER_ATTR)) { | ||
element.setAttribute(PLACEHOLDER_ATTR, element.getAttribute(PRESENTATIONML_PLACEHOLDER_ATTR)); | ||
element.removeAttribute(PRESENTATIONML_PLACEHOLDER_ATTR); | ||
} | ||
|
||
if (element.hasAttribute(PRESENTATIONML_REQUIRED_ATTR)) { | ||
element.setAttribute(REQUIRED_ATTR, element.getAttribute(PRESENTATIONML_REQUIRED_ATTR)); | ||
element.removeAttribute(PRESENTATIONML_REQUIRED_ATTR); | ||
} | ||
|
||
if (element.hasAttribute(PRESENTATIONML_VALUE_ATTR)) { | ||
element.setAttribute(VALUE_ATTR, element.getAttribute(PRESENTATIONML_VALUE_ATTR)); | ||
element.removeAttribute(PRESENTATIONML_VALUE_ATTR); | ||
} | ||
|
||
NamedNodeMap attributes = element.getAttributes(); | ||
|
||
for (int i = 0; i < attributes.getLength(); i++) { | ||
buildAttribute(parser, attributes.item(i)); | ||
} | ||
|
||
NodeList children = element.getChildNodes(); | ||
|
||
for (int i = 0; i < children.getLength(); i++) { | ||
buildNode(parser, children.item(i)); | ||
} | ||
|
||
} | ||
|
||
@Override | ||
public String getPresentationMLTag() { | ||
return PRESENTATIONML_TAG; | ||
} | ||
|
||
@Override | ||
public String getElementId() { | ||
return MESSAGEML_TAG; | ||
} | ||
|
||
@Override | ||
public void updateBiContext(BiContext context) { | ||
Map<String, Object> attributesMapBi = new HashMap<>(); | ||
|
||
this.putOneIfPresent(attributesMapBi, BiFields.TITLE.getValue(), TITLE); | ||
this.putOneIfPresent(attributesMapBi, BiFields.LABEL.getValue(), LABEL); | ||
this.putOneIfPresent(attributesMapBi, BiFields.PLACEHOLDER.getValue(), PLACEHOLDER_ATTR); | ||
this.putOneIfPresent(attributesMapBi, BiFields.REQUIRED.getValue(), REQUIRED_ATTR); | ||
|
||
context.addItem(new BiItem(BiFields.ROOM_SELECTOR.getValue(), attributesMapBi)); | ||
} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/org/symphonyoss/symphony/messageml/markdown/nodes/form/RoomSelectorNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.symphonyoss.symphony.messageml.markdown.nodes.form; | ||
|
||
|
||
/** | ||
* Class that Represents a Markdown Node for the "RoomSelector" form element. | ||
* | ||
* @author Mohamed Rojbeni | ||
* @since 09/15/2023 | ||
*/ | ||
public class RoomSelectorNode extends FormElementNode implements PlaceholderLabelTooltipNode { | ||
private final static String MARKDOWN = "Room Selector"; | ||
|
||
private String placeholder; | ||
private String label; | ||
private String tooltip; | ||
|
||
public RoomSelectorNode(String placeholder, String label, String tooltip) { | ||
super(MARKDOWN, placeholder); | ||
this.placeholder = placeholder; | ||
this.label = label; | ||
this.tooltip = tooltip; | ||
} | ||
|
||
@Override | ||
public String getText() { | ||
return generateMarkdownPlaceholderLabelAndTooltip(placeholder, label, tooltip); | ||
} | ||
} |
Oops, something went wrong.