mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-27 20:01:10 +01:00
Fix workspace creation, reveal sync dir, and don't update timestamps on sync/import
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
"opener:allow-open-url",
|
||||
"opener:allow-open-path",
|
||||
"opener:allow-default-urls",
|
||||
"opener:allow-reveal-item-in-dir",
|
||||
"core:webview:allow-set-webview-zoom",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-internal-toggle-maximize",
|
||||
|
||||
2
src-tauri/gen/schemas/capabilities.json
generated
2
src-tauri/gen/schemas/capabilities.json
generated
@@ -1 +1 @@
|
||||
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-dir","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"opener:allow-open-url","opener:allow-open-path","opener:allow-default-urls","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-internal-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-show","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text","yaak-license:default","yaak-sync:default"]}}
|
||||
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-dir","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"opener:allow-open-url","opener:allow-open-path","opener:allow-default-urls","opener:allow-reveal-item-in-dir","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-internal-toggle-maximize","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-show","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text","yaak-license:default","yaak-sync:default"]}}
|
||||
@@ -9,7 +9,7 @@ use crate::models::{
|
||||
WorkspaceMetaIden,
|
||||
};
|
||||
use crate::plugin::SqliteConnection;
|
||||
use chrono::NaiveDateTime;
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use log::{debug, error, info, warn};
|
||||
use nanoid::nanoid;
|
||||
use rusqlite::OptionalExtension;
|
||||
@@ -278,8 +278,8 @@ pub async fn upsert_workspace<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, workspace.created_at).into(),
|
||||
timestamp_for_upsert(update_source, workspace.updated_at).into(),
|
||||
trimmed_name.into(),
|
||||
workspace.description.into(),
|
||||
workspace.setting_follow_redirects.into(),
|
||||
@@ -297,6 +297,7 @@ pub async fn upsert_workspace<R: Runtime>(
|
||||
WorkspaceIden::SettingRequestTimeout,
|
||||
WorkspaceIden::SettingValidateCertificates,
|
||||
])
|
||||
.values([(WorkspaceIden::UpdatedAt, CurrentTimestamp.into())])
|
||||
.to_owned(),
|
||||
)
|
||||
.returning_all()
|
||||
@@ -333,8 +334,8 @@ pub async fn upsert_workspace_meta<R: Runtime>(
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
workspace_meta.workspace_id.into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, workspace_meta.created_at).into(),
|
||||
timestamp_for_upsert(update_source, workspace_meta.updated_at).into(),
|
||||
workspace_meta.setting_sync_dir.into(),
|
||||
])
|
||||
.on_conflict(
|
||||
@@ -500,8 +501,8 @@ pub async fn upsert_grpc_request<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, request.created_at).into(),
|
||||
timestamp_for_upsert(update_source, request.updated_at).into(),
|
||||
trimmed_name.into(),
|
||||
request.description.into(),
|
||||
request.workspace_id.into(),
|
||||
@@ -612,8 +613,8 @@ pub async fn upsert_grpc_connection<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, connection.created_at).into(),
|
||||
timestamp_for_upsert(update_source, connection.updated_at).into(),
|
||||
connection.workspace_id.as_str().into(),
|
||||
connection.request_id.as_str().into(),
|
||||
connection.service.as_str().into(),
|
||||
@@ -771,8 +772,8 @@ pub async fn upsert_grpc_event<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, event.created_at).into(),
|
||||
timestamp_for_upsert(update_source, event.updated_at).into(),
|
||||
event.workspace_id.as_str().into(),
|
||||
event.request_id.as_str().into(),
|
||||
event.connection_id.as_str().into(),
|
||||
@@ -859,8 +860,8 @@ pub async fn upsert_cookie_jar<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, cookie_jar.created_at).into(),
|
||||
timestamp_for_upsert(update_source, cookie_jar.updated_at).into(),
|
||||
cookie_jar.workspace_id.as_str().into(),
|
||||
trimmed_name.into(),
|
||||
serde_json::to_string(&cookie_jar.cookies)?.into(),
|
||||
@@ -1064,8 +1065,8 @@ pub async fn upsert_environment<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, environment.created_at).into(),
|
||||
timestamp_for_upsert(update_source, environment.updated_at).into(),
|
||||
environment.environment_id.into(),
|
||||
environment.workspace_id.into(),
|
||||
trimmed_name.into(),
|
||||
@@ -1174,8 +1175,8 @@ pub async fn upsert_plugin<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
timestamp_for_upsert(update_source, plugin.created_at).into(),
|
||||
timestamp_for_upsert(update_source, plugin.updated_at).into(),
|
||||
plugin.checked_at.into(),
|
||||
plugin.directory.into(),
|
||||
plugin.url.into(),
|
||||
@@ -1276,15 +1277,15 @@ pub async fn delete_folder<R: Runtime>(
|
||||
|
||||
pub async fn upsert_folder<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
r: Folder,
|
||||
folder: Folder,
|
||||
|
||||
update_source: &UpdateSource,
|
||||
) -> Result<Folder> {
|
||||
let id = match r.id.as_str() {
|
||||
let id = match folder.id.as_str() {
|
||||
"" => generate_model_id(ModelType::TypeFolder),
|
||||
_ => r.id.to_string(),
|
||||
_ => folder.id.to_string(),
|
||||
};
|
||||
let trimmed_name = r.name.trim();
|
||||
let trimmed_name = folder.name.trim();
|
||||
|
||||
let dbm = &*window.app_handle().state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
@@ -1303,13 +1304,13 @@ pub async fn upsert_folder<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
r.workspace_id.as_str().into(),
|
||||
r.folder_id.as_ref().map(|s| s.as_str()).into(),
|
||||
timestamp_for_upsert(update_source, folder.created_at).into(),
|
||||
timestamp_for_upsert(update_source, folder.updated_at).into(),
|
||||
folder.workspace_id.as_str().into(),
|
||||
folder.folder_id.as_ref().map(|s| s.as_str()).into(),
|
||||
trimmed_name.into(),
|
||||
r.description.into(),
|
||||
r.sort_priority.into(),
|
||||
folder.description.into(),
|
||||
folder.sort_priority.into(),
|
||||
])
|
||||
.on_conflict(
|
||||
OnConflict::column(GrpcEventIden::Id)
|
||||
@@ -1419,14 +1420,14 @@ pub async fn duplicate_folder<R: Runtime>(
|
||||
|
||||
pub async fn upsert_http_request<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
r: HttpRequest,
|
||||
request: HttpRequest,
|
||||
update_source: &UpdateSource,
|
||||
) -> Result<HttpRequest> {
|
||||
let id = match r.id.as_str() {
|
||||
let id = match request.id.as_str() {
|
||||
"" => generate_model_id(ModelType::TypeHttpRequest),
|
||||
_ => r.id.to_string(),
|
||||
_ => request.id.to_string(),
|
||||
};
|
||||
let trimmed_name = r.name.trim();
|
||||
let trimmed_name = request.name.trim();
|
||||
|
||||
let dbm = &*window.app_handle().state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
@@ -1453,21 +1454,21 @@ pub async fn upsert_http_request<R: Runtime>(
|
||||
])
|
||||
.values_panic([
|
||||
id.as_str().into(),
|
||||
CurrentTimestamp.into(),
|
||||
CurrentTimestamp.into(),
|
||||
r.workspace_id.into(),
|
||||
r.folder_id.as_ref().map(|s| s.as_str()).into(),
|
||||
timestamp_for_upsert(update_source, request.created_at).into(),
|
||||
timestamp_for_upsert(update_source, request.updated_at).into(),
|
||||
request.workspace_id.into(),
|
||||
request.folder_id.as_ref().map(|s| s.as_str()).into(),
|
||||
trimmed_name.into(),
|
||||
r.description.into(),
|
||||
r.url.into(),
|
||||
serde_json::to_string(&r.url_parameters)?.into(),
|
||||
r.method.into(),
|
||||
serde_json::to_string(&r.body)?.into(),
|
||||
r.body_type.as_ref().map(|s| s.as_str()).into(),
|
||||
serde_json::to_string(&r.authentication)?.into(),
|
||||
r.authentication_type.as_ref().map(|s| s.as_str()).into(),
|
||||
serde_json::to_string(&r.headers)?.into(),
|
||||
r.sort_priority.into(),
|
||||
request.description.into(),
|
||||
request.url.into(),
|
||||
serde_json::to_string(&request.url_parameters)?.into(),
|
||||
request.method.into(),
|
||||
serde_json::to_string(&request.body)?.into(),
|
||||
request.body_type.as_ref().map(|s| s.as_str()).into(),
|
||||
serde_json::to_string(&request.authentication)?.into(),
|
||||
request.authentication_type.as_ref().map(|s| s.as_str()).into(),
|
||||
serde_json::to_string(&request.headers)?.into(),
|
||||
request.sort_priority.into(),
|
||||
])
|
||||
.on_conflict(
|
||||
OnConflict::column(GrpcEventIden::Id)
|
||||
@@ -2167,7 +2168,7 @@ pub async fn get_workspace_export_resources<R: Runtime>(
|
||||
let mut data = WorkspaceExport {
|
||||
yaak_version: mgr.package_info().version.clone().to_string(),
|
||||
yaak_schema: 2,
|
||||
timestamp: chrono::Utc::now().naive_utc(),
|
||||
timestamp: Utc::now().naive_utc(),
|
||||
resources: BatchUpsertResult {
|
||||
workspaces: Vec::new(),
|
||||
environments: Vec::new(),
|
||||
@@ -2197,3 +2198,21 @@ pub async fn get_workspace_export_resources<R: Runtime>(
|
||||
|
||||
data
|
||||
}
|
||||
|
||||
// Generate the created_at or updated_at timestamps for an upsert operation, depending on the ID
|
||||
// provided.
|
||||
fn timestamp_for_upsert(update_source: &UpdateSource, dt: NaiveDateTime) -> NaiveDateTime {
|
||||
match update_source {
|
||||
// Sync and import operations always preserve timestamps
|
||||
UpdateSource::Sync | UpdateSource::Import => {
|
||||
if dt.and_utc().timestamp() == 0 {
|
||||
// Sometimes data won't have timestamps (partial data)
|
||||
Utc::now().naive_utc()
|
||||
} else {
|
||||
dt
|
||||
}
|
||||
},
|
||||
// Other sources will always update to the latest time
|
||||
_ => Utc::now().naive_utc(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::error::Result;
|
||||
use crate::sync::{
|
||||
apply_sync_ops, apply_sync_state_ops, compute_sync_ops, get_db_candidates, get_fs_candidates,
|
||||
SyncOp,
|
||||
FsCandidate, SyncOp,
|
||||
};
|
||||
use crate::watch::{watch_directory, WatchEvent};
|
||||
use chrono::Utc;
|
||||
@@ -23,16 +23,18 @@ pub async fn calculate<R: Runtime>(
|
||||
let fs_candidates = get_fs_candidates(sync_dir)
|
||||
.await?
|
||||
.into_iter()
|
||||
// Strip out any non-workspace candidates
|
||||
// Only keep items in the same workspace
|
||||
.filter(|fs| fs.model.workspace_id() == workspace_id)
|
||||
.collect();
|
||||
.collect::<Vec<FsCandidate>>();
|
||||
// println!("\ndb_candidates: \n{}\n", serde_json::to_string_pretty(&db_candidates)?);
|
||||
// println!("\nfs_candidates: \n{}\n", serde_json::to_string_pretty(&fs_candidates)?);
|
||||
Ok(compute_sync_ops(db_candidates, fs_candidates))
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub async fn calculate_fs(dir: &Path) -> Result<Vec<SyncOp>> {
|
||||
let db_candidates = Vec::new();
|
||||
let fs_candidates = get_fs_candidates(Path::new(&dir)).await?;
|
||||
let fs_candidates = get_fs_candidates(dir).await?;
|
||||
Ok(compute_sync_ops(db_candidates, fs_candidates))
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ impl Display for SyncOp {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub(crate) enum DbCandidate {
|
||||
Added(SyncModel),
|
||||
Modified(SyncModel, SyncState),
|
||||
|
||||
Reference in New Issue
Block a user