mirror of https://github.com/buster-so/buster.git
updated header to match new format
This commit is contained in:
parent
7378a7b115
commit
166afbea2b
|
@ -0,0 +1,36 @@
|
|||
import { createBusterRoute, BusterRoutes } from '@/routes';
|
||||
import { BreadcrumbSeperator } from '@/styles/context/useBreadcrumbStyles';
|
||||
import { Breadcrumb } from 'antd';
|
||||
import Link from 'next/link';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
export const DatasetBreadcrumb: React.FC<{
|
||||
datasetName?: string;
|
||||
}> = React.memo(({ datasetName }) => {
|
||||
const breadcrumbItems = useMemo(
|
||||
() =>
|
||||
[
|
||||
{
|
||||
title: (
|
||||
<Link prefetch href={createBusterRoute({ route: BusterRoutes.APP_DATASETS })}>
|
||||
Datasets
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: datasetName
|
||||
}
|
||||
].filter((item) => item.title),
|
||||
[datasetName]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Breadcrumb
|
||||
className="flex items-center"
|
||||
items={breadcrumbItems}
|
||||
separator={<BreadcrumbSeperator />}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
'use client';
|
||||
|
||||
import { AppSegmented } from '@/components';
|
||||
import { SegmentedProps } from 'antd';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React, { useMemo } from 'react';
|
||||
import { DatasetApps, DataSetAppText } from '../_config';
|
||||
import { createBusterRoute, BusterRoutes } from '@/routes';
|
||||
|
||||
export const DatasetsHeaderOptions: React.FC<{
|
||||
selectedApp: DatasetApps;
|
||||
isAdmin: boolean;
|
||||
datasetId: string;
|
||||
}> = React.memo(({ datasetId, isAdmin, selectedApp }) => {
|
||||
const { push } = useRouter();
|
||||
const optionsItems = isAdmin
|
||||
? [DatasetApps.OVERVIEW, DatasetApps.PERMISSIONS, DatasetApps.EDITOR]
|
||||
: [DatasetApps.OVERVIEW, DatasetApps.PERMISSIONS];
|
||||
|
||||
const options: SegmentedProps['options'] = useMemo(
|
||||
() =>
|
||||
optionsItems.map((key) => ({
|
||||
label: (
|
||||
<Link prefetch href={keyToRoute(datasetId, key)}>
|
||||
{DataSetAppText[key as DatasetApps]}
|
||||
</Link>
|
||||
),
|
||||
value: key
|
||||
})),
|
||||
[datasetId, optionsItems]
|
||||
);
|
||||
|
||||
return (
|
||||
<AppSegmented
|
||||
options={options}
|
||||
value={selectedApp}
|
||||
onChange={(value) => {
|
||||
push(keyToRoute(datasetId, value as DatasetApps));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
DatasetsHeaderOptions.displayName = 'DatasetsHeaderOptions';
|
||||
|
||||
const keyToRoute = (datasetId: string, key: DatasetApps) => {
|
||||
const record: Record<DatasetApps, string> = {
|
||||
[DatasetApps.PERMISSIONS]: createBusterRoute({
|
||||
route: BusterRoutes.APP_DATASETS_ID_DESCRIPTIONS,
|
||||
datasetId
|
||||
}),
|
||||
[DatasetApps.OVERVIEW]: createBusterRoute({
|
||||
route: BusterRoutes.APP_DATASETS_ID_OVERVIEW,
|
||||
datasetId
|
||||
}),
|
||||
[DatasetApps.EDITOR]: createBusterRoute({
|
||||
route: BusterRoutes.APP_DATASETS_ID_SQL,
|
||||
datasetId
|
||||
})
|
||||
};
|
||||
|
||||
return record[key];
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import { AppMaterialIcons } from '@/components';
|
||||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
export const DatasetIndividualThreeDotMenu: React.FC = React.memo(() => {
|
||||
return <Button type="text" icon={<AppMaterialIcons icon="more_horiz" />} />;
|
||||
});
|
||||
DatasetIndividualThreeDotMenu.displayName = 'DatasetIndividualThreeDotMenu';
|
|
@ -7,15 +7,18 @@ import { BusterRoutes, createBusterRoute } from '@/routes';
|
|||
import { AppSegmented, AppTooltip, PreventNavigation } from '@/components';
|
||||
import { useDatasetContextSelector } from '@/context/Datasets';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { AppContentHeader } from '../../_components/AppContentHeader';
|
||||
import { AppContentHeader } from '../../../_components/AppContentHeader';
|
||||
import { BreadcrumbSeperator } from '@/styles/context/useBreadcrumbStyles';
|
||||
import { SegmentedProps } from 'antd/lib';
|
||||
import { DataSetAppIcons, DatasetApps, DataSetAppText } from './_config';
|
||||
import { DataSetAppIcons, DatasetApps, DataSetAppText } from '../_config';
|
||||
import { BusterDataset } from '@/api/busterv2/datasets';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { PublishDatasetModal } from './_PublishModal';
|
||||
import { PublishDatasetModal } from '../_PublishModal';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useUserConfigContextSelector } from '@/context/Users';
|
||||
import { DatasetsHeaderOptions } from './DatasetHeaderOptions';
|
||||
import { DatasetBreadcrumb } from './DatasetBreadcrumb';
|
||||
import { DatasetIndividualThreeDotMenu } from './DatasetIndividualThreeDotMenu';
|
||||
|
||||
export const DatasetsIndividualHeader: React.FC<{
|
||||
selectedApp: DatasetApps;
|
||||
|
@ -28,28 +31,15 @@ export const DatasetsIndividualHeader: React.FC<{
|
|||
const showSkeletonLoader = !selectedDataset?.id;
|
||||
const [openPublishModal, setOpenPublishModal] = React.useState(false);
|
||||
|
||||
const isSQLApp = selectedApp === DatasetApps.SQL;
|
||||
const isSQLApp = selectedApp === DatasetApps.EDITOR;
|
||||
|
||||
const disablePublish = useMemo(() => {
|
||||
const originalSQL = selectedDataset?.definition || '';
|
||||
return originalSQL === sql;
|
||||
return !selectedDataset?.id || !sql || originalSQL === sql;
|
||||
}, [selectedDataset?.definition, sql]);
|
||||
|
||||
const preventNavigation = !disablePublish;
|
||||
|
||||
const breadcrumbItems = [
|
||||
{
|
||||
title: (
|
||||
<Link prefetch href={createBusterRoute({ route: BusterRoutes.APP_DATASETS })}>
|
||||
Datasets
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: selectedDataset?.name
|
||||
}
|
||||
].filter((item) => item.title);
|
||||
|
||||
const onReset = useMemoizedFn(() => {
|
||||
setSQL(selectedDataset?.definition || '');
|
||||
});
|
||||
|
@ -68,6 +58,10 @@ export const DatasetsIndividualHeader: React.FC<{
|
|||
}, 300);
|
||||
});
|
||||
|
||||
const onOpenPublishModal = useMemoizedFn(() => {
|
||||
setOpenPublishModal(true);
|
||||
});
|
||||
|
||||
useHotkeys('d', () => {
|
||||
setOpenNewDatasetModal(true);
|
||||
});
|
||||
|
@ -76,49 +70,33 @@ export const DatasetsIndividualHeader: React.FC<{
|
|||
if (isSQLApp) setOpenPublishModal(true);
|
||||
});
|
||||
|
||||
if (showSkeletonLoader) return <SkeletonLoader />;
|
||||
if (showSkeletonLoader) return <></>;
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppContentHeader className="items-center justify-between space-x-2">
|
||||
<div className="flex space-x-1">
|
||||
<Breadcrumb
|
||||
className="flex items-center"
|
||||
items={breadcrumbItems}
|
||||
separator={<BreadcrumbSeperator />}
|
||||
/>
|
||||
{/* <DatasetFilters
|
||||
activeFilters={dashboardListFilters}
|
||||
onChangeFilter={onSetDatasetListFilters}
|
||||
/> */}
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<DatasetBreadcrumb datasetName={selectedDataset?.name} />
|
||||
|
||||
<div className="flex items-center">
|
||||
<DatasetsHeaderOptions
|
||||
isAdmin={isAdmin}
|
||||
selectedApp={selectedApp}
|
||||
datasetId={selectedDataset?.id || ''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex items-center"
|
||||
style={{
|
||||
display: isSQLApp ? 'flex' : 'none'
|
||||
}}>
|
||||
<Divider type="vertical" className="!h-5" />
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center">
|
||||
<DatasetIndividualThreeDotMenu />
|
||||
|
||||
<Divider type="vertical" className="!h-4" />
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button type="text" onClick={onReset} disabled={sql === selectedDataset?.definition}>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
<AppTooltip title={'Open publish dataset'} shortcuts={['p']}>
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={disablePublish}
|
||||
onClick={() => {
|
||||
setOpenPublishModal(true);
|
||||
}}>
|
||||
<Button type="primary" disabled={disablePublish} onClick={onOpenPublishModal}>
|
||||
Publish
|
||||
</Button>
|
||||
</AppTooltip>
|
||||
|
@ -147,75 +125,3 @@ export const DatasetsIndividualHeader: React.FC<{
|
|||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const keyToRoute = (datasetId: string, key: DatasetApps) => {
|
||||
const record: Record<DatasetApps, string> = {
|
||||
[DatasetApps.DESCRIPTIONS]: createBusterRoute({
|
||||
route: BusterRoutes.APP_DATASETS_ID_DESCRIPTIONS,
|
||||
datasetId
|
||||
}),
|
||||
[DatasetApps.OVERVIEW]: createBusterRoute({
|
||||
route: BusterRoutes.APP_DATASETS_ID_OVERVIEW,
|
||||
datasetId
|
||||
}),
|
||||
[DatasetApps.SQL]: createBusterRoute({
|
||||
route: BusterRoutes.APP_DATASETS_ID_SQL,
|
||||
datasetId
|
||||
})
|
||||
};
|
||||
|
||||
return record[key];
|
||||
};
|
||||
|
||||
const DatasetsHeaderOptions: React.FC<{
|
||||
selectedApp: DatasetApps;
|
||||
isAdmin: boolean;
|
||||
datasetId: string;
|
||||
}> = ({ datasetId, isAdmin, selectedApp }) => {
|
||||
const { push } = useRouter();
|
||||
const optionsItems = isAdmin
|
||||
? [DatasetApps.OVERVIEW, DatasetApps.DESCRIPTIONS, DatasetApps.SQL]
|
||||
: [DatasetApps.OVERVIEW, DatasetApps.DESCRIPTIONS];
|
||||
const options: SegmentedProps['options'] = optionsItems.map((key) => ({
|
||||
label: (
|
||||
<Link prefetch href={keyToRoute(datasetId, key)}>
|
||||
{DataSetAppText[key as DatasetApps]}
|
||||
</Link>
|
||||
),
|
||||
value: key,
|
||||
icon: DataSetAppIcons[key as DatasetApps]
|
||||
}));
|
||||
return (
|
||||
<AppSegmented
|
||||
options={options}
|
||||
value={selectedApp}
|
||||
onChange={(value) => {
|
||||
push(keyToRoute(datasetId, value as DatasetApps));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const SkeletonLoader: React.FC<{}> = () => {
|
||||
const size = 'small';
|
||||
const buttonShape = 'round';
|
||||
|
||||
return (
|
||||
<AppContentHeader className="items-center justify-between space-x-2">
|
||||
<div className="flex h-full w-3/4 items-center justify-center space-x-2">
|
||||
<Skeleton.Button
|
||||
className="!flex h-full min-w-12 !items-center"
|
||||
size={size}
|
||||
shape={buttonShape}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
|
||||
<Skeleton.Input
|
||||
block
|
||||
className="!flex h-full w-24 !items-center overflow-hidden rounded"
|
||||
size={size}
|
||||
/>
|
||||
</div>
|
||||
</AppContentHeader>
|
||||
);
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export * from './DatasetsIndividualHeader';
|
|
@ -2,19 +2,19 @@ import { AppMaterialIcons } from '@/components';
|
|||
import React from 'react';
|
||||
|
||||
export enum DatasetApps {
|
||||
SQL = 'sql',
|
||||
DESCRIPTIONS = 'descriptions',
|
||||
OVERVIEW = 'overview'
|
||||
OVERVIEW = 'overview',
|
||||
PERMISSIONS = 'PERMISSIONS',
|
||||
EDITOR = 'editor'
|
||||
}
|
||||
|
||||
export const DataSetAppText: Record<DatasetApps, string> = {
|
||||
[DatasetApps.OVERVIEW]: 'Overview',
|
||||
[DatasetApps.DESCRIPTIONS]: 'Metadata',
|
||||
[DatasetApps.SQL]: 'SQL Editor'
|
||||
[DatasetApps.PERMISSIONS]: 'Permissions',
|
||||
[DatasetApps.EDITOR]: 'Editor'
|
||||
};
|
||||
|
||||
export const DataSetAppIcons: Record<DatasetApps, React.ReactNode> = {
|
||||
[DatasetApps.OVERVIEW]: <AppMaterialIcons icon="info" />,
|
||||
[DatasetApps.DESCRIPTIONS]: <AppMaterialIcons icon="menu_book" />,
|
||||
[DatasetApps.SQL]: <AppMaterialIcons icon="data_object" />
|
||||
[DatasetApps.PERMISSIONS]: <AppMaterialIcons icon="menu_book" />,
|
||||
[DatasetApps.EDITOR]: <AppMaterialIcons icon="data_object" />
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { DatasetIndividualContent } from '../_DatasetContent';
|
||||
import { useDatasetPageContextSelector } from '../_DatasetPageContext';
|
||||
|
||||
|
|
Loading…
Reference in New Issue