rsdeps

Cargo.lock visualizer (mirror)
Log | Files | Refs | README | LICENSE

commit 7f48eba36823231f96fdc606f025caa35219c816
parent e5f295ca7831ce47a57f0dd4975764bfe27dd620
Author: Andy Khramtsov <>
Date:   Sat, 30 May 2026 04:53:42 +0300

docs: add ui docs

Diffstat:
Msrc/deps/aio_components/collapse_aio.py | 22++++++++++++++++------
Msrc/deps/dash_app.py | 2+-
Msrc/deps/pages/home.py | 136++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
3 files changed, 111 insertions(+), 49 deletions(-)

diff --git a/src/deps/aio_components/collapse_aio.py b/src/deps/aio_components/collapse_aio.py @@ -57,11 +57,25 @@ class CollapseAIO(html.Div): ids = ids - def __init__(self, aio_id=None, label="Collapse", content=None, default_hidden: bool = False): + def __init__( + self, + aio_id=None, + label="Collapse", + content=None, + default_hidden: bool = False, + button_wrapper=None, + ): if content is None: content = [] if aio_id is None: aio_id = str(uuid.uuid4()) + + button = dcc.Button( + id=self.ids.button(aio_id), + className="collapse-button", + children=[html.Div(id=self.ids.arrow(aio_id), className="collapse-button__arrow-right"), label], + ) + super().__init__( children=[ dcc.Store( @@ -70,11 +84,7 @@ class CollapseAIO(html.Div): data={"default_hidden": default_hidden}, ), dcc.Store(id=self.ids.store(aio_id), storage_type="local", data={}), - dcc.Button( - id=self.ids.button(aio_id), - className="collapse-button", - children=[html.Div(id=self.ids.arrow(aio_id), className="collapse-button__arrow-right"), label], - ), + button if button_wrapper is None else button_wrapper(button), html.Div( id=self.ids.content(aio_id), className="", diff --git a/src/deps/dash_app.py b/src/deps/dash_app.py @@ -30,7 +30,7 @@ def main(): html.Div( className="horizontal-content horizontal-content_large-gap", children=[ - html.Div(children="Dash App"), + html.Div(children="Cargo.lock visualizer"), html.Div( className="horizontal-content", children=[ diff --git a/src/deps/pages/home.py b/src/deps/pages/home.py @@ -80,44 +80,61 @@ def layout(): return html.Div( className="padded-box vertical-content vertical-content_large-gap", children=[ - html.H2("Cargo dependency visualisation"), dcc.Store(id=ids.cache_store, storage_type="memory"), dcc.Store(id=ids.selected_node_store, storage_type="memory"), html.Div( + className="horizontal-content horizontal-content_center", + children=[ + html.H2("Cargo dependency visualisation"), + html.Abbr( + "?", + title="Upload Cargo.lock and optionally Cargo.toml to see the full dependency graph. " + "Multiple select avaliable for file upload. Or just paste the contents into the fields.\n\n" + "It is possible to render the dependency graph of many projects because there is " + "only one Cargo.lock.\n\n" + "Note: Cargo.toml is only used for coloring [dependencies]. " + "The implementation of Cargo.toml parsing is primitive, it will not work on many projects. " + "But it is only the coloring feature, the graph is still fun to see.\n\n" + "Text fields are used as storage and the source of truth, they persist data in local storage.", + className="help-icon", + ), + ], + ), + html.Div( className="vertical-content", children=[ dcc.Upload( className="button", id=ids.upload_files, children=[ - "Upload Cargo.toml and Cargo.lock", + "Upload Cargo.lock and optionally Cargo.toml", ], multiple=True, ), - html.Div("Cargo.toml:"), + html.Div("Cargo.lock (required):"), dcc.Textarea( - id=ids.cargo_toml_textarea, - placeholder="Cargo.toml contents", + id=ids.cargo_lock_textarea, + placeholder="Cargo.lock contents", persistence=True, ), html.Div( html.Button( className="button", - id=ids.cargo_toml_clear, - children="Clear Cargo.toml", + id=ids.cargo_lock_clear, + children="Clear Cargo.lock", ), ), - html.Div("Cargo.lock:"), + html.Div("Cargo.toml (optional):"), dcc.Textarea( - id=ids.cargo_lock_textarea, - placeholder="Cargo.lock contents", + id=ids.cargo_toml_textarea, + placeholder="Cargo.toml contents", persistence=True, ), html.Div( html.Button( className="button", - id=ids.cargo_lock_clear, - children="Clear Cargo.lock", + id=ids.cargo_toml_clear, + children="Clear Cargo.toml", ), ), ], @@ -126,42 +143,77 @@ def layout(): aio_id=ids.collapse_tables, label="Table view", default_hidden=True, + button_wrapper=lambda button: html.Div( + className="horizontal-content horizontal-content_center", + children=[ + button, + html.Abbr( + "?", + title="Cargo.toml and Cargo.lock dataframes in table form.\n" + "This is what gets rendered into the graph below.", + className="help-icon", + ), + ], + ), content=[ - html.Button( - className="button", - id=ids.recalculate_button, - children="Recalculate", - ), - html.H3("Cargo toml dependencies"), - TableAIO( - aio_id=ids.cargo_toml_table, - column_defs=[ - {"field": i, "colId": i} - for i in [ - "name", - ] - ], - ), - html.H3("Cargo lock packages"), - TableAIO( - aio_id=ids.cargo_lock_table, - column_defs=[ - {"field": i, "colId": i} - for i in [ - "name", - "version", - "source", - "checksum", - "dependencies", - ] + html.Div( + className="vertical-content", + children=[ + html.Button( + className="button", + id=ids.recalculate_button, + children="Recalculate", + ), + html.H3("Cargo toml dependencies"), + TableAIO( + aio_id=ids.cargo_toml_table, + column_defs=[ + {"field": i, "colId": i} + for i in [ + "name", + ] + ], + ), + html.H3("Cargo lock packages"), + TableAIO( + aio_id=ids.cargo_lock_table, + column_defs=[ + {"field": i, "colId": i} + for i in [ + "name", + "version", + "source", + "checksum", + "dependencies", + ] + ], + ), ], - ), + ) ], ), html.Div( className="vertical-content", children=[ - html.H3("Dependency graph"), + html.Div( + className="horizontal-content horizontal-content_center", + children=[ + html.H3("Dependency graph"), + html.Abbr( + "?", + title="Click on 'Generate' to generate Cargo.lock graph (it is normal for it to take " + "some time).\n\n" + "Graph is Left-to-Right, meaning nodes (packages) to the right are dependencies of " + "nodes (packages) to the left, if they are connected with an arc (edge).\n" + "Or you can think of the graph as if all the edges are directed only to the right or " + "only to the left, it doesn't matter.\n\n" + "Click on any node to see its neighbors. Click it again to deselect, or use the " + "'Deselect' button.\n\n" + "Packages from [dependencies] in Cargo.toml are colored red.", + className="help-icon", + ), + ], + ), html.Div( className="horizontal-content horizontal-content_small-gap", children=[ @@ -173,7 +225,7 @@ def layout(): html.Button( className="button", id=ids.reset_highlight_button, - children="Reset highlight", + children="Deselect", ), ], ),