kopia lustrzana https://github.com/deathbeds/ipydrawio
Minimal RetroLab support (#72)
rodzic
74ac7228b3
commit
33097b5c56
|
@ -77,6 +77,7 @@ dependencies:
|
|||
- pillow
|
||||
- pypdf2
|
||||
- requests_cache
|
||||
- retrolab
|
||||
# building
|
||||
- pip
|
||||
- twine
|
||||
|
|
|
@ -35,6 +35,7 @@ dependencies:
|
|||
- pillow
|
||||
- pypdf2
|
||||
- requests_cache
|
||||
- retrolab
|
||||
# building
|
||||
- pip
|
||||
- twine
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#### @deathbeds/ipydrawio 1.1.2
|
||||
|
||||
- minimal support for RetroLab [#72]
|
||||
|
||||
#### @deathbeds/ipydrawio-notebook 1.1.2
|
||||
|
||||
#### @deathbeds/ipydrawio-webpack 15.7.300
|
||||
|
@ -18,6 +20,8 @@
|
|||
|
||||
#### @deathbeds/ipydrawio-pdf 1.1.2
|
||||
|
||||
[#72]: https://github.com/deathbeds/ipydrawio/issues/72
|
||||
|
||||
## Releases
|
||||
|
||||
### ipydrawio 1.1.1
|
||||
|
|
10
README.md
10
README.md
|
@ -25,12 +25,14 @@ pip install ipydrawio[all]
|
|||
## Features
|
||||
|
||||
- `ipydrawio`
|
||||
- full support for JupyterLab
|
||||
- best-effort support for JupyterLiteⓁ and RetroLabⓡ
|
||||
- Edit multi-page [documents][]
|
||||
- with nearly the same UI and features as [diagrams.net][drawio]
|
||||
- in many file formats
|
||||
- Drawio/mxgraph XML, SVG, PNG
|
||||
- or Jupyter Notebooks
|
||||
- with all the Drawio templates
|
||||
- or Jupyter Notebooksⓡ
|
||||
- with all the Drawio templatesⓡ
|
||||
- plus some Jupyter ones
|
||||
- Jupyter [rich display][] output
|
||||
- Jupyter [Widgets][]
|
||||
|
@ -40,7 +42,7 @@ pip install ipydrawio[all]
|
|||
known yet)
|
||||
- no presence indicators for other editors
|
||||
- `ipydrawio-export`
|
||||
- Export print-quality PDF from diagrams
|
||||
- Export print-quality PDF from diagramsⓁⓡ
|
||||
- optionally include editable Drawio XML as a PDF attachment
|
||||
- > _BEWARE: some **heavy**, maybe fragile dependencies, `mamba`
|
||||
> recommended_
|
||||
|
@ -50,6 +52,8 @@ pip install ipydrawio[all]
|
|||
pip install ipydrawio ipydrawio-export
|
||||
```
|
||||
|
||||
> ⓡ: unavailable in RetroLab Ⓛ: unavailable in JupyterLite
|
||||
|
||||
## Examples
|
||||
|
||||
| Note | Screenshot/Example |
|
||||
|
|
|
@ -268,7 +268,6 @@ Clean Up After Working With File
|
|||
[Arguments] ${file}
|
||||
Remove File ${OUTPUT DIR}${/}home${/}${file}
|
||||
Reset Application State
|
||||
Lab Log Should Not Contain Known Error Messages
|
||||
|
||||
Wait For Dialog
|
||||
Wait Until Page Contains Element ${DIALOG WINDOW} timeout=180s
|
||||
|
@ -331,3 +330,10 @@ Launch Custom Diagram
|
|||
Accept Custom Options
|
||||
Click Element ${CSS ACCEPT CUSTOM}
|
||||
Wait Until Element is Visible ${CSS DIO IFRAME} timeout=20s
|
||||
|
||||
Wait for a Diagram to be Ready
|
||||
${doc id} = Get Element Attribute ${CSS DIO READY} id
|
||||
Select Frame ${CSS DIO IFRAME}
|
||||
Double Click Element ${CSS DIO BG}
|
||||
Capture Page Screenshot 00-launched.png
|
||||
[Return] ${doc id}
|
||||
|
|
|
@ -47,7 +47,8 @@ ${JLAB XP CLOSE SETTINGS} ${JLAB XP DOCK TAB}\[contains(., 'Settings')]/*[con
|
|||
# launcher
|
||||
${XP LAUNCH TAB} ${JLAB XP DOCK TAB}//*[contains(text(), 'Launcher')]
|
||||
${CSS LAUNCHER} css:.jp-Launcher-body
|
||||
${CSS LAUNCH DIO} css:.jp-LauncherCard[title='Create a blank .dio file'] svg
|
||||
${CREATE A BLANK} Create a blank .dio file
|
||||
${CSS LAUNCH DIO} css:.jp-LauncherCard[title='${CREATE A BLANK}'] svg
|
||||
${CSS LAUNCH CUSTOM} css:.jp-LauncherCard[title='Create a diagram with customized formats, templates, and UI'] svg
|
||||
# ipykernel 5 is "Python 3". ipykernel 6 is "Python 3 (ipykernel)"... but only works on python 3.7+
|
||||
# TODO: consider capturing this information as a tag
|
||||
|
@ -94,3 +95,5 @@ ${XP DIO FORMAT PANE VISIBLE} ${XP DIO FORMAT PANE}\[not(contains(@style, 'di
|
|||
${XP DIO PAGE SIZE} //div[contains(@class, "geFormatSection")][contains(., "Paper Size")]//select
|
||||
# mime
|
||||
${MIME STDERR} application/vnd.jupyter.stderr
|
||||
# retro
|
||||
${CSS RETRO TREE DIO BTN} css:button[title='${CREATE A BLANK}']
|
||||
|
|
|
@ -83,10 +83,7 @@ Validate Export Format
|
|||
|
||||
Prepare a Diagram for Export
|
||||
Launch Untitled Diagram
|
||||
${doc id} = Get Element Attribute ${CSS DIO READY} id
|
||||
Select Frame ${CSS DIO IFRAME}
|
||||
Double Click Element ${CSS DIO BG}
|
||||
Capture Page Screenshot 00-launched.png
|
||||
${doc id} = Wait for a Diagram to be Ready
|
||||
[Return] ${doc id}
|
||||
|
||||
Add a Shape to a Diagram
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright 2021 ipydrawio contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation tree tests
|
||||
Resource ./_Keywords.robot
|
||||
Resource ../_Variables.robot
|
||||
|
||||
*** Test Cases ***
|
||||
New Diagram
|
||||
[Documentation] Does the the tree button work?
|
||||
Create a Diagram from Retro Tree
|
||||
Open Retro Path untitled.dio
|
||||
Wait Until Keyword Succeeds 5x 5s Wait for a Diagram to be Ready
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright 2021 ipydrawio contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation smoke tests
|
||||
Resource ./_Keywords.robot
|
||||
|
||||
*** Test Cases ***
|
||||
Smoke
|
||||
[Documentation] Does the app even load?
|
||||
Capture Page Screenshot 00-smoke.png
|
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2021 ipydrawio contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation tree tests
|
||||
Resource ./_Keywords.robot
|
||||
Resource ../_Variables.robot
|
||||
|
||||
*** Test Cases ***
|
||||
New Diagram
|
||||
[Documentation] Does the the tree button work?
|
||||
Create a Diagram from Retro Tree
|
|
@ -0,0 +1,39 @@
|
|||
# Copyright 2021 ipydrawio contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation A work-in-progress set of keywords for RetroLab
|
||||
Library SeleniumLibrary
|
||||
Resource ../_Keywords.robot
|
||||
|
||||
*** Keywords ***
|
||||
Setup Server and Retro Browser
|
||||
Setup Server and Browser
|
||||
Set Screenshot Directory ${OUTPUT DIR}${/}retro
|
||||
Open Retro Tree
|
||||
|
||||
Open Retro Tree
|
||||
Go To ${URL}retro/tree
|
||||
Wait Until Page Contains Element css:#main
|
||||
Sleep 1s
|
||||
|
||||
Open Retro Path
|
||||
[Arguments] ${path}
|
||||
Go To ${URL}retro/edit/${path}
|
||||
|
||||
Create a Diagram from Retro Tree
|
||||
Wait Until Page Contains Element ${CSS RETRO TREE DIO BTN}
|
||||
Click Element ${CSS RETRO TREE DIO BTN}
|
||||
Switch Window NEW
|
||||
Wait Until Keyword Succeeds 5x 5s Wait for a Diagram to be Ready
|
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2021 ipydrawio contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation Retro
|
||||
Force Tags os:${OS.lower()} py:${PY} app:retro
|
||||
Resource ../_Keywords.robot
|
||||
Resource ./_Keywords.robot
|
||||
Resource ../_Variables.robot
|
||||
Suite Setup Setup Server and Retro Browser
|
||||
Suite Teardown Tear Down Everything
|
||||
Test Setup Open Retro Tree
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"LiteBuildConfig": {
|
||||
"apps": ["lab"],
|
||||
"contents": ["."],
|
||||
"federated_extensions": [
|
||||
"../py_packages/ipydrawio/dist/ipydrawio-1.1.2-py3-none-any.whl",
|
||||
|
@ -13,7 +12,7 @@
|
|||
"https://github.com/conda-forge/releases/releases/download/noarch/wxyz_svg-0.5.1-pyhd8ed1ab_0.tar.bz2/wxyz_svg-0.5.1-pyhd8ed1ab_0.tar.bz2"
|
||||
],
|
||||
"ignore_contents": [
|
||||
"(lab/|_output|.gitignore|doit.db|\\.json$|jupyter_config|log$|\\.cache)"
|
||||
"(lab/|_output|.gitignore|doit.db|\\.json$|jupyter_config|log$|\\.cache|\\.ipynb_checkpoints)"
|
||||
],
|
||||
"ignore_sys_prefix": true,
|
||||
"lite_dir": ".",
|
||||
|
|
|
@ -9,10 +9,15 @@
|
|||
id="demo-room-button"
|
||||
>
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
Try <strong>IPyDrawio</strong> Now <span id="demo-room-label"></span>
|
||||
Try <strong>IPyDrawio</strong> Now <span id="demo-room-label"></span> <span id="demo-app-label"></span>
|
||||
</a>
|
||||
<details>
|
||||
<summary><i class="fas fa-users"></i>Collaboration...</summary>
|
||||
<summary><i class="fas fa-flask"></i> App...</summary>
|
||||
<input type="checkbox" id="demo-app"></input>
|
||||
<em>Use RetroLab (some features disabled)</em>
|
||||
</details>
|
||||
<details>
|
||||
<summary><i class="fas fa-users"></i> Collaboration...</summary>
|
||||
<input type="text" placeholder="room name" id="demo-room-name"></input><br/>
|
||||
<em>everyone who uses this room name will be able to edit all files</em>
|
||||
</details>
|
||||
|
@ -29,14 +34,20 @@
|
|||
<hr/>
|
||||
<em>Powered by <a href="https://jupyterlite.rtfd.io" target="_blank">JupyterLite</a></em>
|
||||
<script>$(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
$("#demo-room-name").on('input', () => {
|
||||
const labUrl = `{{ pathto('demo/index') }}`;
|
||||
const retroUrl = `{{ pathto('demo/retro/index') }}`;
|
||||
function updateUrl() {
|
||||
const room = $("#demo-room-name").val().trim();
|
||||
const useRetro = $("#demo-app").prop("value") === "on";
|
||||
$("#demo-room-button").attr(
|
||||
"href",
|
||||
`{{ pathto('demo/index') }}` + (room ? `?room=${room}` : '')
|
||||
(useRetro ? retroUrl : labUrl) + (room ? `?room=${room}` : '')
|
||||
);
|
||||
$("#demo-app-label").text(useRetro ? ` in RetroLab` : '');
|
||||
$("#demo-room-label").text(room ? ` with ${room}` : '');
|
||||
});
|
||||
}
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
$('#demo-app').on('change', updateUrl);
|
||||
$("#demo-room-name").on('input', updateUrl);
|
||||
});</script>
|
||||
</div>
|
||||
|
|
|
@ -67,7 +67,10 @@ autosectionlabel_prefix_document = True
|
|||
myst_heading_anchors = 3
|
||||
suppress_warnings = ["autosectionlabel.*"]
|
||||
|
||||
rediraffe_redirects = {"demo/index": "_static/lab/index"}
|
||||
rediraffe_redirects = {
|
||||
"demo/index": "_static/lab/index",
|
||||
"demo/retro/index": "_static/retro/tree/index",
|
||||
}
|
||||
|
||||
# files
|
||||
templates_path = ["_templates"]
|
||||
|
|
|
@ -50,6 +50,7 @@ dependencies:
|
|||
- pillow
|
||||
- pypdf2
|
||||
- requests_cache
|
||||
- retrolab
|
||||
# building
|
||||
- pip
|
||||
- twine
|
||||
|
|
25
dodo.py
25
dodo.py
|
@ -288,7 +288,10 @@ def task_lint():
|
|||
yield P._ok(
|
||||
dict(
|
||||
name="prettier",
|
||||
file_dep=[P.YARN_INTEGRITY, *P.ALL_PRETTIER],
|
||||
file_dep=[
|
||||
P.YARN_INTEGRITY,
|
||||
*[p for p in P.ALL_PRETTIER if P != P.DEMO_CONFIG],
|
||||
],
|
||||
actions=[[*prettier_args, *P.ALL_PRETTIER]],
|
||||
),
|
||||
P.OK_PRETTIER,
|
||||
|
@ -384,15 +387,14 @@ def task_lint():
|
|||
P.OK_RFLINT,
|
||||
)
|
||||
|
||||
# TODO: try to get this back
|
||||
# yield P._ok(
|
||||
# dict(
|
||||
# name="robot:dryrun",
|
||||
# file_dep=[*P.ALL_ROBOT, P.OK_RFLINT],
|
||||
# actions=[[*P.PYM, "scripts.atest", "--dryrun"]],
|
||||
# ),
|
||||
# P.OK_ROBOT_DRYRUN,
|
||||
# )
|
||||
yield P._ok(
|
||||
dict(
|
||||
name="robot:dryrun",
|
||||
file_dep=[*P.ALL_ROBOT, P.OK_RFLINT],
|
||||
actions=[[*P.PYM, "scripts.atest", "--dryrun"]],
|
||||
),
|
||||
P.OK_ROBOT_DRYRUN,
|
||||
)
|
||||
|
||||
|
||||
def task_build():
|
||||
|
@ -916,8 +918,7 @@ def task_test():
|
|||
|
||||
if not P.TESTING_IN_CI:
|
||||
file_dep += [
|
||||
# TODO: try to get this back
|
||||
# P.OK_ROBOT_DRYRUN,
|
||||
P.OK_ROBOT_DRYRUN,
|
||||
P.DEMO_HASHES,
|
||||
*P.OK_SERVEREXT.values(),
|
||||
]
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import { JupyterLab, JupyterFrontEndPlugin } from '@jupyterlab/application';
|
||||
|
||||
import { PageConfig } from '@jupyterlab/coreutils';
|
||||
import { drawioPlainIcon, IDiagramManager } from '@deathbeds/ipydrawio';
|
||||
|
||||
import { CommandIds, PLUGIN_ID } from './tokens';
|
||||
|
@ -39,6 +40,13 @@ function activate(
|
|||
diagrams: IDiagramManager,
|
||||
notebooks: INotebookTracker
|
||||
) {
|
||||
if (PageConfig.getOption('retroPage')) {
|
||||
console.warn('Unavailable in', app.name, ':', ALL_FORMATS[0].factoryName);
|
||||
console.info(
|
||||
'Please open a full JupyterLab from View -> Open with JupyterLab'
|
||||
);
|
||||
return;
|
||||
}
|
||||
for (const format of ALL_FORMATS) {
|
||||
diagrams.addFormat(format);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ const LIGHT = ['light'];
|
|||
let THEME_TAGS: Record<SCHEMA.UITheme, string[]> = {
|
||||
kennedy: [...FULL_UI, ...LIGHT],
|
||||
dark: [...FULL_UI, ...DARK],
|
||||
sketch: [...LIGHT, ...DARK],
|
||||
sketch: [...FULL_UI, ...LIGHT, ...DARK],
|
||||
min: [...FULL_UI, ...LIGHT, ...DARK],
|
||||
atlas: [...FULL_UI, ...LIGHT],
|
||||
};
|
||||
|
|
|
@ -186,6 +186,10 @@ export class DiagramFactory extends ABCWidgetFactory<
|
|||
});
|
||||
return doc;
|
||||
}
|
||||
|
||||
create(context: DocumentRegistry.Context): DiagramDocument {
|
||||
return this.createNewWidget(context);
|
||||
}
|
||||
}
|
||||
|
||||
export namespace DiagramFactory {
|
||||
|
|
|
@ -59,12 +59,13 @@ export class DiagramManager implements IDiagramManager {
|
|||
private _settings: ISettingRegistry.ISettings;
|
||||
private _palette: ICommandPalette;
|
||||
private _browserFactory: IFileBrowserFactory;
|
||||
private _restorer: ILayoutRestorer;
|
||||
private _restorer: ILayoutRestorer | null;
|
||||
private _app: JupyterLab;
|
||||
private _status: DrawioStatus.Model;
|
||||
private _mimeExport = new Map<string, IFormat>();
|
||||
private _templates = new Map<string, ITemplate>();
|
||||
private _templatesChanged = new Signal<IDiagramManager, void>(this);
|
||||
private _formatsChanged = new Signal<IDiagramManager, void>(this);
|
||||
|
||||
constructor(options: DiagramManager.IOptions) {
|
||||
this._app = options.app;
|
||||
|
@ -125,10 +126,14 @@ export class DiagramManager implements IDiagramManager {
|
|||
/**
|
||||
* Retrieve a list of the supported formats
|
||||
*/
|
||||
get formats() {
|
||||
get formats(): IFormat[] {
|
||||
return [...this._formats.values()];
|
||||
}
|
||||
|
||||
get formatsChanged(): Signal<IDiagramManager, void> {
|
||||
return this._formatsChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the best diagram format for this contents model
|
||||
*/
|
||||
|
@ -346,6 +351,7 @@ export class DiagramManager implements IDiagramManager {
|
|||
format.isDefault ? [format] : []
|
||||
);
|
||||
DEBUG && console.warn(`...tracked ${format.name}`);
|
||||
this._formatsChanged.emit(void 0);
|
||||
}
|
||||
|
||||
protected updateWidgetSettings(widget: DiagramDocument) {
|
||||
|
@ -438,7 +444,8 @@ export class DiagramManager implements IDiagramManager {
|
|||
};
|
||||
|
||||
this._app.commands.addCommand(`drawio:export-${key}`, {
|
||||
label: `Export ${IO.XML_NATIVE.label} as ${label}`,
|
||||
label: (args) =>
|
||||
args.justLabel ? label : `Export ${IO.XML_NATIVE.label} as ${label}`,
|
||||
icon,
|
||||
execute: () => {
|
||||
let cwd = this._browserFactory.defaultBrowser.model.path;
|
||||
|
@ -513,13 +520,15 @@ export class DiagramManager implements IDiagramManager {
|
|||
const tracker = new WidgetTracker<DiagramDocument>({ namespace });
|
||||
|
||||
// Handle state restoration.
|
||||
this._restorer
|
||||
.restore(tracker, {
|
||||
command: 'docmanager:open',
|
||||
args: (widget) => ({ path: widget.context.path, factory: name }),
|
||||
name: (widget) => widget.context.path,
|
||||
})
|
||||
.catch(console.warn);
|
||||
if (this._restorer) {
|
||||
this._restorer
|
||||
.restore(tracker, {
|
||||
command: 'docmanager:open',
|
||||
args: (widget) => ({ path: widget.context.path, factory: name }),
|
||||
name: (widget) => widget.context.path,
|
||||
})
|
||||
.catch(console.warn);
|
||||
}
|
||||
|
||||
factory.widgetCreated.connect((sender, widget) => {
|
||||
this._status.status = `Loading Diagram...`;
|
||||
|
@ -578,7 +587,7 @@ export namespace DiagramManager {
|
|||
*/
|
||||
export interface IOptions extends IDiagramManager.IOptions {
|
||||
app: JupyterLab;
|
||||
restorer: ILayoutRestorer;
|
||||
restorer: ILayoutRestorer | null;
|
||||
palette: ICommandPalette;
|
||||
browserFactory: IFileBrowserFactory;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import {
|
|||
import { DiagramManager } from './manager';
|
||||
import { RenderedDiagram } from './mime';
|
||||
import widgetPlugin from './widgetPlugin';
|
||||
import retroPlugin from './retroPlugin';
|
||||
|
||||
/**
|
||||
* The editor tracker extension.
|
||||
|
@ -58,27 +59,19 @@ import widgetPlugin from './widgetPlugin';
|
|||
const plugin: JupyterFrontEndPlugin<IDiagramManager> = {
|
||||
activate,
|
||||
id: PLUGIN_ID,
|
||||
requires: [
|
||||
IFileBrowserFactory,
|
||||
ILayoutRestorer,
|
||||
IMainMenu,
|
||||
ICommandPalette,
|
||||
ISettingRegistry,
|
||||
],
|
||||
optional: [ILauncher, IStatusBar],
|
||||
requires: [IFileBrowserFactory, IMainMenu, ICommandPalette, ISettingRegistry],
|
||||
optional: [ILayoutRestorer, ILauncher, IStatusBar],
|
||||
provides: IDiagramManager,
|
||||
autoStart: true,
|
||||
};
|
||||
|
||||
export default [plugin, widgetPlugin];
|
||||
|
||||
function activate(
|
||||
app: JupyterLab,
|
||||
browserFactory: IFileBrowserFactory,
|
||||
restorer: ILayoutRestorer,
|
||||
menu: IMainMenu,
|
||||
palette: ICommandPalette,
|
||||
settingsRegistry: ISettingRegistry,
|
||||
restorer: ILayoutRestorer | null,
|
||||
launcher: ILauncher | null,
|
||||
statusBar: IStatusBar | null
|
||||
): IDiagramManager {
|
||||
|
@ -101,11 +94,6 @@ function activate(
|
|||
});
|
||||
}
|
||||
|
||||
// add first-party file types
|
||||
for (const format of IO.ALL_FORMATS) {
|
||||
manager.addFormat(format);
|
||||
}
|
||||
|
||||
settingsRegistry
|
||||
.load(PLUGIN_ID)
|
||||
.then((loadedSettings) => {
|
||||
|
@ -127,17 +115,6 @@ function activate(
|
|||
rank: 2,
|
||||
category: IO.XML_NATIVE.label,
|
||||
});
|
||||
|
||||
// for (const ui of UI_THEMES) {
|
||||
// launcher.add({
|
||||
// command: CommandIds.createNew,
|
||||
// args: {
|
||||
// drawioUrlParams: { ui },
|
||||
// },
|
||||
// rank: 2,
|
||||
// category: IO.XML_NATIVE.label,
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
commands.addCommand(CommandIds.setUrlParams, {
|
||||
|
@ -184,9 +161,12 @@ function activate(
|
|||
}
|
||||
|
||||
if (menu) {
|
||||
const { fileMenu, settingsMenu } = menu;
|
||||
|
||||
// Add new text file creation to the file menu.
|
||||
menu.fileMenu.newMenu.addGroup([{ command: CommandIds.createNew }], 40);
|
||||
|
||||
// themes
|
||||
const theme = new Menu({ commands });
|
||||
theme.title.label = `${IO.XML_NATIVE.label} Theme`;
|
||||
|
||||
|
@ -198,13 +178,46 @@ function activate(
|
|||
});
|
||||
}
|
||||
|
||||
// actually add the thing
|
||||
menu.settingsMenu.addGroup(
|
||||
// exports
|
||||
const exportMenu = new Menu({ commands });
|
||||
exportMenu.title.label = `Save and Export ${IO.XML_NATIVE.label} As...`;
|
||||
|
||||
let added = [] as string[];
|
||||
|
||||
manager.formatsChanged.connect(() => {
|
||||
for (const format of manager.formats) {
|
||||
const { key } = format;
|
||||
if (added.includes(key)) {
|
||||
continue;
|
||||
}
|
||||
added.push(key);
|
||||
exportMenu.addItem({
|
||||
command: `drawio:export-${key}`,
|
||||
args: { justValue: true },
|
||||
type: 'command',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// actually add the menus
|
||||
settingsMenu.addGroup(
|
||||
[{ submenu: theme, type: 'submenu' }],
|
||||
DIAGRAM_MENU_RANK
|
||||
);
|
||||
fileMenu.addGroup(
|
||||
[{ submenu: exportMenu, type: 'submenu' }],
|
||||
DIAGRAM_MENU_RANK
|
||||
);
|
||||
}
|
||||
|
||||
RenderedDiagram.manager = manager;
|
||||
|
||||
// add first-party file types
|
||||
for (const format of IO.ALL_FORMATS) {
|
||||
manager.addFormat(format);
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
export default [plugin, widgetPlugin, retroPlugin];
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright 2021 ipydrawio contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { PLUGIN_ID, CommandIds, DEBUG } from '.';
|
||||
import { IDiagramManager } from './tokens';
|
||||
import { PageConfig } from '@jupyterlab/coreutils';
|
||||
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
||||
import { DiagramDocument } from '.';
|
||||
import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
|
||||
|
||||
import { JupyterLab, JupyterFrontEndPlugin } from '@jupyterlab/application';
|
||||
|
||||
import { CommandToolbarButton } from '@jupyterlab/apputils';
|
||||
|
||||
/**
|
||||
* The editor tracker extension.
|
||||
*/
|
||||
const retroPlugin: JupyterFrontEndPlugin<void> = {
|
||||
activate,
|
||||
id: `${PLUGIN_ID}-retro`,
|
||||
requires: [IDiagramManager],
|
||||
optional: [IFileBrowserFactory],
|
||||
autoStart: true,
|
||||
};
|
||||
|
||||
function activate(
|
||||
app: JupyterLab,
|
||||
manager: IDiagramManager,
|
||||
fileBrowser: IFileBrowserFactory
|
||||
) {
|
||||
const retroPage = PageConfig.getOption('retroPage');
|
||||
const { commands } = app;
|
||||
|
||||
DEBUG && console.warn('retro page is', retroPage);
|
||||
|
||||
if (retroPage == 'tree') {
|
||||
const newDiagram = new CommandToolbarButton({
|
||||
commands,
|
||||
id: CommandIds.createNew,
|
||||
});
|
||||
fileBrowser.defaultBrowser.toolbar.insertItem(2, 'new-diagram', newDiagram);
|
||||
} else if (retroPage === 'edit') {
|
||||
app.shell.currentChanged.connect(async (changed) => {
|
||||
const { currentWidget } = app.shell;
|
||||
if (!currentWidget || currentWidget instanceof DiagramDocument) {
|
||||
return;
|
||||
}
|
||||
const context = (currentWidget as any)
|
||||
.context as DocumentRegistry.Context;
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
await context.ready;
|
||||
if (!context.contentsModel) {
|
||||
return;
|
||||
}
|
||||
const format = manager.formatForModel(context.contentsModel);
|
||||
if (!format || !format.isDefault) {
|
||||
return;
|
||||
}
|
||||
const factory = app.docRegistry.getWidgetFactory(format.factoryName);
|
||||
if (!factory) {
|
||||
return;
|
||||
}
|
||||
const favicon = document.querySelector(
|
||||
'link[rel="icon"], link.favicon'
|
||||
) as HTMLLinkElement;
|
||||
favicon.href = `data:image/svg+xml;utf8,${encodeURIComponent(
|
||||
format.icon.svgstr
|
||||
)}`;
|
||||
favicon.type = 'image/svg+xml';
|
||||
app.shell.addClass('jp-IPyDiagram-main');
|
||||
|
||||
currentWidget.dispose();
|
||||
|
||||
await app.commands.execute('docmanager:open', {
|
||||
path: context.path,
|
||||
factory: factory.name,
|
||||
options: { ref: '_noref' },
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default retroPlugin;
|
|
@ -109,6 +109,7 @@ export interface IDiagramManager {
|
|||
templates(): Promise<ITemplate[]>;
|
||||
addTemplates(...template: ITemplate[]): void;
|
||||
templatesChanged: ISignal<IDiagramManager, void>;
|
||||
formatsChanged: ISignal<IDiagramManager, void>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -202,3 +202,20 @@
|
|||
padding: 0 0.25em;
|
||||
margin: 0.25em 0 0 0.25em;
|
||||
}
|
||||
|
||||
/* some overrides for retro-like applications */
|
||||
.jp-IPyDiagram-main #main-panel {
|
||||
max-width: unset;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100% !important;
|
||||
left: 0 !important;
|
||||
}
|
||||
|
||||
.jp-IPyDiagram-big-dialog .jp-Dialog-content {
|
||||
min-width: 95vw;
|
||||
min-height: 95vh;
|
||||
max-width: 95vw;
|
||||
max-height: 95vh;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@ project_urls =
|
|||
classifiers =
|
||||
Development Status :: 4 - Beta
|
||||
Framework :: Jupyter
|
||||
Framework :: Jupyter :: JupyterLab :: 3
|
||||
Framework :: Jupyter :: JupyterLab :: Extensions
|
||||
Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
|
||||
Intended Audience :: Developers
|
||||
Intended Audience :: Information Technology
|
||||
License :: OSI Approved :: Apache Software License
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# `ipydrawio-export` labextensions
|
||||
|
||||
`ipydrawio-export` ships, and enables by default, several JupyterLab 3 _federated extensions_.
|
||||
At some point in the future, these might become smaller packages, and are independently
|
||||
reusable by other _federated modules_.
|
||||
|
||||
- `@deathbeds/ipydrawio-pdf`
|
||||
- a **work-in-progress** attempt to provide an easy-to-install PDF toolchain
|
||||
for drawio (and more?)
|
|
@ -25,12 +25,14 @@ pip install ipydrawio[all]
|
|||
## Features
|
||||
|
||||
- `ipydrawio`
|
||||
- full support for JupyterLab
|
||||
- best-effort support for JupyterLiteⓁ and RetroLabⓡ
|
||||
- Edit multi-page [documents][]
|
||||
- with nearly the same UI and features as [diagrams.net][drawio]
|
||||
- in many file formats
|
||||
- Drawio/mxgraph XML, SVG, PNG
|
||||
- or Jupyter Notebooks
|
||||
- with all the Drawio templates
|
||||
- or Jupyter Notebooksⓡ
|
||||
- with all the Drawio templatesⓡ
|
||||
- plus some Jupyter ones
|
||||
- Jupyter [rich display][] output
|
||||
- Jupyter [Widgets][]
|
||||
|
@ -40,7 +42,7 @@ pip install ipydrawio[all]
|
|||
known yet)
|
||||
- no presence indicators for other editors
|
||||
- `ipydrawio-export`
|
||||
- Export print-quality PDF from diagrams
|
||||
- Export print-quality PDF from diagramsⓁⓡ
|
||||
- optionally include editable Drawio XML as a PDF attachment
|
||||
- > _BEWARE: some **heavy**, maybe fragile dependencies, `mamba`
|
||||
> recommended_
|
||||
|
@ -50,6 +52,8 @@ pip install ipydrawio[all]
|
|||
pip install ipydrawio ipydrawio-export
|
||||
```
|
||||
|
||||
> ⓡ: unavailable in RetroLab Ⓛ: unavailable in JupyterLite
|
||||
|
||||
## Examples
|
||||
|
||||
| Note | Screenshot/Example |
|
||||
|
|
|
@ -31,6 +31,10 @@ project_urls =
|
|||
classifiers =
|
||||
Development Status :: 4 - Beta
|
||||
Framework :: Jupyter
|
||||
Framework :: Jupyter :: JupyterLab :: 3
|
||||
Framework :: Jupyter :: JupyterLab :: Extensions
|
||||
Framework :: Jupyter :: JupyterLab :: Extensions :: Mime Renderers
|
||||
Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
|
||||
Intended Audience :: Developers
|
||||
Intended Audience :: Information Technology
|
||||
License :: OSI Approved :: Apache Software License
|
||||
|
|
|
@ -13,8 +13,9 @@ reusable by other _federated modules_.
|
|||
- the Jupyter Widgets
|
||||
- `@deathbeds/ipydrawio-notebook`
|
||||
- the custom `ipynb` format
|
||||
- `@deathbeds/ipydrawio-pdf`
|
||||
- a **work-in-progress** attempt to provide an easy-to-install PDF toolchain
|
||||
for drawio (and more?)
|
||||
- `@deathbeds/ipydrawio`
|
||||
- the core renderer library
|
||||
- `@deathbeds/ipydrawio-jupyter-templates`
|
||||
- some templates for building Jupyter-related diagrams
|
||||
|
||||
[drawio]: https://github.com/jgraph/drawio
|
||||
|
|
|
@ -841,6 +841,7 @@ def _sync_lite_config(from_env, to_json, marker, extras):
|
|||
config = json.loads(to_json.read_text(encoding="utf-8"))
|
||||
config["LiteBuildConfig"]["federated_extensions"] = sorted(tarball_urls)
|
||||
to_json.write_text(json.dumps(config, indent=2, sort_keys=True))
|
||||
subprocess.call([*PRETTIER, "--write", to_json])
|
||||
|
||||
|
||||
# Late environment hacks
|
||||
|
|
Ładowanie…
Reference in New Issue