From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <yew-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 214B01FF187 for <inbox@lore.proxmox.com>; Wed, 7 May 2025 16:37:49 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D9B0D3DF86; Wed, 7 May 2025 16:38:06 +0200 (CEST) From: Dominik Csapak <d.csapak@proxmox.com> To: yew-devel@lists.proxmox.com Date: Wed, 7 May 2025 16:38:00 +0200 Message-Id: <20250507143800.3461963-5-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250507143800.3461963-1-d.csapak@proxmox.com> References: <20250507143800.3461963-1-d.csapak@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.022 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [yew-devel] [PATCH yew-comp 2/2] tasks: don't add entries we already loaded X-BeenThere: yew-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Yew framework devel list at Proxmox <yew-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/yew-devel>, <mailto:yew-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/yew-devel/> List-Post: <mailto:yew-devel@lists.proxmox.com> List-Help: <mailto:yew-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel>, <mailto:yew-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Yew framework devel list at Proxmox <yew-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: yew-devel-bounces@lists.proxmox.com Sender: "yew-devel" <yew-devel-bounces@lists.proxmox.com> If there is a new task in between loads due to scrolling, we got old tasks from the api that we already loaded. This happens because: * tasks are sorted descending by their start time * we initially request up to 500 from start 0 * we save the amount of tasks there are * on a new load due to scrolling, we set start to the amount of tasks knew of -> if there are new tasks now, the start offset we sent would be too low To fix this, skip the amount of tasks in the list that were added in the meantime, which is the new total minus the new total. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- ideally we could implement a kind of cursor for our tasks, so that this scenario would not happen, but I'm not sure if this is feasible alternatively/additionally we could implement some key constraints for datastores, or use a Store with a HashMap instead of a vector (we'd have to do the ordering manually in this case though, which might be a big overhead for big task lists..) src/tasks.rs | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/tasks.rs b/src/tasks.rs index 3c531c1..ac8d1c5 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -95,7 +95,8 @@ pub enum ViewDialog { pub enum Msg { Redraw, ToggleFilter, - LoadBatch(u64), // start + LoadBatch(u64), // start + LoadFinished(Option<u64>, Vec<TaskListItem>), // total UpdateFilter, ShowTask, } @@ -109,6 +110,7 @@ pub struct ProxmoxTasks { last_filter: serde_json::Value, load_timeout: Option<Timeout>, columns: Rc<Vec<DataTableHeader<TaskListItem>>>, + total: Option<u64>, } impl ProxmoxTasks { @@ -192,6 +194,7 @@ impl LoadableComponent for ProxmoxTasks { start: 0, load_timeout: None, columns: Self::columns(ctx), + total: None, } } @@ -206,8 +209,6 @@ impl LoadableComponent for ProxmoxTasks { None => format!("/nodes/{nodename}/tasks"), }; - let store = self.store.clone(); - let form_context = self.filter_form_context.read(); let mut filter = form_context.get_submit_data(); @@ -234,13 +235,11 @@ impl LoadableComponent for ProxmoxTasks { filter["start"] = start.into(); filter["limit"] = BATCH_LIMIT.into(); + let link = ctx.link().clone(); Box::pin(async move { - let mut data: Vec<_> = crate::http_get(&path, Some(filter)).await?; - if start == 0 { - store.write().set_data(data); - } else { - store.write().append(&mut data); - } + let response = crate::http_get_full(&path, Some(filter)).await?; + let total = response.attribs.get("total").and_then(|v| v.as_u64()); + link.send_message(Msg::LoadFinished(total, response.data)); Ok(()) }) } @@ -279,6 +278,33 @@ impl LoadableComponent for ProxmoxTasks { })); false } + Msg::LoadFinished(total, mut data) => { + let old_total = self.total.take(); + self.total = total; + if self.start == 0 { + self.store.write().set_data(data); + } else { + // if new elements were added at the front, we need to skip as many from the + // newly gathered list, otherwise we have duplicate items + match (old_total, self.total) { + (Some(old), Some(new)) if new > old => { + let to_skip = (new - old) as usize; + + if to_skip <= data.len() { + data.drain(..to_skip); + } + } + _ => {} + }; + + if data.is_empty() { + return false; + } else { + self.store.write().append(&mut data); + } + } + true + } Msg::ShowTask => { if let Some(on_show_task) = &ctx.props().on_show_task { let selected_item = self -- 2.39.5 _______________________________________________ yew-devel mailing list yew-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel