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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions quilt-sync/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
<!-- markdownlint-disable MD013 -->
# Changelog

## [v0.18.3-alpha9] - 2026-07-10

### Changed

- 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>)

## [v0.18.3-alpha8] - 2026-07-10

### Added
Expand Down
2 changes: 1 addition & 1 deletion quilt-sync/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "quilt-sync"
version = "0.18.3-alpha8"
version = "0.18.3-alpha9"
authors = ["Quilt Data, Inc."]
description = "Cross-platform desktop application for editing Quilt data packages"
documentation = "https://docs.quiltdata.com"
Expand Down
14 changes: 13 additions & 1 deletion quilt-sync/ui/assets/css/components/button.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@
background: var(--q-ui-palette-warning);
}

&.danger {
color: #fff;
background: var(--q-ui-palette-error);
}

&.danger[disabled]:hover {
color: #fff;
background: var(--q-ui-palette-error);
}

&.link {
background: transparent;
border: 0;
Expand Down Expand Up @@ -105,7 +115,9 @@
&.primary .qui-icon,
&.primary .icon,
&.warning .qui-icon,
&.warning .icon {
&.warning .icon,
&.danger .qui-icon,
&.danger .icon {
filter: invert(1);
}

Expand Down
10 changes: 10 additions & 0 deletions quilt-sync/ui/assets/css/pages/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@
font-size: 0.875rem;
}

.global-scope-warning {
background: color-mix(in srgb, var(--q-ui-palette-error) 12%, transparent);
border: 1px solid var(--q-ui-palette-error);
border-radius: 4px;
color: var(--q-ui-palette-error);
font-size: 0.875rem;
margin: 0;
padding: 8px 12px;
}

.popup-actions {
align-items: center;
display: flex;
Expand Down
6 changes: 5 additions & 1 deletion quilt-sync/ui/src/components/buttons/base/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub fn IconButton(
#[prop(optional)] small: bool,
#[prop(optional)] primary: bool,
#[prop(optional)] warning: bool,
#[prop(optional, into)] danger: MaybeProp<bool>,
#[prop(optional)] large: bool,
#[prop(optional)] link: bool,
#[prop(optional, into)] disabled: MaybeProp<bool>,
Expand All @@ -17,8 +18,11 @@ pub fn IconButton(
view! {
<button
class="qui-button"
class:primary=primary
// `danger` replaces `primary` rather than stacking on it, so the
// error color never depends on CSS rule order to win.
class:primary=move || primary && !danger.get().unwrap_or(false)
class:warning=warning
class:danger=move || danger.get().unwrap_or(false)
class:small=small
class:large=large
class:link=link
Expand Down
8 changes: 7 additions & 1 deletion quilt-sync/ui/src/components/buttons/form_primary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ use super::IconButton;
pub fn FormPrimary(
on_click: impl Fn(leptos::ev::MouseEvent) + 'static,
#[prop(optional, into)] disabled: MaybeProp<bool>,
#[prop(optional, into)] danger: MaybeProp<bool>,
children: Children,
) -> impl IntoView {
view! {
<IconButton on_click=UnsyncCallback::new(on_click) primary=true disabled=disabled>
<IconButton
on_click=UnsyncCallback::new(on_click)
primary=true
danger=danger
disabled=disabled
Comment thread
greptile-apps[bot] marked this conversation as resolved.
>
{children()}
</IconButton>
}
Expand Down
2 changes: 1 addition & 1 deletion quilt-sync/ui/src/pages/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ fn SettingsContent(
changelog=data.changelog
notification=notification
/>
<PublishSection publish=data.publish notification=notification refetch=refetch />
<AutosyncSection autosync=data.autosync notification=notification refetch=refetch />
<PublishSection publish=data.publish notification=notification refetch=refetch />
<FsWatcherSection fswatcher=data.fswatcher notification=notification refetch=refetch />
<AccountSection auth_hosts=data.auth_hosts notification=notification refetch=refetch />
<DiagnosticsSection
Expand Down
56 changes: 55 additions & 1 deletion quilt-sync/ui/src/pages/settings/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ use crate::components::buttons;
const PUBLISH_PLACEHOLDERS: &[&str] =
&["{date}", "{time}", "{datetime}", "{namespace}", "{changes}"];

/// Copy for the global-scope reminder shown in the "Edit commit defaults" popup.
const GLOBAL_SCOPE_WARNING: &str = "These settings apply to every bucket. Workflow ids and \
metadata schemas are defined per bucket — a global override can make commits fail in \
buckets that don't define it.";

/// Whether the global-scope warning should be shown for the current popup state.
///
/// The commit defaults are global (they apply to every bucket), so we warn
/// whenever the user leans on a per-bucket-sensitive setting: the workflow is
/// overridden (regardless of the id text), or default metadata is present.
/// Reflects current state, not dirtiness — a pre-populated override warns too.
fn show_global_scope_warning(override_selected: bool, metadata: &str) -> bool {
override_selected || !metadata.trim().is_empty()
}

fn apply_placeholders(template: &str, values: &[&str]) -> String {
debug_assert_eq!(PUBLISH_PLACEHOLDERS.len(), values.len());
let mut rendered = template.to_string();
Expand Down Expand Up @@ -144,6 +159,11 @@ fn PublishSettingsPopup(
let metadata_error = RwSignal::new(None::<String>);
let saving = RwSignal::new(false);

// Reactive: warn while an override is selected or metadata is present.
let show_warning = Signal::derive(move || {
show_global_scope_warning(!use_bucket_default.get(), &metadata.get())
});

let on_close_save = on_close.clone();
let on_save = move |_: leptos::ev::MouseEvent| {
if saving.get_untracked() {
Expand Down Expand Up @@ -268,8 +288,14 @@ fn PublishSettingsPopup(
</Show>
</div>

<Show when=move || show_warning.get()>
<p class="global-scope-warning" role="alert">
{GLOBAL_SCOPE_WARNING}
</p>
</Show>

<div class="popup-actions">
<buttons::FormPrimary on_click=on_save disabled=saving>
<buttons::FormPrimary on_click=on_save disabled=saving danger=show_warning>
"Save"
</buttons::FormPrimary>
<buttons::FormSecondary on_click=on_cancel />
Expand All @@ -281,3 +307,31 @@ fn PublishSettingsPopup(
</div>
}
}

#[cfg(test)]
mod tests {
use super::show_global_scope_warning;

#[test]
fn override_selected_warns() {
// Override selected warns regardless of the id text (even empty).
assert!(show_global_scope_warning(true, ""));
assert!(show_global_scope_warning(true, "my-workflow"));
}

#[test]
fn metadata_non_empty_warns() {
// Bucket default + present metadata still warns.
assert!(show_global_scope_warning(false, r#"{"source":"desktop"}"#));
}

#[test]
fn whitespace_only_metadata_does_not_warn() {
assert!(!show_global_scope_warning(false, " \n\t "));
}

#[test]
fn neither_does_not_warn() {
assert!(!show_global_scope_warning(false, ""));
}
}