mirror of https://github.com/zulip/zulip.git
stream_settings: Add new "Stream details" section in General tab.
We want to make it easier to find stream details such as creator, creation date and stream id. The commit replaces the "Email address" section in General tab of stream overlay with a new section called "Stream details", "Email address" is now a field in this section. If the stream does not have a creator, we only show the stream creation date in creation details. Fixes: #25648.
This commit is contained in:
parent
6c63043130
commit
b524a2c1ea
|
@ -126,7 +126,7 @@ help center because they are primarily useful to API clients:
|
|||
|
||||
A user ID can be found by [viewing a user's profile][view-profile]
|
||||
in the web or desktop apps. A stream ID can be found when [browsing
|
||||
streams][browse-streams] in the web app via the URL.
|
||||
streams][browse-streams] in the web or desktop apps.
|
||||
|
||||
The operands for these search options must be encoded either as an
|
||||
integer ID or a JSON list of integer IDs. For example, to query
|
||||
|
|
|
@ -187,7 +187,7 @@ the integration will send direct messages to the bot's owner.
|
|||
!!! tip ""
|
||||
|
||||
A stream ID can be found when [browsing streams][browse-streams]
|
||||
in the web app via the URL.
|
||||
in the web or desktop apps.
|
||||
|
||||
### topic
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as color_data from "./color_data";
|
|||
import {FoldDict} from "./fold_dict";
|
||||
import {page_params} from "./page_params";
|
||||
import * as peer_data from "./peer_data";
|
||||
import type {User} from "./people";
|
||||
import * as people from "./people";
|
||||
import * as settings_config from "./settings_config";
|
||||
import * as settings_data from "./settings_data";
|
||||
|
@ -186,6 +187,14 @@ export function get_sub_by_id(stream_id: number): StreamSubscription | undefined
|
|||
return stream_info.get(stream_id);
|
||||
}
|
||||
|
||||
export function maybe_get_creator_details(creator_id: number | null): User | undefined {
|
||||
if (creator_id === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return people.get_user_by_id_assert_valid(creator_id);
|
||||
}
|
||||
|
||||
export function get_stream_id(name: string): number | undefined {
|
||||
// Note: Only use this function for situations where
|
||||
// you are comfortable with a user dealing with an
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
import * as hash_util from "./hash_util";
|
||||
import * as peer_data from "./peer_data";
|
||||
import type {User} from "./people";
|
||||
import * as settings_config from "./settings_config";
|
||||
import {current_user} from "./state_data";
|
||||
import * as stream_data from "./stream_data";
|
||||
import type {StreamSpecificNotificationSettings, StreamSubscription} from "./sub_store";
|
||||
import * as sub_store from "./sub_store";
|
||||
import * as timerender from "./timerender";
|
||||
import {user_settings} from "./user_settings";
|
||||
import * as util from "./util";
|
||||
|
||||
export type SettingsSubscription = StreamSubscription & {
|
||||
date_created_string: string;
|
||||
is_realm_admin: boolean;
|
||||
creator: User | undefined;
|
||||
is_creator: boolean;
|
||||
can_change_name_description: boolean;
|
||||
should_display_subscription_button: boolean;
|
||||
should_display_preview_button: boolean;
|
||||
|
@ -26,6 +31,14 @@ export function get_sub_for_settings(sub: StreamSubscription): SettingsSubscript
|
|||
return {
|
||||
...sub,
|
||||
|
||||
// We get timestamp in seconds from the API but timerender needs milliseconds.
|
||||
date_created_string: timerender.get_localized_date_or_time_for_format(
|
||||
new Date(sub.date_created * 1000),
|
||||
"dayofyear_year",
|
||||
),
|
||||
creator: stream_data.maybe_get_creator_details(sub.creator_id),
|
||||
|
||||
is_creator: sub.creator_id === current_user.user_id,
|
||||
is_realm_admin: current_user.is_admin,
|
||||
// Admin can change any stream's name & description either stream is public or
|
||||
// private, subscribed or unsubscribed.
|
||||
|
|
|
@ -11,6 +11,7 @@ export const enum StreamPostPolicy {
|
|||
|
||||
// These types are taken from the `zerver/lib/types.py`.
|
||||
export type Stream = {
|
||||
creator_id: number | null;
|
||||
date_created: number;
|
||||
description: string;
|
||||
first_message_id: number | null;
|
||||
|
|
|
@ -164,7 +164,8 @@
|
|||
|
||||
/* These pill are similar to .not-editable, but are meant to show
|
||||
profile cards when clicked. */
|
||||
.panel_user_list > .pill-container {
|
||||
.panel_user_list > .pill-container,
|
||||
.stream_creator_details > .display_only_pill {
|
||||
background-color: hsl(0deg 0% 0% / 7%);
|
||||
|
||||
&:hover {
|
||||
|
@ -191,6 +192,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
.stream_creator_details > .display_only_pill.inline_with_text_pill {
|
||||
padding: 0;
|
||||
|
||||
> .pill {
|
||||
margin: 0;
|
||||
align-items: baseline;
|
||||
|
||||
> .pill-image {
|
||||
/* Add line-height equal to height to mimic baseline alignment. */
|
||||
line-height: 20px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
> .pill-label {
|
||||
> .pill-value {
|
||||
padding: 0 5px;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
> .my_user_status {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
10%,
|
||||
90% {
|
||||
|
|
|
@ -950,7 +950,11 @@ h4.user_group_setting_subsection_title {
|
|||
}
|
||||
}
|
||||
|
||||
.stream-email-box {
|
||||
.stream_details_box {
|
||||
> .stream_details_subsection {
|
||||
margin: 0 0 10px; /* mimic paragraph spacing */
|
||||
}
|
||||
|
||||
.stream_email_address_error {
|
||||
vertical-align: top;
|
||||
margin-left: 15px;
|
||||
|
|
|
@ -75,22 +75,56 @@
|
|||
can_remove_subscribers_setting_widget_name="can_remove_subscribers_group" }}
|
||||
</div>
|
||||
{{/with}}
|
||||
<div class="stream-email-box" {{#unless can_access_stream_email}}style="display: none;"{{/unless}}>
|
||||
<div class="stream-email-box-header">
|
||||
<div class="stream_details_box">
|
||||
<div class="stream_details_box_header">
|
||||
<h3 class="stream_setting_subsection_title">
|
||||
{{t "Email address" }}
|
||||
{{> ../help_link_widget link="/help/message-a-stream-by-email" }}
|
||||
{{t "Stream details" }}
|
||||
</h3>
|
||||
<div class="stream_email_address_error alert-notification"></div>
|
||||
</div>
|
||||
<p>
|
||||
{{t "You can use email to send messages to Zulip streams."}}
|
||||
</p>
|
||||
<p>
|
||||
<button class="button rounded copy_email_button" type="button" name="button">
|
||||
{{#with sub}}
|
||||
<div class="stream_creator_details stream_details_subsection">
|
||||
{{#if creator}}
|
||||
{{#tr}}
|
||||
Created by <z-user></z-user> on <z-stream-date-created></z-stream-date-created>.
|
||||
{{#*inline "z-user"}}
|
||||
{{> ../user_display_only_pill
|
||||
is_inline=true
|
||||
user_id=creator.user_id
|
||||
img_src=creator.avatar_url
|
||||
display_value=creator.full_name
|
||||
is_current_user=is_creator }}
|
||||
{{/inline}}
|
||||
{{#*inline "z-stream-date-created"}}{{date_created_string}}{{/inline}}
|
||||
{{/tr}}
|
||||
{{else}}
|
||||
{{#tr}}
|
||||
Created on <z-stream-date-created></z-stream-date-created>.
|
||||
{{#*inline "z-stream-date-created"}}{{date_created_string}}{{/inline}}
|
||||
{{/tr}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="stream_details_subsection">
|
||||
{{t "Stream events"}}<br/>
|
||||
<a href="{{preview_url}}/topic/stream.20events">{{t "View events" }}</a>
|
||||
</div>
|
||||
<div class="stream_details_subsection">
|
||||
{{t "Stream ID"}}<br/>
|
||||
{{stream_id}}
|
||||
</div>
|
||||
{{/with}}
|
||||
{{#if can_access_stream_email}}
|
||||
<div class="input-group stream-email-box">
|
||||
<label for="copy_stream_email_button" class="title inline-block">Email address</label>
|
||||
<p class="field-hint">
|
||||
{{t "You can use email to send messages to Zulip streams."}}
|
||||
{{> ../help_link_widget link="/help/message-a-stream-by-email" }}
|
||||
</p>
|
||||
<button class="button small rounded copy_email_button" id="copy_stream_email_button" type="button">
|
||||
<span class="copy_button">{{t "Generate email address" }}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<span class="pill-container display_only_pill">
|
||||
<span class="pill-container display_only_pill {{#if is_inline}}inline_with_text_pill{{/if}}">
|
||||
<a data-user-id="{{user_id}}" class="view_user_profile pill" tabindex="0">
|
||||
{{#if img_src}}
|
||||
<img class="pill-image" src="{{img_src}}" />
|
||||
|
|
|
@ -46,6 +46,7 @@ exports.test_streams = {
|
|||
invite_only: false,
|
||||
stream_id: 101,
|
||||
date_created: fake_now,
|
||||
creator_id: null,
|
||||
first_message_id: 1,
|
||||
history_public_to_subscribers: false,
|
||||
is_announcement_only: false,
|
||||
|
@ -61,6 +62,7 @@ exports.test_streams = {
|
|||
invite_only: true,
|
||||
stream_id: 102,
|
||||
date_created: fake_then,
|
||||
creator_id: null,
|
||||
first_message_id: 1,
|
||||
history_public_to_subscribers: false,
|
||||
is_web_public: false,
|
||||
|
|
|
@ -326,6 +326,8 @@ test("admin_options", () => {
|
|||
is_muted: true,
|
||||
invite_only: false,
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
stream_data.add_sub(sub);
|
||||
return sub;
|
||||
|
@ -379,6 +381,8 @@ test("stream_settings", () => {
|
|||
subscribed: true,
|
||||
invite_only: false,
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
|
||||
const blue = {
|
||||
|
@ -388,6 +392,8 @@ test("stream_settings", () => {
|
|||
subscribed: false,
|
||||
invite_only: false,
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
|
||||
const amber = {
|
||||
|
@ -400,6 +406,8 @@ test("stream_settings", () => {
|
|||
stream_post_policy: settings_config.stream_post_policy_values.admins.code,
|
||||
message_retention_days: 10,
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
stream_data.add_sub(cinnamon);
|
||||
stream_data.add_sub(amber);
|
||||
|
@ -810,6 +818,25 @@ test("create_sub", () => {
|
|||
assert.equal(antarctica_sub.color, "#76ce90");
|
||||
});
|
||||
|
||||
test("creator_id", () => {
|
||||
people.add_active_user(test_user);
|
||||
|
||||
// When creator id is not a valid user id
|
||||
assert.throws(() => stream_data.maybe_get_creator_details(-1), {
|
||||
name: "Error",
|
||||
message: "Unknown user_id in get_by_user_id: -1",
|
||||
});
|
||||
|
||||
// When there is no creator
|
||||
assert.equal(stream_data.maybe_get_creator_details(null), undefined);
|
||||
|
||||
const creator_details = people.get_by_user_id(test_user.user_id);
|
||||
assert.deepStrictEqual(
|
||||
stream_data.maybe_get_creator_details(test_user.user_id),
|
||||
creator_details,
|
||||
);
|
||||
});
|
||||
|
||||
test("initialize", () => {
|
||||
function get_params() {
|
||||
const params = {};
|
||||
|
|
|
@ -50,6 +50,8 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
|||
stream_weekly_traffic: null,
|
||||
color: "red",
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
const poland = {
|
||||
elem: "poland",
|
||||
|
@ -61,6 +63,8 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
|||
stream_weekly_traffic: 13,
|
||||
color: "red",
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
const pomona = {
|
||||
elem: "pomona",
|
||||
|
@ -72,6 +76,8 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
|||
stream_weekly_traffic: 0,
|
||||
color: "red",
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
const cpp = {
|
||||
elem: "cpp",
|
||||
|
@ -83,6 +89,8 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
|||
stream_weekly_traffic: 6,
|
||||
color: "red",
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
const zzyzx = {
|
||||
elem: "zzyzx",
|
||||
|
@ -94,6 +102,8 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
|||
stream_weekly_traffic: 6,
|
||||
color: "red",
|
||||
can_remove_subscribers_group: admins_group.id,
|
||||
date_created: 1691057093,
|
||||
creator_id: null,
|
||||
};
|
||||
|
||||
const sub_row_data = [denmark, poland, pomona, cpp, zzyzx];
|
||||
|
|
Loading…
Reference in New Issue