diff --git a/static/js/invite.js b/static/js/invite.js index a336c11963..88339d4090 100644 --- a/static/js/invite.js +++ b/static/js/invite.js @@ -34,7 +34,15 @@ function reset_error_messages() { function get_common_invitation_data() { const invite_as = Number.parseInt($("#invite_as").val(), 10); - const expires_in = Number.parseFloat($("#expires_in").val()); + let expires_in = $("#expires_in").val(); + + // See settings_config.expires_in_values for why we do this conversion. + if (expires_in === "null") { + expires_in = JSON.stringify(null); + } else { + expires_in = Number.parseFloat($("#expires_in").val()); + } + const stream_ids = []; $("#invite-stream-checkboxes input:checked").each(function () { const stream_id = Number.parseInt($(this).val(), 10); diff --git a/static/js/settings_config.ts b/static/js/settings_config.ts index 1526c44ef2..b4611b979c 100644 --- a/static/js/settings_config.ts +++ b/static/js/settings_config.ts @@ -467,12 +467,15 @@ export const expires_in_values = { description: $t({defaultMessage: "30 days"}), default: false, }, - // Backend support for this configuration is not available yet. - // never: { - // value: "never", - // description: $t({defaultMessage: "Never expires"}), - // default: false, - // } + never: { + // Ideally we'd just store `null`, not the string `"null"`, but + // .val() will read null back as `""`. Custom logic in + // get_common_invitation_data converts this back to `null` + // before sending to the server. + value: "null", + description: $t({defaultMessage: "Never expires"}), + default: false, + }, }; const user_role_array = Object.values(user_role_values); diff --git a/static/js/settings_invites.js b/static/js/settings_invites.js index 43cc8b8e26..bb23cef7a2 100644 --- a/static/js/settings_invites.js +++ b/static/js/settings_invites.js @@ -62,7 +62,9 @@ function populate_invites(invites_data) { name: "admin_invites_list", modifier(item) { item.invited_absolute_time = timerender.absolute_time(item.invited * 1000); - item.expiry_date_absolute_time = timerender.absolute_time(item.expiry_date * 1000); + if (item.expiry_date !== null) { + item.expiry_date_absolute_time = timerender.absolute_time(item.expiry_date * 1000); + } item.is_admin = page_params.is_admin; item.disable_buttons = item.invited_as === settings_config.user_role_values.owner.code && diff --git a/static/templates/settings/admin_invites_list.hbs b/static/templates/settings/admin_invites_list.hbs index 3cfe948764..a68c9493c8 100644 --- a/static/templates/settings/admin_invites_list.hbs +++ b/static/templates/settings/admin_invites_list.hbs @@ -22,7 +22,11 @@ {{invited_absolute_time}} + {{#if expiry_date_absolute_time}} {{expiry_date_absolute_time}} + {{else}} + {{t "Never expires"}} + {{/if}} {{invited_as_text}}