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

Services filtering and other stuff #11241

Merged
merged 12 commits into from
Mar 1, 2019

Conversation

marusak
Copy link
Member

@marusak marusak commented Feb 24, 2019

This PR implements #10010 and #11237.
This PR is WIP and I am happy to improve further if design moves (especially in #11237).
I am opening as there are a lot of questions for design that rose as I was implementing this. (See screenshots at the end, there are the issues visible). Mostly asking @andreasn as he is reporter of both issues, but every single option would be great!

  1. How should the page look like when there are no matches for current filters? (I put there just something very fast, I don't like it that the page can be blank)
  2. Under Timers there is another button, should it be on far right or left? (Makes sense to have on left, but rather asking)
  3. On filtering columns can resize and they often do as for example you filter our some service with very long name. Is this okay, or not? If not, what can be done?
  4. Label Automatic Startup is rather long. On PC screen it is fine, problem is on small screens. If I put there wrapping then it wraps on PC screen (surely can be limited by screen size). Would for example Autostart be suitable?
  5. Label All services or some state for empty search (sth. like No services...) can be confusing as there are button Targets, Sockets, Timers, Paths and you would filter them by All services. And also it is filtering autostart options.
  6. I am confused a bit by Templates behavior (very likely I misunderstood templates) - but now they can be under all Enabled/Disabled/Static. Would it make sense to make it own "class"?

Screenshots:
emptystate
timers_automtic_startup
disbaled_services
overview_services

TODOs:

  • Use listing
  • Empty page
  • Wrapping of Automatic Startup on small screens
  • Change All Services by page
  • Filter placeholder
  • Column widths
  • Case insensitive search
  • Dropdown menu with pull-left
  • Design approval
  • Open issue for templates
  • Tests

@andreasn
Copy link
Contributor

  1. How should the page look like when there are no matches for current filters? (I put there just something very fast, I don't like it that the page can be blank)

Good question. I didn't consider this!
The Patternfly design guidelines on filters suggests something like this:
mockup

@andreasn
Copy link
Contributor

4\. Label `Automatic Startup` is rather long. On PC screen it is fine, problem is on small screens. If I put there wrapping then it wraps on PC screen (surely can be limited by screen size). Would for example `Autostart` be suitable?

I went for Automatic Startup since it matches what we show on the Services details page where it forms the sentence "Automatic Startup Enabled". It also feels like more natural language to me.
I think it's OK if the header label breaks into two lines on smaller screens.

@andreasn
Copy link
Contributor

Label All services or some state for empty search (sth. like No services...) can be confusing as there are button Targets, Sockets, Timers, Paths and you would filter them by All services. And also it is filtering autostart options.

Do you think it could work to relabel the dropdown "All Timers" etc. on the Timers page (and same for all the other pages). I realize this ends up being a bunch more work, but it would reflect the notion that the filter only applies to the current page.

@andreasn
Copy link
Contributor

I am confused a bit by Templates behavior (very likely I misunderstood templates) - but now they can be under all Enabled/Disabled/Static. Would it make sense to make it own "class"?

I honestly don't understand how systemd templates work. Maybe @martinpitt can shed some light.

@martinpitt
Copy link
Member

Yeah, maybe templates should have their own class. You can enable/disable/start/stop a template, which will create instances -- But you always have to give it an actual instantiation value, so this requires a dialog.

I. e. it makes no sense to start/stop getty@.service, as the template needs an actual terminal device. You can start/enable two instances like getty@tty1 and getty@ttyS0, and then stop/disable these.

Please see "man systemd.unit" for details about templates, but in short it's a way to build a family of similar services which differ only in a parameter (usually a device name or something such).

@marusak
Copy link
Member Author

marusak commented Feb 25, 2019

Thank you @andreasn for answers, I will incorporate them.
Also thank you @martinpitt for explaining templates. I understood them in the same way, still does not explain though why should getty@.service be now under enabled , httpd@.service under disabled and sshd@.service in static. Anyway, should it become 4th option in the dropdown menu? And also what should be written in column State for templates? (Template, nothing?) @andreasn

@martinpitt
Copy link
Member

still does not explain though why should getty@.service be now under enabled , httpd@.service under disabled and sshd@.service in static

Right, that does make no sense. Templates by themselves are nothing by themselves, we should only show the instances. These can be enabled or static.

@martinpitt
Copy link
Member

Sorry, I meant "show the instances in their respective categories". Templates themselves can/should of course still be shown, but in their separate category.

@andreasn
Copy link
Contributor

Does it currently only filter based on Id's? If so, it's probably best to mention that in the filter inputs placeholder text to give a hint of how the search will function.
What about Filter by id rather than Type to filter...

@andreasn
Copy link
Contributor

3\. On filtering columns can resize and they often do as for example you filter our some service with very long name. Is this okay, or not? If not, what can be done?

I played around with this now. It jumps around a little bit, but it's not too bad.
The only solution I can think of to fixing the jumping would be to give the columns a fixed width as a percentage of the page, so that the service-unit-description always gets, say 35% of the screen estate.

@marusak
Copy link
Member Author

marusak commented Feb 25, 2019

Sorry, I meant "show the instances in their respective categories". Templates themselves can/should of course still be shown, but in their separate category.

A lot of confusion between category, class, type... :)
Maybe would be great if @andreasn could draw design. It would make sense to have two tables in each category (Timers, Services...) one for real instances and one for templates. But that would be step back. Or make another category Templates and put it next to Paths? But Templates can be for timers or services (again two tables?). Or put it into autostart (makes less sense, but could be the least confusing?)

Does it currently only filter based on Id's?

Ids and description. But yes, design states also having there Filter by id or description... so I will go with it.

The only solution I can think of to fixing the jumping would be to give the columns a fixed width as a percentage of the page, so that the service-unit-description always gets, say 35% of the screen estate.

That would be a solution. Kinda hard to guess the widths though :) But surely I can play with it and see if there is something reasonable that can be used. (Mind that timers need custom widths as there are more columns)

@andreasn
Copy link
Contributor

@garrett pointed out that the text for the no-results-found state was a little too complex, so changing that to No Matching Results
mockup

@andreasn
Copy link
Contributor

On filtering columns can resize and they often do as for example you filter our some service with very long name. Is this okay, or not? If not, what can be done?

With the help of @garrett I figured out a way to make the columns not jump around so much.
Just drop this into pkg/systemd/services.css:

#services-list table {
    table-layout: fixed;
}

