mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-24 09:14:47 +01:00
[Supporting the platform - Azure Cosmos DB - Data Explorer]: All the controls present under 'Data Explorer' page are truncated after setting the viewport to 320*256 pixel. (#2092)
* [accessibility-2278267]:[Supporting the platform - Azure Cosmos DB - Data Explorer]: All the controls present under 'Data Explorer' page are truncated after setting the viewport to 320*256 pixel. * feat: implement zoom level hook and update components for responsive design. * Format fixed. * feat: add conditionalClass utility and refactor className assignments for improved readability. --------- Co-authored-by: Satyapriya Bai <v-satybai@microsoft.com>
This commit is contained in:
parent
95d33356c3
commit
d657c4919e
@ -30,8 +30,10 @@ import { KeyboardAction, KeyboardActionGroup, KeyboardActionHandler, useKeyboard
|
||||
import { isFabric, isFabricMirrored, isFabricNative, isFabricNativeReadOnly } from "Platform/Fabric/FabricUtil";
|
||||
import { userContext } from "UserContext";
|
||||
import { getCollectionName, getDatabaseName } from "Utils/APITypeUtils";
|
||||
import { conditionalClass } from "Utils/StyleUtils";
|
||||
import { Allotment, AllotmentHandle } from "allotment";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import useZoomLevel from "hooks/useZoomLevel";
|
||||
import { debounce } from "lodash";
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
@ -104,6 +106,23 @@ const useSidebarStyles = makeStyles({
|
||||
display: "flex",
|
||||
},
|
||||
},
|
||||
accessibleContent: {
|
||||
"@media (max-width: 420px)": {
|
||||
overflow: "scroll",
|
||||
},
|
||||
},
|
||||
minHeightResponsive: {
|
||||
"@media (max-width: 420px)": {
|
||||
minHeight: "400px",
|
||||
},
|
||||
},
|
||||
accessibleContentZoom: {
|
||||
overflow: "scroll",
|
||||
},
|
||||
|
||||
minHeightZoom: {
|
||||
minHeight: "400px",
|
||||
},
|
||||
});
|
||||
|
||||
interface GlobalCommandsProps {
|
||||
@ -275,6 +294,7 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
||||
const [expandedSize, setExpandedSize] = React.useState(300);
|
||||
const hasSidebar = userContext.apiType !== "Postgres" && userContext.apiType !== "VCoreMongo";
|
||||
const allotment = useRef<AllotmentHandle>(null);
|
||||
const isZoomed = useZoomLevel();
|
||||
|
||||
const expand = useCallback(() => {
|
||||
if (!expanded) {
|
||||
@ -325,11 +345,23 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
||||
|
||||
return (
|
||||
<div className="sidebarContainer">
|
||||
<Allotment ref={allotment} onChange={onChange} onDragEnd={onDragEnd} className="resourceTreeAndTabs">
|
||||
<Allotment
|
||||
ref={allotment}
|
||||
onChange={onChange}
|
||||
onDragEnd={onDragEnd}
|
||||
className={`resourceTreeAndTabs ${styles.accessibleContent} ${conditionalClass(
|
||||
isZoomed,
|
||||
styles.accessibleContentZoom,
|
||||
)}`}
|
||||
>
|
||||
{/* Collections Tree - Start */}
|
||||
{hasSidebar && (
|
||||
// When collapsed, we force the pane to 24 pixels wide and make it non-resizable.
|
||||
<Allotment.Pane minSize={24} preferredSize={250}>
|
||||
<Allotment.Pane
|
||||
className={`${styles.minHeightResponsive} ${conditionalClass(isZoomed, styles.minHeightZoom)}`}
|
||||
minSize={24}
|
||||
preferredSize={250}
|
||||
>
|
||||
<CosmosFluentProvider className={mergeClasses(styles.sidebar)}>
|
||||
<div className={styles.sidebarContainer}>
|
||||
{loading && (
|
||||
@ -385,7 +417,10 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
||||
</CosmosFluentProvider>
|
||||
</Allotment.Pane>
|
||||
)}
|
||||
<Allotment.Pane minSize={200}>
|
||||
<Allotment.Pane
|
||||
className={`${styles.minHeightResponsive} ${conditionalClass(isZoomed, styles.minHeightZoom)}`}
|
||||
minSize={200}
|
||||
>
|
||||
<Tabs explorer={explorer} />
|
||||
</Allotment.Pane>
|
||||
</Allotment>
|
||||
|
@ -144,6 +144,13 @@ export const useDocumentsTabStyles = makeStyles({
|
||||
deleteProgressContent: {
|
||||
paddingTop: tokens.spacingVerticalL,
|
||||
},
|
||||
smallScreenContent: {
|
||||
"@media (max-width: 420px)": {
|
||||
flexWrap: "wrap",
|
||||
minHeight: "max-content",
|
||||
padding: "4px",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export class DocumentsTabV2 extends TabsBase {
|
||||
@ -2102,7 +2109,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
||||
return (
|
||||
<CosmosFluentProvider className={styles.container}>
|
||||
<div data-test={"DocumentsTab"} className="tab-pane active" role="tabpanel" style={{ display: "flex" }}>
|
||||
<div data-test={"DocumentsTab/Filter"} className={styles.filterRow}>
|
||||
<div data-test={"DocumentsTab/Filter"} className={`${styles.filterRow} ${styles.smallScreenContent}`}>
|
||||
{!isPreferredApiMongoDB && <span> SELECT * FROM c </span>}
|
||||
<InputDataList
|
||||
dropdownOptions={getFilterChoices()}
|
||||
|
@ -15,7 +15,7 @@ exports[`Documents tab (noSql API) when rendered should render the page 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="___11ktxfv_0000000 f1o614cb fy9rknc f22iagw fsnqrgy f1f5gg8d fjodcmx f122n59 f1f09k3d fg706s2 frpde29"
|
||||
className="___11ktxfv_0000000 f1o614cb fy9rknc f22iagw fsnqrgy f1f5gg8d fjodcmx f122n59 f1f09k3d fg706s2 frpde29 ___1ngl8o6_0000000 fz7mnu6 fl3egqs flhmrkm"
|
||||
data-test="DocumentsTab/Filter"
|
||||
>
|
||||
<span>
|
||||
|
@ -8,6 +8,8 @@ import RunQuery from "../../../../images/RunQuery.png";
|
||||
import { QueryResults } from "../../../Contracts/ViewModels";
|
||||
import { ErrorList } from "./ErrorList";
|
||||
import { ResultsView } from "./ResultsView";
|
||||
import useZoomLevel from "hooks/useZoomLevel";
|
||||
import { conditionalClass } from "Utils/StyleUtils";
|
||||
|
||||
export interface ResultsViewProps {
|
||||
isMongoDB: boolean;
|
||||
@ -23,11 +25,16 @@ interface QueryResultProps extends ResultsViewProps {
|
||||
|
||||
const ExecuteQueryCallToAction: React.FC = () => {
|
||||
const styles = useQueryTabStyles();
|
||||
const isZoomed = useZoomLevel();
|
||||
return (
|
||||
<div data-test="QueryTab/ResultsPane/ExecuteCTA" className={styles.executeCallToAction}>
|
||||
<div>
|
||||
<p>
|
||||
<img src={RunQuery} aria-hidden="true" />
|
||||
<img
|
||||
className={`${styles.responsiveImg} ${conditionalClass(isZoomed, styles.zoomedImageSize)}`}
|
||||
src={RunQuery}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</p>
|
||||
<p>Execute a query to see the results</p>
|
||||
</div>
|
||||
|
@ -25,6 +25,9 @@ export const useQueryTabStyles = makeStyles({
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
"@media (max-width: 420px)": {
|
||||
overflow: "scroll",
|
||||
},
|
||||
},
|
||||
queryResultsMessage: {
|
||||
...shorthands.margin("5px"),
|
||||
@ -38,6 +41,9 @@ export const useQueryTabStyles = makeStyles({
|
||||
display: "flex",
|
||||
rowGap: "12px",
|
||||
flexDirection: "column",
|
||||
"@media (max-width: 420px)": {
|
||||
height: "auto",
|
||||
},
|
||||
},
|
||||
queryResultsTabContentContainer: {
|
||||
display: "flex",
|
||||
@ -93,4 +99,12 @@ export const useQueryTabStyles = makeStyles({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
},
|
||||
responsiveImg: {
|
||||
"@media (max-width: 420px)": {
|
||||
width: "50px",
|
||||
},
|
||||
},
|
||||
zoomedImageSize: {
|
||||
width: "60px",
|
||||
},
|
||||
});
|
||||
|
@ -21,3 +21,11 @@ export function copyStyles(sourceDoc: Document, targetDoc: Document): void {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally returns a class name based on a boolean condition.
|
||||
* If the condition is true, returns the `trueValue` class; otherwise, returns `falseValue` (or an empty string if not provided).
|
||||
*/
|
||||
export function conditionalClass(condition: boolean, trueValue: string, falseValue?: string): string {
|
||||
return condition ? trueValue : falseValue || "";
|
||||
}
|
||||
|
20
src/hooks/useZoomLevel.ts
Normal file
20
src/hooks/useZoomLevel.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const useZoomLevel = (threshold: number = 2): boolean => {
|
||||
const [isZoomed, setIsZoomed] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const checkZoom = () => {
|
||||
const zoomLevel = window.devicePixelRatio;
|
||||
setIsZoomed(zoomLevel >= threshold);
|
||||
};
|
||||
|
||||
checkZoom();
|
||||
window.addEventListener("resize", checkZoom);
|
||||
return () => window.removeEventListener("resize", checkZoom);
|
||||
}, [threshold]);
|
||||
|
||||
return isZoomed;
|
||||
};
|
||||
|
||||
export default useZoomLevel;
|
Loading…
x
Reference in New Issue
Block a user