UI: Added custom property pages into global settings (#6381)

* Added custom property i global settings

* prettier formatting

* addressing comment

* addressing comment

* added prettier
This commit is contained in:
Shailesh Parmar 2022-07-27 20:35:20 +05:30 committed by GitHub
parent 384d64221f
commit e35cfe489c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 182 additions and 2 deletions

View File

@ -14,7 +14,7 @@
export const GLOBAL_SETTINGS_MENU = [
{
category: 'Access',
items: ['Teams', 'Users', 'Roles', 'Policies'],
items: ['Teams', 'Users', 'Roles'],
},
{
category: 'Services',
@ -22,7 +22,7 @@ export const GLOBAL_SETTINGS_MENU = [
},
{
category: 'Custom Attributes',
items: ['Tables'],
items: ['Tables', 'Topics', 'Dashboards', 'Pipelines', 'ML Models'],
},
{
category: 'Integrations',
@ -30,6 +30,14 @@ export const GLOBAL_SETTINGS_MENU = [
},
];
export const customAttributesPath = {
tables: 'table',
topics: 'topic',
dashboards: 'dashboard',
pipelines: 'pipeline',
mlModels: 'mlmodel',
};
export enum GlobalSettingsMenuCategory {
ACCESS = 'access',
SERVICES = 'services',

View File

@ -0,0 +1,159 @@
/*
* Copyright 2022 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AxiosError } from 'axios';
import { compare } from 'fast-json-patch';
import { isUndefined } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { getTypeByFQN, updateType } from '../../axiosAPIs/metadataTypeAPI';
import { Button } from '../../components/buttons/Button/Button';
import ErrorPlaceHolder from '../../components/common/error-with-placeholder/ErrorPlaceHolder';
import TabsPane from '../../components/common/TabsPane/TabsPane';
import { CustomPropertyTable } from '../../components/CustomEntityDetail/CustomPropertyTable';
import Loader from '../../components/Loader/Loader';
import SchemaEditor from '../../components/schema-editor/SchemaEditor';
import { getAddCustomPropertyPath } from '../../constants/constants';
import { customAttributesPath } from '../../constants/globalSettings.constants';
import { Type } from '../../generated/entity/type';
import jsonData from '../../jsons/en';
import { showErrorToast } from '../../utils/ToastUtils';
const CustomEntityDetailV1 = () => {
const { tab } = useParams<{ [key: string]: string }>();
const history = useHistory();
const [activeTab, setActiveTab] = useState<number>(1);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);
const [selectedEntityTypeDetail, setSelectedEntityTypeDetail] =
useState<Type>({} as Type);
const fetchTypeDetail = async (typeFQN: string) => {
setIsLoading(true);
try {
const { data } = await getTypeByFQN(typeFQN);
setSelectedEntityTypeDetail(data);
} catch (error) {
showErrorToast(error as AxiosError);
setIsError(true);
}
setIsLoading(false);
};
const onTabChange = (tab: number) => {
setActiveTab(tab);
};
const handleAddProperty = () => {
const path = getAddCustomPropertyPath(tab);
history.push(path);
};
const tabs = useMemo(() => {
const { customProperties } = selectedEntityTypeDetail;
return [
{
name: 'Custom Properties',
isProtected: false,
position: 1,
count: (customProperties || []).length,
},
{
name: 'Schema',
isProtected: false,
position: 2,
},
];
}, [selectedEntityTypeDetail]);
const updateEntityType = async (properties: Type['customProperties']) => {
const patch = compare(selectedEntityTypeDetail, {
...selectedEntityTypeDetail,
customProperties: properties,
});
try {
const { data } = await updateType(
selectedEntityTypeDetail.id || '',
patch
);
setSelectedEntityTypeDetail((prev) => ({
...prev,
customProperties: data.customProperties,
}));
} catch (error) {
showErrorToast(error as AxiosError);
}
};
useEffect(() => {
if (!isUndefined(tab)) {
setActiveTab(1);
setIsError(false);
fetchTypeDetail(
customAttributesPath[tab as keyof typeof customAttributesPath]
);
}
}, [tab]);
if (isLoading) {
return <Loader />;
}
if (isError) {
return (
<ErrorPlaceHolder>
{jsonData['message']['no-custom-entity']}
</ErrorPlaceHolder>
);
}
return (
<div data-testid="custom-entity-container">
<TabsPane activeTab={activeTab} setActiveTab={onTabChange} tabs={tabs} />
<div className="tw-mt-4">
{activeTab === 2 && (
<div data-testid="entity-schema">
<SchemaEditor
className="tw-border tw-border-main tw-rounded-md tw-py-4"
editorClass="custom-entity-schema"
value={JSON.parse(selectedEntityTypeDetail.schema ?? '{}')}
/>
</div>
)}
{activeTab === 1 && (
<div data-testid="entity-custom-fields">
<div className="tw-flex tw-justify-end">
<Button
className="tw-mb-4 tw-py-1 tw-px-2 tw-rounded"
data-testid="add-field-button"
size="custom"
theme="primary"
onClick={() => handleAddProperty()}>
Add Property
</Button>
</div>
<CustomPropertyTable
customProperties={selectedEntityTypeDetail.customProperties || []}
updateEntityType={updateEntityType}
/>
</div>
)}
</div>
</div>
);
};
export default CustomEntityDetailV1;

View File

@ -29,6 +29,11 @@ const ServicesPage = withSuspenseFallback(
const BotsListPage = withSuspenseFallback(
React.lazy(() => import('../pages/BotsListpage/BotsListpage.component'))
);
const CustomPropertiesPageV1 = withSuspenseFallback(
React.lazy(
() => import('../pages/CustomPropertiesPage/CustomPropertiesPageV1')
)
);
const GlobalSettingRouter = () => {
return (
@ -63,6 +68,14 @@ const GlobalSettingRouter = () => {
component={ServicesPage}
path={getSettingCategoryPath(GlobalSettingsMenuCategory.SERVICES)}
/>
<Route
exact
component={CustomPropertiesPageV1}
path={getSettingCategoryPath(
GlobalSettingsMenuCategory.CUSTOM_ATTRIBUTES
)}
/>
</Switch>
);
};