Skip to content

Commit

Permalink
feat(Datasets): Add tab to display datasetversionfile columns (#910)
Browse files Browse the repository at this point in the history
* feat(Datasets): Add tab to display datasetversionfile columns

* fix(Datasets): fix bad import name and percentage compute

* feat(Datasets): use count instead of totalValues

* chore: text color when hovering tab links was incorrect

* chore: Improve the styles

* Small adaptations

---------

Co-authored-by: Quentin Gérôme <[email protected]>
  • Loading branch information
cheikhgwane and qgerome authored Dec 4, 2024
1 parent 3b595d4 commit 9226340
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 13 deletions.
3 changes: 3 additions & 0 deletions public/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"Close": "Close",
"Code": "Code",
"Columns": "Columns",
"Columns metadata not available.": "Columns metadata not available.",
"Configuration": "Configuration",
"Configure & run": "Configure & run",
"Configure & Run": "Configure & Run",
Expand Down Expand Up @@ -131,6 +132,7 @@
"Details": "Details",
"Disable": "Disable",
"Disable Two-Factor Authentication": "Disable Two-Factor Authentication",
"Distinct": "Distinct",
"Documentation": "Documentation",
"Download": "Download",
"Download code": "Download code",
Expand Down Expand Up @@ -238,6 +240,7 @@
"Members": "Members",
"Messages": "Messages",
"Metadata": "Metadata",
"Missing": "Missing",
"Missing configuration: set default parameters to fix the problem.": "Missing configuration: set default parameters to fix the problem.",
"Multiple": "Multiple",
"Mute notifications": "Mute notifications",
Expand Down
5 changes: 4 additions & 1 deletion public/locales/fr/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"Close": "Fermer",
"Code": "Code",
"Columns": "Colonnes",
"Columns metadata not available.": "Les métadonnées des colonnes ne sont pas disponibles.",
"Configuration": "Configuration",
"Configure & run": "Configurer et exécuter",
"Configure & Run": "Configurer et exécuter",
Expand Down Expand Up @@ -133,6 +134,7 @@
"Details": "Détails",
"Disable": "Désactiver",
"Disable Two-Factor Authentication": "Désactiver l'authentification à deux facteurs",
"Distinct": "Distinct",
"Documentation": "Documentation",
"Download": "Télécharger",
"Download code": "Télécharger le code",
Expand Down Expand Up @@ -240,6 +242,7 @@
"Members": "Membres",
"Messages": "Messages",
"Metadata": "Métadonnées",
"Missing": "Manquant",
"Missing configuration: set default parameters to fix the problem.": "Configuration manquante : définissez les paramètres par défaut pour résoudre le problème.",
"Multiple": "Multiple",
"Mute notifications": "Désactiver les notifications",
Expand Down Expand Up @@ -501,4 +504,4 @@
"You're about to remove {{name}} from this workspace.": "Vous êtes sur le point de supprimer {{name}} de ce workspace.",
"Your account": "Votre compte",
"Your workspaces": "Vos workspaces"
}
}
10 changes: 9 additions & 1 deletion src/core/components/DescriptionList/DescriptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@ DescriptionList.Item = function Item({
help,
className,
fullWidth,
titleClassName,
contentClassName,
}: {
label: ReactNode;
children: ReactNode;
help?: ReactNode;
className?: string;
fullWidth?: boolean;
titleClassName?: string;
contentClassName?: string;
}) {
const { displayMode } = useDescriptionList();
return (
Expand All @@ -61,6 +65,7 @@ DescriptionList.Item = function Item({
"grid grid-cols-5 gap-2 sm:gap-4",
displayMode === DescriptionListDisplayMode.LABEL_ABOVE && "space-y-1",
fullWidth && "col-span-full",
className,
)}
>
<dt
Expand All @@ -70,6 +75,7 @@ DescriptionList.Item = function Item({
"col-span-1 items-center",
displayMode === DescriptionListDisplayMode.LABEL_ABOVE &&
"col-span-5",
titleClassName,
)}
>
<span className="inline">{label}</span>
Expand All @@ -85,7 +91,9 @@ DescriptionList.Item = function Item({
/>
)}
</dt>
<dd className={clsx("col-span-4 text-sm text-gray-900", className)}>
<dd
className={clsx("col-span-4 text-sm text-gray-900", contentClassName)}
>
{children}
</dd>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/core/components/Tabs/LinkTabs/LinkTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const LinkTabs = ({
selected,
className,
selectedStyle = "text-gray-900 font-medium",
style = "text-gray-500 hover:border-gray-400",
style = "text-gray-500 hover:border-gray-400 hover:text-gray-900",
}: LinkTabProps) => {
return (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as Types from '../../../graphql/types';
import { gql } from '@apollo/client';
import { DownloadVersionFile_FileFragmentDoc } from '../DownloadVersionFile/DownloadVersionFile.generated';
import { DatasetVersionFileSample_FileFragmentDoc } from '../DatasetVersionFileSample/DatasetVersionFileSample.generated';
import { DatasetVersionFileColumns_FileFragmentDoc } from '../DatasetVersionFileColumns/DatasetVersionFileColumns.generated';
export type DatasetExplorer_FileFragment = { __typename?: 'DatasetVersionFile', id: string, filename: string, createdAt: any, contentType: string, size: any, uri: string, downloadUrl?: string | null, createdBy?: { __typename?: 'User', displayName: string } | null };

export type DatasetExplorer_VersionFragment = { __typename?: 'DatasetVersion', id: string, files: { __typename?: 'DatasetVersionFilePage', items: Array<{ __typename?: 'DatasetVersionFile', id: string, filename: string, createdAt: any, contentType: string, size: any, uri: string, downloadUrl?: string | null, createdBy?: { __typename?: 'User', displayName: string } | null }> } };
Expand All @@ -17,12 +18,14 @@ export const DatasetExplorer_FileFragmentDoc = gql`
}
...DownloadVersionFile_file
...DatasetVersionFileSample_file
...DatasetVersionFileColumns_file
contentType
size
uri
}
${DownloadVersionFile_FileFragmentDoc}
${DatasetVersionFileSample_FileFragmentDoc}`;
${DatasetVersionFileSample_FileFragmentDoc}
${DatasetVersionFileColumns_FileFragmentDoc}`;
export const DatasetExplorer_VersionFragmentDoc = gql`
fragment DatasetExplorer_version on DatasetVersion {
id
Expand Down
10 changes: 9 additions & 1 deletion src/datasets/features/DatasetExplorer/DatasetExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
DatasetExplorer_VersionFragment,
} from "./DatasetExplorer.generated";
import ErrorBoundary from "core/components/ErrorBoundary";
import DatasetVersionFileColumns from "../DatasetVersionFileColumns";

type DatasetExplorerProps = {
version: DatasetExplorer_VersionFragment;
Expand Down Expand Up @@ -82,7 +83,6 @@ const DatasetExplorer = ({
</code>
</DescriptionList.Item>
</DescriptionList>

<Tabs>
<Tabs.Tab
label={t("Preview")}
Expand All @@ -92,6 +92,12 @@ const DatasetExplorer = ({
<DatasetVersionFileSample file={currentFile} />
</ErrorBoundary>
</Tabs.Tab>
<Tabs.Tab
label={t("Columns")}
className="space-y-2 mt-2 h-[560px] xtall:h-[700px] relative"
>
<DatasetVersionFileColumns file={currentFile} />
</Tabs.Tab>
</Tabs>
</div>
)}
Expand All @@ -111,12 +117,14 @@ DatasetExplorer.fragments = {
}
...DownloadVersionFile_file
...DatasetVersionFileSample_file
...DatasetVersionFileColumns_file
contentType
size
uri
}
${DownloadVersionFile.fragments.file}
${DatasetVersionFileSample.fragments.file}
${DatasetVersionFileColumns.fragments.file}
`,
version: gql`
fragment DatasetExplorer_version on DatasetVersion {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as Types from '../../../graphql/types';

import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type DatasetVersionFileColumnsMetadataQueryVariables = Types.Exact<{
id: Types.Scalars['ID']['input'];
}>;


export type DatasetVersionFileColumnsMetadataQuery = { __typename?: 'Query', datasetVersionFile?: { __typename?: 'DatasetVersionFile', id: string, attributes: Array<{ __typename?: 'MetadataAttribute', id: string, key: string, value?: any | null, system: boolean }> } | null };

export type DatasetVersionFileColumns_FileFragment = { __typename?: 'DatasetVersionFile', id: string };

export const DatasetVersionFileColumns_FileFragmentDoc = gql`
fragment DatasetVersionFileColumns_file on DatasetVersionFile {
id
}
`;
export const DatasetVersionFileColumnsMetadataDocument = gql`
query DatasetVersionFileColumnsMetadata($id: ID!) {
datasetVersionFile(id: $id) {
id
attributes {
id
key
value
system
}
}
}
`;

/**
* __useDatasetVersionFileColumnsMetadataQuery__
*
* To run a query within a React component, call `useDatasetVersionFileColumnsMetadataQuery` and pass it any options that fit your needs.
* When your component renders, `useDatasetVersionFileColumnsMetadataQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useDatasetVersionFileColumnsMetadataQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useDatasetVersionFileColumnsMetadataQuery(baseOptions: Apollo.QueryHookOptions<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables> & ({ variables: DatasetVersionFileColumnsMetadataQueryVariables; skip?: boolean; } | { skip: boolean; }) ) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables>(DatasetVersionFileColumnsMetadataDocument, options);
}
export function useDatasetVersionFileColumnsMetadataLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables>(DatasetVersionFileColumnsMetadataDocument, options);
}
export function useDatasetVersionFileColumnsMetadataSuspenseQuery(baseOptions?: Apollo.SkipToken | Apollo.SuspenseQueryHookOptions<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables>) {
const options = baseOptions === Apollo.skipToken ? baseOptions : {...defaultOptions, ...baseOptions}
return Apollo.useSuspenseQuery<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables>(DatasetVersionFileColumnsMetadataDocument, options);
}
export type DatasetVersionFileColumnsMetadataQueryHookResult = ReturnType<typeof useDatasetVersionFileColumnsMetadataQuery>;
export type DatasetVersionFileColumnsMetadataLazyQueryHookResult = ReturnType<typeof useDatasetVersionFileColumnsMetadataLazyQuery>;
export type DatasetVersionFileColumnsMetadataSuspenseQueryHookResult = ReturnType<typeof useDatasetVersionFileColumnsMetadataSuspenseQuery>;
export type DatasetVersionFileColumnsMetadataQueryResult = Apollo.QueryResult<DatasetVersionFileColumnsMetadataQuery, DatasetVersionFileColumnsMetadataQueryVariables>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { gql, useQuery } from "@apollo/client";
import { useMemo } from "react";
import Spinner from "core/components/Spinner";
import { MetadataAttribute } from "graphql/types";
import { camelCase } from "lodash";
import Card from "core/components/Card";
import DescriptionList from "core/components/DescriptionList";
import { useTranslation } from "react-i18next";
import Badge from "core/components/Badge";
import { percentage } from "datasets/helpers/dataset";

export type DatasetColumn = {
id: string;
columnName: string;
constantValues?: boolean;
dataType: string;
distinctValues: number;
key: string;
missingValues: number;
system: boolean;
uniqueValues?: number;
count: number;
};

type DatasetVersionFileColumnsProps = {
file: any;
};

const DatasetVersionFileColumns = (props: DatasetVersionFileColumnsProps) => {
const { t } = useTranslation();
const { file } = props;
const { data, loading } = useQuery(
gql`
query DatasetVersionFileColumnsMetadata($id: ID!) {
datasetVersionFile(id: $id) {
id
attributes {
id
key
value
system
}
}
}
`,
{
variables: {
id: file.id,
},
},
);

const { columns, total } = useMemo(() => {
if (!data?.datasetVersionFile.attributes) {
return { columns: [], total: 0 };
}

const { attributes } = data.datasetVersionFile;
const res: Array<DatasetColumn> = Object.values(
attributes.reduce((acc: any, item: MetadataAttribute) => {
const [columnKey, property] = item.key.split(".");
if (!acc[columnKey]) {
acc[columnKey] = {
id: item.id,
key: columnKey,
system: item.system,
};
}
acc[columnKey][camelCase(property)] = item.value;
return acc;
}, {}),
);

return {
columns: res,
total: res.length ? res[0].count + res[0].missingValues : 0,
};
}, [data]);

if (loading)
return (
<div className="flex justify-center items-center h-24 p-4">
<Spinner size="md" />
</div>
);

if (!columns.length) {
return (
<div className="text-sm text-gray-500 italic w-full flex justify-center p-4">
{t("Columns metadata not available.")}
</div>
);
}

return (
<div className="grid grid-cols-1 2xl:grid-cols-2 gap-4">
{columns.map((column: DatasetColumn) => (
<Card
key={column.key}
title={
<div className="flex justify-between">
<span className="max-w-[80%] font-semibold text-sm font-mono">
{column.columnName}
</span>
<div>
<Badge className="text-xs bg-gray-100 font-mono">
{column.dataType}
</Badge>
</div>
</div>
}
>
<Card.Content>
<DescriptionList compact>
<DescriptionList.Item label={t("Distinct")}>
<code className="font-mono text-sm text-gray-600">
{`${column.distinctValues} (${percentage(column.distinctValues, total)}%)`}
</code>
</DescriptionList.Item>
<DescriptionList.Item label={t("Missing")} className="gap-4">
<code className="font-mono text-sm text-gray-600 ">
{`${column.missingValues} (${percentage(column.missingValues, total)}%)`}
</code>
</DescriptionList.Item>
</DescriptionList>
</Card.Content>
</Card>
))}
</div>
);
};

DatasetVersionFileColumns.fragments = {
file: gql`
fragment DatasetVersionFileColumns_file on DatasetVersionFile {
id
}
`,
};

export default DatasetVersionFileColumns;
3 changes: 3 additions & 0 deletions src/datasets/features/DatasetVersionFileColumns/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import DatasetVersionFileColumns from "./DatasetVersionFileColumns";

export default DatasetVersionFileColumns;
Loading

0 comments on commit 9226340

Please sign in to comment.