.service-unit-description {
    width: 40%;
}

It will of course still jump a little bit when the web browser adds and removes the scrollbar due to the page height, but that tolerable.

@andreasn
Copy link
Contributor

I just noticed that the text is centered here instead of left aligned, but I can't quite figure out why.
screenshot from 2019-02-25 17-56-06

@andreasn
Copy link
Contributor

It probably makes most sense to spin off any changes to Templates into it's own issue. I don't think it's really blocking this PR.

@andreasn
Copy link
Contributor

Ids and description. But yes, design states also having there Filter by id or description... so I will go with it.

Awesome. I just realized that the description seems case-sensitive. Is there a quick way to make it not case-sensitive? That would make searching for the description easier.

@andreasn
Copy link
Contributor

Seems the dropdown centers the text due to the btn class in Patternfly.
It is solved elsewhere with a pull-left class on the span that surrounds the text label. Not super-elegant, and @garrett is working on a new dropdown widget in #11155 that we can use instead, where that wouldn't be needed. Do we want to block on that PR landing first?

@marusak
Copy link
Member Author

marusak commented Feb 25, 2019

With the help of @garrett I figured out a way to make the columns not jump around so much.

Awesome! Thanks :)

It probably makes most sense to spin off any changes to Templates into it's own issue. I don't think it's really blocking this PR.

Agree. I will open issue after this one gets merged (or at least design stabled).

Is there a quick way to make it not case-sensitive?

Sure, adding into TODO.

Not super-elegant, and @garrett is working on a new dropdown widget in #11155 that we can use instead, where that wouldn't be needed. Do we want to block on that PR landing first?

It is developed in React. Services page is not in React yet.

@andreasn
Copy link
Contributor

It is developed in React. Services page is not in React yet.

Ah, ok. Let's use the pull-left class on the span then.

@garrett
Copy link
Member

garrett commented Feb 26, 2019

It will of course still jump a little bit when the web browser adds and removes the scrollbar due to the page height, but that tolerable.

It's possible to make the page not jump in that case, with overflow-y: scroll on the element that will scroll. (It's often, but not always, body.)

