fix(admin): save premium limits and model changes (#3386)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-11 13:26:39 +02:00
1 parent 7d2c51a57f
commit 6acd7f3d22
18 files changed
+1035 -59

No files matched your search

@@ -151,6 +151,10 @@ pub fn danger_button(label: &str) -> Markup {
button_markup(label, "submit", DANGER_BUTTON_CLASS)
}
pub fn secondary_button(label: &str) -> Markup {
button_markup(label, "submit", SECONDARY_BUTTON_CLASS)
}
pub fn form_field_group(
label: &str,
name: &str,
@@ -9,7 +9,7 @@ use crate::{
ExperimentDeliveryConfigResponse, GatewayRolloutConfigResponse, InstanceConfigResponse,
InstanceIntegrationsResponse, InstanceMediaResponse, InstancePolicyResponse,
InstanceRegistrationResponse, LimitConfigResponse, PendingRegistrationResponse,
PushRelayConfigResponse, RegistrationUrlResponse, SsoConfigResponse, TagStyle,
PremiumMode, PushRelayConfigResponse, RegistrationUrlResponse, SsoConfigResponse, TagStyle,
VOICE_P2P_DEFAULT_SALT, VOICE_P2P_MAX_PARTICIPANTS_RANGE, VoiceP2pConfigResponse,
},
config::AdminConfig,
@@ -158,6 +158,7 @@ pub fn instance_config_page(
csrf_token,
&instance_config.policy,
&instance_config.app_public.branding.premium_product_name,
instance_config.billing.enabled == Some(true),
))
},
))
@@ -264,6 +265,7 @@ fn policy_config_section(
csrf_token: &str,
policy: &InstancePolicyResponse,
premium_name: &str,
billing_enabled: bool,
) -> Markup {
section_card_with_description(
"Community & Policy",
@@ -274,7 +276,7 @@ fn policy_config_section(
div class="space-y-8" {
(single_community_form(base, csrf_token, policy))
(direct_messages_form(base, csrf_token, policy))
(premium_mode_form(base, csrf_token, policy, premium_name))
(premium_mode_form(base, csrf_token, policy, premium_name, billing_enabled))
(community_creation_form(base, csrf_token, policy))
(services_form(base, csrf_token, policy))
}
@@ -373,6 +375,7 @@ fn premium_mode_form(
csrf_token: &str,
policy: &InstancePolicyResponse,
premium_name: &str,
billing_enabled: bool,
) -> Markup {
let mirror_label = format!("Mirror (Free and {premium_name} tiers)");
let everyone_label = format!("Everyone (every member gets {premium_name} limits)");
@@ -386,6 +389,16 @@ fn premium_mode_form(
("mirror", mirror_label.as_str()),
("everyone", everyone_label.as_str()),
], policy.premium_mode.as_str()))
p class="text-xs text-neutral-500" {
"Limits you have not edited follow the model. Limits you changed under Limit \
Config keep your values in both models."
}
@if billing_enabled && matches!(policy.premium_mode, PremiumMode::Mirror) {
p class="text-sm text-amber-700" {
"Billing is enabled. Disable it under Premium & billing before switching \
the premium model to Everyone."
}
}
(form_actions(html! {
(submit_button("Save premium model"))
}))
@@ -8,7 +8,10 @@ use crate::{
middleware::auth::AuthContext,
templates::{
components::{
form::{FORM_INPUT_CLASS, csrf_input, danger_button, form_actions, submit_button},
form::{
FORM_INPUT_CLASS, csrf_input, danger_button, form_actions, secondary_button,
submit_button,
},
page_container::{card_with_header, page_header},
tooltip,
},
@@ -81,7 +84,7 @@ fn render_limit_page(
div class="space-y-6" {
(rule_tabs(config, &rules, active_rule_id, can_update))
@if let Some(rule) = active_rule {
(rule_header(config, csrf_token, rule, can_update))
(rule_header(&config.base_path, csrf_token, rule, can_update, response.defaults.contains_key(&rule.id)))
(rule_editor(config, csrf_token, response, rule, can_update))
} @else {
div class="rounded-lg border border-neutral-200 bg-white p-4 shadow-sm" {
@@ -151,11 +154,18 @@ fn rule_tabs(
}
fn rule_header(
config: &AdminConfig,
base: &str,
csrf_token: &str,
rule: &LimitRule,
can_update: bool,
has_defaults: bool,
) -> Markup {
let can_reset = can_update
&& has_defaults
&& rule
.modified_fields
.as_ref()
.is_some_and(|fields| !fields.is_empty());
card_with_header(
"",
html! {
@@ -176,11 +186,20 @@ fn rule_header(
}
}
}
@if can_update && rule.id != "default" {
form method="post"
action={(config.base_path) "/limit-config?action=delete&rule=" (rule.id)} {
(csrf_input(csrf_token))
(danger_button("Delete Rule"))
div class="flex flex-wrap gap-2" {
@if can_reset {
form method="post"
action={(base) "/limit-config?action=reset&rule=" (rule.id)} {
(csrf_input(csrf_token))
(secondary_button("Reset to Defaults"))
}
}
@if can_update && rule.id != "default" {
form method="post"
action={(base) "/limit-config?action=delete&rule=" (rule.id)} {
(csrf_input(csrf_token))
(danger_button("Delete Rule"))
}
}
}
}
@@ -550,6 +550,10 @@ fn traits_form(
class="w-full rounded-lg border border-neutral-300 bg-white px-3 py-1.5 text-sm text-neutral-900 placeholder:text-neutral-400 focus:border-brand-primary focus:outline-none focus:ring-2 focus:ring-brand-primary/20" {
(custom_traits.join("\n"))
}
p class="text-neutral-500 text-xs" {
"The premium trait follows each member's subscription or gift and cannot be \
assigned here."
}
}
(form_actions(html! {
(submit_button("Save Traits"))