@ovine/core
Version:
Build flexible admin system with json.
118 lines (117 loc) • 5.22 kB
JavaScript
/**
* TODO:
* 1. 将预先设置的 HerderItem 项,都拆为独立组件,可以独自放于任何地方
*/
import { uuid } from 'amis/lib/utils/helper';
import { get, map } from 'lodash';
import React, { useMemo } from 'react';
import { createPortal } from 'react-dom';
import { Link } from 'react-router-dom';
import { message } from "../../constants";
import { publish } from "../../utils/message";
import { Amis } from "../amis/schema";
import HeadItem from "./head_item";
import ItemCode from "./item_code";
import ItemSearch from "./item_search";
import ItemSetting from "./item_setting";
export default (props) => {
const { asideFolded, withRouteTabs, themeNs, children, brand, items = [] } = props;
const renderBrand = () => {
const { logo, title, link, className: brandCls = '' } = brand;
const wrapperCls = `${themeNs}Layout-brand navbar-brand text-center ${brandCls}`;
const content = (React.createElement(React.Fragment, null,
React.createElement("img", { className: " brand-logo", src: logo, alt: "logo" }),
React.createElement("span", { className: "hidden-folded m-l-sm " }, title)));
if (!link) {
return React.createElement("div", { className: wrapperCls }, content);
}
return (React.createElement(Link, { className: wrapperCls, to: link.href, title: link.title }, content));
};
// 由于布局 z-index 冲突,导致菜单在收缩状态下,会被侧边栏图标遮挡
const renderBrandHolder = () => {
return createPortal(React.createElement("div", { className: "navbar-brand-holder" },
React.createElement("img", { src: brand === null || brand === void 0 ? void 0 : brand.logo, alt: "logo" })), $('#app-layout>div').get(0));
};
const renderFoldItem = () => {
const asideItemProps = {
faIcon: asideFolded ? 'indent' : 'dedent',
tip: `${asideFolded ? '展开' : '收起'}侧边栏`,
onClick: () => publish(message.asideLayoutCtrl.msg, {
key: message.asideLayoutCtrl.toggleFold,
}),
};
return React.createElement(HeadItem, { itemProps: asideItemProps });
};
const headerItems = useMemo(() => {
const itemsSchema = {
type: 'page',
role: 'header',
body: {
type: 'wrapper',
component: (renderProps) => (React.createElement(HeadItems, Object.assign({ renderFoldItem: renderFoldItem, items: items }, renderProps))),
},
};
return React.createElement(Amis, { key: uuid(), schema: itemsSchema });
}, [items, themeNs]);
return (React.createElement(React.Fragment, null,
React.createElement("div", { className: `${themeNs}Layout-brandBar navbar-dark` },
React.createElement("button", { className: "navbar-toggler d-block d-sm-none float-right", type: "button", onClick: () => publish(message.asideLayoutCtrl.msg, {
key: message.asideLayoutCtrl.toggleScreen,
}) },
React.createElement("span", { className: "navbar-toggler-icon" })),
withRouteTabs && brand && asideFolded && renderBrandHolder(),
brand && renderBrand()),
React.createElement("div", { className: `${themeNs}Layout-headerBar navbar navbar-expand-md` },
headerItems,
children)));
};
const presetComponents = {
'head-item': HeadItem,
'item-search-menu': ItemSearch,
'item-setting': ItemSetting,
'item-dev-code': ItemCode,
};
const ItemComponent = (props) => {
const { render, item } = props;
const getPresetComponent = (i) => {
let preset = null;
map(presetComponents, (Component, type) => {
if (i === type || get(i, 'type') === type) {
preset = (renderProps) => React.createElement(Component, Object.assign({}, renderProps, { itemProps: item }));
}
});
return preset;
};
const preset = getPresetComponent(item);
if (!preset) {
return render('body', item);
}
return render('body', {
type: 'wrapper',
component: preset,
});
};
function HeadItems(props) {
const { items: propItems, render, renderFoldItem } = props;
const items = useMemo(() => {
const lefts = [];
const rights = [];
propItems.forEach((item) => {
if (get(item, 'align') === 'right') {
rights.push(item);
}
else {
lefts.push(item);
}
});
return {
lefts: lefts.map((item, index) => React.createElement(ItemComponent, { key: index, render: render, item: item })),
rights: rights.map((item, index) => (React.createElement(ItemComponent, { key: index, render: render, item: item }))),
};
}, [propItems]);
return (React.createElement("div", { className: "collapse navbar-collapse" },
React.createElement("div", { className: "navbar-nav mr-auto" },
React.createElement("div", { className: "head-item-fold d-flex" }, renderFoldItem()),
items.lefts),
items.rights));
}