mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 13:33:24 +00:00
settings: Update save button style when "Saved" is shown.
This commit updates the save button style in the settings component to ensure that the button appears as a borderless attention + success intent action button alongside the "Saved" label, when an updated setting is saved.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
import * as loading from "./loading.ts";
|
import * as loading from "./loading.ts";
|
||||||
|
import {COMPONENT_INTENT_VALUES} from "./types.ts";
|
||||||
import type {ComponentIntent} from "./types.ts";
|
import type {ComponentIntent} from "./types.ts";
|
||||||
|
|
||||||
export const ACTION_BUTTON_ATTENTION_VALUES = ["primary", "quiet", "borderless"] as const;
|
export const ACTION_BUTTON_ATTENTION_VALUES = ["primary", "quiet", "borderless"] as const;
|
||||||
@@ -50,3 +51,32 @@ export function hide_button_loading_indicator($button: JQuery): void {
|
|||||||
$button.find(".zulip-icon").css("visibility", "visible");
|
$button.find(".zulip-icon").css("visibility", "visible");
|
||||||
$button.find(".action-button-label").css("visibility", "visible");
|
$button.find(".action-button-label").css("visibility", "visible");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function modify_action_button_style(
|
||||||
|
$button: JQuery,
|
||||||
|
opts: {
|
||||||
|
attention?: ActionButtonAttention;
|
||||||
|
intent?: ComponentIntent;
|
||||||
|
},
|
||||||
|
): void {
|
||||||
|
if (opts.attention === undefined && opts.intent === undefined) {
|
||||||
|
// If neither attention nor intent is provided, do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const action_button_attention_pattern = ACTION_BUTTON_ATTENTION_VALUES.join("|");
|
||||||
|
const component_intent_pattern = COMPONENT_INTENT_VALUES.join("|");
|
||||||
|
const action_button_style_regex = new RegExp(
|
||||||
|
`action-button-(${action_button_attention_pattern})-(${component_intent_pattern})`,
|
||||||
|
);
|
||||||
|
const action_button_style_regex_match = $button.attr("class")?.match(action_button_style_regex);
|
||||||
|
if (!action_button_style_regex_match) {
|
||||||
|
// If the button doesn't have the expected class, do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const [action_button_style_class, old_attention, old_intent] = action_button_style_regex_match;
|
||||||
|
// Replace the old attention and intent values with the new ones, if provided.
|
||||||
|
$button.removeClass(action_button_style_class);
|
||||||
|
$button.addClass(
|
||||||
|
`action-button-${opts.attention ?? old_attention}-${opts.intent ?? old_intent}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -557,19 +557,17 @@ export function change_save_button_state($element: JQuery, state: string): void
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let button_text;
|
let button_text = $t({defaultMessage: "Save changes"});
|
||||||
let data_status;
|
let data_status;
|
||||||
let is_show;
|
let is_show;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case "unsaved":
|
case "unsaved":
|
||||||
button_text = $t({defaultMessage: "Save changes"});
|
|
||||||
data_status = "unsaved";
|
data_status = "unsaved";
|
||||||
is_show = true;
|
is_show = true;
|
||||||
|
|
||||||
$element.find(".discard-button").show();
|
$element.find(".discard-button").show();
|
||||||
break;
|
break;
|
||||||
case "saved":
|
case "saved":
|
||||||
button_text = $t({defaultMessage: "Save changes"});
|
|
||||||
data_status = "";
|
data_status = "";
|
||||||
is_show = false;
|
is_show = false;
|
||||||
break;
|
break;
|
||||||
@@ -584,7 +582,6 @@ export function change_save_button_state($element: JQuery, state: string): void
|
|||||||
buttons.show_button_loading_indicator($save_button);
|
buttons.show_button_loading_indicator($save_button);
|
||||||
break;
|
break;
|
||||||
case "failed":
|
case "failed":
|
||||||
button_text = $t({defaultMessage: "Save changes"});
|
|
||||||
data_status = "failed";
|
data_status = "failed";
|
||||||
is_show = true;
|
is_show = true;
|
||||||
break;
|
break;
|
||||||
@@ -595,9 +592,23 @@ export function change_save_button_state($element: JQuery, state: string): void
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button_text !== undefined) {
|
requestAnimationFrame(() => {
|
||||||
|
// We need to use requestAnimationFrame to ensure that the
|
||||||
|
// button text and style are updated in the same frame.
|
||||||
$textEl.text(button_text);
|
$textEl.text(button_text);
|
||||||
}
|
if (state === "succeeded") {
|
||||||
|
buttons.modify_action_button_style($save_button, {
|
||||||
|
attention: "borderless",
|
||||||
|
intent: "success",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
buttons.modify_action_button_style($save_button, {
|
||||||
|
attention: "primary",
|
||||||
|
intent: "brand",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
assert(data_status !== undefined);
|
assert(data_status !== undefined);
|
||||||
$save_button.attr("data-status", data_status);
|
$save_button.attr("data-status", data_status);
|
||||||
if (state === "unsaved") {
|
if (state === "unsaved") {
|
||||||
|
|||||||
@@ -885,6 +885,10 @@ input.settings_text_input {
|
|||||||
&.hide {
|
&.hide {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.save-button[data-status="saved"] {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stream-privacy-type-icon {
|
.stream-privacy-type-icon {
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ mock_esm("../src/loading", {
|
|||||||
mock_esm("../src/buttons", {
|
mock_esm("../src/buttons", {
|
||||||
show_button_loading_indicator: noop,
|
show_button_loading_indicator: noop,
|
||||||
hide_button_loading_indicator: noop,
|
hide_button_loading_indicator: noop,
|
||||||
|
modify_action_button_style: noop,
|
||||||
});
|
});
|
||||||
mock_esm("../src/scroll_util", {scroll_element_into_container: noop});
|
mock_esm("../src/scroll_util", {scroll_element_into_container: noop});
|
||||||
set_global("document", "document-stub");
|
set_global("document", "document-stub");
|
||||||
|
|
||||||
|
set_global("requestAnimationFrame", (func) => func());
|
||||||
|
|
||||||
const settings_account = zrequire("settings_account");
|
const settings_account = zrequire("settings_account");
|
||||||
const settings_components = zrequire("settings_components");
|
const settings_components = zrequire("settings_components");
|
||||||
const settings_config = zrequire("settings_config");
|
const settings_config = zrequire("settings_config");
|
||||||
|
|||||||
Reference in New Issue
Block a user