Skip to content

Commit 0178162

Browse files
authored
Merge pull request #764 from jupyterlab/bundled-env-update-notification-and-auto-install
notification for bundled env updates, auto update bundled env
2 parents 3c3dbac + 71e7fe0 commit 0178162

20 files changed

+441
-48
lines changed

src/assets/server-icon.svg

+1
Loading

src/main/app.ts

+50-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import * as yaml from 'js-yaml';
1616
import * as semver from 'semver';
1717
import * as fs from 'fs';
1818
import {
19+
bundledEnvironmentIsInstalled,
1920
clearSession,
2021
EnvironmentInstallStatus,
2122
getBundledPythonEnvPath,
@@ -392,6 +393,12 @@ export class JupyterApplication implements IApplication, IDisposable {
392393
installUpdatesAutomatically: settings.getValue(
393394
SettingType.installUpdatesAutomatically
394395
),
396+
notifyOnBundledEnvUpdates: settings.getValue(
397+
SettingType.notifyOnBundledEnvUpdates
398+
),
399+
updateBundledEnvAutomatically: settings.getValue(
400+
SettingType.updateBundledEnvAutomatically
401+
),
395402
defaultWorkingDirectory: userSettings.getValue(
396403
SettingType.defaultWorkingDirectory
397404
),
@@ -429,7 +436,9 @@ export class JupyterApplication implements IApplication, IDisposable {
429436
isDarkTheme: this._isDarkTheme,
430437
defaultPythonPath: userSettings.getValue(SettingType.pythonPath),
431438
app: this,
432-
activateTab
439+
activateTab,
440+
bundledEnvInstallationExists: bundledEnvironmentIsInstalled(),
441+
bundledEnvInstallationLatest: this._registry.bundledEnvironmentIsLatest()
433442
});
434443

435444
this._managePythonEnvDialog = dialog;
@@ -529,7 +538,16 @@ export class JupyterApplication implements IApplication, IDisposable {
529538
};
530539

531540
dialog.showMessageBox(dialogOpts).then(returnValue => {
532-
if (returnValue.response === 0) autoUpdater.quitAndInstall();
541+
if (returnValue.response === 0) {
542+
if (
543+
userSettings.getValue(SettingType.updateBundledEnvAutomatically) &&
544+
bundledEnvironmentIsInstalled()
545+
) {
546+
appData.updateBundledEnvOnRestart = true;
547+
appData.save();
548+
}
549+
autoUpdater.quitAndInstall();
550+
}
533551
});
534552
});
535553

@@ -773,6 +791,27 @@ export class JupyterApplication implements IApplication, IDisposable {
773791
}
774792
);
775793

794+
this._evm.registerEventHandler(
795+
EventTypeMain.UpdateBundledPythonEnv,
796+
async event => {
797+
const choice = dialog.showMessageBoxSync({
798+
type: 'warning',
799+
message: 'Update bundled environment',
800+
detail:
801+
'App will restart and the existing environment installation will be deleted before the update. Would you like to continue?',
802+
buttons: ['Update', 'Cancel'],
803+
defaultId: 1,
804+
cancelId: 1
805+
});
806+
807+
if (choice === 0) {
808+
appData.updateBundledEnvOnRestart = true;
809+
app.relaunch();
810+
app.quit();
811+
}
812+
}
813+
);
814+
776815
this._evm.registerEventHandler(
777816
EventTypeMain.ShowManagePythonEnvironmentsDialog,
778817
async (event, activateTab) => {
@@ -1091,6 +1130,15 @@ export class JupyterApplication implements IApplication, IDisposable {
10911130
}
10921131
);
10931132

1133+
this._evm.registerEventHandler(
1134+
EventTypeMain.SetSettings,
1135+
(_event, settings: { [key: string]: any }) => {
1136+
for (const key in settings) {
1137+
userSettings.setValue(key as SettingType, settings[key]);
1138+
}
1139+
}
1140+
);
1141+
10941142
this._evm.registerSyncEventHandler(
10951143
EventTypeMain.GetServerInfo,
10961144
(event): IServerInfo => {

src/main/config/appdata.ts

+10
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ export class ApplicationData {
169169
});
170170
}
171171
}
172+
173+
if ('updateBundledEnvOnRestart' in jsonData) {
174+
this.updateBundledEnvOnRestart = jsonData.updateBundledEnvOnRestart;
175+
}
172176
}
173177

