Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A better metadata toolbar #1812

Open
flying-sheep opened this issue Oct 5, 2016 · 16 comments
Open

A better metadata toolbar #1812

flying-sheep opened this issue Oct 5, 2016 · 16 comments

Comments

@flying-sheep
Copy link
Contributor

flying-sheep commented Oct 5, 2016

Hi, Notebooks powered by the IRkernel got a competitor (cc @takluyver) i’m pretty sad that they choose to build their own ghetto instead of joining our awesomely growing garden of language-independent tooling.

but to the point: they have some nice features: a progress bar and actually easily editable metadata.

our way to edit cell metadata frankly sucks: hidden behind a huge bar that only holds a small button is a a plain text editor for a JSON blob, which isn’t even highlighted and riddled with internal metadata from plugins (e.g. “collapsed” and “trusted”)

my idea is to standardise some common metadata (apart from the already standard “trusted”), that appears in the extensions latex template

  • hidden (this cell is hidden from nbconvert output, but still able to be run, and can be unhidden by clicking some UI)
  • hide_input, hide_output (self explaining)

then we make that and nonstandard metadata available via a easy to use toolbar.

  1. the bar only appears as bar and only increases cell height when it contains nonstandard cell metadata, which can then be graphically edited. (else it’s maybe just a small rectangle in the cell corner with a expand button)
  2. the UI for metadata i imagine is a horizontal bar with key: value pairs that can easily be appended to or removed from. the values can easily be switched between JSON primitive types.
  3. extensions can register top-level keys that they provide custom UI for, which takes the place of the normal value UI.

a minimum working version would be a expandable/retractable bar with inline JSON editor.

@takluyver
Copy link
Member

One thing that I've wanted for a long time for easy metadata editing is a 'cell tagging' UI, which would let you attach simple tags to cells. We could define some common ones (e.g. hide_output), and extensions could use arbitrary tags for whatever makes sense.

@flying-sheep
Copy link
Contributor Author

flying-sheep commented Oct 5, 2016

