Skip to content

Commit 558926c

Browse files
committed
refactor: rework display state system to be extensible
1 parent 24e17d5 commit 558926c

2 files changed

Lines changed: 95 additions & 67 deletions

File tree

src/utils.ts

Lines changed: 91 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { JupyterFrontEnd } from '@jupyterlab/application';
22

3-
import { ToolbarButton } from '@jupyterlab/apputils';
3+
// import { ToolbarButton } from '@jupyterlab/apputils';
44

55
import { find } from '@lumino/algorithm';
66

7+
import { Widget } from '@lumino/widgets';
8+
79
import { ISettingRegistry } from '@jupyterlab/settingregistry';
810

911
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
@@ -33,15 +35,53 @@ export async function nbgitpullerUpdateButton(
3335
}
3436

3537
// Create widget
36-
const updateReposBtn = new ToolbarButton({
37-
className: 'nbgitpuller-jl-interface-update-btn',
38-
label: '◉ Initializing',
39-
tooltip: 'Initializing nbgitpuller'
38+
// const updateReposBtn = new ToolbarButton({
39+
// className: 'nbgitpuller-jl-interface-update-btn',
40+
// label: '◉ Initializing',
41+
// tooltip: 'Initializing nbgitpuller'
42+
// });
43+
// updateReposBtn.id = widget_id;
44+
// updateReposBtn.addClass('nbgitpuller-jl-interface-wrapper');
45+
46+
const newWidget = new Widget();
47+
newWidget.id = widget_id;
48+
newWidget.addClass("lm-Widget");
49+
newWidget.addClass("jp-ToolbarButton");
50+
newWidget.addClass("nbgitpuller-jl-interface-wrapper");
51+
newWidget.node.addEventListener('click', async () => {
52+
// Throttle updating
53+
if (currentlyUpdating) {
54+
return;
55+
}
56+
// Set updating flag
57+
currentlyUpdating = true;
58+
59+
// Update widget to running animation
60+
const pendingTooltip = 'Updating Notebooks...';
61+
await setUpdateButtonDisplay(WidgetState.Updating, pendingTooltip);
62+
63+
// Pull each repository
64+
const failed_updates = await makeNbgitpullerRequest(repositories);
65+
66+
// Update widget to all updated or pending updates
67+
await checkForUpdatesAndSetDisplay(repositories);
68+
69+
// Notify users of any failure
70+
if (failed_updates.length !== 0) {
71+
let failure_message = 'Failed to update the following notebooks: \n';
72+
for (const failure of failed_updates) {
73+
failure_message += `${failure['repo']}`;
74+
}
75+
console.log(failure_message);
76+
alert(failure_message);
77+
}
78+
79+
// Unset updating flag
80+
currentlyUpdating = false;
4081
});
41-
updateReposBtn.id = widget_id;
42-
updateReposBtn.addClass('nbgitpuller-jl-interface-wrapper');
82+
4383
// 1-899 left justified, 900+ right justified
44-
app.shell.add(updateReposBtn, 'top', { rank: rank });
84+
app.shell.add(newWidget, 'top', { rank: rank });
4585

4686
// Wait one second for initial creation timing
4787
await new Promise(f => setTimeout(f, 1000));
@@ -174,39 +214,44 @@ export async function checkForUpdatesAndSetDisplay(
174214
numToBeUpdated: number;
175215
numWithErrors: number;
176216
};
217+
177218
// Generate tooltip
178-
let tooltip = '';
179-
if (
180-
updateCheckResponse['numToBeUpdated'] +
181-
updateCheckResponse['numWithErrors']
182-
) {
183-
if (updateCheckResponse['numToBeUpdated']) {
184-
tooltip += `${updateCheckResponse['numToBeUpdated']} notebooks awaiting updates\n`;
185-
}
186-
if (updateCheckResponse['numWithErrors']) {
187-
tooltip += `${updateCheckResponse['numWithErrors']} notebooks with errors`;
188-
}
189-
} else {
219+
let tooltip;
220+
let widgetState;
221+
if (updateCheckResponse['numWithErrors'] > 0){
222+
tooltip = `${updateCheckResponse['numWithErrors']} notebooks with errors`;
223+
widgetState = WidgetState.Error;
224+
225+
}else if(updateCheckResponse['numToBeUpdated'] > 0){
226+
tooltip = `${updateCheckResponse['numToBeUpdated']} notebooks awaiting updates\n`;
227+
widgetState = WidgetState.UpdateRequired;
228+
229+
}else {
190230
tooltip = `${repositories.length} Notebooks up to date`;
231+
widgetState = WidgetState.UpToDate;
191232
}
192233

193234
const updateDisplayResponse = await setUpdateButtonDisplay(
194-
updateCheckResponse['numToBeUpdated'] +
195-
updateCheckResponse['numWithErrors'] ===
196-
0,
235+
widgetState,
197236
tooltip,
198-
repositories
199237
);
200238
if (updateDisplayResponse.returncode !== 0) {
201239
console.error(updateDisplayResponse);
202240
}
203241
}
204242
}
205243

244+
enum WidgetState {
245+
UpToDate,
246+
UpdateRequired,
247+
Updating,
248+
Error,
249+
Initializing,
250+
}
251+
206252
export async function setUpdateButtonDisplay(
207-
upToDate: boolean,
253+
targetWidgetState: WidgetState,
208254
tooltip: string,
209-
repositories: IRepository[]
210255
): Promise<{ error: string; returncode: number }> {
211256
// Get widget
212257
const widget: HTMLElement | null = document.getElementById(widget_id);
@@ -216,56 +261,35 @@ export async function setUpdateButtonDisplay(
216261

217262
// Create button label html
218263
let labelHTML;
219-
if (upToDate) {
264+
if(targetWidgetState == WidgetState.UpToDate){
220265
labelHTML = '<p><span class="success">◉</span> Up to Date</p>';
221-
} else {
222-
labelHTML = '<p><span class="failure blink">◉</span> Update Notebooks</p>';
266+
267+
}else if (targetWidgetState == WidgetState.Updating){
268+
labelHTML = '<p><span class="lds-dual-ring"></span> Updating</p>';
269+
270+
}else if (targetWidgetState == WidgetState.UpdateRequired){
271+
labelHTML = '<p><span class="pending blink">◉</span> Update Error</p>';
272+
273+
}else if (targetWidgetState == WidgetState.Error){
274+
labelHTML = '<p><span class="failure blink">◉</span> Update Error</p>';
275+
276+
}else if (targetWidgetState == WidgetState.Initializing){
277+
labelHTML = '<p><span class="">◉</span> Initializing</p>';
278+
279+
}else{
280+
return { error: "Unknown widget state", returncode: 2 };
223281
}
224282

225-
function generateWidgetHTML(tooltip: string, labelHTML: string): string {
283+
function generateWidgetHTML(labelHTML: string): string {
226284
return `
227-
<div class="lm-Widget jp-ToolbarButton nbgitpuller-jl-interface-wrapper"
228-
title="${tooltip}">
229285
<jp-button class="nbgitpuller-jl-interface-update-btn jp-ToolbarButtonComponent">
230286
${labelHTML}
231-
</jp-button>
232-
</div>`;
287+
</jp-button>`;
233288
}
234289

235290
// Update widget functionality
236-
widget.innerHTML = generateWidgetHTML(tooltip, labelHTML);
237-
widget.addEventListener('click', async () => {
238-
// Throttle updating
239-
if (currentlyUpdating) {
240-
return;
241-
}
242-
// Set updating flag
243-
currentlyUpdating = true;
244-
// Update widget to running animation
245-
const pendingTooltip = 'Updating Notebooks...';
246-
const pendingLabelHTML =
247-
'<p><span class="lds-dual-ring"></span> Updating</p>';
248-
widget.innerHTML = generateWidgetHTML(pendingTooltip, pendingLabelHTML);
249-
250-
// Pull each repository
251-
const failed_updates = await makeNbgitpullerRequest(repositories);
252-
253-
// Update widget to all updated or pending updates
254-
await checkForUpdatesAndSetDisplay(repositories);
255-
256-
// Notify users of any failure
257-
if (failed_updates.length !== 0) {
258-
let failure_message = 'Failed to update the following notebooks: \n';
259-
for (const failure of failed_updates) {
260-
failure_message += `${failure['repo']}`;
261-
}
262-
console.log(failure_message);
263-
alert(failure_message);
264-
}
265-
266-
// Unset updating flag
267-
currentlyUpdating = false;
268-
});
291+
widget.title = tooltip;
292+
widget.innerHTML = generateWidgetHTML(labelHTML);
269293

270294
return { error: '', returncode: 0 };
271295
}

style/base.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ jp-button.nbgitpuller-jl-interface-update-btn {
3232
color: #5cb85c;
3333
}
3434

35+
.pending {
36+
color: #f29339;
37+
}
38+
3539
.failure {
3640
color: #d63124;
3741
}

0 commit comments

Comments
 (0)