Skip to content

Commit a840568

Browse files
committed
Settings: Autosync first, global-scope warning on commit-default overrides
Reorder the Settings page so Autosync precedes Commit and Push. In the 'Edit commit defaults' popup, show an error-palette reminder that these settings are global whenever a workflow override is selected or default metadata is present, and recolor SAVE with a new .danger button variant. The warning is purely advisory — SAVE stays functional.
1 parent d85a99b commit a840568

9 files changed

Lines changed: 96 additions & 6 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quilt-sync/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
<!-- markdownlint-disable MD013 -->
1010
# Changelog
1111

12+
## [v0.18.3-alpha9] - 2026-07-10
13+
14+
### Changed
15+
16+
- Settings now lists Autosync before Commit and Push, and the "Edit commit defaults" popup shows a warning that these settings apply to every bucket when a workflow override or default metadata is set (<https://github.com/quiltdata/quilt-rs/pull/759>)
17+
1218
## [v0.18.3-alpha8] - 2026-07-10
1319

1420
### Added

quilt-sync/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "quilt-sync"
3-
version = "0.18.3-alpha8"
3+
version = "0.18.3-alpha9"
44
authors = ["Quilt Data, Inc."]
55
description = "Cross-platform desktop application for editing Quilt data packages"
66
documentation = "https://docs.quiltdata.com"

quilt-sync/ui/assets/css/components/button.css

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@
5050
background: var(--q-ui-palette-warning);
5151
}
5252

