Skip to content

2.1.7 fixes. Video Components, OAuth, Navigation #514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1e4f02a
Updated Translations
Nov 20, 2023
e03639f
Updated Section Control
Nov 20, 2023
2e13bff
fix: change oauth url format to allow whole base url
ludomikula Nov 20, 2023
5380655
Broadcast Function including Array Length
Nov 20, 2023
3ae23af
Merge branch 'dev' into agora-integrationn
FalkWolsky Nov 20, 2023
da9515f
Merge pull request #509 from lowcoder-org/agora-integrationn
FalkWolsky Nov 20, 2023
aa9a3e1
new: updated docker build process to use nodejs debian/ubuntu repos
ludomikula Nov 20, 2023
6e1bc05
fix: handle empty itemKeys for sub-menus
raheeliftikhar5 Nov 14, 2023
48e4c71
feat: allow more than 2 levels nested nav
raheeliftikhar5 Nov 14, 2023
ee148f5
feat: make parent menu items clickable
raheeliftikhar5 Nov 14, 2023
8e39c18
feat: added width and background option for nav bar
raheeliftikhar5 Nov 14, 2023
ce51a67
feat: styling option for nav layout
raheeliftikhar5 Nov 16, 2023
4be209b
feat: background-image for nav layout
raheeliftikhar5 Nov 16, 2023
b06fa7e
feat: allow json data for nav layout
raheeliftikhar5 Nov 20, 2023
d3ef400
Updated Documentation Functions
Nov 20, 2023
a3389a4
Merge branch 'dev' into nav-layout-updates
FalkWolsky Nov 20, 2023
f7ec8fd
Merge pull request #510 from raheeliftikhar5/nav-layout-updates
FalkWolsky Nov 20, 2023
7105b92
Fixed OAuth for KeyCloak
Nov 20, 2023
de62a2f
new: use scope provided from frontend
ludomikula Nov 20, 2023
ab89612
Updated Readme
Nov 20, 2023
86b23ef
Updated Readme
Nov 20, 2023
480a4a2
Updated Branding
Nov 20, 2023
f563ca6
added video sharing component and its controls
freddysundowner Nov 21, 2023
b83ae94
Bunch of Frontend Fixes
Nov 21, 2023
39bbd15
Merge branch 'dev' into agora-integrationn
FalkWolsky Nov 21, 2023
c02d325
Merge pull request #513 from lowcoder-org/agora-integrationn
FalkWolsky Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: styling option for nav layout
  • Loading branch information
raheeliftikhar5 committed Nov 20, 2023
commit ce51a678e7a27e5c33e96af6ad9339086c3b1c78
220 changes: 196 additions & 24 deletions client/packages/lowcoder/src/comps/comps/layout/navLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Layout, Menu as AntdMenu, MenuProps } from "antd";
import { Layout, Menu as AntdMenu, MenuProps, Segmented } from "antd";
import MainContent from "components/layout/MainContent";
import { LayoutMenuItemComp, LayoutMenuItemListComp } from "comps/comps/layout/layoutMenuItemComp";
import { menuPropertyView } from "comps/comps/navComp/components/MenuItemList";
Expand All @@ -8,17 +8,47 @@ import { withDispatchHook } from "comps/generators/withDispatchHook";
import { NameAndExposingInfo } from "comps/utils/exposingTypes";
import { ALL_APPLICATIONS_URL } from "constants/routesURL";
import { TopHeaderHeight } from "constants/style";
import { Section, sectionNames } from "lowcoder-design";
import { Section, controlItem, sectionNames } from "lowcoder-design";
import { trans } from "i18n";
import { EditorContainer, EmptyContent } from "pages/common/styledComponent";
import { useCallback, useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import styled, { css } from "styled-components";
import { isUserViewMode, useAppPathParam } from "util/hooks";
import { StringControl } from "comps/controls/codeControl";
import { styleControl } from "comps/controls/styleControl";
import { NavLayoutStyle } from "comps/controls/styleControlConstants";
import {
NavLayoutStyle,
NavLayoutItemStyle,
NavLayoutItemStyleType,
NavLayoutItemHoverStyle,
NavLayoutItemHoverStyleType,
NavLayoutItemActiveStyle,
NavLayoutItemActiveStyleType,
} from "comps/controls/styleControlConstants";
import { dropdownControl } from "comps/controls/dropdownControl";

const DEFAULT_WIDTH = 240;
const ModeOptions = [
{ label: trans("navLayout.modeInline"), value: "inline" },
{ label: trans("navLayout.modeVertical"), value: "vertical" },
] as const;

type MenuItemStyleOptionValue = "normal" | "hover" | "active";

const menuItemStyleOptions = [
{
value: "normal",
label: "Normal",
},
{
value: "hover",
label: "Hover",
},
{
value: "active",
label: "Active",
}
]

const StyledSide = styled(Layout.Sider)`
max-height: calc(100vh - ${TopHeaderHeight});
Expand All @@ -44,34 +74,138 @@ const ContentWrapper = styled.div`
}
`;

const StyledMenu = styled(AntdMenu)<{
$navItemStyle?: NavLayoutItemStyleType & { width: string},
$navItemHoverStyle?: NavLayoutItemHoverStyleType,
$navItemActiveStyle?: NavLayoutItemActiveStyleType,
}>`
.ant-menu-item {
height: auto;
width: ${(props) => props.$navItemStyle?.width};
background-color: ${(props) => props.$navItemStyle?.background};
color: ${(props) => props.$navItemStyle?.text};
border-radius: ${(props) => props.$navItemStyle?.radius} !important;
border: ${(props) => `1px solid ${props.$navItemStyle?.border}`};
margin: ${(props) => props.$navItemStyle?.margin};
padding: ${(props) => props.$navItemStyle?.padding};

}
.ant-menu-item-active {
background-color: ${(props) => props.$navItemHoverStyle?.background} !important;
color: ${(props) => props.$navItemHoverStyle?.text} !important;
border: ${(props) => `1px solid ${props.$navItemHoverStyle?.border}`};
}

