Merge branch 'master' of https://gitea.51mars.com/pqc/new-demo
This commit is contained in:
commit
77883fae1f
|
|
@ -4,16 +4,16 @@ import { useHomeContext } from './context/homeContext';
|
||||||
import EssaysByLabel from './essays/byLabel';
|
import EssaysByLabel from './essays/byLabel';
|
||||||
|
|
||||||
const FrontendBody = () => {
|
const FrontendBody = () => {
|
||||||
const { selectedTagId } = useHomeContext();
|
const { selectedLabelId } = useHomeContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{!selectedTagId ? (
|
{!selectedLabelId ? (
|
||||||
<Essays oakPath='essays'></Essays>
|
<Essays oakPath='essays'></Essays>
|
||||||
) : (
|
) : (
|
||||||
<EssaysByLabel
|
<EssaysByLabel
|
||||||
oakPath='essaysByLabel'
|
oakPath='essaysByLabel'
|
||||||
oakId={selectedTagId!}
|
oakId={selectedLabelId!}
|
||||||
></EssaysByLabel>
|
></EssaysByLabel>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,34 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import LabelList from './labels';
|
import LabelList from './labels';
|
||||||
import Styles from './styles.module.less';
|
import Styles from './styles.module.less';
|
||||||
|
import CategoryList from './categories';
|
||||||
|
import { useHomeContext } from './context/homeContext';
|
||||||
|
import LabelsByCategory from './labels/byCategory';
|
||||||
|
|
||||||
const FrontendHeader = () => {
|
const FrontendHeader = () => {
|
||||||
|
const { selectedCategoryId } = useHomeContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<div className={Styles.categories}>
|
||||||
|
<CategoryList oakPath='categories'></CategoryList>
|
||||||
|
</div>
|
||||||
<div className={Styles.labels}>
|
<div className={Styles.labels}>
|
||||||
|
{!selectedCategoryId ? (
|
||||||
<LabelList
|
<LabelList
|
||||||
oakPath='labels'
|
oakPath='labels'
|
||||||
labelClassName={Styles.label}
|
labelClassName={Styles.label}
|
||||||
></LabelList>
|
></LabelList>
|
||||||
|
) : (
|
||||||
|
<LabelsByCategory
|
||||||
|
oakPath='labelsByCategory'
|
||||||
|
oakId={selectedCategoryId!}
|
||||||
|
labelClassName={Styles.label}
|
||||||
|
></LabelsByCategory>
|
||||||
|
)}
|
||||||
<div className={Styles.blank}></div>
|
<div className={Styles.blank}></div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { categoryProjection } from "@project/utils/projection";
|
||||||
|
|
||||||
|
export default OakComponent({
|
||||||
|
entity: 'category',
|
||||||
|
isList: true,
|
||||||
|
projection: categoryProjection,
|
||||||
|
formData({ data }) {
|
||||||
|
return {
|
||||||
|
list: data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { EntityDict } from '@project/oak-app-domain';
|
||||||
|
import { RowWithActions } from 'oak-frontend-base';
|
||||||
|
import Styles from './styles.module.less';
|
||||||
|
|
||||||
|
const CatrgoryItem = (props: {
|
||||||
|
item: RowWithActions<EntityDict, 'category'>;
|
||||||
|
navigateTo: (params: { url: string; oakId: string }) => void;
|
||||||
|
t: (key: string) => string;
|
||||||
|
onClick?: () => void;
|
||||||
|
selected?: boolean;
|
||||||
|
}) => {
|
||||||
|
const { item, navigateTo, t, selected } = props;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={Styles.category}
|
||||||
|
onClick={() => {
|
||||||
|
props.onClick && props.onClick();
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
backgroundColor: selected ? '#f0f0f0' : 'white',
|
||||||
|
border: selected ? '1px solid #f0f0f0' : '1px solid #f0f0f0',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CatrgoryItem;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
.category {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"noCategaries": "没有找到分类",
|
||||||
|
"categories": "分类"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
.list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 10px;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { EntityDict } from '@project/oak-app-domain';
|
||||||
|
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||||||
|
import { useHomeContext } from '../context/homeContext';
|
||||||
|
import { Empty } from 'antd';
|
||||||
|
import CatrgoryItem from './item';
|
||||||
|
import Styles from './styles.module.less';
|
||||||
|
|
||||||
|
const CategoryList = (
|
||||||
|
props: WebComponentProps<
|
||||||
|
EntityDict,
|
||||||
|
'category',
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
list: RowWithActions<EntityDict, 'category'>[];
|
||||||
|
}
|
||||||
|
>
|
||||||
|
) => {
|
||||||
|
const { list } = props.data;
|
||||||
|
const { t, navigateTo } = props.methods;
|
||||||
|
const { selectedCategoryId, setSelectedCategoryId } = useHomeContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{list && list.length ? (
|
||||||
|
<div className={Styles.list}>
|
||||||
|
<div className={Styles.title}>
|
||||||
|
{t('categories')} ({list.length})
|
||||||
|
</div>
|
||||||
|
{list.map((item) => {
|
||||||
|
return (
|
||||||
|
<CatrgoryItem
|
||||||
|
item={item}
|
||||||
|
navigateTo={navigateTo}
|
||||||
|
t={t}
|
||||||
|
key={item.id}
|
||||||
|
onClick={() => {
|
||||||
|
if (selectedCategoryId === item.id) {
|
||||||
|
setSelectedCategoryId(null);
|
||||||
|
} else {
|
||||||
|
setSelectedCategoryId(item.id!);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
selected={selectedCategoryId === item.id}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
// <Empty description={t('common::noData')} />
|
||||||
|
<div>{t('noCategaries')}</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CategoryList;
|
||||||
|
|
@ -2,8 +2,12 @@ import React from 'react';
|
||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
|
|
||||||
type HomeContextType = {
|
type HomeContextType = {
|
||||||
selectedTagId: string | undefined;
|
// label selection
|
||||||
setSelectedTagId: (tagId: string | null) => void;
|
selectedLabelId: string | undefined;
|
||||||
|
setSelectedLabelId: (tagId: string | null) => void;
|
||||||
|
// category selection
|
||||||
|
selectedCategoryId: string | undefined;
|
||||||
|
setSelectedCategoryId: (categoryId: string | null) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const HomeContext = createContext<HomeContextType | undefined>(undefined);
|
const HomeContext = createContext<HomeContextType | undefined>(undefined);
|
||||||
|
|
@ -11,15 +15,25 @@ const HomeContext = createContext<HomeContextType | undefined>(undefined);
|
||||||
export const HomeProvider: React.FC<{
|
export const HomeProvider: React.FC<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}> = ({ children }) => {
|
}> = ({ children }) => {
|
||||||
const [selectedTagId, _setSelectedTagId] = React.useState<string>();
|
const [selectedLabelId, _setSelectedLabelId] = React.useState<string>();
|
||||||
const setSelectedTagId = (tagId: string | null) => {
|
const setSelectedLabelId = (tagId: string | null) => {
|
||||||
_setSelectedTagId(tagId || undefined);
|
_setSelectedLabelId(tagId || undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [selectedCategoryId, _setSelectedCategoryId] =
|
||||||
|
React.useState<string>();
|
||||||
|
const setSelectedCategoryId = (categoryId: string | null) => {
|
||||||
|
_setSelectedLabelId(undefined);
|
||||||
|
_setSelectedCategoryId(categoryId || undefined);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HomeContext.Provider
|
<HomeContext.Provider
|
||||||
value={{
|
value={{
|
||||||
selectedTagId,
|
selectedLabelId,
|
||||||
setSelectedTagId,
|
setSelectedLabelId,
|
||||||
|
selectedCategoryId,
|
||||||
|
setSelectedCategoryId,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
export default OakComponent({
|
||||||
|
entity: 'category',
|
||||||
|
isList: false,
|
||||||
|
projection: {
|
||||||
|
essay$category: {
|
||||||
|
$entity: 'essay',
|
||||||
|
data: {
|
||||||
|
essayLabels$essay: {
|
||||||
|
$entity: 'essayLabels',
|
||||||
|
data: {
|
||||||
|
label: {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
description: 1,
|
||||||
|
bgColor: 1,
|
||||||
|
textColor: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
iState: 'published',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formData({ data }) {
|
||||||
|
return {
|
||||||
|
list:
|
||||||
|
data.essay$category
|
||||||
|
?.flatMap((item) => {
|
||||||
|
return item.essayLabels$essay?.map((item) => {
|
||||||
|
return item.label;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.filter((item) => !!item) || [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { EntityDict } from '@project/oak-app-domain';
|
||||||
|
import { WebComponentProps } from 'oak-frontend-base';
|
||||||
|
import React from 'react';
|
||||||
|
import LabelLists from '../components/LabelLists';
|
||||||
|
|
||||||
|
const LabelsByCategory = (
|
||||||
|
props: WebComponentProps<
|
||||||
|
EntityDict,
|
||||||
|
'category',
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
list: EntityDict['label']['Schema'][];
|
||||||
|
labelClassName?: string;
|
||||||
|
}
|
||||||
|
>
|
||||||
|
) => {
|
||||||
|
|
||||||
|
const { list, oakFullpath, labelClassName } = props.data;
|
||||||
|
const { t } = props.methods;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{list && (
|
||||||
|
<LabelLists
|
||||||
|
list={list}
|
||||||
|
oakFullpath={oakFullpath}
|
||||||
|
labelClassName={labelClassName}
|
||||||
|
t={t}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LabelsByCategory;
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { EntityDict } from '@project/oak-app-domain';
|
||||||
|
import { useHomeContext } from '../../context/homeContext';
|
||||||
|
import Listitem from '@project/components/console/labels/list/listitem';
|
||||||
|
|
||||||
|
const LabelLists = (props: {
|
||||||
|
list: EntityDict['label']['Schema'][];
|
||||||
|
oakFullpath: string;
|
||||||
|
labelClassName?: string;
|
||||||
|
t: (key: string) => string;
|
||||||
|
}) => {
|
||||||
|
const { list, oakFullpath, labelClassName, t } = props;
|
||||||
|
|
||||||
|
const { selectedLabelId, setSelectedLabelId } = useHomeContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{list.length ? (
|
||||||
|
list.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Listitem
|
||||||
|
oakPath={`${oakFullpath}.${item.id}`}
|
||||||
|
oakId={item.id}
|
||||||
|
enablePopup
|
||||||
|
labelClassName={`${labelClassName}`}
|
||||||
|
labelStyle={{
|
||||||
|
border:
|
||||||
|
selectedLabelId === item.id
|
||||||
|
? '2px solid #000'
|
||||||
|
: '2px solid #fff',
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (selectedLabelId === item.id) {
|
||||||
|
setSelectedLabelId(null);
|
||||||
|
} else {
|
||||||
|
setSelectedLabelId(item.id!);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
key={item.id}
|
||||||
|
></Listitem>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<div>{t('common::noData')}</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LabelLists;
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EntityDict } from '@project/oak-app-domain';
|
import { EntityDict } from '@project/oak-app-domain';
|
||||||
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||||||
import Listitem from '@project/components/console/labels/list/listitem';
|
import LabelLists from './components/LabelLists';
|
||||||
import { useHomeContext } from '../context/homeContext';
|
|
||||||
import { set } from 'lodash';
|
|
||||||
|
|
||||||
const LabelList = (
|
const LabelList = (
|
||||||
props: WebComponentProps<
|
props: WebComponentProps<
|
||||||
|
|
@ -19,41 +17,15 @@ const LabelList = (
|
||||||
const { list, oakFullpath, labelClassName } = props.data;
|
const { list, oakFullpath, labelClassName } = props.data;
|
||||||
const { t } = props.methods;
|
const { t } = props.methods;
|
||||||
|
|
||||||
const { selectedTagId, setSelectedTagId } = useHomeContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{list && (
|
{list && (
|
||||||
<>
|
<LabelLists
|
||||||
{list.length ? (
|
list={list as EntityDict['label']['Schema'][]}
|
||||||
list.map((item, index) => {
|
oakFullpath={oakFullpath}
|
||||||
return (
|
labelClassName={labelClassName}
|
||||||
<Listitem
|
t={t}
|
||||||
oakPath={`${oakFullpath}.${item.id}`}
|
/>
|
||||||
oakId={item.id}
|
|
||||||
enablePopup
|
|
||||||
labelClassName={`${labelClassName}`}
|
|
||||||
labelStyle={{
|
|
||||||
border:
|
|
||||||
selectedTagId === item.id
|
|
||||||
? '2px solid #000'
|
|
||||||
: '2px solid #fff',
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
if (selectedTagId === item.id) {
|
|
||||||
setSelectedTagId(null);
|
|
||||||
} else {
|
|
||||||
setSelectedTagId(item.id!);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
key={item.id}
|
|
||||||
></Listitem>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<div>{t('common::noData')}</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,24 @@ export const essayProjection: EntityDict['essay']['Selection']['data'] = {
|
||||||
count: 1,
|
count: 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const categoryProjection: EntityDict['category']['Selection']['data'] = {
|
||||||
|
id: 1,
|
||||||
|
name: 1,
|
||||||
|
description: 1,
|
||||||
|
extraFile$entity: {
|
||||||
|
$entity: 'extraFile',
|
||||||
|
data: extraFileProjection,
|
||||||
|
filter: {
|
||||||
|
tag1: 'cover',
|
||||||
|
},
|
||||||
|
sorter: [
|
||||||
|
{
|
||||||
|
$attr: {
|
||||||
|
sort: 1,
|
||||||
|
},
|
||||||
|
$direction: 'asc',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue