From b16b3e523d38e21076f8a9891cd4baf5958e918d Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Fri, 4 Dec 2020 19:04:02 +0100 Subject: [PATCH] Add checkpoint indicator --- packages/application-extension/src/index.ts | 50 ++++++++++++++++++- packages/application-extension/style/base.css | 10 ++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/packages/application-extension/src/index.ts b/packages/application-extension/src/index.ts index 0f57f08b2..2aff95010 100644 --- a/packages/application-extension/src/index.ts +++ b/packages/application-extension/src/index.ts @@ -14,7 +14,7 @@ import { DOMUtils } from '@jupyterlab/apputils'; -import { PageConfig } from '@jupyterlab/coreutils'; +import { PageConfig, Time } from '@jupyterlab/coreutils'; import { IDocumentManager, renameDialog } from '@jupyterlab/docmanager'; @@ -44,6 +44,53 @@ namespace CommandIDs { export const open = 'docmanager:open'; } +/** + * A plugin for the checkpoint indicator + */ +const checkpoints: JupyterFrontEndPlugin = { + id: '@jupyterlab-classic/application-extension:checkpoints', + autoStart: true, + requires: [IDocumentManager], + optional: [IClassicShell], + activate: ( + app: JupyterFrontEnd, + docManager: IDocumentManager, + classicShell: IClassicShell + ) => { + const { shell } = app; + const widget = new Widget(); + widget.id = DOMUtils.createDomID(); + widget.addClass('jp-ClassicCheckpoint'); + app.shell.add(widget, 'top', { rank: 100 }); + + const onChange = async () => { + const current = shell.currentWidget; + if (!current) { + return; + } + const context = docManager.contextForWidget(current); + + context?.fileChanged.disconnect(onChange); + context?.fileChanged.connect(onChange); + + const checkpoints = await context?.listCheckpoints(); + if (!checkpoints) { + return; + } + const checkpoint = checkpoints[checkpoints.length - 1]; + widget.node.textContent = `Last Checkpoint: ${Time.formatHuman( + new Date(checkpoint.last_modified) + )}`; + }; + + if (classicShell) { + classicShell.currentChanged.connect(onChange); + } else { + onChange(); + } + } +}; + /** * The kernel logo plugin. */ @@ -310,6 +357,7 @@ const tree: JupyterFrontEndPlugin = { * Export the plugins as default. */ const plugins: JupyterFrontEndPlugin[] = [ + checkpoints, kernelLogo, logo, main, diff --git a/packages/application-extension/style/base.css b/packages/application-extension/style/base.css index 049399f11..6ece8eca1 100644 --- a/packages/application-extension/style/base.css +++ b/packages/application-extension/style/base.css @@ -36,3 +36,13 @@ #jp-title h1:hover { background: var(--jp-layout-color2); } + +.jp-ClassicCheckpoint { + font-size: 14px; + margin-left: 5px; + margin-right: 5px; + font-weight: normal; + color: var(--jp-ui-font-color0); + font-family: var(--jp-ui-font-family); + line-height: calc(1.5 * var(--jp-private-title-panel-height)); +}