mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
groups-ui: Add option to copy membership from group.
Instead of adding group as a subgroup, we now provide option to add direct members and direct subgroups of a group to a user group by providing an expand button in the group pill. Fixes #32335.
This commit is contained in:
@@ -283,6 +283,11 @@ Source: https://lucide.dev/icons/plus
|
||||
Copyright: 2013-2022 Cole Bemis
|
||||
License: ISC License
|
||||
|
||||
Files: web/shared/icons/expand-both-diagonals.svg
|
||||
Source: https://lucide.dev/icons/expand
|
||||
Copyright: 2013-2022 Cole Bemis
|
||||
License: ISC License
|
||||
|
||||
Files: web/third/bootstrap/css/bootstrap.app.css
|
||||
Copyright: 2012 Twitter, Inc.
|
||||
License: Apache-2.0
|
||||
|
10
web/shared/icons/expand-both-diagonals.svg
Normal file
10
web/shared/icons/expand-both-diagonals.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 15,14 a 1,1 0 0 0 -0.707031,0.292969 1,1 0 0 0 0,1.414062 l 6,6 a 1,1 0 0 0 1.414062,0 1,1 0 0 0 0,-1.414062 l -6,-6 A 1,1 0 0 0 15,14 Z" />
|
||||
<path d="m 20.292969,2.2929688 -6,6 a 1,1 0 0 0 0,1.4140625 1,1 0 0 0 1.414062,0 l 6,-6 a 1,1 0 0 0 0,-1.4140625 1,1 0 0 0 -1.414062,0 z" />
|
||||
<path d="m 21,15.199219 a 1,1 0 0 0 -1,1 V 20 h -3.800781 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 H 21 a 1.0001,1.0001 0 0 0 1,-1 v -4.800781 a 1,1 0 0 0 -1,-1 z" />
|
||||
<path d="m 16.199219,2 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 H 20 v 3.8007812 a 1,1 0 0 0 1,1.0000001 1,1 0 0 0 1,-1.0000001 V 3 A 1.0001,1.0001 0 0 0 21,2 Z" />
|
||||
<path d="m 3,15.199219 a 1,1 0 0 0 -1,1 V 21 a 1.0001,1.0001 0 0 0 1,1 H 7.8007812 A 1,1 0 0 0 8.8007813,21 1,1 0 0 0 7.8007812,20 H 4 v -3.800781 a 1,1 0 0 0 -1,-1 z" />
|
||||
<path d="m 9,14 a 1,1 0 0 0 -0.7070312,0.292969 l -6,6 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140625,0 l 6,-6 a 1,1 0 0 0 0,-1.414062 A 1,1 0 0 0 9,14 Z" />
|
||||
<path d="M 3,2 A 1.0001,1.0001 0 0 0 2,3 V 7.8007812 A 1,1 0 0 0 3,8.8007813 1,1 0 0 0 4,7.8007812 V 4 H 7.8007812 A 1,1 0 0 0 8.8007813,3 1,1 0 0 0 7.8007812,2 Z" />
|
||||
<path d="m 3,2 a 1,1 0 0 0 -0.7070312,0.2929688 1,1 0 0 0 0,1.4140625 l 6,6 a 1,1 0 0 0 1.4140625,0 1,1 0 0 0 0,-1.4140625 l -6,-6 A 1,1 0 0 0 3,2 Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@@ -3,6 +3,7 @@ import assert from "minimalistic-assert";
|
||||
import * as add_subscribers_pill from "./add_subscribers_pill.ts";
|
||||
import * as input_pill from "./input_pill.ts";
|
||||
import * as keydown_util from "./keydown_util.ts";
|
||||
import * as people from "./people.ts";
|
||||
import type {User} from "./people.ts";
|
||||
import * as stream_pill from "./stream_pill.ts";
|
||||
import type {CombinedPill, CombinedPillContainer} from "./typeahead_helper.ts";
|
||||
@@ -24,6 +25,30 @@ function get_pill_group_ids(pill_widget: CombinedPillContainer): number[] {
|
||||
return group_user_ids;
|
||||
}
|
||||
|
||||
function expand_group_pill($pill_elem: JQuery, pill_widget: CombinedPillContainer): void {
|
||||
const group_id = Number.parseInt($pill_elem.attr("data-user-group-id")!, 10);
|
||||
const group = user_groups.get_user_group_from_id(group_id);
|
||||
const direct_subgroup_ids = group.direct_subgroup_ids;
|
||||
const direct_member_ids = group.members;
|
||||
|
||||
const taken_group_ids = user_group_pill.get_group_ids(pill_widget);
|
||||
const taken_user_ids = user_pill.get_user_ids(pill_widget);
|
||||
|
||||
for (const member_id of direct_member_ids) {
|
||||
if (!taken_user_ids.includes(member_id)) {
|
||||
const user = people.get_by_user_id(member_id);
|
||||
user_pill.append_user(user, pill_widget, false);
|
||||
}
|
||||
}
|
||||
|
||||
for (const group_id of direct_subgroup_ids) {
|
||||
if (!taken_group_ids.includes(group_id)) {
|
||||
const subgroup = user_groups.get_user_group_from_id(group_id);
|
||||
user_group_pill.append_user_group(subgroup, pill_widget, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function create_item_from_text(
|
||||
text: string,
|
||||
current_items: CombinedPill[],
|
||||
@@ -42,6 +67,8 @@ export function create_item_from_text(
|
||||
const group_item = user_group_pill.create_item_from_group_name(text, current_items);
|
||||
if (group_item) {
|
||||
const subgroup = user_groups.get_user_group_from_id(group_item.group_id);
|
||||
group_item.show_expand_button =
|
||||
subgroup.members.size > 0 || subgroup.direct_subgroup_ids.size > 0;
|
||||
const current_group_id = user_group_components.active_group_id;
|
||||
assert(current_group_id !== undefined);
|
||||
const current_group = user_groups.get_user_group_from_id(current_group_id);
|
||||
@@ -88,6 +115,10 @@ export function create({
|
||||
return user_group_pill.filter_taken_groups(potential_groups, pill_widget);
|
||||
}
|
||||
|
||||
pill_widget.onPillExpand((pill) => {
|
||||
expand_group_pill(pill, pill_widget);
|
||||
});
|
||||
|
||||
add_subscribers_pill.set_up_pill_typeahead({
|
||||
pill_widget,
|
||||
$pill_container,
|
||||
@@ -136,6 +167,10 @@ export function create_without_add_button({
|
||||
onPillRemoveAction(get_pill_user_ids(pill_widget), get_pill_group_ids(pill_widget));
|
||||
});
|
||||
|
||||
pill_widget.onPillExpand((pill) => {
|
||||
expand_group_pill(pill, pill_widget);
|
||||
});
|
||||
|
||||
add_subscribers_pill.set_up_pill_typeahead({
|
||||
pill_widget,
|
||||
$pill_container,
|
||||
|
@@ -58,6 +58,7 @@ type InputPillStore<ItemType> = {
|
||||
on_pill_exit: InputPillCreateOptions<ItemType>["on_pill_exit"];
|
||||
onPillCreate?: () => void;
|
||||
onPillRemove?: (pill: InputPill<ItemType>, trigger: RemovePillTrigger) => void;
|
||||
onPillExpand?: (pill: JQuery) => void;
|
||||
createPillonPaste?: () => void;
|
||||
split_text_on_comma: boolean;
|
||||
convert_to_pill_on_enter: boolean;
|
||||
@@ -78,6 +79,7 @@ export type InputPillContainer<ItemType> = {
|
||||
onPillRemove: (
|
||||
callback: (pill: InputPill<ItemType>, trigger: RemovePillTrigger) => void,
|
||||
) => void;
|
||||
onPillExpand: (callback: (pill: JQuery) => void) => void;
|
||||
onTextInputHook: (callback: () => void) => void;
|
||||
createPillonPaste: (callback: () => void) => void;
|
||||
clear: (quiet?: boolean) => void;
|
||||
@@ -469,6 +471,15 @@ export function create<ItemType extends {type: string}>(
|
||||
store.$input.trigger("focus");
|
||||
});
|
||||
|
||||
store.$parent.on("click", ".expand", function (this: HTMLElement, e) {
|
||||
assert(store.onPillExpand !== undefined);
|
||||
e.stopPropagation();
|
||||
store.onPillExpand($(this).closest(".pill"));
|
||||
const pill = util.the($(this).closest(".pill"));
|
||||
funcs.removePill(pill, "close");
|
||||
store.$input.trigger("focus");
|
||||
});
|
||||
|
||||
store.$parent.on("click", function (e) {
|
||||
if ($(e.target).is(".pill-container")) {
|
||||
$(this).find(".input").trigger("focus");
|
||||
@@ -501,6 +512,10 @@ export function create<ItemType extends {type: string}>(
|
||||
store.onPillRemove = callback;
|
||||
},
|
||||
|
||||
onPillExpand(callback) {
|
||||
store.onPillExpand = callback;
|
||||
},
|
||||
|
||||
onTextInputHook(callback) {
|
||||
store.onTextInputHook = callback;
|
||||
},
|
||||
|
@@ -394,7 +394,10 @@ export function set_up_combined(
|
||||
if (include_streams(query) && item.type === "stream") {
|
||||
stream_pill.append_stream(item, pills);
|
||||
} else if (include_user_groups && item.type === "user_group") {
|
||||
user_group_pill.append_user_group(item, pills);
|
||||
const show_expand_button =
|
||||
!opts.for_stream_subscribers &&
|
||||
(item.members.size > 0 || item.direct_subgroup_ids.size > 0);
|
||||
user_group_pill.append_user_group(item, pills, true, show_expand_button);
|
||||
} else if (
|
||||
include_users &&
|
||||
item.type === "user" &&
|
||||
|
@@ -17,6 +17,7 @@ export type UserGroupPill = {
|
||||
type: "user_group";
|
||||
group_id: number;
|
||||
group_name: string;
|
||||
show_expand_button?: boolean;
|
||||
};
|
||||
|
||||
export type UserGroupPillWidget = InputPillContainer<UserGroupPill>;
|
||||
@@ -34,6 +35,7 @@ export function generate_pill_html(item: UserGroupPill): string {
|
||||
group_id: item.group_id,
|
||||
show_group_members_count: true,
|
||||
group_members_count: group_members.length,
|
||||
show_expand_button: item.show_expand_button ?? false,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -87,12 +89,14 @@ export function append_user_group(
|
||||
group: UserGroup,
|
||||
pill_widget: CombinedPillContainer | GroupSettingPillContainer | UserGroupPillWidget,
|
||||
execute_oncreate_callback = true,
|
||||
show_expand_button = false,
|
||||
): void {
|
||||
pill_widget.appendValidatedData(
|
||||
{
|
||||
type: "user_group",
|
||||
group_id: group.id,
|
||||
group_name: group.name,
|
||||
show_expand_button,
|
||||
},
|
||||
false,
|
||||
!execute_oncreate_callback,
|
||||
|
@@ -70,7 +70,8 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.pill-close-button {
|
||||
.pill-close-button,
|
||||
.pill-expand-button {
|
||||
font-size: 0.7142em; /* 10px at 14px em */
|
||||
text-decoration: none;
|
||||
/* Let the close button's box stretch,
|
||||
@@ -92,20 +93,22 @@
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.exit {
|
||||
.exit,
|
||||
.expand {
|
||||
width: var(--length-input-pill-exit);
|
||||
height: var(--length-input-pill-exit);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.exit:hover {
|
||||
background: var(--color-background-input-pill-exit-hover);
|
||||
&:hover {
|
||||
background: var(--color-background-input-pill-exit-hover);
|
||||
|
||||
.pill-close-button {
|
||||
opacity: 1;
|
||||
.pill-close-button,
|
||||
.pill-expand-button {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,11 @@
|
||||
<span class="group-members-count">({{group_members_count}})</span>
|
||||
{{~/if~}}
|
||||
</span>
|
||||
{{#if show_expand_button}}
|
||||
<div class="expand">
|
||||
<a role="button" class="zulip-icon zulip-icon-expand-both-diagonals pill-expand-button"></a>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#unless disabled}}
|
||||
<div class="exit">
|
||||
<a role="button" class="zulip-icon zulip-icon-close pill-close-button"></a>
|
||||
|
@@ -94,14 +94,14 @@ const admins = {
|
||||
name: "Admins",
|
||||
description: "foo",
|
||||
id: 1,
|
||||
members: [jill.user_id, mark.user_id, me.user_id],
|
||||
members: new Set([jill.user_id, mark.user_id, me.user_id]),
|
||||
};
|
||||
const admins_item = user_group_item(admins);
|
||||
const testers = {
|
||||
name: "Testers",
|
||||
description: "bar",
|
||||
id: 2,
|
||||
members: [mark.user_id, fred.user_id, me.user_id],
|
||||
members: new Set([mark.user_id, fred.user_id, me.user_id]),
|
||||
};
|
||||
const testers_item = user_group_item(testers);
|
||||
|
||||
|
@@ -77,6 +77,7 @@ const testers_pill = {
|
||||
group_id: testers.id,
|
||||
group_name: testers.name,
|
||||
type: "user_group",
|
||||
show_expand_button: false,
|
||||
};
|
||||
const everyone_pill = {
|
||||
group_id: everyone.id,
|
||||
|
Reference in New Issue
Block a user