diff --git a/pebblo/app/pebblo-ui/src/components/applicationList.js b/pebblo/app/pebblo-ui/src/components/applicationList.js index fe526007..8ffddf8c 100644 --- a/pebblo/app/pebblo-ui/src/components/applicationList.js +++ b/pebblo/app/pebblo-ui/src/components/applicationList.js @@ -3,20 +3,21 @@ import { GET_REPORT } from "../constants/routesConstant.js"; import { DownloadIcon, SearchIcon } from "../icons/index.js"; import { GET_FILE } from "../services/get.js"; import { waitForElement } from "../util.js"; +import { EmptyState } from "./emptyState.js"; import { Button, Table, Td } from "./index.js"; -// PROPS { title: string, +// PROPS { title: string, // tableCol: Array<{ // label:string; // field:string; // align?:string; -// render?:(e)=>void -// }>, -// tableData: Array, -// isDownloadReport?: boolean, -// searchField: Array < string >, -// isSorting?: boolean, -// link?: string, +// render?:(e)=>void +// }>, +// tableData: Array, +// isDownloadReport?: boolean, +// searchField: Array < string >, +// isSorting?: boolean, +// link?: string, // inputPlaceholder?: string } export function ApplicationsList(props) { @@ -28,7 +29,8 @@ export function ApplicationsList(props) { searchField, isSorting, link, - inputPlaceholder = "Search" + inputPlaceholder = "Search", + error, } = props; window.addEventListener(LOAD, function () { @@ -67,25 +69,25 @@ export function ApplicationsList(props) { document.getElementsByTagName("tbody")[0].innerHTML = filteredData?.length ? ` ${filteredData?.myMap( - (item) => /*html*/ ` + (item) => /*html*/ ` ${tableCol?.myMap((col) => - Td({ - children: col?.actions - ? col?.actions(item) - : col?.render - ? col?.render(item) - : item[col?.field], - align: col?.align, - link: - col?.field !== ACTIONS && link - ? `${link}?app_name=${item?.name}` - : "", - maxWidth: col?.type === "label" ? "text-ellipsis" : "fit", - }) - )} + Td({ + children: col?.actions + ? col?.actions(item) + : col?.render + ? col?.render(item) + : item[col?.field], + align: col?.align, + link: + col?.field !== ACTIONS && link + ? `${link}?app_name=${item?.name}` + : "", + maxWidth: col?.type === "label" ? "text-ellipsis" : "fit", + }) + )} ` - )} + )} ` : /*html*/ ` No Data Found @@ -93,31 +95,38 @@ export function ApplicationsList(props) { } return /*html*/ ` -
-
-
${title}
-
- +
`; } diff --git a/pebblo/app/pebblo-ui/src/components/emptyState.js b/pebblo/app/pebblo-ui/src/components/emptyState.js new file mode 100644 index 00000000..069a08b3 --- /dev/null +++ b/pebblo/app/pebblo-ui/src/components/emptyState.js @@ -0,0 +1,25 @@ +import { EMPTY_STATES } from "../constants/constant.js"; +import { Button } from "./index.js"; + +export const EmptyState = (props) => { + const { image, heading, subHeading, buttonNodes } = + EMPTY_STATES[props?.variant]; + + return /*html*/ ` +
+ pebblo +
+
+
${heading}
+
${subHeading}
+
+ ${ + buttonNodes?.length + ? `
+ ${buttonNodes?.myMap((btnDetails) => Button({ ...btnDetails }))} +
` + : "" + } +
+
`; +}; diff --git a/pebblo/app/pebblo-ui/src/components/snippetDetails.js b/pebblo/app/pebblo-ui/src/components/snippetDetails.js index 50d542ad..a614c098 100644 --- a/pebblo/app/pebblo-ui/src/components/snippetDetails.js +++ b/pebblo/app/pebblo-ui/src/components/snippetDetails.js @@ -1,6 +1,7 @@ import { KEYUP } from "../constants/enums.js"; import { SearchIcon } from "../icons/index.js"; import { waitForElement } from "../util.js"; +import { EmptyState } from "./emptyState.js"; import { KeyValue } from "./index.js"; // PROPS { @@ -10,7 +11,7 @@ import { KeyValue } from "./index.js"; // } export function SnippetDetails(props) { - const { title, data, searchField, inputPlaceholder } = props; + const { title, data, searchField, inputPlaceholder, error } = props; waitForElement("#snippet_search", 1000).then(function () { const inputEl = document.getElementById("snippet_search"); @@ -38,29 +39,31 @@ export function SnippetDetails(props) { snippet_body.innerHTML = ""; snippet_body.innerHTML = filteredData?.length ? filteredData?.myMap( - (item) => /*html*/ ` + (item) => /*html*/ `
-
${item?.labelName - }
-
Showing ${item?.snippetCount - } out of ${item?.findings}
+
${ + item?.labelName + }
+
Showing ${ + item?.snippetCount + } out of ${item?.findings}
${item?.snippets?.myMap( - (snipp) => ` + (snipp) => `
${KeyValue({ key: "Snippets", value: snipp?.snippet })} ${KeyValue({ - key: "Retrieved From", - value: snipp?.sourcePath, - })} + key: "Retrieved From", + value: snipp?.sourcePath, + })}
` - )} + )}
` - ) + ) : /*html*/ `
No Data Found!!
`; } @@ -71,39 +74,46 @@ export function SnippetDetails(props) {
-
- ${data?.length - ? data?.myMap( - (item) => /*html*/ ` -
-
-
${item?.labelName - }
-
Showing ${item?.snippets?.length - } out of ${item?.snippetCount}
-
- ${item?.snippets?.myMap( - (snipp) => ` -
- ${KeyValue({ key: "Snippets", value: snipp?.snippet })} - ${KeyValue({ - key: "Retrieved From", - value: snipp?.sourcePath, - })} -
-
- ` - )} -
+ ${ + !error + ? `
+ ${ + data?.length + ? data?.myMap( + (item) => /*html*/ ` +
+
+
${ + item?.labelName + }
+
Showing ${ + item?.snippets?.length + } out of ${item?.snippetCount}
+
+ ${item?.snippets?.myMap( + (snipp) => ` +
+ ${KeyValue({ key: "Snippets", value: snipp?.snippet })} + ${KeyValue({ + key: "Retrieved From", + value: snipp?.sourcePath, + })} +
+
+ ` + )} +
` - ) - : /*html*/ `
No Data Found!!
` - } -
+ ) + : /*html*/ `
No Data Found!!
` + } +
` + : `
${EmptyState({ variant: error })}
` + }
`; } diff --git a/pebblo/app/pebblo-ui/src/constants/constant.js b/pebblo/app/pebblo-ui/src/constants/constant.js index 90de716c..16ae5641 100644 --- a/pebblo/app/pebblo-ui/src/constants/constant.js +++ b/pebblo/app/pebblo-ui/src/constants/constant.js @@ -5,12 +5,40 @@ import { DownloadIcon } from "../icons/index.js"; import { get_Formatted_Date } from "../util.js"; import { APP_DETAILS_ROUTE } from "./routesConstant.js"; -const SCRIPT_ELEMENT = document.getElementById("main_script") +const SCRIPT_ELEMENT = document.getElementById("main_script"); +const DOCUMENTATION_URL = "https://daxa-ai.github.io/pebblo"; -export const MEDIA_URL = SCRIPT_ELEMENT.dataset['static']; -export const APP_DATA = JSON.parse(SCRIPT_ELEMENT.dataset['appdata'] || ''); +export const MEDIA_URL = SCRIPT_ELEMENT.dataset["static"]; +export const APP_DATA = JSON.parse(SCRIPT_ELEMENT.dataset["appdata"] || ""); export const PORT = window.location.port; +export const NO_APPLICATIONS_FOUND = Object.keys(APP_DATA)?.length === 0; +export const NO_FINDINGS_FOR_APP = + APP_DATA && APP_DATA?.reportSummary + ? APP_DATA.reportSummary?.findings === 0 + : true; + +export const EMPTY_STATES = { + ENABLE_PEBBLO_EMPTY_STATE: { + image: `${MEDIA_URL}/static/pebblo-image.png`, + heading: "Enable Pebblo to unlock insights in your Gen-AI apps", + subHeading: + "Check out our installation guide or watch the video tutorial to enable Pebblo", + buttonNodes: [ + { + variant: "contained", + btnText: "View Installation Guide", + href: `${DOCUMENTATION_URL}/installation`, + }, + ], + }, + NO_FINDINGS_EMPTY_STATE: { + image: `${MEDIA_URL}/static/no-findings.png`, + heading: "", + subHeading: + "We scanned all your documents and didn’t discover any documents with findings", + }, +}; export const APP_DETAILS_FINDINGS_TABLE = [ { @@ -35,7 +63,7 @@ export const APP_DETAILS_FINDINGS_TABLE = [ }, { label: "Data Source", - render: () => APP_DATA?.dataSources[0]?.name + render: () => APP_DATA?.dataSources[0]?.name, }, ]; @@ -62,7 +90,7 @@ export const APP_DETAILS = [ }, { label: "Path", - render: /*html*/` + render: /*html*/ `
${APP_DATA?.instanceDetails?.path}
@@ -102,7 +130,7 @@ export const FILES_WITH_FINDINGS_TABLE = [ }, { label: "Data Source", - render: () => APP_DATA?.dataSources[0]?.name + render: () => APP_DATA?.dataSources[0]?.name, }, ]; @@ -156,7 +184,11 @@ export const TABLE_DATA_FOR_APPLICATIONS = [ render: (item) => Tooltip({ children: /*html*/ `
- ${DownloadIcon({ color: "primary", class: 'download-icon', id: `${item?.name}` })} + ${DownloadIcon({ + color: "primary", + class: "download-icon", + id: `${item?.name}`, + })}
`, title: "Download Icon", variant: "right", @@ -241,8 +273,9 @@ export const TABLE_DATA_FOR_DATA_SOURCE = [ render: (item) => /*html*/ `
${item.name || "-"}
-
${item.sourceSize} | ${item.sourcePath - }
+
${item.sourceSize} | ${ + item.sourcePath + }
`, align: "start", @@ -271,8 +304,9 @@ export const TABLE_DATA_FOR_DATA_SOURCE_APP_DETAILS = [ render: (item) => /*html*/ `
${item.name || "-"}
-
${item.sourceSize} | ${item.sourcePath - }
+
${item.sourceSize} | ${ + item.sourcePath + }
`, align: "start", @@ -295,31 +329,40 @@ export const TABLE_DATA_FOR_DATA_SOURCE_APP_DETAILS = [ }, ]; +const IS_CRITICAL_DATA = + NO_APPLICATIONS_FOUND || APP_DATA?.applicationsAtRiskCount?.length === 0 + ? false + : true; + export const TABS_ARR_FOR_APPLICATIONS = [ { label: "Applications With Findings", - critical: APP_DATA?.applicationsAtRiskCount || 0, + critical: NO_APPLICATIONS_FOUND + ? "-" + : APP_DATA?.applicationsAtRiskCount || 0, outOf: APP_DATA?.appList?.length || 0, value: 0, - isCritical: true, + isCritical: IS_CRITICAL_DATA, }, { label: "Findings", - critical: APP_DATA?.findingsCount || 0, + critical: NO_APPLICATIONS_FOUND ? "-" : APP_DATA?.findingsCount || 0, value: 1, - isCritical: true, + isCritical: IS_CRITICAL_DATA, }, { label: "Documents With Findings", - critical: APP_DATA?.documentsWithFindingsCount || 0, + critical: NO_APPLICATIONS_FOUND + ? "-" + : APP_DATA?.documentsWithFindingsCount || 0, value: 2, - isCritical: true, + isCritical: IS_CRITICAL_DATA, }, { label: "Data Source", - critical: APP_DATA?.dataSourceCount || 0, + critical: NO_APPLICATIONS_FOUND ? "-" : APP_DATA?.dataSourceCount || 0, value: 3, - isCritical: false, + isCritical: IS_CRITICAL_DATA, }, ]; @@ -332,6 +375,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATIONS = [ isDownloadReport: false, searchField: ["name", "owner"], isSorting: true, + error: NO_APPLICATIONS_FOUND ? "ENABLE_PEBBLO_EMPTY_STATE" : null, link: APP_DETAILS_ROUTE, inputPlaceholder: "Search by Application & Owner", }, @@ -343,6 +387,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATIONS = [ tableCol: TABLE_DATA_FOR_FINDINGS, tableData: APP_DATA?.findings, isDownloadReport: false, + error: NO_APPLICATIONS_FOUND ? "ENABLE_PEBBLO_EMPTY_STATE" : null, searchField: ["findingsType", "labelName", "appName"], isSorting: true, inputPlaceholder: "Search by Finding, Type & Application", @@ -355,6 +400,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATIONS = [ tableCol: TABLE_DATA_FOR_FILES_WITH_FINDINGS, tableData: APP_DATA?.documentsWithFindings, isDownloadReport: false, + error: NO_APPLICATIONS_FOUND ? "ENABLE_PEBBLO_EMPTY_STATE" : null, searchField: ["sourceFilePath", "appName"], isSorting: true, inputPlaceholder: "Search by File, Data Source & Application", @@ -367,6 +413,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATIONS = [ tableCol: TABLE_DATA_FOR_DATA_SOURCE, tableData: APP_DATA?.dataSource, isDownloadReport: false, + error: NO_APPLICATIONS_FOUND ? "ENABLE_PEBBLO_EMPTY_STATE" : null, searchField: ["name", "appName"], isSorting: true, inputPlaceholder: "Search by Data Source & Application", @@ -375,36 +422,46 @@ export const TAB_PANEL_ARR_FOR_APPLICATIONS = [ }, ]; +const IS_CRITICAL_COUNT = NO_FINDINGS_FOR_APP ? false : true; + export const TABS_ARR_FOR_APPLICATION_DETAILS = [ { label: "Findings", - critical: APP_DATA?.reportSummary?.findings || 0, + critical: NO_FINDINGS_FOR_APP + ? "-" + : APP_DATA?.reportSummary?.findings || 0, value: 0, - isCritical: true, + isCritical: IS_CRITICAL_COUNT, }, { label: "Documents With Findings", - critical: APP_DATA?.reportSummary?.filesWithFindings || 0, - outOf: APP_DATA?.reportSummary?.totalFiles || 0, + critical: NO_FINDINGS_FOR_APP + ? "-" + : APP_DATA?.reportSummary?.filesWithFindings || 0, + outOf: NO_FINDINGS_FOR_APP ? "" : APP_DATA?.reportSummary?.totalFiles || 0, value: 1, - isCritical: true, + isCritical: IS_CRITICAL_COUNT, }, { label: "Data Source", critical: APP_DATA?.reportSummary?.dataSources || 0, value: 2, - isCritical: false, + isCritical: IS_CRITICAL_COUNT, }, { label: "Snippets", - critical: APP_DATA?.dataSources + critical: NO_FINDINGS_FOR_APP + ? "-" + : APP_DATA?.dataSources ? APP_DATA?.dataSources[0]?.displayedSnippetCount : 0, - outOf: APP_DATA?.dataSources + outOf: NO_FINDINGS_FOR_APP + ? "" + : APP_DATA?.dataSources ? APP_DATA?.dataSources[0]?.totalSnippetCount : 0, value: 3, - isCritical: false, + isCritical: IS_CRITICAL_COUNT, }, ]; @@ -419,6 +476,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATION_DETAILS = [ searchField: ["labelName", "findingsType"], isSorting: true, inputPlaceholder: "Search by Finding & Type", + error: NO_FINDINGS_FOR_APP ? "NO_FINDINGS_EMPTY_STATE" : null, }, component: ApplicationsList, }, @@ -430,6 +488,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATION_DETAILS = [ searchField: ["fileName"], isSorting: true, inputPlaceholder: "Search by File", + error: NO_FINDINGS_FOR_APP ? "NO_FINDINGS_EMPTY_STATE" : null, }, component: ApplicationsList, }, @@ -452,6 +511,7 @@ export const TAB_PANEL_ARR_FOR_APPLICATION_DETAILS = [ : [], searchField: ["labelName"], inputPlaceholder: "Search", + error: NO_FINDINGS_FOR_APP ? "NO_FINDINGS_EMPTY_STATE" : null, }, component: SnippetDetails, }, diff --git a/pebblo/app/pebblo-ui/static/index.css b/pebblo/app/pebblo-ui/static/index.css index 24c9d448..7c2d0707 100644 --- a/pebblo/app/pebblo-ui/static/index.css +++ b/pebblo/app/pebblo-ui/static/index.css @@ -6,6 +6,7 @@ --surface-50: #787d9e; --surface-60: #7e83a5; --surface-70: #ced0dc; + --surface-80: #838282; } * { margin: 0; @@ -29,31 +30,31 @@ body { /* ICON STYLES */ -svg.icon-size-md{ +svg.icon-size-md { height: 20px; width: 20px; } -svg.icon-size-sm{ +svg.icon-size-sm { height: 14px; width: 14px; } -svg.icon-primary{ +svg.icon-primary { fill: var(--primary-blue); } -svg.icon-white{ +svg.icon-white { fill: white; } -svg:focus{ +svg:focus { outline: none; } -svg.icon-grey{ - fill: #7E83A5; +svg.icon-grey { + fill: #7e83a5; } -svg.icon-success{ - fill: #14BE9B; +svg.icon-success { + fill: #14be9b; } /* <----------- POSITION -----------> */ .absolute { @@ -346,6 +347,9 @@ svg.icon-success{ .surface-70 { color: var(--surface-70); } +.surface-80 { + color: var(--surface-80); +} .surface-100 { color: #eeeef2; } @@ -798,11 +802,11 @@ svg.icon-success{ background: none; padding-left: 8px; } -.search input::placeholder{ +.search input::placeholder { color: var(--surface-60); opacity: 50%; } -.search svg{ +.search svg { opacity: 50%; } @@ -831,30 +835,30 @@ button { background: none; } -button.btn-contained-primary{ +button.btn-contained-primary { background-color: var(--primary-blue); - color: white; + color: white; } -button.btn-contained-primary svg{ - fill: white; +button.btn-contained-primary svg { + fill: white; } -button.btn-outlined-primary{ +button.btn-outlined-primary { color: var(--primary-blue); border: 1px solid var(--primary-blue); } -button.btn-text-primary{ +button.btn-text-primary { color: var(--primary-blue); padding: 8px 10px; } -button.btn-contained-primary:hover{ +button.btn-contained-primary:hover { background-color: #4d61ef; } -button.btn-outlined-primary:hover{ +button.btn-outlined-primary:hover { background: #5468f308; border: 1px solid #4d61ef; } @@ -863,10 +867,10 @@ button.btn-text-primary:hover { background: #f1f3ff80; } -button.btn-text-white{ +button.btn-text-white { color: white; } -button.btn-text-white:hover{ +button.btn-text-white:hover { background: rgba(0, 0, 0, 0.05); } @@ -927,7 +931,7 @@ th.asc > div > svg { th.dsc > div > svg { rotate: 0deg; } -.sort-column{ +.sort-column { opacity: 0.8; } .sort-column:hover { @@ -935,7 +939,7 @@ th.dsc > div > svg { opacity: 1; } .sort-column:hover svg { - fill: var(--surface-50) !important; + fill: var(--surface-50) !important; } td.fit { width: 0; @@ -1077,7 +1081,10 @@ dialog::backdrop { text-overflow: ellipsis; } -.tooltip-wrapper-top, .tooltip-wrapper-right, .tooltip-wrapper-bottom, .tooltip-wrapper-left { +.tooltip-wrapper-top, +.tooltip-wrapper-right, +.tooltip-wrapper-bottom, +.tooltip-wrapper-left { position: absolute; visibility: hidden; } @@ -1170,4 +1177,4 @@ dialog::backdrop { border-width: 5px; border-style: solid; border-color: transparent transparent black transparent; -} \ No newline at end of file +} diff --git a/pebblo/app/pebblo-ui/static/no-findings.png b/pebblo/app/pebblo-ui/static/no-findings.png new file mode 100644 index 00000000..2ba8460e Binary files /dev/null and b/pebblo/app/pebblo-ui/static/no-findings.png differ diff --git a/pebblo/app/pebblo-ui/static/pebblo-image.png b/pebblo/app/pebblo-ui/static/pebblo-image.png new file mode 100644 index 00000000..3dfcb308 Binary files /dev/null and b/pebblo/app/pebblo-ui/static/pebblo-image.png differ