1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! A table masked for one request: [`Table::without`].
use topcoat::context::Cx;
use super::Table;
use crate::lens::shows;
impl<M> Table<M> {
/// Whether a column shows a field of a related record its resource hides from `cx`.
pub(crate) fn has_masked(&self, cx: &Cx) -> bool {
self.columns
.iter()
.any(|column| column.internals().masked(cx))
}
/// This table as `cx` reads it, without what reads one of the `hidden` fields: its columns,
/// filters, tabs, summaries, groupings, row color and row links, and a default sort on a
/// column or field it drops. A search, a sort or a filter naming one then matches nothing the
/// table declares, as one naming an unknown column does. It drops a column showing a field of
/// a related record its resource hides from `cx` too.
pub(crate) fn without(&self, cx: &Cx, hidden: &[String]) -> Self
where
M: toasty::schema::Model,
{
let mut table = self.clone();
table
.columns
.retain(|column| crate::column::shows(cx, &**column, hidden));
table.filters.retain(|filter| shows(filter.reads(), hidden));
table.tabs.retain(|tab| shows(Some(tab.reads()), hidden));
table
.summaries
.retain(|summary| shows(Some(summary.reads()), hidden));
table
.groupings
.retain(|group| shows(Some(group.reads()), hidden));
if table
.default_field
.as_ref()
.is_some_and(|field| !shows(Some(field.reads::<M>()), hidden))
{
table.default_field = None;
}
if !shows(table.row_color.reads.clone(), hidden) {
table.row_color = Default::default();
}
table
.row_links
.retain(|link| shows(link.reads.clone(), hidden));
if table
.default_sort
.as_ref()
.is_some_and(|sort| !table.orders_by(sort))
{
table.default_sort = None;
}
table
}
}