.ant-menu-item-selected {
background-color: ${(props) => props.$navItemActiveStyle?.background} !important;
color: ${(props) => props.$navItemActiveStyle?.text} !important;
border: ${(props) => `1px solid ${props.$navItemActiveStyle?.border}`};
}

.ant-menu-submenu {
margin: ${(props) => props.$navItemStyle?.margin};
width: ${(props) => props.$navItemStyle?.width};

.ant-menu-submenu-title {
width: 100%;
height: auto !important;
background-color: ${(props) => props.$navItemStyle?.background};
color: ${(props) => props.$navItemStyle?.text};
border-radius: ${(props) => props.$navItemStyle?.radius} !important;
border: ${(props) => `1px solid ${props.$navItemStyle?.border}`};
margin: 0;
padding: ${(props) => props.$navItemStyle?.padding};

}

.ant-menu-item {
width: 100%;
}

&.ant-menu-submenu-active {
>.ant-menu-submenu-title {
width: 100%;
background-color: ${(props) => props.$navItemHoverStyle?.background} !important;
color: ${(props) => props.$navItemHoverStyle?.text} !important;
border: ${(props) => `1px solid ${props.$navItemHoverStyle?.border}`};
}
}
&.ant-menu-submenu-selected {
>.ant-menu-submenu-title {
width: 100%;
background-color: ${(props) => props.$navItemActiveStyle?.background} !important;
color: ${(props) => props.$navItemActiveStyle?.text} !important;
border: ${(props) => `1px solid ${props.$navItemActiveStyle?.border}`};
}
}
}

