ui: Fix navigation issues To get the bare minimum working, this change adds some basic navigation to the applicaiton. It's far from perfect, but nonetheless, it's something. :)

zj
Oct 7, 2021, 12:20 PM
GD7FCQ2KD5YJQ3UDLAWNJQUAUK4LTHMPFVGHMUAWMKNIBYZWK2NAC

Dependencies

  • [2] E4OBIIUB templates: Fix navigation mocks Cleans up the directory structure for templates and fixes the navigation bugs in the applications too. Includes a context! macro which is lifted from upstream, but is currently unreleased. When rocket_dyn_templates is updates, it could be DRY'ed out.
  • [3] FS2NWBVN pijul: Start of push/pull work This change includes one API endpoint, .pijul. It allows for getting a channels remote ID. A lot of plumbing around repositories is added too, from init to opening pristine and actions like it.
  • [4] TWIZ7QV4 db: Add interface to add a project Right now a project has a name, and an owner which is hardcoded to 1. This is because basically I'm speedrunning to implement push/pull of Pijul and then revisit to add depth to features and tests. Model code is now split into files properly too.
  • [5] F5DMFQAO routes: Move project routes to controllers module Much like other routes, just move the files and clean up the tree.
  • [6] S6TFYMRG routes: Move pijul routes to controllers module As with the root routes, now the pijul routes are moved. The mounting of the routes is still done in main.rs though the controller module now collects them. This should DRY this code
  • [7] KFVJ3KMW frontend: Introduce navigation bar Minor changes to the front-end mostly, to allow users to register, sign in, and sign out. The sign out route is changed to a GET endpoint, as links in HTML cannot DELETE.
  • [8] 3E77DEMD routes: Move root route to controllers module The routes were now in modules in the root, which created a messy situation for the future. For now the routes will be moved to the controllers module and later additional changes will be done to further clean this up.

Change contents

  • file addition: show.html.tera (----------)
    [3.20]
    {% extends "base" %}
    {% block body %}
    <div class="p-5 mb-4 bg-light rounded-3">
    <div class="container-fluid py-5">
    <h1 class="display-5 fw-bold">{{ project.name }}</h1>
    <p class="col-md-8 fs-4">Clone this repository using: <code>pijul clone http://nidobyte.com/{{organisation.name}}/{{project.name}}</code>.</p>
    </div>
    </div>
    {% endblock body %}
  • file addition: explore.html.tera (----------)
    [3.20]
    {% extends "base" %}
    {% block body %}
    <table class="table table-borderless">
    {% for project in projects %}
    <tr>
    <td>{{project.organisation.name}}</td>
    <td><a href="{{project.uri}}">{{project.name}}</a></td>
    </tr>
    {% endfor %}
    </table>
    {% endblock body %}
  • replacement in templates/base.html.tera at line 13
    [3.2437][3.2437:2498]()
    {% block body %}
    <p> foo</p>
    {% endblock body %}
    [3.2437]
    [3.2498]
    <div class="container-fluid">
    {% block body %}
    {% endblock body %}
    </div>
  • replacement in src/models/projects.rs at line 18
    [3.1669][3.1669:1712]()
    proj_path, org_path).fetch_optional(&**db)
    [3.1669]
    [3.1712]
    proj_path, org_path).fetch_optional(&**db)
  • edit in src/models/projects.rs at line 24
    [3.1749]
    [3.1749]
    pub async fn list(db: &State<Database>) -> Result<Vec<Project>, sqlx::Error> {
    sqlx::query_as!(Project, "SELECT * FROM projects")
    .fetch_all(&**db)
    .await
    }
  • edit in src/models/projects.rs at line 48
    [3.2150]
    [3.2150]
    use crate::models::users::User;
  • edit in src/models/projects.rs at line 53
    [3.3728]
    [3.2196]
    pub async fn organisation(&self, db: &State<Database>) -> Result<User> {
    let u = User::find(db, self.owner_id).await?;
    Ok(u)
    }
  • edit in src/models/projects.rs at line 71
    [3.4073]
    #[derive(Debug, Clone, Deserialize, Serialize)]
    pub struct DispProject {
    pub name: String,
    pub organisation: User,
    pub uri: String,
    }
    impl DispProject {
    pub async fn new(db: &State<Database>, project: Project) -> Self {
    let org = project.organisation(db).await.unwrap();
    let uri = rocket::uri!(crate::controllers::projects::show(&org.name, &project.name));
    DispProject {
    name: project.name,
    organisation: org,
    uri: uri.to_string(),
    }
    }
    }
  • replacement in src/controllers/projects.rs at line 58
    [3.1391][2.4581:4584]()
    /*
    [3.1391]
    [2.4584]
    // Rank 3 is assigned as project/new and users/new might else collide
    #[get("/<org_path>/<proj_path>", rank = 3)]
    async fn show_anonymous(
    db: &State<Database>,
    org_path: String,
    proj_path: String,
    ) -> Result<Template, rocket::http::Status> {
    let p = if let Some(p) = projects::find(db, org_path, proj_path).await {
    p
    } else {
    return Err(rocket::http::Status::InternalServerError);
    };
    Ok(Template::render(
    "projects/show",
    crate::context! {
    project: p.clone(),
    organisation: p.organisation(db).await.ok(),
    },
    ))
    }
    #[get("/<org_path>/<proj_path>", rank = 4)]
  • replacement in src/controllers/projects.rs at line 83
    [2.4625][2.4625:4655]()
    repoman: &State<RepoMan>,
    [2.4625]
    [3.1391]
    user: User,
    org_path: String,
    proj_path: String,
    ) -> Result<Template, rocket::http::Status> {
    let p = if let Some(p) = projects::find(db, org_path, proj_path).await {
    p
    } else {
    return Err(rocket::http::Status::InternalServerError);
    };
    Ok(Template::render(
    "projects/show",
    crate::context! {
    current_user: user,
    project: p.clone(),
    organisation: p.organisation(db).await.ok(),
    },
    ))
    }
  • edit in src/controllers/projects.rs at line 103
    [3.1392]
    [2.4656]
    use std::vec::Vec;
  • edit in src/controllers/projects.rs at line 105
    [2.4657]
    [2.4657]
    #[get("/projects/explore")]
    async fn explore(
    db: &State<Database>,
    current_user: Option<User>,
    ) -> Result<Template, rocket::http::Status> {
    let projects = if let Ok(projects) = projects::list(db).await {
    projects
    } else {
    return Err(rocket::http::Status::InternalServerError);
    };
    let mut disp = Vec::new();
    for proj in projects.iter() {
    disp.push(projects::DispProject::new(db, proj.clone()).await)
  • replacement in src/controllers/projects.rs at line 120
    [2.4663][2.4663:4666]()
    */
    [2.4663]
    [2.4666]
    Ok(Template::render(
    "projects/explore",
    crate::context! {
    current_user: current_user,
    projects: disp,
    },
    ))
    }
  • replacement in src/controllers/projects.rs at line 131
    [3.1424][3.1424:1449]()
    routes![new, create]
    [3.1424]
    [3.1449]
    routes![new, create, show, show_anonymous, explore]
  • replacement in src/controllers/mod.rs at line 4
    [3.4132][3.1452:1466]()
    mod projects;
    [3.4132]
    [3.4132]
    pub mod projects;