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

feat(console): Add icon that sorting state #301

Merged
merged 10 commits into from
Mar 8, 2022

Conversation

nrskt
Copy link
Contributor

@nrskt nrskt commented Mar 4, 2022

Add or icon that represents the sorting state.

Screenshot_20220304_183030 Screenshot_20220304_183046

Relates to #300

Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

This is definitely a good idea, thanks for working on it!

The main thing I think we need to change before this is ready to merge is supporting ASCII-only mode, which I left a comment about. Besides that, this seems more or less correct --- I think it might be worth changing how we add extra length to column titles, so that we don't change column width as often, but that's up to you.

Comment on lines 166 to 168
"▵"
} else {
"▿"
Copy link
Member

Choose a reason for hiding this comment

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

The console supports running in an ASCII-only mode, so we need to be able to switch between these Unicode characters and ASCII-only text. For other Unicode characters we use as icons, we use the if_utf8 method on the Styles type to switch between Unicode and ASCII variants:

pub fn if_utf8<'a>(&self, utf8: &'a str, ascii: &'a str) -> &'a str {
if self.utf8 {
utf8
} else {
ascii
}
}

Here, I think we should do something like this:

Suggested change
"▵"
} else {
"▿"
styles.if_utf8("▵", "+")
} else {
styles.if_utf8("▿", "-")

using + for ascending and - for descending in ASCII-only mode. alternatively, we could use something like (asc.)/(desc.) for ascending/descending, if we don't think a single character is descriptive enough...

note that if we use multiple characters in the ASCII-only mode, we'll also have to add that much additional length to the column width, rather than just adding a single character in every case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the clear explanation. I will fix it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I fixed c29d6c9.

Comment on lines 76 to 85
match table_list_state.sort_by {
SortBy::Warns => warn_width.update_len(warn_width.len() + 1),
SortBy::Tid => id_width.update_len(id_width.len() + 1),
SortBy::State => state_len += 1,
SortBy::Name => name_width.update_len(name_width.len() + 1),
SortBy::Polls => polls_width.update_len(polls_width.len() + 1),
SortBy::Target => target_width.update_len(target_width.len() + 1),
SortBy::Location => location_width.update_len(location_width.len() + 1),
SortBy::Total | SortBy::Busy | SortBy::Idle => (),
};
Copy link
Member

Choose a reason for hiding this comment

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

one note about this approach is that it means that changing the sorted column has the potential to make that column one character wider than it was previously, if none of the text in the column was longer than the header. i feel like this has the potential to look a little bit jarring if selecting a new column to sort by makes the columns shift around. it might honestly be better to just always add an additional character of width to every column?

but, i'm definitely willing to be convinced otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i feel like this has the potential to look a little bit jarring if selecting a new column to sort by makes the columns shift around. it might honestly be better to just always add an additional character of width to every column?

I agree. I feel it would be more clear to add an additional character of width to every column. However, I am confused because there are a few places in the current implementation where the width is adjusted. I would like to fix it at another opportunity and understand the whole implementation a little bit.

Copy link
Member

Choose a reason for hiding this comment

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

We can always address that later!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I realize an idea.

  1. Add const WIDTHS param to TableList trait definition.
  2. Set the widths on the implementation.
pub(crate) trait TableList<const N: usize> {
    type Row;
    type Sort: SortBy + TryFrom<usize>;
    type Context;

    const HEADER: &'static [&'static str; N];
    const WIDTHS: &'static [usize; N];

    fn render<B: tui::backend::Backend>(
        state: &mut TableListState<Self, N>,
        styles: &view::Styles,
        frame: &mut tui::terminal::Frame<B>,
        area: layout::Rect,
        state: &mut state::State,
        cx: Self::Context,
    ) where
        Self: Sized;
}
impl TableList<11> for TasksTable {
    type Row = Task;
    type Sort = SortBy;
    type Context = ();

    const HEADER: &'static [&'static str; 11] = &[
        "Warn", "ID", "State", "Name", "Total", "Busy", "Idle", "Polls", "Target", "Location",
        "Fields",
    ];

    const WIDTHS: &'static [usize; 11] = &[
        Self::HEADER[0].len() + 1,
        Self::HEADER[1].len() + 1,
        Self::HEADER[2].len() + 1,
        Self::HEADER[3].len() + 1,
        Self::HEADER[4].len() + 1,
        Self::HEADER[5].len() + 1,
        Self::HEADER[6].len() + 1,
        Self::HEADER[7].len() + 1,
        Self::HEADER[8].len() + 1,
        Self::HEADER[9].len() + 1,
        Self::HEADER[10].len() + 1,
    ];

What do you think it?
(I worry about implement WIDTHS param is complex and boring)

@hawkw hawkw changed the title feat(subscriber): Add icon that sorting state feat(console): Add icon that sorting state Mar 4, 2022
Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

oh, I just realized something else: we should make the same change for the resource list view (https://github.com/tokio-rs/console/blob/main/tokio-console/src/view/resources.rs) and the async ops list view (https://github.com/tokio-rs/console/blob/main/tokio-console/src/view/async_ops.rs). that should be pretty straightforward, but it would be nice to add this to every table view as part of this change.

since we'll be using the same icons for ascending and descending sorts on all three views, we may want to just add methods to the Styles type for returning the ascending and descending icons based on whether or not Unicode is enabled. There are existing methods on Styles for other commonly-used symbols, like the warning symbol:

pub fn warning_narrow(&self) -> Span<'static> {
Span::styled(
self.if_utf8("\u{26A0} ", "! "),
self.fg(Color::LightYellow).add_modifier(Modifier::BOLD),
)
}

Comment on lines 76 to 85
match table_list_state.sort_by {
SortBy::Warns => warn_width.update_len(warn_width.len() + 1),
SortBy::Tid => id_width.update_len(id_width.len() + 1),
SortBy::State => state_len += 1,
SortBy::Name => name_width.update_len(name_width.len() + 1),
SortBy::Polls => polls_width.update_len(polls_width.len() + 1),
SortBy::Target => target_width.update_len(target_width.len() + 1),
SortBy::Location => location_width.update_len(location_width.len() + 1),
SortBy::Total | SortBy::Busy | SortBy::Idle => (),
};
Copy link
Member

Choose a reason for hiding this comment

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

We can always address that later!

@nrskt
Copy link
Contributor Author

nrskt commented Mar 4, 2022

cargo clippy raise a few warnings of unnecessary use of to_owned. I have tried to fix it but caused compile error...
Should I fix it? If so, how to fix it?

@hawkw
Copy link
Member

hawkw commented Mar 4, 2022

cargo clippy raise a few warnings of unnecessary use of to_owned. I have tried to fix it but caused compile error... Should I fix it? If so, how to fix it?

This is fixed on the main branch, by PR #305. I'll update this branch from main and we should get a passing CI build now.

@nrskt
Copy link
Contributor Author

nrskt commented Mar 5, 2022

@hawkw

Screenshot_20220305_185330
Screenshot_20220305_185359
Screenshot_20220305_185415

Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

This looks good to me, thanks!

I had some suggestions, but you can feel free to take them or leave them. Let me know what you think!

Comment on lines +140 to +145
let value = format!("{}{}", value, self.if_utf8("▵", "+"));
self.selected(&value)
}

pub fn descending(&self, value: &str) -> Span<'static> {
let value = format!("{}{}", value, self.if_utf8("▿", "-"));
Copy link
Member

Choose a reason for hiding this comment

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

i think it might look a little bit nicer if we added a space after the symbol in the case where it's a plus or minus sign, but not a blocker.

Comment on lines +74 to +82
let viz_len: u16 = Self::WIDTHS[6] as u16;

let mut id_width = view::Width::new(Self::HEADER[0].len() as u16);
let mut parent_width = view::Width::new(Self::HEADER[1].len() as u16);
let mut id_width = view::Width::new(Self::WIDTHS[0] as u16);
let mut parent_width = view::Width::new(Self::WIDTHS[1] as u16);

let mut kind_width = view::Width::new(Self::HEADER[2].len() as u16);
let mut target_width = view::Width::new(Self::HEADER[4].len() as u16);
let mut type_width = view::Width::new(Self::HEADER[5].len() as u16);
let mut location_width = view::Width::new(Self::HEADER[7].len() as u16);
let mut kind_width = view::Width::new(Self::WIDTHS[2] as u16);
let mut target_width = view::Width::new(Self::WIDTHS[4] as u16);
let mut type_width = view::Width::new(Self::WIDTHS[5] as u16);
let mut location_width = view::Width::new(Self::WIDTHS[7] as u16);
Copy link
Member

Choose a reason for hiding this comment

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

The WIDTHS array seems fine to me, but, for what it's worth, think it would also be fine to just change this code to something like

        let viz_len: u16 = (Self::HEADER[6].len() + 1) as u16;

        let mut id_width = view::Width::new((Self::HEADER[0].len() + 1) as u16);
        let mut parent_width = view::Width::new((Self::HEADER[1].len() + 1) as u16);
        // ... and so on ...

Since the HEADER array is a const, and the 1 is also a constant, this calculation should probably get const-folded, so I don't think there would be a performance difference between this approach and creating a separate const array. I think the code might be a bit simpler if we avoided the separate array.

But, this is fine either way --- it's not a big deal.

@nrskt
Copy link
Contributor Author

nrskt commented Mar 8, 2022

@hawkw
Thank you for reviewing.
Your suggestions are very helpful to me. However, I would like to merge this PR.

I’m interested in this project and I hope I can reflect your suggestions in another PR.

@hawkw
Copy link
Member

hawkw commented Mar 8, 2022

@hawkw Thank you for reviewing. Your suggestions are very helpful to me. However, I would like to merge this PR.

I’m interested in this project and I hope I can reflect your suggestions in another PR.

Sounds good, I'm happy to go ahead and merge this now!

@hawkw hawkw enabled auto-merge (squash) March 8, 2022 03:07
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
auto-merge was automatically disabled March 8, 2022 06:33

Head branch was pushed to by a user without write access

auto-merge was automatically disabled March 8, 2022 06:33

Head branch was pushed to by a user without write access

@hawkw hawkw enabled auto-merge (squash) March 8, 2022 17:11
@hawkw hawkw requested a review from a team as a code owner March 8, 2022 22:39
@hawkw hawkw merged commit b9e0a22 into tokio-rs:main Mar 8, 2022
hawkw added a commit that referenced this pull request Mar 9, 2022
## 0.1.3 (2022-03-09)

#### Bug Fixes

*  exit crossterm before printing panic messages (#307)
   ([43606b9](43606b9))
*  prevent panics if subscriber reports out-of-order times (#295)
   ([80d7f42](80d7f42))

#### Features

*  add icon representing column sorting state (#301)
   ([b9e0a22](b9e0a22))
hawkw added a commit that referenced this pull request Mar 9, 2022
## 0.1.3 (2022-03-09)

#### Bug Fixes

*  exit crossterm before printing panic messages (#307)
   ([43606b9](43606b9))
*  prevent panics if subscriber reports out-of-order times (#295)
   ([80d7f42](80d7f42))

#### Features

*  add icon representing column sorting state (#301)
   ([b9e0a22](b9e0a22))
hawkw added a commit that referenced this pull request Mar 9, 2022
## 0.1.3 (2022-03-09)

#### Bug Fixes

*  exit crossterm before printing panic messages (#307)
   ([43606b9](43606b9))
*  prevent panics if subscriber reports out-of-order times (#295)
   ([80d7f42](80d7f42))

#### Features

*  add icon representing column sorting state (#301)
   ([b9e0a22](b9e0a22))
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.

2 participants