From eb78264162006bbcd73f2676881466a54dcad8be Mon Sep 17 00:00:00 2001 From: Joelute Date: Fri, 11 Aug 2023 13:46:58 -0400 Subject: [PATCH] navbar_alerts: Delay showing "Complete the organization profile" banner. Currently, we are displaying the "Complete the organization profile" banner immediately after the organization was created. It's important to strongly encourage orgs to configure their profile, so we should delay showing the banner if the profile has not been configured after 15 days. Thus also allows the users to check out Zulip and see how it works before configuring the organization settings. Fixes: #24122. --- api_docs/changelog.md | 5 +++++ web/src/navbar_alerts.js | 4 ++++ web/src/timerender.ts | 11 +++++++++++ web/tests/navbar_alerts.test.js | 6 +++++- web/tests/timerender.test.js | 14 ++++++++++++++ zerver/lib/events.py | 1 + zerver/openapi/zulip.yaml | 7 +++++++ zerver/tests/test_home.py | 1 + 8 files changed, 48 insertions(+), 1 deletion(-) diff --git a/api_docs/changelog.md b/api_docs/changelog.md index 5fc916383a..676e62d7dd 100644 --- a/api_docs/changelog.md +++ b/api_docs/changelog.md @@ -20,6 +20,11 @@ format used by the Zulip server that they are interacting with. ## Changes in Zulip 8.0 +**Feature level 203** + +* [`POST /register`](/api/register-queue): Add + `realm_date_created` field to realm data. + **Feature level 202** * [`PATCH /realm/linkifiers`](/api/reorder-linkifiers): Added new endpoint diff --git a/web/src/navbar_alerts.js b/web/src/navbar_alerts.js index 4aa9e088a4..c292f39ed7 100644 --- a/web/src/navbar_alerts.js +++ b/web/src/navbar_alerts.js @@ -15,6 +15,7 @@ import * as keydown_util from "./keydown_util"; import {localstorage} from "./localstorage"; import * as notifications from "./notifications"; import {page_params} from "./page_params"; +import {should_display_profile_incomplete_alert} from "./timerender"; import * as unread from "./unread"; import * as unread_ops from "./unread_ops"; import * as unread_ui from "./unread_ui"; @@ -96,6 +97,9 @@ export function check_profile_incomplete() { if (!page_params.is_admin) { return false; } + if (!should_display_profile_incomplete_alert(page_params.realm_date_created)) { + return false; + } // Eventually, we might also check page_params.realm_icon_source, // but it feels too aggressive to ask users to do change that diff --git a/web/src/timerender.ts b/web/src/timerender.ts index 1edde3402e..c8d2569b6c 100644 --- a/web/src/timerender.ts +++ b/web/src/timerender.ts @@ -490,3 +490,14 @@ export function get_time_limit_setting_in_appropriate_unit( const time_limit_in_days = Math.floor(time_limit_in_hours / 24); return {value: time_limit_in_days, unit: "day"}; } + +export function should_display_profile_incomplete_alert(timestamp: number): boolean { + const today = new Date(Date.now()); + const time = new Date(timestamp); + const days_old = differenceInCalendarDays(today, time); + + if (days_old >= 15) { + return true; + } + return false; +} diff --git a/web/tests/navbar_alerts.test.js b/web/tests/navbar_alerts.test.js index 4aebaa7e8e..5d3c52379c 100644 --- a/web/tests/navbar_alerts.test.js +++ b/web/tests/navbar_alerts.test.js @@ -12,6 +12,7 @@ page_params.is_spectator = false; const notifications = mock_esm("../src/notifications"); const util = mock_esm("../src/util"); +const timerender = mock_esm("../src/timerender"); const {localstorage} = zrequire("localstorage"); const navbar_alerts = zrequire("navbar_alerts"); @@ -62,7 +63,10 @@ test("allow_notification_alert", ({disallow, override}) => { assert.equal(navbar_alerts.should_show_notifications(ls), false); }); -test("profile_incomplete_alert", () => { +test("profile_incomplete_alert", ({override}) => { + // Don't test time related conditions + override(timerender, "should_display_profile_incomplete_alert", () => true); + // Show alert. page_params.is_admin = true; page_params.realm_description = "Organization imported from Slack!"; diff --git a/web/tests/timerender.test.js b/web/tests/timerender.test.js index 809f08a7de..3eed481ac5 100644 --- a/web/tests/timerender.test.js +++ b/web/tests/timerender.test.js @@ -597,3 +597,17 @@ run_test("set_full_datetime", () => { expected = "10:52 AM"; assert.equal(time_str, expected); }); + +run_test("should_display_profile_incomplete_alert", () => { + // Organization created < 15 days ago + let realm_date_created = new Date(); + realm_date_created.setDate(realm_date_created.getDate() - 5); + + assert.equal(timerender.should_display_profile_incomplete_alert(realm_date_created), false); + + // Organization created > 15 days ago + realm_date_created = new Date(); + realm_date_created.setDate(realm_date_created.getDate() - 15); + + assert.equal(timerender.should_display_profile_incomplete_alert(realm_date_created), true); +}); diff --git a/zerver/lib/events.py b/zerver/lib/events.py index 8020d6c9ef..27a5888744 100644 --- a/zerver/lib/events.py +++ b/zerver/lib/events.py @@ -359,6 +359,7 @@ def fetch_initial_state_data( state["demo_organization_scheduled_deletion_date"] = datetime_to_timestamp( realm.demo_organization_scheduled_deletion_date ) + state["realm_date_created"] = datetime_to_timestamp(realm.date_created) # Presence system parameters for client behavior. state["server_presence_ping_interval_seconds"] = settings.PRESENCE_PING_INTERVAL_SECS diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 8121958f08..3165f2e8db 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -11195,6 +11195,13 @@ paths: type: string description: | The name of the custom profile field type. + realm_date_created: + type: integer + description: | + The UNIX timestamp (UTC) for when the organization was + created. + + **Changes**: New in Zulip 8.0 (feature level 203). demo_organization_scheduled_deletion_date: type: integer description: | diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py index 98dcea61d7..b1521e194e 100644 --- a/zerver/tests/test_home.py +++ b/zerver/tests/test_home.py @@ -118,6 +118,7 @@ class HomeTest(ZulipTestCase): "realm_create_private_stream_policy", "realm_create_public_stream_policy", "realm_create_web_public_stream_policy", + "realm_date_created", "realm_default_code_block_language", "realm_default_external_accounts", "realm_default_language",