Skip to content

Commit

Permalink
♻️ refactor(plugin): 重构 plugin Store 组织结构,便于开发与迭代维护
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Sep 2, 2023
1 parent 17c39ef commit ec527cb
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 91 deletions.
2 changes: 1 addition & 1 deletion src/features/AgentSetting/AgentPlugin/LocalPluginItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const MarketList = memo<{ id: string }>(({ id }) => {
const [useFetchPluginList, fetchPluginManifest, dispatchDevPluginList] = usePluginStore((s) => [
s.useFetchPluginList,
s.fetchPluginManifest,
s.dispatchDevPluginList,
s.dispatchCustomPluginList,
]);

const pluginManifestLoading = usePluginStore((s) => s.pluginManifestLoading, isEqual);
Expand Down
20 changes: 14 additions & 6 deletions src/features/AgentSetting/AgentPlugin/MarketList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,22 @@ const MarketList = memo(() => {
// setModal(true);
// }, []);

const updateConfig = useStore((s) => s.toggleAgentPlugin);
const [plugins, hasPlugin] = useStore((s) => [s.config.plugins || [], !!s.config.plugins]);
const [plugins, hasPlugin, toggleAgentPlugin] = useStore((s) => [
s.config.plugins || [],
!!s.config.plugins,
s.toggleAgentPlugin,
]);

const [useFetchPluginList, fetchPluginManifest, saveToDevList, updateNewDevPlugin] =
usePluginStore((s) => [
s.useFetchPluginList,
s.fetchPluginManifest,
s.saveToDevList,
s.saveToCustomPluginList,
s.updateNewDevPlugin,
]);
const pluginManifestLoading = usePluginStore((s) => s.pluginManifestLoading, isEqual);
const pluginList = usePluginStore((s) => s.pluginList, isEqual);
const devPluginList = usePluginStore((s) => s.devPluginList, isEqual);
const devPluginList = usePluginStore((s) => s.customPluginList, isEqual);

useFetchPluginList();

Expand Down Expand Up @@ -92,7 +95,7 @@ const MarketList = memo(() => {
}
loading={pluginManifestLoading[identifier]}
onChange={(checked) => {
updateConfig(identifier);
toggleAgentPlugin(identifier);
if (checked) {
fetchPluginManifest(identifier);
}
Expand Down Expand Up @@ -125,7 +128,12 @@ const MarketList = memo(() => {
<>
<DevModal
onOpenChange={setModal}
onSave={saveToDevList}
onSave={(devPlugin) => {
// 先保存
saveToDevList(devPlugin);
// 再开启
toggleAgentPlugin(devPlugin.identifier);
}}
onValueChange={updateNewDevPlugin}
open={showModal}
/>
Expand Down
8 changes: 1 addition & 7 deletions src/features/PluginDevModal/MetaForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Form, FormItemProps, Input } from '@lobehub/ui';
import { FormInstance } from 'antd';
import { memo, useEffect } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

import EmojiPicker from '@/components/EmojiPicker';
Expand All @@ -12,12 +12,6 @@ const MetaForm = memo<{ form: FormInstance; mode?: 'edit' | 'create' }>(({ form,
const { t } = useTranslation('plugin');
const [plugins] = usePluginStore((s) => [pluginSelectors.pluginList(s).map((i) => i.identifier)]);

useEffect(() => {
if (usePluginStore.getState().newDevPlugin) {
form.setFieldsValue(usePluginStore.getState().newDevPlugin);
}
}, []);

const configItem: FormItemProps[] = [
{
children: <Input disabled placeholder={'searchEngine'} />,
Expand Down
4 changes: 2 additions & 2 deletions src/features/PluginDevModal/PluginPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { pluginHelpers } from '@/store/plugin';
import { DevPlugin } from '@/store/plugin/initialState';
import { CustomPlugin } from '@/types/plugin';

const PluginPreview = memo<{ form: FormInstance }>(({ form }) => {
const { t } = useTranslation('plugin');
const plugin: DevPlugin = AForm.useWatch([], form);
const plugin: CustomPlugin = AForm.useWatch([], form);

const items = {
avatar: <Avatar avatar={pluginHelpers.getPluginAvatar(plugin?.meta) || '🧩'} />,
Expand Down
11 changes: 6 additions & 5 deletions src/features/PluginDevModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { memo, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { DevPlugin } from '@/store/plugin/initialState';
import { CustomPlugin } from '@/types/plugin';

import ManifestForm from './ManifestForm';
import MetaForm from './MetaForm';
Expand All @@ -29,10 +29,10 @@ interface DevModalProps {
mode?: 'edit' | 'create';
onDelete?: () => void;
onOpenChange: (open: boolean) => void;
onSave?: (value: DevPlugin) => void;
onValueChange?: (value: Partial<DevPlugin>) => void;
onSave?: (value: CustomPlugin) => void;
onValueChange?: (value: Partial<CustomPlugin>) => void;
open?: boolean;
value?: DevPlugin;
value?: CustomPlugin;
}

const DevModal = memo<DevModalProps>(
Expand Down Expand Up @@ -92,13 +92,14 @@ const DevModal = memo<DevModalProps>(
</Flexbox>
</Flexbox>
);

return (
<Form.Provider
onFormChange={() => {
onValueChange?.(form.getFieldsValue());
}}
onFormFinish={(_, info) => {
onSave?.(info.values as DevPlugin);
onSave?.(info.values as CustomPlugin);
message.success(t(isEditMode ? 'dev.updateSuccess' : 'dev.saveSuccess'));
onOpenChange(false);
}}
Expand Down
39 changes: 5 additions & 34 deletions src/store/plugin/initialState.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
import { LobeChatPluginManifest, LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
import { CustomPluginState, initialCustomPluginState } from './slices/customPlugin';
import { PluginState, initialPluginState } from './slices/plugin';

import { PluginManifestMap } from '@/types/plugin';

export type PluginManifestLoadingState = Record<string, boolean>;
export type PluginsSettings = Record<string, any>;

export interface DevPlugin extends LobeChatPluginMeta {
apiMode: 'openapi' | 'simple';
enableSettings: boolean;
manifestConfig?: LobeChatPluginManifest;
manifestMode: 'local' | 'url';
}

export interface PluginStoreState {
devPluginList: DevPlugin[];
manifestPrepared: boolean;
newDevPlugin: Partial<DevPlugin>;
pluginList: LobeChatPluginMeta[];
pluginManifestLoading: PluginManifestLoadingState;
pluginManifestMap: PluginManifestMap;
pluginsSettings: PluginsSettings;
}
export const defaultDevPlugin: Partial<DevPlugin> = {
apiMode: 'simple',
enableSettings: false,
manifestMode: 'url',
};
export type PluginStoreState = PluginState & CustomPluginState;

export const initialState: PluginStoreState = {
devPluginList: [],
manifestPrepared: false,
newDevPlugin: defaultDevPlugin,
pluginList: [],
pluginManifestLoading: {},
pluginManifestMap: {},
pluginsSettings: {},
...initialPluginState,
...initialCustomPluginState,
};
4 changes: 2 additions & 2 deletions src/store/plugin/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ const enabledSchema =
);
};

const pluginList = (s: PluginStoreState) => [...s.pluginList, ...s.devPluginList];
const pluginList = (s: PluginStoreState) => [...s.pluginList, ...s.customPluginList];

const getPluginMetaById = (id: string) => (s: PluginStoreState) =>
pluginHelpers.getPluginFormList(pluginList(s), id);

const getDevPluginById = (id: string) => (s: PluginStoreState) =>
s.devPluginList.find((i) => i.identifier === id);
s.customPluginList.find((i) => i.identifier === id);

const getPluginManifestById = (id: string) => (s: PluginStoreState) => s.pluginManifestMap[id];
const getPluginSettingsById = (id: string) => (s: PluginStoreState) => s.pluginsSettings[id];
Expand Down
46 changes: 46 additions & 0 deletions src/store/plugin/slices/customPlugin/action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { merge } from 'lodash-es';
import { StateCreator } from 'zustand/vanilla';

import { CustomPlugin } from '@/types/plugin';
import { setNamespace } from '@/utils/storeDebug';

import { PluginStore } from '../../store';
import { defaultCustomPlugin } from './initialState';
import { CustomPluginListDispatch, devPluginListReducer } from './reducers/customPluginList';

const t = setNamespace('customPlugin');

/**
* 代理行为接口
*/
export interface CustomPluginAction {
dispatchCustomPluginList: (payload: CustomPluginListDispatch) => void;
saveToCustomPluginList: (value: CustomPlugin) => void;
updateNewDevPlugin: (value: Partial<CustomPlugin>) => void;
}

export const createCustomPluginSlice: StateCreator<
PluginStore,
[['zustand/devtools', never]],
[],
CustomPluginAction
> = (set, get) => ({
dispatchCustomPluginList: (payload) => {
const { customPluginList } = get();

const nextList = devPluginListReducer(customPluginList, payload);
set({ customPluginList: nextList }, false, t('dispatchDevList', payload));
},
saveToCustomPluginList: (value) => {
get().dispatchCustomPluginList({ plugin: value, type: 'addItem' });
set({ newCustomPlugin: defaultCustomPlugin }, false, t('saveToDevList'));
},

updateNewDevPlugin: (newCustomPlugin) => {
set(
{ newCustomPlugin: merge({}, get().newCustomPlugin, newCustomPlugin) },
false,
t('updateNewDevPlugin'),
);
},
});
3 changes: 3 additions & 0 deletions src/store/plugin/slices/customPlugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './action';
export * from './initialState';
// export * from './selectors';
16 changes: 16 additions & 0 deletions src/store/plugin/slices/customPlugin/initialState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { CustomPlugin } from '@/types/plugin';

export interface CustomPluginState {
customPluginList: CustomPlugin[];
newCustomPlugin: Partial<CustomPlugin>;
}
export const defaultCustomPlugin: Partial<CustomPlugin> = {
apiMode: 'simple',
enableSettings: false,
manifestMode: 'url',
};

export const initialCustomPluginState: CustomPluginState = {
customPluginList: [],
newCustomPlugin: defaultCustomPlugin,
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { produce } from 'immer';

import { DevPlugin } from '../initialState';
import { CustomPlugin } from '@/types/plugin';

export type DevListState = DevPlugin[];
export type DevListState = CustomPlugin[];

export type AddPluginAction = {
plugin: DevPlugin;
plugin: CustomPlugin;
type: 'addItem';
};

Expand All @@ -16,15 +16,15 @@ export type DeletePluginAction = {

export type UpdatePluginAction = {
id: string;
plugin: DevPlugin;
plugin: CustomPlugin;
type: 'updateItem';
};

export type DevListDispatch = AddPluginAction | DeletePluginAction | UpdatePluginAction;
export type CustomPluginListDispatch = AddPluginAction | DeletePluginAction | UpdatePluginAction;

export const devPluginListReducer = (
state: DevListState,
payload: DevListDispatch,
payload: CustomPluginListDispatch,
): DevListState => {
switch (payload.type) {
case 'addItem': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ import { pluginSelectors } from '@/store/plugin/selectors';
import { LobeSessions } from '@/types/session';
import { setNamespace } from '@/utils/storeDebug';

import { DevPlugin, defaultDevPlugin } from './initialState';
import { DevListDispatch, devPluginListReducer } from './reducers/devPluginList';
import { PluginStore } from '../../store';
import { PluginDispatch, pluginManifestReducer } from './reducers/manifest';
import { PluginStore } from './store';

const t = setNamespace('plugin');

Expand All @@ -26,12 +24,9 @@ const t = setNamespace('plugin');
*/
export interface PluginAction {
checkLocalEnabledPlugins: (sessions: LobeSessions) => void;
dispatchDevPluginList: (payload: DevListDispatch) => void;
dispatchPluginManifest: (payload: PluginDispatch) => void;
fetchPluginManifest: (name: string) => Promise<void>;
saveToDevList: (value: DevPlugin) => void;
updateManifestLoadingState: (key: string, value: boolean | undefined) => void;
updateNewDevPlugin: (value: Partial<DevPlugin>) => void;
updatePluginSettings: <T>(id: string, settings: Partial<T>) => void;
useFetchPluginList: () => SWRResponse<LobeChatPluginsMarketIndex>;
}
Expand Down Expand Up @@ -60,12 +55,6 @@ export const createPluginSlice: StateCreator<

set({ manifestPrepared: true }, false, t('checkLocalEnabledPlugins'));
},
dispatchDevPluginList: (payload) => {
const { devPluginList } = get();

const nextList = devPluginListReducer(devPluginList, payload);
set({ devPluginList: nextList }, false, t('dispatchDevList', payload));
},
dispatchPluginManifest: (payload) => {
const { pluginManifestMap } = get();
const nextManifest = pluginManifestReducer(pluginManifestMap, payload);
Expand Down Expand Up @@ -113,10 +102,6 @@ export const createPluginSlice: StateCreator<
// 4. 存储 manifest 信息
get().dispatchPluginManifest({ id: plugin.identifier, plugin: data, type: 'addManifest' });
},
saveToDevList: (value) => {
get().dispatchDevPluginList({ plugin: value, type: 'addItem' });
set({ newDevPlugin: defaultDevPlugin }, false, t('saveToDevList'));
},

updateManifestLoadingState: (key, value) => {
set(
Expand All @@ -127,13 +112,6 @@ export const createPluginSlice: StateCreator<
t('updateManifestLoadingState'),
);
},
updateNewDevPlugin: (newDevPlugin) => {
set(
{ newDevPlugin: merge({}, get().newDevPlugin, newDevPlugin) },
false,
t('updateNewDevPlugin'),
);
},
updatePluginSettings: (id, settings) => {
set(
produce((draft) => {
Expand Down
3 changes: 3 additions & 0 deletions src/store/plugin/slices/plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './action';
export * from './initialState';
// export * from './selectors';
22 changes: 22 additions & 0 deletions src/store/plugin/slices/plugin/initialState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';

import { PluginManifestMap } from '@/types/plugin';

export type PluginManifestLoadingState = Record<string, boolean>;
export type PluginsSettings = Record<string, any>;

export interface PluginState {
manifestPrepared: boolean;
pluginList: LobeChatPluginMeta[];
pluginManifestLoading: PluginManifestLoadingState;
pluginManifestMap: PluginManifestMap;
pluginsSettings: PluginsSettings;
}

export const initialPluginState: PluginState = {
manifestPrepared: false,
pluginList: [],
pluginManifestLoading: {},
pluginManifestMap: {},
pluginsSettings: {},
};
File renamed without changes.
Loading

0 comments on commit ec527cb

Please # to comment.