you mean switch "metadata": {"hide_output":true} to "metadata": {"tags: ["hide_output"]}?

and then maintain a list of known tags, one of tags in the document, and a UI allowing to easily add tags from both lists or new ones (like this)

@takluyver
Copy link
Member

Yup, exactly. Mostly just because there's already a well-established UI convention, and existing components we may be able to reuse, for 'tags', whereas for editing key-value pairs we'd need something much more custom.

@Carreau
Copy link
Member

Carreau commented Oct 5, 2016

Yes. The tags have been in the notebook format for a couple of year. it's true that just the UI is missing.

cc @michaelpacer

@mpacer
Copy link
Member

mpacer commented Oct 11, 2016

Trying to implement a filter that would look for this. I'm assuming that this is taking the wrong tack, because the error I got trying to keep with our general style of call was that booleans have no get method.

{%- if cell.metadata.get("tags",False).get("hidden", False) -%}

jinja2.exceptions.UndefinedError: 'bool object' has no attribute 'get'

But, if I try to just go with

{%- if cell.metadata.tags.get("hidden", False) -%}

jinja2.exceptions.UndefinedError: 'nbformat.notebooknode.NotebookNode object' has no attribute 'tags'

Some cells don't have a tags part of their metadata and so the call fails.

So I don't think our metadata format should be determined only by how we may be able to easily query their contents, however this does seem unnecessarily complicated.

and just for clarification's sake, this is the data just below the cell level including the metadata with the tags argument (reformatted for human legibility):

    "cell_type": "code",
        "execution_count": 1,
        "metadata": {
            "collapsed": false,
            "deletable": true,
            "editable": true,
            "tags": [
                "hidden"
            ]
     }, 

That was how you were imagining it being stored, correct? @takluyver @Carreau @flying-sheep

@mpacer
Copy link
Member

mpacer commented Oct 11, 2016

Note: this nested dictionary thing seems to be somewhat intractable… at least acc. to this SO: http://stackoverflow.com/questions/10788771/no-side-effect-nested-dictionary-implementation.

@mpacer
Copy link
Member

mpacer commented Oct 11, 2016

Ok so this worked.

{%- if cell.metadata.get("tags",False) and "hidden" in cell.metadata.tags -%}

But that still looks pretty icky.

So I'm attempting to mod the nice toggling in http://www.damian.oquanta.info/posts/mimic-the-ipython-notebook-cell-execution.html.

So the hard part is when you're hiding a cell altogether, there is a need to create something that is clickable that can appear and disappear on the fly depending on whether it is expanded.

I wasn't able to figure out how to do that yet, but I was able to get the following to work.

{%- block any_cell -%}
{%- if cell.metadata.get("tags",False) and "hidden" in cell.metadata.tags -%}
<img class="clickimage" src="broken.png" alt="">
<div class="hidden_cell">
{{super() }}
</div>
{%- else -%}
{{ super() }}
{%- endif -%}
{%- endblock any_cell -%}

and use the image as the clicking target instead of the input area:

<script>
$(document).ready(function(){
    $(".clickimage").click(function(){  // This is where it breaks because there's nothing left to use as the toggle.  
        $(this).next('.hidden_cell').slideToggle();
    });
})
</script>

@flying-sheep
Copy link
Contributor Author

flying-sheep commented Oct 11, 2016

None, as well as empty dicts and lists are falsey, so both things would work:

{% if metadata.get('maybe_dict', {}).get('hidden') %}
metadata['maybe_dict'] is a dict
metadata['maybe_dict']['hidden'] is truthy
{% else %}
metadata doesn’t contain the key 'maybe_dict', or
metadata['maybe_dict'] or metadata['maybe_dict']['hidden'] is falsey.
{% endif %}
{% if 'hidden' in metadata.get('maybe_list', []) %}
metadata['maybe_list'] is a sequence containing the item 'hidden'
{% else %}
metadata doesn’t contain the key 'maybe_list', or
metadata['maybe_list'] doesn’t contain the item 'hidden'
{% endif %}

@mpacer
Copy link
Member

mpacer commented Oct 11, 2016

Since tags as stated above are a list, the latter seems more appropriate and cleaner than my solution.

Other details seem like they should be saved for the nbconvert repo… any thoughts on how to hide things while maintaining a clickable area to unhide them would also be welcome!

@Carreau
Copy link
Member

Carreau commented Oct 11, 2016

Since tags as stated above a list, the latter seems more appropriate and cleaner than my solution.

Other details seem like they should be saved for the nbconvert repo… any thoughts on how to hide things while maintaining a clickable area to unhide them would also be welcome!

See what dashbords from IBM is doing they have a global toggle that make things translucent but not hidden. THen while in this mode click hide/unhide.

@ellisonbg
Copy link
Contributor

Marking this with the JupyterLab milestone as we are working on something over there that would address much of this.

@mpacer
Copy link
Member

mpacer commented Dec 23, 2016

@ellisonbg
Can you link to those jupyterlab prs and issues here?

Is jupyterlab focusing on the UI or the tag semantics?

Also @mgeier had some thoughts about the tagging semantics that are discussed here: spatialaudio/nbsphinx#65

@mgeier
Copy link
Contributor

mgeier commented Dec 23, 2016

@michaelpacer Thanks for bringing this to my attention.

I'm sorry if this was explained already somewhere else, but are you planning to have special UI elements for hiding and unhiding cells/input/output?
Or should everything be done with a generic metadata or tag editing interface?
Those two things seem a bit mixed up in the discussion above.

If there will be special UI elements, I don't think it makes sense to store the state in the list of tags.
Those tags might still be very useful, just not for things that have already special UI elements.

AFAIU, the "tag toolbar" we're talking about here is part of each cell, right?
Now if a cell gets "hidden", will the "tag toolbar" still be visible?

@mgeier
Copy link
Contributor

mgeier commented Jan 2, 2017

My concerns were addressed here: spatialaudio/nbsphinx#65 (comment), thanks!

@mpacer
Copy link
Member

mpacer commented Jan 18, 2017

@blink1073
Copy link
Contributor

Agreed, thanks for coordinating, @michaelpacer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants