Skip to content

Commit

Permalink
Add tab to download csv file of the list of users in a room (#613)
Browse files Browse the repository at this point in the history
* Add tab to download csv file of the list of users in a room

* Put download file in tchap utils, and change csv to txt donwload

* Add tooltip
  • Loading branch information
aulamber authored Jun 22, 2023
1 parent a7436a2 commit 1e29119
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 5 deletions.
10 changes: 5 additions & 5 deletions cypress/utils/room-utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Chainable = Cypress.Chainable;
import TchapCreateRoom from "../../src/tchap/lib/createTchapRoom";
import { TchapRoomType } from "../../src/tchap/@types/tchap";
import TchapCreateRoom from "../../src/lib/createTchapRoom";
import { TchapRoomType } from "../../src/@types/tchap";
export default class RoomUtils {
public static createPublicRoom(roomName: string): Chainable<string> {
return cy.createRoom(TchapCreateRoom.roomCreateOptions(roomName, TchapRoomType.Forum).createOpts);
return cy.createRoom(TchapCreateRoom.roomCreateOptions(roomName, TchapRoomType.Forum, false).createOpts);
}
public static createPrivateRoom(roomName: string): Chainable<string> {
return cy.createRoom(TchapCreateRoom.roomCreateOptions(roomName, TchapRoomType.Private).createOpts);
return cy.createRoom(TchapCreateRoom.roomCreateOptions(roomName, TchapRoomType.Private, false).createOpts);
}
public static createPrivateWithExternalRoom(roomName: string): Chainable<string> {
return cy.createRoom(TchapCreateRoom.roomCreateOptions(roomName, TchapRoomType.External).createOpts);
return cy.createRoom(TchapCreateRoom.roomCreateOptions(roomName, TchapRoomType.External, false).createOpts);
}
public static openRoomAccessSettings(roomName: string): Chainable<JQuery<HTMLElement>> {
//open room
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
diff --git a/node_modules/matrix-react-sdk/src/components/views/right_panel/RoomSummaryCard.tsx b/node_modules/matrix-react-sdk/src/components/views/right_panel/RoomSummaryCard.tsx
index a32d8da..45b1307 100644
--- a/node_modules/matrix-react-sdk/src/components/views/right_panel/RoomSummaryCard.tsx
+++ b/node_modules/matrix-react-sdk/src/components/views/right_panel/RoomSummaryCard.tsx
@@ -17,7 +17,14 @@ limitations under the License.
import React, { useCallback, useContext, useEffect, useMemo, useState } from "react";
import classNames from "classnames";
import { Room } from "matrix-js-sdk/src/models/room";
-
+import { keys } from "lodash"; /* :TCHAP: */
+
+// src/components/views/right_panel/RoomSummaryCard.tsx
+// src/components/views/elements/Tooltip.tsx
+import Tooltip, { Alignment } from "../elements/Tooltip"; /* :TCHAP: */
+import { useTimeoutToggle } from "../../../hooks/useTimeoutToggle"; /* :TCHAP: */
+import { generateAndDownloadTextFile } from "../../../../../../src/tchap/util/TchapExportFiles"; /* :TCHAP: */
+import { useRoomContext } from "../../../contexts/RoomContext";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { useIsEncrypted } from "../../../hooks/useIsEncrypted";
import BaseCard, { Group } from "./BaseCard";
@@ -274,6 +281,7 @@ const onRoomSettingsClick = (ev: ButtonEvent): void => {

const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose }) => {
const cli = useContext(MatrixClientContext);
+ const context = useRoomContext();

const onShareRoomClick = (): void => {
Modal.createDialog(ShareDialog, {
@@ -287,6 +295,20 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose })
});
};

+ /* :TCHAP:
+ add a tab to download the list of users in current room
+ so that they can create new rooms with the same users
+ */
+ const onRoomExportMemberEmailsClick = async (): Promise<void> => {
+ const members = keys(context?.room?.currentState?.members);
+ generateAndDownloadTextFile({
+ fileName: "members",
+ format: "txt",
+ content: members.join(",")
+ });
+ }
+ /* end :TCHAP: */
+
const onRoomPollHistoryClick = (): void => {
Modal.createDialog(PollHistoryDialog, {
room,
@@ -295,6 +317,7 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose })
});
};

