From e902920669b117961108566a3416a1ed7f454486 Mon Sep 17 00:00:00 2001 From: QCQCQC <1220204124@zust.edu.cn> Date: Thu, 17 Oct 2024 16:05:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=9C=A8context=E4=B8=AD=E6=96=B0=E5=A2=9E?= =?UTF-8?q?selectedCategory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/frontend/home/FrontendBody.tsx | 6 ++--- .../frontend/home/context/homeContext.tsx | 27 ++++++++++++++----- .../frontend/home/labels/web.pc.tsx | 10 +++---- src/data/i18n.ts | 20 +++++++++++--- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/components/frontend/home/FrontendBody.tsx b/src/components/frontend/home/FrontendBody.tsx index bbcd4b9..eede4c6 100644 --- a/src/components/frontend/home/FrontendBody.tsx +++ b/src/components/frontend/home/FrontendBody.tsx @@ -4,16 +4,16 @@ import { useHomeContext } from './context/homeContext'; import EssaysByLabel from './essays/byLabel'; const FrontendBody = () => { - const { selectedTagId } = useHomeContext(); + const { selectedLabelId } = useHomeContext(); return (
- {!selectedTagId ? ( + {!selectedLabelId ? ( ) : ( )}
diff --git a/src/components/frontend/home/context/homeContext.tsx b/src/components/frontend/home/context/homeContext.tsx index 4f14705..0d2ec81 100644 --- a/src/components/frontend/home/context/homeContext.tsx +++ b/src/components/frontend/home/context/homeContext.tsx @@ -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(undefined); @@ -11,15 +15,24 @@ const HomeContext = createContext(undefined); export const HomeProvider: React.FC<{ children: React.ReactNode; }> = ({ children }) => { - const [selectedTagId, _setSelectedTagId] = React.useState(); - const setSelectedTagId = (tagId: string | null) => { - _setSelectedTagId(tagId || undefined); + const [selectedLabelId, _setSelectedLabelId] = React.useState(); + const setSelectedLabelId = (tagId: string | null) => { + _setSelectedLabelId(tagId || undefined); }; + + const [selectedCategoryId, _setSelectedCategoryId] = + React.useState(); + const setSelectedCategoryId = (categoryId: string | null) => { + _setSelectedCategoryId(categoryId || undefined); + }; + return ( {children} diff --git a/src/components/frontend/home/labels/web.pc.tsx b/src/components/frontend/home/labels/web.pc.tsx index 447eaed..12170a6 100644 --- a/src/components/frontend/home/labels/web.pc.tsx +++ b/src/components/frontend/home/labels/web.pc.tsx @@ -19,7 +19,7 @@ const LabelList = ( const { list, oakFullpath, labelClassName } = props.data; const { t } = props.methods; - const { selectedTagId, setSelectedTagId } = useHomeContext(); + const { selectedLabelId, setSelectedLabelId } = useHomeContext(); return ( <> @@ -35,15 +35,15 @@ const LabelList = ( labelClassName={`${labelClassName}`} labelStyle={{ border: - selectedTagId === item.id + selectedLabelId === item.id ? '2px solid #000' : '2px solid #fff', }} onClick={() => { - if (selectedTagId === item.id) { - setSelectedTagId(null); + if (selectedLabelId === item.id) { + setSelectedLabelId(null); } else { - setSelectedTagId(item.id!); + setSelectedLabelId(item.id!); } }} key={item.id} diff --git a/src/data/i18n.ts b/src/data/i18n.ts index d45146b..27ba1ab 100644 --- a/src/data/i18n.ts +++ b/src/data/i18n.ts @@ -26,8 +26,7 @@ const i18ns: I18n[] = [ "summary": "文章摘要", "author": "作者", "action": { - "updateLabels": "修改标签", - "createLabels": "新建标签" + "setting": "设置" }, "label": { "selectLabels": "选择标签" @@ -35,7 +34,8 @@ const i18ns: I18n[] = [ "essay": { "isTop": "已置顶", "notTop": "未置顶" - } + }, + "cover": "封面" } }, { @@ -126,6 +126,17 @@ const i18ns: I18n[] = [ "userLogin": "用户登录" } }, + { + id: "803dd2892be9bb5973f8da5b83a35bc1", + namespace: "new-demo-c-console-category-selector", + language: "zh-CN", + module: "new-demo", + position: "src/components/console/category/selector", + data: { + "placeholder": "请选择分类", + "blank": "无分类" + } + }, { id: "592037eadc9833a3b3307d6881daf2fb", namespace: "new-demo-c-console-essay-editor", @@ -137,7 +148,8 @@ const i18ns: I18n[] = [ "error": { "titleCannotBeEmpty": "文章标题不能为空", "contentCannotBeEmpty": "文章内容不能为空" - } + }, + "setting": "设置" } }, { From 955e092728069f6989fbd8928feb5135f0aabf82 Mon Sep 17 00:00:00 2001 From: QCQCQC <1220204124@zust.edu.cn> Date: Thu, 17 Oct 2024 17:55:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E9=80=9A=E8=BF=87category=E5=8E=BB?= =?UTF-8?q?=E7=AD=9B=E9=80=89label?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/home/FrontendHeader.tsx | 31 +++++++--- .../frontend/home/categories/index.ts | 12 ++++ .../frontend/home/categories/item/index.tsx | 30 ++++++++++ .../home/categories/item/styles.module.less | 11 ++++ .../home/categories/locales/zh_CN.json | 4 ++ .../home/categories/styles.module.less | 23 ++++++++ .../frontend/home/categories/web.pc.tsx | 57 +++++++++++++++++++ .../frontend/home/context/homeContext.tsx | 1 + .../frontend/home/labels/byCategory/index.ts | 38 +++++++++++++ .../home/labels/byCategory/web.pc.tsx | 35 ++++++++++++ .../home/labels/components/LabelLists.tsx | 49 ++++++++++++++++ .../frontend/home/labels/web.pc.tsx | 42 +++----------- src/utils/projection.ts | 21 +++++++ 13 files changed, 312 insertions(+), 42 deletions(-) create mode 100644 src/components/frontend/home/categories/index.ts create mode 100644 src/components/frontend/home/categories/item/index.tsx create mode 100644 src/components/frontend/home/categories/item/styles.module.less create mode 100644 src/components/frontend/home/categories/locales/zh_CN.json create mode 100644 src/components/frontend/home/categories/styles.module.less create mode 100644 src/components/frontend/home/categories/web.pc.tsx create mode 100644 src/components/frontend/home/labels/byCategory/index.ts create mode 100644 src/components/frontend/home/labels/byCategory/web.pc.tsx create mode 100644 src/components/frontend/home/labels/components/LabelLists.tsx diff --git a/src/components/frontend/home/FrontendHeader.tsx b/src/components/frontend/home/FrontendHeader.tsx index 9359ba0..800d893 100644 --- a/src/components/frontend/home/FrontendHeader.tsx +++ b/src/components/frontend/home/FrontendHeader.tsx @@ -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 ( -
- -
-
+ <> +
+ +
+
+ {!selectedCategoryId ? ( + + ) : ( + + )} +
+
+ ); }; diff --git a/src/components/frontend/home/categories/index.ts b/src/components/frontend/home/categories/index.ts new file mode 100644 index 0000000..788e2ac --- /dev/null +++ b/src/components/frontend/home/categories/index.ts @@ -0,0 +1,12 @@ +import { categoryProjection } from "@project/utils/projection"; + +export default OakComponent({ + entity: 'category', + isList: true, + projection: categoryProjection, + formData({ data }) { + return { + list: data, + }; + } +}) diff --git a/src/components/frontend/home/categories/item/index.tsx b/src/components/frontend/home/categories/item/index.tsx new file mode 100644 index 0000000..32df755 --- /dev/null +++ b/src/components/frontend/home/categories/item/index.tsx @@ -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; + navigateTo: (params: { url: string; oakId: string }) => void; + t: (key: string) => string; + onClick?: () => void; + selected?: boolean; +}) => { + const { item, navigateTo, t, selected } = props; + return ( +
{ + props.onClick && props.onClick(); + }} + style={{ + backgroundColor: selected ? '#f0f0f0' : 'white', + border: selected ? '1px solid #f0f0f0' : '1px solid #f0f0f0', + }} + > + {item.name} +
+ ); +}; + +export default CatrgoryItem; diff --git a/src/components/frontend/home/categories/item/styles.module.less b/src/components/frontend/home/categories/item/styles.module.less new file mode 100644 index 0000000..e4fe72b --- /dev/null +++ b/src/components/frontend/home/categories/item/styles.module.less @@ -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; +} \ No newline at end of file diff --git a/src/components/frontend/home/categories/locales/zh_CN.json b/src/components/frontend/home/categories/locales/zh_CN.json new file mode 100644 index 0000000..0181fc3 --- /dev/null +++ b/src/components/frontend/home/categories/locales/zh_CN.json @@ -0,0 +1,4 @@ +{ + "noCategaries": "没有找到分类", + "categories": "分类" +} \ No newline at end of file diff --git a/src/components/frontend/home/categories/styles.module.less b/src/components/frontend/home/categories/styles.module.less new file mode 100644 index 0000000..9a85db1 --- /dev/null +++ b/src/components/frontend/home/categories/styles.module.less @@ -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; + } + } +} \ No newline at end of file diff --git a/src/components/frontend/home/categories/web.pc.tsx b/src/components/frontend/home/categories/web.pc.tsx new file mode 100644 index 0000000..2f27631 --- /dev/null +++ b/src/components/frontend/home/categories/web.pc.tsx @@ -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[]; + } + > +) => { + const { list } = props.data; + const { t, navigateTo } = props.methods; + const { selectedCategoryId, setSelectedCategoryId } = useHomeContext(); + + return ( + <> + {list && list.length ? ( +
+
+ {t('categories')} ({list.length}) +
+ {list.map((item) => { + return ( + { + if (selectedCategoryId === item.id) { + setSelectedCategoryId(null); + } else { + setSelectedCategoryId(item.id!); + } + }} + selected={selectedCategoryId === item.id} + /> + ); + })} +
+ ) : ( + // +
{t('noCategaries')}
+ )} + + ); +}; + +export default CategoryList; diff --git a/src/components/frontend/home/context/homeContext.tsx b/src/components/frontend/home/context/homeContext.tsx index 0d2ec81..d7a544a 100644 --- a/src/components/frontend/home/context/homeContext.tsx +++ b/src/components/frontend/home/context/homeContext.tsx @@ -23,6 +23,7 @@ export const HomeProvider: React.FC<{ const [selectedCategoryId, _setSelectedCategoryId] = React.useState(); const setSelectedCategoryId = (categoryId: string | null) => { + _setSelectedLabelId(undefined); _setSelectedCategoryId(categoryId || undefined); }; diff --git a/src/components/frontend/home/labels/byCategory/index.ts b/src/components/frontend/home/labels/byCategory/index.ts new file mode 100644 index 0000000..036b14b --- /dev/null +++ b/src/components/frontend/home/labels/byCategory/index.ts @@ -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) || [], + }; + }, +}); diff --git a/src/components/frontend/home/labels/byCategory/web.pc.tsx b/src/components/frontend/home/labels/byCategory/web.pc.tsx new file mode 100644 index 0000000..c1ac63b --- /dev/null +++ b/src/components/frontend/home/labels/byCategory/web.pc.tsx @@ -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 && ( + + )} + + ); +}; + +export default LabelsByCategory; diff --git a/src/components/frontend/home/labels/components/LabelLists.tsx b/src/components/frontend/home/labels/components/LabelLists.tsx new file mode 100644 index 0000000..dac0879 --- /dev/null +++ b/src/components/frontend/home/labels/components/LabelLists.tsx @@ -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 ( + { + if (selectedLabelId === item.id) { + setSelectedLabelId(null); + } else { + setSelectedLabelId(item.id!); + } + }} + key={item.id} + > + ); + }) + ) : ( +
{t('common::noData')}
+ )} + + ); +}; + +export default LabelLists; diff --git a/src/components/frontend/home/labels/web.pc.tsx b/src/components/frontend/home/labels/web.pc.tsx index 12170a6..4088646 100644 --- a/src/components/frontend/home/labels/web.pc.tsx +++ b/src/components/frontend/home/labels/web.pc.tsx @@ -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 { selectedLabelId, setSelectedLabelId } = useHomeContext(); - return ( <> {list && ( - <> - {list.length ? ( - list.map((item, index) => { - return ( - { - if (selectedLabelId === item.id) { - setSelectedLabelId(null); - } else { - setSelectedLabelId(item.id!); - } - }} - key={item.id} - > - ); - }) - ) : ( -
{t('common::noData')}
- )} - + )} ); diff --git a/src/utils/projection.ts b/src/utils/projection.ts index 6c78fff..96b030a 100644 --- a/src/utils/projection.ts +++ b/src/utils/projection.ts @@ -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', + }, + ], + }, +};