diff --git a/frontend_tests/node_tests/gear_menu.js b/frontend_tests/node_tests/gear_menu.js new file mode 100644 index 0000000000..d6c1f6ea5a --- /dev/null +++ b/frontend_tests/node_tests/gear_menu.js @@ -0,0 +1,67 @@ +"use strict"; + +const {strict: assert} = require("assert"); + +const {zrequire} = require("../zjsunit/namespace"); +const {run_test} = require("../zjsunit/test"); +const {page_params} = require("../zjsunit/zpage_params"); + +const gear_menu = zrequire("gear_menu"); + +run_test("version_display_string", () => { + let expected_version_display_string; + + // An official release + page_params.zulip_version = "5.6"; + page_params.zulip_merge_base = "5.6"; + expected_version_display_string = "translated: Zulip Server 5.6"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // An official beta + page_params.zulip_version = "6.0-beta1"; + page_params.zulip_merge_base = "6.0-beta1"; + expected_version_display_string = "translated: Zulip Server 6.0-beta1"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // An official release candidate + page_params.zulip_version = "6.0-rc1"; + page_params.zulip_merge_base = "6.0-rc1"; + expected_version_display_string = "translated: Zulip Server 6.0-rc1"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // The Zulip development environment + page_params.zulip_version = "6.0-dev+git"; + page_params.zulip_merge_base = "6.0-dev+git"; + expected_version_display_string = "translated: Zulip Server dev environment"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // A commit on Zulip's main branch. + page_params.zulip_version = "6.0-dev-1976-g4bb381fc80"; + page_params.zulip_merge_base = "6.0-dev-1976-g4bb381fc80"; + expected_version_display_string = "translated: Zulip Server 6.0-dev"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // A fork with 18 commits beyond Zulip's main branch. + page_params.zulip_version = "6.0-dev-1994-g93730766b0"; + page_params.zulip_merge_base = "6.0-dev-1976-g4bb381fc80"; + expected_version_display_string = "translated: Zulip Server 6.0-dev (modified)"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // A commit from the Zulip 5.x branch + page_params.zulip_version = "5.6+git-4-g385a408be5"; + page_params.zulip_merge_base = "5.6+git-4-g385a408be5"; + expected_version_display_string = "translated: Zulip Server 5.6 (patched)"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // A fork with 3 commits beyond the Zulip 5.x branch. + page_params.zulip_version = "5.6+git-4-g385a408be5"; + page_params.zulip_merge_base = "5.6+git-7-abcda4235c2"; + expected_version_display_string = "translated: Zulip Server 5.6 (modified)"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); + + // A fork of a Zulip release commit, not on 5.x branch. + page_params.zulip_version = "5.3-1-g7ed896c0db"; + page_params.zulip_merge_base = "5.3"; + expected_version_display_string = "translated: Zulip Server 5.3 (modified)"; + assert.equal(gear_menu.version_display_string(), expected_version_display_string); +}); diff --git a/static/js/gear_menu.js b/static/js/gear_menu.js index 70ad0c492a..870f7f5691 100644 --- a/static/js/gear_menu.js +++ b/static/js/gear_menu.js @@ -98,8 +98,52 @@ export function update_org_settings_menu_item() { } } +export function version_display_string() { + const version = page_params.zulip_version; + const is_fork = page_params.zulip_merge_base && page_params.zulip_merge_base !== version; + + if (page_params.zulip_version.endsWith("-dev+git")) { + // The development environment uses this version string format. + return $t({defaultMessage: "Zulip Server dev environment"}); + } + + if (is_fork) { + // For forks, we want to describe the Zulip version this was + // forked from, and that it was modified. + const display_version = page_params.zulip_merge_base + .replace(/\+git.*/, "") + .replace(/-dev.*/, "-dev"); + return $t({defaultMessage: "Zulip Server {display_version} (modified)"}, {display_version}); + } + + // The below cases are all for official versions; either a + // release, or Git commit from one of Zulip's official branches. + + if (version.includes("+git")) { + // A version from a Zulip official maintenance branch such as 5.x. + const display_version = version.replace(/\+git.*/, ""); + return $t({defaultMessage: "Zulip Server {display_version} (patched)"}, {display_version}); + } + + const display_version = version.replace(/\+git.*/, "").replace(/-dev.*/, "-dev"); + return $t({defaultMessage: "Zulip Server {display_version}"}, {display_version}); +} + export function initialize() { const rendered_gear_menu = render_gear_menu({ + realm_name: page_params.realm_name, + realm_uri: new URL(page_params.realm_uri).hostname, + is_owner: page_params.is_owner, + is_admin: page_params.is_admin, + is_self_hosted: page_params.realm_plan_type === 1, + is_plan_limited: page_params.realm_plan_type === 2, + is_plan_standard: page_params.realm_plan_type === 3, + is_plan_standard_sponsored_for_free: page_params.realm_plan_type === 4, + is_business_org: page_params.realm_org_type === 10, + is_education_org: page_params.realm_org_type === 30 || page_params.realm_org_type === 35, + standard_plan_name: "Zulip Cloud Standard", + server_needs_upgrade: page_params.server_needs_upgrade, + version_display_string: version_display_string(), apps_page_url: page_params.apps_page_url, can_invite_others_to_realm: settings_data.user_can_invite_others_to_realm(), corporate_enabled: page_params.corporate_enabled, diff --git a/static/styles/dark_theme.css b/static/styles/dark_theme.css index 40e76c2a1a..084bd4ca08 100644 --- a/static/styles/dark_theme.css +++ b/static/styles/dark_theme.css @@ -504,6 +504,10 @@ body.dark-theme { .light-theme { display: block; } + + .dropdown-menu a:hover { + color: hsl(0, 0%, 100%); + } } .nav .dropdown-menu::after, diff --git a/static/styles/zulip.css b/static/styles/zulip.css index 71a285b806..3bb5a2afbd 100644 --- a/static/styles/zulip.css +++ b/static/styles/zulip.css @@ -361,6 +361,59 @@ p.n-margin { } } +#gear-menu .dropdown-menu { + .org-name, + .org-url { + padding: 0 20px; + } + + .org-info { + text-align: center; + + a { + white-space: normal; + } + } + + .org-name { + font-size: large; + font-weight: bold; + } + + .org-url { + line-height: 100%; + color: hsl(0, 0%, 52%); + } + + .org-version { + padding-top: 3px; + white-space: normal; + } + + .org-upgrade { + color: hsl(226, 82%, 60%); + + a { + padding: 0; + } + } + + .org-plan, + .org-upgrade { + a { + line-height: 16px; + } + } + + .plan-separator { + line-height: 8px; + } + + .small-font-size { + font-size: 12px; + } +} + .app { width: 100%; height: 100%; diff --git a/static/templates/gear_menu.hbs b/static/templates/gear_menu.hbs index 2fcbe028c7..b603fa045b 100644 --- a/static/templates/gear_menu.hbs +++ b/static/templates/gear_menu.hbs @@ -8,6 +8,45 @@ view is a Bootstrap nav tab, even though we don't show the tab anymore --}} +
  • {{realm_name}}
  • +
  • {{realm_uri}}
  • + {{#if is_self_hosted }} +
  • + {{version_display_string}} +
  • + {{#if server_needs_upgrade }} +
  • + {{t 'Upgrade to the latest release' }} +
  • + {{/if}} + {{else}} +
  • + {{#if is_plan_limited }} + Zulip Cloud Free + {{else if is_plan_standard}} + Zulip Cloud Standard + {{else if is_plan_standard_sponsored_for_free}} + Zulip Cloud Standard, sponsored for free + {{/if}} +
  • + {{/if}} + {{#if (and is_plan_limited is_owner) }} +
  • + {{#tr}}Upgrade to {standard_plan_name}{{/tr}} +
  • + {{/if}} + {{#if is_plan_limited }} + {{#if is_education_org }} +
  • + {{t 'Request education pricing' }} +
  • + {{else if (not is_business_org) }} +
  • + {{t 'Request sponsorship' }} +
  • + {{/if}} + {{/if}} +