+
const isRoomEncrypted = useIsEncrypted(cli, room);
const roomContext = useContext(RoomContext);
const e2eStatus = roomContext.e2eStatus;
@@ -328,6 +351,11 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose })
const memberCount = useRoomMemberCount(room);
const pinningEnabled = useFeatureEnabled("feature_pinning");
const pinCount = usePinnedEvents(pinningEnabled ? room : undefined)?.length;
+ /* :TCHAP: add tooltip for export room member list button */
+ const [exportRoomMembersYooltipVisible, setExportRoomMembersYooltipVisible] = useState(false);
+ const onExportRoomMembersEnter = () => setExportRoomMembersYooltipVisible(true);
+ const onExportRoomMembersLeave = () => setExportRoomMembersYooltipVisible(false);
+ /* end :TCHAP: */

return (
<BaseCard header={header} className="mx_RoomSummaryCard" onClose={onClose}>
@@ -357,6 +385,21 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose })
{_t("Export chat")}
</Button>
)}
+ {/* :TCHAP: */ !isVideoRoom && (
+ <Button
+ className="mx_RoomSummaryCard_icon_export"
+ onClick={onRoomExportMemberEmailsClick}
+ onMouseEnter={onExportRoomMembersEnter}
+ onMouseLeave={onExportRoomMembersLeave}
+ >
+ {_t("Export room members (txt)")}
+ <Tooltip
+ label={_t("By exporting the members of the room, you obtain the identifiers of the participants that you can copy/paste to invite them into another room.")}
+ alignment={Alignment.Top}
+ visible={exportRoomMembersYooltipVisible}
+ />
+ </Button>
+ ) /* end :TCHAP */}
<Button
data-testid="shareRoomButton"
className="mx_RoomSummaryCard_icon_share"
7 changes: 7 additions & 0 deletions patches/patches.json
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,12 @@
"files": [
"src/stores/RoomViewStore.tsx"
]
},
"add-tab-to-download-csv-file-of-the-list-of-users-in-a-room": {
"github-issue": "https://github.com/tchapgouv/tchap-web-v4/issues/593",
"package": "matrix-react-sdk",
"files": [
"src/components/views/right_panel/RoomSummaryCard.tsx"
]
}
}
9 changes: 9 additions & 0 deletions src/tchap/i18n/strings/tchap_translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,15 @@
"fr": "Veuillez ne continuer que si vous êtes certain d’avoir perdu tous vos autres appareils et votre Code de Récupération.",
"en": "Please only proceed if you're sure you've lost all of your other devices and your Recovery Code."
},
"Export room members (txt)": {
"fr": "Exporter les membres du salon (txt)",
"en": "Export room members (txt)"
},
"By exporting the members of the room, you obtain the identifiers of the participants that you can copy/paste to invite them into another room.": {
"fr": "En exportant les membres du salon, vous obtenez les identifiants des participants que vous pourrez copier/coller pour les inviter dans un autre salon.",
"en": "By exporting the members of the room, you obtain the identifiers of the participants that you can copy/paste to invite them into another room."
},

"Destroy cross-signing keys?": {
"fr": "Réinitialiser les clés de signature croisée ?",
"en": "Reset cross-signing keys?"
Expand Down
22 changes: 22 additions & 0 deletions src/tchap/util/TchapExportFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const generateAndDownloadTextFile = ({
fileName,
format,
content
}: {
fileName: string,
format: "csv" | "txt",
content: string
}) => {
const formats = {
csv: "csv",
txt: "plain",
};
const contentToSend = `data:text/${formats[format]};charset=utf-8,${content}`;
const encodedUri = encodeURI(contentToSend);
const link = document.createElement("a");

link.setAttribute("href", encodedUri);
link.setAttribute("download", `${fileName}.${format}`);
document.body.appendChild(link); // Required for firefox
link.click(); // download the data file named "emails.csv".
}

0 comments on commit 1e29119

Please sign in to comment.