53+
&.danger {
54+
color: #fff;
55+
background: var(--q-ui-palette-error);
56+
}
57+
58+
&.danger[disabled]:hover {
59+
color: #fff;
60+
background: var(--q-ui-palette-error);
61+
}
62+
5363
&.link {
5464
background: transparent;
5565
border: 0;
@@ -105,7 +115,9 @@
105115
&.primary .qui-icon,
106116
&.primary .icon,
107117
&.warning .qui-icon,
108-
&.warning .icon {
118+
&.warning .icon,
119+
&.danger .qui-icon,
120+
&.danger .icon {
109121
filter: invert(1);
110122
}
111123

quilt-sync/ui/assets/css/pages/settings.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,16 @@
199199
font-size: 0.875rem;
200200
}
201201

202+
.global-scope-warning {
203+
background: color-mix(in srgb, var(--q-ui-palette-error) 12%, transparent);
204+
border: 1px solid var(--q-ui-palette-error);
205+
border-radius: 4px;
206+
color: var(--q-ui-palette-error);
207+
font-size: 0.875rem;
208+
margin: 0;
209+
padding: 8px 12px;
210+
}
211+
202212
.popup-actions {
203213
align-items: center;
204214
display: flex;

quilt-sync/ui/src/components/buttons/base/icon.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub fn IconButton(
99
#[prop(optional)] small: bool,
1010
#[prop(optional)] primary: bool,
1111
#[prop(optional)] warning: bool,
12+
#[prop(optional, into)] danger: MaybeProp<bool>,
1213
#[prop(optional)] large: bool,
1314
#[prop(optional)] link: bool,
1415
#[prop(optional, into)] disabled: MaybeProp<bool>,
@@ -19,6 +20,7 @@ pub fn IconButton(
1920
class="qui-button"
2021
class:primary=primary
2122
class:warning=warning
23+
class:danger=move || danger.get().unwrap_or(false)
2224
class:small=small
2325
class:large=large
2426
class:link=link

quilt-sync/ui/src/components/buttons/form_primary.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@ use super::IconButton;
77
pub fn FormPrimary(
88
on_click: impl Fn(leptos::ev::MouseEvent) + 'static,
99
#[prop(optional, into)] disabled: MaybeProp<bool>,
10+
#[prop(optional, into)] danger: MaybeProp<bool>,
1011
children: Children,
1112
) -> impl IntoView {
1213
view! {
13-
<IconButton on_click=UnsyncCallback::new(on_click) primary=true disabled=disabled>
14+
<IconButton
15+
on_click=UnsyncCallback::new(on_click)
16+
primary=true
17+
danger=danger
18+
disabled=disabled
19+
>
1420
{children()}
1521
</IconButton>
1622
}

quilt-sync/ui/src/pages/settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ fn SettingsContent(
8080
changelog=data.changelog
8181
notification=notification
8282
/>
83-
<PublishSection publish=data.publish notification=notification refetch=refetch />
8483
<AutosyncSection autosync=data.autosync notification=notification refetch=refetch />
84+
<PublishSection publish=data.publish notification=notification refetch=refetch />
8585
<FsWatcherSection fswatcher=data.fswatcher notification=notification refetch=refetch />
8686
<AccountSection auth_hosts=data.auth_hosts notification=notification refetch=refetch />
8787
<DiagnosticsSection

quilt-sync/ui/src/pages/settings/publish.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ use crate::components::buttons;
1515
const PUBLISH_PLACEHOLDERS: &[&str] =
1616
&["{date}", "{time}", "{datetime}", "{namespace}", "{changes}"];
1717

18+
/// Copy for the global-scope reminder shown in the "Edit commit defaults" popup.
19+
const GLOBAL_SCOPE_WARNING: &str = "These settings apply to every bucket. Workflow ids and \
20+
metadata schemas are defined per bucket — a global override can make commits fail in \
21+
buckets that don't define it.";
22+
23+
/// Whether the global-scope warning should be shown for the current popup state.
24+
///
25+
/// The commit defaults are global (they apply to every bucket), so we warn
26+
/// whenever the user leans on a per-bucket-sensitive setting: the workflow is
27+
/// overridden (regardless of the id text), or default metadata is present.
28+
/// Reflects current state, not dirtiness — a pre-populated override warns too.
29+
fn show_global_scope_warning(override_selected: bool, metadata: &str) -> bool {
30+
override_selected || !metadata.trim().is_empty()
31+
}
32+
1833
fn apply_placeholders(template: &str, values: &[&str]) -> String {
1934
debug_assert_eq!(PUBLISH_PLACEHOLDERS.len(), values.len());
2035
let mut rendered = template.to_string();
@@ -144,6 +159,11 @@ fn PublishSettingsPopup(
144159
let metadata_error = RwSignal::new(None::<String>);
145160
let saving = RwSignal::new(false);
146161

162+
// Reactive: warn while an override is selected or metadata is present.
163+
let show_warning = Signal::derive(move || {
164+
show_global_scope_warning(!use_bucket_default.get(), &metadata.get())
165+
});
166+
147167
let on_close_save = on_close.clone();
148168
let on_save = move |_: leptos::ev::MouseEvent| {
149169
if saving.get_untracked() {
@@ -268,8 +288,14 @@ fn PublishSettingsPopup(
268288
</Show>
269289
</div>
270290

291+
<Show when=move || show_warning.get()>
292+
<p class="global-scope-warning" role="alert">
293+
{GLOBAL_SCOPE_WARNING}
294+
</p>
295+
</Show>
296+
271297
<div class="popup-actions">
272-
<buttons::FormPrimary on_click=on_save disabled=saving>
298+
<buttons::FormPrimary on_click=on_save disabled=saving danger=show_warning>
273299
"Save"
274300
</buttons::FormPrimary>
275301
<buttons::FormSecondary on_click=on_cancel />
@@ -281,3 +307,31 @@ fn PublishSettingsPopup(
281307
</div>
282308
}
283309
}
310+
311+
#[cfg(test)]
312+
mod tests {
313+
use super::show_global_scope_warning;
314+
315+
#[test]
316+
fn override_selected_warns() {
317+
// Override selected warns regardless of the id text (even empty).
318+
assert!(show_global_scope_warning(true, ""));
319+
assert!(show_global_scope_warning(true, "my-workflow"));
320+
}
321+
322+
#[test]
323+
fn metadata_non_empty_warns() {
324+
// Bucket default + present metadata still warns.
325+
assert!(show_global_scope_warning(false, r#"{"source":"desktop"}"#));
326+
}
327+
328+
#[test]
329+
fn whitespace_only_metadata_does_not_warn() {
330+
assert!(!show_global_scope_warning(false, " \n\t "));
331+
}
332+
333+
#[test]
334+
fn neither_does_not_warn() {
335+
assert!(!show_global_scope_warning(false, ""));
336+
}
337+
}

0 commit comments

Comments
 (0)