diff --git a/ui/src/components/linkauditorcomponents/DetailsByDest.svelte b/ui/src/components/linkauditorcomponents/DetailsByDest.svelte index 80c92320..9f138c37 100644 --- a/ui/src/components/linkauditorcomponents/DetailsByDest.svelte +++ b/ui/src/components/linkauditorcomponents/DetailsByDest.svelte @@ -12,6 +12,7 @@ export let builds = []; export let scanUrl; + export let isIgnoredHidden; const ignore = url => dispatch("ignore", url); let destinations; @@ -47,7 +48,7 @@ const deleteIgnore = async (url) => { deleteUrl = url; - loadingChecks[url] = true; + loadingChecks[url.dst] = true; const rules = getMatchingIgnoredRules(url, scanUrl, $ignoredUrls$); try { for await (const rule of rules) { @@ -56,82 +57,84 @@ } catch (error) { addedFailedToast = true; } finally { - loadingChecks[url] = false; + loadingChecks[url.dst] = false; } }; const toggleIgnore = async (url) => { - if (ignoredChecks[url]) { + if (ignoredChecks[url.dst]) { await deleteIgnore(url); } else { - ignore(url); + ignore(url.dst); } }; {#each destinationsKeys as url} -
- - hideShow(url)}> - {#if !hiddenRows[url]} - + {#if !(isIgnoredHidden && ignoredChecks[url])} +
+ + hideShow(url)}> + {#if !hiddenRows[url]} + + {:else} + + {/if} + + {destinations[url][0].statusmsg} ({destinations[url][0].statuscode || 0}) + : + + + {url} + +
+ {#if !hiddenRows[url]} +
+ + Ignore: + {#if loadingChecks[url]} + {:else} - + toggleIgnore(url)} bind:checked={ignoredChecks[url]} /> {/if} - - {destinations[url][0].statusmsg} ({destinations[url][0].statuscode || 0}) - : - - - {url} - -
- {#if !hiddenRows[url]} -
- - Ignore: - {#if loadingChecks[url]} - - {:else} - toggleIgnore(url)} bind:checked={ignoredChecks[url]} /> - {/if} -
- {#if destinations[url][0].daysUnfixed > -1} -
- - {formatDaysUnfixed(destinations[url][0].daysUnfixed)}
- {/if} - - - - - - - - - {#each destinations[url] as val} + {#if destinations[url][0].daysUnfixed > -1} +
+ + {formatDaysUnfixed(destinations[url][0].daysUnfixed)} +
+ {/if} +
- Found on Page ({destinations[url].length}) - Anchor Text
+ - - + + - {/each} - -
- - {val.src} - - {val.link || ''} + Found on Page ({destinations[url].length}) + Anchor Text
+ + + {#each destinations[url] as val} + + + + {val.src} + + + {val.link || ''} + + {/each} + + + {/if} {/if} {/each} diff --git a/ui/src/components/linkauditorcomponents/DetailsByReason.svelte b/ui/src/components/linkauditorcomponents/DetailsByReason.svelte index 8371a684..8959878b 100644 --- a/ui/src/components/linkauditorcomponents/DetailsByReason.svelte +++ b/ui/src/components/linkauditorcomponents/DetailsByReason.svelte @@ -8,12 +8,14 @@ import LoadingCircle from "../misccomponents/LoadingCircle.svelte"; import Toastr from "../misccomponents/Toastr.svelte"; import { tooltip } from '../misccomponents/tooltip'; + export let builds = []; + export let scanUrl; + export let isIgnoredHidden; + const dispatch = createEventDispatcher(); const ignore = url => dispatch("ignore", url); - export let scanUrl; - let reasons; let reasonsKeys = []; let hiddenRows = {}; @@ -22,7 +24,7 @@ let deleteUrl = ''; let addedFailedToast = false; - $: if (builds.length > 0) { + $: { reasons = groupBy(props(["statusmsg"]))(builds); reasonsKeys = Object.keys(reasons); @@ -47,7 +49,7 @@ const deleteIgnore = async (url) => { deleteUrl = url; - loadingChecks[url] = true; + loadingChecks[url.dst] = true; const rules = getMatchingIgnoredRules(url, scanUrl, $ignoredUrls$); try { for await (const rule of rules) { @@ -56,88 +58,92 @@ } catch (error) { addedFailedToast = true; } finally { - loadingChecks[url] = false; + loadingChecks[url.dst] = false; } }; const toggleIgnore = async (url) => { - if (ignoredChecks[url]) { + if (ignoredChecks[url.dst]) { await deleteIgnore(url); } else { - ignore(url); + ignore(url.dst); } }; {#each reasonsKeys as reason} -
- - hideShow(reason)}> - {#if !hiddenRows[reason]} - - {:else} - - {/if} - - Failure reason: - - {reason} -
+ {#if !(isIgnoredHidden && reasons[reason].every((val) => ignoredChecks[val.dst]))} +
+ + hideShow(reason)}> + {#if !hiddenRows[reason]} + + {:else} + + {/if} + + Failure reason: + + {reason} +
- {#if !hiddenRows[reason]} - - - - - - - - - - - - - {#each reasons[reason] as val} + {#if !hiddenRows[reason]} +
Source ({reasons[reason].length})DestinationAnchor TextStatusDays Unfixed
+ - - - - - - + + + + + + - {/each} - -
- - {val.src} - - - - {val.dst.length < 70 ? val.dst : val.dst.substring(0, 70) + '...'} - - {val.link || ''} - {val.statuscode || '0'} - - {formatDaysUnfixed(val.daysUnfixed)} - Source ({reasons[reason].length})DestinationAnchor TextStatusDays Unfixed
+ + + {#each reasons[reason] as val} + {#if !(isIgnoredHidden && ignoredChecks[val.dst])} + + + + {val.src} + + + + + {val.dst.length < 70 ? val.dst : val.dst.substring(0, 70) + '...'} + + + {val.link || ''} + + {val.statuscode || '0'} + + + {formatDaysUnfixed(val.daysUnfixed)} + + + {#if loadingChecks[val.dst]} + + {:else} + toggleIgnore(val.dst)} bind:checked={ignoredChecks[val.dst]} /> + {/if} + + + {/if} + {/each} + + + {/if} {/if} {/each} diff --git a/ui/src/components/linkauditorcomponents/DetailsBySource.svelte b/ui/src/components/linkauditorcomponents/DetailsBySource.svelte index be135621..32a9398f 100644 --- a/ui/src/components/linkauditorcomponents/DetailsBySource.svelte +++ b/ui/src/components/linkauditorcomponents/DetailsBySource.svelte @@ -3,17 +3,19 @@ import { isInIgnored, getMatchingIgnoredRules } from "../../utils/utils.js"; import { fade } from "svelte/transition"; import { ignoredUrls$, deleteIgnoreUrl, userSession$ } from "../../stores.js"; - import { createEventDispatcher } from "svelte"; + import { createEventDispatcher, onMount } from "svelte"; import Icon from "../misccomponents/Icon.svelte"; import LoadingCircle from "../misccomponents/LoadingCircle.svelte"; import Toastr from "../misccomponents/Toastr.svelte"; import { tooltip } from '../misccomponents/tooltip'; + export let builds = []; + export let scanUrl; + export let isIgnoredHidden; + const dispatch = createEventDispatcher(); const ignore = url => dispatch("ignore", url); - export let scanUrl; - let sources; let sourcesKeys = []; let ignoredChecks = {}; @@ -21,13 +23,14 @@ let deleteUrl = ''; let addedFailedToast = false; - $: if (builds.length > 0) { + $: { sources = groupBy(props(["src"]))(builds); sourcesKeys = Object.keys(sources); + ignoredChecks = builds.reduce((acc, val) => { - acc[val.dst] = isInIgnored(val, scanUrl, $ignoredUrls$); - return acc; - }, {}); + acc[val.dst] = isInIgnored(val, scanUrl, $ignoredUrls$); + return acc; + }, {}); } let hiddenRows = {}; @@ -46,7 +49,7 @@ const deleteIgnore = async (url) => { deleteUrl = url; - loadingChecks[url] = true; + loadingChecks[url.dst] = true; const rules = getMatchingIgnoredRules(url, scanUrl, $ignoredUrls$); try { for await (const rule of rules) { @@ -55,83 +58,87 @@ } catch (error) { addedFailedToast = true; } finally { - loadingChecks[url] = false; + loadingChecks[url.dst] = false; } }; const toggleIgnore = async (url) => { - if (ignoredChecks[url]) { + if (ignoredChecks[url.dst]) { await deleteIgnore(url); } else { - ignore(url); + ignore(url.dst); } }; {#each sourcesKeys as url} -
- - hideShow(url)} - cssClass="inline-block cursor-pointer"> - {#if !hiddenRows[url]} - - {:else} - - {/if} - - Broken links on: - - {url} -
- {#if !hiddenRows[url]} - - - - - - - - - - - - - {#each sources[url] as val} + {#if !(isIgnoredHidden && sources[url].every((val) => ignoredChecks[val.dst]))} +
+ + hideShow(url)} + cssClass="inline-block cursor-pointer"> + {#if !hiddenRows[url]} + + {:else} + + {/if} + + Broken links on: + + {url} +
+ {#if !hiddenRows[url]} +
Broken Link ({sources[url].length})Status
+ - - - - - - + + + + + + - {/each} - -
- - {val.dst.length < 70 ? val.dst : val.dst.substring(0, 70) + '...'} - - - - {val.statuscode || '0'} - Broken Link ({sources[url].length})Status
+ + + {#each sources[url] as val} + {#if !(isIgnoredHidden && ignoredChecks[val.dst])} + + + + {val.dst.length < 70 ? val.dst : val.dst.substring(0, 70) + '...'} + + + + {val.link || ''} + + {val.statuscode || '0'} + + + {val.statusmsg || ''} + + + {formatDaysUnfixed(val.daysUnfixed)} + + + {#if loadingChecks[val.dst]} + + {:else} + toggleIgnore(val)} bind:checked={ignoredChecks[val.dst]} /> + {/if} + + + {/if} + {/each} + + + {/if} {/if} {/each} diff --git a/ui/src/components/linkauditorcomponents/DetailsTable.svelte b/ui/src/components/linkauditorcomponents/DetailsTable.svelte index f010214f..0e71769e 100644 --- a/ui/src/components/linkauditorcomponents/DetailsTable.svelte +++ b/ui/src/components/linkauditorcomponents/DetailsTable.svelte @@ -7,20 +7,25 @@ import DetailsByReason from "./DetailsByReason.svelte"; import { onMount } from "svelte"; import { createEventDispatcher } from "svelte"; - import { fade } from "svelte/transition"; export let builds = []; export let currentRoute; - export let unscannableLinks; export let scanUrl; - - let foundUnscannableLinks = []; - foundUnscannableLinks = builds.filter(build => unscannableLinks.some(link => build.dst.includes(link))); - - // Filter out unscannable links - builds = builds.filter(build => !unscannableLinks.some(link => build.dst.includes(link))); let displayMode = 0; + let filterString = ""; + let isIgnoredHidden = false; + let filteredBuilds = []; + + $: { + const input = filterString.toLowerCase(); + filteredBuilds = builds.filter( + x => + x.src.toLowerCase().includes(input) || + x.dst.toLowerCase().includes(input) || + x.link.toLowerCase().includes(input) + ); + } const changeMode = m => { displayMode = m; @@ -35,11 +40,6 @@ changeMode(+currentRoute.queryParams.displayMode); } }); - - let hiddenRows = true; - const hideShow = () => { - hiddenRows = !hiddenRows - } {#if builds.length} -
+
@@ -102,53 +95,13 @@
-{/if} -{#if foundUnscannableLinks.length > 0}
- - hideShow()} - cssClass="inline-block cursor-pointer"> - {#if !hiddenRows} - - {:else} - - {/if} - - Unscannable Links ({foundUnscannableLinks.length}): - + +
- {#if !hiddenRows} - - Some working links are reported as broken by CodeAuditor. They're marked as "unscannable". Learn more on our KB. - - {#each foundUnscannableLinks as url} - - - - - - - - - - - - - - - - -
Source - {url.src} -
Anchor Text{url.link || ''}
Link - {url.dst} -
- {/each} - {/if} {/if} {#if !builds.length}
@@ -168,10 +121,10 @@ {#if builds.length} {#if displayMode === 0} - + {:else if displayMode === 1} - + {:else} - + {/if} {/if} diff --git a/ui/src/containers/LinkReport.svelte b/ui/src/containers/LinkReport.svelte index aca9a22d..fb4e8763 100644 --- a/ui/src/containers/LinkReport.svelte +++ b/ui/src/containers/LinkReport.svelte @@ -85,7 +85,6 @@ on:ignore={url => showIgnore(data.buildDetails.summary.url, url, $userSession$)} builds={data.buildDetails ? data.buildDetails.brokenLinks : []} {currentRoute} - unscannableLinks={[]} scanUrl={data.buildDetails.summary.url} /> diff --git a/ui/src/global.scss b/ui/src/global.scss index da209374..7c7a51c0 100644 --- a/ui/src/global.scss +++ b/ui/src/global.scss @@ -6,6 +6,7 @@ @import '../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss'; @import '../node_modules/@fortawesome/fontawesome-free/scss/solid.scss'; @import '../node_modules/@fortawesome/fontawesome-free/scss/brands.scss'; +@import '../node_modules/@fortawesome/fontawesome-free/scss/regular.scss'; html, body {