`;

const defaultStyle = {
radius: '0px',
margin: '0px',
padding: '0px',
}

let NavTmpLayout = (function () {
const childrenMap = {
items: withDefault(LayoutMenuItemListComp, [
{
label: trans("menuItem") + " 1",
},
]),
width: StringControl,
style: styleControl(NavLayoutStyle),
width: withDefault(StringControl, DEFAULT_WIDTH),
mode: dropdownControl(ModeOptions, "inline"),
navStyle: withDefault(styleControl(NavLayoutStyle), defaultStyle),
navItemStyle: withDefault(styleControl(NavLayoutItemStyle), defaultStyle),
navItemHoverStyle: withDefault(styleControl(NavLayoutItemHoverStyle), {}),
navItemActiveStyle: withDefault(styleControl(NavLayoutItemActiveStyle), {}),
};
return new MultiCompBuilder(childrenMap, (props) => {
return null;
})
.setPropertyViewFn((children) => {
const [styleSegment, setStyleSegment] = useState('normal')

return (
<>
<div style={{overflowY: 'auto'}}>
<Section name={trans("menu")}>{menuPropertyView(children.items)}</Section>
<Section name={sectionNames.layout}>
{ children.width.propertyView({
label: trans("drawer.width"),
tooltip: trans("drawer.widthTooltip"),
label: trans("navLayout.width"),
tooltip: trans("navLayout.widthTooltip"),
placeholder: DEFAULT_WIDTH + "",
})}
})}
{ children.mode.propertyView({
label: trans("labelProp.position"),
radioButton: true
})}
</Section>
<Section name={sectionNames.style}>
{ children.style.getPropertyView() }
<Section name={trans("navLayout.navStyle")}>
{ children.navStyle.getPropertyView() }
</Section>
</>
<Section name={trans("navLayout.navItemStyle")}>
{controlItem({}, (
<Segmented
block
options={menuItemStyleOptions}
value={styleSegment}
// className="comp-panel-tab"
onChange={(k) => setStyleSegment(k as MenuItemStyleOptionValue)}
/>
))}
{styleSegment === 'normal' && (
children.navItemStyle.getPropertyView()
)}
{styleSegment === 'hover' && (
children.navItemHoverStyle.getPropertyView()
)}
{styleSegment === 'active' && (
children.navItemActiveStyle.getPropertyView()
)}
</Section>
</div>
);
})
.build();
Expand All @@ -82,13 +216,19 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
const isViewMode = isUserViewMode(pathParam);
const [selectedKey, setSelectedKey] = useState("");
const items = useMemo(() => comp.children.items.getView(), [comp.children.items]);

const navWidth = useMemo(() => comp.children.width.getView(), [comp.children.width]);
const navMode = useMemo(() => comp.children.mode.getView(), [comp.children.mode]);
const navStyle = useMemo(() => comp.children.navStyle.getView(), [comp.children.navStyle]);
const navItemStyle = useMemo(() => comp.children.navItemStyle.getView(), [comp.children.navItemStyle]);
const navItemHoverStyle = useMemo(() => comp.children.navItemHoverStyle.getView(), [comp.children.navItemHoverStyle]);
const navItemActiveStyle = useMemo(() => comp.children.navItemActiveStyle.getView(), [comp.children.navItemActiveStyle]);
console.log(navItemActiveStyle);
// filter out hidden. unauthorised items filtered by server
const filterItem = useCallback((item: LayoutMenuItemComp): boolean => {
return !item.children.hidden.getView();
}, []);

const generateItemKeyRecord = useCallback((items: LayoutMenuItemComp[]) => {
const generateItemKeyRecord = (items: LayoutMenuItemComp[]) => {
const result: Record<string, LayoutMenuItemComp> = {};
items.forEach((item) => {
const subItems = item.children.items.getView();
Expand All @@ -98,13 +238,13 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
result[item.getItemKey()] = item;
});
return result;
}, [items])
}

const itemKeyRecord = useMemo(() => {
return generateItemKeyRecord(items)
}, [generateItemKeyRecord, items]);
}, [items]);

const onMenuItemClick = ({key}: {key: string}) => {
const onMenuItemClick = useCallback(({key}: {key: string}) => {
const itemComp = itemKeyRecord[key];
const url = [
ALL_APPLICATIONS_URL,
Expand All @@ -113,7 +253,7 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
itemComp.getItemKey(),
].join("/");
itemComp.children.action.act(url);
}
}, [pathParam.applicationId, pathParam.viewMode, itemKeyRecord])

const getMenuItem = useCallback(
(itemComps: LayoutMenuItemComp[]): MenuProps["items"] => {
Expand All @@ -131,7 +271,7 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
};
});
},
[filterItem]
[onMenuItemClick, filterItem]
);

const menuItems = useMemo(() => getMenuItem(items), [items, getMenuItem]);
Expand Down Expand Up @@ -210,15 +350,47 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
}
}

const getVerticalMargin = (margin: string[]) => {
if(margin.length === 1) return `${margin[0]}`;
if(margin.length === 2) return `(${margin[0]} + ${margin[0]})`;
if(margin.length === 3 || margin.length === 4)
return `(${margin[0]} + ${margin[2]})`;

return '0px';
}
const getHorizontalMargin = (margin: string[]) => {
if(margin.length === 1) return `(${margin[0]} + ${margin[0]})`;
if(margin.length === 2) return `(${margin[1]} + ${margin[1]})`;
if(margin.length === 3 || margin.length === 4)
return `(${margin[1]} + ${margin[3]})`;

return '0px';
}

let content = (
<Layout>
<StyledSide theme="light" width={DEFAULT_WIDTH}>
<AntdMenu
<StyledSide theme="light" width={navWidth}>
<StyledMenu
items={menuItems}
mode="inline"
style={{ height: "100%" }}
mode={navMode}
style={{
height: `calc(100% - ${getVerticalMargin(navStyle.margin.split(' '))})`,
width: `calc(100% - ${getHorizontalMargin(navStyle.margin.split(' '))})`,
borderRadius: navStyle.radius,
color: navStyle.text,
margin: navStyle.margin,
padding: navStyle.padding,
background: navStyle.background,
borderRight: `1px solid ${navStyle.border}`,
}}
defaultOpenKeys={defaultOpenKeys}
selectedKeys={[selectedKey]}
$navItemStyle={{
width: `calc(100% - ${getHorizontalMargin(navItemStyle.margin.split(' '))})`,
...navItemStyle
}}
$navItemHoverStyle={navItemHoverStyle}
$navItemActiveStyle={navItemActiveStyle}
/>
</StyledSide>
<MainContent>{pageView}</MainContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,7 @@ export const TreeStyle = [

export const TreeSelectStyle = [...multiSelectCommon, ...ACCENT_VALIDATE] as const;

export const DrawerStyle = [getBackground()] as const;

export const NavLayoutStyle = [getBackground()] as const;
export const DrawerStyle = [getBackground()] as const

export const JsonEditorStyle = [LABEL] as const;

Expand Down Expand Up @@ -930,6 +928,59 @@ export const ResponsiveLayoutColStyle = [
PADDING,
] as const;

export const NavLayoutStyle = [
...getBgBorderRadiusByBg(),
{
name: "text",
label: trans("text"),
depName: "background",
// depTheme: "primary",
depType: DEP_TYPE.CONTRAST_TEXT,
transformer: contrastText,
},
MARGIN,
PADDING,
] as const;

export const NavLayoutItemStyle = [
getBackground("primarySurface"),
getStaticBorder('transparent'),
RADIUS,
{
name: "text",
label: trans("text"),
depName: "background",
depType: DEP_TYPE.CONTRAST_TEXT,
transformer: contrastText,
},
MARGIN,
PADDING,
] as const;

export const NavLayoutItemHoverStyle = [
getBackground("canvas"),
getStaticBorder('transparent'),
{
name: "text",
label: trans("text"),
depName: "background",
depType: DEP_TYPE.CONTRAST_TEXT,
transformer: contrastText,
},
] as const;

export const NavLayoutItemActiveStyle = [
getBackground("primary"),
getStaticBorder('transparent'),
{
name: "text",
label: trans("text"),
depName: "background",
depType: DEP_TYPE.CONTRAST_TEXT,
transformer: contrastText,
},
] as const;

export const CarouselStyle = [getBackground("canvas")] as const;

export const RichTextEditorStyle = [getStaticBorder(), RADIUS] as const;
Expand Down Expand Up @@ -970,6 +1021,10 @@ export type CarouselStyleType = StyleConfigType<typeof CarouselStyle>;
export type RichTextEditorStyleType = StyleConfigType<typeof RichTextEditorStyle>;
export type ResponsiveLayoutRowStyleType = StyleConfigType<typeof ResponsiveLayoutRowStyle>;
export type ResponsiveLayoutColStyleType = StyleConfigType<typeof ResponsiveLayoutColStyle>;
export type NavLayoutStyleType = StyleConfigType<typeof NavLayoutStyle>;
export type NavLayoutItemStyleType = StyleConfigType<typeof NavLayoutItemStyle>;
export type NavLayoutItemHoverStyleType = StyleConfigType<typeof NavLayoutItemHoverStyle>;
export type NavLayoutItemActiveStyleType = StyleConfigType<typeof NavLayoutItemActiveStyle>;

export function widthCalculator(margin: string) {
const marginArr = margin?.trim().replace(/\s+/g,' ').split(" ") || "";
Expand Down
Loading