You could, for example, set overflow-y: scroll; on body when you're going to filter and remove it when you're not filtering. Or we could always set that attribute for the page, as it's usually a long table-based list of items.

@garrett
Copy link
Member

garrett commented Feb 26, 2019

Ah, ok. Let's use the pull-left class on the span then.

It would most likely be better to use display: flex (or display: grid, depending). I can help with this, if you'd like. 😉

BTW: The new dropdown widget is a drop-in replacement for React components, but copy/pasting the HTML (when it is done and merged) should be possible, as the CSS will be in the global CSS used for Cockpit.

Copy link
Member

@garrett garrett left a comment

Choose a reason for hiding this comment

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

Issues I've found in this PR

  1. There's an empty <div> around "create-timer". (See inline comment.)
  2. Hitting escape doesn't clear the filter box.
  3. There's no label for the filter with a for="Element_ID_goes_HERE" or aria-labelledby (as a fallback for elements without a label but with text somewhere) — or, in this case, as there's no element visibly saying "Filter", an aria-label.
  4. Filter isn't focused by default (this is debatable, but probably would be nice feature-wise — there's a possible accessibility issue by skipping the toggle buttons on the left, however).

This last one is debatable. I'm fine if we talk about this and if it comes later. Or we could discuss it and it would be implement The other items on the list should be fixed, however.

As noted above, the dropdown has some issues, but we're hoping to solve those elsewhere (and backport it to the non-React parts of Cockpit, like here).

Suitable for another PR

  1. Filter bar behaves oddly in small viewports. As the list is also problematic in small viewports, and this is an existing problem (although now excerbated with the filtering), I'm happy with it as another PR.

@@ -56,13 +59,27 @@
<button class="btn btn-default" role="tab" data-pattern="\.timer$" translatable="yes">Timers</button>
<button class="btn btn-default" role="tab" data-pattern="\.path$" translatable="yes">Paths</button>
</div>
<button id="create-timer" data-toggle="#timer-dialog" data-target="#timer-dialog" class="btn btn-primary pull-right" translate>Create Timer</button>
<div>
Copy link
Member

Choose a reason for hiding this comment

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

There's an empty <div> here. Usually this comes up with React, where <React.Fragment> should be used. I'm not sure why there's an empty div here though. If you need to group elements in a wrapper, try to use a semantic element (when it makes sense) and please at least give it a class and/or ID regardless to describe why this is here. (Something like "services-filter" might work.)

@andreasn
Copy link
Contributor

As noted above, the dropdown has some issues, but we're hoping to solve those elsewhere (and backport it to the non-React parts of Cockpit, like here).

What do you think is the timeline for the non-react-dropdown fixes? Is it blocking this PR on fixing that first, or should we do the pull-left hack?

@garrett
Copy link
Member

garrett commented Feb 26, 2019

What do you think is the timeline for the non-react-dropdown fixes?

  1. I need to include the CSS.
    • To do so, I need to include an SVG somehow. @larskarlitski and I are looking into this. @martinpitt might need to look into it too when he's back.
  2. Then it needs to be tweaked from the CSS side of things and tested everywhere.

Is it blocking this PR on fixing that first, or should we do the pull-left hack?

No, it's not blocking on the dropdown.

We should all avoid pull-left and using floats for layout (especially floats that change display order from visible content order). It's just bad code and a bad concept.

I don't think it has anything to do with the dropdown though? There are other ways to solve it?

@garrett
Copy link
Member

garrett commented Feb 26, 2019

Oh, I looked at it, and pull-left is fine in this usage, as:

  1. it doesn't change order of elements
  2. it is already contained (so it wouldn't escape the parent element)

Go for it. 👍

@marusak
Copy link
Member Author

marusak commented Feb 26, 2019

Thank you guys for all the comments and ideas!!
I went through all of them and fixed them. I pushed new version. I will comment on few things, what I do not comment on is done.

There's an empty <div> here. Usually this comes up with React, where <React.Fragment> should be used. I'm not sure why there's an empty div here though

It is to make it work with flex. I want some controls to be on left and some on right. So I split it into two divs, put there justify-content: space-between. I guess it can be done better. Anyway put there class to make it at least a bit more understandable.

Hitting escape doesn't clear the filter box.

I either don't understand what you are trying to do, or cannot reproduce. I can write text into filter box and then delete it just fine with escape - it is standard input with no magic at all.

Filter isn't focused by default (this is debatable, but probably would be nice feature-wise — there's a possible accessibility issue by skipping the toggle buttons on the left, however).

