mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
fix dashboard scroll to top issue
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
}
|
||||
|
||||
let chartContainer;
|
||||
let sizingContainer;
|
||||
let width = 300;
|
||||
let height = 200; // Balanced height to prevent overflow
|
||||
let containerReady = false;
|
||||
@@ -777,9 +778,9 @@
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (chartContainer) {
|
||||
await tick(); // Wait for DOM/layout
|
||||
const containerWidth = chartContainer.clientWidth || 0;
|
||||
await tick(); // Wait for DOM/layout
|
||||
if (sizingContainer) {
|
||||
const containerWidth = sizingContainer.parentElement?.clientWidth || 0;
|
||||
width = Math.min(Math.max(containerWidth, 300), containerWidth); // Minimum 300px but never exceed container
|
||||
if (width > 0) containerReady = true;
|
||||
resizeObserver = new ResizeObserver((entries) => {
|
||||
@@ -791,13 +792,13 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
resizeObserver.observe(chartContainer);
|
||||
resizeObserver.observe(sizingContainer.parentElement || sizingContainer);
|
||||
}
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (resizeObserver && chartContainer) {
|
||||
resizeObserver.unobserve(chartContainer);
|
||||
if (resizeObserver && sizingContainer) {
|
||||
resizeObserver.unobserve(sizingContainer.parentElement || sizingContainer);
|
||||
}
|
||||
if (loadingTimeout) {
|
||||
clearTimeout(loadingTimeout);
|
||||
@@ -814,9 +815,9 @@
|
||||
</script>
|
||||
|
||||
<div class="w-full box-border" style="contain: layout style;">
|
||||
<!-- Always render a hidden chartContainer for ResizeObserver -->
|
||||
<!-- Hidden sizing element for ResizeObserver -->
|
||||
<div
|
||||
bind:this={chartContainer}
|
||||
bind:this={sizingContainer}
|
||||
class="chart-container w-full overflow-x-auto"
|
||||
style="height:0;overflow:hidden;visibility:hidden;position:absolute;"
|
||||
></div>
|
||||
|
||||
@@ -88,9 +88,9 @@
|
||||
contextCompanyName = context.companyName;
|
||||
}
|
||||
refresh();
|
||||
activeTableURLParams.onChange(refreshActiveCampaigns);
|
||||
scheduledTableURLParams.onChange(refreshScheduledCampaigns);
|
||||
completedTableURLParams.onChange(refreshFinishedCampaigns);
|
||||
activeTableURLParams.onChange(() => refreshActiveCampaigns(true));
|
||||
scheduledTableURLParams.onChange(() => refreshScheduledCampaigns(true));
|
||||
completedTableURLParams.onChange(() => refreshFinishedCampaigns(true));
|
||||
|
||||
return () => {
|
||||
activeTableURLParams.unsubscribe();
|
||||
@@ -305,7 +305,87 @@
|
||||
<AutoRefresh
|
||||
isLoading={false}
|
||||
onRefresh={async () => {
|
||||
await refresh(false);
|
||||
// refresh all data
|
||||
let res = await api.campaign.getStats(contextCompanyID, {
|
||||
includeTest: includeTestCampaigns
|
||||
});
|
||||
if (!res.success) {
|
||||
throw res.error;
|
||||
}
|
||||
await refreshRepeatOffenders();
|
||||
|
||||
active = res.data.active;
|
||||
scheduled = res.data.upcoming;
|
||||
finished = res.data.finished;
|
||||
|
||||
// refresh table data directly like campaign page does
|
||||
const activeOptions = {
|
||||
page: activeTableURLParams.currentPage,
|
||||
perPage: activeTableURLParams.perPage,
|
||||
sortBy: activeTableURLParams.sortBy,
|
||||
sortOrder: activeTableURLParams.sortOrder,
|
||||
search: activeTableURLParams.search,
|
||||
includeTest: includeTestCampaigns
|
||||
};
|
||||
const activeRes = await api.campaign.getAllActive(activeOptions, contextCompanyID);
|
||||
if (activeRes.success) {
|
||||
activeCampaigns = [];
|
||||
await tick();
|
||||
activeCampaigns = activeRes.data.rows;
|
||||
}
|
||||
|
||||
const scheduledOptions = {
|
||||
page: scheduledTableURLParams.currentPage,
|
||||
perPage: scheduledTableURLParams.perPage,
|
||||
sortBy: scheduledTableURLParams.sortBy,
|
||||
sortOrder: scheduledTableURLParams.sortOrder,
|
||||
search: scheduledTableURLParams.search,
|
||||
includeTest: includeTestCampaigns
|
||||
};
|
||||
const scheduledRes = await api.campaign.getAllUpcoming(
|
||||
scheduledOptions,
|
||||
contextCompanyID
|
||||
);
|
||||
if (scheduledRes.success) {
|
||||
scheduledCampaigns = [];
|
||||
await tick();
|
||||
scheduledCampaigns = scheduledRes.data.rows;
|
||||
}
|
||||
|
||||
const completedOptions = {
|
||||
page: completedTableURLParams.currentPage,
|
||||
perPage: completedTableURLParams.perPage,
|
||||
sortBy: completedTableURLParams.sortBy,
|
||||
sortOrder: completedTableURLParams.sortOrder,
|
||||
search: completedTableURLParams.search,
|
||||
includeTest: includeTestCampaigns
|
||||
};
|
||||
const completedRes = await api.campaign.getAllFinished(
|
||||
completedOptions,
|
||||
contextCompanyID
|
||||
);
|
||||
if (completedRes.success) {
|
||||
completedCampaigns = [];
|
||||
await tick();
|
||||
completedCampaigns = completedRes.data.rows;
|
||||
}
|
||||
|
||||
const statsOptions = {
|
||||
page: 1,
|
||||
perPage: 10,
|
||||
sortBy: 'campaign_closed_at',
|
||||
sortOrder: 'desc',
|
||||
search: '',
|
||||
includeTest: includeTestCampaigns
|
||||
};
|
||||
const statsRes = await api.campaign.getAllCampaignStats(statsOptions, contextCompanyID);
|
||||
if (statsRes.success) {
|
||||
campaignStats = [];
|
||||
await tick();
|
||||
campaignStats = statsRes.data.rows || [];
|
||||
}
|
||||
|
||||
await refreshCalendarCampaings();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user