diff --git a/package-lock.json b/package-lock.json index 5a140588d..5a2b6a59c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "graph-explorer-v2", - "version": "4.11.0", + "version": "4.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1d8ab4f3d..b1bff9a0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "graph-explorer-v2", - "version": "4.11.0", + "version": "4.12.0", "private": true, "dependencies": { "@azure/msal-browser": "2.12.0", diff --git a/src/app/services/actions/theme-action-creator.ts b/src/app/services/actions/theme-action-creator.ts index 3193f264a..b8b476ec2 100644 --- a/src/app/services/actions/theme-action-creator.ts +++ b/src/app/services/actions/theme-action-creator.ts @@ -2,7 +2,6 @@ import { Dispatch } from 'redux'; import { saveTheme } from '../../../themes/theme-utils'; import { IAction } from '../../../types/action'; -import { IThemeChangedMessage } from '../../../types/query-runner'; import { CHANGE_THEME_SUCCESS } from '../redux-constants'; export function changeThemeSuccess(response: string): IAction { @@ -12,8 +11,7 @@ export function changeThemeSuccess(response: string): IAction { }; } -export function changeTheme(theme: IThemeChangedMessage['theme']): Function { - +export function changeTheme(theme: string): Function { saveTheme(theme); return (dispatch: Dispatch) => { diff --git a/src/app/utils/status-message.ts b/src/app/utils/status-message.ts index 7aa75e8e3..f555dc563 100644 --- a/src/app/utils/status-message.ts +++ b/src/app/utils/status-message.ts @@ -20,7 +20,7 @@ export function convertArrayToObject(array: any[]): object { }; export function extractUrl(value: string): string[] | null { - return value.toString().match(/\bhttps?:\/\/\S+/gi); + return value.toString().match(/\bhttps?:\/\/\S+(? { this.state = { selectedVerb: 'GET', mobileScreen: false, - hideDialog: true + hideDialog: true, }; } @@ -103,7 +113,7 @@ class App extends Component { 'https://docs.microsoft.com', 'https://review.docs.microsoft.com', 'https://ppe.docs.microsoft.com', - 'https://docs.azure.cn' + 'https://docs.azure.cn', ]; // Notify host document that GE is ready to receive messages @@ -147,7 +157,8 @@ class App extends Component { } private generateQueryObjectFrom(queryParams: any) { - const { request, method, version, graphUrl, requestBody, headers } = queryParams; + const { request, method, version, graphUrl, requestBody, headers } = + queryParams; if (!request) { return null; @@ -158,7 +169,7 @@ class App extends Component { selectedVerb: method, selectedVersion: version, sampleBody: requestBody ? this.hashDecode(requestBody) : null, - sampleHeaders: (headers) ? JSON.parse(this.hashDecode(headers)) : [], + sampleHeaders: headers ? JSON.parse(this.hashDecode(headers)) : [], }; } @@ -214,7 +225,7 @@ class App extends Component { if (actions) { actions.setSampleQuery({ sampleUrl: url, - selectedVerb: verb + selectedVerb: verb, }); } @@ -232,7 +243,7 @@ class App extends Component { const requestHeaders = headers.map((header: any) => { return { name: Object.keys(header)[0], - value: Object.values(header)[0] + value: Object.values(header)[0], }; }); @@ -241,7 +252,7 @@ class App extends Component { selectedVerb: verb, sampleBody: body, selectedVersion: queryVersion, - sampleHeaders: requestHeaders + sampleHeaders: requestHeaders, }; substituteTokens(query, profile); @@ -249,12 +260,11 @@ class App extends Component { actions.setSampleQuery(query); } }, 1000); - }; public handleSelectVerb = (verb: string) => { this.setState({ - selectedVerb: verb + selectedVerb: verb, }); }; @@ -263,12 +273,10 @@ class App extends Component { const properties = { ...sidebarProperties }; properties.showSidebar = !properties.showSidebar; this.props.actions!.toggleSidebar(properties); - telemetry.trackEvent( - eventTypes.BUTTON_CLICK_EVENT, - { - ComponentName: componentNames.SIDEBAR_HAMBURGER_BUTTON - }); - } + telemetry.trackEvent(eventTypes.BUTTON_CLICK_EVENT, { + ComponentName: componentNames.SIDEBAR_HAMBURGER_BUTTON, + }); + }; public displayToggleButton = (mediaQueryList: any) => { const mobileScreen = mediaQueryList.matches; @@ -279,32 +287,45 @@ class App extends Component { const properties = { mobileScreen, - showSidebar + showSidebar, }; this.props.actions!.toggleSidebar(properties); - } + }; public displayAuthenticationSection = (minimised: boolean) => { - return
-
- -
-
- + return ( +
+
+ +
+
+ +
-
; - } + ); + }; public render() { const classes = classNames(this.props); - const { authenticated, graphExplorerMode, queryState, minimised, termsOfUse, sampleQuery, - actions, sidebarProperties, intl: { messages } }: any = this.props; + const { + authenticated, + graphExplorerMode, + queryState, + minimised, + termsOfUse, + sampleQuery, + actions, + sidebarProperties, + intl: { messages }, + }: any = this.props; const query = createShareLink(sampleQuery, authenticated); const sampleHeaderText = messages['Sample Queries']; // tslint:disable-next-line:no-string-literal @@ -320,7 +341,7 @@ class App extends Component { const stackTokens: IStackTokens = { childrenGap: 10, - padding: 10 + padding: 10, }; let sidebarWidth = `col-sm-12 col-lg-3 col-md-4 ${classes.sidebar}`; @@ -343,46 +364,62 @@ class App extends Component { // @ts-ignore
- +
{graphExplorerMode === Mode.Complete && (
- {mobileScreen && appTitleDisplayOnMobileScreen( - stackTokens, - classes, - this.toggleSidebar)} - - {!mobileScreen && appTitleDisplayOnFullScreen( - classes, - minimised, - this.toggleSidebar - )} + {mobileScreen && + appTitleDisplayOnMobileScreen( + stackTokens, + classes, + this.toggleSidebar + )} + + {!mobileScreen && + appTitleDisplayOnFullScreen( + classes, + minimised, + this.toggleSidebar + )}
{this.displayAuthenticationSection(minimised)}
- {showSidebar && <> - - } + {showSidebar && ( + <> + + + )}
)}
- {graphExplorerMode === Mode.TryIt && headerMessaging(classes, query)} - - {displayContent && <> -
- -
- {statusMessages(queryState, sampleQuery, actions)} - {termsOfUseMessage(termsOfUse, actions, classes, geLocale)} - { - // @ts-ignore - - } - } + {graphExplorerMode === Mode.TryIt && + headerMessaging(classes, query)} + + {displayContent && ( + <> +
+ +
+ {statusMessages(queryState, sampleQuery, actions)} + {termsOfUseMessage(termsOfUse, actions, classes, geLocale)} + { + // @ts-ignore + + } + + )}
@@ -391,8 +428,15 @@ class App extends Component { } } -const mapStateToProps = ({ sidebarProperties, theme, - queryRunnerStatus, profile, sampleQuery, termsOfUse, authToken, graphExplorerMode +const mapStateToProps = ({ + sidebarProperties, + theme, + queryRunnerStatus, + profile, + sampleQuery, + termsOfUse, + authToken, + graphExplorerMode, }: IRootState) => { const mobileScreen = !!sidebarProperties.mobileScreen; const showSidebar = !!sidebarProperties.showSidebar; @@ -407,23 +451,24 @@ const mapStateToProps = ({ sidebarProperties, theme, termsOfUse, minimised: !mobileScreen && !showSidebar, sampleQuery, - authenticated: !!authToken.token + authenticated: !!authToken.token, }; }; const mapDispatchToProps = (dispatch: Dispatch) => { return { - actions: bindActionCreators({ - clearQueryStatus, - clearTermsOfUse, - runQuery, - setSampleQuery, - toggleSidebar, - ...authActionCreators, - changeTheme: (newTheme: string) => { - return (disp: Function) => disp(changeThemeSuccess(newTheme)); - } - }, dispatch) + actions: bindActionCreators( + { + clearQueryStatus, + clearTermsOfUse, + runQuery, + setSampleQuery, + toggleSidebar, + ...authActionCreators, + changeTheme, + }, + dispatch + ), }; }; @@ -431,4 +476,4 @@ const StyledApp = styled(App, appStyles as any); const IntlApp = injectIntl(StyledApp); //@ts-ignore -export default connect(mapStateToProps, mapDispatchToProps)(IntlApp); \ No newline at end of file +export default connect(mapStateToProps, mapDispatchToProps)(IntlApp); diff --git a/src/app/views/app-sections/TermsOfUseMessage.tsx b/src/app/views/app-sections/TermsOfUseMessage.tsx index f864b9bf4..b3e7cf260 100644 --- a/src/app/views/app-sections/TermsOfUseMessage.tsx +++ b/src/app/views/app-sections/TermsOfUseMessage.tsx @@ -7,7 +7,8 @@ export function termsOfUseMessage(termsOfUse: any, actions: any, classes: any, l + dismissButtonAriaLabel='Close' + style={{ position: 'relative' }}> telemetry.trackLinkClickEvent(e.currentTarget.href, componentNames.MICROSOFT_APIS_TERMS_OF_USE_LINK)} className={classes.links} href={'https://docs.microsoft.com/' + language + diff --git a/src/app/views/query-response/headers/ResponseHeaders.tsx b/src/app/views/query-response/headers/ResponseHeaders.tsx index 322de98b2..282a31f3b 100644 --- a/src/app/views/query-response/headers/ResponseHeaders.tsx +++ b/src/app/views/query-response/headers/ResponseHeaders.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { RESPONSE_HEADERS_COPY_BUTTON } from '../../../../telemetry/component-names'; import { IRootState } from '../../../../types/root'; +import { translateMessage } from '../../../utils/translate-messages'; import { Monaco } from '../../common'; import { trackedGenericCopy } from '../../common/copy'; @@ -20,6 +21,7 @@ const ResponseHeaders = () => {
diff --git a/src/app/views/query-response/pivot-items/pivot-items.tsx b/src/app/views/query-response/pivot-items/pivot-items.tsx index af0fe70c9..8a08d104c 100644 --- a/src/app/views/query-response/pivot-items/pivot-items.tsx +++ b/src/app/views/query-response/pivot-items/pivot-items.tsx @@ -62,7 +62,7 @@ export const getPivotItems = () => { const pivotItems = [ { , { pivotItems.push( { , { , trackedGenericCopy( diff --git a/src/app/views/query-runner/query-input/QueryInput.tsx b/src/app/views/query-runner/query-input/QueryInput.tsx index 70c51ac1e..69524c2f0 100644 --- a/src/app/views/query-runner/query-input/QueryInput.tsx +++ b/src/app/views/query-runner/query-input/QueryInput.tsx @@ -1,3 +1,4 @@ +import { IDropdownOption } from 'office-ui-fabric-react'; import { Dropdown } from 'office-ui-fabric-react'; import React from 'react'; import { injectIntl } from 'react-intl'; @@ -21,7 +22,7 @@ const QueryInput = (props: IQueryInputProps) => { } = props; const dispatch = useDispatch(); - const httpMethods = [ + const httpMethods: IDropdownOption[] = [ { key: 'GET', text: 'GET' }, { key: 'POST', text: 'POST' }, { key: 'PUT', text: 'PUT' }, @@ -29,7 +30,7 @@ const QueryInput = (props: IQueryInputProps) => { { key: 'DELETE', text: 'DELETE' }, ]; - const urlVersions = [ + const urlVersions: IDropdownOption[] = [ { key: 'v1.0', text: 'v1.0' }, { key: 'beta', text: 'beta' }, ]; diff --git a/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx b/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx index f1403d551..6f6d60f0b 100644 --- a/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx +++ b/src/app/views/query-runner/query-input/auto-complete/AutoComplete.tsx @@ -23,6 +23,7 @@ import SuggestionsList from './SuggestionsList'; class AutoComplete extends Component { private autoCompleteRef: React.RefObject; + private element: HTMLDivElement | null | undefined; constructor(props: IAutoCompleteProps) { super(props); @@ -36,7 +37,8 @@ class AutoComplete extends Component { showSuggestions: false, userInput: this.props.sampleQuery.sampleUrl, queryUrl: this.props.sampleQuery.sampleUrl, - compare: '' + compare: '', + multiline: false }; } @@ -57,13 +59,34 @@ class AutoComplete extends Component { this.props.contentChanged(userInput); }; + public isOverflowing = (input: string) => { + + function getTextWidth(text: string) { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + + if (context === null) { + return 0; + } + + context.font = getComputedStyle(document.body).font; + return context.measureText(text).width + 5; + + } + + return !!this.element + && getTextWidth(input) > this.element.scrollWidth; + + } + public onChange = (e: any) => { const { suggestions, showSuggestions, userInput: previousUserInput, compare } = this.state; const userInput = e.target.value; this.setState({ userInput, - queryUrl: userInput + queryUrl: userInput, + multiline: this.isOverflowing(userInput) }); if (showSuggestions && suggestions.length) { @@ -247,7 +270,8 @@ class AutoComplete extends Component { if (newUrl !== this.state.queryUrl) { this.setState({ queryUrl: newUrl, - userInput: newUrl + userInput: newUrl, + multiline: this.isOverflowing(newUrl) }); } } @@ -323,6 +347,7 @@ class AutoComplete extends Component { userInput: selectedSuggestion, compare: '', queryUrl: selectedSuggestion, + multiline: this.isOverflowing(selectedSuggestion) }); this.props.contentChanged(selectedSuggestion); this.setFocus(); @@ -378,7 +403,8 @@ class AutoComplete extends Component { filteredSuggestions, showSuggestions, userInput, - queryUrl + queryUrl, + multiline } = this.state; const currentTheme = getTheme(); @@ -388,20 +414,25 @@ class AutoComplete extends Component { return (
- +
{ this.element = el }}> + +
{showSuggestions && userInput && filteredSuggestions.length > 0 && { borderWidth: '1px', borderStyle: 'solid', borderColor: theme.palette.neutralLight, - overflow: 'hidden', + overflow: 'hidden' }, suggestionActive: { display: 'block', @@ -61,6 +61,7 @@ export const autoCompleteStyles = (theme: ITheme) => { borderWidth: '1px', borderStyle: 'solid', overflow: 'hidden', + wordWrap: "normal", backgroundColor: theme.palette.neutralLight }, suggestionTitle: { diff --git a/src/app/views/query-runner/query-runner.scss b/src/app/views/query-runner/query-runner.scss index 6f7468493..47cc1312f 100644 --- a/src/app/views/query-runner/query-runner.scss +++ b/src/app/views/query-runner/query-runner.scss @@ -7,3 +7,8 @@ } } + .ms-Dropdown:focus { + outline-style:double !important; + outline-width:thick !important ; +} + diff --git a/src/app/views/query-runner/request/auth/Auth.tsx b/src/app/views/query-runner/request/auth/Auth.tsx index 034ba32ca..a896746d1 100644 --- a/src/app/views/query-runner/request/auth/Auth.tsx +++ b/src/app/views/query-runner/request/auth/Auth.tsx @@ -53,7 +53,7 @@ export function Auth(props: any) {
- + { const [headerName, setHeaderName] = useState(''); const [headerValue, setHeaderValue] = useState(''); const [announcedMessage, setAnnouncedMessage] = useState(''); + const [isHoverOverHeadersList, setIsHoverOverHeadersList] = useState(false); const { intl: { messages } } = props; const sampleQueryHeaders = sampleQuery.sampleHeaders; @@ -28,6 +29,9 @@ const RequestHeaders = (props: any) => { const dispatch = useDispatch(); const classes = classNames(props); + const textfieldRef = React.createRef(); + const onSetFocus = () => textfieldRef.current!.focus(); + const handleOnHeaderNameChange = (name?: string) => { if (name) { setHeaderName(name); @@ -49,6 +53,7 @@ const RequestHeaders = (props: any) => { dispatch(queryInputActionCreators.setSampleQuery(query)); setAnnouncedMessage(translateMessage('Request Header deleted')); + onSetFocus(); //set focus to textfield after an item is deleted }; const handleOnHeaderAdd = () => { @@ -76,7 +81,11 @@ const RequestHeaders = (props: any) => { }; return ( -
+
setIsHoverOverHeadersList(true)} + onMouseLeave={() => setIsHoverOverHeadersList(false)} + className={classes.container} + style={isHoverOverHeadersList ? { height: convertVhToPx(height, 60) } : { height: convertVhToPx(height, 60), overflow: "hidden" }}>
@@ -84,6 +93,7 @@ const RequestHeaders = (props: any) => { placeholder={messages.Key} value={headerName} onChange={(event, name) => handleOnHeaderNameChange(name)} + componentRef={textfieldRef} />
diff --git a/src/app/views/query-runner/request/permissions/TabList.tsx b/src/app/views/query-runner/request/permissions/TabList.tsx index b5c42205e..589996644 100644 --- a/src/app/views/query-runner/request/permissions/TabList.tsx +++ b/src/app/views/query-runner/request/permissions/TabList.tsx @@ -1,5 +1,5 @@ import { DetailsList, DetailsListLayoutMode, IColumn, Label, Link, SelectionMode } from 'office-ui-fabric-react'; -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { useDispatch, useSelector } from 'react-redux'; @@ -21,6 +21,7 @@ const TabList = ({ columns, classes, renderItemColumn, renderDetailsHeader, maxH const { consentedScopes, scopes, authToken } = useSelector((state: IRootState) => state); const permissions: IPermission[] = scopes.hasUrl ? scopes.data : []; const tokenPresent = !!authToken.token; + const [isHoverOverPermissionsList, setIsHoverOverPermissionsList] = useState(false); setConsentedStatus(tokenPresent, permissions, consentedScopes); @@ -63,13 +64,18 @@ const TabList = ({ columns, classes, renderItemColumn, renderDetailsHeader, maxH {!tokenPresent && } {tokenPresent && } - renderItemColumn(item, index, column)} - selectionMode={SelectionMode.none} - layoutMode={DetailsListLayoutMode.justified} - onRenderDetailsHeader={(props?: any, defaultRender?: any) => renderDetailsHeader(props, defaultRender)} /> +
setIsHoverOverPermissionsList(true)} + onMouseLeave={() => setIsHoverOverPermissionsList(false)}> + renderItemColumn(item, index, column)} + selectionMode={SelectionMode.none} + layoutMode={DetailsListLayoutMode.justified} + onRenderDetailsHeader={(props?: any, defaultRender?: any) => renderDetailsHeader(props, defaultRender)} /> +
{permissions && permissions.length === 0 && displayNoPermissionsFoundMessage() } diff --git a/src/app/views/settings/Settings.tsx b/src/app/views/settings/Settings.tsx index fa6a5a203..149ec9959 100644 --- a/src/app/views/settings/Settings.tsx +++ b/src/app/views/settings/Settings.tsx @@ -11,7 +11,7 @@ import { Panel, PanelType, PrimaryButton, - TooltipHost + TooltipHost, } from 'office-ui-fabric-react'; import React, { useEffect, useState } from 'react'; import { FormattedMessage, injectIntl } from 'react-intl'; @@ -30,17 +30,20 @@ import { togglePermissionsPanel } from '../../services/actions/permissions-panel import { changeTheme } from '../../services/actions/theme-action-creator'; import { Permission } from '../query-runner/request/permissions'; - function Settings(props: ISettingsProps) { const dispatch = useDispatch(); - const { permissionsPanelOpen, authToken, theme: appTheme } = useSelector((state: IRootState) => state); + const { + permissionsPanelOpen, + authToken, + theme: appTheme, + } = useSelector((state: IRootState) => state); const authenticated = authToken.token; const [themeChooserDialogHidden, hideThemeChooserDialog] = useState(true); const [items, setItems] = useState([]); const [selectedPermissions, setSelectedPermissions] = useState([]); const { - intl: { messages } + intl: { messages }, }: any = props; useEffect(() => { @@ -68,7 +71,7 @@ function Settings(props: ISettingsProps) { { key: 'divider', text: '-', - itemType: DropdownMenuItemType.Divider + itemType: DropdownMenuItemType.Divider, }, { key: 'change-theme', @@ -77,7 +80,7 @@ function Settings(props: ISettingsProps) { iconName: 'Color', }, onClick: () => toggleThemeChooserDialogState(), - } + }, ]; if (authenticated) { @@ -107,11 +110,9 @@ function Settings(props: ISettingsProps) { let hidden = themeChooserDialogHidden; hidden = !hidden; hideThemeChooserDialog(hidden); - telemetry.trackEvent( - eventTypes.BUTTON_CLICK_EVENT, - { - ComponentName: componentNames.THEME_CHANGE_BUTTON - }); + telemetry.trackEvent(eventTypes.BUTTON_CLICK_EVENT, { + ComponentName: componentNames.THEME_CHANGE_BUTTON, + }); }; const handleSignOut = () => { @@ -119,15 +120,13 @@ function Settings(props: ISettingsProps) { }; const handleChangeTheme = (selectedTheme: any) => { - const newTheme: AppTheme = selectedTheme.key; + const newTheme: string = selectedTheme.key; dispatch(changeTheme(newTheme)); loadGETheme(newTheme); - telemetry.trackEvent( - eventTypes.BUTTON_CLICK_EVENT, - { - ComponentName: componentNames.SELECT_THEME_BUTTON, - SelectedTheme: selectedTheme.key.replace('-', ' ').toSentenceCase() - }); + telemetry.trackEvent(eventTypes.BUTTON_CLICK_EVENT, { + ComponentName: componentNames.SELECT_THEME_BUTTON, + SelectedTheme: selectedTheme.key.replace('-', ' ').toSentenceCase(), + }); }; const changePanelState = () => { @@ -139,21 +138,16 @@ function Settings(props: ISettingsProps) { }; const trackSelectPermissionsButtonClickEvent = () => { - telemetry.trackEvent( - eventTypes.BUTTON_CLICK_EVENT, - { - ComponentName: componentNames.VIEW_ALL_PERMISSIONS_BUTTON - }); - } + telemetry.trackEvent(eventTypes.BUTTON_CLICK_EVENT, { + ComponentName: componentNames.VIEW_ALL_PERMISSIONS_BUTTON, + }); + }; const trackReportAnIssueLinkClickEvent = () => { - telemetry.trackEvent( - eventTypes.LINK_CLICK_EVENT, - { - ComponentName: componentNames.REPORT_AN_ISSUE_LINK - }); - } - + telemetry.trackEvent(eventTypes.LINK_CLICK_EVENT, { + ComponentName: componentNames.REPORT_AN_ISSUE_LINK, + }); + }; const setPermissions = (permissions: []) => { setSelectedPermissions(permissions); @@ -165,11 +159,9 @@ function Settings(props: ISettingsProps) { }; const trackOfficeDevProgramLinkClickEvent = () => { - telemetry.trackEvent( - eventTypes.LINK_CLICK_EVENT, - { - ComponentName: componentNames.OFFICE_DEV_PROGRAM_LINK - }); + telemetry.trackEvent(eventTypes.LINK_CLICK_EVENT, { + ComponentName: componentNames.OFFICE_DEV_PROGRAM_LINK, + }); }; const getSelectionDetails = () => { @@ -206,7 +198,7 @@ function Settings(props: ISettingsProps) { const menuProperties = { shouldFocusOnMount: true, alignTargetEdge: true, - items + items, }; return ( @@ -214,17 +206,18 @@ function Settings(props: ISettingsProps) { + calloutProps={{ gapSpace: 0 }} + > - + menuProps={menuProperties} + />
- handleChangeTheme(selectedTheme)} + onChange={(event, selectedTheme) => + handleChangeTheme(selectedTheme) + } /> toggleThemeChooserDialogState()} /> + onClick={() => toggleThemeChooserDialogState()} + /> diff --git a/src/app/views/sidebar/Sidebar.styles.ts b/src/app/views/sidebar/Sidebar.styles.ts index 07661c73d..bc83111f1 100644 --- a/src/app/views/sidebar/Sidebar.styles.ts +++ b/src/app/views/sidebar/Sidebar.styles.ts @@ -21,10 +21,14 @@ export const sidebarStyles = (theme: ITheme) => { cursor: 'pointer', maxHeight: pageHeightInVh, minHeight: pageHeightInVh, - overflowY: 'auto', - overflowX: 'auto', + overflow: 'hidden', fontSize: FontSizes.medium, - background: 'inherit' + background: 'inherit', + selectors: { + ':hover': { + overflow: 'scroll', + }, + }, }, pullLeft: { float: 'left' diff --git a/src/app/views/sidebar/history/History.tsx b/src/app/views/sidebar/history/History.tsx index ac93044c0..5290f8135 100644 --- a/src/app/views/sidebar/history/History.tsx +++ b/src/app/views/sidebar/history/History.tsx @@ -199,19 +199,25 @@ export class History extends Component { ]; return ( - + + + ); default: + const shortQueryContent = queryContent.replace(GRAPH_URL, ''); return ( <> { styles={{ root: { display: 'inline-block' } }} > - {queryContent.replace(GRAPH_URL, '')} + {shortQueryContent} @@ -518,20 +524,26 @@ export class History extends Component { - {items.length > 0 && } + {items.length > 0 && +
this.setState({ isHoverOverHistoryList: true })} + onMouseLeave={() => this.setState({ isHoverOverHistoryList: false })}> + +
}