feat: community backends marketplace
This commit is contained in:
@@ -44,5 +44,5 @@ export default {
|
|||||||
'backend.filter.source': 'Filter by source',
|
'backend.filter.source': 'Filter by source',
|
||||||
'backend.add.custom': 'Custom',
|
'backend.add.custom': 'Custom',
|
||||||
'backend.add.community': 'Community Repository',
|
'backend.add.community': 'Community Repository',
|
||||||
'backend.community.title': 'Community Backends'
|
'backend.community.title': 'Community Backends Marketplace'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,5 +44,5 @@ export default {
|
|||||||
'backend.filter.source': 'Filter by source',
|
'backend.filter.source': 'Filter by source',
|
||||||
'backend.add.custom': 'Custom',
|
'backend.add.custom': 'Custom',
|
||||||
'backend.add.community': 'Community Repository',
|
'backend.add.community': 'Community Repository',
|
||||||
'backend.community.title': 'Community Backends'
|
'backend.community.title': 'Community Backends Marketplace'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default {
|
|||||||
'backend.filter.source': 'Filter by source',
|
'backend.filter.source': 'Filter by source',
|
||||||
'backend.add.custom': 'Custom',
|
'backend.add.custom': 'Custom',
|
||||||
'backend.add.community': 'Community Repository',
|
'backend.add.community': 'Community Repository',
|
||||||
'backend.community.title': 'Community Backends'
|
'backend.community.title': 'Community Backends Marketplace'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -53,5 +53,5 @@ export default {
|
|||||||
// 3. 'backend.filter.source': 'Filter by source',
|
// 3. 'backend.filter.source': 'Filter by source',
|
||||||
// 4. 'backend.add.custom': 'Custom',
|
// 4. 'backend.add.custom': 'Custom',
|
||||||
// 5. 'backend.add.community': 'Community Repository',
|
// 5. 'backend.add.community': 'Community Repository',
|
||||||
// 6. 'backend.community.title': 'Community Backends'
|
// 6. 'backend.community.title': 'Community Backends Marketplace'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -41,5 +41,5 @@ export default {
|
|||||||
'backend.filter.source': '按来源过滤',
|
'backend.filter.source': '按来源过滤',
|
||||||
'backend.add.custom': '自定义',
|
'backend.add.custom': '自定义',
|
||||||
'backend.add.community': '社区仓库',
|
'backend.add.community': '社区仓库',
|
||||||
'backend.community.title': '社区后端'
|
'backend.community.title': '社区后端市场'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const AddCommunityModal: React.FC<{
|
|||||||
>
|
>
|
||||||
<BackendDetail
|
<BackendDetail
|
||||||
onEnable={handleOnEnable}
|
onEnable={handleOnEnable}
|
||||||
currentData={currentData}
|
data={currentData}
|
||||||
></BackendDetail>
|
></BackendDetail>
|
||||||
</ColumnWrapper>
|
</ColumnWrapper>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { BulbOutlined } from '@ant-design/icons';
|
|||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Tag, Typography } from 'antd';
|
import { Button, Tag, Typography } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { generateIcon } from '../components/backend-card';
|
import { generateIcon } from '../components/backend-card';
|
||||||
|
|
||||||
@@ -62,9 +62,22 @@ const UL = styled.ul`
|
|||||||
const BackendDetail: React.FC<{
|
const BackendDetail: React.FC<{
|
||||||
onEnable: (checked: boolean, data: any) => void;
|
onEnable: (checked: boolean, data: any) => void;
|
||||||
onDisable?: () => void;
|
onDisable?: () => void;
|
||||||
currentData?: any;
|
data?: any;
|
||||||
}> = ({ onEnable, onDisable, currentData }) => {
|
}> = ({ onEnable, onDisable, data }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const [currentData, setCurrentData] = React.useState<any>(data);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentData(data);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
const handleOnEnable = async (checked: boolean) => {
|
||||||
|
await onEnable(true, currentData);
|
||||||
|
setCurrentData({
|
||||||
|
...currentData,
|
||||||
|
enabled: checked
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const renderSupportedFrameworks = () => {
|
const renderSupportedFrameworks = () => {
|
||||||
const frameworks = currentData?.framework_index_map || {};
|
const frameworks = currentData?.framework_index_map || {};
|
||||||
@@ -109,7 +122,7 @@ const BackendDetail: React.FC<{
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="middle"
|
size="middle"
|
||||||
onClick={() => onEnable(true, currentData)}
|
onClick={() => handleOnEnable(true)}
|
||||||
>
|
>
|
||||||
{intl.formatMessage({ id: 'common.button.enable' })}
|
{intl.formatMessage({ id: 'common.button.enable' })}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import ThemeTag from '@/components/tags-wrapper/theme-tag';
|
|||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import { SearchOutlined } from '@ant-design/icons';
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Input, Switch, Tooltip } from 'antd';
|
import { Input, Tooltip } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@@ -68,17 +68,10 @@ const CommunityBackends: React.FC<{
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
{data.enabled ? (
|
{data.enabled && (
|
||||||
<ThemeTag style={{ margin: 0 }} color="geekblue" variant="filled">
|
<ThemeTag style={{ margin: 0 }} color="geekblue" variant="filled">
|
||||||
{intl.formatMessage({ id: 'common.status.enabled' })}
|
{intl.formatMessage({ id: 'common.status.enabled' })}
|
||||||
</ThemeTag>
|
</ThemeTag>
|
||||||
) : (
|
|
||||||
<span onClick={(e) => e.stopPropagation()}>
|
|
||||||
<Switch
|
|
||||||
onChange={(checked) => handleOnEnable(checked, data)}
|
|
||||||
size="small"
|
|
||||||
></Switch>
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -49,13 +49,14 @@ const SourceWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const TagInner = styled(Tag)`
|
// add height props
|
||||||
|
const TagInner = styled(Tag)<{ height?: number }>`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
height: 28px;
|
height: ${({ height }) => (height ? `${height}px` : '28px')};
|
||||||
width: 28px;
|
width: ${({ height }) => (height ? `${height}px` : '28px')};
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
`;
|
`;
|
||||||
@@ -146,18 +147,21 @@ interface BackendCardProps {
|
|||||||
active?: boolean;
|
active?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generateIcon = (data: ListItem, height = 20) => {
|
export const generateIcon = (data: ListItem, height?: number) => {
|
||||||
|
const innHeight = height || 20;
|
||||||
if (builtInBackendLogos[data.backend_name]) {
|
if (builtInBackendLogos[data.backend_name]) {
|
||||||
return <img src={builtInBackendLogos[data.backend_name]} height={height} />;
|
return (
|
||||||
|
<img src={builtInBackendLogos[data.backend_name]} height={innHeight} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (data.icon) {
|
if (data.icon) {
|
||||||
return <img src={data.icon} height={height} />;
|
return <img src={data.icon} height={innHeight} />;
|
||||||
}
|
}
|
||||||
const color = customColors[data.id % customColors.length];
|
const color = customColors[data.id % customColors.length];
|
||||||
const icon = customIcons[data.id % customIcons.length];
|
const icon = customIcons[data.id % customIcons.length];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TagInner color={color} variant="filled">
|
<TagInner color={color} variant="filled" height={height || 28}>
|
||||||
{icon}
|
{icon}
|
||||||
</TagInner>
|
</TagInner>
|
||||||
);
|
);
|
||||||
@@ -387,7 +391,11 @@ const BackendCard: React.FC<BackendCardProps> = ({
|
|||||||
>
|
>
|
||||||
<Content>
|
<Content>
|
||||||
<CardName>
|
<CardName>
|
||||||
<span>{data.backend_name}</span>
|
<span>
|
||||||
|
{data.backend_source === BackendSourceValueMap.CUSTOM
|
||||||
|
? data.backend_name.replace(/-custom$/g, '')
|
||||||
|
: data.backend_name}
|
||||||
|
</span>
|
||||||
{renderSource()}
|
{renderSource()}
|
||||||
</CardName>
|
</CardName>
|
||||||
{/* <SourceWrapper>
|
{/* <SourceWrapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user