This is an automated email from the ASF dual-hosted git repository.
shuai pushed a commit to branch feat/1.4.3/ui
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git
The following commit(s) were added to refs/heads/feat/1.4.3/ui by this push:
new f4de9842 fix: add preivew model to question list page
f4de9842 is described below
commit f4de98424f7cb5af2661cc12d6303e34e5d35b17
Author: shuai <[email protected]>
AuthorDate: Mon Dec 23 11:50:40 2024 +0800
fix: add preivew model to question list page
---
i18n/en_US.yaml | 3 ++
i18n/zh_CN.yaml | 3 ++
ui/src/common/constants.ts | 1 +
ui/src/components/QueryGroup/index.tsx | 2 +-
ui/src/components/QuestionList/index.tsx | 62 +++++++++++++++++++++++++-------
5 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml
index f4c67a18..df83c6e8 100644
--- a/i18n/en_US.yaml
+++ b/i18n/en_US.yaml
@@ -1500,6 +1500,9 @@ ui:
deleted: Deleted
pending: Pending
more: More
+ view: View
+ card: Card
+ compact: Compact
search:
title: Search Results
keywords: Keywords
diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml
index 07f8d2ea..2ce84a02 100644
--- a/i18n/zh_CN.yaml
+++ b/i18n/zh_CN.yaml
@@ -1467,6 +1467,9 @@ ui:
deleted: 已删除
pending: 等待处理
more: 更多
+ view: 视图
+ card: 卡片模式
+ compact: 简洁模式
search:
title: 搜索结果
keywords: 关键词
diff --git a/ui/src/common/constants.ts b/ui/src/common/constants.ts
index 303926fb..d8b17db7 100644
--- a/ui/src/common/constants.ts
+++ b/ui/src/common/constants.ts
@@ -30,6 +30,7 @@ export const DRAFT_TIMESIGH_STORAGE_KEY = '|_a_t_s_|';
export const DEFAULT_THEME = 'system';
export const ADMIN_PRIVILEGE_CUSTOM_LEVEL = 99;
export const SKELETON_SHOW_TIME = 1000;
+export const LIST_VIEW_STORAGE_KEY = '_a_list_view_';
export const USER_AGENT_NAMES = {
SegmentFault: 'SegmentFault',
diff --git a/ui/src/components/QueryGroup/index.tsx
b/ui/src/components/QueryGroup/index.tsx
index 878e8ed6..f713a3c5 100644
--- a/ui/src/components/QueryGroup/index.tsx
+++ b/ui/src/components/QueryGroup/index.tsx
@@ -133,7 +133,7 @@ const Index: FC<Props> = ({
<DropdownButton
size="sm"
variant="outline-secondary"
- className="md-hide"
+ className={classNames('md-hide', wrapClassName)}
title={t(currentSort)}>
{data.map((btn) => {
const key = typeof btn === 'string' ? btn : btn.sort;
diff --git a/ui/src/components/QuestionList/index.tsx
b/ui/src/components/QuestionList/index.tsx
index c94602ff..88c48de3 100644
--- a/ui/src/components/QuestionList/index.tsx
+++ b/ui/src/components/QuestionList/index.tsx
@@ -17,8 +17,8 @@
* under the License.
*/
-import { FC } from 'react';
-import { ListGroup } from 'react-bootstrap';
+import { FC, useEffect, useState } from 'react';
+import { ListGroup, Dropdown } from 'react-bootstrap';
import { NavLink, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
@@ -33,9 +33,12 @@ import {
QuestionListLoader,
Counts,
PinList,
+ Icon,
} from '@/components';
import * as Type from '@/common/interface';
import { useSkeletonControl } from '@/hooks';
+import Storage from '@/utils/storage';
+import { LIST_VIEW_STORAGE_KEY } from '@/common/constants';
export const QUESTION_ORDER_KEYS: Type.QuestionOrderBy[] = [
'newest',
@@ -77,6 +80,19 @@ const QuestionList: FC<Props> = ({
(v) => pinData.findIndex((p) => p.id === v.id) === -1,
);
+ const [viewType, setViewType] = useState('card');
+
+ // 切换列表预览模式
+ const handleViewMode = (key) => {
+ Storage.set(LIST_VIEW_STORAGE_KEY, key);
+ setViewType(key);
+ };
+
+ useEffect(() => {
+ const type = Storage.get(LIST_VIEW_STORAGE_KEY) || 'card';
+ setViewType(type);
+ }, []);
+
return (
<div>
<div className="mb-3 d-flex flex-wrap justify-content-between">
@@ -85,13 +101,33 @@ const QuestionList: FC<Props> = ({
? t('all_questions')
: t('x_questions', { count })}
</h5>
- <QueryGroup
- data={orderKeys}
- currentSort={curOrder}
- pathname={source === 'questions' ? '/questions' : ''}
- i18nKeyPrefix="question"
- maxBtnCount={source === 'tag' ? 3 : 4}
- />
+ <div className="d-flex flex-wrap">
+ <QueryGroup
+ data={orderKeys}
+ currentSort={curOrder}
+ pathname={source === 'questions' ? '/questions' : ''}
+ i18nKeyPrefix="question"
+ maxBtnCount={source === 'tag' ? 3 : 4}
+ wrapClassName="me-2"
+ />
+ <Dropdown align="end" onSelect={handleViewMode}>
+ <Dropdown.Toggle variant="outline-secondary" size="sm">
+ <Icon name="list" />
+ </Dropdown.Toggle>
+
+ <Dropdown.Menu>
+ <Dropdown.Header>
+ {t('view', { keyPrefix: 'btns' })}
+ </Dropdown.Header>
+ <Dropdown.Item eventKey="card" active={viewType === 'card'}>
+ {t('view', { keyPrefix: 'card' })}
+ </Dropdown.Item>
+ <Dropdown.Item eventKey="compact" active={viewType ===
'compact'}>
+ {t('view', { keyPrefix: 'compact' })}
+ </Dropdown.Item>
+ </Dropdown.Menu>
+ </Dropdown>
+ </div>
</div>
<ListGroup className="rounded-0">
{isSkeletonShow ? (
@@ -131,9 +167,11 @@ const QuestionList: FC<Props> = ({
{li.status === 2 ? ` [${t('closed')}]` : ''}
</NavLink>
</h5>
- <p className="mb-2 small text-body text-truncate-2">
- {li.description}
- </p>
+ {viewType === 'card' && (
+ <p className="mb-2 small text-body text-truncate-2">
+ {li.description}
+ </p>
+ )}
<div className="question-tags mb-12">
{Array.isArray(li.tags)