Skip to content

Commit

Permalink
Merge branch 'main' into retention-policy-app
Browse files Browse the repository at this point in the history
  • Loading branch information
Siddhanttimeline authored Dec 20, 2024
2 parents 020f918 + 9a76b07 commit c209618
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;

@Slf4j
public class AppScheduler {
Expand Down Expand Up @@ -93,10 +94,32 @@ private AppScheduler(
.getListenerManager()
.addJobListener(new OmAppJobListener(dao), jobGroupEquals(APPS_JOB_GROUP));

this.resetErrorTriggers();

// Start Scheduler
this.scheduler.start();
}

private void resetErrorTriggers() {
try {
scheduler
.getTriggerKeys(GroupMatcher.anyGroup())
.forEach(
triggerKey -> {
try {
if (scheduler.getTriggerState(triggerKey) == Trigger.TriggerState.ERROR) {
LOG.info("Resetting trigger {} from error state", triggerKey);
scheduler.resetTriggerFromErrorState(triggerKey);
}
} catch (SchedulerException e) {
throw new RuntimeException(e);
}
});
} catch (SchedulerException ex) {
LOG.error("Failed to reset failed triggers", ex);
}
}

public static void initialize(
OpenMetadataApplicationConfig config, CollectionDAO dao, SearchRepository searchClient)
throws SchedulerException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public void sendEmailVerification(UriInfo uriInfo, User user) throws IOException
String.format(
"%s/users/registrationConfirmation?user=%s&token=%s",
getSmtpSettings().getOpenMetadataUrl(),
user.getFullyQualifiedName(),
URLEncoder.encode(user.getFullyQualifiedName(), StandardCharsets.UTF_8),
mailVerificationToken);
try {
EmailUtil.sendEmailVerification(emailVerificationLink, user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import static org.openmetadata.service.util.email.TemplateConstants.INVITE_RANDOM_PASSWORD_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.INVITE_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.PASSWORD;
import static org.openmetadata.service.util.email.TemplateConstants.PASSWORD_RESET_LINKKEY;
import static org.openmetadata.service.util.email.TemplateConstants.PASSWORD_RESET_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.REPORT_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.SUPPORT_URL;
Expand Down Expand Up @@ -179,7 +180,7 @@ public static void sendPasswordResetLink(
.add(ENTITY, getSmtpSettings().getEmailingEntity())
.add(SUPPORT_URL, getSmtpSettings().getSupportUrl())
.add(USERNAME, user.getName())
.add(EMAIL_VERIFICATION_LINKKEY, passwordResetLink)
.add(PASSWORD_RESET_LINKKEY, passwordResetLink)
.add(EXPIRATION_TIME_KEY, DEFAULT_EXPIRATION_TIME)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,17 @@ export class TableClass extends EntityClass {
children: [
{
name: 'first_name',
dataType: 'VARCHAR',
dataType: 'STRUCT',
dataLength: 100,
dataTypeDisplay: 'varchar',
dataTypeDisplay:
'struct<username:varchar(32),name:varchar(32),sex:char(1),address:varchar(128),mail:varchar(64),birthdate:varchar(16)>',
description: 'First name of the staff member.',
},
{
name: 'last_name',
dataType: 'VARCHAR',
dataType: 'ARRAY',
dataLength: 100,
dataTypeDisplay: 'varchar',
dataTypeDisplay: 'array<struct<type:string,provider:array<int>>>',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,9 @@ export const approveTagsTask = async (
await taskResolve;

await redirectToHomePage(page);
const glossaryTermsResponse = page.waitForResponse('/api/v1/glossaryTerms*');
await sidebarClick(page, SidebarItem.GLOSSARY);
await glossaryTermsResponse;
await selectActiveGlossary(page, entity.data.displayName);

const tagVisibility = await page.isVisible(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,9 @@ export const dragAndDropNode = async (
await page.hover(originSelector);
await page.mouse.down();
const box = (await destinationElement.boundingBox())!;
const x = (box.x + box.width / 2) * 0.25; // 0.25 as zoom factor
const y = (box.y + box.height / 2) * 0.25; // 0.25 as zoom factor
await page.mouse.move(x, y);
await destinationElement.hover();
const x = box.x + 250;
const y = box.y + box.height / 2;
await page.mouse.move(x, y, { steps: 20 });
await page.mouse.up();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import { Button, Col, Row } from 'antd';
import { Gutter } from 'antd/lib/grid/row';
import classNames from 'classnames';
import { includes, toLower } from 'lodash';
import { includes, startCase, toLower } from 'lodash';
import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { updateActiveChartFilter } from '../../utils/ChartUtils';
Expand Down Expand Up @@ -114,7 +114,7 @@ const TotalEntityInsightSummary = ({
onMouseEnter={() => handleLegendMouseEnter(entity)}
onMouseLeave={handleLegendMouseLeave}>
<EntitySummaryProgressBar
entity={entity}
entity={startCase(entity)}
isActive={
activeKeys?.length ? activeKeys.includes(entity) : true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
getColumnSorter,
getEntityName,
getFrequentlyJoinedColumns,
highlightSearchArrayElement,
highlightSearchText,
searchInColumns,
} from '../../../utils/EntityUtils';
Expand Down Expand Up @@ -251,7 +252,7 @@ const SchemaTable = ({
<Typography.Paragraph
className="cursor-pointer"
ellipsis={{ tooltip: displayValue, rows: 3 }}>
{stringToHTML(highlightSearchText(displayValue, searchText))}
{highlightSearchArrayElement(dataTypeDisplay, searchText)}
</Typography.Paragraph>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface DataInsightChartTooltipProps extends TooltipProps<any, any> {
dateTimeFormatter?: (date?: number) => string;
valueFormatter?: (value: number | string, key?: string) => string | number;
timeStampKey?: string;
transformLabel?: boolean;
}

export interface UIKpiResult extends KpiResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export const CustomTooltip = (props: DataInsightChartTooltipProps) => {
dateTimeFormatter = formatDate,
isPercentage,
timeStampKey = 'timestampValue',
transformLabel = true,
} = props;

if (active && payload && payload.length) {
Expand All @@ -172,7 +173,9 @@ export const CustomTooltip = (props: DataInsightChartTooltipProps) => {
<Surface className="mr-2" height={12} version="1.1" width={12}>
<rect fill={entry.color} height="14" rx="2" width="14" />
</Surface>
{startCase(entry.name ?? (entry.dataKey as string))}
{transformLabel
? startCase(entry.name ?? (entry.dataKey as string))
: entry.name ?? (entry.dataKey as string)}
</span>
<span className="font-medium">
{valueFormatter
Expand Down
100 changes: 100 additions & 0 deletions openmetadata-ui/src/main/resources/ui/src/utils/EntityUtils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { render } from '@testing-library/react';
import React from 'react';
import { getEntityDetailsPath } from '../constants/constants';
import { EntityTabs, EntityType } from '../enums/entity.enum';
import { ExplorePageTabs } from '../enums/Explore.enum';
Expand All @@ -23,6 +25,7 @@ import {
getEntityLinkFromType,
getEntityOverview,
highlightEntityNameAndDescription,
highlightSearchArrayElement,
highlightSearchText,
} from './EntityUtils';
import {
Expand Down Expand Up @@ -255,4 +258,101 @@ describe('EntityUtils unit tests', () => {
}
);
});

describe('highlightSearchArrayElement method', () => {
it('should highlight the searchText in the text', () => {
const result = highlightSearchArrayElement(mockText, 'highlightText');
const { container } = render(<>{result}</>); // Render the result to check JSX output

// Check if the correct part of the text is wrapped in a <span> with the correct class
const highlighted = container.querySelector('.text-highlighter');

expect(highlighted).toBeInTheDocument();
expect(highlighted?.textContent).toBe('highlightText');
});

it('should highlight multiple occurrences of the searchText', () => {
const result = highlightSearchArrayElement(
'Data testing environment, Manually test data',
'data'
);
const { container } = render(<>{result}</>);

// Check that there are two highlighted parts (one for each 'hello')
const highlightedElements =
container.querySelectorAll('.text-highlighter');

expect(highlightedElements).toHaveLength(2);
expect(highlightedElements[0].textContent).toBe('Data');
expect(highlightedElements[1].textContent).toBe('data');
});

it('should not modify parts of the text that do not match searchText', () => {
const result = highlightSearchArrayElement(mockText, 'highlightText');
const { container } = render(<>{result}</>);

// Ensure the non-matching part is plain text
const nonHighlighted = container.textContent;

expect(nonHighlighted).toContain('description');
});

it('should not wrap searchText in the result if it does not appear in text', () => {
const result = highlightSearchArrayElement(mockText, 'foo');
const { container } = render(<>{result}</>);

// Ensure that no parts of the text are highlighted
const highlighted = container.querySelector('.text-highlighter');

expect(highlighted).toBeNull();
});

it('should handle case-insensitive search', () => {
const result = highlightSearchArrayElement(mockText, 'HighlightText');
const { container } = render(<>{result}</>);

const highlighted = container.querySelector('.text-highlighter');

expect(highlighted).toBeInTheDocument();
expect(highlighted?.textContent).toBe('highlightText');
});

it('should return an empty string if no text is provided', () => {
const result = highlightSearchArrayElement('', 'test');

expect(result).toBe('');
});

it('should return an empty string if no searchText is provided', () => {
const result = highlightSearchArrayElement(mockText, '');

expect(result).toBe(mockText);
});

it('should return empty string if both text and searchText are missing', () => {
const result = highlightSearchArrayElement('', '');

expect(result).toBe('');
});

const falsyTestCases = [
{ text: null, searchText: 'test', expected: '' },
{ text: 'mockText', searchText: null, expected: 'mockText' },
{ text: null, searchText: null, expected: '' },
{ text: 0 as any, searchText: '', expected: 0 },
{ text: false as any, searchText: '', expected: false },
];

it.each(falsyTestCases)(
'should return expected when text or searchText is null or falsy',
({ text, searchText, expected }) => {
const result = highlightSearchArrayElement(
text ?? undefined,
searchText ?? undefined
);

expect(result).toBe(expected);
}
);
});
});
29 changes: 28 additions & 1 deletion openmetadata-ui/src/main/resources/ui/src/utils/EntityUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2404,5 +2404,32 @@ export const highlightSearchText = (

const regex = new RegExp(`(${searchText})`, 'gi');

return text.replace(regex, `<mark class="text-highlighter">$1</mark>`);
return text.replace(regex, `<span class="text-highlighter">$1</span>`);
};

/**
* It searches for a given text in a given string and returns an array that contains the string parts that have
* highlighted element if match found.
* @param text - The text to search in.
* @param searchText - The text to search for.
* @returns An Array of string or JSX.Element which contains highlighted element.
*/
export const highlightSearchArrayElement = (
text?: string,
searchText?: string
): string | (string | JSX.Element)[] => {
if (!searchText || !text) {
return text ?? '';
}
const stringParts = text.split(new RegExp(`(${searchText})`, 'gi'));

return stringParts.map((part, index) =>
part.toLowerCase() === (searchText ?? '').toLowerCase() ? (
<span className="text-highlighter" key={`${part}-${index}`}>
{part}
</span>
) : (
part
)
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,4 @@ export const mockText =
export const mockSearchText = 'test';

export const mockHighlightedResult =
'This is a <mark class="text-highlighter">test</mark> description to verify highlightText method.';
'This is a <span class="text-highlighter">test</span> description to verify highlightText method.';

0 comments on commit c209618

Please sign in to comment.