{"action":"created","issue":{"url":"https://api.github.com/repos/eclipse/smarthome/issues/5337","repository_url":"https://api.github.com/repos/eclipse/smarthome","labels_url":"https://api.github.com/repos/eclipse/smarthome/issues/5337/labels{/name}","comments_url":"https://api.github.com/repos/eclipse/smarthome/issues/5337/comments","events_url":"https://api.github.com/repos/eclipse/smarthome/issues/5337/events","html_url":"https://github.com/eclipse/smarthome/issues/5337","id":310696642,"number":5337,"title":"Proposal for a new Sitemap concept","user":{"login":"flaviocosta-net","id":35621323,"avatar_url":"https://avatars3.githubusercontent.com/u/35621323?v=4","gravatar_id":"","url":"https://api.github.com/users/flaviocosta-net","html_url":"https://github.com/flaviocosta-net","followers_url":"https://api.github.com/users/flaviocosta-net/followers","following_url":"https://api.github.com/users/flaviocosta-net/following{/other_user}","gists_url":"https://api.github.com/users/flaviocosta-net/gists{/gist_id}","starred_url":"https://api.github.com/users/flaviocosta-net/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flaviocosta-net/subscriptions","organizations_url":"https://api.github.com/users/flaviocosta-net/orgs","repos_url":"https://api.github.com/users/flaviocosta-net/repos","events_url":"https://api.github.com/users/flaviocosta-net/events{/privacy}","received_events_url":"https://api.github.com/users/flaviocosta-net/received_events","type":"User","site_admin":false},"labels":[{"id":294421378,"url":"https://api.github.com/repos/eclipse/smarthome/labels/REST/SSE","name":"REST/SSE","color":"fbca04","default":false},{"id":294421415,"url":"https://api.github.com/repos/eclipse/smarthome/labels/UI","name":"UI","color":"bfdadc","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":17,"created_at":"2018-04-03T05:13:36Z","updated_at":"2018-05-07T21:16:20Z","closed_at":null,"author_association":"NONE","body":"This issue is a transfer of the [respective ESH forum topic](https://www.eclipse.org/forums/index.php/m/1784414/) to GitHub.\r\n\r\nThe idea is to propose a new Sitemap concept that would help overcome various problems seen on the current sitemap implementation:\r\n\r\n- It is represented on Xtext DSL, which is an unnecessary dependency for many scenarios\r\n- It is not editable via REST\r\n- Components cannot be easily reused or extended for different UIs\r\n\r\n# New or Renewed Concepts\r\n\r\n- **Atom:** the smallest composition unit of a sitemap. An atom cannot contain any other components, although it does have certain attributes that describe how that atom can be rendered. Atoms are usually grouped to form more complex components that users can interact with (e.g. a widget containing an icon, a label and a switch control, as typically seen on today's sitemaps).\r\n- **Container:** an ordered set of components that provides hierarchical structure to the sitemap. Containers may be visually rendered (e.g. as a frame on the current page, or as a subpage) or be completely seamless. The latter case is useful as a container may be used to specify attributes that are propagated to its child components, without displaying any visual cue to the user.\r\n- **Component:** an Atom or Container. All components may have at least three attributes: _type_, _data_ and _style_. Type is a mandatory attribute that defines the semantic of the component for the UI. The other two attributes are optional, but most components should have at least one or the other. Containers have a mandatory attribute _layout_ that is used by the UI to decide how the components inside the container should be laid out.\r\n- **Sitemap:** the root container for all components arranged to provide certain system views. As the sitemap is a container, it contains the mandatory \"type\" property of every component and the properties \"data\" and \"layout\" that can be specified on any container.\r\n- **Current page:** all components being currently displayed to a user on the screen, or that can be displayed by horizontal or vertical scrolling the current view. The current page is typically changed by clicking on a visible and enabled atom associated with another page. If a current page is not specified, the UI should display the contents visible on the topmost container.\r\n\r\n# Sample Sitemap\r\n\r\nI'd like to start with the sample sitemap definition written in the current DSL that we find on the openHAB documentation:\r\n\r\n```\r\nsitemap demo label=\"My home automation\" {\r\n    Frame label=\"Date\" {\r\n        Text item=Date\r\n    }\r\n    Frame label=\"Demo\" {\r\n        Switch item=Lights icon=\"light\"\r\n        Text item=LR_Temperature label=\"Livingroom [%.1f °C]\"\r\n        Group item=Heating\r\n        Text item=LR_Multimedia_Summary label=\"Multimedia [%s]\" icon=\"video\" {\r\n            Selection item=LR_TV_Channel mappings=[0=\"off\", 1=\"DasErste\", 2=\"BBC One\", 3=\"Cartoon Network\"]\r\n            Slider item=LR_TV_Volume\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nThis is the expected visual rendering for this sitemap:\r\n\r\n![Demo sitemap](https://docs.openhab.org/configuration/images/sitemap_demo_fullexample.png)\r\n\r\nIn this proposal, this same sitemap could be specified with the following JSON:\r\n\r\n```\r\n{\r\n   smarthome: {\r\n      id: \"demo\", label: \"My home automation\",\r\n      components: {\r\n         frame: {\r\n            label: \"Date\",\r\n            components: {\r\n               text: {item: \"Date\"}\r\n            }\r\n         },\r\n         frame: {\r\n            label: \"Demo\",\r\n            components: {\r\n               switch: {item: \"Lights\", icon: \"light\"},\r\n               text: {item: \"LR_Temperature\", label: \"Livingroom\", state: \"%.1f °C\"},\r\n               group: {item: \"Heating\"},\r\n               text: {item: \"LR_Multimedia_Summary\", label: \"Multimedia\", state: \"%s\", icon: \"video\",\r\n                  components: {\r\n                     selection: {item: \"LR_TV_Channel\", mappings: {0: \"off\", 1: \"DasErste\", 2: \"BBC One\", 3: \"Cartoon Network\"}},\r\n                     slider: {item: \"LR_TV_Volume\"}\r\n                  }\r\n               }\r\n            }\r\n         }\r\n      }   \r\n   }\r\n}\r\n```\r\n\r\nExcept for the added \"components\" and \"state\" elements, this is almost a 1-to-1 mapping of the DSL to JSON. This approach can make it easier to understand the new concepts and how they can support backwards compatibility with the existing sitemap definition files. The system can easily parse a source file in the sitemap DSL and convert it to the JSON format, using the resulting structure for all further processing while still giving the user the convenience of the shorter DSL syntax.\r\n\r\nThe idea is to put most of the processing burden on the server side, so content and formatting are added on top of the input JSON (sitemap definition model) to generate a **rendering model** that is sent to the UI with the contents of the current page. The rendering model for the initial page of the above sitemap could look like this:\r\n\r\n```\r\n{\r\n   sitemap: {\r\n      type: \"smarthome\", data: {id: \"demo\", label: \"My home automation\", lang: \"en\"}, layout: \"list\",\r\n      components: {\r\n         container: {\r\n            type: \"frame\", data: \"Date\", style: \"font-weight:bold;font-size:large\", layout: \"listcontrol\",\r\n            components: {\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:text\", value: \"20160801000000\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Today\"}\r\n                  {type: \"text\", data: \"Monday, 01.Aug.2016\", style: \"font-weight:bold\"}\r\n               }\r\n            }\r\n         },\r\n         container: {\r\n            type: \"frame\", data: \"Demo\", style: \"font-weight:bold;font-size:large\", layout: \"listcontrol\",\r\n            components: {\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:light\", value: \"OFF\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Lights\"},\r\n                  {type: \"switch\", data: \"OFF\"}\r\n               },\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:temperature\", value: \"21.3\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Livingroom\"},\r\n                  {type: \"text\", data: \"21.3 °C\", style: \"font-weight:bold\"}\r\n               },\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:group\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Heating\"},\r\n                  {type: \"group\", data: \"item:Heating\"}\r\n               },\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:video\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Multimedia\"},\r\n                  {type: \"group\", data: \"components:4\"}\r\n               }\r\n            }\r\n         }\r\n      }   \r\n   }\r\n}\r\n```\r\n\r\n# Sitemap rendering\r\n\r\nIn order to convert a definition model into the respective rendering model, a SitemapRenderer service needs the following inputs:\r\n\r\n- A well-formed sitemap **definition model**, usually provided as a text file created manually or via some visual editor.\r\n- A sitemap **style definition**, specified as CSS.\r\n- A sitemap **prototype definition**, specified as JSON with JSONPath references.\r\n\r\nThe _style_ definition specifies how containers and atoms will be formatted. The approach used here is similar to the one adopted by JavaFX: while standard CSS syntax is used, it does not support some CSS layout properties such as float, position or overflow. The style actually provides a theme to format the sitemap components and it may be customized by the user. The disposition of the elements is determined by the \"layout\" attribute seen on the rendering model. This is different from the current sitemap solution, where colors, size, margins and fonts are decided by the client GUI. By following a style definition imposed on the server side, now the sitemap will have a more consistent look on the Basic UI, or on various mobile clients.\r\n\r\nThe _prototype_ definition determines how the elements in the definition model will be restructured to form the component _types_ in the rendering model. The prototypes can also be customized by the user, by editing the existing prototypes or creating new ones. This flexible abstraction layer allows component definitions reuse across the sitemap.\r\n\r\nThe following style file should generate output with formatting similar to the sitemap screenshot seen above:\r\n\r\n```\r\n/* Default theme */\r\n\r\ncontainer.frame {\r\n   font-weight: bold; font-size: large;\r\n}\r\n\r\natom {\r\n   font-weight: initial; font-size: initial;\r\n}\r\n\r\natom.text {\r\n   font-weight: bold;\r\n}\r\n\r\natom.icon {\r\n   width: 16px;\r\n   height: 16px;\r\n}\r\n```\r\n\r\nThe CSS class name (for instance, .frame seen on the first definition above) needs to match the component type. The SitemapRenderer on the server side adds these style definitions to each component where they apply, so the client doesn't need to bother with stylesheet inheritance - each component specifies on its \"style\" attribute any formatting options to be applied. If there is no style for a certain component, then the client UI can decide its default formatting. Usage of standard CSS syntax and semantics make it easier to implement web browser-based UIs, which already include built-in support for CSS.\r\n\r\nHere is an example of a prototype definition file that would work for the sitemap concepts used in the sample above:\r\n\r\n```\r\nsmarthome: {\r\n   sitemap: {\r\n      type: \"$\",\r\n      data: {id: \"$.id\", label: \"$.label\", lang: \"$.lang,system:language\"},\r\n      layout: \"list\",\r\n      components: { \"$.components..*\" }\r\n   }\r\n}\r\n\r\nframe: {\r\n   container: {\r\n      type: \"$\",\r\n      data: \"$.label\",\r\n      layout: \"listcontrol\",\r\n      components: { \"$.components..*\" }\r\n   }\r\n}\r\n\r\nseamless: {\r\n   container: {\r\n      type: \"$\",\r\n      layout: \"listcontrol\",\r\n      components: { \"$.components..*\" }\r\n   }\r\n}\r\n\r\nimplicit: {\r\n   container: {\r\n      type: \"$\",\r\n      layout: \"listcontrol\",\r\n      components: { \"$.components..*\" }\r\n   }\r\n}\r\n\r\ntext: {\r\n   atoms: {\r\n      {type: \"icon\", data: {id: \"$.icon,item:icon,classic:$\", value: \"item:state\"}},\r\n      {type: \"label\", data: \"$.label,item:label\"},\r\n      {\r\n            metadata: {\r\n                  if: \"$.[?(@.components)]\",\r\n                  then: {type: \"group\", data: \"components:seqno\"},\r\n                  else: {type: \"$\", data: \"item:state\"}\r\n            }\r\n      }\r\n   }\r\n}\r\n\r\nslider: {\r\n   atoms: {\r\n      {type: \"icon\", data: {id: \"$.icon,item:icon,classic:$\", value: \"item:state\"}},\r\n      {type: \"label\", data: \"$.label,item:label\"},\r\n      {type: \"$\", data: \"item:state\"}\r\n   }\r\n}\r\n\r\nswitch: {\r\n   atoms: {\r\n      {type: \"icon\", data: {id: \"$.icon,item:icon,classic:$\", value: \"item:state\"}},\r\n      {type: \"label\", data: \"$.label,item:label\"},\r\n      {type: \"$\", data: \"item:state\"}\r\n   }\r\n}\r\n\r\ngroup: {\r\n   atoms: {\r\n      {type: \"icon\", data: {id: \"$.icon,item:icon,classic:$\", value: \"item:state\"}},\r\n      {type: \"label\", data: \"$.label,item:label\"},\r\n      {type: \"$\", data: \"components:seqno,item:id\"}\r\n   }\r\n}\r\n\r\nselection: {\r\n   atoms: {\r\n      {type: \"icon\", data: {id: \"$.icon,item:icon,classic:$\", value: \"item:state\"}},\r\n      {type: \"label\", data: \"$.label,item:label\"},\r\n      {type: \"$\", data: \"$.mappings\"}\r\n   }\r\n}\r\n```\r\n\r\nLet's analyze each line of the \"sitemap\" prototype to understand how it works:\r\n\r\n```\r\nsmarthome: {\r\n```\r\nWhen the \"smarthome\" element is found in the sitemap definition model, the renderer expands this prototype.\r\n\r\n```\r\n   sitemap: {\r\n```\r\nThe name of the resulting element will be \"sitemap\".\r\n\r\n```\r\n      type: \"$\",\r\n```\r\nThe type property will be set to \"smarthome\". The \"$\" character is a JSONPath reference to the original element in the definition model, which happens to be \"smarthome\". We are not using an explicit reference to a JSONPATH transformation, but we may decide that it's better to have that either with a \"FUNCTION()\" syntax or as a \"namespace:\".\r\n\r\n```\r\n      data: {id: \"$.id\", label: \"$.label\", lang: \"$.lang,system:language\"},\r\n```\r\nThe data property will be set to a JSON, containing an id and a label copied from the original definition element, also using JSONPath syntax.  The lang property is passed to the client to indicate the language of the components in the container. It can be used, for instance, to change text alignment or even rearrange the atoms to better suit a language written from right-to-left, such as Hebrew or Arabic. Based on the specification in the prototype, the renderer will first try to read a lang attribute from the source element in the definition model. If absent, then it retrieves the language from the system settings (i.e. using the system: namespace).\r\n\r\n```\r\n      layout: \"list\",\r\n```\r\nThe layout property does not come form the definition model, it is fixed in this prototype. The value \"list\" is a reference to the Material Design concept of a list, so this is informing the UI that it should arrange the components of the container as a list:\r\n\r\n![Material Design list layout](https://www.eclipse.org/forums/index.php/fa/32442/0/)\r\n\r\n```\r\n      components: { \"$.components..*\" }\r\n```\r\nThe recursive descent operator (..) followed by the wildcard (*) tells the renderer to recursively retrieve all members contained under components (and expand the relevant prototypes as needed).\r\n\r\nThere are also some atoms under the \"text\" prototype using a special syntax that is worth explaining here:\r\n\r\n```\r\n      {type: \"icon\", data: {id: \"$.icon,item:icon,classic:$\", value: \"item:state\"}},\r\n```\r\nThe icon data will have an id and a value. The id will be the icon attribute in the definition model, or if it's missing then it's the icon attribute on the associated item (via the item: namespace), else it will be the icon \"text\" from the classic iconset (via the classic: namespace). The value attribute is always the state of the associated item.\r\n\r\n```\r\n         metadata: {\r\n\t\t    if: \"$.[?(@.components)]\",\r\n\t\t    then: {type: \"group\", data: \"components:seqno\"},\r\n\t\t    else: {type: \"$\", data: \"item:state\"}\r\n         }\r\n```\r\nOnce the prototype expander meets an element named \"metadata\", it knows that the elements immediately below it should not simply be sent to the output, put interpreted in a certain way to decide how the prototype is expanded. On the example above, if there is a member \"components\" on the definition model, the third (rightmost) atom will be rendered as a \"group\" atom; if absent, we render it as a regular \"text\" atom.\r\n\r\nWe can notice that the \"Multimedia\" element on our example sitemap does contain components, so it was rendered as a group with data \"components:4\" (meaning the fourth occurrence of \"components\" in the definition model). When the user clicks on the arrow on this component, the client makes a REST API call to the server which returns the sitemap view for that specific page, to display the contained components:\r\n\r\n```\r\n{\r\n   sitemap: {\r\n      type: \"smarthome\", data: {id: \"demo\", label: \"My home automation\", lang: \"en\"}, layout: \"list\",\r\n      components: {\r\n         container: {\r\n            type: \"implicit\", layout: \"listcontrol\",\r\n            components: {\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:screen\", value: \"0\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Channel\"},\r\n                  {type: \"selection\", data: {0: \"off\", 1: \"DasErste\", 2: \"BBC One\", 3: \"Cartoon Network\"}}\r\n               },\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:soundvolume\", value: \"15\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"TV Volume\"},\r\n                  {type: \"slider\", data: \"15\"}\r\n               }\r\n            }\r\n         }\r\n      }\r\n   }\r\n}\r\n```\r\n\r\nOn a very high level, the main work performed by the SitemapRenderer is:\r\n\r\n- Load the definition model and maintain a Java representation of it.\r\n- Load the default style and prototypes that match the sitemap type.\r\n- Convert the definition model into the rendering model by expanding the prototypes until the elements are resolved to the final component types. In this process, it should resolve any references based on the specified namespaces with a separate service that could be called something like NamespaceReferenceResolver.\r\n- Augment the resulting components with the applicable CSS styles.\r\n\r\nThe namespaces mentioned in this example are:\r\n\r\n- **smarthome:** any types that have no explicit namespace use the sitemap type as the default namespace (so type: \"frame\" internally resolves as type: \"smarthome:frame\").\r\n- **classic:** icon in the classic iconset - it is actually the only namespace actually sent to the client, since all other references are resolved on the server side. The resolver for this namespace knows that it should not be replaced with a value on the server side, but sent as-is to the client. Then the client can make a separate HTTP request to the server to obtain the image represented by the icon.\r\n- **system:** information about the system (e.g. default language or position).\r\n- **item:** attributes from the item associated with the component.\r\n- **components:** references to components in the sitemap. Components are a mandatory member of containers.\r\n\r\nNow let's demonstrate \"dynamic sitemap\" features that match the existing capabilities of the sitemap:\r\n\r\n```\r\n{\r\n   smarthome: {\r\n      id: \"dynamic\", label: \"My dynamic sitemap\",\r\n      components: {\r\n         selection: {item: \"LR_TV_Channel\", mappings: {0: \"off\", 1: \"DasErste\", 2: \"BBC One\", 3: \"Cartoon Network\"}},\r\n         slider: {item: \"LR_TV_Volume\",\r\n            visibility: {\r\n               or: {\r\n                  {value: \"item:LR_TV_Power.state\", eq: \"ON\"}\r\n                  {value: \"item:LR_TV_Channel.state\", noteq: \"0\"}\r\n               }\r\n            }\r\n            labelcolor: {\r\n               {gteq: \"50\", color: \"red\"}\r\n               {gteq: \"15\", color: \"orange\"}\r\n            }\r\n         }\r\n      }\r\n}\r\n```\r\n\r\nBelow we can see the resulting rendering model - you will notice that the visibility and labelcolor definitions are implemented by the renderer as specific CSS styles (e.g. \"display:none;color:orange\"). Since style processing cannot be implemented via prototype expansion, we would need the Java implementation for the NamespaceReferenceResolver to apply the required logic once it sees smarthome:visibility and visibility:labelcolor elements.\r\n\r\n```\r\n{\r\n   sitemap: {\r\n      type: \"smarthome\", data: {id: \"demo\", label: \"My home automation\", lang: \"en\"}, layout: \"list\",\r\n      components: {\r\n         container: {\r\n            type: \"implicit\", layout: \"listcontrol\",\r\n            components: {\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:screen\", value: \"0\"}, style: \"width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"Channel\"},\r\n                  {type: \"selection\", data: {0: \"off\", 1: \"DasErste\", 2: \"BBC One\", 3: \"Cartoon Network\"}}\r\n               },\r\n               atoms: {\r\n                  {type: \"icon\", data: {id: \"classic:soundvolume\", value: \"15\"}, style: \"display:none;width:16px;height:16px\"},\r\n                  {type: \"label\", data: \"TV Volume\", style: \"display:none;color:orange\"},\r\n                  {type: \"slider\", data: \"15\", style: \"display:none\"}\r\n               }\r\n            }\r\n         }\r\n      }\r\n   }\r\n}\r\n```\r\n\r\n# Extension and reuse\r\n\r\nOne virtue of the proposed solution is the fact that definitions can be added or changed declaratively.\r\n\r\nStyles can be adjusted by editing the style file. Alternative style files can also be provided, giving the user the option to select in the UI which theme to use. The API endpoint that lists the available sitemaps can also return the available styles or themes available for each sitemap, for instance:\r\n\r\n- **smarthome.style:** Default theme.\r\n- **smarthome-dark.style:** Theme with dark background and white text.\r\n- **smarthome-tablet.style:** Theme with bigger icons and text, optimized for big tablet screens.\r\n\r\nNew prototypes can be created, and they may also be based on existing prototypes. For instance, I may want to have all my smart bulbs to have the same icon and with intensity changed by predefined mapping options:\r\n\r\n```\r\nlightselection: {\r\n   selection: {\r\n      item: \"$.item\", icon: \"light\", mappings: {0: \"Off\", 50: \"Medium\", 100: \"Bright\"}}\r\n}\r\n```\r\n\r\nWhen the renderer identifies that \"lightselection\" is mapped to another prototype \"selection\", it takes the intermediate structure and apply the second prototype to it, which will then generate the atoms and stop the processing of this element. Now we can use our new prototype on the sitemap definition model:\r\n\r\n```\r\n   lightselection: {item: \"GF_Hall\"},\r\n   lightselection: {item: \"GF_Dining_Room\"}\r\n```\r\n\r\nThe rendering model will have fully expanded containers and/or atoms:\r\n\r\n```\r\n   components: {\r\n      atoms: {\r\n         {type: \"icon\", data: {id: \"classic:light\", value: \"0\"}, style: \"width:16px;height:16px\"},\r\n         {type: \"label\", data: \"Hall\"},\r\n         {type: \"selection\", data: {0: \"Off\", 50: \"Medium\", 100: \"Bright\"}}\r\n      },\r\n      atoms: {\r\n         {type: \"icon\", data: {id: \"classic:light\", value: \"50\"}, style: \"width:16px;height:16px\"},\r\n         {type: \"label\", data: \"Dining Room\"},\r\n         {type: \"selection\", data: {0: \"Off\", 50: \"Medium\", 100: \"Bright\"}}\r\n      }\r\n   }\r\n```\r\n\r\nAnother possible customization via the prototypes would be to convert the standard sitemap layout into a dashboard-like interface: instead of \"list\" layout on the sitemap and \"[listcontrol](https://material.io/guidelines/components/lists-controls.html)\" for the inner containers, the layouts \"cardcollection\" and \"[card](https://material.io/guidelines/components/cards.html)\" could be used respectively to display widgets in a very different way:\r\n\r\n![Card collection layout](https://www.eclipse.org/forums/index.php/fa/32443/0/)\r\n\r\nThe prototype expansion functionality is actually generic enough that it could even be used for other purposes not in the sitemap scope, such as allowing the creation of reusable Item definitions.\r\n\r\nOther possible new features that are not supported by the current sitemap could be:\r\n\r\n- Defining component visibility based on more than one condition using \"and\" (the current sitemap only supports \"or\").\r\n- Creating a vertical navigation sidebar consisting only on Icon atoms, or keeping a component always visible on top regardless of the page the user is in (e.g. an intrusion alert generated by a home security system).\r\n- Decoupling the icon from the item state - the presented prototypes links dynamic icons to simulate the current sitemap implementation, but they can be changed to determine the icon to be displayed based on the state of an item not displayed in the sitemap.\r\n- Disabling a component instead of hiding it.\r\n- Adding a \"Webcam pictures\" to a sitemap which, once clicked, would open a page with \"[gridlist](https://material.io/guidelines/components/grid-lists.html)\" layout to display all photos captured by a webcam in the last 24 hours.\r\n- Associate an URL with a component, so once the user clicks it a web page is displayed on a new window.\r\n- Create custom component types for specialized UIs (e.g. a date picker atom generated declaratively by a new prototype, it's the client that would have the burden to determine how this component should be displayed).\r\n\r\nThis proposal is still on a very abstract level, and some adjustments would likely be needed once certain issues became more obvious during an implementation attempt. Topics such as SSE and notifications are not addressed here yet. There are also some interesting features that I've left aside here, such as the possibility of using an indoor positioning system (e.g. [FIND](https://www.internalpositioning.com/)) to automatically set the current page that corresponds to the room the user currently is in.\r\n\r\n# Implementation\r\n\r\nThe core steps/modules to accomplish the proposal above could be:\r\n\r\n- Sitemap definition model parser: reads the definition model in JSON, and creates Java instances for Containers and Atom.\r\n- JSON Prototype parser and expander: reads prototypes and applies them to the definition model.\r\n- Sitemap CSS parser: reads the style file applying relevant rules such as CSS selectors. \r\n- Namespace reference resolver: resolves references on the server side.\r\n- Sitemap renderer: produces the rendering model using the 4 components above.\r\n- REST API/SSE and sample client implementation\r\n\r\nThere is also some additional work required for a complete solution:\r\n\r\n- Sitemap DSL to JSON converter: for DSL support for backwards compatibility on the server side.\r\n- Rendering model converter for legacy clients: for backwards compatibility on the client UI side.\r\n- VS Code support for new sitemap: syntax highlighting and autocomplete for definition model, and maybe for CSS and prototypes.\r\n- Sitemap editing REST API: create/update/remove atoms and containers."},"comment":{"url":"https://api.github.com/repos/eclipse/smarthome/issues/comments/387209221","html_url":"https://github.com/eclipse/smarthome/issues/5337#issuecomment-387209221","issue_url":"https://api.github.com/repos/eclipse/smarthome/issues/5337","id":387209221,"user":{"login":"flaviocosta-net","id":35621323,"avatar_url":"https://avatars3.githubusercontent.com/u/35621323?v=4","gravatar_id":"","url":"https://api.github.com/users/flaviocosta-net","html_url":"https://github.com/flaviocosta-net","followers_url":"https://api.github.com/users/flaviocosta-net/followers","following_url":"https://api.github.com/users/flaviocosta-net/following{/other_user}","gists_url":"https://api.github.com/users/flaviocosta-net/gists{/gist_id}","starred_url":"https://api.github.com/users/flaviocosta-net/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flaviocosta-net/subscriptions","organizations_url":"https://api.github.com/users/flaviocosta-net/orgs","repos_url":"https://api.github.com/users/flaviocosta-net/repos","events_url":"https://api.github.com/users/flaviocosta-net/events{/privacy}","received_events_url":"https://api.github.com/users/flaviocosta-net/received_events","type":"User","site_admin":false},"created_at":"2018-05-07T21:16:20Z","updated_at":"2018-05-07T21:16:20Z","author_association":"NONE","body":"@yveshanoulle, I will take that into consideration, although:\r\n\r\n1. On web-based clients (e.g. Basic UI), language settings rely on browser configuration. You may need different user profiles on the browser or on the OS if you want to serve content in different languages ([Firefox](https://developer.mozilla.org/en-US/Firefox/Multiple_profiles)), or use some plugin/extension to switch between these ([Google Chrome](https://chrome.google.com/webstore/detail/quick-language-switcher/pmjbhfmaphnpbehdanbjphdcniaelfie)). This is mostly a client problem, not something to be fixed on ESH.\r\n1. On general sites, you should have more problems with that because, as you say, content availability is different depending on the language. On sitemaps, the content will be the same, it's only a matter of providing the preferred translations, proper date/time formatting, etc.\r\n\r\nFor now, I have [created a fork](https://github.com/flaviocosta-net/smarthome) to start working on it and see where it goes."}}
{"actor":{"display_login":"flaviocosta-net"}}