@jupyter/collaboration 3.1.0-rc.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -89,7 +89,7 @@ export function Collaborator(props) {
89
89
  var _a, _b;
90
90
  const path = document.split(':');
91
91
  const fileTypes = (_b = (_a = props.docRegistry) === null || _a === void 0 ? void 0 : _a.getFileTypesForPath(path[1])) === null || _b === void 0 ? void 0 : _b.filter(ft => ft.icon !== undefined);
92
- const icon = fileTypes ? fileTypes[0].icon : fileIcon;
92
+ const icon = (fileTypes === null || fileTypes === void 0 ? void 0 : fileTypes.length) ? fileTypes[0].icon : fileIcon;
93
93
  const iconClass = fileTypes
94
94
  ? fileTypes[0].iconClass
95
95
  : undefined;
package/lib/index.d.ts CHANGED
@@ -8,3 +8,4 @@ export * from './cursors';
8
8
  export * from './menu';
9
9
  export * from './sharedlink';
10
10
  export * from './userinfopanel';
11
+ export * from './users-item';
package/lib/index.js CHANGED
@@ -10,3 +10,4 @@ export * from './cursors';
10
10
  export * from './menu';
11
11
  export * from './sharedlink';
12
12
  export * from './userinfopanel';
13
+ export * from './users-item';
@@ -0,0 +1,85 @@
1
+ import { DocumentRegistry } from '@jupyterlab/docregistry';
2
+ import { User } from '@jupyterlab/services';
3
+ import { ReactWidget } from '@jupyterlab/ui-components';
4
+ import * as React from 'react';
5
+ /**
6
+ * The namespace for the UsersItem component.
7
+ */
8
+ export declare namespace UsersItem {
9
+ /**
10
+ * Properties of the component.
11
+ */
12
+ interface IProps {
13
+ /**
14
+ * The model of the document.
15
+ */
16
+ model: DocumentRegistry.IModel | null;
17
+ /**
18
+ * A function to display the user icons, optional.
19
+ * This function will overwrite the default one, and can be used to handle event on
20
+ * icons.
21
+ */
22
+ iconRenderer?: (props: UsersItem.IIconRendererProps) => JSX.Element;
23
+ }
24
+ /**
25
+ * The state of the component.
26
+ */
27
+ interface IState {
28
+ /**
29
+ * The user list.
30
+ */
31
+ usersList: IUserData[];
32
+ }
33
+ /**
34
+ * Properties send to the iconRenderer function.
35
+ */
36
+ interface IIconRendererProps extends React.HTMLAttributes<HTMLElement> {
37
+ /**
38
+ * The user.
39
+ */
40
+ user: IUserData;
41
+ /**
42
+ * The document's model.
43
+ */
44
+ model?: DocumentRegistry.IModel;
45
+ }
46
+ /**
47
+ * The user data type.
48
+ */
49
+ type IUserData = {
50
+ /**
51
+ * User id (the client id of the awareness).
52
+ */
53
+ userId: number;
54
+ /**
55
+ * User data.
56
+ */
57
+ userData: User.IIdentity;
58
+ };
59
+ }
60
+ /**
61
+ * A component displaying the collaborative users of a document.
62
+ */
63
+ export declare class UsersItem extends React.Component<UsersItem.IProps, UsersItem.IState> {
64
+ constructor(props: UsersItem.IProps);
65
+ /**
66
+ * Static method to create a widget.
67
+ */
68
+ static createWidget(options: UsersItem.IProps): ReactWidget;
69
+ componentDidMount(): void;
70
+ /**
71
+ * Filter out the duplicated users, which can happen temporary on reload.
72
+ */
73
+ private filterDuplicated;
74
+ render(): React.ReactNode;
75
+ /**
76
+ * Triggered when a change occurs in the document awareness, to build again the users list.
77
+ */
78
+ private _awarenessChange;
79
+ private _model;
80
+ private _iconRenderer;
81
+ }
82
+ /**
83
+ * Default renderer for the user icon.
84
+ */
85
+ export declare function DefaultIconRenderer(props: UsersItem.IIconRendererProps): JSX.Element;
@@ -0,0 +1,90 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import { classes, ReactWidget } from '@jupyterlab/ui-components';
6
+ import * as React from 'react';
7
+ const USERS_ITEM_CLASS = 'jp-toolbar-users-item';
8
+ /**
9
+ * A component displaying the collaborative users of a document.
10
+ */
11
+ export class UsersItem extends React.Component {
12
+ constructor(props) {
13
+ var _a;
14
+ super(props);
15
+ /**
16
+ * Triggered when a change occurs in the document awareness, to build again the users list.
17
+ */
18
+ this._awarenessChange = () => {
19
+ var _a;
20
+ const clients = (_a = this._model) === null || _a === void 0 ? void 0 : _a.sharedModel.awareness.getStates();
21
+ const users = [];
22
+ if (clients) {
23
+ clients.forEach((val, key) => {
24
+ if (val.user) {
25
+ users.push({ userId: key, userData: val.user });
26
+ }
27
+ });
28
+ }
29
+ this.setState(old => ({ ...old, usersList: users }));
30
+ };
31
+ this._model = props.model;
32
+ this._iconRenderer = (_a = props.iconRenderer) !== null && _a !== void 0 ? _a : null;
33
+ this.state = { usersList: [] };
34
+ }
35
+ /**
36
+ * Static method to create a widget.
37
+ */
38
+ static createWidget(options) {
39
+ return ReactWidget.create(React.createElement(UsersItem, { ...options }));
40
+ }
41
+ componentDidMount() {
42
+ var _a;
43
+ (_a = this._model) === null || _a === void 0 ? void 0 : _a.sharedModel.awareness.on('change', this._awarenessChange);
44
+ this._awarenessChange();
45
+ }
46
+ /**
47
+ * Filter out the duplicated users, which can happen temporary on reload.
48
+ */
49
+ filterDuplicated(usersList) {
50
+ var _a;
51
+ const newList = [];
52
+ const selected = new Set();
53
+ for (const element of usersList) {
54
+ if (((_a = element === null || element === void 0 ? void 0 : element.userData) === null || _a === void 0 ? void 0 : _a.username) &&
55
+ !selected.has(element.userData.username)) {
56
+ selected.add(element.userData.username);
57
+ newList.push(element);
58
+ }
59
+ }
60
+ return newList;
61
+ }
62
+ render() {
63
+ var _a;
64
+ const IconRenderer = (_a = this._iconRenderer) !== null && _a !== void 0 ? _a : DefaultIconRenderer;
65
+ return (React.createElement("div", { className: USERS_ITEM_CLASS }, this.filterDuplicated(this.state.usersList).map(user => {
66
+ if (this._model &&
67
+ user.userId !== this._model.sharedModel.awareness.clientID) {
68
+ return IconRenderer({ user, model: this._model });
69
+ }
70
+ })));
71
+ }
72
+ }
73
+ /**
74
+ * Default renderer for the user icon.
75
+ */
76
+ export function DefaultIconRenderer(props) {
77
+ let el;
78
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
79
+ const { user, model, ...htmlProps } = props;
80
+ const iconClasses = classes('lm-MenuBar-itemIcon', props.className || '');
81
+ if (user.userData.avatar_url) {
82
+ el = (React.createElement("div", { ...htmlProps, key: user.userId, title: user.userData.display_name, className: classes(iconClasses, 'jp-MenuBar-imageIcon') },
83
+ React.createElement("img", { src: user.userData.avatar_url, alt: "" })));
84
+ }
85
+ else {
86
+ el = (React.createElement("div", { ...htmlProps, key: user.userId, title: user.userData.display_name, className: classes(iconClasses, 'jp-MenuBar-anonymousIcon'), style: { backgroundColor: user.userData.color } },
87
+ React.createElement("span", null, user.userData.initials)));
88
+ }
89
+ return el;
90
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/collaboration",
3
- "version": "3.1.0-rc.0",
3
+ "version": "3.1.1",
4
4
  "description": "JupyterLab - Real-Time Collaboration Widgets",
5
5
  "homepage": "https://github.com/jupyterlab/jupyter-collaboration",
6
6
  "bugs": {
package/style/base.css CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  @import url('./menu.css');
7
7
  @import url('./sidepanel.css');
8
+ @import url('./users-item.css');
8
9
 
9
10
  .jp-shared-link-body {
10
11
  user-select: none;
@@ -0,0 +1,20 @@
1
+ /* -----------------------------------------------------------------------------
2
+ | Copyright (c) Jupyter Development Team.
3
+ | Distributed under the terms of the Modified BSD License.
4
+ |---------------------------------------------------------------------------- */
5
+
6
+ .jp-toolbar-users-item {
7
+ flex-grow: 1;
8
+ display: flex;
9
+ flex-direction: row;
10
+ }
11
+
12
+ .jp-toolbar-users-item .jp-MenuBar-anonymousIcon,
13
+ .jp-toolbar-users-item .jp-MenuBar-imageIcon {
14
+ position: relative;
15
+ left: 0;
16
+ height: 22px;
17
+ width: 22px;
18
+ box-sizing: border-box;
19
+ cursor: default;
20
+ }