|
1 |
+ |
use std::fmt::Write as _;
|
| 1 |
2 |
|
use std::fs;
|
| 2 |
3 |
|
use std::path::Path;
|
| 3 |
4 |
|
|
| 131 |
132 |
|
},
|
| 132 |
133 |
|
];
|
| 133 |
134 |
|
|
|
135 |
+ |
/// The tables: `(name, header class, selector, columns)`.
|
|
136 |
+ |
///
|
|
137 |
+ |
/// One list, read twice. [`table_css`] emits the rules and
|
|
138 |
+ |
/// [`table_columns_json`] hands the same order to the frontend's tests, which
|
|
139 |
+ |
/// is what lets them assert that a row's cells are the columns the description
|
|
140 |
+ |
/// names.
|
|
141 |
+ |
///
|
|
142 |
+ |
/// The two event selectors carry a modifier rather than a class of their own,
|
|
143 |
+ |
/// so everything the two tables genuinely share -- padding, hover, the row
|
|
144 |
+ |
/// border -- stays on `.event-row-virtual` and only the grid splits.
|
|
145 |
+ |
const TABLES: &[(&str, &str, &str, &[Column<'static>])] = &[
|
|
146 |
+ |
(
|
|
147 |
+ |
"task",
|
|
148 |
+ |
"task-header-row",
|
|
149 |
+ |
".task-header-row, .task-row",
|
|
150 |
+ |
TASK_COLUMNS,
|
|
151 |
+ |
),
|
|
152 |
+ |
(
|
|
153 |
+ |
"upcoming",
|
|
154 |
+ |
"event-header-upcoming",
|
|
155 |
+ |
".event-header-row.event-header-upcoming, .event-row-virtual.event-upcoming",
|
|
156 |
+ |
UPCOMING_COLUMNS,
|
|
157 |
+ |
),
|
|
158 |
+ |
(
|
|
159 |
+ |
"recurring",
|
|
160 |
+ |
"event-header-recurring",
|
|
161 |
+ |
".event-header-row.event-header-recurring, .event-row-virtual.event-recurring",
|
|
162 |
+ |
RECURRING_COLUMNS,
|
|
163 |
+ |
),
|
|
164 |
+ |
];
|
|
165 |
+ |
|
|
166 |
+ |
/// The column names, for a reader that is not a stylesheet.
|
|
167 |
+ |
///
|
|
168 |
+ |
/// The CSS carries the names of the columns it *hides* and nothing else, so a
|
|
169 |
+ |
/// cell whose `col-` class matches no column is invisible to it: the narrowing
|
|
170 |
+ |
/// rules simply never match, and the cell stays on a narrow screen with nothing
|
|
171 |
+ |
/// said. That is how the events table came to render six cells into five
|
|
172 |
+ |
/// tracks. This file is the description in a form the frontend can check itself
|
|
173 |
+ |
/// against.
|
|
174 |
+ |
fn table_columns_json() -> String {
|
|
175 |
+ |
let mut json = String::from("{\n");
|
|
176 |
+ |
for (i, (table, header, _, columns)) in TABLES.iter().enumerate() {
|
|
177 |
+ |
let names = columns
|
|
178 |
+ |
.iter()
|
|
179 |
+ |
.map(|c| format!("\"{}\"", c.name))
|
|
180 |
+ |
.collect::<Vec<_>>()
|
|
181 |
+ |
.join(", ");
|
|
182 |
+ |
let _ = writeln!(
|
|
183 |
+ |
json,
|
|
184 |
+ |
" \"{table}\": {{ \"header\": \"{header}\", \"columns\": [{names}] }}{}",
|
|
185 |
+ |
if i + 1 == TABLES.len() { "" } else { "," }
|
|
186 |
+ |
);
|
|
187 |
+ |
}
|
|
188 |
+ |
json.push_str("}\n");
|
|
189 |
+ |
json
|
|
190 |
+ |
}
|
|
191 |
+ |
|
| 134 |
192 |
|
/// Generate the tables' column CSS.
|
| 135 |
193 |
|
///
|
| 136 |
194 |
|
/// Both halves of narrowing come out of one call per breakpoint: the track list
|
| 218 |
276 |
|
silently disappears. */\n",
|
| 219 |
277 |
|
);
|
| 220 |
278 |
|
|
| 221 |
|
- |
// The two event selectors carry a modifier rather than a class of their
|
| 222 |
|
- |
// own, so everything the two tables genuinely share -- padding, hover, the
|
| 223 |
|
- |
// row border -- stays on .event-row-virtual and only the grid splits.
|
| 224 |
|
- |
for (selector, columns, wide, narrow) in [
|
| 225 |
|
- |
(
|
| 226 |
|
- |
".task-header-row, .task-row",
|
| 227 |
|
- |
TASK_COLUMNS,
|
| 228 |
|
- |
&task_wide,
|
| 229 |
|
- |
&task_narrow,
|
| 230 |
|
- |
),
|
| 231 |
|
- |
(
|
| 232 |
|
- |
".event-header-row.event-header-upcoming, .event-row-virtual.event-upcoming",
|
| 233 |
|
- |
UPCOMING_COLUMNS,
|
| 234 |
|
- |
&upcoming_wide,
|
| 235 |
|
- |
&upcoming_narrow,
|
| 236 |
|
- |
),
|
| 237 |
|
- |
(
|
| 238 |
|
- |
".event-header-row.event-header-recurring, .event-row-virtual.event-recurring",
|
| 239 |
|
- |
RECURRING_COLUMNS,
|
| 240 |
|
- |
&recurring_wide,
|
| 241 |
|
- |
&recurring_narrow,
|
| 242 |
|
- |
),
|
| 243 |
|
- |
] {
|
|
279 |
+ |
// Zipped rather than carried in TABLES: a length is a CSS answer and the
|
|
280 |
+ |
// description deliberately holds none, which is the split Sizing exists for.
|
|
281 |
+ |
for ((_, _, selector, columns), (wide, narrow)) in TABLES.iter().zip([
|
|
282 |
+ |
(&task_wide, &task_narrow),
|
|
283 |
+ |
(&upcoming_wide, &upcoming_narrow),
|
|
284 |
+ |
(&recurring_wide, &recurring_narrow),
|
|
285 |
+ |
]) {
|
| 244 |
286 |
|
css.push('\n');
|
| 245 |
287 |
|
css.push_str(&narrowing_css(
|
| 246 |
288 |
|
columns,
|
| 299 |
341 |
|
|
| 300 |
342 |
|
// The columns are this app's, so the shared helper cannot know them, but
|
| 301 |
343 |
|
// what is done with them comes from the description all the same.
|
| 302 |
|
- |
let tables = Path::new(env!("CARGO_MANIFEST_DIR")).join("frontend/css/tables.css");
|
| 303 |
|
- |
fs::write(&tables, table_css()).expect("write tables.css");
|
|
344 |
+ |
let frontend = Path::new(env!("CARGO_MANIFEST_DIR")).join("frontend");
|
|
345 |
+ |
fs::write(frontend.join("css/tables.css"), table_css()).expect("write tables.css");
|
|
346 |
+ |
fs::write(frontend.join("tables.columns.json"), table_columns_json())
|
|
347 |
+ |
.expect("write tables.columns.json");
|
| 304 |
348 |
|
println!("cargo:rerun-if-changed=build.rs");
|
| 305 |
349 |
|
|
| 306 |
350 |
|
tauri_build::build();
|