diff --git a/Design:-Library-Sidebar.md b/Design:-Library-Sidebar.md new file mode 100644 index 0000000..5b44930 --- /dev/null +++ b/Design:-Library-Sidebar.md @@ -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. + +---