I don't have any strong options about this. Kinda it feels strange to focus search field (especially when there are other selectors left of them). But I am fine with implementing it if I am told so.

The new dropdown widget is a drop-in replacement for React components, but copy/pasting the HTML (when it is done and merged) should be possible, as the CSS will be in the global CSS used for Cockpit.

Sounds well, but I would not do it in this PR. It should be separate PR that will do it on all non-react place of Cockpit.

Anyway, anything discussed here should be fixed. I also went through and used listing instead of what we currently had. It works nicely with small screens (current the table breaks very weirdly on small screens) buuut there are two isses - one is in design and now sure if can be fixed (possible reason why this wont work and other solution needs to be found) other is just styling.

First issue - between two last columns there is that big gap - it is because second to last column floats left and last to right. Is this a problem? What style can be used to improve this?
newdesign

Second issue - On smaller screens columns can break layout - notice how last items second column jumps to left.
breaksmallscreen

@marusak
Copy link
Member Author

marusak commented Feb 26, 2019

A bit of thinking about the second issue - the breaking layout. Possibly grid, where each column would be some percentage could work. We would need a few classes as different tables may have different number of columns, but surely could be done. Ideas?

@garrett
Copy link
Member

garrett commented Feb 26, 2019

I either don't understand what you are trying to do, or cannot reproduce. I can write text into filter box and then delete it just fine with escape - it is standard input with no magic at all.

I simply typed into the box and hit the ESC key. Nothing happened. It should clear the entry (but keep focus).


The layout fixing should be in another PR, hence me opening up #11258 earlier today. It's too complex to block this PR, and it is an existing problem. It's probably tricky with lots of HTML/CSS changes too. (The HTML changes would most likely be attribute related, not massive restructuring.)

More details about making accessible tables are in #11260. But I guess that's more for react tables and we'd handle services similarly, but sadly as a one-off, as it isn't React based.

Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

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

Just one bug away from landing, from my POV. The page works really well now, great work!

<script id="service-empty-tmpl" type="x-template/mustache">
<div id="empty-search" class="blank-slate-pf blank-screen">
<h1 translate>
No Matching Results
Copy link
Member

Choose a reason for hiding this comment

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

The whitiespacing doesn't work, it gets copied literally to cockpit.pot:

msgid "        No Matching Results      "

Please write it as <h1>Bla</h1>.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ach, did not notice that. Thank you for pointing this out. Repushed

@@ -62,6 +62,19 @@
<div class="filter-group">
<button id="create-timer" data-toggle="#timer-dialog" data-target="#timer-dialog" class="btn btn-primary" translate>Create Timer</button>
<input type="search" id="services-text-filter" class="form-control" aria-label="Filter" placeholder="Filter by Id or description..." translate="placeholder"/>
<div class="dropdown" id="services-dropdown">
Copy link
Member

Choose a reason for hiding this comment

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

FTR, in the spirit of #11155 this should become an actual <select> soon. Right now the selector isn't keyboard navigatable at all. Fine for a follow-up of course.

Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

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

Thanks for the tabindex change, that should help!

@martinpitt martinpitt merged commit 1035cbe into cockpit-project:master Mar 1, 2019
<li class="active" aria-current=true tabindex="0" data-pattern="\.service$"><a translatable="yes">System Services</a></li>
<li tabindex="0" data-pattern="\.socket$"><a translatable="yes">Sockets</a></li>
<li tabindex="0" data-pattern="\.timer$"><a translatable="yes">Timers</a><li>
<li tabindex="0" data-pattern="\.path$"><a translatable="yes">Paths</a><li>
Copy link
Member

Choose a reason for hiding this comment

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

Ah, cool to see tabindex as the tabs need to be selected — but why is it in <li> instead of <a>? (Better yet would be to add href to the <a>, instead of using a tabindex, and use a URL fragment* to remember the state in the URL.)

* URL fragment (#this-thing-here), not to be confused with a Document Fragment, React.Fragment, CSS Fragmentation, or anything else called "fragment" in webdev. 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants