Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/src/configurations/config-file-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ max_concurrent_requests = 5

default_region = "us-east-1"

[ui.bucket_list]
default_sort = "default"

[ui.object_list]
date_format = "%Y-%m-%d %H:%M:%S"
date_width = 19
default_sort = "default"

[ui.object_detail]
date_format = "%Y-%m-%d %H:%M:%S"
Expand Down Expand Up @@ -58,6 +62,17 @@ The default region to use if the region cannot be obtained from the command line
- type: `string`
- default: `us-east-1`

### `ui.bucket_list.default_sort`

The default sort order of the bucket list.

- type: `string`
- default: `default`
- possible values:
- `default`
- `name_asc`
- `name_desc`

### `ui.object_list.date_format`

The date format of a last modified in the object list.
Expand All @@ -74,6 +89,21 @@ It is recommended to set this when setting `date_format`.
- type: `u16`
- default: `19`

### `ui.object_list.default_sort`

The default sort order of the object list.

- type: `string`
- default: `default`
- possible values:
- `default`
- `name_asc`
- `name_desc`
- `date_asc`
- `date_desc`
- `size_asc`
- `size_desc`

### `ui.object_detail.date_format`

The date format of a last modified in the object detail.
Expand Down
31 changes: 31 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub struct Config {
#[optional(derives = [Deserialize])]
#[derive(Debug, Clone, SmartDefault)]
pub struct UiConfig {
#[nested]
pub bucket_list: UiBucketListConfig,
#[nested]
pub object_list: UiObjectListConfig,
#[nested]
Expand All @@ -45,13 +47,42 @@ pub struct UiConfig {
pub help: UiHelpConfig,
}

#[optional(derives = [Deserialize])]
#[derive(Debug, Clone, SmartDefault)]
pub struct UiBucketListConfig {
#[default(BucketListDefaultSort::Default)]
pub default_sort: BucketListDefaultSort,
}

#[derive(Debug, Clone, Copy, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BucketListDefaultSort {
Default,
NameAsc,
NameDesc,
}

#[optional(derives = [Deserialize])]
#[derive(Debug, Clone, SmartDefault)]
pub struct UiObjectListConfig {
#[default = "%Y-%m-%d %H:%M:%S"]
pub date_format: String,
#[default = 19] // // "2021-01-01 12:34:56".len()
pub date_width: usize,
#[default(ObjectListDefaultSort::Default)]
pub default_sort: ObjectListDefaultSort,
}

#[derive(Debug, Clone, Copy, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ObjectListDefaultSort {
Default,
NameAsc,
NameDesc,
DateAsc,
DateDesc,
SizeAsc,
SizeDesc,
}

#[optional(derives = [Deserialize])]
Expand Down
10 changes: 7 additions & 3 deletions src/pages/bucket_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,20 @@ impl BucketListPage {
pub fn new(bucket_items: Vec<BucketItem>, ctx: Rc<AppContext>, tx: Sender) -> Self {
let items_len = bucket_items.len();
let view_indices = (0..items_len).collect();
Self {
let mut page = Self {
bucket_items,
view_indices,
view_state: ViewState::Default,
list_state: ScrollListState::new(items_len),
filter_input_state: InputDialogState::default(),
sort_dialog_state: BucketListSortDialogState::default(),
sort_dialog_state: BucketListSortDialogState::new(
ctx.config.ui.bucket_list.default_sort,
),
ctx,
tx,
}
};
page.sort_view_indices(); // initial sort
page
}

pub fn handle_key(&mut self, user_events: Vec<UserEvent>, key_event: KeyEvent) {
Expand Down
10 changes: 7 additions & 3 deletions src/pages/object_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,21 @@ impl ObjectListPage {
) -> Self {
let items_len = object_items.len();
let view_indices = (0..items_len).collect();
Self {
let mut page = Self {
object_items,
object_key,
view_indices,
view_state: ViewState::Default,
list_state: ScrollListState::new(items_len),
filter_input_state: InputDialogState::default(),
sort_dialog_state: ObjectListSortDialogState::default(),
sort_dialog_state: ObjectListSortDialogState::new(
ctx.config.ui.object_list.default_sort,
),
ctx,
tx,
}
};
page.sort_view_indices(); // initial sort
page
}

pub fn handle_key(&mut self, user_events: Vec<UserEvent>, key_event: KeyEvent) {
Expand Down
54 changes: 45 additions & 9 deletions src/widget/sort_list_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@ use ratatui::{
widgets::{block::Title, Block, BorderType, List, ListItem, Padding, Widget, WidgetRef},
};

use crate::{color::ColorTheme, widget::Dialog};
use crate::{color::ColorTheme, config, widget::Dialog};

#[derive(Default)]
#[zero_indexed_enum]
pub enum BucketListSortType {
#[default]
Default,
NameAsc,
NameDesc,
}

impl From<config::BucketListDefaultSort> for BucketListSortType {
fn from(sort: config::BucketListDefaultSort) -> Self {
match sort {
config::BucketListDefaultSort::Default => BucketListSortType::Default,
config::BucketListDefaultSort::NameAsc => BucketListSortType::NameAsc,
config::BucketListDefaultSort::NameDesc => BucketListSortType::NameDesc,
}
}
}

impl BucketListSortType {
pub fn str(&self) -> &'static str {
match self {
Expand All @@ -29,12 +37,20 @@ impl BucketListSortType {
}
}

#[derive(Debug, Default, Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub struct BucketListSortDialogState {
default: BucketListSortType,
selected: BucketListSortType,
}

impl BucketListSortDialogState {
pub fn new(default_sort: config::BucketListDefaultSort) -> Self {
Self {
default: default_sort.into(),
selected: default_sort.into(),
}
}

pub fn select_next(&mut self) {
self.selected = self.selected.next();
}
Expand All @@ -44,7 +60,7 @@ impl BucketListSortDialogState {
}

pub fn reset(&mut self) {
self.selected = BucketListSortType::Default;
self.selected = self.default;
}

pub fn selected(&self) -> BucketListSortType {
Expand Down Expand Up @@ -84,10 +100,8 @@ impl Widget for BucketListSortDialog {
}
}

#[derive(Default)]
#[zero_indexed_enum]
pub enum ObjectListSortType {
#[default]
Default,
NameAsc,
NameDesc,
Expand All @@ -97,6 +111,20 @@ pub enum ObjectListSortType {
SizeDesc,
}

impl From<config::ObjectListDefaultSort> for ObjectListSortType {
fn from(sort: config::ObjectListDefaultSort) -> Self {
match sort {
config::ObjectListDefaultSort::Default => ObjectListSortType::Default,
config::ObjectListDefaultSort::NameAsc => ObjectListSortType::NameAsc,
config::ObjectListDefaultSort::NameDesc => ObjectListSortType::NameDesc,
config::ObjectListDefaultSort::DateAsc => ObjectListSortType::LastModifiedAsc,
config::ObjectListDefaultSort::DateDesc => ObjectListSortType::LastModifiedDesc,
config::ObjectListDefaultSort::SizeAsc => ObjectListSortType::SizeAsc,
config::ObjectListDefaultSort::SizeDesc => ObjectListSortType::SizeDesc,
}
}
}

impl ObjectListSortType {
pub fn str(&self) -> &'static str {
match self {
Expand All @@ -111,12 +139,20 @@ impl ObjectListSortType {
}
}

#[derive(Debug, Default, Clone, Copy)]
#[derive(Debug, Clone, Copy)]
pub struct ObjectListSortDialogState {
default: ObjectListSortType,
selected: ObjectListSortType,
}

impl ObjectListSortDialogState {
pub fn new(default_sort: config::ObjectListDefaultSort) -> Self {
Self {
default: default_sort.into(),
selected: default_sort.into(),
}
}

pub fn select_next(&mut self) {
self.selected = self.selected.next();
}
Expand All @@ -126,7 +162,7 @@ impl ObjectListSortDialogState {
}

pub fn reset(&mut self) {
self.selected = ObjectListSortType::Default;
self.selected = self.default;
}

pub fn selected(&self) -> ObjectListSortType {
Expand Down