mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-09-16 14:51:37 +02:00
Replace the default workspace with a home screen (#660)
This commit is contained in:
@@ -6,7 +6,6 @@ use sea_query::{IntoColumnRef, IntoIden, SimpleExpr};
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
use std::sync::mpsc;
|
||||
use yaak_database::DbContext;
|
||||
|
||||
/// A read handle. Comes from the reader pool and can only query.
|
||||
@@ -80,7 +79,6 @@ impl<'a> ClientDb<'a> {
|
||||
/// discards them along with the rows.
|
||||
pub struct WriteDb<'a> {
|
||||
db: ClientDb<'a>,
|
||||
events_tx: mpsc::Sender<ModelPayload>,
|
||||
pending_events: RefCell<Vec<ModelPayload>>,
|
||||
}
|
||||
|
||||
@@ -93,8 +91,8 @@ impl<'a> Deref for WriteDb<'a> {
|
||||
}
|
||||
|
||||
impl<'a> WriteDb<'a> {
|
||||
pub fn new(ctx: DbContext<'a>, events_tx: mpsc::Sender<ModelPayload>) -> Self {
|
||||
Self { db: ClientDb::new(ctx), events_tx, pending_events: RefCell::new(Vec::new()) }
|
||||
pub fn new(ctx: DbContext<'a>) -> Self {
|
||||
Self { db: ClientDb::new(ctx), pending_events: RefCell::new(Vec::new()) }
|
||||
}
|
||||
|
||||
/// The events for everything written so far, to send once the
|
||||
|
||||
@@ -171,11 +171,11 @@ pub fn init_in_memory() -> Result<(QueryManager, BlobManager, mpsc::Receiver<Mod
|
||||
Ok((query_manager, blob_manager, rx))
|
||||
}
|
||||
|
||||
/// The rows every client assumes exist: settings and at least one workspace.
|
||||
/// The rows every client assumes exist. Workspaces are not among them: a fresh
|
||||
/// install has none, and the client shows onboarding until the user makes one.
|
||||
fn bootstrap(query_manager: &QueryManager) -> Result<()> {
|
||||
query_manager.with_tx(|tx| {
|
||||
tx.ensure_settings()?;
|
||||
tx.ensure_default_workspace()?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -192,8 +192,10 @@ mod tests {
|
||||
#[test]
|
||||
fn request_resolution_preserves_duplicate_request_headers() {
|
||||
let (query_manager, _blob_manager, _rx) = init_in_memory().expect("Failed to init DB");
|
||||
let workspace = query_manager
|
||||
.with_tx(|tx| tx.upsert_workspace(&Workspace::default(), &UpdateSource::Background))
|
||||
.expect("Failed to create workspace");
|
||||
let db = query_manager.connect();
|
||||
let workspace = db.list_workspaces().expect("Failed to list workspaces").remove(0);
|
||||
let request = HttpRequest {
|
||||
workspace_id: workspace.id,
|
||||
headers: vec![
|
||||
|
||||
@@ -79,18 +79,6 @@ impl<'a> ClientDb<'a> {
|
||||
}
|
||||
|
||||
impl<'a> WriteDb<'a> {
|
||||
/// There is always at least one workspace. Called at startup and after a
|
||||
/// workspace is deleted.
|
||||
pub fn ensure_default_workspace(&self) -> Result<()> {
|
||||
if self.find_all::<Workspace>()?.is_empty() {
|
||||
self.upsert_workspace(
|
||||
&Workspace { name: "Yaak".to_string(), ..Default::default() },
|
||||
&UpdateSource::Background,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Delete a workspace and everything in it.
|
||||
///
|
||||
/// Children are bulk-deleted with one statement per table and are NOT
|
||||
@@ -138,7 +126,6 @@ impl<'a> WriteDb<'a> {
|
||||
self.delete_many_untracked::<SyncState>(SyncStateIden::WorkspaceId, wid)?;
|
||||
self.delete_many_untracked::<WorkspaceMeta>(WorkspaceMetaIden::WorkspaceId, wid)?;
|
||||
let deleted = self.delete(workspace, source)?;
|
||||
self.ensure_default_workspace()?;
|
||||
|
||||
// Best-effort cleanup of response bodies (disk files and blob chunks).
|
||||
// Failures only orphan unreferenced data, and are logged.
|
||||
@@ -193,18 +180,32 @@ pub fn default_headers() -> Vec<HttpRequestHeader> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::init_in_memory;
|
||||
use crate::models::Workspace;
|
||||
use crate::util::UpdateSource;
|
||||
|
||||
#[test]
|
||||
fn bootstraps_first_workspace_with_real_defaults() {
|
||||
fn fresh_install_has_no_workspaces() {
|
||||
let (query_manager, _blob_manager, _rx) = init_in_memory().expect("Failed to init DB");
|
||||
let db = query_manager.connect();
|
||||
let workspaces = query_manager.connect().list_workspaces().expect("Failed to list");
|
||||
assert!(workspaces.is_empty());
|
||||
}
|
||||
|
||||
let workspaces = db.list_workspaces().expect("Failed to list workspaces");
|
||||
let workspace = workspaces.first().expect("No workspace was bootstrapped");
|
||||
#[test]
|
||||
fn default_workspace_carries_real_defaults() {
|
||||
let (query_manager, _blob_manager, _rx) = init_in_memory().expect("Failed to init DB");
|
||||
let created = query_manager
|
||||
.with_tx(|tx| {
|
||||
tx.upsert_workspace(
|
||||
&Workspace { name: "Yaak".to_string(), ..Default::default() },
|
||||
&UpdateSource::Background,
|
||||
)
|
||||
})
|
||||
.expect("Failed to create workspace");
|
||||
let workspace = query_manager.connect().get_workspace(&created.id).expect("get");
|
||||
|
||||
// This workspace is built in Rust and never deserialized, so it only gets
|
||||
// these values if `Workspace::default()` carries them. Asserted through the
|
||||
// DB round trip, since the column values are what a fresh install lives with.
|
||||
// A workspace built in Rust and never deserialized only gets these values
|
||||
// if `Workspace::default()` carries them. Asserted through the DB round
|
||||
// trip, since the column values are what the user lives with.
|
||||
assert!(workspace.setting_send_cookies, "setting_send_cookies");
|
||||
assert!(workspace.setting_store_cookies, "setting_store_cookies");
|
||||
assert!(workspace.setting_follow_redirects, "setting_follow_redirects");
|
||||
|
||||
@@ -62,8 +62,7 @@ impl QueryManager {
|
||||
let tx = Transaction::new_unchecked(&conn, TransactionBehavior::Immediate)
|
||||
.map_err(crate::error::Error::SqlError)?;
|
||||
|
||||
let db =
|
||||
WriteDb::new(DbContext::new(ConnectionOrTx::Transaction(&tx)), self.events_tx.clone());
|
||||
let db = WriteDb::new(DbContext::new(ConnectionOrTx::Transaction(&tx)));
|
||||
|
||||
match func(&db) {
|
||||
Ok(val) => {
|
||||
|
||||
Reference in New Issue
Block a user