Skip to content

Commit efebf2c

Browse files
sathishlxgZsailer
authored andcommitted
Readonly share dialog for shared with me items (jupyter-server#459)
1 parent cdf71f0 commit efebf2c

File tree

8 files changed

+193
-84
lines changed

8 files changed

+193
-84
lines changed

src/publish_notebooks/components/index.tsx

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,25 @@ import { AutoSuggestionInput } from './auto_suggestion';
66

77
type Props = {
88
author: Contact;
9+
isReadOnly: boolean;
910
onChange: (v: Contact[]) => void;
1011
client: PublishingExtensionClient;
11-
collaborators: ICollaborators[] | undefined;
12+
collaborators: ICollaborators[] | null;
1213
};
1314

1415
export const ShareNotebooksComponent: FC<Props> = ({
1516
onChange,
1617
author,
1718
client,
19+
isReadOnly,
1820
collaborators = []
1921
}) => {
2022
const [query, setQuery] = useState('');
2123
const searchQuery = useDebounce(query, 100);
2224
const [value, setValue] = useState<Contact[]>([]);
23-
const [people, setPeople] = useState(collaborators);
25+
const [people, setPeople] = useState(collaborators || []);
2426
const [contacts, setContacts] = useState<Contact[]>([]);
25-
const owner = useMemo(() => collaborators.find(c => c.id === author.id), []);
27+
const owner = useMemo(() => collaborators?.find(c => c.id === author.id), []);
2628

2729
useEffect(() => {
2830
const fetchContacts = async (input: string) => {
@@ -66,16 +68,25 @@ export const ShareNotebooksComponent: FC<Props> = ({
6668

6769
return (
6870
<>
69-
<p>
70-
This document has been published to Data Studio's document sharing
71-
service. You can now share this document with others.
72-
</p>
73-
<AutoSuggestionInput
74-
value={value}
75-
contacts={contacts}
76-
onChange={handleChange}
77-
onSearch={handleSearchQuery}
78-
/>
71+
{isReadOnly ? (
72+
<p className="header-info">
73+
You're a viewer and can't share. Please request owner to share with
74+
others
75+
</p>
76+
) : (
77+
<>
78+
<p>
79+
This document has been published to Data Studio's document sharing
80+
service. You can now share this document with others.
81+
</p>
82+
<AutoSuggestionInput
83+
value={value}
84+
contacts={contacts}
85+
onChange={handleChange}
86+
onSearch={handleSearchQuery}
87+
/>
88+
</>
89+
)}
7990
<div className="list-header">People with access</div>
8091
<ul className="list">
8192
{owner && (
@@ -96,7 +107,11 @@ export const ShareNotebooksComponent: FC<Props> = ({
96107
<div>{item.name}</div>
97108
<div>{item.email}</div>
98109
</div>
99-
<button onClick={() => handleRemove(item.email)}>Remove</button>
110+
{isReadOnly ? null : (
111+
<button onClick={() => handleRemove(item.email)}>
112+
Remove
113+
</button>
114+
)}
100115
</li>
101116
);
102117
})}

src/publish_notebooks/extension.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,14 @@ function addShareNotebookCommand(
8181
};
8282

8383
const handleShareExecute = async (args: ReadonlyPartialJSONObject) => {
84+
const { isReadOnly, title: fileName } = args;
85+
const title = `${isReadOnly ? 'View' : 'Share'} "${fileName}"`;
86+
8487
const dialog = new PublishDialog({
88+
title,
8589
buttons,
8690
actionHandlers,
8791
hasClose: true,
88-
title: `Share "${args.title}"`,
8992
body: new ShareNotebooksWidget(
9093
(args as unknown) as IPublishedFileMetadata,
9194
publishingClient
@@ -94,12 +97,9 @@ function addShareNotebookCommand(
9497

9598
const result = await dialog.launch();
9699

97-
if (result.value) {
100+
if (result.value && !args.isReadOnly) {
98101
publishingClient.updateFile(result.value.value);
99102
}
100-
101-
// TODO: Send data to API
102-
console.log(result);
103103
};
104104

105105
app.commands.addCommand(CommandIDs.shareCommandID, {
@@ -117,9 +117,7 @@ function addPreviewCommand(
117117
publishingClient: PublishingExtensionClient
118118
) {
119119
const handleExecute = async (args: ReadonlyPartialJSONObject) => {
120-
// TODO: Use file ID instead of shareable_link
121-
const widgetId = (args.shareable_link as string) || '';
122-
// const path: string = (args.shareable_link as string) || '';
120+
const widgetId = args.id as string;
123121
const fileId: string = (args.id as string) || '';
124122
const widgetExists = previewTracker.find(w => w.id === widgetId);
125123
const title = `Preview - ${args.title}`;

src/publish_notebooks/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export interface IPublishedFileMetadata {
3131
shareable_link: string;
3232
collaborators?: Array<ICollaborators>;
3333
content?: IJupyterContentsModel;
34+
isReadOnly?: boolean;
3435
}
3536

3637
export interface IShareDialogBody {

src/publish_notebooks/widget.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export class ShareNotebooksWidget extends ReactWidget {
5555
super();
5656
this._value = [];
5757
this._data = data;
58+
this._isReadOnly = Boolean(data.isReadOnly);
5859
this.handleChange = this.handleChange.bind(this);
5960
this._publishingClient = publishingClient;
6061
this._author = tryParse(this._data.author);
@@ -90,16 +91,18 @@ export class ShareNotebooksWidget extends ReactWidget {
9091
render(): JSX.Element {
9192
return (
9293
<ShareNotebooksComponent
94+
isReadOnly={this._isReadOnly}
9395
onChange={this.handleChange}
9496
author={this._author}
9597
client={this._publishingClient}
96-
collaborators={this._data.collaborators}
98+
collaborators={this._data.collaborators || []}
9799
/>
98100
);
99101
}
100102

101103
_author: Contact;
102104
_value: Contact[];
105+
_isReadOnly = false;
103106
_data: IPublishedFileMetadata;
104107
private _publishingClient: PublishingExtensionClient;
105108
}

src/shared_notebooks/components/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ export const SharedNotebooks: React.FC<SharedNotebooksProp> = ({
5656
key={index}
5757
name={item.title}
5858
title={item.title}
59-
onShare={onShare.bind(null, item)}
6059
onPreview={onPreview.bind(null, item)}
60+
onShare={onShare.bind(null, { ...item, isReadOnly: true })}
6161
/>
6262
))}
6363
</SharedNotebooksList>

src/shared_notebooks/extension.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import { SharedNotebooksWidget } from './widget';
99

1010
import { LabIcon } from '@jupyterlab/ui-components';
1111
import shareIconSvg from '../../style/icons/share_icon.svg';
12-
import { SharedNotebooksModel } from './model';
12+
import { IPublishedFileMetadata, SharedNotebooksModel } from './model';
1313
import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
14+
import { BoxLayout, Panel } from '@lumino/widgets';
15+
import { Dialog, showErrorMessage, Spinner } from '@jupyterlab/apputils';
1416

1517
const shareIcon = new LabIcon({
1618
name: 'publish:shareIcon',
@@ -22,16 +24,44 @@ async function activate(
2224
labShell: ILabShell,
2325
restorer: ILayoutRestorer
2426
): Promise<void> {
25-
const onDialogOpen = (args: unknown) =>
26-
app.commands.execute('publishing:share', args as ReadonlyPartialJSONObject);
27+
const model = new SharedNotebooksModel();
28+
29+
const onDialogOpen = async (args: unknown) => {
30+
const box = new BoxLayout();
31+
const { id, title: fileName, isReadOnly } = args as IPublishedFileMetadata;
32+
33+
box.addWidget(new Spinner());
34+
35+
const title = `Sharing "${fileName}"`;
36+
const loading = new Dialog({
37+
title,
38+
buttons: [],
39+
hasClose: false,
40+
body: new Panel({ layout: box })
41+
});
42+
43+
loading.launch();
44+
45+
try {
46+
const data = await model.getFile(id);
47+
48+
app.commands.execute('publishing:share', ({
49+
...data,
50+
isReadOnly
51+
} as unknown) as ReadonlyPartialJSONObject);
52+
} catch (error) {
53+
showErrorMessage('Sharing failed', error);
54+
} finally {
55+
loading.close();
56+
}
57+
};
2758

2859
const onPreviewFile = (args: unknown) =>
2960
app.commands.execute(
3061
'publishing:download',
3162
args as ReadonlyPartialJSONObject
3263
);
3364

34-
const model = new SharedNotebooksModel();
3565
const sharedNotebooks = new SharedNotebooksWidget(model, {
3666
onDialogOpen,
3767
onPreviewFile

0 commit comments

Comments
 (0)