mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Created Design: Library Sidebar (markdown)
parent
3148e7e31d
commit
63f94c9fc5
120
Design:-Library-Sidebar.md
Normal file
120
Design:-Library-Sidebar.md
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
The library feature in Node-RED comes in two parts:
|
||||||
|
|
||||||
|
1. the flow library is exposed via the drop-down menu : `import->library->...`
|
||||||
|
2. within nodes that allow part of their config to be saved to a type-specific library, such as Function and Template
|
||||||
|
|
||||||
|
The current UX is fairly bad for the flow library. The drop-down menu is hard to navigate, closes too easily and doesn't work well beyond one or two levels of hierarchy.
|
||||||
|
|
||||||
|
The purpose of this work is to overhaul the library experience, bringing together the two different types of library into one unified design.
|
||||||
|
|
||||||
|
Some notes on what is needed:
|
||||||
|
|
||||||
|
- a single sidebar tab for the library that provides a file-browser like interface
|
||||||
|
- support for different types of library entities (flows, functions, templates, etc)
|
||||||
|
- allow the library to not only get its content from the 'local library' we have today, but also allow custom library sources be provided
|
||||||
|
- custom library sources should either be identified in settings.js (a la palette catalogues), or allow the user to provide a library url to use (a la Eclipse p2 repo model).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Considerations
|
||||||
|
|
||||||
|
We don't currently document the library API as part of the admin http api. That gives us some small amount of freedom to redesign it.
|
||||||
|
|
||||||
|
The Storage API does expose get/set library functions - they should not have to change.
|
||||||
|
|
||||||
|
The current library http API is inconsistent; `flows` have a slightly different behaviour to other library types.
|
||||||
|
|
||||||
|
|
||||||
|
### `/library/[type]/[path]` -> directory
|
||||||
|
|
||||||
|
If a `path` resolves to a directory, a list of the files contained therein is returned:
|
||||||
|
|
||||||
|
```
|
||||||
|
["b",{"fn":"dave"},{"fn":"steve"},{"fn":"test2.json"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Entries are a string if they represent directories, or an object for files with a `fn` property containing the filename.
|
||||||
|
|
||||||
|
**Note**: `path` can be empty to get the top most directory listing - except for when `type` is `flows`. See the later section for what that does.
|
||||||
|
|
||||||
|
### `/library/[type]/[path]` -> file
|
||||||
|
|
||||||
|
If a path resolves to a file, the json is returned.
|
||||||
|
|
||||||
|
**TODO:** write-up what a Function/Template file response looks like.
|
||||||
|
|
||||||
|
### `/library/flows`
|
||||||
|
|
||||||
|
For `flows` type, if the path is empty, it returns a complete listing of all `flow` library entries. The response object is a simple recursive structure; at the top level, two properties might exist:
|
||||||
|
|
||||||
|
- `f` (if it exists) points at an array of filenames that exist at that level.
|
||||||
|
- `d` points at an object whose properties are pathnames and values are objects with `f`/`d` properties.
|
||||||
|
|
||||||
|
Given the structure:
|
||||||
|
```
|
||||||
|
/
|
||||||
|
├── one
|
||||||
|
│ └── example1.json
|
||||||
|
└── two
|
||||||
|
└── three
|
||||||
|
└── example2.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The following representation is returned:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"d": {
|
||||||
|
"one": {
|
||||||
|
"f": [
|
||||||
|
"example1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"two": {
|
||||||
|
"d": {
|
||||||
|
"three": {
|
||||||
|
"f": [
|
||||||
|
"example2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This was done because, unlike the other types that are exposed via a file-browser-like UI, the flows are displayed in the drop-down menu which needs to know about everything at the start to build the menu structure.
|
||||||
|
|
||||||
|
A goal of this work is to make this all consistent!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This reveals two different approaches of what gets returned:
|
||||||
|
|
||||||
|
- a complete summary of the available entries : this allows for a more responsive UI (no network requests whilst browsing the tree). It also allows for a UI that can search/filter the full list of available entries
|
||||||
|
- a directory-by-directory approach : lots more requests, can't search the full list
|
||||||
|
|
||||||
|
This suggests the desired consistent approach is:
|
||||||
|
|
||||||
|
- `/library/[type]` : return a full listing
|
||||||
|
- `/library/[type]/path` : if resolves to an entry, return the entry. Otherwise return the full listing rooted at this point
|
||||||
|
|
||||||
|
The format of the listing response should be made clearer.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"path": "the full path at this level represents",
|
||||||
|
"name": "the name of this entity"
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"path": ...
|
||||||
|
"name": ...
|
||||||
|
"children": [ ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If an entry has no `children` property, it is a file. Otherwise it is a directory.
|
||||||
|
|
||||||
|
---
|
Loading…
Reference in New Issue
Block a user