mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-22 07:58:06 +00:00
UI: Fix miscellaneous UI issues (#4451)
This commit is contained in:
parent
e880224da8
commit
e82cd76e1c
@ -227,7 +227,8 @@ public class ChangeEventHandler implements EventHandler {
|
||||
// In this case, the entity itself got deleted
|
||||
// for which there will be no change description.
|
||||
String message =
|
||||
String.format("Deleted %s **%s**", entityInterface.getEntityType(), entityInterface.getFullyQualifiedName());
|
||||
String.format(
|
||||
"Deleted **%s**: `%s`", entityInterface.getEntityType(), entityInterface.getFullyQualifiedName());
|
||||
EntityLink about =
|
||||
new EntityLink(entityInterface.getEntityType(), entityInterface.getFullyQualifiedName(), null, null, null);
|
||||
Thread thread =
|
||||
|
@ -214,7 +214,7 @@ public final class ChangeEventParser {
|
||||
case ADD:
|
||||
String fieldValue = getFieldValue(newFieldValue);
|
||||
if (Entity.FIELD_FOLLOWERS.equals(updatedField)) {
|
||||
message = String.format("Started to follow %s `%s`", link.getEntityType(), link.getEntityFQN());
|
||||
message = String.format("Started to follow **%s** `%s`", link.getEntityType(), link.getEntityFQN());
|
||||
} else if (fieldValue != null && !fieldValue.isEmpty()) {
|
||||
message = String.format("Added **%s**: `%s`", updatedField, fieldValue);
|
||||
}
|
||||
@ -238,7 +238,7 @@ public final class ChangeEventParser {
|
||||
private static String getPlainTextUpdateMessage(String updatedField, String oldValue, String newValue) {
|
||||
// Get diff of old value and new value
|
||||
String diff = getPlaintextDiff(oldValue, newValue);
|
||||
return nullOrEmpty(diff) ? StringUtils.EMPTY : String.format("Updated **%s** : %s", updatedField, diff);
|
||||
return nullOrEmpty(diff) ? StringUtils.EMPTY : String.format("Updated **%s**: %s", updatedField, diff);
|
||||
}
|
||||
|
||||
private static String getObjectUpdateMessage(String updatedField, JsonObject oldJson, JsonObject newJson) {
|
||||
@ -256,7 +256,7 @@ public final class ChangeEventParser {
|
||||
if (newJson.containsKey("name")) {
|
||||
updatedField = String.format("%s.%s", updatedField, newJson.getString("name"));
|
||||
}
|
||||
return String.format("Updated **%s** : <br/> %s", updatedField, updates);
|
||||
return String.format("Updated **%s**: <br/> %s", updatedField, updates);
|
||||
}
|
||||
|
||||
private static String getUpdateMessage(String updatedField, Object oldValue, Object newValue) {
|
||||
|
@ -550,7 +550,7 @@ public class FeedResourceTest extends CatalogApplicationTest {
|
||||
assertEquals(initialThreadCount + 3, threads.getPaging().getTotal());
|
||||
assertEquals(initialThreadCount + 3, threads.getData().size());
|
||||
assertEquals(
|
||||
String.format("Started to follow table `%s`", TABLE2.getFullyQualifiedName()),
|
||||
String.format("Started to follow **table** `%s`", TABLE2.getFullyQualifiedName()),
|
||||
threads.getData().get(0).getMessage());
|
||||
assertEquals("Message 2", threads.getData().get(1).getMessage());
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class ChangeEventParserTest extends CatalogApplicationTest {
|
||||
assertEquals(1, messages.size());
|
||||
|
||||
assertEquals(
|
||||
"Updated **description** : <span class=\"diff-removed\">old</span>"
|
||||
"Updated **description**: <span class=\"diff-removed\">old</span>"
|
||||
+ "<span class=\"diff-added\">new</span> description",
|
||||
messages.values().iterator().next());
|
||||
|
||||
@ -161,7 +161,7 @@ public class ChangeEventParserTest extends CatalogApplicationTest {
|
||||
assertEquals(1, messages.size());
|
||||
|
||||
assertEquals(
|
||||
"Updated **columns.lo_orderpriority** : <br/> name: <span class=\"diff-removed\">\"lo_order\"</span><span class=\"diff-added\">\"lo_orderpriority\"</span> <br/> displayName: <span class=\"diff-removed\">\"lo_order\"</span><span class=\"diff-added\">\"lo_orderpriority\"</span> <br/> fullyQualifiedName: \"local_mysql.sample_db.lineorder.<span class=\"diff-removed\">lo_order\"</span><span class=\"diff-added\">lo_orderpriority\"</span>",
|
||||
"Updated **columns.lo_orderpriority**: <br/> name: <span class=\"diff-removed\">\"lo_order\"</span><span class=\"diff-added\">\"lo_orderpriority\"</span> <br/> displayName: <span class=\"diff-removed\">\"lo_order\"</span><span class=\"diff-added\">\"lo_orderpriority\"</span> <br/> fullyQualifiedName: \"local_mysql.sample_db.lineorder.<span class=\"diff-removed\">lo_order\"</span><span class=\"diff-added\">lo_orderpriority\"</span>",
|
||||
messages.values().iterator().next());
|
||||
|
||||
// Simulate a change of datatype change in column
|
||||
@ -179,7 +179,7 @@ public class ChangeEventParserTest extends CatalogApplicationTest {
|
||||
assertEquals(1, messages.size());
|
||||
|
||||
assertEquals(
|
||||
"Updated **columns.lo_orderpriority** : <br/> dataType: <span class=\"diff-removed\">\"BLOB\"</span><span class=\"diff-added\">\"INT\"</span> <br/> dataTypeDisplay: <span class=\"diff-removed\">\"blob\"</span><span class=\"diff-added\">\"int\"</span>",
|
||||
"Updated **columns.lo_orderpriority**: <br/> dataType: <span class=\"diff-removed\">\"BLOB\"</span><span class=\"diff-added\">\"INT\"</span> <br/> dataTypeDisplay: <span class=\"diff-removed\">\"blob\"</span><span class=\"diff-added\">\"int\"</span>",
|
||||
messages.values().iterator().next());
|
||||
|
||||
// Simulate multiple changes to columns
|
||||
@ -197,7 +197,7 @@ public class ChangeEventParserTest extends CatalogApplicationTest {
|
||||
assertEquals(1, messages.size());
|
||||
|
||||
assertEquals(
|
||||
"Updated **columns** : lo_orderpriority<span class=\"diff-added\">, newColumn</span>",
|
||||
"Updated **columns**: lo_orderpriority<span class=\"diff-added\">, newColumn</span>",
|
||||
messages.values().iterator().next());
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ const FeedCardHeader: FC<FeedHeaderProp> = ({
|
||||
};
|
||||
|
||||
const getUserData = () => {
|
||||
const displayName = userData.displayName ?? '';
|
||||
const name = userData.name ?? '';
|
||||
const displayName = userData.displayName ?? name;
|
||||
const teams = getNonDeletedTeams(userData.teams ?? []);
|
||||
const roles = userData.roles;
|
||||
const isAdmin = userData?.isAdmin;
|
||||
@ -89,7 +89,9 @@ const FeedCardHeader: FC<FeedHeaderProp> = ({
|
||||
{displayName}
|
||||
</span>
|
||||
</a>
|
||||
<span className="tw-text-grey-muted">{name}</span>
|
||||
{displayName !== name ? (
|
||||
<span className="tw-text-grey-muted">{name}</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tw-text-left">
|
||||
|
@ -693,7 +693,7 @@ const ColumnTestForm = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onFormCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className="tw-w-16 tw-h-10"
|
||||
|
@ -358,7 +358,7 @@ const TableTestForm = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onFormCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className="tw-w-16 tw-h-10"
|
||||
|
@ -265,7 +265,7 @@ const AddGlossary = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
{getSaveButton()}
|
||||
</div>
|
||||
|
@ -487,7 +487,7 @@ const AddGlossaryTerm = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
{getSaveButton()}
|
||||
</Field>
|
||||
|
@ -101,7 +101,7 @@ const SelectServiceType = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
<span>Discard</span>
|
||||
<span>Cancel</span>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
@ -821,7 +821,7 @@ const AddWebhook: FunctionComponent<AddWebhookProps> = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
{getSaveButton()}
|
||||
</div>
|
||||
@ -830,7 +830,7 @@ const AddWebhook: FunctionComponent<AddWebhookProps> = ({
|
||||
{data && isDelete && (
|
||||
<ConfirmationModal
|
||||
bodyText={`You want to delete webhook ${data.name} permanently? This action cannot be reverted.`}
|
||||
cancelText="Discard"
|
||||
cancelText="Cancel"
|
||||
confirmButtonCss="tw-bg-error hover:tw-bg-error focus:tw-bg-error"
|
||||
confirmText="Delete"
|
||||
header="Are you sure?"
|
||||
|
@ -338,7 +338,7 @@ const CreateUser = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
{getSaveButton()}
|
||||
</Field>
|
||||
|
@ -219,7 +219,7 @@ const DataQualityTable = ({
|
||||
deleteSelection.data?.testCase?.columnTestType ||
|
||||
deleteSelection.data?.testCase?.tableTestType
|
||||
} permanently? This action cannot be reverted.`}
|
||||
cancelText="Discard"
|
||||
cancelText="Cancel"
|
||||
confirmButtonCss="tw-bg-error hover:tw-bg-error focus:tw-bg-error"
|
||||
confirmText={
|
||||
deleteSelection.state === 'waiting' ? (
|
||||
|
@ -302,7 +302,7 @@ const GlossaryV1 = ({
|
||||
{selectedData && isDelete && (
|
||||
<ConfirmationModal
|
||||
bodyText={`You want to delete ${selectedData.name} permanently? This action cannot be reverted.`}
|
||||
cancelText="Discard"
|
||||
cancelText="Cancel"
|
||||
confirmButtonCss="tw-bg-error hover:tw-bg-error focus:tw-bg-error"
|
||||
confirmText="Delete"
|
||||
header="Are you sure?"
|
||||
|
@ -103,7 +103,7 @@ const EntityDeleteModal: FC<Prop> = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
{loadingState === 'waiting' ? (
|
||||
<Button
|
||||
|
@ -52,7 +52,7 @@ interface Props {
|
||||
const ConnectionConfigForm: FunctionComponent<Props> = ({
|
||||
data,
|
||||
okText = 'Save',
|
||||
cancelText = 'Discard',
|
||||
cancelText = 'Cancel',
|
||||
serviceCategory,
|
||||
status,
|
||||
onCancel,
|
||||
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*/
|
||||
|
||||
.table-title:hover {
|
||||
border-bottom: solid 1px;
|
||||
}
|
@ -11,7 +11,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import {
|
||||
faAngleRight,
|
||||
faExclamationCircle,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { isString, isUndefined, startCase, uniqueId } from 'lodash';
|
||||
import { ExtraInfo } from 'Models';
|
||||
@ -26,6 +29,7 @@ import { TableType } from '../../../generated/entity/data/table';
|
||||
import { TagLabel } from '../../../generated/type/tagLabel';
|
||||
import { serviceTypeLogo } from '../../../utils/ServiceUtils';
|
||||
import { getEntityLink, getUsagePercentile } from '../../../utils/TableUtils';
|
||||
import './TableDataCard.style.css';
|
||||
import TableDataCardBody from './TableDataCardBody';
|
||||
|
||||
type Props = {
|
||||
@ -112,6 +116,26 @@ const TableDataCard: FunctionComponent<Props> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const fqnParts = fullyQualifiedName.split(FQN_SEPARATOR_CHAR);
|
||||
const separatorHtml = (
|
||||
<span className="tw-px-2">
|
||||
<FontAwesomeIcon
|
||||
className="tw-text-xs tw-cursor-default tw-text-gray-400 tw-align-middle"
|
||||
icon={faAngleRight}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
const tableTitle = fqnParts.map((part, i) => {
|
||||
const separator = i !== fqnParts.length - 1 ? separatorHtml : null;
|
||||
|
||||
return (
|
||||
<span key={i}>
|
||||
<span>{part}</span>
|
||||
{separator}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="tw-bg-white tw-p-3 tw-border tw-border-main tw-rounded-md"
|
||||
@ -130,7 +154,7 @@ const TableDataCard: FunctionComponent<Props> = ({
|
||||
data-testid="table-link"
|
||||
id={`${id}Title`}
|
||||
onClick={handleLinkClick}>
|
||||
{fullyQualifiedName}
|
||||
<span className="table-title">{tableTitle}</span>
|
||||
</button>
|
||||
</h6>
|
||||
{deleted && (
|
||||
|
@ -352,6 +352,18 @@ export const getGlossaryPath = (fqn?: string) => {
|
||||
return path;
|
||||
};
|
||||
|
||||
export const getParentGlossaryPath = (fqn?: string) => {
|
||||
if (fqn) {
|
||||
const parts = fqn.split(FQN_SEPARATOR_CHAR);
|
||||
if (parts.length > 1) {
|
||||
// remove the last part to get parent FQN
|
||||
fqn = parts.slice(0, -1).join(FQN_SEPARATOR_CHAR);
|
||||
}
|
||||
}
|
||||
|
||||
return getGlossaryPath(fqn);
|
||||
};
|
||||
|
||||
export const getGlossaryTermsPath = (
|
||||
glossaryName: string,
|
||||
glossaryTerm = ''
|
||||
|
@ -24,7 +24,10 @@ import {
|
||||
import AddGlossaryTerm from '../../components/AddGlossaryTerm/AddGlossaryTerm.component';
|
||||
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
||||
import Loader from '../../components/Loader/Loader';
|
||||
import { getGlossaryPath } from '../../constants/constants';
|
||||
import {
|
||||
getGlossaryPath,
|
||||
getParentGlossaryPath,
|
||||
} from '../../constants/constants';
|
||||
import { CreateGlossaryTerm } from '../../generated/api/data/createGlossaryTerm';
|
||||
import { Glossary } from '../../generated/entity/data/glossary';
|
||||
import { GlossaryTerm } from '../../generated/entity/data/glossaryTerm';
|
||||
@ -44,8 +47,12 @@ const AddGlossaryTermPage = () => {
|
||||
|
||||
const [parentGlossaryData, setParentGlossaryData] = useState<GlossaryTerm>();
|
||||
|
||||
const goToGlossaryPath = (path: string) => {
|
||||
history.push(path);
|
||||
};
|
||||
|
||||
const goToGlossary = (name = '') => {
|
||||
history.push(getGlossaryPath(name));
|
||||
goToGlossaryPath(getGlossaryPath(name));
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
@ -68,7 +75,9 @@ const AddGlossaryTermPage = () => {
|
||||
setStatus('success');
|
||||
setTimeout(() => {
|
||||
setStatus('initial');
|
||||
goToGlossary(res?.data?.fullyQualifiedName);
|
||||
goToGlossaryPath(
|
||||
getParentGlossaryPath(res?.data?.fullyQualifiedName)
|
||||
);
|
||||
}, 500);
|
||||
} else {
|
||||
handleSaveFailure(
|
||||
|
@ -558,7 +558,7 @@ const ServicesPage = () => {
|
||||
return isConfirmationModalOpen ? (
|
||||
<ConfirmationModal
|
||||
bodyText={`You want to delete service ${deleteSelection.name} permanently? This action cannot be reverted.`}
|
||||
cancelText="Discard"
|
||||
cancelText="Cancel"
|
||||
confirmButtonCss="tw-bg-error hover:tw-bg-error focus:tw-bg-error"
|
||||
confirmText="Delete"
|
||||
header="Are you sure?"
|
||||
|
@ -92,7 +92,7 @@ describe('Test AddUsersModal component', () => {
|
||||
onSave={mockSave}
|
||||
/>
|
||||
);
|
||||
const discard = await findByText(container, /Discard/i);
|
||||
const discard = await findByText(container, /Cancel/i);
|
||||
fireEvent.click(discard);
|
||||
|
||||
expect(mockCancel).toBeCalledTimes(1);
|
||||
|
@ -123,7 +123,7 @@ const AddUsersModal = ({
|
||||
theme="primary"
|
||||
variant="text"
|
||||
onClick={onCancel}>
|
||||
Discard
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
data-testid="AddUserSave"
|
||||
|
@ -474,4 +474,9 @@
|
||||
@apply tw-border-gray-300 tw-border tw-text-error focus:tw-outline-none focus:tw-bg-transparent hover:tw-border-error focus:tw-border-error
|
||||
hover:tw-text-error focus:tw-text-error focus:tw-ring focus:tw-ring-error;
|
||||
}
|
||||
|
||||
/* ToastUI Editor style */
|
||||
.ProseMirror .placeholder {
|
||||
@apply tw-text-grey-muted;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user