I’m trying to improve the homepage layout by hiding things family members are not interested in. For example the music and light controls in my office room are my priority (something I want right at the top) but for others it only clutters up the screen. Using visibleTo would work perfectly fine for this scenario if I were able to hide the cell together with the hidden widget. Unfortunately, the cell gets rendered empty and uses up the space.
Here is an example of an oh-masonry with two widgets, each visible to another user:
As expected, the widget is not shown but it’s cell still uses up the space.
Creating an oh-grid-cells or masonry for every user and hiding the whole block is working but this would make no sense as I would have to replicate nearly all widgets for every user.
The syntax seems good without the whitespace but component: “” just renders an empty cell like with oh-cell. Maybe I can use this to modify the style somehow but so far I found nothing that prevents the cell from getting rendered, i.e.:
Looks like the width does not come form the cell itself but from the elements containing the cell and I guess this is where we have little control over.
maybe creating a “dummy” widget of 0px of size (width)?
However, I am not familiar with oh-masonry.
Are there any more details available if you inspect the page? Is there an oh-cell rendered or an empty parent-container?
Seems it requires some additional code support to render the outer container only if there is a visible component inside. It works with oh-grid-col when using visibleTo inside the column configuration:
Most components, including the oh-grid-col accept a visible parameter which takes a boolean value. If the visible parameter is false, that component isn’t even rendered. So in this case you want to add:
visible: =(user.name=="marcus")
to the oh-grid-col to completely remove that column from the row.
Edit: Sorry, I see now that you are trying to use masonry instead of the row and col grids.
The default oh-masonry will always have the number of columns that matches the number of child components even if one of those components is not visible. You can fix this with a property of the oh-masonry
- component: oh-masonry
config:
flavor: css-grid
With that property an invisible component should not contribute a column to the masonry. Without seeing your whole page code, or more information about your particular use-case, I cannot say if there are any negative side-effects of using the flavor property.
This seems to work. Thanks a lot! Interestingly, only in Chrome does this display each widget on its own line. FF looks fine. I’ll test it some more with the app and a few more widgets.
These are some of the down-stream effects I mentioned. One of the impacts of changing the flavor property is that your masonry is then rendered with display: block which is just less responsive then something like display: flex. Now you can fix that too by adding a stylesheet parameter to the page config. Something like this:
But there’s a chance that also impacts some of the widgets in the masonry depending on how they are designed.
Ultimately, I think this issue is an XY problem. You don’t need to resort to component or column hiding shenanigans if you just make the component itself responsive. You only need a single cell; you just have to modify its contents based on the user which you can do in 3.4:
That’s a good idea but it won’t work in all cases. My goal is a clean home screen layout with things not relevant for a user removed. That’s why some widgets won’t be shown and this is where the whole issue begins with the masonry.
Maybe I can fix this using the stylesheet idea. It only needs an CSS selector which sets display:none on cells without children.
I don’t believe this will work. There shouldn’t really be any functional difference between setting a component’s visible property and setting display: none. They both wind up just not rendering that particular element; it’s only a matter of whether that element is not rendered while compiling the vue or parsing the html. But, your issue isn’t with the element itself, it’s with the oh-masonry.
When the oh-masonry uses the default settings it’s using the vue masonry library and you can see that this winds up wrapping each oh-masonry-item in an additional div container:
Those extra containers are the masonry columns (which means they are fixed-width based on the number of columns in the masonry) and they don’t go away even if there’s nothing rendered in the oh-masonry-item container. As far as the vue masonry library is concerned, that’s a feature not a bug.
When you set the flavor: css-grid then the oh-masonry just uses a regular div for its top-level element (with a different set of stylings) and those extra column containers are not created:
This is why, when you use the css-grid “flavor” of masonry you get the child elements stacked instead of inline, the top-level container doesn’t have display: flex set and you have to do it yourself using the page stylesheet. I’ve never looked comprehensively, so I don’t know what other style differences there are between the top-level containers in these two scenarios which is why I said there might be additional downstream effects of using the css-grid. There also might not.
If the combination of flavor: css-grid and setting the flex with the stylesheet works, then just go with that. That combination should probably work both with the visible and visisbleTo settings. While there may be other solutions, you’re not going to find a more direct solution to hiding elements while using the oh-masonry.