Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UI defined sitemaps #3850

Merged
merged 4 commits into from
Oct 26, 2023
Merged

Fix UI defined sitemaps #3850

merged 4 commits into from
Oct 26, 2023

Conversation

mherwege
Copy link
Contributor

@mherwege mherwege commented Oct 18, 2023

Close #3846.

Recent enhancements to the sitemap syntax completely broke UI defined sitemaps.

This PR makes sitemap definitions in the UI work again, and is a quick fix.

However, most of the new syntax will still not work in the UI. This requires a larger refactoring both in core and webui.

EDIT:
With the second commit, AND conditions in visibility, color and icon rules are now allowed.
The JSON config format has not been changed (except for the addition of iconrules) to keep full backward compatibility and avoid major refactoring on the UI side. Logic has been created to correctly interpret the condition text strings.

This logic has one inherent problem. Condition strings will be split on ' AND ' strings in their composing parts. If any of the comparisons contains an ' AND ' string (in capitals, including the blanks before and after), provider will give the wrong result.

I will follow up with a UI PR to introduce icon rules and allow AND conditions.

@lolodomo Could you please have a look.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
@mherwege mherwege requested a review from a team as a code owner October 18, 2023 10:12
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Copy link
Contributor

@lolodomo lolodomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review

sitemap.setLabel(rootComponent.getConfig().get("label").toString());
Object label = rootComponent.getConfig().get("label");
if (label == null) {
return sitemap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why returning ? In this case, you will not set the children.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Label is a required parameter. It being null should not happen as it is verified in the UI when constructing the sitemap. But this avoids a null waring in Eclipse.

Copy link
Contributor

@lolodomo lolodomo Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my mistake. Previous code would have failed also if no label existed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking UI code, UI configured sitemaps always imposed a label. I will remove the requirement in the UI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking again, the UI heavily relies on the label being available. The name of the sitemap will always be something like 'uicomponents_...', so is not very good anyway. I propose to keep enforcing a label for UI provided sitemaps.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, makes sense to me.

return;
}
Object staticIcon = component.getConfig().get("staticIcon");
if (staticIcon != null && Boolean.valueOf(ConfigUtil.normalizeType(staticIcon).toString())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure to understand: staticIcon is not a boolean but a string containing the icon.

Copy link
Contributor Author

@mherwege mherwege Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not in the JSON db and JSON config. It is only in the grammar. The UI simply shows a switch turning staticIcon on or off. The state of that switch is what goes into the field. For the UI that is a lot nicer than showing 2 icon fields and having to move the value between them if switching to static. It could obviously be solved differently in the UI, but I see no reason to make it more complex there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Copy link
Contributor

@lolodomo lolodomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

End of review

String conditions = rule;
if (argument != null) {
conditions = rule.substring(0, rule.lastIndexOf(argument)).trim();
if (conditions.endsWith("=")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if there is one or several spaces between = and the "argument" ?

Copy link
Contributor Author

@mherwege mherwege Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full rule will be something like:

Item>=5 = red

The passed in argument would be red.
If there is an argument (!= null), it is split off and conditions should end with = (after trim). If there is a second = before, it should actually be part of the state string (5 in the example). So I think this is right.

Spaces after = are removed using trim.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not take attention that the previous line ended with a call to trim(). So, no problem, you can ignore this comment.

conditions = conditions.substring(0, conditions.length() - 1);
}
}
List<String> conditionsList = List.of(conditions.split(" AND "));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does UI systematically adds space around the AND ?

Copy link
Contributor Author

@mherwege mherwege Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does. And the chance of having an erronuous match is lower when adding the spaces in the separator string.

condition.setSign(matcher.group("sign"));
condition.setState(matcher.group("state"));
colorArray.eSet(SitemapPackage.COLOR_ARRAY__CONDITIONS, condition);
colorArray.eSet(SitemapPackage.COLOR_ARRAY__ARG, argument);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using colorArray.setArg is probably proper.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

iconDef.add(iconRule);
} else {
logger.warn("Syntax error in icon rule '{}' for widget {}", sourceIcon, component.getType());
iconRule.eSet(SitemapPackage.ICON_RULE__ARG, argument);
Copy link
Contributor

@lolodomo lolodomo Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using iconRule.setArg is probably proper.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Copy link
Contributor

@lolodomo lolodomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you a lot

@mherwege
Copy link
Contributor Author

@lolodomo Thanks for the quick review.

@lolodomo
Copy link
Contributor

@openhab/core-maintainers : a merge would be appreciated.

@kaikreuzer kaikreuzer added the bug An unexpected problem or unintended behavior of the Core label Oct 26, 2023
Copy link
Member

@kaikreuzer kaikreuzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mherwege!

@kaikreuzer kaikreuzer changed the title fix UI defined sitemaps Fix UI defined sitemaps Oct 26, 2023
@kaikreuzer kaikreuzer added this to the 4.1 milestone Oct 26, 2023
@kaikreuzer kaikreuzer merged commit d75d6df into openhab:main Oct 26, 2023
3 checks passed
@mherwege mherwege deleted the ui_sitemap branch October 27, 2023 08:39
florian-h05 pushed a commit to openhab/openhab-webui that referenced this pull request Oct 27, 2023
Fixes #2149: Syntax validation errors when command mappings contain special characters like [ and ].

Sitemaps now support icon rules and AND conditions in icon, color and visibility rules.
Mappings now also support an icon.

This PR introduces support to configure this in the sitemap editor.
It also contains a fix for staticIcon support.

Depends on openhab/openhab-core#3850.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An unexpected problem or unintended behavior of the Core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sitemaps defined in UI do not load anymore in 4.1M2
3 participants