mirror of https://github.com/zulip/zulip.git
parent
b859cc4a3d
commit
379c6acbea
|
@ -9,6 +9,7 @@ from corporate.views.event_status import event_status, event_status_page
|
|||
from corporate.views.portico import (
|
||||
app_download_link_redirect,
|
||||
apps_view,
|
||||
communities_view,
|
||||
hello_view,
|
||||
landing_view,
|
||||
plans_view,
|
||||
|
@ -125,6 +126,7 @@ landing_page_urls = [
|
|||
landing_view,
|
||||
{"template_name": "corporate/case-studies/recurse-center-case-study.html"},
|
||||
),
|
||||
path("communities/", communities_view),
|
||||
]
|
||||
i18n_urlpatterns += landing_page_urls
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ from django.template.response import TemplateResponse
|
|||
from zerver.context_processors import get_realm_from_request, latest_info_context
|
||||
from zerver.decorator import add_google_analytics
|
||||
from zerver.lib.github import InvalidPlatform, get_latest_github_release_download_link_for_platform
|
||||
from zerver.lib.realm_description import get_realm_text_description
|
||||
from zerver.lib.realm_icon import get_realm_icon_url
|
||||
from zerver.lib.subdomains import is_subdomain_root_or_alias
|
||||
from zerver.models import Realm
|
||||
|
||||
|
@ -103,3 +105,47 @@ def landing_view(request: HttpRequest, template_name: str) -> HttpResponse:
|
|||
@add_google_analytics
|
||||
def hello_view(request: HttpRequest) -> HttpResponse:
|
||||
return TemplateResponse(request, "corporate/hello.html", latest_info_context())
|
||||
|
||||
|
||||
@add_google_analytics
|
||||
def communities_view(request: HttpRequest) -> HttpResponse:
|
||||
eligible_realms = []
|
||||
unique_org_type_ids = set()
|
||||
want_to_be_advertised_realms = Realm.objects.filter(
|
||||
want_advertise_in_communities_directory=True
|
||||
).order_by("name")
|
||||
for realm in want_to_be_advertised_realms:
|
||||
if realm.allow_web_public_streams_access():
|
||||
eligible_realms.append(
|
||||
{
|
||||
"id": realm.id,
|
||||
"name": realm.name,
|
||||
"realm_url": realm.uri,
|
||||
"logo_url": get_realm_icon_url(realm),
|
||||
"description": get_realm_text_description(realm),
|
||||
"org_type_key": [
|
||||
org_type
|
||||
for org_type in Realm.ORG_TYPES
|
||||
if Realm.ORG_TYPES[org_type]["id"] == realm.org_type
|
||||
][0],
|
||||
}
|
||||
)
|
||||
unique_org_type_ids.add(realm.org_type)
|
||||
|
||||
# Remove org_types for which there are no open organizations.
|
||||
org_types = dict()
|
||||
for org_type in Realm.ORG_TYPES:
|
||||
if Realm.ORG_TYPES[org_type]["id"] in unique_org_type_ids:
|
||||
org_types[org_type] = Realm.ORG_TYPES[org_type]
|
||||
|
||||
# Remove `Unspecified` ORG_TYPE
|
||||
org_types.pop("unspecified", None)
|
||||
|
||||
return TemplateResponse(
|
||||
request,
|
||||
"corporate/communities.html",
|
||||
context={
|
||||
"eligible_realms": eligible_realms,
|
||||
"org_types": org_types,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import $ from "jquery";
|
||||
|
||||
function sync_open_organizations_page_with_current_hash() {
|
||||
const hash = window.location.hash;
|
||||
if (!hash || hash === "#all" || hash === "#undefined") {
|
||||
$(".eligible_realm").show();
|
||||
$(".realm-category").removeClass("selected");
|
||||
$(`[data-category="all"]`).addClass("selected");
|
||||
} else {
|
||||
$(".eligible_realm").hide();
|
||||
$(`.eligible_realm[data-org-type="${CSS.escape(hash.slice(1))}"]`).show();
|
||||
$(".realm-category").removeClass("selected");
|
||||
$(`[data-category="${CSS.escape(hash.slice(1))}"]`).addClass("selected");
|
||||
}
|
||||
}
|
||||
|
||||
// init
|
||||
$(() => {
|
||||
sync_open_organizations_page_with_current_hash();
|
||||
$(window).on("hashchange", () => {
|
||||
sync_open_organizations_page_with_current_hash();
|
||||
});
|
||||
});
|
|
@ -342,7 +342,8 @@ $category-text: hsl(219, 23%, 33%);
|
|||
font-weight: 400;
|
||||
}
|
||||
|
||||
.integration-category {
|
||||
.integration-category,
|
||||
.realm-category {
|
||||
font-size: 0.85em;
|
||||
margin-top: 5px;
|
||||
font-weight: 400;
|
||||
|
@ -390,7 +391,8 @@ $category-text: hsl(219, 23%, 33%);
|
|||
font-size: 1em;
|
||||
}
|
||||
|
||||
.integration-category {
|
||||
.integration-category,
|
||||
.realm-category {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +418,8 @@ $category-text: hsl(219, 23%, 33%);
|
|||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.integration-category {
|
||||
.integration-category,
|
||||
.realm-category {
|
||||
font-size: 0.77em;
|
||||
}
|
||||
}
|
||||
|
@ -465,7 +468,8 @@ $category-text: hsl(219, 23%, 33%);
|
|||
margin: 0 21px 20px;
|
||||
order: 1;
|
||||
|
||||
.integration-category {
|
||||
.integration-category,
|
||||
.realm-category {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -501,7 +505,8 @@ $category-text: hsl(219, 23%, 33%);
|
|||
.categories {
|
||||
order: 2;
|
||||
|
||||
.integration-category {
|
||||
.integration-category,
|
||||
.realm-category {
|
||||
font-size: 0.9em;
|
||||
font-weight: 400;
|
||||
padding: 6px 3px;
|
||||
|
@ -585,3 +590,89 @@ $category-text: hsl(219, 23%, 33%);
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.portico-landing.integrations.communities {
|
||||
.main {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.portico-page-heading {
|
||||
color: hsl(0, 0%, 0%);
|
||||
font-size: 44px;
|
||||
}
|
||||
|
||||
.portico-page-subheading {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: hsl(0, 0%, 20%);
|
||||
max-width: 340px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.integration-categories-sidebar h3 {
|
||||
color: hsl(0, 0%, 0%);
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.catalog {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.eligible_realms {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
|
||||
.eligible_realm {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid hsl(167, 34%, 56%);
|
||||
}
|
||||
|
||||
.eligible_realm_logo {
|
||||
display: flex;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.eligible_realm_details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.eligible_realm_name {
|
||||
font-weight: 400;
|
||||
font-size: 21px;
|
||||
color: hsl(220.6, 20%, 33.3%);
|
||||
line-height: 23px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.eligible_realm_description {
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: hsl(220, 2.7%, 56.5%);
|
||||
line-height: 19px;
|
||||
margin: 0;
|
||||
width: min(600px, 50vw);
|
||||
/* For restricting text to only two lines.
|
||||
See https://caniuse.com/?search=display%3A%20-webkit-box for support. */
|
||||
overflow: hidden;
|
||||
display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.eligible_realm_end_notice {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
{% extends "zerver/portico.html" %}
|
||||
{% set entrypoint = "communities" %}
|
||||
|
||||
{% block customhead %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
{% endblock %}
|
||||
|
||||
{% block hello_page_container %} hello-main{% endblock %}
|
||||
|
||||
{% block portico_content %}
|
||||
|
||||
{% include 'zerver/landing_nav.html' %}
|
||||
{% include 'zerver/gradients.html' %}
|
||||
|
||||
<div class="portico-landing integrations communities">
|
||||
<div class="main">
|
||||
<div class="padded-content">
|
||||
<div class="inner-content">
|
||||
|
||||
<div class="integration-main-text">
|
||||
<header>
|
||||
<h1 class="portico-page-heading">
|
||||
{% trans %}Open communities directory{% endtrans %}
|
||||
</h1>
|
||||
<p class="portico-page-subheading">
|
||||
These Zulip communities are open to the public, and have
|
||||
<a href="/help/communities-directory">asked to be listed</a>.
|
||||
</p>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div class="integration-categories-dropdown">
|
||||
<div class="dropdown-toggle">
|
||||
<h3 class="dropdown-category-label">{% trans %}Filter by category{% endtrans %}</h3>
|
||||
<i class="fa fa-angle-down" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="dropdown-list">
|
||||
<a href="#all">
|
||||
<h4 class="realm-category selected" data-category="all">All</h4>
|
||||
</a>
|
||||
{% for org_type in org_types.keys() %}
|
||||
<a href="#{{ org_type }}">
|
||||
<h4 class="realm-category" data-category="{{ org_type }}">
|
||||
{{ org_types[org_type]["name"] }}
|
||||
</h4>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="catalog">
|
||||
<div class="integration-categories-sidebar">
|
||||
<h3>{% trans %}Categories{% endtrans %}</h3>
|
||||
<a href="#all">
|
||||
<h4 data-category="all" class="realm-category selected">{% trans %}All{% endtrans %}</h4>
|
||||
</a>
|
||||
{% for org_type in org_types.keys() %}
|
||||
<a href="#{{ org_type }}">
|
||||
<h4 data-category="{{ org_type }}" class="realm-category">
|
||||
{{ org_types[org_type]["name"] }}
|
||||
</h4>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="eligible_realms">
|
||||
{% for eligible_realm in eligible_realms %}
|
||||
<a class="eligible_realm" data-org-type="{{ eligible_realm.org_type_key }}" href="{{ eligible_realm.realm_url }}">
|
||||
<img class="eligible_realm_logo" src="{{ eligible_realm.logo_url }}" alt="{{ eligible_realm.name }} logo"/>
|
||||
<div class="eligible_realm_details">
|
||||
<h3 class="eligible_realm_name">{{ eligible_realm.name }}</h3>
|
||||
<h4 class="eligible_realm_description">
|
||||
{{ eligible_realm.description }}
|
||||
</h4>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
<hr />
|
||||
<div class="eligible_realm_end_notice">
|
||||
<p>Learn how Zulip can be a <a href="/for/communities">home for your community</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- .inner-content -->
|
||||
</div> <!-- .padded-content -->
|
||||
</div> <!-- .main -->
|
||||
</div> <!-- .portico-landing -->
|
||||
|
||||
{% endblock %}
|
|
@ -57,6 +57,12 @@
|
|||
"./static/styles/portico/landing_page.css",
|
||||
"./static/styles/portico/integrations.css"
|
||||
],
|
||||
"communities": [
|
||||
"./static/js/bundles/portico",
|
||||
"./static/js/portico/communities",
|
||||
"./static/styles/portico/landing_page.css",
|
||||
"./static/styles/portico/integrations.css"
|
||||
],
|
||||
"signup": ["./static/js/bundles/portico", "jquery-validation", "./static/js/portico/signup"],
|
||||
"register": ["./static/js/bundles/portico", "jquery-validation", "./static/js/portico/signup"],
|
||||
"confirm-preregistrationuser": [
|
||||
|
|
|
@ -199,6 +199,13 @@ class DocPageTest(ZulipTestCase):
|
|||
result = self.client_get("/for/companies/", follow=True)
|
||||
self.assert_in_success_response(["Communication efficiency represents"], result)
|
||||
|
||||
def test_open_organizations_endpoint(self) -> None:
|
||||
realm = get_realm("zulip")
|
||||
realm.want_advertise_in_communities_directory = True
|
||||
realm.save()
|
||||
|
||||
self._test("/communities/", "Open communities directory")
|
||||
|
||||
def test_portico_pages_open_graph_metadata(self) -> None:
|
||||
# Why Zulip
|
||||
url = "/why-zulip/"
|
||||
|
|
Loading…
Reference in New Issue