Skip to content

Commit 33dd9df

Browse files
committed
Merge branch 'feature/RI-2586_database_analysis' into fe/feature/RI-3558_extrapolate-results
# Conflicts: # redisinsight/ui/src/components/charts/donut-chart/DonutChart.tsx # redisinsight/ui/src/pages/databaseAnalysis/components/summary-per-data/SummaryPerData.tsx
2 parents e4fe25b + b0dd0d5 commit 33dd9df

File tree

18 files changed

+316
-124
lines changed

18 files changed

+316
-124
lines changed

redisinsight/ui/src/components/charts/donut-chart/DonutChart.spec.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ describe('DonutChart', () => {
7272
expect(screen.getByTestId('label-E-30')).toHaveTextContent('E: 30')
7373
})
7474

75+
it('should render label value without title', () => {
76+
render(<DonutChart data={mockData} config={{ percentToShowLabel: 5 }} hideLabelTitle />)
77+
expect(screen.getByTestId('label-E-30').textContent).toBe('30')
78+
})
79+
7580
it('should call render tooltip and label methods', () => {
7681
const renderLabel = jest.fn()
7782
const renderTooltip = jest.fn()

redisinsight/ui/src/components/charts/donut-chart/DonutChart.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const DonutChart = (props: IProps) => {
5757
labelAs = 'value',
5858
renderLabel,
5959
renderTooltip,
60-
hideLabelTitle = false
60+
hideLabelTitle = false,
6161
} = props
6262

6363
const margin = config?.margin || 98
@@ -123,6 +123,15 @@ const DonutChart = (props: IProps) => {
123123
return `translate(${(x / h) * (radius + 12)}, ${((y + 4) / h) * (radius + 12)})`
124124
}
125125

126+
useEffect(() => {
127+
d3
128+
.select(svgRef.current)
129+
.attr('width', width)
130+
.attr('height', height)
131+
.select('g')
132+
.attr('transform', `translate(${width / 2},${height / 2})`)
133+
}, [height, width])
134+
126135
useEffect(() => {
127136
const pie = d3.pie<ChartData>().value((d: ChartData) => d.value).sort(null)
128137
const dataReady = pie(data.filter((d) => d.value !== 0))
@@ -184,7 +193,7 @@ const DonutChart = (props: IProps) => {
184193
return truncateNumberToRange(d.value)
185194
})
186195
.attr('class', cx(styles.chartLabelValue, classNames?.arcLabelValue))
187-
}, [data])
196+
}, [data, hideLabelTitle])
188197

189198
if (!data.length || sum === 0) {
190199
return null

redisinsight/ui/src/components/monitor/Monitor/Monitor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const Monitor = (props: Props) => {
7676
</EuiFlexItem>
7777
<EuiFlexItem grow={false}>
7878
<EuiTextColor color="warning" className="warning--light" style={{ paddingLeft: 4 }} data-testid="monitor-warning-message">
79-
Running Profiler will decrease throughput, avoid running it in production databases
79+
Running Profiler will decrease throughput, avoid running it in production databases.
8080
</EuiTextColor>
8181
</EuiFlexItem>
8282
</EuiFlexGroup>

redisinsight/ui/src/pages/databaseAnalysis/components/empty-analysis-message/EmptyAnalysisMessage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface Props {
1515
const emptyMessageContent: { [key in EmptyMessage]: Content } = {
1616
[EmptyMessage.Reports]: {
1717
title: 'No Reports found',
18-
text: () => 'Run "New Analysis" to generate first report'
18+
text: () => 'Run "New Analysis" to generate first report.'
1919
},
2020
[EmptyMessage.Keys]: {
2121
title: 'No keys to display',

redisinsight/ui/src/pages/databaseAnalysis/components/summary-per-data/SummaryPerData.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@ export interface Props {
2020
onSwitchExtrapolation?: (value: boolean) => void
2121
}
2222

23+
const widthResponsiveSize = 1024
24+
const CHART_WITH_LABELS_WIDTH = 432
25+
const CHART_WIDTH = 320
26+
2327
const SummaryPerData = ({ data, loading, extrapolation, onSwitchExtrapolation }: Props) => {
2428
const { totalMemory, totalKeys } = data || {}
2529
const [memoryData, setMemoryData] = useState<ChartData[]>([])
2630
const [keysData, setKeysData] = useState<ChartData[]>([])
2731
const [isExtrapolated, setIsExtrapolated] = useState<boolean>(true)
32+
const [hideLabelTitle, setHideLabelTitle] = useState(false)
2833

2934
const getChartData = (t: SimpleTypeSummary) => ({
3035
value: t.total,
@@ -33,10 +38,22 @@ const SummaryPerData = ({ data, loading, extrapolation, onSwitchExtrapolation }:
3338
meta: { ...t }
3439
})
3540

41+
const updateChartSize = () => {
42+
setHideLabelTitle(globalThis.innerWidth < widthResponsiveSize)
43+
}
44+
3645
useEffect(() => {
3746
setIsExtrapolated(extrapolation !== 1)
3847
}, [data, extrapolation])
3948

49+
useEffect(() => {
50+
updateChartSize()
51+
globalThis.addEventListener('resize', updateChartSize)
52+
return () => {
53+
globalThis.removeEventListener('resize', updateChartSize)
54+
}
55+
}, [])
56+
4057
useEffect(() => {
4158
if (data && totalMemory && totalKeys) {
4259
setMemoryData(totalMemory.types?.map(getChartData) as ChartData[])
@@ -125,7 +142,8 @@ const SummaryPerData = ({ data, loading, extrapolation, onSwitchExtrapolation }:
125142
name="memory"
126143
data={memoryData}
127144
labelAs="percentage"
128-
width={432}
145+
hideLabelTitle={hideLabelTitle}
146+
width={hideLabelTitle ? CHART_WIDTH : CHART_WITH_LABELS_WIDTH}
129147
config={{ radius: 94 }}
130148
renderTooltip={renderMemoryTooltip}
131149
title={(
@@ -151,7 +169,8 @@ const SummaryPerData = ({ data, loading, extrapolation, onSwitchExtrapolation }:
151169
name="keys"
152170
data={keysData}
153171
labelAs="percentage"
154-
width={432}
172+
hideLabelTitle={hideLabelTitle}
173+
width={hideLabelTitle ? CHART_WIDTH : CHART_WITH_LABELS_WIDTH}
155174
config={{ radius: 94 }}
156175
renderTooltip={renderKeysTooltip}
157176
title={(

tests/e2e/docker.web.docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ services:
1111
- ./report:/usr/src/app/report
1212
- ./plugins:/usr/src/app/plugins
1313
- .redisinsight-v2:/root/.redisinsight-v2
14+
- .ritmp:/tmp
1415
env_file:
1516
- ./.env
1617
entrypoint: [
@@ -38,4 +39,5 @@ services:
3839
- ./.env
3940
volumes:
4041
- .redisinsight-v2:/root/.redisinsight-v2
42+
- .ritmp:/tmp
4143

tests/e2e/pageObjects/memory-efficiency-page.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ export class MemoryEfficiencyPage {
1414
showNoExpiryToggle = Selector('[data-testid=show-no-expiry-switch]');
1515
reportItem = Selector('[data-test-subj^=items-report-]');
1616
selectedReport = Selector('[data-testid=select-report]');
17+
sortByLength = Selector('[data-testid=btn-change-table-keys]');
1718
// ICONS
1819
reportTooltipIcon = Selector('[data-testid=db-new-reports-icon]');
1920
// TEXT ELEMENTS
2021
noReportsText = Selector('[data-testid=empty-analysis-no-reports]');
2122
noKeysText = Selector('[data-testid=empty-analysis-no-keys]');
2223
scannedPercentageInReport = Selector('[data-testid=analysis-progress]');
2324
scannedKeysInReport = Selector('[data-testid=bulk-delete-summary]');
25+
topKeysTitle = Selector('[data-testid=top-keys-title]');
26+
topKeysKeyName = Selector('[data-testid=top-keys-table-name]');
2427
// TABLE
25-
tableRows = Selector('tr[class*=euiTableRow]');
28+
namespaceTable = Selector('[data-testid=nsp-table-memory]');
29+
nameSpaceTableRows = this.namespaceTable.find('[data-testid^=row-]');
2630
expandedRow = Selector('#row_test_expansion');
2731
tableKeyPatternHeader = Selector('[data-test-subj*=tableHeaderCell_nsp]');
2832
tableMemoryHeader = Selector('[data-test-subj*=tableHeaderCell_memory]');

tests/e2e/pageObjects/workbench-page.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export class WorkbenchPage {
5151
cancelButton = Selector('[data-testid=cancel-btn]');
5252
applyButton = Selector('[data-testid=apply-btn]');
5353
documentButtonInQuickGuides = Selector('[data-testid=accordion-button-document]');
54+
guidesGraphAccordion = Selector('[data-testid=accordion-button-graph]');
5455
redisStackTutorialsButton = Selector('[data-testid=accordion-button-redis_stack]');
5556
nextPageButton = Selector('[data-testid=enablement-area__next-page-btn]');
5657
prevPageButton = Selector('[data-testid=enablement-area__prev-page-btn]');
@@ -60,6 +61,7 @@ export class WorkbenchPage {
6061
showSalesPerRegiomButton = Selector('[data-testid="preselect-Show all sales per region"]');
6162
queryCardNoModuleButton = Selector('[data-testid=query-card-no-module-button] a');
6263
rawModeBtn = Selector('[data-testid="btn-change-mode"]');
64+
closeEnablementPage = Selector('[data-testid=enablement-area__page-close]');
6365
groupMode = Selector('[data-testid=btn-change-group-mode]');
6466
copyCommand = Selector('[data-testid=copy-command]');
6567
redisStackTimeSeriesLoadMorePoints = Selector('[data-testid=preselect-Load more data points]');
@@ -69,7 +71,9 @@ export class WorkbenchPage {
6971
//LINKS
7072
timeSeriesLink = Selector('[data-testid=internal-link-redis_for_time_series]');
7173
redisStackLinks = Selector('[data-testid=accordion-redis_stack] [data-testid^=internal-link]');
72-
workingWithGraphLink = Selector('[data-testid=internal-link-working_with_graphs]');
74+
tutorialsWorkingWithGraphLink = Selector('[data-testid=internal-link-working_with_graphs]');
75+
guidesWorkingWithGraphLink = Selector('[data-testid=internal-link-working-with-graphs]');
76+
guidesIntroductionGraphLink = Selector('[data-testid=internal-link-introduction]');
7377
internalLinkWorkingWithHashes = Selector('[data-testid=internal-link-working-with-hashes]');
7478
vectorSimilitaritySearchButton = Selector('[data-testid=internal-link-vector_similarity_search]');
7579
//TEXT INPUTS (also referred to as 'Text fields')
@@ -104,6 +108,7 @@ export class WorkbenchPage {
104108
runButtonToolTip = Selector('[data-testid=run-query-tooltip]');
105109
loadedCommand = Selector('[class=euiLoadingContent__singleLine]');
106110
runButtonSpinner = Selector('[data-testid=loading-spinner]');
111+
enablementAreaEmptyContent = Selector('[data-testid=enablement-area__empty-prompt]');
107112
workbenchCommandInHistory = Selector(this.cssWorkbenchCommandInHistory);
108113
workbenchCommandSuccessResultInHistory = Selector(this.cssWorkbenchCommandSuccessResultInHistory);
109114
workbenchCommandFailedResultInHistory = Selector(this.cssWorkbenchCommandFailedResultInHistory);

tests/e2e/tests/critical-path/database/autoupdate-of-json.e2e.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { join } from 'path';
2+
import * as os from 'os';
3+
import * as fs from 'fs';
4+
import * as editJsonFile from 'edit-json-file';
5+
import { acceptLicenseTermsAndAddDatabaseApi} from '../../../helpers/database';
6+
import { MyRedisDatabasePage, WorkbenchPage } from '../../../pageObjects';
7+
import { commonUrl, ossStandaloneConfig } from '../../../helpers/conf';
8+
import { rte, env } from '../../../helpers/constants';
9+
import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database';
10+
11+
const myRedisDatabasePage = new MyRedisDatabasePage();
12+
const workbenchPage = new WorkbenchPage();
13+
14+
const workingDirectory = process.env.APP_FOLDER_ABSOLUTE_PATH
15+
|| (join(os.homedir(), process.env.APP_FOLDER_NAME || '.redisinsight-v2'));
16+
if (fs.existsSync(workingDirectory)) {
17+
// Guides content
18+
const guidesTimestampPath = `${workingDirectory}/guides/build.json`;
19+
const guidesGraphIntroductionFilePath = `${workingDirectory}/guides/quick-guides/graph/introduction.md`;
20+
21+
// Tutorials content
22+
const tutorialsTimestampPath = `${workingDirectory}/tutorials/build.json`;
23+
const tutorialsTimeSeriesFilePath = `${workingDirectory}/tutorials/redis_stack/redis_for_time_series.md`;
24+
25+
// Remove md files from local folder. When desktop tests are started, files will be updated from remote repository
26+
// Need to uncomment when desktop tests are started
27+
// fs.unlinkSync(guidesGraphIntroductionFilePath);
28+
// fs.unlinkSync(tutorialsTimeSeriesFilePath);
29+
30+
// Update timestamp for build files
31+
const guidesTimestampFile = editJsonFile(guidesTimestampPath);
32+
const tutorialsTimestampFile = editJsonFile(tutorialsTimestampPath);
33+
34+
const guidesNewTimestamp = guidesTimestampFile.get('timestamp') - 10;
35+
const tutorialNewTimestamp = tutorialsTimestampFile.get('timestamp') - 10;
36+
37+
guidesTimestampFile.set('timestamp', guidesNewTimestamp);
38+
guidesTimestampFile.save();
39+
tutorialsTimestampFile.set('timestamp', tutorialNewTimestamp);
40+
tutorialsTimestampFile.save();
41+
42+
fixture `Auto-update in Enablement Area`
43+
.meta({ type: 'critical_path' })
44+
.page(commonUrl)
45+
.beforeEach(async() => {
46+
await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName);
47+
})
48+
.afterEach(async() => {
49+
await deleteStandaloneDatabaseApi(ossStandaloneConfig);
50+
});
51+
test
52+
.meta({ rte: rte.standalone, env: env.desktop })('Verify that user can see updated info in Enablement Area', async t => {
53+
// Create new file due to cache-ability
54+
const guidesTimestampFileNew = editJsonFile(guidesTimestampPath);
55+
const tutorialsTimestampFileNew = editJsonFile(tutorialsTimestampPath);
56+
57+
// Open Workbench page
58+
await t.click(myRedisDatabasePage.workbenchButton);
59+
60+
// Check Enablement area and validate that removed file is existed in Guides
61+
await t.click(workbenchPage.guidesGraphAccordion);
62+
await t.click(workbenchPage.guidesIntroductionGraphLink.nth(1));
63+
await t.expect(workbenchPage.enablementAreaEmptyContent.visible).notOk('Guides folder is not updated');
64+
await t.click(workbenchPage.closeEnablementPage);
65+
66+
// Check Enablement area and validate that removed file is existed in Tutorials
67+
await t.click(workbenchPage.redisStackTutorialsButton);
68+
await t.click(workbenchPage.timeSeriesLink);
69+
await t.expect(workbenchPage.enablementAreaEmptyContent.visible).notOk('Tutorials folder is not updated');
70+
71+
// Check that timestamp is new
72+
const actualGuidesTimestamp = await guidesTimestampFileNew.get('timestamp');
73+
const actualTutorialTimestamp = await tutorialsTimestampFileNew.get('timestamp');
74+
await t.expect(actualGuidesTimestamp).notEql(guidesNewTimestamp, 'Guides timestamp is not updated');
75+
await t.expect(actualTutorialTimestamp).notEql(tutorialNewTimestamp, 'Tutorials timestamp is not updated');
76+
});
77+
}

0 commit comments

Comments
 (0)