diff --git a/src/assets/core.scss b/src/assets/core.scss
index b1acba5..72e2ebf 100644
--- a/src/assets/core.scss
+++ b/src/assets/core.scss
@@ -29,12 +29,12 @@
}
::-webkit-scrollbar-thumb {
- background: #ccc;
+ background: rgba(64, 150, 255, 0.5);
height: 10px;
border-radius: 5px;
&:hover {
- background: #999;
+ background: rgba(64, 150, 255, 1);
cursor: pointer;
}
}
@@ -176,9 +176,22 @@
}
}
+.page-action-to-top {
+ @apply text-right;
+ .btn-to-top {
+ @apply w-[44px] h-[44px] inline-block bg-blue-300 text-center p-0 transition hover:bg-blue-500;
+ min-width: 0;
+ border-radius: 50px;
+ font-size: 24px;
+ }
+}
+
.data-list-container {
height: calc(100vh - var(--app-header-header) - 200px);
overflow: auto;
+ margin-right: -20px;
+ padding-right: 16px;
+ scrollbar-gutter: stable;
.data-list-container-inner {
@@ -186,6 +199,20 @@
}
// override antd style
+.ant-checkbox {
+ border-radius: 2px;
+
+ .ant-checkbox-inner {
+ border-radius: 2px;
+ width: 18px;
+ height: 18px;
+
+ &:after {
+ //inset-inline-start: 28%;
+ }
+ }
+}
+
.ant-message {
z-index: var(--message-z-index);
}
@@ -259,6 +286,7 @@
.select-value {
@apply text-blue-500 px-4 cursor-pointer h-[31px];
}
+
.options-list-container {
@apply overflow-auto py-1 drop-shadow absolute top-[30px];
border-radius: 0 0 0.75rem 0.75rem;
@@ -281,7 +309,8 @@
.tag-select-child-container {
.ant-popover-inner {
- @apply p-0 overflow-hidden drop-shadow shadow-none; //
+ @apply p-0 overflow-hidden drop-shadow shadow-none;
+ //
background: linear-gradient(180deg, rgb(235, 242, 253) 0%, rgb(244, 247, 252) 100%);
border-radius: 0 0.75rem 0.75rem 0;
transform: translate(16px, -7px);
diff --git a/src/components/icons/index.tsx b/src/components/icons/index.tsx
index 04c873f..575a6f8 100644
--- a/src/components/icons/index.tsx
+++ b/src/components/icons/index.tsx
@@ -69,13 +69,11 @@ export const IconPin = ({style, className}: IconProps) => (
)
export const IconDelete = ({style, className}: IconProps) => (
)
export const IconAddText = ({style, className}: IconProps) => (
@@ -84,6 +82,8 @@ export const IconAddText = ({style, className}: IconProps) => (
+
)
@@ -130,9 +130,8 @@ export const IconLive = ({style, className}: IconProps) => (
export const IconEdit = ({style, className}: IconProps) => (
)
\ No newline at end of file
diff --git a/src/components/scoller/button-to-top.tsx b/src/components/scoller/button-to-top.tsx
new file mode 100644
index 0000000..66b7b52
--- /dev/null
+++ b/src/components/scoller/button-to-top.tsx
@@ -0,0 +1,26 @@
+import {Button} from "antd";
+import {ArrowUpOutlined} from "@ant-design/icons";
+
+
+type ButtonToTopProps = {
+ onClick?: () => void;
+ visible?: boolean;
+ container?: HTMLElement | string;
+}
+export default function ButtonToTop(props: ButtonToTopProps) {
+ return (
+
+ {props.visible &&
}
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/scoller/infinite-scroller.tsx b/src/components/scoller/infinite-scroller.tsx
index e25bd78..288c46a 100644
--- a/src/components/scoller/infinite-scroller.tsx
+++ b/src/components/scoller/infinite-scroller.tsx
@@ -1,12 +1,17 @@
-import React, {useEffect} from "react";
-import {useInViewport} from "ahooks";
+import React, {CSSProperties, useCallback, useEffect, useImperativeHandle, useRef} from "react";
+import {useInViewport, useScroll} from "ahooks";
+export type InfiniteScrollerRef = {
+ scrollToPosition: (top: number) => void
+};
export type InfiniteScrollerProps = {
children?: React.ReactNode;
className?: string;
rootClassName?: string;
+ style?: CSSProperties;
loadingPlaceholder?: React.ReactNode;
onCallback: (page: number, prevPage) => void;
+ onScroll?: (top: number) => void;
empty?: React.ReactNode;
loading?: boolean;
pagination?: {
@@ -15,10 +20,32 @@ export type InfiniteScrollerProps = {
total: number;
};
}
-
-export default function InfiniteScroller(props: InfiniteScrollerProps) {
+const InfiniteScroller = React.forwardRef((props, ref) => {
const {pagination} = props;
const [inView] = useInViewport(() => document.querySelector('.data-load-control-element'))
+ const scrollContainerRef = useRef(null)
+ const scrollPosition = useScroll(scrollContainerRef);
+ const scrollToPosition = useCallback((top: number) => {
+ if (scrollContainerRef.current) {
+ console.log('xaf');
+ scrollContainerRef.current.scrollTo({
+ top,
+ behavior: 'smooth'
+ })
+ }
+ }, [scrollContainerRef])
+
+ useImperativeHandle(ref, () => {
+ return {
+ scrollToPosition
+ }
+ })
+
+ useEffect(() => {
+ if (scrollPosition && props.onScroll) {
+ props.onScroll(scrollPosition.top)
+ }
+ }, [scrollPosition])
useEffect(() => {
if (!pagination) return;
@@ -30,16 +57,18 @@ export default function InfiniteScroller(props: InfiniteScrollerProps) {
}
}
}, [inView])
- return (
+
+ return (
{props.children}
{props?.pagination && props.pagination.total > props.pagination.limit * props.pagination.page && (props.loadingPlaceholder ||
)}
{props?.empty && props.pagination?.total == 0 &&
-
- {props.empty}
+
+ {props.empty}
}
);
-}
\ No newline at end of file
+}) //(props: InfiniteScrollerProps) =>{}
+export default InfiniteScroller
\ No newline at end of file
diff --git a/src/pages/news/components/edit-search-form.tsx b/src/pages/news/components/edit-search-form.tsx
index 094b77d..ee66dd7 100644
--- a/src/pages/news/components/edit-search-form.tsx
+++ b/src/pages/news/components/edit-search-form.tsx
@@ -49,11 +49,11 @@ export default function EditSearchForm(props: {
placeholder="请输入新闻标题关键词进行搜索"
onPressEnter={handleSubmit}
/>
-
来源
-
+ {/*
来源*/}
+ {/*
*/}
)
diff --git a/src/pages/news/components/style.module.scss b/src/pages/news/components/style.module.scss
index 708fc0b..7fd0a67 100644
--- a/src/pages/news/components/style.module.scss
+++ b/src/pages/news/components/style.module.scss
@@ -31,10 +31,51 @@
}
.newListTable{
:global{
- .header{}
- .body{}
.row{
- @apply bg-white mt-2 p-4 rounded;
+ @apply bg-white mt-2 py-2 px-4 rounded-xl gap-2 border;
+ border-width: 2px;
+ &.checked{
+ @apply border-primary-blue bg-primary-blue-bg;
+ }
+ }
+ .col{
+ @apply flex items-center relative pl-6;
+ height: 44px;
+ &:after{
+ @apply absolute;
+ border-right: solid 1px #e8e8e8;
+ content: ' ';
+ top:2px;
+ bottom: 2px;
+ left:0;
+ }
+ }
+ .title{
+ @apply flex-1 pl-0;
+ &:after{
+ display: none;
+ }
+ }
+ .source{
+ width: 150px;
+ }
+ .time{
+ width: 150px;
+ }
+ .operations{
+ @apply gap-4;
+ width: 100px;
+ }
+ .header{
+ @apply bg-primary-bg;
+ .operations{
+ }
+ }
+ .body{}
+ .icon-btn{
+ @apply text-gray-400 hover:text-blue-500 cursor-pointer;
+ font-size: 18px;
+
}
}
}
\ No newline at end of file
diff --git a/src/pages/news/edit.tsx b/src/pages/news/edit.tsx
index 0bf5626..2eaeced 100644
--- a/src/pages/news/edit.tsx
+++ b/src/pages/news/edit.tsx
@@ -1,142 +1,136 @@
-import {Button, Checkbox, Pagination, Space, Table, TableColumnsType, TableProps, Typography} from "antd";
+import {Checkbox, Space} from "antd";
-import {Card} from "@/components/card";
-import React, {useState} from "react";
+import React, {useRef, useState} from "react";
import {useRequest} from "ahooks";
import {formatTime} from "@/util/strings.ts";
import ArticleEditModal from "@/components/article/edit-modal.tsx";
import {getList} from "@/service/api/article.ts";
import EditSearchForm from "@/pages/news/components/edit-search-form.tsx";
import ButtonPush2Video from "@/pages/news/components/button-push2video.tsx";
-import {Key} from "antd/es/table/interface";
import styles from './components/style.module.scss'
-import InfiniteScroller from "@/components/scoller/infinite-scroller.tsx";
+import InfiniteScroller, {InfiniteScrollerRef} from "@/components/scoller/infinite-scroller.tsx";
+import {IconDelete, IconEdit} from "@/components/icons";
+import {clsx} from "clsx";
+import ButtonToTop from "@/components/scoller/button-to-top.tsx";
export default function NewEdit() {
+ const [state, setState] = useState<{
+ checkAll?: boolean;
+ showToTop?: boolean;
+ }>({})
const [editId, setEditId] = useState(-1)
const [selectedRowKeys, setSelectedRowKeys] = useState
([])
+
const [params, setParams] = useState({
pagination: {page: 1, limit: 10}
})
- const {data, refresh, loading} = useRequest(() => getList(params), {refreshDeps: [params]})
+ const [data, setData] = useState