mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 08:01:25 +00:00
71b7135cf2
Adds recently-updated / oldest / name A-Z / name Z-A sort orders to the homepage (WIN-2236), produced server-side by a new merged, index-backed, keyset-paginated GET /w/{workspace}/runnables/list so a chosen order is globally correct across scripts + flows + apps and stays efficient on large workspaces.
- Backend: UNION ALL of script/flow/app ordered by index (Merge Append + LIMIT); keyset (sort_key, path, kind, tiebreak) cursor; per-branch LIMIT bounds correlated projections; starred-first pinning; RLS + scope-token filters in SQL. Archived view returns the latest row per path. Migration adds time + lowered-name indexes (built CONCURRENTLY).
- Frontend: server-side sort/kind/owner filters + hybrid search (instant client + on-demand server pagination); file-explorer tree with every folder and your user namespace as lazy-loaded top-level nodes (per-owner "Load more", nested subfolders, bounded "expand all", in-place re-sort without collapse or flicker); the client sorts by the server fetch ordinal to reproduce the endpoint's exact order; empty state distinguishes an empty workspace from too-narrow filters.
Reviewed clean by Claude and Pi (good to merge) and Codex (mergeable).
49 lines
1.4 KiB
Rust
49 lines
1.4 KiB
Rust
/*
|
|
* Author: Ruben Fiszel
|
|
* Copyright: Windmill Labs, Inc 2022
|
|
* This file and its contents are licensed under the AGPLv3 License.
|
|
* Please see the included NOTICE for copyright information and
|
|
* LICENSE-AGPL for a copy of the license.
|
|
*/
|
|
|
|
use axum::{body::Body, response::Response};
|
|
use serde::{Deserialize, Deserializer};
|
|
|
|
pub use windmill_api_auth::{
|
|
build_scope_path_filter, build_scope_path_predicate, check_scopes, require_devops_role,
|
|
require_super_admin, ScopePathFilter,
|
|
};
|
|
|
|
#[cfg(feature = "private")]
|
|
pub use windmill_common::usernames::generate_instance_wide_unique_username;
|
|
|
|
#[cfg(feature = "enterprise")]
|
|
pub use windmill_alerting::{
|
|
acknowledge_all_critical_alerts, acknowledge_critical_alert, get_critical_alerts,
|
|
AlertQueryParams,
|
|
};
|
|
|
|
pub fn content_plain(body: Body) -> Response {
|
|
use axum::http::header;
|
|
Response::builder()
|
|
.header(header::CONTENT_TYPE, "text/plain")
|
|
.body(body)
|
|
.unwrap()
|
|
}
|
|
|
|
#[allow(unused)]
|
|
pub fn non_empty_str<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let o: Option<String> = Option::deserialize(deserializer)?;
|
|
Ok(o.filter(|s| !s.trim().is_empty()))
|
|
}
|
|
|
|
#[cfg(feature = "http_trigger")]
|
|
pub use windmill_common::utils::ExpiringCacheEntry;
|
|
|
|
lazy_static::lazy_static! {
|
|
static ref DUCKLAKE_INSTANCE_PG_PASSWORD: std::sync::RwLock<Option<String>> = std::sync::RwLock::new(None);
|
|
}
|