174178
save() {
@@ -245,6 +249,10 @@ export class ApplicationData {
245249
});
246250
}
247251

252+
if (this.updateBundledEnvOnRestart) {
253+
appDataJSON.updateBundledEnvOnRestart = true;
254+
}
255+
248256
fs.writeFileSync(appDataPath, JSON.stringify(appDataJSON, null, 2));
249257
}
250258

@@ -396,6 +404,8 @@ export class ApplicationData {
396404
discoveredPythonEnvs: IPythonEnvironment[] = [];
397405
userSetPythonEnvs: IPythonEnvironment[] = [];
398406

407+
updateBundledEnvOnRestart: boolean = false;
408+
399409
private _recentSessionsChanged = new Signal<this, void>(this);
400410
}
401411

src/main/config/settings.ts

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export type KeyValueMap = { [key: string]: string };
4040
export enum SettingType {
4141
checkForUpdatesAutomatically = 'checkForUpdatesAutomatically',
4242
installUpdatesAutomatically = 'installUpdatesAutomatically',
43+
notifyOnBundledEnvUpdates = 'notifyOnBundledEnvUpdates',
44+
updateBundledEnvAutomatically = 'updateBundledEnvAutomatically',
4345

4446
theme = 'theme',
4547
syncJupyterLabTheme = 'syncJupyterLabTheme',
@@ -124,6 +126,8 @@ export class UserSettings {
124126
this._settings = {
125127
checkForUpdatesAutomatically: new Setting<boolean>(true),
126128
installUpdatesAutomatically: new Setting<boolean>(true),
129+
notifyOnBundledEnvUpdates: new Setting<boolean>(true),
130+
updateBundledEnvAutomatically: new Setting<boolean>(false),
127131
showNewsFeed: new Setting<boolean>(true),
128132

129133
/* making themes workspace overridable is not feasible.

src/main/dialog/dialogtitlebar.ts

+14-8
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ class JupyterLabDialogTitleBar extends HTMLElement {
1515
const titleEl = document.createElement('div');
1616
titleEl.setAttribute('class', 'dialog-title');
1717

18-
const closeButton = document.createElement('div');
19-
closeButton.setAttribute('class', 'close-button');
20-
closeButton.innerHTML = `<svg viewBox='0 0 10 10'><polygon points='10.2,0.7 9.5,0 5.1,4.4 0.7,0 0,0.7 4.4,5.1 0,9.5 0.7,10.2 5.1,5.8 9.5,10.2 10.2,9.5 5.8,5.1'/></svg>`;
21-
closeButton.title = 'Close';
22-
closeButton.onclick = () => {
23-
window.close();
24-
};
18+
const closable = this.getAttribute('data-closable') !== 'false';
19+
let closeButton = null;
20+
if (closable) {
21+
closeButton = document.createElement('div');
22+
closeButton.setAttribute('class', 'close-button');
23+
closeButton.innerHTML = `<svg viewBox='0 0 10 10'><polygon points='10.2,0.7 9.5,0 5.1,4.4 0.7,0 0,0.7 4.4,5.1 0,9.5 0.7,10.2 5.1,5.8 9.5,10.2 10.2,9.5 5.8,5.1'/></svg>`;
24+
closeButton.title = 'Close';
25+
closeButton.onclick = () => {
26+
window.close();
27+
};
28+
}
2529

2630
const title = this.getAttribute('data-title');
2731
titleEl.textContent = title;
@@ -85,7 +89,9 @@ class JupyterLabDialogTitleBar extends HTMLElement {
8589
shadow.appendChild(style);
8690
shadow.appendChild(wrapper);
8791
wrapper.appendChild(titleEl);
88-
wrapper.appendChild(closeButton);
92+
if (closeButton) {
93+
wrapper.appendChild(closeButton);
94+
}
8995
}
9096
}
9197

src/main/dialog/themedwindow.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import { DarkThemeBGColor, LightThemeBGColor } from '../utils';
99
export class ThemedWindow {
1010
constructor(options: ThemedWindow.IOptions) {
1111
this._isDarkTheme = options.isDarkTheme;
12+
this._closable = options.closable !== false;
1213
this._window = new BrowserWindow({
1314
parent: options.parent,
1415
modal: options.modal,
1516
title: options.title,
1617
width: options.width,
1718
height: options.height,
1819
show: false,
20+
closable: this._closable,
1921
resizable: options.resizable !== false,
2022
titleBarStyle: 'hidden',
2123
frame: process.platform === 'darwin',
@@ -40,6 +42,11 @@ export class ThemedWindow {
4042
return this._window;
4143
}
4244

45+
close() {
46+
this._window.closable = true;
47+
this._window.close();
48+
}
49+
4350
loadDialogContent(bodyHtml: string) {
4451
let toolkitJsSrc = fs
4552
.readFileSync(
@@ -114,7 +121,7 @@ export class ThemedWindow {
114121
<div class="page-container">
115122
<jlab-dialog-titlebar id="title-bar" data-title="${
116123
this._window.title
117-
}" class="${
124+
}" data-closable="${this._closable ? 'true' : 'false'}" class="${
118125
this._isDarkTheme ? 'app-ui-dark' : ''
119126
}"></jlab-dialog-titlebar>
120127
<div id="jlab-dialog-body" class="jlab-dialog-body">
@@ -130,6 +137,7 @@ export class ThemedWindow {
130137
}
131138

132139
private _isDarkTheme: boolean;
140+
private _closable: boolean;
133141
private _window: BrowserWindow;
134142
}
135143

@@ -141,6 +149,7 @@ export namespace ThemedWindow {
141149
title: string;
142150
width: number;
143151
height: number;
152+
closable?: boolean;
144153
resizable?: boolean;
145154
preload?: string;
146155
}

src/main/eventtypes.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export enum EventTypeMain {
3939
SetDefaultWorkingDirectory = 'set-default-working-directory',
4040
SelectPythonPath = 'select-python-path',
4141
InstallBundledPythonEnv = 'install-bundled-python-env',
42+
UpdateBundledPythonEnv = 'update-bundled-python-env',
4243
ValidatePythonPath = 'validate-python-path',
4344
ValidateRemoteServerUrl = 'validate-remote-server-url',
4445
SetDefaultPythonPath = 'set-default-python-path',
@@ -79,7 +80,8 @@ export enum EventTypeMain {
7980
ValidateSystemPythonPath = 'validate-system-python-path',
8081
SetSystemPythonPath = 'set-system-python-path',
8182
CopySessionInfoToClipboard = 'copy-session-info-to-clipboard',
82-
RestartSession = 'restart-session'
83+
RestartSession = 'restart-session',
84+
SetSettings = 'set-settings'
8385
}
8486

8587
// events sent to Renderer process
@@ -94,12 +96,14 @@ export enum EventTypeRenderer {
9496
SetTitle = 'set-title',
9597
SetActive = 'set-active',
9698
ShowServerStatus = 'show-server-status',
99+
ShowServerNotificationBadge = 'show-server-notification-badge',
97100
SetRecentSessionList = 'set-recent-session-list',
98101
SetNewsList = 'set-news-list',
99102
SetNotificationMessage = 'set-notification-message',
100103
EnableLocalServerActions = 'enable-local-server-actions',
101104
SetDefaultWorkingDirectoryResult = 'set-default-working-directory-result',
102105
ResetPythonEnvSelectPopup = 'reset-python-env-select-popup',
103106
SetPythonEnvironmentList = 'set-python-environment-list',
104-
SetEnvironmentListUpdateStatus = 'set-environment-list-update-status'
107+
SetEnvironmentListUpdateStatus = 'set-environment-list-update-status',
108+
ShowUpdateBundledEnvAction = 'show-bundled-env-action'
105109
}

0 commit comments

Comments
 (0)