Skip to main content

ui_grid_core/
viewmodel.rs

1use crate::{
2    constants::SortDirection,
3    models::{GridColumnDef, GridIcon, GridIcons, GridLabels, GridOptions, GridRow},
4};
5
6pub fn resolve_grid_labels(overrides: Option<&GridLabels>) -> GridLabels {
7    overrides.cloned().unwrap_or_default()
8}
9
10pub fn resolve_grid_icons(overrides: Option<&GridIcons>) -> GridIcons {
11    overrides.cloned().unwrap_or_default()
12}
13
14pub fn is_grid_tree_enabled(options: &GridOptions) -> bool {
15    options.enable_tree_view
16}
17
18pub fn is_grid_grouping_enabled(options: &GridOptions) -> bool {
19    options.enable_grouping && !is_grid_tree_enabled(options)
20}
21
22pub fn can_grid_expand_rows(options: &GridOptions) -> bool {
23    options.enable_expandable
24}
25
26pub fn is_grid_pagination_enabled(options: &GridOptions) -> bool {
27    options.enable_pagination || options.pagination_page_size.unwrap_or(0) > 0
28}
29
30pub fn should_show_grid_pagination_controls(options: &GridOptions) -> bool {
31    is_grid_pagination_enabled(options) && options.enable_pagination_controls
32}
33
34pub fn is_grid_infinite_scroll_enabled(options: &GridOptions) -> bool {
35    options.infinite_scroll_rows_from_end.is_some()
36        || options.infinite_scroll_up
37        || options.infinite_scroll_down.is_some()
38}
39
40pub fn is_grid_sorting_enabled(options: &GridOptions) -> bool {
41    options.enable_sorting
42}
43
44pub fn is_grid_filtering_enabled(options: &GridOptions) -> bool {
45    options.enable_filtering
46}
47
48pub fn can_grid_move_columns(options: &GridOptions) -> bool {
49    options.enable_column_moving
50}
51
52pub fn can_grid_resize_columns(options: &GridOptions) -> bool {
53    options.enable_column_resizing
54}
55
56pub fn is_grid_primary_column(visible_columns: &[GridColumnDef], column: &GridColumnDef) -> bool {
57    visible_columns
58        .first()
59        .is_some_and(|candidate| candidate.name == column.name)
60}
61
62pub fn is_grid_column_sortable(options: &GridOptions, column: &GridColumnDef) -> bool {
63    is_grid_sorting_enabled(options) && column.sortable && column.enable_sorting
64}
65
66pub fn is_grid_column_filterable(options: &GridOptions, column: &GridColumnDef) -> bool {
67    is_grid_filtering_enabled(options) && column.filterable && column.enable_filtering
68}
69
70pub fn should_show_grid_tree_toggle(
71    options: &GridOptions,
72    visible_columns: &[GridColumnDef],
73    row: &GridRow,
74    column: &GridColumnDef,
75) -> bool {
76    is_grid_primary_column(visible_columns, column)
77        && is_grid_tree_enabled(options)
78        && (row.has_children || options.show_tree_expand_no_children)
79}
80
81pub fn should_show_grid_expand_toggle(
82    options: &GridOptions,
83    visible_columns: &[GridColumnDef],
84    column: &GridColumnDef,
85) -> bool {
86    is_grid_primary_column(visible_columns, column) && can_grid_expand_rows(options)
87}
88
89pub fn grid_sort_button_label(direction: SortDirection, labels: &GridLabels) -> String {
90    match direction {
91        SortDirection::Asc => labels.sort_asc.clone(),
92        SortDirection::Desc => labels.sort_desc.clone(),
93        SortDirection::None => labels.sort_default.clone(),
94    }
95}
96
97pub fn grid_sort_button_icon(direction: SortDirection, icons: &GridIcons) -> GridIcon {
98    match direction {
99        SortDirection::Asc => icons.sort_asc.clone(),
100        SortDirection::Desc => icons.sort_desc.clone(),
101        SortDirection::None => icons.sort_default.clone(),
102    }
103}
104
105pub fn grid_sort_aria_sort(direction: SortDirection) -> String {
106    match direction {
107        SortDirection::Asc => "ascending".to_string(),
108        SortDirection::Desc => "descending".to_string(),
109        SortDirection::None => "none".to_string(),
110    }
111}
112
113pub fn grid_grouping_button_label(is_grouped: bool, labels: &GridLabels) -> String {
114    if is_grouped {
115        labels.ungroup_column.clone()
116    } else {
117        labels.group_column.clone()
118    }
119}
120
121pub fn grid_grouping_button_icon(is_grouped: bool, icons: &GridIcons) -> GridIcon {
122    if is_grouped {
123        icons.ungroup_column.clone()
124    } else {
125        icons.group_column.clone()
126    }
127}
128
129pub fn grid_filter_placeholder(is_filterable: bool, labels: &GridLabels) -> String {
130    if is_filterable {
131        labels.filter_placeholder.clone()
132    } else {
133        labels.filter_disabled.clone()
134    }
135}
136
137pub fn grid_group_disclosure_label(collapsed: bool, labels: &GridLabels) -> String {
138    if collapsed {
139        labels.group_expand.clone()
140    } else {
141        labels.group_collapse.clone()
142    }
143}
144
145pub fn grid_group_disclosure_icon(collapsed: bool, icons: &GridIcons) -> GridIcon {
146    if collapsed {
147        icons.group_expand.clone()
148    } else {
149        icons.group_collapse.clone()
150    }
151}
152
153pub fn grid_editor_input_type(column: &GridColumnDef) -> String {
154    match column.r#type {
155        crate::models::GridColumnType::Number => "number".to_string(),
156        crate::models::GridColumnType::Date => "date".to_string(),
157        crate::models::GridColumnType::String
158        | crate::models::GridColumnType::Boolean
159        | crate::models::GridColumnType::Object => "text".to_string(),
160    }
161}
162
163pub fn grid_column_width(column: &GridColumnDef) -> String {
164    column
165        .width
166        .clone()
167        .unwrap_or_else(|| "minmax(11rem, max-content)".to_string())
168}
169
170pub fn grid_cell_indent(
171    options: &GridOptions,
172    visible_columns: &[GridColumnDef],
173    row: &GridRow,
174    column: &GridColumnDef,
175) -> String {
176    if !is_grid_primary_column(visible_columns, column) || !is_grid_tree_enabled(options) {
177        return "0px".to_string();
178    }
179
180    format!("{}px", row.tree_level * options.tree_indent.unwrap_or(10))
181}
182
183pub fn grid_tree_toggle_label(expanded: bool, labels: &GridLabels) -> String {
184    if expanded {
185        labels.tree_collapse.clone()
186    } else {
187        labels.tree_expand.clone()
188    }
189}
190
191pub fn grid_tree_toggle_icon(expanded: bool, icons: &GridIcons) -> GridIcon {
192    if expanded {
193        icons.tree_collapse.clone()
194    } else {
195        icons.tree_expand.clone()
196    }
197}
198
199pub fn grid_expand_toggle_label(expanded: bool, labels: &GridLabels) -> String {
200    if expanded {
201        labels.collapse_detail.clone()
202    } else {
203        labels.expand_detail.clone()
204    }
205}
206
207pub fn grid_expand_toggle_icon(expanded: bool, icons: &GridIcons) -> GridIcon {
208    if expanded {
209        icons.collapse_detail.clone()
210    } else {
211        icons.expand_detail.clone()
212    }
213}
214
215pub fn grid_drag_handle_icon(icons: &GridIcons) -> GridIcon {
216    icons.drag_handle.clone()
217}
218
219pub fn grid_move_left_icon(icons: &GridIcons) -> GridIcon {
220    icons.move_left.clone()
221}
222
223pub fn grid_move_right_icon(icons: &GridIcons) -> GridIcon {
224    icons.move_right.clone()
225}
226
227pub fn grid_pin_left_icon(icons: &GridIcons) -> GridIcon {
228    icons.pin_left.clone()
229}
230
231pub fn grid_pin_right_icon(icons: &GridIcons) -> GridIcon {
232    icons.pin_right.clone()
233}
234
235pub fn grid_unpin_icon(icons: &GridIcons) -> GridIcon {
236    icons.unpin.clone()
237}
238
239pub fn is_grid_column_grouped(group_by_columns: &[String], column: &GridColumnDef) -> bool {
240    group_by_columns.iter().any(|name| name == &column.name)
241}
242
243pub fn is_grid_tree_row_expanded(
244    expanded_tree_rows: &std::collections::BTreeMap<String, bool>,
245    row: &GridRow,
246) -> bool {
247    expanded_tree_rows.get(&row.id).copied().unwrap_or(false)
248}
249
250pub fn grid_tree_toggle_label_for_row(
251    expanded_tree_rows: &std::collections::BTreeMap<String, bool>,
252    row: &GridRow,
253    labels: &GridLabels,
254) -> String {
255    grid_tree_toggle_label(is_grid_tree_row_expanded(expanded_tree_rows, row), labels)
256}
257
258pub fn grid_expand_toggle_label_for_row(row: &GridRow, labels: &GridLabels) -> String {
259    grid_expand_toggle_label(row.expanded, labels)
260}