This commit is contained in:
pqcqaq 2024-10-17 21:39:19 +08:00
commit 77883fae1f
14 changed files with 335 additions and 52 deletions

View File

@ -4,16 +4,16 @@ import { useHomeContext } from './context/homeContext';
import EssaysByLabel from './essays/byLabel';
const FrontendBody = () => {
const { selectedTagId } = useHomeContext();
const { selectedLabelId } = useHomeContext();
return (
<div>
{!selectedTagId ? (
{!selectedLabelId ? (
<Essays oakPath='essays'></Essays>
) : (
<EssaysByLabel
oakPath='essaysByLabel'
oakId={selectedTagId!}
oakId={selectedLabelId!}
></EssaysByLabel>
)}
</div>

View File

@ -1,17 +1,34 @@
import React from 'react';
import LabelList from './labels';
import Styles from './styles.module.less';
import CategoryList from './categories';
import { useHomeContext } from './context/homeContext';
import LabelsByCategory from './labels/byCategory';
const FrontendHeader = () => {
const { selectedCategoryId } = useHomeContext();
return (
<div className={Styles.labels}>
<LabelList
oakPath='labels'
labelClassName={Styles.label}
></LabelList>
<div className={Styles.blank}></div>
</div>
<>
<div className={Styles.categories}>
<CategoryList oakPath='categories'></CategoryList>
</div>
<div className={Styles.labels}>
{!selectedCategoryId ? (
<LabelList
oakPath='labels'
labelClassName={Styles.label}
></LabelList>
) : (
<LabelsByCategory
oakPath='labelsByCategory'
oakId={selectedCategoryId!}
labelClassName={Styles.label}
></LabelsByCategory>
)}
<div className={Styles.blank}></div>
</div>
</>
);
};

View File

@ -0,0 +1,12 @@
import { categoryProjection } from "@project/utils/projection";
export default OakComponent({
entity: 'category',
isList: true,
projection: categoryProjection,
formData({ data }) {
return {
list: data,
};
}
})

View File

@ -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;

View File

@ -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;
}

View File

@ -0,0 +1,4 @@
{
"noCategaries": "没有找到分类",
"categories": "分类"
}

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -2,8 +2,12 @@ import React from 'react';
import { createContext } from 'react';
type HomeContextType = {
selectedTagId: string | undefined;
setSelectedTagId: (tagId: string | null) => void;
// label selection
selectedLabelId: string | undefined;
setSelectedLabelId: (tagId: string | null) => void;
// category selection
selectedCategoryId: string | undefined;
setSelectedCategoryId: (categoryId: string | null) => void;
};
const HomeContext = createContext<HomeContextType | undefined>(undefined);
@ -11,15 +15,25 @@ const HomeContext = createContext<HomeContextType | undefined>(undefined);
export const HomeProvider: React.FC<{
children: React.ReactNode;
}> = ({ children }) => {
const [selectedTagId, _setSelectedTagId] = React.useState<string>();
const setSelectedTagId = (tagId: string | null) => {
_setSelectedTagId(tagId || undefined);
const [selectedLabelId, _setSelectedLabelId] = React.useState<string>();
const setSelectedLabelId = (tagId: string | null) => {
_setSelectedLabelId(tagId || undefined);
};
const [selectedCategoryId, _setSelectedCategoryId] =
React.useState<string>();
const setSelectedCategoryId = (categoryId: string | null) => {
_setSelectedLabelId(undefined);
_setSelectedCategoryId(categoryId || undefined);
};
return (
<HomeContext.Provider
value={{
selectedTagId,
setSelectedTagId,
selectedLabelId,
setSelectedLabelId,
selectedCategoryId,
setSelectedCategoryId,
}}
>
{children}

View File

@ -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) || [],
};
},
});

View File

@ -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;

View File

@ -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;

View File

@ -1,9 +1,7 @@
import React from 'react';
import { EntityDict } from '@project/oak-app-domain';
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
import Listitem from '@project/components/console/labels/list/listitem';
import { useHomeContext } from '../context/homeContext';
import { set } from 'lodash';
import LabelLists from './components/LabelLists';
const LabelList = (
props: WebComponentProps<
@ -19,41 +17,15 @@ const LabelList = (
const { list, oakFullpath, labelClassName } = props.data;
const { t } = props.methods;
const { selectedTagId, setSelectedTagId } = useHomeContext();
return (
<>
{list && (
<>
{list.length ? (
list.map((item, index) => {
return (
<Listitem
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>
)}
</>
<LabelLists
list={list as EntityDict['label']['Schema'][]}
oakFullpath={oakFullpath}
labelClassName={labelClassName}
t={t}
/>
)}
</>
);

View File

@ -82,3 +82,24 @@ export const essayProjection: EntityDict['essay']['Selection']['data'] = {
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',
},
],
},
};