From 5e9c097ebdbad5bd8d2387aff17faea08da2af1b Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Tue, 28 May 2024 10:44:28 +0100 Subject: [PATCH 01/12] feat: Dashboard page --- src/app/components/AppBar/index.tsx | 16 +- .../components/Dialogs/deleteChartDialog.tsx | 6 +- src/app/components/Styled/tabs.ts | 2 +- .../home-module/assets/add-img-white.svg | 3 + .../home-module/components/All/assetsGrid.tsx | 362 ++++++++++++++++++ .../components/Charts/chartAddNewCard.tsx | 30 +- .../components/Charts/chartsGrid.tsx | 6 +- .../components/Charts/gridItem.tsx | 2 +- .../components/Datasets/datasetAddNewCard.tsx | 28 +- .../components/Datasets/datasetsGrid.tsx | 13 +- .../components/Datasets/gridItem.tsx | 2 +- .../home-module/components/Footer/index.tsx | 336 ++++++++-------- .../home-module/components/Footer/style.ts | 2 +- .../components/Reports/gridItem.tsx | 4 +- .../components/Reports/reportAddNewCard.tsx | 28 +- .../components/Reports/reportsGrid.tsx | 2 +- .../home-module/components/Table/index.tsx | 1 + src/app/modules/home-module/index.tsx | 144 +++++-- src/app/modules/home-module/style.ts | 30 +- .../sub-modules/explore-assets/index.tsx | 1 + .../state/api/action-reducers/assets/index.ts | 10 + src/app/state/api/interfaces/index.ts | 4 + src/app/state/recoil/atoms/index.ts | 4 +- src/app/state/store/index.ts | 5 + 24 files changed, 763 insertions(+), 278 deletions(-) create mode 100644 src/app/modules/home-module/assets/add-img-white.svg create mode 100644 src/app/modules/home-module/components/All/assetsGrid.tsx create mode 100644 src/app/state/api/action-reducers/assets/index.ts diff --git a/src/app/components/AppBar/index.tsx b/src/app/components/AppBar/index.tsx index bcfa407a8..de4a44962 100644 --- a/src/app/components/AppBar/index.tsx +++ b/src/app/components/AppBar/index.tsx @@ -307,19 +307,19 @@ const ActionMenu = () => { :nth-child(1) { width: ${isAuthenticated ? "146px" : "110px"}; height: 34px; - border-radius: ${isAuthenticated ? "24px 0px 0px 24px" : "24px"}; + border-radius: 24px; &:hover { opacity: 1; } } - :nth-child(2) { + /* :nth-child(2) { width: 41px; height: 34px; border-radius: 0px 24px 24px 0px; background: ${openActionPopover ? "#b5b5db" : "#dadaf8"}; &:hover { background: #b5b5db; - } + } */ } svg { ${openActionPopover ? "transform: rotate(180deg)" : ""} @@ -327,14 +327,12 @@ const ActionMenu = () => { } `} > - + - {isAuthenticated && ( + {/* {isAuthenticated && ( - )} + )} */} {isAuthenticated && ( - - - - - {/* {props.uploadError && ( -
+

-

- {" "} - Unable to upload your file. Please try again! -

- Error -
- )} */} - - )} + Drag and Drop Spreadsheets File here +

+ + )} + + - + + {fileRejections.length > 0 && fileRejectionItems} + ); }; diff --git a/src/app/modules/dataset-upload-module/component/externalSourcesList.tsx b/src/app/modules/dataset-upload-module/component/externalSourcesList.tsx new file mode 100644 index 000000000..602353970 --- /dev/null +++ b/src/app/modules/dataset-upload-module/component/externalSourcesList.tsx @@ -0,0 +1,78 @@ +import React from "react"; + +interface Source { + name: string; + value: string; +} + +interface Props { + baseSources: Source[]; + sources: string[]; + setSources: (c: string[]) => void; + customCss?: { gap: string }; +} +export default function SourceCategoryList(props: Readonly) { + const { customCss } = props; + return ( +
button { + font-size: 14px; + cursor: pointer; + min-width: 160px; + background: #fff; + border-radius: 30px; + border: 0.5px solid #231d2c; + font-family: "GothamNarrow-Book", sans-serif; + padding: 12px 0px; + } + `} + > + {props.baseSources.map((s) => ( + + ))} +
+ ); +} diff --git a/src/app/modules/dataset-upload-module/component/tabs.tsx b/src/app/modules/dataset-upload-module/component/tabs.tsx new file mode 100644 index 000000000..d5267d986 --- /dev/null +++ b/src/app/modules/dataset-upload-module/component/tabs.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import ComputerIcon from "../assets/computer-icon"; +import { Search } from "@material-ui/icons"; + +interface Props { + activeTab: "search" | "file"; + setActiveTab: (c: "search" | "file") => void; +} + +function UploadTabs({ activeTab, setActiveTab }: Props) { + return ( +
+ + + +
+ ); +} + +export default UploadTabs; diff --git a/src/app/modules/dataset-upload-module/component/uploadOption.tsx b/src/app/modules/dataset-upload-module/component/uploadOption.tsx new file mode 100644 index 000000000..cdbd60c52 --- /dev/null +++ b/src/app/modules/dataset-upload-module/component/uploadOption.tsx @@ -0,0 +1,196 @@ +import React from "react"; +import SettingsIcon from "../assets/upload-options-icons/settings"; + +const UploadOption = (props: { + name: string; + type: string; + formats: string[]; + icon: React.ReactNode; + disabled?: boolean; + onClick: (e: React.MouseEvent) => void; + setActiveOption: React.Dispatch>; + connected?: boolean; + onLogout?: () => void; + canConnect?: boolean; +}) => { + const [openSettings, setOpenSettings] = React.useState(false); + return ( + + + + + + ) : null} + + ) : ( +
+ {props.formats.map((f) => ( + {f} + ))} +
+ )} + + + ); +}; + +export default UploadOption; diff --git a/src/app/modules/dataset-upload-module/style.ts b/src/app/modules/dataset-upload-module/style.ts index 14969be72..f94d6767c 100644 --- a/src/app/modules/dataset-upload-module/style.ts +++ b/src/app/modules/dataset-upload-module/style.ts @@ -18,36 +18,14 @@ export const stepcss = css` height: 50px; } `; -export const uploadDatasetcss = css` - div:nth-child(1) { - background: #dadaf8; - height: 55px; - width: 100%; - color: #231d2c; - font-family: "GothamNarrow-Book"; - font-style: normal; - font-weight: 500; - font-size: 14px; - display: flex; - align-items: center; - padding-left: 2rem; - margin-top: 5rem; - } -`; export const uploadAreacss = (isDragActive: boolean, disabled?: boolean) => css` - height: 529px; + height: 131px; display: flex; flex-direction: column; justify-content: center; align-items: center; - background-color: ${isDragActive && !disabled ? "#c4c4c4" : "#ffffff"}; - background-image: ${isDragActive && !disabled - ? `url( - "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='163' height='163' viewBox='0 0 20 20'%3E%3Cg %3E%3Cpolygon fill='%23ffffff' points='20 10 10 0 0 0 20 20'/%3E%3Cpolygon fill='%23ffffff' points='0 10 0 20 10 20'/%3E%3C/g%3E%3C/svg%3E" - )` - : "unset"}; &:hover { cursor: ${!isDragActive && !disabled ? "pointer" : "default"}; } @@ -94,7 +72,7 @@ export const metaDatacss = css` font-weight: 500; font-size: 48px; font-family: "Inter", sans-serif; - margin-top: 6rem; + margin-top: 40px; margin-bottom: 4.5rem; } diff --git a/src/app/modules/dataset-upload-module/upload-steps/addDatasetFragment.tsx b/src/app/modules/dataset-upload-module/upload-steps/addDatasetFragment.tsx index 583b07326..509fcae5a 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/addDatasetFragment.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/addDatasetFragment.tsx @@ -1,69 +1,59 @@ /**third party */ -import React, { useCallback, useEffect } from "react"; -import { useDropzone } from "react-dropzone"; -import useDrivePicker from "react-google-drive-picker"; -import { - CallbackDoc, - PickerCallback, -} from "react-google-drive-picker/dist/typeDefs"; -import axios from "axios"; +import React, { useCallback } from "react"; + /** project */ -import { formatBytes } from "app/utils/formatBytes"; -import { useStoreState } from "app/state/store/hooks"; + import { DropZone } from "app/modules/dataset-upload-module/component/dropzone/"; +import { Box } from "@material-ui/core"; +import LocalIcon from "../assets/upload-options-icons/local"; +import GoogleIcon from "../assets/upload-options-icons/google"; +import MicrosoftIcon from "../assets/upload-options-icons/microsoft"; +import ApiIcon from "../assets/upload-options-icons/api"; +import MSSQLIcon from "../assets/upload-options-icons/mssql.png"; +import MYSQLIcon from "../assets/upload-options-icons/mysql.png"; +import PostgresIcon from "../assets/upload-options-icons/postgres"; +import MongoDbIcon from "../assets/upload-options-icons/mongodb"; +import HubspotIcon from "../assets/upload-options-icons/hubspot"; +import UploadOption from "../component/uploadOption"; +import { useCookie } from "react-use"; +import useGoogleDrivePicker from "app/hooks/useGoogleDrivePicker"; +import { useOneDrivePicker } from "app/hooks/useOneDrivePicker"; interface Props { disabled: boolean; onFileSubmit: (file: File) => void; processingError: string | null; - setIsExternalSearch: React.Dispatch>; + activeOption: string | null; + setActiveOption: React.Dispatch>; + setActiveStep: React.Dispatch>; } export default function AddDatasetFragment(props: Props) { - const [openPicker] = useDrivePicker(); - const token = useStoreState((state) => state.AuthToken.value); - - const handleGoogleDriveFilePicker = async ( - file: CallbackDoc, - accessToken: string - ) => { - try { - const response = await axios({ - url: `https://www.googleapis.com/drive/v3/files/${file.id}${ - file.type === "file" ? "?alt=media" : "/export?mimeType=text/csv" - }`, - method: "GET", - headers: { - Authorization: `Bearer ${accessToken}`, - }, - responseType: "blob", // important - }); - - const b = response?.data; - const gfile = new File([b], file.name, { type: "text/csv" }); + const [googleDriveToken, setGoogleDriveToken, deleteGoogleDriveToken] = + useCookie("googleDriveToken"); - props.onFileSubmit(gfile); - } catch (e) { - console.log(e, "handleGoogleDriveFilePicker error"); - } - }; - useEffect(() => { - if (process.env.REACT_APP_CYPRESS_TEST === "true") { - window.handleGoogleDriveFilePicker = function (file: any, token: string) { - handleGoogleDriveFilePicker(file, token); - }; - } - }, []); + const { getAccessTokenAndOpenPicker } = useGoogleDrivePicker({ + onCancel: () => { + props.setActiveOption(null); + }, + onFileSubmit: (file: File) => { + props.onFileSubmit(file); + }, + googleDriveToken, + setGoogleDriveToken, + }); - const ACCEPTED_FILES = { - "text/csv": [".csv"], - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [ - ".xlsx", - ], - "application/xml": [".xml"], - "application/vnd.ms-excel": [".xls"], - "application/xhtml+xml": [".xhtml"], - }; + const { launchPicker, clearToken, connected } = useOneDrivePicker({ + onCancel: () => { + props.setActiveOption(null); + }, + onFileSubmit: (file: File) => { + props.onFileSubmit(file); + }, + onDownloadStart: () => { + props.setActiveStep(1); + }, + }); const onDrop = useCallback((acceptedFiles: File[]) => { if (acceptedFiles.length > 0) { @@ -71,76 +61,207 @@ export default function AddDatasetFragment(props: Props) { } }, []); - const { - getRootProps, - getInputProps, - isDragActive, - acceptedFiles, - fileRejections, - } = useDropzone({ onDrop, accept: ACCEPTED_FILES }); - - const getAccessToken = () => { - return axios.get( - `${process.env.REACT_APP_API}/dataset/google-drive/user-token`, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - }; - - const getAccessTokenAndOpenPicker = async () => { - try { - const res = await getAccessToken(); - - //opens google drive picker - openPicker({ - clientId: process.env.REACT_APP_GOOGLE_API_CLIENT_ID as string, - developerKey: process.env.REACT_APP_GOOGLE_API_DEV_KEY as string, - viewId: "SPREADSHEETS", - supportDrives: true, - token: res.data, - setSelectFolderEnabled: true, - callbackFunction: (d: PickerCallback) => { - handleGoogleDriveFilePicker(d.docs[0], res.data); - }, - }); - } catch (e) { - console.log(e, "error"); - } - }; - - function handleOpenPicker(e: React.MouseEvent) { - e.stopPropagation(); - getAccessTokenAndOpenPicker(); - } - - const fileRejectionItems = fileRejections.map(({ file, errors }) => ( -
  • - {file.name} - {formatBytes(file.size)} -
      - {errors.map((e) => ( -
    • {e.message}
    • - ))} -
    -
  • - )); + const uploadOptions = [ + { + name: "Local upload", + type: "Table Dataset", + formats: ["CSV", "XSLX", "JSON", "ODS", "SQLite"], + icon: , + onClick: () => {}, + }, + { + name: "Google Drive", + type: "Upload", + formats: [], + icon: , + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + getAccessTokenAndOpenPicker(); + }, + canConnect: true, + connected: !!googleDriveToken, + onLogout: () => { + deleteGoogleDriveToken(); + }, + }, + { + name: "Microsoft Cloud", + type: "Upload", + formats: [], + icon: , + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + launchPicker(); + }, + canConnect: true, + connected: connected, + onLogout: async () => { + await clearToken(); + }, + }, + { + name: "API Connection", + type: "URL, JSON or XML root", + formats: ["CSV", "XSLX", "JSON", "ODS", "SQLite"], + icon: , + onClick: () => {}, + }, + { + name: "MSSQL", + type: "DataBase Connection", + formats: ["Coming Soon"], + icon: , + onClick: () => {}, + }, + { + name: "MSSQL", + type: "DataBase Connection", + formats: ["Coming Soon"], + icon: , + onClick: () => {}, + }, + { + name: "PostgreSQL", + type: "DataBase Connection", + formats: ["Coming Soon"], + icon: , + onClick: () => {}, + }, + { + name: "MongoDB", + type: "DataBase Connection", + formats: ["Coming Soon"], + icon: , + onClick: () => {}, + }, + { + name: "Hubspot", + type: "DataBase Connection", + formats: ["Coming Soon"], + icon: , + onClick: () => {}, + }, + ]; return ( <> - - {fileRejections.length > 0 && fileRejectionItems} +
    +

    File Upload

    + +

    + Upload your favourite data effortlessly in DataXplorer, and with just + a few clicks, import datasets without the hassle of downloading,{" "} +
    + enabling you to visualize and analyse diverse data like never before. +

    +
    + + + + {props.activeOption === "Local upload" ? ( + <> + + + ) : ( +
    +
    + Connect your data +
    +
    +
    + {uploadOptions.slice(0, 3).map((option) => ( + + ))} +
    + +
    + +
    + {uploadOptions.slice(3).map((option) => ( + + ))} +
    +
    +
    + )} ); } diff --git a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx index 2ffa2cd79..43aae4f6c 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx @@ -9,6 +9,7 @@ import useDebounce from "react-use/lib/useDebounce"; import axios from "axios"; import CircleLoader from "app/modules/home-module/components/Loader"; import { useInfinityScroll } from "app/hooks/useInfinityScroll"; +import SourceCategoryList from "../component/externalSourcesList"; export interface IExternalDataset { name: string; @@ -32,7 +33,6 @@ export default function ExternalSearch(props: { handleDownload: (dataset: IExternalDataset) => void; setProcessingError: React.Dispatch>; setActiveStep: React.Dispatch>; - setIsExternalSearch: React.Dispatch>; }) { const observerTarget = React.useRef(null); const [tableView, setTableView] = React.useState(false); @@ -45,6 +45,14 @@ export default function ExternalSearch(props: { const limit = 20; const [datasets, setDatasets] = React.useState([]); + const [sources, setSources] = React.useState([]); + const baseSources = [ + { name: "Kaggle", value: "Kaggle" }, + { name: "World Bank", value: "World Bank" }, + { name: "WHO", value: "WHO" }, + { name: "HDX", value: "HDX" }, + ]; + const { isObserved } = useInfinityScroll(observerTarget); const abortControllerRef = React.useRef( @@ -53,8 +61,8 @@ export default function ExternalSearch(props: { const terminateSearch = () => { abortControllerRef.current.abort(); abortControllerRef.current = new AbortController(); - setDatasets([]); - setOffset(0); + // setDatasets([]); + // setOffset(0); }; // Pagination on scroll @@ -70,7 +78,9 @@ export default function ExternalSearch(props: { const response = await axios.get( `${ process.env.REACT_APP_API - }/external-sources/search?q=${searchValue}&source=${"Kaggle,World Bank,WHO,HDX"}&offset=${offset}&limit=${limit}`, + }/external-sources/search?q=${searchValue}&source=${ + sources.length ? sources.join(",") : "Kaggle,World Bank,WHO,HDX" + }&offset=${offset}&limit=${limit}`, { signal: abortControllerRef.current.signal, headers: { @@ -112,70 +122,62 @@ export default function ExternalSearch(props: { } }, 500, - [searchValue, token] + [searchValue, token, sources] ); return ( <>
    - props.setIsExternalSearch(false)}> - - -
    -

    External Search

    -

    - Connect to your favourite data sources effortlessly in DataXplorer, - and with just a few clicks, import datasets without the hassle of - downloading, enabling you to visualize and analyse diverse data like - never before. -

    -
    +

    Federated Search

    + +

    + Connect to your favourite data sources effortlessly in DataXplorer, + and with just a few clicks, import datasets without the hassle of + downloading, +
    enabling you to visualize and analyse diverse data like never + before. +

    - - - - + + + + + - + + {datasets && datasets?.map((dataset, index) => ( diff --git a/src/app/modules/dataset-upload-module/upload-steps/index.tsx b/src/app/modules/dataset-upload-module/upload-steps/index.tsx index 7cbe4154d..6c0919e58 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/index.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/index.tsx @@ -1,5 +1,5 @@ /** third party */ -import React from "react"; +import React, { useEffect } from "react"; import axios from "axios"; import Container from "@material-ui/core/Container"; import { useAuth0, withAuthenticationRequired } from "@auth0/auth0-react"; @@ -23,6 +23,10 @@ import ExternalSearch, { import Stepper from "app/modules/dataset-upload-module/component/stepper"; import { Box } from "@material-ui/core"; import { useTitle } from "react-use"; +import BreadCrumbs from "app/modules/home-module/components/Breadcrumbs"; +import UploadTabs from "../component/tabs"; +import HomeFooter from "app/modules/home-module/components/Footer"; +import SmallFooter from "app/modules/home-module/components/Footer/smallFooter"; interface Props { datasetId: string; @@ -50,7 +54,9 @@ function DatasetUploadSteps(props: Props) { const [processed, setProcessed] = React.useState(false); const [selectedFile, setSelectedFile] = React.useState(null); const [isExternalSearch, setIsExternalSearch] = React.useState(false); - const [fromExternalSearch, setFromExternalSearch] = React.useState(false); + + const [activeTab, setActiveTab] = React.useState<"search" | "file">("search"); + const [activeOption, setActiveOption] = React.useState(null); const defaultProcessingError = "Data could not be processed, please try again or contact your administrator"; @@ -203,9 +209,6 @@ function DatasetUploadSteps(props: Props) { const id = ObjectId(); //expose file id to datasetId state; to be used in dataset upload props.setDatasetId(id); - //set isExternalSearch to false - setIsExternalSearch(false); - setFromExternalSearch(true); //set active step to processing setActiveStep(1); axios @@ -249,21 +252,63 @@ function DatasetUploadSteps(props: Props) { const tryAgain = () => { setActiveStep(0); - if (fromExternalSearch) { - setIsExternalSearch(true); - } }; + useEffect(() => { + if (activeOption) { + setActiveOption(null); + } + }, [activeTab]); + const currentStep = () => { switch (activeStep) { case 0: return ( - + <> + + { + if (activeOption) { + setActiveOption(null); + } + }} + > + Connect Data + + ), + path: "#", + }, + ...(activeOption ? [{ title: activeOption }] : []), + ]} + /> + + + + {activeTab === "search" ? ( + <> + + + ) : ( + + )} + ); case 1: return ( @@ -309,7 +354,9 @@ function DatasetUploadSteps(props: Props) { onFileSubmit={onFileSubmit} disabled={false} processingError={processingError} - setIsExternalSearch={setIsExternalSearch} + setActiveOption={setActiveOption} + activeOption={activeOption} + setActiveStep={setActiveStep} /> ); } @@ -317,38 +364,32 @@ function DatasetUploadSteps(props: Props) { return ( <> - -
    - {steps.map((tab, index) => ( - 0 && !processed && activeStep !== index} - /> - ))} -
    +
    + +
    + {steps.map((tab, index) => ( + 0 && !processed && activeStep !== index} + /> + ))} +
    - {isExternalSearch ? ( - <> - - - - ) : ( <>
    {currentStep()}
    - )} -
    + +
    + {activeStep === 0 ? : null} ); } diff --git a/src/app/modules/home-module/components/All/assetsGrid.tsx b/src/app/modules/home-module/components/All/assetsGrid.tsx index 09f6b0211..760c9449e 100644 --- a/src/app/modules/home-module/components/All/assetsGrid.tsx +++ b/src/app/modules/home-module/components/All/assetsGrid.tsx @@ -22,12 +22,12 @@ import ReportAddnewCard from "../Reports/reportAddNewCard"; import ColoredReportIcon from "app/assets/icons/ColoredReportIcon"; import DeleteDatasetDialog from "app/components/Dialogs/deleteDatasetDialog"; import DeleteReportDialog from "app/components/Dialogs/deleteReportDialog"; +import { HomepageTable } from "../Table"; interface Props { sortBy: string; searchStr: string; tableView: boolean; - addCard?: boolean; showMenuButton: boolean; inChartBuilder?: boolean; category?: string; @@ -236,87 +236,115 @@ export default function AssetsGrid(props: Props) { return ( <> - - {props.addCard && ( - <> - - - - - )} - {loadedAssets.map((d, index) => ( - - { - { - chart: ( - { - setActiveAssetType(d.assetType as assetType); - handleModal(d.id); - }} - handleDuplicate={() => - handleDuplicate(d.id, d.assetType as assetType) - } - owner={d.owner} - isAIAssisted={d.isAIAssisted} - /> - ), - dataset: ( - { - setActiveAssetType(d.assetType as assetType); - handleModal(d.id); - }} - descr={d.description} - handleDuplicate={() => { - handleDuplicate(d.id, d.assetType as assetType); - }} - showMenu={!props.inChartBuilder} - id={d.id} - owner={d.owner} - inChartBuilder={props.inChartBuilder as boolean} - fromHome={props.fromHome} - /> - ), - report: ( - } - color={d.backgroundColor} - showMenuButton={props.showMenuButton} - handleDelete={() => { - setActiveAssetType(d.assetType as assetType); - handleModal(d.id); - }} - handleDuplicate={() => - handleDuplicate(d.id, d.assetType as assetType) - } - title={d.title || d.name} - owner={d.owner} - /> - ), - }[d.assetType as assetType] + {props.tableView ? ( + { + if (data.assetType === "chart") { + return { + id: data.id, + name: data.name, + description: data.title, + createdDate: data.createdDate, + type: data.assetType, + }; + } else if (data.assetType === "dataset") { + return { + id: data.id, + name: data.name, + description: data.description, + createdDate: data.createdDate, + type: data.assetType, + }; } - - - ))} - + return { + id: data.id, + name: data.name, + description: data.title, + createdDate: data.createdDate, + type: data.assetType, + }; + })} + /> + ) : ( + + {loadedAssets.map((d, index) => ( + + { + { + chart: ( + { + setActiveAssetType(d.assetType as assetType); + handleModal(d.id); + }} + handleDuplicate={() => + handleDuplicate(d.id, d.assetType as assetType) + } + owner={d.owner} + isAIAssisted={d.isAIAssisted} + /> + ), + dataset: ( + { + setActiveAssetType(d.assetType as assetType); + handleModal(d.id); + }} + descr={d.description} + handleDuplicate={() => { + handleDuplicate(d.id, d.assetType as assetType); + }} + showMenu={!props.inChartBuilder} + id={d.id} + owner={d.owner} + inChartBuilder={props.inChartBuilder as boolean} + fromHome={props.fromHome} + /> + ), + report: ( + } + color={d.backgroundColor} + showMenuButton={props.showMenuButton} + handleDelete={() => { + setActiveAssetType(d.assetType as assetType); + handleModal(d.id); + }} + handleDuplicate={() => + handleDuplicate(d.id, d.assetType as assetType) + } + title={d.title || d.name} + owner={d.owner} + /> + ), + }[d.assetType as assetType] + } + + + + ))} + + )} diff --git a/src/app/modules/home-module/components/Breadcrumbs/index.tsx b/src/app/modules/home-module/components/Breadcrumbs/index.tsx new file mode 100644 index 000000000..9e5b45b9d --- /dev/null +++ b/src/app/modules/home-module/components/Breadcrumbs/index.tsx @@ -0,0 +1,81 @@ +import { KeyboardArrowRight } from "@material-ui/icons"; +import React from "react"; +import { Link } from "react-router-dom"; + +interface BreadCrumbsProps { + items: { path?: string; title: React.ReactNode }[]; +} + +function BreadCrumbs(props: BreadCrumbsProps) { + return ( +
    + {props.items.map((item, index) => ( +
    + {index === props.items.length - 1 ? ( + + {item.title} + + ) : ( + + {item.title} + + )} + + {index < props.items.length - 1 && ( + + )} +
    + ))} +
    + ); +} + +export default BreadCrumbs; diff --git a/src/app/modules/home-module/components/Charts/chartsGrid.tsx b/src/app/modules/home-module/components/Charts/chartsGrid.tsx index 9bca2b8d5..ef90a2044 100644 --- a/src/app/modules/home-module/components/Charts/chartsGrid.tsx +++ b/src/app/modules/home-module/components/Charts/chartsGrid.tsx @@ -210,7 +210,7 @@ export default function ChartsGrid(props: Props) { <> {!props.tableView && ( - {props.addCard && isAuthenticated ? : null} + {props.addCard ? : null} {loadedCharts.map((c, index) => ( )} diff --git a/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx b/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx index 5b9f49bbd..b904bd863 100644 --- a/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx +++ b/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx @@ -209,7 +209,7 @@ export default function DatasetsGrid(props: Readonly) { <> {!props.tableView && ( - {props.addCard && isAuthenticated ? : null} + {props.addCard ? : null} {loadedDatasets?.map((data, index) => ( ) { name: data.name, description: data.description, createdDate: data.createdDate, + type: "dataset", }))} /> )} diff --git a/src/app/modules/home-module/components/Filter/index.tsx b/src/app/modules/home-module/components/Filter/index.tsx index 1eda07ad1..270096dc5 100644 --- a/src/app/modules/home-module/components/Filter/index.tsx +++ b/src/app/modules/home-module/components/Filter/index.tsx @@ -20,6 +20,7 @@ export default function Filter( setTableView: React.Dispatch>; tableView: boolean; terminateSearch?: () => void; + searchInputWidth?: string; }> ) { const inputRef = React.useRef(null); @@ -55,7 +56,7 @@ export default function Filter( gap: 8px; `} > -
    +
    + +
    +

    + + {moment(new Date()).format("YYYY")} DataXplorer All Rights Reserved +

    +

    + + Privacy + +

    +

    + + Terms and conditions + +

    +
    +
    +
    + ); +} + +export default SmallFooter; diff --git a/src/app/modules/home-module/components/Reports/reportsGrid.tsx b/src/app/modules/home-module/components/Reports/reportsGrid.tsx index dd8f1eb38..fcd207cbe 100644 --- a/src/app/modules/home-module/components/Reports/reportsGrid.tsx +++ b/src/app/modules/home-module/components/Reports/reportsGrid.tsx @@ -198,7 +198,7 @@ export default function ReportsGrid(props: Props) { <> {!props.tableView && ( - {props.addCard && isAuthenticated ? : null} + {props.addCard ? : null} {loadedReports.map((data, index) => ( )} diff --git a/src/app/modules/home-module/components/Table/index.tsx b/src/app/modules/home-module/components/Table/index.tsx index f2bb9ef40..063aaa884 100644 --- a/src/app/modules/home-module/components/Table/index.tsx +++ b/src/app/modules/home-module/components/Table/index.tsx @@ -16,19 +16,13 @@ export function HomepageTable(props: { name: string; description: string; createdDate: Date; + type: string; }[]; inChartBuilder?: boolean; onItemClick?: (v: string) => void; fromHome?: boolean; }) { const history = useHistory(); - const display = useRecoilState(homeDisplayAtom)[0]; - const pathBase = { - all: "all", - data: "dataset", - charts: "chart", - reports: "report", - }; return ( { if (!props.inChartBuilder) { history.push( - `/${pathBase[display]}/${data.id}${ - display === "data" + `/${data.type}/${data.id}${ + data.type === "dataset" ? `/detail?fromHome=${props.fromHome}` : "" }` diff --git a/src/app/modules/home-module/index.tsx b/src/app/modules/home-module/index.tsx index 62b119c64..462a1657d 100644 --- a/src/app/modules/home-module/index.tsx +++ b/src/app/modules/home-module/index.tsx @@ -7,21 +7,14 @@ import { useRecoilState, useResetRecoilState } from "recoil"; import { Box, Grid, Container, IconButton, Popover } from "@material-ui/core"; /* project */ import { Tab } from "app/components/Styled/tabs"; -import { socialAuth } from "app/utils/socialAuth"; import HomeFooter from "app/modules/home-module/components/Footer"; import ChartsGrid from "app/modules/home-module/components/Charts/chartsGrid"; import ReportsGrid from "app/modules/home-module/components/Reports/reportsGrid"; -import DatasetDetailImage from "app/modules/home-module/assets/dataset-detail.png"; import DatasetsGrid from "app/modules/home-module/components/Datasets/datasetsGrid"; import { ReactComponent as SortIcon } from "app/modules/home-module/assets/sort-fill.svg"; import { ReactComponent as GridIcon } from "app/modules/home-module/assets/grid-fill.svg"; import { ReactComponent as CloseIcon } from "app/modules/home-module/assets/close-icon.svg"; import { ReactComponent as SearchIcon } from "app/modules/home-module/assets/search-fill.svg"; -import { ReactComponent as GoogleIcon } from "app/modules/onboarding-module/asset/google-img.svg"; -import { ReactComponent as LinkedInIcon } from "app/modules/onboarding-module/asset/linkedIn-img.svg"; -import { ReactComponent as TopRightEllipse } from "app/modules/home-module/assets/top-right-ellipse.svg"; -import { ReactComponent as BottomLeftEllipse } from "app/modules/home-module/assets/bottom-left-ellipse.svg"; -import { ReactComponent as BottomRightEllipse } from "app/modules/home-module/assets/bottom-right-ellipse.svg"; import { homeDisplayAtom, persistedReportStateAtom, @@ -29,10 +22,6 @@ import { unSavedReportPreviewModeAtom, } from "app/state/recoil/atoms"; import { - TopRightEllipseCss, - bottomLeftEllipseCss, - bottomRightEllipseCss, - datsetDetailImgcss, featuredAssetsCss, iconButtonCss, rowFlexCss, @@ -43,6 +32,8 @@ import { import DatasetCategoryList from "./components/Datasets/datasetCategoryList"; import { datasetCategories } from "../dataset-upload-module/upload-steps/metaData"; import AssetsGrid from "./components/All/assetsGrid"; +import BreadCrumbs from "./components/Breadcrumbs"; +import SmallFooter from "./components/Footer/smallFooter"; export default function HomeModule() { useTitle("DX DataXplorer"); @@ -63,7 +54,7 @@ export default function HomeModule() { setReportPreviewMode(false); }, []); - const [category, setCategory] = React.useState(""); + const [categories, setCategories] = React.useState([]); const [tableView, setTableView] = React.useState(false); const [searchValue, setSearchValue] = React.useState( @@ -106,8 +97,7 @@ export default function HomeModule() { sortBy={sortByStr} searchStr={searchStr} tableView={tableView} - category={category} - addCard + categories={categories} fromHome /> ); @@ -117,7 +107,6 @@ export default function HomeModule() { sortBy={sortByStr} searchStr={searchStr} tableView={tableView} - addCard /> ); case "reports": @@ -127,7 +116,6 @@ export default function HomeModule() { searchStr={searchStr} tableView={tableView} showMenuButton={false} - addCard /> ); case "all": @@ -137,7 +125,6 @@ export default function HomeModule() { searchStr={searchStr} tableView={tableView} showMenuButton={false} - addCard fromHome /> ); @@ -166,7 +153,7 @@ export default function HomeModule() { }, [display]); const descriptions = { - all: "Explore the collection of Reports, Charts and Datasets", + all: "Explore the collection of Assets", data: "Explore the collection of Datasets used to create Charts", charts: "Explore the collection of Charts used in Reports", reports: "Explore the collection of Reports", @@ -175,132 +162,10 @@ export default function HomeModule() { return (
    - {/*
    - - - -
    -

    Turn data into impact with DataXplorer

    - -

    - - DataXplorer simplifies and empowers visual data reporting - for all. - -

    - - {isAuthenticated && ( -
    - - CREATE REPORT - - -
    - )} - {!isAuthenticated && ( -
    button { - gap: 10px; - color: #fff; - display: flex; - padding: 9px 18px; - background: #a1a2ff; - align-items: center; - justify-content: center; - text-transform: uppercase; - - > svg { - transform: scale(0.8); - } - } - `} - > - - -
    - )} -
    -
    - - dataset-detail-img - -
    -
    - - - - - - -
    */} - -

    Library:

    + ))} - {display !== "all" && ( - { - setTableView(!tableView); - }} - css={iconButtonCss(tableView)} - > - - - )} + { + setTableView(!tableView); + }} + css={iconButtonCss(tableView)} + > + +
    @@ -525,9 +388,9 @@ export default function HomeModule() {
    {display === "data" ? ( ) : ( @@ -545,7 +408,7 @@ export default function HomeModule() { {displayGrid(searchValue as string, sortValue)}
    - + ); } diff --git a/src/app/modules/home-module/style.ts b/src/app/modules/home-module/style.ts index d80553d02..c7901f648 100644 --- a/src/app/modules/home-module/style.ts +++ b/src/app/modules/home-module/style.ts @@ -7,7 +7,6 @@ export const turnsDataCss = css` justify-content: center; align-items: center; } */ - margin-top: 80px; display: flex; justify-content: space-between; align-items: center; @@ -103,11 +102,14 @@ export const TopRightEllipseCss = css` position: absolute; `; -export const searchInputCss = (openSearch: boolean) => css` +export const searchInputCss = ( + openSearch: boolean, + width: string = "385px" +) => css` background: #dadaf8; display: flex; align-items: center; - width: 385px; + width: ${width ?? "385px"}; height: 32px; border-radius: 20px; opacity: ${openSearch ? 1 : 0}; diff --git a/yarn.lock b/yarn.lock index 7fbe7f0df..3652ded13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,6 +28,18 @@ resolved "https://registry.yarnpkg.com/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.2.tgz#2217db13ce0feb480a190ed165b36681bd48633c" integrity sha512-xdA65Z/U7++Y7L9Uwh8Q8OVOs6qgFz+fb7GAzHFjpr1icO37B//xdzLXm7ZRgA19RWrsNe1nme3h896igJSvvw== +"@azure/msal-browser@^3.15.0": + version "3.15.0" + resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-3.15.0.tgz#a3b223e79e46db827f54057021a200f3755cbdf7" + integrity sha512-jqngIR0zGLtEHCAhgXLl+VZTFcU/9DmRSjGj5RbrLnFPL/0L9Hr68k8grvLrTIq7tjhTM5Xgh6Xc0l7JlViHQQ== + dependencies: + "@azure/msal-common" "14.10.0" + +"@azure/msal-common@14.10.0": + version "14.10.0" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.10.0.tgz#215449726717b53d549953db77562cad6cb8421c" + integrity sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA== + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3": version "7.16.7" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz" From ef94de3cc14f298d43f449456276fb26c79aa2e7 Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Fri, 31 May 2024 06:32:40 +0100 Subject: [PATCH 03/12] feat: restrict file types for one drive picker --- src/app/hooks/useOneDrivePicker.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/hooks/useOneDrivePicker.tsx b/src/app/hooks/useOneDrivePicker.tsx index 108a5e91d..d0422b93e 100644 --- a/src/app/hooks/useOneDrivePicker.tsx +++ b/src/app/hooks/useOneDrivePicker.tsx @@ -52,6 +52,7 @@ export const useOneDrivePicker = ({ }, typesAndSources: { mode: "files", + filters: [".xlsx", ".csv", ".xml", ".xls", ".xhtml"], pivots: { oneDrive: true, recent: true, From 385452ba16ec604990939d57baeae4c70ace866e Mon Sep 17 00:00:00 2001 From: Sylvan Ridderinkhof Date: Mon, 3 Jun 2024 16:13:24 +0200 Subject: [PATCH 04/12] chore: add TGF as option for external search results --- .../upload-steps/externalSearch.tsx | 2 +- .../modules/home-module/assets/tgf-logo.svg | 88 +++++++++++++++++++ .../Datasets/externalDatasetCard.tsx | 3 + 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/app/modules/home-module/assets/tgf-logo.svg diff --git a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx index 2ffa2cd79..2e438b456 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx @@ -70,7 +70,7 @@ export default function ExternalSearch(props: { const response = await axios.get( `${ process.env.REACT_APP_API - }/external-sources/search?q=${searchValue}&source=${"Kaggle,World Bank,WHO,HDX"}&offset=${offset}&limit=${limit}`, + }/external-sources/search?q=${searchValue}&source=${"Kaggle,World Bank,WHO,HDX,TGF"}&offset=${offset}&limit=${limit}`, { signal: abortControllerRef.current.signal, headers: { diff --git a/src/app/modules/home-module/assets/tgf-logo.svg b/src/app/modules/home-module/assets/tgf-logo.svg new file mode 100644 index 000000000..020f6e39a --- /dev/null +++ b/src/app/modules/home-module/assets/tgf-logo.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/modules/home-module/components/Datasets/externalDatasetCard.tsx b/src/app/modules/home-module/components/Datasets/externalDatasetCard.tsx index 17d9edee0..a807d49a7 100644 --- a/src/app/modules/home-module/components/Datasets/externalDatasetCard.tsx +++ b/src/app/modules/home-module/components/Datasets/externalDatasetCard.tsx @@ -6,6 +6,7 @@ import WHOLogo from "app/modules/home-module/assets/WHO-logo.svg"; import KaggleLogo from "app/modules/home-module/assets/kaggle-logo.svg"; import WorldBankLogo from "app/modules/home-module/assets/world-bank-logo.svg"; import HDXLogo from "app/modules/home-module/assets/hdx-logo.svg"; +import TGFLogo from "app/modules/home-module/assets/tgf-logo.svg"; import { ReactComponent as ClockIcon } from "app/modules/home-module/assets/clock-icon.svg"; import moment from "moment"; @@ -31,6 +32,8 @@ export default function IExternalDatasetCard( return world-bank-logo; case "HDX": return hdx-logo; + case "TGF": + return tgf-logo; default: return
    ; } From d49fb8cafb6bb18fb463b548c1c43a2baa8838c5 Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Tue, 4 Jun 2024 05:07:34 +0100 Subject: [PATCH 05/12] feat: DX-1523 - Update bignumber chart icon on cards --- .../icons/data-themes-chart-types/coloredBigNumber.tsx | 10 +++++----- .../components/right-panel-create-view/data.tsx | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/app/assets/icons/data-themes-chart-types/coloredBigNumber.tsx b/src/app/assets/icons/data-themes-chart-types/coloredBigNumber.tsx index 299ce87e1..243104ac9 100644 --- a/src/app/assets/icons/data-themes-chart-types/coloredBigNumber.tsx +++ b/src/app/assets/icons/data-themes-chart-types/coloredBigNumber.tsx @@ -3,15 +3,15 @@ import React from "react"; export default function Icon() { return ( ); diff --git a/src/app/modules/report-module/components/right-panel-create-view/data.tsx b/src/app/modules/report-module/components/right-panel-create-view/data.tsx index 108ba5018..13237e7e4 100644 --- a/src/app/modules/report-module/components/right-panel-create-view/data.tsx +++ b/src/app/modules/report-module/components/right-panel-create-view/data.tsx @@ -3122,15 +3122,15 @@ export const Charts = [ id: "bigNumber", icon: ( ), From c1db42f63c2abc1e9d2ea862bef76699647cad54 Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Tue, 4 Jun 2024 05:09:48 +0100 Subject: [PATCH 06/12] feat: update routes --- src/app/Routes.tsx | 4 ++-- src/app/components/AppBar/index.tsx | 2 +- .../dataset-upload-module/component/tabs.tsx | 2 ++ .../component/uploadOption.tsx | 1 + .../upload-steps/externalSearch.tsx | 2 +- .../upload-steps/finishedFragment.tsx | 2 +- .../dataset-upload-module/upload-steps/index.tsx | 14 ++++++-------- .../home-module/components/All/assetsGrid.tsx | 3 --- .../components/Datasets/datasetsGrid.tsx | 3 --- .../home-module/components/Datasets/gridItem.tsx | 3 +-- .../home-module/components/Footer/index.tsx | 2 +- .../modules/home-module/components/Table/index.tsx | 7 +------ src/app/modules/home-module/index.tsx | 5 +++-- .../partners/components/empowerBlock.tsx | 2 +- src/app/modules/report-module/index.tsx | 2 +- .../modules/report-module/views/initial/index.tsx | 5 ++++- 16 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/app/Routes.tsx b/src/app/Routes.tsx index e649ade7d..8cde0fef2 100755 --- a/src/app/Routes.tsx +++ b/src/app/Routes.tsx @@ -242,9 +242,9 @@ export function MainRoutes() { - + {/* - + */} diff --git a/src/app/components/AppBar/index.tsx b/src/app/components/AppBar/index.tsx index cd5d482ec..0ece6c626 100644 --- a/src/app/components/AppBar/index.tsx +++ b/src/app/components/AppBar/index.tsx @@ -231,7 +231,7 @@ export function AppBar() { > {" "}
    - + Explore
    diff --git a/src/app/modules/dataset-upload-module/component/tabs.tsx b/src/app/modules/dataset-upload-module/component/tabs.tsx index d5267d986..18429ba5a 100644 --- a/src/app/modules/dataset-upload-module/component/tabs.tsx +++ b/src/app/modules/dataset-upload-module/component/tabs.tsx @@ -45,6 +45,7 @@ function UploadTabs({ activeTab, setActiveTab }: Props) { color: ${activeTab === "search" ? "white" : "#231D2C"}; `} onClick={() => setActiveTab("search")} + data-cy="federated-search-tab" > Federated search @@ -56,6 +57,7 @@ function UploadTabs({ activeTab, setActiveTab }: Props) { color: ${activeTab === "file" ? "white" : "#231D2C"}; `} onClick={() => setActiveTab("file")} + data-cy="file-upload-tab" > FILE upload diff --git a/src/app/modules/dataset-upload-module/component/uploadOption.tsx b/src/app/modules/dataset-upload-module/component/uploadOption.tsx index cdbd60c52..446b9e67f 100644 --- a/src/app/modules/dataset-upload-module/component/uploadOption.tsx +++ b/src/app/modules/dataset-upload-module/component/uploadOption.tsx @@ -33,6 +33,7 @@ const UploadOption = (props: { props.setActiveOption(props.name); props.onClick(e); }} + data-cy="upload-option-button" >
    diff --git a/src/app/modules/dataset-upload-module/upload-steps/finishedFragment.tsx b/src/app/modules/dataset-upload-module/upload-steps/finishedFragment.tsx index 312646d93..52bb85825 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/finishedFragment.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/finishedFragment.tsx @@ -81,7 +81,7 @@ export default function FinishedFragment(props: Props) { { setDisplay("data"); - return location.search.includes("?fromHome=true") ? "/" : "/explore"; + return "/"; })()} css={` display: flex; diff --git a/src/app/modules/dataset-upload-module/upload-steps/index.tsx b/src/app/modules/dataset-upload-module/upload-steps/index.tsx index 6c0919e58..b8e37b8d3 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/index.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/index.tsx @@ -290,14 +290,12 @@ function DatasetUploadSteps(props: Props) { {activeTab === "search" ? ( - <> - - + ) : ( void; md?: GridSize; lg?: GridSize; - fromHome?: boolean; } type assetType = "chart" | "dataset" | "report"; @@ -238,7 +237,6 @@ export default function AssetsGrid(props: Props) { <> {props.tableView ? ( { @@ -313,7 +311,6 @@ export default function AssetsGrid(props: Props) { id={d.id} owner={d.owner} inChartBuilder={props.inChartBuilder as boolean} - fromHome={props.fromHome} /> ), report: ( diff --git a/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx b/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx index b904bd863..192a21638 100644 --- a/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx +++ b/src/app/modules/home-module/components/Datasets/datasetsGrid.tsx @@ -28,7 +28,6 @@ interface Props { onItemClick?: (v: string) => void; md?: GridSize; lg?: GridSize; - fromHome?: boolean; } export default function DatasetsGrid(props: Readonly) { @@ -262,7 +261,6 @@ export default function DatasetsGrid(props: Readonly) { id={data.id} owner={data.owner} inChartBuilder={props.inChartBuilder as boolean} - fromHome={props.fromHome} /> {!props.inChartBuilder && } @@ -273,7 +271,6 @@ export default function DatasetsGrid(props: Readonly) { {props.tableView && ( ({ diff --git a/src/app/modules/home-module/components/Datasets/gridItem.tsx b/src/app/modules/home-module/components/Datasets/gridItem.tsx index fe426bdf5..0a247e8c0 100644 --- a/src/app/modules/home-module/components/Datasets/gridItem.tsx +++ b/src/app/modules/home-module/components/Datasets/gridItem.tsx @@ -27,7 +27,6 @@ interface Props { id?: string; owner: string; inChartBuilder: boolean; - fromHome?: boolean; } export default function GridItem(props: Readonly) { @@ -64,7 +63,7 @@ export default function GridItem(props: Readonly) { data-cy="dataset-grid-item" > Why DataXplorer?{" "}
  • - Explore{" "} + Explore{" "}
  • About diff --git a/src/app/modules/home-module/components/Table/index.tsx b/src/app/modules/home-module/components/Table/index.tsx index 063aaa884..49c815f42 100644 --- a/src/app/modules/home-module/components/Table/index.tsx +++ b/src/app/modules/home-module/components/Table/index.tsx @@ -1,13 +1,11 @@ import React from "react"; import moment from "moment"; -import { useRecoilState } from "recoil"; import Table from "@material-ui/core/Table"; import { useHistory } from "react-router-dom"; import TableRow from "@material-ui/core/TableRow"; import TableHead from "@material-ui/core/TableHead"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; -import { homeDisplayAtom } from "app/state/recoil/atoms"; import TableContainer from "@material-ui/core/TableContainer"; export function HomepageTable(props: { @@ -20,7 +18,6 @@ export function HomepageTable(props: { }[]; inChartBuilder?: boolean; onItemClick?: (v: string) => void; - fromHome?: boolean; }) { const history = useHistory(); @@ -85,9 +82,7 @@ export function HomepageTable(props: { if (!props.inChartBuilder) { history.push( `/${data.type}/${data.id}${ - data.type === "dataset" - ? `/detail?fromHome=${props.fromHome}` - : "" + data.type === "dataset" ? `/detail?` : "" }` ); } else if (props.inChartBuilder && props.onItemClick) { diff --git a/src/app/modules/home-module/index.tsx b/src/app/modules/home-module/index.tsx index 462a1657d..ef0bf87ab 100644 --- a/src/app/modules/home-module/index.tsx +++ b/src/app/modules/home-module/index.tsx @@ -98,7 +98,6 @@ export default function HomeModule() { searchStr={searchStr} tableView={tableView} categories={categories} - fromHome /> ); case "charts": @@ -125,7 +124,6 @@ export default function HomeModule() { searchStr={searchStr} tableView={tableView} showMenuButton={false} - fromHome /> ); default: @@ -191,6 +189,7 @@ export default function HomeModule() { css={` background: #e492bd; `} + data-cy="home-connect-dataset-button" > CONNECT DATASET @@ -199,6 +198,7 @@ export default function HomeModule() { css={` background: #64afaa; `} + data-cy="home-create-chart-button" > CREATE CHART @@ -207,6 +207,7 @@ export default function HomeModule() { css={` background: #6061e5; `} + data-cy="home-create-report-button" > CREATE REPORT diff --git a/src/app/modules/home-module/sub-modules/partners/components/empowerBlock.tsx b/src/app/modules/home-module/sub-modules/partners/components/empowerBlock.tsx index 55a34734d..5d3415bc3 100644 --- a/src/app/modules/home-module/sub-modules/partners/components/empowerBlock.tsx +++ b/src/app/modules/home-module/sub-modules/partners/components/empowerBlock.tsx @@ -88,7 +88,7 @@ export default function EmpowerBlock(props: { CREATE REPORT - + EXPLORE REPORTS diff --git a/src/app/modules/report-module/index.tsx b/src/app/modules/report-module/index.tsx index c1fbd190a..3df021854 100644 --- a/src/app/modules/report-module/index.tsx +++ b/src/app/modules/report-module/index.tsx @@ -20,7 +20,7 @@ import { } from "app/modules/report-module/data"; import ReportCreateView from "app/modules/report-module/views/create"; import { ReportPreviewView } from "app/modules/report-module/views/preview"; -import { ReportInitialView } from "app/modules/report-module/views/initial"; +import ReportInitialView from "app/modules/report-module/views/initial"; import { IFramesArray } from "app/modules/report-module/views/create/data"; import { ReportRightPanel } from "app/modules/report-module/components/right-panel"; import { ReportElementsType } from "app/modules/report-module/components/right-panel-create-view"; diff --git a/src/app/modules/report-module/views/initial/index.tsx b/src/app/modules/report-module/views/initial/index.tsx index 0ebc5f6f9..90daf460c 100644 --- a/src/app/modules/report-module/views/initial/index.tsx +++ b/src/app/modules/report-module/views/initial/index.tsx @@ -27,8 +27,9 @@ import { useHistory, useParams } from "react-router-dom"; import { useStoreActions, useStoreState } from "app/state/store/hooks"; import { useMount, useTitle, useUpdateEffect } from "react-use"; import { isEmpty } from "lodash"; +import { withAuthenticationRequired } from "@auth0/auth0-react"; -export function ReportInitialView(props: Readonly) { +function ReportInitialView(props: Readonly) { useTitle("DX DataXplorer - New Report"); const history = useHistory(); @@ -294,3 +295,5 @@ export function ReportInitialView(props: Readonly) { ); } + +export default withAuthenticationRequired(ReportInitialView); From b763257da6347ce8b55ad53ad10ac46828cea49b Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Tue, 4 Jun 2024 05:13:03 +0100 Subject: [PATCH 07/12] chore: update cypress tests --- cypress/e2e/1-dx/1-test-login.cy.ts | 2 +- cypress/e2e/1-dx/2-datasets.cy.ts | 8 +++++--- cypress/e2e/1-dx/3-charts.cy.ts | 7 ++----- cypress/e2e/1-dx/4-reports.cy.ts | 2 +- cypress/e2e/1-dx/5-home.cy.ts | 2 +- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/cypress/e2e/1-dx/1-test-login.cy.ts b/cypress/e2e/1-dx/1-test-login.cy.ts index 0684dc07e..d21fcf3ff 100644 --- a/cypress/e2e/1-dx/1-test-login.cy.ts +++ b/cypress/e2e/1-dx/1-test-login.cy.ts @@ -13,6 +13,6 @@ describe("Login for a test user on DX", () => { }); it("Is Logged in", function () { - cy.contains("CREATE REPORT").should("be.visible"); + cy.contains("Welcome").should("be.visible"); }); }); diff --git a/cypress/e2e/1-dx/2-datasets.cy.ts b/cypress/e2e/1-dx/2-datasets.cy.ts index a572ef7d3..9c5c5f27a 100644 --- a/cypress/e2e/1-dx/2-datasets.cy.ts +++ b/cypress/e2e/1-dx/2-datasets.cy.ts @@ -28,13 +28,11 @@ describe("Testing connecting data on DX", () => { cy.get('[data-cy="cookie-btn"]').click(); - cy.get('[data-cy="create-report-dropdown"]').click(); - cy.get('[data-cy="appbar-connect-data"]').click(); + cy.get('[data-cy="home-connect-dataset-button"]').click(); }); it("Can import data from External Search", () => { cy.intercept(`${apiUrl}/external-sources/search?q=*`).as("getDefaultData"); - cy.get('[data-cy="external-search-button"]').click(); cy.wait("@getDefaultData").then((interception) => { cy.get('[data-cy="external-search-card-Kaggle"]').should( @@ -129,6 +127,8 @@ describe("Testing connecting data on DX", () => { // }); it("Can import data through local upload", () => { + cy.get('[data-cy="file-upload-tab"]').click(); + cy.get('[data-cy="upload-option-button"').first().click(); cy.get('[data-cy="local-upload-input"]').as("fileInput"); cy.fixture("football-players.csv").then((fileContent) => { cy.get("@fileInput").attachFile({ @@ -154,6 +154,8 @@ describe("Testing connecting data on DX", () => { }); it("Can import another dataset through local upload", () => { + cy.get('[data-cy="file-upload-tab"]').click(); + cy.get('[data-cy="upload-option-button"').first().click(); cy.get('[data-cy="local-upload-input"]').as("fileInput"); cy.fixture("grossing-movies.csv").then((fileContent) => { cy.get("@fileInput").attachFile({ diff --git a/cypress/e2e/1-dx/3-charts.cy.ts b/cypress/e2e/1-dx/3-charts.cy.ts index 98f45e2bb..552d93f6d 100644 --- a/cypress/e2e/1-dx/3-charts.cy.ts +++ b/cypress/e2e/1-dx/3-charts.cy.ts @@ -25,9 +25,8 @@ describe("Testing create chart on DX", () => { cy.get('[data-cy="cookie-btn"]').click(); - cy.get('[data-cy="create-report-dropdown"]').click(); cy.intercept("GET", `${apiUrl}/datasets?filter=*`).as("getDatasets"); - cy.get('[data-cy="appbar-create-chart"]').click(); + cy.get('[data-cy="home-create-chart-button"]').click(); cy.wait("@getDatasets"); cy.intercept("GET", `${apiUrl}/chart/sample-data/*`).as("getDataset"); @@ -190,10 +189,8 @@ describe("Testing Ai chart creation", () => { cy.visit("/"); cy.get('[data-cy="cookie-btn"]').click(); - - cy.get('[data-cy="create-report-dropdown"]').click(); cy.intercept("GET", `${apiUrl}/datasets?filter=*`).as("getDatasets"); - cy.get('[data-cy="appbar-create-chart"]').click(); + cy.get('[data-cy="home-create-chart-button"]').click(); cy.wait("@getDatasets"); cy.intercept("GET", `${apiUrl}/chart/sample-data/*`).as("getDataset"); diff --git a/cypress/e2e/1-dx/4-reports.cy.ts b/cypress/e2e/1-dx/4-reports.cy.ts index 10f30c02a..c0418cfd6 100644 --- a/cypress/e2e/1-dx/4-reports.cy.ts +++ b/cypress/e2e/1-dx/4-reports.cy.ts @@ -27,7 +27,7 @@ describe("Testing reports on DX", () => { }); it("Can Create report", () => { - cy.get('[data-cy="appbar-create-report/login"]').click(); + cy.get('[data-cy="home-create-report-button"]').click(); cy.contains( '[data-cy="report-template-card"]', diff --git a/cypress/e2e/1-dx/5-home.cy.ts b/cypress/e2e/1-dx/5-home.cy.ts index 707d0550b..509e35b08 100644 --- a/cypress/e2e/1-dx/5-home.cy.ts +++ b/cypress/e2e/1-dx/5-home.cy.ts @@ -14,7 +14,7 @@ describe("Home page tests", () => { cy.location("pathname").should("include", "/about"); cy.get('[data-cy="empower-block-explore-reports-link"]').click(); cy.wait(2000); - cy.location("pathname").should("include", "/explore"); + cy.location("pathname").should("include", "/"); cy.get('[data-cy="nav-about"]').click(); cy.wait(2000); From 5afb6b2fd011ed572fb0a8af83be5c2ba25a7820 Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Tue, 4 Jun 2024 13:15:07 +0100 Subject: [PATCH 08/12] chore: update cypress test --- cypress/e2e/1-dx/4-reports.cy.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/cypress/e2e/1-dx/4-reports.cy.ts b/cypress/e2e/1-dx/4-reports.cy.ts index c0418cfd6..e9fec3630 100644 --- a/cypress/e2e/1-dx/4-reports.cy.ts +++ b/cypress/e2e/1-dx/4-reports.cy.ts @@ -153,8 +153,6 @@ describe("Testing reports on DX", () => { cy.visit("/"); - cy.wait("@fetchReports"); - cy.get('[data-cy="home-charts-tab"]').scrollIntoView().click(); cy.get('[data-cy="home-reports-tab"]').scrollIntoView().click(); From 04672c14e8a5499909b8a8786326209aa35ff1a6 Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Thu, 6 Jun 2024 20:21:59 +0100 Subject: [PATCH 09/12] feat: DX-1379 - Keep search input after an error + clicking Try Again --- .../upload-steps/externalSearch.tsx | 27 +++++++++++-------- .../upload-steps/index.tsx | 7 ++++- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx index 448893dc8..99436d443 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx @@ -33,10 +33,14 @@ export default function ExternalSearch(props: { handleDownload: (dataset: IExternalDataset) => void; setProcessingError: React.Dispatch>; setActiveStep: React.Dispatch>; + searchValue: string | undefined; + setSearchValue: React.Dispatch>; + sources: string[]; + setSources: React.Dispatch>; }) { const observerTarget = React.useRef(null); const [tableView, setTableView] = React.useState(false); - const [searchValue, setSearchValue] = React.useState(""); + const [sortValue, setSortValue] = React.useState("createdDate"); const token = useStoreState((state) => state.AuthToken.value); const history = useHistory(); @@ -45,7 +49,6 @@ export default function ExternalSearch(props: { const limit = 20; const [datasets, setDatasets] = React.useState([]); - const [sources, setSources] = React.useState([]); const baseSources = [ { name: "Kaggle", value: "Kaggle" }, { name: "World Bank", value: "World Bank" }, @@ -76,10 +79,12 @@ export default function ExternalSearch(props: { try { setLoading(true); const response = await axios.get( - `${ - process.env.REACT_APP_API - }/external-sources/search?q=${searchValue}&source=${ - sources.length ? sources.join(",") : "Kaggle,World Bank,WHO,HDX" + `${process.env.REACT_APP_API}/external-sources/search?q=${ + props.searchValue + }&source=${ + props.sources.length + ? props.sources.join(",") + : "Kaggle,World Bank,WHO,HDX" }&offset=${offset}&limit=${limit}`, { signal: abortControllerRef.current.signal, @@ -122,7 +127,7 @@ export default function ExternalSearch(props: { } }, 500, - [searchValue, token, sources] + [props.searchValue, token, props.sources] ); return ( <> @@ -160,14 +165,14 @@ export default function ExternalSearch(props: { (null); - const [isExternalSearch, setIsExternalSearch] = React.useState(false); + const [searchValue, setSearchValue] = React.useState(""); + const [sources, setSources] = React.useState([]); const [activeTab, setActiveTab] = React.useState<"search" | "file">("search"); const [activeOption, setActiveOption] = React.useState(null); @@ -295,6 +296,10 @@ function DatasetUploadSteps(props: Props) { setActiveStep={setActiveStep} setProcessingError={setProcessingError} handleDownload={handleDownloadExternalDataset} + searchValue={searchValue} + setSearchValue={setSearchValue} + sources={sources} + setSources={setSources} /> ) : ( Date: Fri, 7 Jun 2024 13:38:36 +0100 Subject: [PATCH 10/12] tests: update failing unit tests --- package.json | 2 +- .../__test__/add-dataset.test.tsx | 114 ++++++++++++------ .../component/uploadOption.tsx | 1 + yarn.lock | 18 +-- 4 files changed, 87 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index ac0ebaa5f..9d255b02d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@auth0/auth0-react": "^2.2.1", - "@azure/msal-browser": "^3.15.0", + "@azure/msal-browser": "^3.16.0", "@craco/craco": "^6.4.3", "@devhammed/use-cookie": "^1.1.1", "@draft-js-plugins/anchor": "^4.1.4", diff --git a/src/app/modules/dataset-upload-module/__test__/add-dataset.test.tsx b/src/app/modules/dataset-upload-module/__test__/add-dataset.test.tsx index 5bc8ce439..e0769b253 100644 --- a/src/app/modules/dataset-upload-module/__test__/add-dataset.test.tsx +++ b/src/app/modules/dataset-upload-module/__test__/add-dataset.test.tsx @@ -5,6 +5,27 @@ import { StoreProvider, createStore } from "easy-peasy"; import { AuthTokenState } from "app/state/api/action-reducers/sync"; import axios from "axios"; +interface MockProps { + onFileSubmit: jest.Mock; + disabled: boolean; + processingError: string | null; + activeOption: string | null; + setActiveOption: jest.Mock; + setActiveStep: jest.Mock; +} + +const defaultProps = (newProps: Partial = {}): MockProps => { + return { + onFileSubmit: jest.fn(), + disabled: false, + processingError: null, + activeOption: null, + setActiveOption: jest.fn().mockImplementation(() => "Local upload"), + setActiveStep: jest.fn(), + ...newProps, + }; +}; + const mockOpenPicker = jest.fn(); jest.mock("react-google-drive-picker", () => { return { @@ -14,36 +35,64 @@ jest.mock("react-google-drive-picker", () => { }, }; }); +jest.mock("app/hooks/useOneDrivePicker", () => { + return { + useOneDrivePicker: () => { + return { + launchPicker: jest.fn(), + clearToken: jest.fn(), + connected: true, + }; + }, + }; +}); jest.mock("axios"); -const appFn = (mockSetSelectedFile: jest.Mock) => { +const appFn = (newProps: Partial = {}) => { const mockStore = createStore({ AuthToken: AuthTokenState, }); + const props = defaultProps(newProps); - return ( - - - - ); + return { + app: ( + + + + ), + props, + }; }; -test("local upload of dataset", async () => { +test("open local upload option", async () => { const mockSetSelectedFile = jest.fn(); - const app = appFn(mockSetSelectedFile); + const { app, props } = appFn({ + onFileSubmit: mockSetSelectedFile, + }); + const user = userEvent.setup(); + render(app); + await user.click( + screen.getByTestId(/Local upload-option/i) as HTMLInputElement + ); + expect(props.setActiveOption).toHaveBeenCalledWith("Local upload"); +}); + +test("local file upload of dataset", async () => { + const mockSetSelectedFile = jest.fn(); + const { app, props } = appFn({ + onFileSubmit: mockSetSelectedFile, + activeOption: "Local upload", + }); + render(app); const file = new File(["(⌐□_□)"], "chucknorris.csv", { type: "text/csv" }); - const dndText = screen.getByText(/drag and drop/i); - expect(dndText).toBeInTheDocument(); + + expect( + screen.getByText(/Drag and Drop Spreadsheets File here/i) + ).toBeInTheDocument(); + const uploadInput = screen.getByTestId("local-upload") as HTMLInputElement; Object.defineProperty(uploadInput, "files", { value: [file] }); @@ -55,33 +104,22 @@ test("local upload of dataset", async () => { }); }); -test("external search of dataset", async () => { - const user = userEvent.setup(); - +test("select google drive button", async () => { const mockSetSelectedFile = jest.fn(); - - const app = appFn(mockSetSelectedFile); - - render(app); - - const searchButton = screen.getByText(/external search/i); - await user.click(searchButton); -}); - -test("google drive button", async () => { - const mockSetSelectedFile = jest.fn(); - const app = appFn(mockSetSelectedFile); + const user = userEvent.setup(); + const { app, props } = appFn({ + onFileSubmit: mockSetSelectedFile, + }); mockOpenPicker.mockImplementation(({ callbackFunction }) => { callbackFunction({ docs: [{ id: "123", name: "test.csv", type: "file" }] }); }); (axios.get as jest.Mock).mockResolvedValueOnce({ data: "access_token" }); render(app); - const googleDriveButton = screen.getByTestId("google-drive-button"); - - expect(googleDriveButton).toBeInTheDocument(); - await userEvent.click(googleDriveButton); - (axios.get as jest.Mock).mockResolvedValueOnce({ data: [] }); + await user.click( + screen.getByTestId(/Google Drive-option/i) as HTMLInputElement + ); + expect(props.setActiveOption).toHaveBeenCalledWith("Google Drive"); // Assert that openPicker is called with the correct parameters expect(mockOpenPicker).toHaveBeenCalledWith({ @@ -89,7 +127,7 @@ test("google drive button", async () => { developerKey: expect.any(String), viewId: "SPREADSHEETS", supportDrives: true, - token: "access_token", + token: null, setSelectFolderEnabled: true, callbackFunction: expect.any(Function), }); diff --git a/src/app/modules/dataset-upload-module/component/uploadOption.tsx b/src/app/modules/dataset-upload-module/component/uploadOption.tsx index 446b9e67f..ebef45a68 100644 --- a/src/app/modules/dataset-upload-module/component/uploadOption.tsx +++ b/src/app/modules/dataset-upload-module/component/uploadOption.tsx @@ -34,6 +34,7 @@ const UploadOption = (props: { props.onClick(e); }} data-cy="upload-option-button" + data-testid={`${props.name}-option`} >
    Date: Fri, 7 Jun 2024 15:20:25 +0100 Subject: [PATCH 11/12] feat:DX-1379; maintain search input state --- .../upload-steps/externalSearch.tsx | 4 ++++ .../dataset-upload-module/upload-steps/index.tsx | 3 +++ .../modules/home-module/components/Filter/index.tsx | 11 ++++++----- .../home-module/sub-modules/explore-assets/index.tsx | 3 +++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx index 99436d443..f6933cbf7 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/externalSearch.tsx @@ -35,6 +35,8 @@ export default function ExternalSearch(props: { setActiveStep: React.Dispatch>; searchValue: string | undefined; setSearchValue: React.Dispatch>; + openSearch: boolean; + setOpenSearch: React.Dispatch>; sources: string[]; setSources: React.Dispatch>; }) { @@ -179,6 +181,8 @@ export default function ExternalSearch(props: { tableView={tableView} terminateSearch={terminateSearch} searchInputWidth="249px" + openSearch={props.openSearch} + setOpenSearch={props.setOpenSearch} /> diff --git a/src/app/modules/dataset-upload-module/upload-steps/index.tsx b/src/app/modules/dataset-upload-module/upload-steps/index.tsx index 69f57fe7a..28335c4ad 100644 --- a/src/app/modules/dataset-upload-module/upload-steps/index.tsx +++ b/src/app/modules/dataset-upload-module/upload-steps/index.tsx @@ -54,6 +54,7 @@ function DatasetUploadSteps(props: Props) { const [processed, setProcessed] = React.useState(false); const [selectedFile, setSelectedFile] = React.useState(null); const [searchValue, setSearchValue] = React.useState(""); + const [openSearch, setOpenSearch] = React.useState(false); const [sources, setSources] = React.useState([]); const [activeTab, setActiveTab] = React.useState<"search" | "file">("search"); @@ -298,6 +299,8 @@ function DatasetUploadSteps(props: Props) { handleDownload={handleDownloadExternalDataset} searchValue={searchValue} setSearchValue={setSearchValue} + openSearch={openSearch} + setOpenSearch={setOpenSearch} sources={sources} setSources={setSources} /> diff --git a/src/app/modules/home-module/components/Filter/index.tsx b/src/app/modules/home-module/components/Filter/index.tsx index 270096dc5..f770fe0cd 100644 --- a/src/app/modules/home-module/components/Filter/index.tsx +++ b/src/app/modules/home-module/components/Filter/index.tsx @@ -21,6 +21,8 @@ export default function Filter( tableView: boolean; terminateSearch?: () => void; searchInputWidth?: string; + openSearch: boolean; + setOpenSearch: React.Dispatch>; }> ) { const inputRef = React.useRef(null); @@ -30,7 +32,6 @@ export default function Filter( setSortPopoverAnchorEl(null); }; const openSortPopover = Boolean(sortPopoverAnchorEl); - const [openSearch, setOpenSearch] = React.useState(false); const sortOptions = [ { label: "Last updated", value: "updatedDate" }, { label: "Created date", value: "createdDate" }, @@ -56,7 +57,7 @@ export default function Filter( gap: 8px; `} > -
    +
    { props.setSearchValue(""); props.terminateSearch && props.terminateSearch(); - setOpenSearch(false); + props.setOpenSearch(false); }} css={` &:hover { @@ -87,10 +88,10 @@ export default function Filter( { - setOpenSearch(true); + props.setOpenSearch(true); inputRef.current?.focus(); }} - css={iconButtonCss(openSearch)} + css={iconButtonCss(props.openSearch)} > diff --git a/src/app/modules/home-module/sub-modules/explore-assets/index.tsx b/src/app/modules/home-module/sub-modules/explore-assets/index.tsx index 4de2b23a6..37c170a14 100644 --- a/src/app/modules/home-module/sub-modules/explore-assets/index.tsx +++ b/src/app/modules/home-module/sub-modules/explore-assets/index.tsx @@ -75,6 +75,7 @@ export default function ExploreAssetsModule() { const [searchValue, setSearchValue] = React.useState( undefined ); + const [openSearch, setOpenSearch] = React.useState(false); const [sortValue, setSortValue] = React.useState("updatedDate"); const exploreViewRef = React.useRef(null); const [display, setDisplay] = useRecoilState(homeDisplayAtom); @@ -182,6 +183,8 @@ export default function ExploreAssetsModule() { setTableView={setTableView} sortValue={sortValue} tableView={tableView} + openSearch={openSearch} + setOpenSearch={setOpenSearch} /> From 0e276f6df6581a74b5ebee624b9effa258c9c4d6 Mon Sep 17 00:00:00 2001 From: Psami-wondah Date: Fri, 7 Jun 2024 16:35:04 +0100 Subject: [PATCH 12/12] feat: Add type to all assets table --- src/app/modules/home-module/components/All/assetsGrid.tsx | 1 + src/app/modules/home-module/components/Table/index.tsx | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/app/modules/home-module/components/All/assetsGrid.tsx b/src/app/modules/home-module/components/All/assetsGrid.tsx index 47d46448e..1d6b44157 100644 --- a/src/app/modules/home-module/components/All/assetsGrid.tsx +++ b/src/app/modules/home-module/components/All/assetsGrid.tsx @@ -239,6 +239,7 @@ export default function AssetsGrid(props: Props) { { if (data.assetType === "chart") { return { diff --git a/src/app/modules/home-module/components/Table/index.tsx b/src/app/modules/home-module/components/Table/index.tsx index 49c815f42..8bd42037f 100644 --- a/src/app/modules/home-module/components/Table/index.tsx +++ b/src/app/modules/home-module/components/Table/index.tsx @@ -7,6 +7,7 @@ import TableHead from "@material-ui/core/TableHead"; import TableBody from "@material-ui/core/TableBody"; import TableCell from "@material-ui/core/TableCell"; import TableContainer from "@material-ui/core/TableContainer"; +import _ from "lodash"; export function HomepageTable(props: { data: { @@ -18,6 +19,7 @@ export function HomepageTable(props: { }[]; inChartBuilder?: boolean; onItemClick?: (v: string) => void; + all?: boolean; }) { const history = useHistory(); @@ -65,8 +67,9 @@ export function HomepageTable(props: { > - Name - Description + Name + {props.all && Type} + Description Creation date @@ -98,6 +101,7 @@ export function HomepageTable(props: { > {index + 1} {data.name} + {props.all && {_.capitalize(data.type)}} {data.description} {moment(data.createdDate).format("MMMM YYYY")}