Repository: zulip/zulip

Issue:
Show info about organization and Zulip in gear menu
At present, it requires some digging to find a few key pieces of information about the Zulip organization one is viewing:

- Organization name
- Organization URL (if using the Desktop app)
- For Zulip Cloud, the plan that the organization on.
- For self-hosted Zulip, does the server need to be upgraded?  What's the version of the server, and what's the current release version?

We should address this by adding this information at the top of the gear settings menu.

- For all users: Show organization name and URL
- For all Zulip Cloud users: Show plan name with a link to `/plans`, e.g. "Zulip Cloud Free"
- For owners of Zulip Cloud Free orgs: Show "Upgrade to Zulip Cloud Standard" link to `/upgrade`
- For all self-hosted users:
   - Show Zulip server version (same as in the "About Zulip" widget); we'll need to test to make sure it looks reasonable for non-standard versions (e.g. forks, installs running off `main`).
   - If the server version is old, we should show an "Upgrade to the latest release (x.y)" linking to https://zulip.readthedocs.io/en/stable/production/upgrade-or-modify.html. We should probably show this link to all users, as server admins might not be owners/admins of the organization.

## Mockups
<img width="1552" alt="popover-menu" src="https://user-images.githubusercontent.com/2090066/172440944-5dc8ee48-908f-4642-beb7-9ec141128a29.png">

<img width="1552" alt="dark-inbox-01" src="https://user-images.githubusercontent.com/2090066/172440973-12639e2a-3f42-408d-b976-27b01498ecda.png">

<img width="1608" alt="selfhosted-upgrade" src="https://user-images.githubusercontent.com/2090066/172441028-c0ce417f-e3db-4542-845f-10ba3fab98df.png">

**CZO discussion threads:**
- [Design proposal (Zulip Cloud)](https://chat.zulip.org/#narrow/stream/101-design/topic/UI.20redesign.3A.20popover.20menu/near/1388585)
- [Server upgrade notice](https://chat.zulip.org/#narrow/stream/101-design/topic/server.20upgrade.20notice)




Discussion:

Resolving patch:
diff --git a/tools/lib/capitalization.py b/tools/lib/capitalization.py
--- a/tools/lib/capitalization.py
+++ b/tools/lib/capitalization.py
@@ -42,6 +42,7 @@
     r"Zephyr",
     r"Zoom",
     r"Zulip",
+    r"Zulip Server",
     r"Zulip Account Security",
     r"Zulip Security",
     r"Zulip Cloud Standard",


Test patch:
diff --git a/frontend_tests/node_tests/gear_menu.js b/frontend_tests/node_tests/gear_menu.js
new file mode 100644
--- /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);
+});