We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Jump to file
- ∟ assets/js/app.js
- ∟ lib/my_app/storage.ex
- ∟ lib/my_app/storage/drive.ex
- ∟ lib/my_app/storage/drive/directory.ex
- ∟ lib/my_app/storage/drive/directory_user.ex
- ∟ lib/my_app/storage/drive/object_directory.ex
- ∟ lib/my_app/storage/object.ex
- ∟ lib/my_app_web/live/drive_live.ex
- ∟ lib/my_app_web/live/drive_live/components.ex
- ∟ lib/my_app_web/live/drive_live/directory_form_component.ex
- ∟ lib/my_app_web/router.ex
- ∟ priv/repo/migrations/20240531120111_create_storage_objects_directories.exs
JavaScript helpers
Add a global event listener on
"my_app:open"
. This will be used later for triggering file downloads.
|
|
|
|
|
|
|
|
+ |
|
+ |
|
+ |
|
+ |
|
|
|
|
|
|
Modify existing Storage context
Update the call to
Object.insert_assocs_multi/2
in our existing Storage context to accept uploads to directories.
|
|
|
|
|
|
|
|
- |
|
+ |
|
|
|
|
|
|
Drive sub-context
Here we introduce a new sub-context,
MyApp.Storage.Drive
, responsible for operations managing directories and their contents.
See documentation for individual functions for what their purposes are and how they work.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
Directory schema
Defines a schema for a directory. A directory has a name, an optional parent (if it is a child directory), and can be marked as deleted.
This module includes standard changesets and queries for directories.
However, there is also a more advanced usage of Ecto: recursive common table expressions (CTE).
The function
recursive_directory_tree_query/3
exposes a functional interface for querying directories in a tree structure.
This is useful when you want to do something that involves a hierarchy of directories.
As the doc string states, examples of this are querying breadcrumbs (all parents of a child directory) and applying auth restrictions (user must own directory or a parent of a directory).
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
DirectoryUser schema
Schema that defines a relationship between a directory and a user. Although not implemented in this guide, this is a many-to-many structure and so can support directories with many users. Additional fields may be added for defining user-specific ownership rules.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
ObjectDirectory schema
Schema that defines a relationship between a directory and an object. Generally, an object should only ever be in a single directory. Add a unique constraint if this should be enforced at the database level.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
Update existing Object schema
Here we make a small modification to our
Object
schema which allows existing code to associate new objects with a particular directory.
|
|
|
|
|
|
|
|
+ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ |
|
+ |
|
+ |
|
|
|
|
|
|
Drive LiveView
This is a LiveView implementation of a Drive directory and file management UI. It might seem intimidating, however there is a lot of functionality here for comparatively little code. In this one module, we implement behavior to create, update, view, delete, and navigate directories, show breadcrumbs for the current directory, and upload files to the current directory. All of this while also scoping operations to the currently signed in user.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
Drive components
To keep our LiveView module less cluttered, we add a separate components module which contains the components specific to our Drive. Right now, this only has our breadcrumbs component, but as the interface becomes more complex new components can be placed here.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
Directory form component
A LiveComponent that contains the functionality for creating and updating directory fields. Right now, this is only the name of the directory. However, you can imagine that this might be where permissions and sharing features are managed.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
Router updates
These are the new routes we need to add for our new Drive LiveView to function.
|
|
|
|
|
|
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
|
|
|
|
|
Migration
Creates tables for directories and associating directories with other records in our app domain. Add fields, constraints, and other associations here as needed.
|
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|
+ |
|