chore: Split library side pane for adding package control section (#36926)
## Description Purpose of this PR is to split the Libraries section to extend it in EE and introduced a tab layout that has both js libraries and packages Changes: 1. Increased width of Libraries pane to 384px 2. Added a route `/package` which opens the same as library 3. Extracted the JSLibraries section to be reused as a tab panel body in EE 4. Created `SidePaneWrapper` common component to be reused in EE 5. Split the title of the Libraries section under a hook to return empty string if package feature flag is enabled. 6. Minor linting refactors. In CE there is only one visual change i.e the increase in width of the Libraries side pane from 250px to 384px [Figma](https://www.figma.com/design/Z0QsSdGOydURn6WIMQ3rHM/Appsmith-Reusability?node-id=6816-319511&node-type=frame&t=x0DzN9HIxjefe3J1-0) PR for https://github.com/appsmithorg/appsmith-ee/pull/5362 ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/11434291701> > Commit: ec76cc569ea90ba55e451f5ab18fa85244ac076f > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11434291701&attempt=3" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Mon, 21 Oct 2024 08:54:31 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced new functions for constructing URLs for application libraries and packages. - Added new route constants and matching functions for improved routing of application packages and libraries. - Implemented a custom hook for dynamic header titles in the libraries section. - Added a new `LibrarySidePane` component to enhance the editor interface. - Introduced a new `SidePaneWrapper` component for better layout management. - **Bug Fixes** - Enhanced entity identification logic to recognize both libraries and packages. - **Chores** - Updated routing logic for improved maintainability. - Added constants for configurable UI component widths. These updates aim to enhance user experience and improve the overall functionality of the application. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
1f72d758c0
commit
67046f8693
29
app/client/src/IDE/Components/SidePaneWrapper.tsx
Normal file
29
app/client/src/IDE/Components/SidePaneWrapper.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { Flex } from "@appsmith/ads";
|
||||
import React from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
interface SidePaneContainerProps {
|
||||
children?: ReactNode;
|
||||
padded?: boolean;
|
||||
}
|
||||
|
||||
const StyledContainer = styled(Flex)<Pick<SidePaneContainerProps, "padded">>`
|
||||
padding: ${({ padded }) => padded && "var(--ads-v2-spaces-2)"};
|
||||
`;
|
||||
|
||||
function SidePaneWrapper({ children, padded = false }: SidePaneContainerProps) {
|
||||
return (
|
||||
<StyledContainer
|
||||
borderRight="1px solid var(--ads-v2-color-border)"
|
||||
flexDirection="column"
|
||||
height="100%"
|
||||
padded={padded}
|
||||
width={"100%"}
|
||||
>
|
||||
{children}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default SidePaneWrapper;
|
||||
|
|
@ -54,6 +54,11 @@ export { default as IDEBottomView } from "./Components/BottomView";
|
|||
* It switches between different editor states
|
||||
*/
|
||||
export { default as IDESidebar } from "./Components/Sidebar";
|
||||
/**
|
||||
* IDESidePaneWrapper is used as a wrapper for side panes, which provides a border and optional padding
|
||||
* and enforces 100% width and height to the parent.
|
||||
*/
|
||||
export { default as IDESidePaneWrapper } from "./Components/SidePaneWrapper";
|
||||
|
||||
/**
|
||||
* ToolbarSettingsPopover is a popover attached to a settings toggle button in the toolbar
|
||||
|
|
|
|||
|
|
@ -204,3 +204,12 @@ export const queryAddURL = (props: URLBuilderParams): string =>
|
|||
...props,
|
||||
suffix: `queries/add`,
|
||||
});
|
||||
|
||||
export const appLibrariesURL = (): string =>
|
||||
urlBuilder.build({
|
||||
suffix: "libraries",
|
||||
});
|
||||
export const appPackagesURL = (): string =>
|
||||
urlBuilder.build({
|
||||
suffix: "packages",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ export const JS_COLLECTION_ID_ADD_PATH = `${JS_COLLECTION_EDITOR_PATH}/:baseColl
|
|||
export const DATA_SOURCES_EDITOR_LIST_PATH = `/datasource`;
|
||||
export const DATA_SOURCES_EDITOR_ID_PATH = `/datasource/:datasourceId`;
|
||||
export const APP_LIBRARIES_EDITOR_PATH = `/libraries`;
|
||||
export const APP_PACKAGES_EDITOR_PATH = `/packages`;
|
||||
export const APP_SETTINGS_EDITOR_PATH = `/settings`;
|
||||
export const SAAS_GSHEET_EDITOR_ID_PATH = `/saas/google-sheets-plugin/datasources/:datasourceId`;
|
||||
export const GEN_TEMPLATE_URL = "generate-page";
|
||||
|
|
@ -128,6 +129,12 @@ export const matchGeneratePagePath = (pathName: string) =>
|
|||
match(`${BUILDER_CUSTOM_PATH}${GENERATE_TEMPLATE_FORM_PATH}`)(pathName) ||
|
||||
match(`${BUILDER_PATH_DEPRECATED}${GENERATE_TEMPLATE_FORM_PATH}`)(pathName);
|
||||
|
||||
export const matchAppLibrariesPath = (pathName: string) =>
|
||||
match(`${BUILDER_PATH}${APP_LIBRARIES_EDITOR_PATH}`)(pathName);
|
||||
|
||||
export const matchAppPackagesPath = (pathName: string) =>
|
||||
match(`${BUILDER_PATH}${APP_PACKAGES_EDITOR_PATH}`)(pathName);
|
||||
|
||||
export const addBranchParam = (branch: string) => {
|
||||
const url = new URL(window.location.href);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export const getPageDependencyActions = (
|
|||
currentWorkspaceId: string = "",
|
||||
featureFlags: DependentFeatureFlags = {},
|
||||
allResponses: EditConsolidatedApi,
|
||||
applicationId: string,
|
||||
) => {
|
||||
const { datasources, pagesWithMigratedDsl, plugins } = allResponses || {};
|
||||
const initActions = [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import { createMessage, HEADER_TITLES } from "ee/constants/messages";
|
||||
|
||||
/**
|
||||
* In CE this returns a simple text as title but this
|
||||
* hook is extended in EE where based on feature flags
|
||||
* the title changes
|
||||
*/
|
||||
function useLibraryHeaderTitle() {
|
||||
return createMessage(HEADER_TITLES.LIBRARIES);
|
||||
}
|
||||
|
||||
export default useLibraryHeaderTitle;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import React from "react";
|
||||
import JSLibrariesSection from "pages/Editor/IDE/LeftPane/JSLibrariesSection";
|
||||
import { IDESidePaneWrapper } from "IDE";
|
||||
|
||||
const LibrarySidePane = () => {
|
||||
return (
|
||||
<IDESidePaneWrapper>
|
||||
<JSLibrariesSection />
|
||||
</IDESidePaneWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default LibrarySidePane;
|
||||
|
|
@ -4,6 +4,7 @@ import {
|
|||
API_EDITOR_ID_ADD_PATH,
|
||||
API_EDITOR_ID_PATH,
|
||||
APP_LIBRARIES_EDITOR_PATH,
|
||||
APP_PACKAGES_EDITOR_PATH,
|
||||
APP_SETTINGS_EDITOR_PATH,
|
||||
BUILDER_CHECKLIST_PATH,
|
||||
BUILDER_CUSTOM_PATH,
|
||||
|
|
@ -82,6 +83,7 @@ function useRoutes(path: string): RouteReturnType[] {
|
|||
`${path}${SAAS_EDITOR_API_ID_PATH}`,
|
||||
`${path}${SAAS_EDITOR_API_ID_ADD_PATH}`,
|
||||
`${path}${APP_LIBRARIES_EDITOR_PATH}`,
|
||||
`${path}${APP_PACKAGES_EDITOR_PATH}`,
|
||||
`${path}${APP_SETTINGS_EDITOR_PATH}`,
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export const CANVAS_DEFAULT_MIN_ROWS = Math.ceil(
|
|||
export const DEFAULT_ENTITY_EXPLORER_WIDTH = 256;
|
||||
export const DEFAULT_PROPERTY_PANE_WIDTH = 288;
|
||||
export const APP_SETTINGS_PANE_WIDTH = 525;
|
||||
export const APP_LIBRARIES_PANE_WIDTH = 384;
|
||||
export const DEFAULT_EXPLORER_PANE_WIDTH = 255;
|
||||
export const SPLIT_SCREEN_RATIO = 0.404;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
export * from "ce/pages/Editor/IDE/Header/useLibraryHeaderTitle";
|
||||
import { default as CE_useLibraryHeaderTitle } from "ce/pages/Editor/IDE/Header/useLibraryHeaderTitle";
|
||||
export default CE_useLibraryHeaderTitle;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export * from "ce/pages/Editor/IDE/LeftPane/LibrarySidePane";
|
||||
import { default as CE_LibrarySidePane } from "ce/pages/Editor/IDE/LeftPane/LibrarySidePane";
|
||||
export default CE_LibrarySidePane;
|
||||
|
|
@ -199,6 +199,7 @@ export default class AppEditorEngine extends AppEngine {
|
|||
private *loadPluginsAndDatasources(
|
||||
allResponses: EditConsolidatedApi,
|
||||
rootSpan: Span,
|
||||
applicationId: string,
|
||||
) {
|
||||
const loadPluginsAndDatasourcesSpan = startNestedSpan(
|
||||
"AppEditorEngine.loadPluginsAndDatasources",
|
||||
|
|
@ -211,7 +212,12 @@ export default class AppEditorEngine extends AppEngine {
|
|||
getFeatureFlagsForEngine,
|
||||
);
|
||||
const { errorActions, initActions, successActions } =
|
||||
getPageDependencyActions(currentWorkspaceId, featureFlags, allResponses);
|
||||
getPageDependencyActions(
|
||||
currentWorkspaceId,
|
||||
featureFlags,
|
||||
allResponses,
|
||||
applicationId,
|
||||
);
|
||||
|
||||
if (!isAirgappedInstance) {
|
||||
initActions.push(fetchMockDatasources(mockDatasources));
|
||||
|
|
@ -259,7 +265,12 @@ export default class AppEditorEngine extends AppEngine {
|
|||
allResponses,
|
||||
rootSpan,
|
||||
);
|
||||
yield call(this.loadPluginsAndDatasources, allResponses, rootSpan);
|
||||
yield call(
|
||||
this.loadPluginsAndDatasources,
|
||||
allResponses,
|
||||
rootSpan,
|
||||
applicationId,
|
||||
);
|
||||
}
|
||||
|
||||
public *completeChore(rootSpan: Span) {
|
||||
|
|
|
|||
|
|
@ -278,7 +278,10 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo {
|
|||
}
|
||||
|
||||
if (match.params.entity) {
|
||||
if (match.params.entity === "libraries") {
|
||||
if (
|
||||
match.params.entity === "libraries" ||
|
||||
match.params.entity === "packages"
|
||||
) {
|
||||
return {
|
||||
entity: FocusEntity.LIBRARY,
|
||||
id: "",
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ import type { Page } from "entities/Page";
|
|||
import { IDEHeader, IDEHeaderTitle } from "IDE";
|
||||
import { APPLICATIONS_URL } from "constants/routes";
|
||||
import { useNavigationMenuData } from "../../EditorName/useNavigationMenuData";
|
||||
import useLibraryHeaderTitle from "ee/pages/Editor/IDE/Header/useLibraryHeaderTitle";
|
||||
|
||||
const StyledDivider = styled(Divider)`
|
||||
height: 50%;
|
||||
|
|
@ -92,6 +93,8 @@ interface HeaderTitleProps {
|
|||
}
|
||||
|
||||
const HeaderTitleComponent = ({ appState, currentPage }: HeaderTitleProps) => {
|
||||
const libraryHeaderTitle = useLibraryHeaderTitle();
|
||||
|
||||
switch (appState) {
|
||||
case EditorState.DATA:
|
||||
return (
|
||||
|
|
@ -110,12 +113,7 @@ const HeaderTitleComponent = ({ appState, currentPage }: HeaderTitleProps) => {
|
|||
/>
|
||||
);
|
||||
case EditorState.LIBRARIES:
|
||||
return (
|
||||
<IDEHeaderTitle
|
||||
key={appState}
|
||||
title={createMessage(HEADER_TITLES.LIBRARIES)}
|
||||
/>
|
||||
);
|
||||
return <IDEHeaderTitle key={appState} title={libraryHeaderTitle} />;
|
||||
default:
|
||||
return <EditorTitle key={appState} title={currentPage?.pageName || ""} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import {
|
|||
import {
|
||||
APP_SETTINGS_PANE_WIDTH,
|
||||
APP_SIDEBAR_WIDTH,
|
||||
APP_LIBRARIES_PANE_WIDTH,
|
||||
} from "constants/AppConstants";
|
||||
import { useEditorStateLeftPaneWidth } from "./useEditorStateLeftPaneWidth";
|
||||
import { type Area, Areas, SIDEBAR_WIDTH } from "../constants";
|
||||
|
|
@ -97,10 +98,10 @@ function useGridLayoutTemplate(): ReturnValue {
|
|||
} else {
|
||||
setColumns([
|
||||
SIDEBAR_WIDTH,
|
||||
"255px",
|
||||
`${APP_LIBRARIES_PANE_WIDTH}px`,
|
||||
(windowWidth -
|
||||
APP_SIDEBAR_WIDTH -
|
||||
255 +
|
||||
APP_LIBRARIES_PANE_WIDTH +
|
||||
"px") as AnimatedGridUnit,
|
||||
"0px",
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import React from "react";
|
||||
import AddLibraryPopover from "./AddLibraryPopover";
|
||||
import PaneHeader from "./PaneHeader";
|
||||
import { useSelector } from "react-redux";
|
||||
import React, { useMemo } from "react";
|
||||
|
||||
import PaneHeader from "pages/Editor/IDE/LeftPane/PaneHeader";
|
||||
import AddLibraryPopover from "pages/Editor/IDE/LeftPane/AddLibraryPopover";
|
||||
import { selectLibrariesForExplorer } from "ee/selectors/entitiesSelector";
|
||||
import { useSelector } from "react-redux";
|
||||
import { animated, useTransition } from "react-spring";
|
||||
import { LibraryEntity } from "pages/Editor/Explorer/Libraries";
|
||||
import { Flex } from "@appsmith/ads";
|
||||
|
||||
const LibrarySidePane = () => {
|
||||
function JSLibrariesSection() {
|
||||
const libraries = useSelector(selectLibrariesForExplorer);
|
||||
const transitions = useTransition(libraries, {
|
||||
keys: (lib) => lib.name,
|
||||
|
|
@ -16,24 +16,18 @@ const LibrarySidePane = () => {
|
|||
leave: { opacity: 1 },
|
||||
});
|
||||
|
||||
const rightIcon = useMemo(() => <AddLibraryPopover />, []);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
borderRight="1px solid var(--ads-v2-color-border)"
|
||||
flexDirection="column"
|
||||
height="100%"
|
||||
width={"100%"}
|
||||
>
|
||||
<PaneHeader
|
||||
rightIcon={<AddLibraryPopover />}
|
||||
title="Installed Libraries"
|
||||
/>
|
||||
<>
|
||||
<PaneHeader rightIcon={rightIcon} title="Installed Libraries" />
|
||||
{transitions((style, lib) => (
|
||||
<animated.div style={style}>
|
||||
<LibraryEntity lib={lib} />
|
||||
</animated.div>
|
||||
))}
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default LibrarySidePane;
|
||||
export default JSLibrariesSection;
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
import React from "react";
|
||||
import React, { useMemo } from "react";
|
||||
import styled from "styled-components";
|
||||
import { Switch, useRouteMatch } from "react-router";
|
||||
import { SentryRoute } from "ee/AppRouter";
|
||||
import {
|
||||
APP_LIBRARIES_EDITOR_PATH,
|
||||
APP_PACKAGES_EDITOR_PATH,
|
||||
APP_SETTINGS_EDITOR_PATH,
|
||||
DATA_SOURCES_EDITOR_ID_PATH,
|
||||
DATA_SOURCES_EDITOR_LIST_PATH,
|
||||
|
|
@ -12,8 +13,8 @@ import {
|
|||
} from "constants/routes";
|
||||
import AppSettingsPane from "./AppSettings";
|
||||
import DataSidePane from "./DataSidePane";
|
||||
import LibrarySidePane from "./LibrarySidePane";
|
||||
import EditorPane from "../EditorPane";
|
||||
import LibrarySidePane from "ee/pages/Editor/IDE/LeftPane/LibrarySidePane";
|
||||
|
||||
export const LeftPaneContainer = styled.div<{ showRightBorder?: boolean }>`
|
||||
height: 100%;
|
||||
|
|
@ -26,23 +27,32 @@ export const LeftPaneContainer = styled.div<{ showRightBorder?: boolean }>`
|
|||
const LeftPane = () => {
|
||||
const { path } = useRouteMatch();
|
||||
|
||||
const dataSidePanePaths = useMemo(
|
||||
() => [
|
||||
`${path}${DATA_SOURCES_EDITOR_LIST_PATH}`,
|
||||
`${path}${DATA_SOURCES_EDITOR_ID_PATH}`,
|
||||
`${path}${INTEGRATION_EDITOR_PATH}`,
|
||||
`${path}${SAAS_GSHEET_EDITOR_ID_PATH}`,
|
||||
],
|
||||
[path],
|
||||
);
|
||||
|
||||
const librarySidePanePaths = useMemo(
|
||||
() => [
|
||||
`${path}${APP_LIBRARIES_EDITOR_PATH}`,
|
||||
`${path}${APP_PACKAGES_EDITOR_PATH}`,
|
||||
],
|
||||
[path],
|
||||
);
|
||||
|
||||
return (
|
||||
<LeftPaneContainer showRightBorder={false}>
|
||||
<Switch>
|
||||
<SentryRoute
|
||||
component={DataSidePane}
|
||||
exact
|
||||
path={[
|
||||
`${path}${DATA_SOURCES_EDITOR_LIST_PATH}`,
|
||||
`${path}${DATA_SOURCES_EDITOR_ID_PATH}`,
|
||||
`${path}${INTEGRATION_EDITOR_PATH}`,
|
||||
`${path}${SAAS_GSHEET_EDITOR_ID_PATH}`,
|
||||
]}
|
||||
/>
|
||||
<SentryRoute component={DataSidePane} exact path={dataSidePanePaths} />
|
||||
<SentryRoute
|
||||
component={LibrarySidePane}
|
||||
exact
|
||||
path={`${path}${APP_LIBRARIES_EDITOR_PATH}`}
|
||||
path={librarySidePanePaths}
|
||||
/>
|
||||
<SentryRoute
|
||||
component={AppSettingsPane}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user