Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions web/packages/axios/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import type {
ResponseType
} from './type';

axios.defaults.withCredentials = true;

function createCommonRequest<ResponseData = any>(
axiosConfig?: CreateAxiosDefaults,
options?: Partial<RequestOption<ResponseData>>
Expand Down
4 changes: 2 additions & 2 deletions web/packages/utils/src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import localforage from 'localforage';
/** The storage type */
export type StorageType = 'local' | 'session';

export function createStorage<T extends object>(type: StorageType, storagePrefix: string) {
const stg = type === 'session' ? window.sessionStorage : window.localStorage;
export function createStorage<T extends object>(type: StorageType, storagePrefix: string, proxy?: any) {
const stg = proxy ? proxy : (type === 'session' ? window.sessionStorage : window.localStorage);

const storage = {
clear() {
Expand Down
11 changes: 9 additions & 2 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { WatermarkProps } from 'antd';

import { info } from '@/constants/app';
import { router } from '@/router';
import { getLocale } from '@/store/slice/app';
import { changeLocale, getLocale } from '@/store/slice/app';
import { getDarkMode, getThemeSettings, themeColors } from '@/store/slice/theme';
import { getAntdTheme, setupThemeVarsToHtml, toggleCssDarkMode } from '@/store/slice/theme/shared';
import { localStg } from '@/utils/storage';
Expand Down Expand Up @@ -48,6 +48,13 @@ const App = () => {
const locale = useAppSelector(getLocale);

const { antdTheme, themeSettings } = useTheme();
const dispatch = useAppDispatch();

useEffect(() => {
if (window.$wujie?.props?.locale) {
dispatch(changeLocale(window.$wujie?.props?.locale));
}
}, [window.$wujie?.props?.locale]);

return (
<AConfigProvider
Expand All @@ -63,7 +70,7 @@ const App = () => {
{...watermarkProps}
>
<RouterProvider
fallback={<GlobalLoading />}
fallback={<GlobalLoading className={window.__POWERED_BY_WUJIE__ ? 'absolute' : ''} />}
router={router}
/>
</AWatermark>
Expand Down
2 changes: 2 additions & 0 deletions web/src/assets/svg-icon/folder.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions web/src/assets/svg-icon/home.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions web/src/assets/svg-icon/puzzle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions web/src/assets/svg-icon/robot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions web/src/assets/svg-icon/settings.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions web/src/components/common/icon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import React from 'react';

import FontIcon from '@/components/common/font_icon';

const Icon = ({ className, src, style, ...rest }) => {
import normalizeUrl from 'normalize-url';
import { getProxyEndpoint } from '@/components/micro/utils'

const Icon = ({ className, src, style, server, ...rest }) => {
if (!src) {
return null;
}
Expand All @@ -17,9 +20,13 @@ const Icon = ({ className, src, style, ...rest }) => {
/>
);
}
let formatSrc = src
if (!src.startsWith('http')) {
formatSrc = normalizeUrl(`${getProxyEndpoint() || server}/${src}`)
}
return (
<Image
src={src}
src={formatSrc}
style={style}
{...rest}
preview={false}
Expand Down
55 changes: 55 additions & 0 deletions web/src/components/micro/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export function setupMicro(root, renderRoot) {

window.__WUJIE_MOUNT = () => {
renderRoot(root)
};
window.__WUJIE_UNMOUNT = () => {
root.unmount()
};
window.__WUJIE.mount()

setupIcons();
setupHistoryHooks();
}

function setupIcons() {
const parentDoc = window.$wujie?.props?.parentDocument;
if (!parentDoc) return;

const existingMicroIcon = parentDoc.getElementById('__MICRO__SVG_ICON_LOCAL__');
if (existingMicroIcon) return;

const sourceIcon = document.getElementById('__SVG_ICON_LOCAL__');
if (!sourceIcon) return;

const clonedIcon = sourceIcon.cloneNode(true) as any;
clonedIcon.id = '__MICRO__SVG_ICON_LOCAL__';

parentDoc.body.appendChild(clonedIcon);
}

function setupHistoryHooks() {
let lastUrl = window.location.href;

function handleUrlChange() {
const currentUrl = window.location.href;
if (currentUrl !== lastUrl) {
lastUrl = currentUrl;
window.$wujie?.props?.onRouteChange({
url: currentUrl,
})
}
}

const originalPushState = window.history.pushState;
window.history.pushState = function(...args) {
originalPushState.apply(this, args);
handleUrlChange();
};

const originalReplaceState = window.history.replaceState;
window.history.replaceState = function(...args) {
originalReplaceState.apply(this, args);
handleUrlChange();
};
}
12 changes: 12 additions & 0 deletions web/src/components/micro/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function getEndpoint() {
return window.__POWERED_BY_WUJIE__ && window.$wujie?.props?.endpoint ? window.$wujie?.props?.endpoint : window.location.origin;
}

export function getProxyEndpoint() {
const proxy = window.__POWERED_BY_WUJIE__ ? window.$wujie?.props?.proxy_endpoint : ''
return proxy
}

export function getName(name: string) {
return window.__POWERED_BY_WUJIE__ && window.$wujie?.props?.name ? window.$wujie?.props?.name : name;
}
6 changes: 3 additions & 3 deletions web/src/components/stateless/common/GlobalLoading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ const loadingClasses = [
'right-0 bottom-0 animate-delay-1500'
];

const GlobalLoading = memo(() => {
const { t } = useTranslation();
const GlobalLoading = memo((props: any) => {
const { className } = props;
const darkMode = useAppSelector(getDarkMode);

return (
<div className="fixed-center flex-col bg-[rgb(var(--layout-bg-color))]">
<div className={`fixed-center flex-col bg-[rgb(var(--layout-bg-color))] ${className}`}>
{darkMode ? (
<div className="h-128px w-320px">
<DarkSystemLogo />
Expand Down
17 changes: 14 additions & 3 deletions web/src/layouts/base-layout/BaseLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import GlobalHeader from '../modules/global-header';
import GlobalMenu from '../modules/global-menu';
import GlobalSider from '../modules/global-sider';
import GlobalTab from '../modules/global-tab';
import { logout } from '@/service/api';

const ThemeDrawer = lazy(() => import('../modules/theme-drawer'));

Expand All @@ -36,6 +37,7 @@ const BaseLayout = () => {
const fullContent = useAppSelector(getFullContent);
const dispatch = useAppDispatch();
const responsive = useResponsive();
const nav = useNavigate()
const { childLevelMenus, isActiveFirstLevelMenuHasChildren } = useMixMenuContext();

const contentXScrollable = useAppSelector(getContentXScrollable);
Expand Down Expand Up @@ -98,7 +100,16 @@ const BaseLayout = () => {
}
}, [isMobile, dispatch]);

const isMicro = window.$wujie?.props?.isMicro;
const isMicro = window.__POWERED_BY_WUJIE__;

useEffect(() => {
if (window.$wujie?.props?.onMicroMounted) {
window.$wujie?.props?.onMicroMounted({
nav,
logout: async () => await logout({ ignoreError: true })
})
}
}, [isMicro])

return (
<AdminLayout
Expand Down Expand Up @@ -135,7 +146,7 @@ const BaseLayout = () => {
)
}
Sider={
window.$wujie?.props?.isMicro ? null : (
isMicro ? null : (
<GlobalSider
headerHeight={themeSettings.header.height}
inverted={themeSettings.sider.inverted}
Expand All @@ -146,7 +157,7 @@ const BaseLayout = () => {
)
}
>
<GlobalContent />
<GlobalContent closePadding={isMicro}/>

<GlobalMenu
mode={themeSettings.layout.mode}
Expand Down
39 changes: 39 additions & 0 deletions web/src/layouts/base-layout/MenuProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getActiveFirstLevelMenuKey } from '@/store/slice/tab/shared';
import { MixMenuContext } from '../context';

import { getGlobalMenusByAuthRoutes } from './MenuUtil';
import { renderToString } from 'react-dom/server';

interface Props {
readonly children: ReactNode;
Expand All @@ -22,6 +23,8 @@ const MenuProvider: FC<Props> = ({ children }) => {

const locale = useAppSelector(getLocale);

const { t } = useTranslation();

const update = useUpdate();

const activeFirstLevelMenuKey = useAppSelector(selectActiveFirstLevelMenuKey);
Expand Down Expand Up @@ -69,6 +72,42 @@ const MenuProvider: FC<Props> = ({ children }) => {
update();
}, [locale]);

useEffect(() => {
if (window.$wujie?.props?.onRoutesUpdate) {
const formatRoutes = (routes: any[] = [], newRoutes: any[] = [], pathPrefix?: string) => {
routes.forEach((item) => {
let activeRoute
if (item.meta?.activeMenu) {
activeRoute = routes.find((r) => r.name === item.meta?.activeMenu)
}
const route = {
...item,
path: `${pathPrefix || ''}${item.path}`,
localeName: item.meta?.i18nKey ? t(item.meta?.i18nKey) : undefined,
icon: renderToString(<SvgIcon icon={item.meta?.icon} localIcon={item.meta?.localIcon} />),
hideInMenu: item.meta?.hideInMenu,
activeRoute: pathPrefix ? undefined : (
activeRoute ? {
...activeRoute,
path: `${activeRoute.path}`,
localeName: activeRoute.meta?.i18nKey ? t(activeRoute.meta?.i18nKey) : undefined,
icon: renderToString(<SvgIcon icon={activeRoute.meta?.icon} localIcon={activeRoute.meta?.localIcon} />),
hideInMenu: activeRoute.meta?.hideInMenu,
} : undefined
)
}
newRoutes.push(route)
if (item.children) {
formatRoutes(item.children, newRoutes, `${route.path}/`)
}
})
}
const newRoutes: any[] = []
formatRoutes(sortRoutes, newRoutes)
window.$wujie?.props?.onRoutesUpdate(newRoutes)
}
}, [sortRoutes])

const mixMenuContext = {
activeFirstLevelMenuKey,
allMenus: menus,
Expand Down
33 changes: 21 additions & 12 deletions web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ import './plugins/assets';
import { setupI18n } from './locales';
import { setupAppVersionNotification, setupDayjs, setupIconifyOffline, setupLoading, setupNProgress } from './plugins';
import './icons';
import { setupMicro } from './components/micro/index.tsx';

function renderRoot(root) {
root.render(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
<ErrorBoundary fallbackRender={FallbackRender}>
<Provider store={store}>
<App />
</Provider>
</ErrorBoundary>
);
}

function setupApp() {
setupI18n();
Expand All @@ -25,21 +38,17 @@ function setupApp() {
setupRouter();

setupDayjs();

setupAppVersionNotification();


const container = document.getElementById('root');
if (!container) return;
const root = createRoot(container);
root.render(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
<ErrorBoundary fallbackRender={FallbackRender}>
<Provider store={store}>
<App />
</Provider>
</ErrorBoundary>
);

if (window.__POWERED_BY_WUJIE__) {
setupMicro(root, renderRoot)
} else {
setupAppVersionNotification();
renderRoot(root)
}
}

setupApp();
4 changes: 4 additions & 0 deletions web/src/pages/ai-assistant/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useQueryParams from '@/hooks/common/queryParams';
import { cloneAssistant, deleteAssistant, searchAssistant, updateAssistant } from '@/service/api/assistant';
import { formatESSearchResult } from '@/service/request/es';
import { Api } from '@/types/api';
import { getServer } from '@/store/slice/server';

type Assistant = Api.LLM.Assistant;

Expand All @@ -22,6 +23,8 @@ export function Component() {

const { hasAuth } = useAuth();

const server = useAppSelector(getServer);

const permissions = {
read: hasAuth('coco#assistant/read'),
create: hasAuth('coco#assistant/create'),
Expand Down Expand Up @@ -129,6 +132,7 @@ export function Component() {
height='1em'
src={record.icon}
width='1em'
server={server}
/>
</IconWrapper>
)}
Expand Down
3 changes: 3 additions & 0 deletions web/src/pages/ai-assistant/modules/ModelSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ModelSettings from './ModelSettings';
import InfiniIcon from '@/components/common/icon';
import { getLocale } from '@/store/slice/app';
import { Form, Input } from 'antd';
import { getServer } from '@/store/slice/server';

const DefaultModelSettings = {
temperature: 0.7,
Expand Down Expand Up @@ -141,6 +142,7 @@ export default (props: any) => {
}, [providers]);

const locale = useAppSelector(getLocale);
const server = useAppSelector(getServer);

const [sorter, setSorter] = useState([]);
const [filters, setFilters] = useState({});
Expand All @@ -159,6 +161,7 @@ export default (props: any) => {
height='1em'
src={item.icon}
width='1em'
server={server}
/>
</IconWrapper>
)}
Expand Down
Loading
Loading