[sitemap] Provide information about widget label source to clients (#3804)
* [sitemap] Provide information about widget label source to clients The label can be populated from a label specified on the respective sitemap widget, or (if no label was specified) from the label of the backing item. Allow clients to differentiate between both cases. Related to openhab/openhab-webui#2065 Signed-off-by: Danny Baumann <dannybaumann@web.de>pull/3597/head
parent
99bb994b36
commit
fb6f1923e8
|
@ -213,6 +213,7 @@ public class PageChangeListener implements EventSubscriber {
|
|||
event.sitemapName = sitemapName;
|
||||
event.pageId = pageId;
|
||||
event.label = itemUIRegistry.getLabel(widget);
|
||||
event.labelSource = itemUIRegistry.getLabelSource(widget).toString();
|
||||
event.widgetId = itemUIRegistry.getWidgetId(widget);
|
||||
event.icon = itemUIRegistry.getCategory(widget);
|
||||
event.reloadIcon = widget.getStaticIcon() == null;
|
||||
|
|
|
@ -536,6 +536,7 @@ public class SitemapResource
|
|||
bean.valuecolor = convertItemValueColor(itemUIRegistry.getValueColor(widget), itemState);
|
||||
bean.iconcolor = convertItemValueColor(itemUIRegistry.getIconColor(widget), itemState);
|
||||
bean.label = itemUIRegistry.getLabel(widget);
|
||||
bean.labelSource = itemUIRegistry.getLabelSource(widget).toString();
|
||||
bean.pattern = itemUIRegistry.getFormatPattern(widget);
|
||||
bean.unit = itemUIRegistry.getUnitForWidget(widget);
|
||||
bean.type = widget.eClass().getName();
|
||||
|
|
|
@ -20,12 +20,14 @@ import org.openhab.core.io.rest.core.item.EnrichedItemDTO;
|
|||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Laurent Garnier - New field iconcolor
|
||||
* @author Laurent Garnier - New field reloadIcon
|
||||
* @author Danny Baumann - New field labelSource
|
||||
*/
|
||||
public class SitemapWidgetEvent extends SitemapEvent {
|
||||
|
||||
public String widgetId;
|
||||
|
||||
public String label;
|
||||
public String labelSource;
|
||||
public String icon;
|
||||
public boolean reloadIcon;
|
||||
public String labelcolor;
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.openhab.core.io.rest.core.item.EnrichedItemDTO;
|
|||
* @author Laurent Garnier - New field iconcolor
|
||||
* @author Mark herwege - New fields pattern, unit
|
||||
* @author Laurent Garnier - New field columns
|
||||
* @author Danny Baumann - New field labelSource
|
||||
*/
|
||||
public class WidgetDTO {
|
||||
|
||||
|
@ -35,6 +36,7 @@ public class WidgetDTO {
|
|||
public boolean visibility;
|
||||
|
||||
public String label;
|
||||
public String labelSource;
|
||||
public String icon;
|
||||
/**
|
||||
* staticIcon is a boolean indicating if the widget state must be ignored when requesting the icon.
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.openhab.core.test.java.JavaTest;
|
|||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.ui.items.ItemUIRegistry;
|
||||
import org.openhab.core.ui.items.ItemUIRegistry.WidgetLabelSource;
|
||||
|
||||
/**
|
||||
* Test aspects of the {@link SitemapResource}.
|
||||
|
@ -74,6 +75,7 @@ public class SitemapResourceTest extends JavaTest {
|
|||
|
||||
private static final String HTTP_HEADER_X_ATMOSPHERE_TRANSPORT = "X-Atmosphere-Transport";
|
||||
private static final String ITEM_NAME = "itemName";
|
||||
private static final String ITEM_LABEL = "item label";
|
||||
private static final String SITEMAP_PATH = "/sitemaps";
|
||||
private static final String SITEMAP_MODEL_NAME = "sitemapModel";
|
||||
private static final String SITEMAP_NAME = "defaultSitemap";
|
||||
|
@ -84,7 +86,6 @@ public class SitemapResourceTest extends JavaTest {
|
|||
private static final String ICON_COLOR_ITEM_NAME = "iconColorItemName";
|
||||
private static final String ICON_ITEM_NAME = "iconItemName";
|
||||
private static final String WIDGET1_LABEL = "widget 1";
|
||||
private static final String WIDGET2_LABEL = "widget 2";
|
||||
private static final String WIDGET3_LABEL = "widget 3";
|
||||
private static final String WIDGET1_ID = "00";
|
||||
private static final String WIDGET2_ID = "01";
|
||||
|
@ -332,6 +333,7 @@ public class SitemapResourceTest extends JavaTest {
|
|||
|
||||
assertThat(pageDTO.widgets.get(0).widgetId, is(WIDGET1_ID));
|
||||
assertThat(pageDTO.widgets.get(0).label, is(WIDGET1_LABEL));
|
||||
assertThat(pageDTO.widgets.get(0).labelSource, is("SITEMAP_WIDGET"));
|
||||
assertThat(pageDTO.widgets.get(0).labelcolor, is("GREEN"));
|
||||
assertThat(pageDTO.widgets.get(0).valuecolor, is("BLUE"));
|
||||
assertThat(pageDTO.widgets.get(0).iconcolor, is("ORANGE"));
|
||||
|
@ -343,7 +345,8 @@ public class SitemapResourceTest extends JavaTest {
|
|||
assertThat(pageDTO.widgets.get(0).item.state, is("50"));
|
||||
|
||||
assertThat(pageDTO.widgets.get(1).widgetId, is(WIDGET2_ID));
|
||||
assertThat(pageDTO.widgets.get(1).label, is(WIDGET2_LABEL));
|
||||
assertThat(pageDTO.widgets.get(1).label, is(ITEM_LABEL));
|
||||
assertThat(pageDTO.widgets.get(1).labelSource, is("ITEM_LABEL"));
|
||||
assertThat(pageDTO.widgets.get(1).labelcolor, nullValue());
|
||||
assertThat(pageDTO.widgets.get(1).valuecolor, nullValue());
|
||||
assertThat(pageDTO.widgets.get(1).iconcolor, nullValue());
|
||||
|
@ -379,6 +382,7 @@ public class SitemapResourceTest extends JavaTest {
|
|||
when(itemUIRegistryMock.getWidgetId(widgets.get(0))).thenReturn(WIDGET1_ID);
|
||||
when(itemUIRegistryMock.getCategory(widgets.get(0))).thenReturn(WIDGET1_ICON);
|
||||
when(itemUIRegistryMock.getLabel(widgets.get(0))).thenReturn(WIDGET1_LABEL);
|
||||
when(itemUIRegistryMock.getLabelSource(widgets.get(0))).thenReturn(WidgetLabelSource.SITEMAP_WIDGET);
|
||||
when(itemUIRegistryMock.getVisiblity(widgets.get(0))).thenReturn(true);
|
||||
when(itemUIRegistryMock.getLabelColor(widgets.get(0))).thenReturn("GREEN");
|
||||
when(itemUIRegistryMock.getValueColor(widgets.get(0))).thenReturn("BLUE");
|
||||
|
@ -387,7 +391,8 @@ public class SitemapResourceTest extends JavaTest {
|
|||
|
||||
when(itemUIRegistryMock.getWidgetId(widgets.get(1))).thenReturn(WIDGET2_ID);
|
||||
when(itemUIRegistryMock.getCategory(widgets.get(1))).thenReturn(WIDGET2_ICON);
|
||||
when(itemUIRegistryMock.getLabel(widgets.get(1))).thenReturn(WIDGET2_LABEL);
|
||||
when(itemUIRegistryMock.getLabel(widgets.get(1))).thenReturn(ITEM_LABEL);
|
||||
when(itemUIRegistryMock.getLabelSource(widgets.get(1))).thenReturn(WidgetLabelSource.ITEM_LABEL);
|
||||
when(itemUIRegistryMock.getVisiblity(widgets.get(1))).thenReturn(true);
|
||||
when(itemUIRegistryMock.getLabelColor(widgets.get(1))).thenReturn(null);
|
||||
when(itemUIRegistryMock.getValueColor(widgets.get(1))).thenReturn(null);
|
||||
|
@ -397,6 +402,7 @@ public class SitemapResourceTest extends JavaTest {
|
|||
when(itemUIRegistryMock.getWidgetId(widgets.get(2))).thenReturn(WIDGET3_ID);
|
||||
when(itemUIRegistryMock.getCategory(widgets.get(2))).thenReturn(WIDGET3_ICON);
|
||||
when(itemUIRegistryMock.getLabel(widgets.get(2))).thenReturn(WIDGET3_LABEL);
|
||||
when(itemUIRegistryMock.getLabelSource(widgets.get(2))).thenReturn(WidgetLabelSource.SITEMAP_WIDGET);
|
||||
when(itemUIRegistryMock.getVisiblity(widgets.get(2))).thenReturn(true);
|
||||
when(itemUIRegistryMock.getLabelColor(widgets.get(2))).thenReturn(null);
|
||||
when(itemUIRegistryMock.getValueColor(widgets.get(2))).thenReturn(null);
|
||||
|
@ -484,7 +490,7 @@ public class SitemapResourceTest extends JavaTest {
|
|||
when(switchEClass.getName()).thenReturn("switch");
|
||||
when(switchEClass.getInstanceTypeName()).thenReturn("org.openhab.core.model.sitemap.Switch");
|
||||
when(w2.eClass()).thenReturn(switchEClass);
|
||||
when(w2.getLabel()).thenReturn(WIDGET2_LABEL);
|
||||
when(w2.getLabel()).thenReturn(null);
|
||||
when(w2.getItem()).thenReturn(ITEM_NAME);
|
||||
when(w2.getIcon()).thenReturn(WIDGET2_ICON);
|
||||
when(w2.getStaticIcon()).thenReturn(null);
|
||||
|
@ -528,6 +534,7 @@ public class SitemapResourceTest extends JavaTest {
|
|||
|
||||
public TestItem(String name) {
|
||||
super("Number", name);
|
||||
label = ITEM_LABEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -112,6 +112,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Mark Herwege - new method getFormatPattern(widget), clean pattern
|
||||
* @author Laurent Garnier - Support added for multiple AND conditions in labelcolor/valuecolor/visibility
|
||||
* @author Laurent Garnier - new icon parameter based on conditional rules
|
||||
* @author Danny Baumann - widget label source support
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, configurationPid = "org.openhab.sitemap", //
|
||||
|
@ -142,6 +143,16 @@ public class ItemUIRegistryImpl implements ItemUIRegistry {
|
|||
|
||||
private String groupMembersSorting = DEFAULT_SORTING;
|
||||
|
||||
private static class WidgetLabelWithSource {
|
||||
public final String label;
|
||||
public final WidgetLabelSource source;
|
||||
|
||||
public WidgetLabelWithSource(String l, WidgetLabelSource s) {
|
||||
label = l;
|
||||
source = s;
|
||||
}
|
||||
}
|
||||
|
||||
@Activate
|
||||
public ItemUIRegistryImpl(@Reference ItemRegistry itemRegistry) {
|
||||
this.itemRegistry = itemRegistry;
|
||||
|
@ -325,7 +336,7 @@ public class ItemUIRegistryImpl implements ItemUIRegistry {
|
|||
|
||||
@Override
|
||||
public @Nullable String getLabel(Widget w) {
|
||||
String label = getLabelFromWidget(w);
|
||||
String label = getLabelFromWidget(w).label;
|
||||
|
||||
String itemName = w.getItem();
|
||||
if (itemName == null || itemName.isBlank()) {
|
||||
|
@ -468,6 +479,11 @@ public class ItemUIRegistryImpl implements ItemUIRegistry {
|
|||
return transform(label, considerTransform, labelMappedOption);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WidgetLabelSource getLabelSource(Widget w) {
|
||||
return getLabelFromWidget(w).source;
|
||||
}
|
||||
|
||||
private QuantityType<?> convertStateToWidgetUnit(QuantityType<?> quantityState, Widget w) {
|
||||
Unit<?> widgetUnit = UnitUtils.parseUnit(getFormatPattern(w));
|
||||
if (widgetUnit != null && !widgetUnit.equals(quantityState.getUnit())) {
|
||||
|
@ -479,7 +495,7 @@ public class ItemUIRegistryImpl implements ItemUIRegistry {
|
|||
|
||||
@Override
|
||||
public @Nullable String getFormatPattern(Widget w) {
|
||||
String label = getLabelFromWidget(w);
|
||||
String label = getLabelFromWidget(w).label;
|
||||
String pattern = getFormatPattern(label);
|
||||
String itemName = w.getItem();
|
||||
try {
|
||||
|
@ -543,24 +559,30 @@ public class ItemUIRegistryImpl implements ItemUIRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
private String getLabelFromWidget(Widget w) {
|
||||
private WidgetLabelWithSource getLabelFromWidget(Widget w) {
|
||||
String label = null;
|
||||
WidgetLabelSource source = WidgetLabelSource.NONE;
|
||||
|
||||
if (w.getLabel() != null) {
|
||||
// if there is a label defined for the widget, use this
|
||||
label = w.getLabel();
|
||||
source = WidgetLabelSource.SITEMAP_WIDGET;
|
||||
} else {
|
||||
String itemName = w.getItem();
|
||||
if (itemName != null) {
|
||||
// check if any item ui provider provides a label for this item
|
||||
label = getLabel(itemName);
|
||||
// if there is no item ui provider saying anything, simply use the name as a label
|
||||
if (label == null) {
|
||||
if (label != null) {
|
||||
source = WidgetLabelSource.ITEM_LABEL;
|
||||
} else {
|
||||
label = itemName;
|
||||
source = WidgetLabelSource.ITEM_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
// use an empty string, if no label could be found
|
||||
return label != null ? label : "";
|
||||
return new WidgetLabelWithSource(label != null ? label : "", source);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,9 +36,20 @@ import org.openhab.core.types.State;
|
|||
* @author Laurent Garnier - new method getIconColor
|
||||
* @author Mark Herwege - new method getFormatPattern
|
||||
* @author Laurent Garnier - new method getConditionalIcon
|
||||
* @author Danny Baumann - widget label source support
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ItemUIRegistry extends ItemRegistry, ItemUIProvider {
|
||||
public enum WidgetLabelSource {
|
||||
/** Label is taken from widget definition in sitemap */
|
||||
SITEMAP_WIDGET,
|
||||
/** Label is taken from the widget's backing item definition */
|
||||
ITEM_LABEL,
|
||||
/** Label equals the widget's backing item name */
|
||||
ITEM_NAME,
|
||||
/** No suitable label source could be determined */
|
||||
NONE
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the label for a widget.
|
||||
|
@ -57,6 +68,14 @@ public interface ItemUIRegistry extends ItemRegistry, ItemUIProvider {
|
|||
@Nullable
|
||||
String getLabel(Widget w);
|
||||
|
||||
/**
|
||||
* Retrieves the label source for a widget.
|
||||
*
|
||||
* @param w the widget to retrieve the label source for
|
||||
* @return the source the widget label is taken from
|
||||
*/
|
||||
WidgetLabelSource getLabelSource(Widget w);
|
||||
|
||||
/**
|
||||
* Retrieves the category for a widget.
|
||||
*
|
||||
|
|
|
@ -84,6 +84,7 @@ import org.openhab.core.types.StateOption;
|
|||
import org.openhab.core.types.UnDefType;
|
||||
import org.openhab.core.types.util.UnitUtils;
|
||||
import org.openhab.core.ui.items.ItemUIProvider;
|
||||
import org.openhab.core.ui.items.ItemUIRegistry.WidgetLabelSource;
|
||||
|
||||
/**
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
|
@ -121,8 +122,8 @@ public class ItemUIRegistryImplTest {
|
|||
String testLabel = "This is a plain text";
|
||||
|
||||
when(widgetMock.getLabel()).thenReturn(testLabel);
|
||||
String label = uiRegistry.getLabel(widgetMock);
|
||||
assertEquals(testLabel, label);
|
||||
assertEquals(testLabel, uiRegistry.getLabel(widgetMock));
|
||||
assertEquals(WidgetLabelSource.SITEMAP_WIDGET, uiRegistry.getLabelSource(widgetMock));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -455,14 +456,14 @@ public class ItemUIRegistryImplTest {
|
|||
@Test
|
||||
public void getLabelWidgetWithoutLabelAndItem() {
|
||||
Widget w = mock(Widget.class);
|
||||
String label = uiRegistry.getLabel(w);
|
||||
assertEquals("", label);
|
||||
assertEquals("", uiRegistry.getLabel(w));
|
||||
assertEquals(WidgetLabelSource.NONE, uiRegistry.getLabelSource(w));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLabelWidgetWithoutLabel() {
|
||||
String label = uiRegistry.getLabel(widgetMock);
|
||||
assertEquals(ITEM_NAME, label);
|
||||
assertEquals(ITEM_NAME, uiRegistry.getLabel(widgetMock));
|
||||
assertEquals(WidgetLabelSource.ITEM_NAME, uiRegistry.getLabelSource(widgetMock));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -470,8 +471,8 @@ public class ItemUIRegistryImplTest {
|
|||
ItemUIProvider provider = mock(ItemUIProvider.class);
|
||||
uiRegistry.addItemUIProvider(provider);
|
||||
when(provider.getLabel(anyString())).thenReturn("ProviderLabel");
|
||||
String label = uiRegistry.getLabel(widgetMock);
|
||||
assertEquals("ProviderLabel", label);
|
||||
assertEquals("ProviderLabel", uiRegistry.getLabel(widgetMock));
|
||||
assertEquals(WidgetLabelSource.ITEM_LABEL, uiRegistry.getLabelSource(widgetMock));
|
||||
uiRegistry.removeItemUIProvider(provider);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue