Skip to content

Commit

Permalink
feat: re-order local partial configs
Browse files Browse the repository at this point in the history
  • Loading branch information
magicdawn committed Nov 3, 2023
1 parent dd90a7a commit 1fb0aad
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 111 deletions.
1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"react-dom": "^18.2.0",
"react-monaco-editor": "^0.54.0",
"react-router-dom": "^6.18.0",
"react-sortablejs": "^6.1.4",
"react-spinkit": "^3.0.0",
"react-spinners": "^0.13.8",
"reuse-promise": "^2.0.0",
Expand Down
42 changes: 32 additions & 10 deletions packages/ui/src/page/library-rule-list/index.module.less
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
.page {
margin: 10px;
height: calc(100vh - 46px);
padding: 10px 0;
display: flex;
flex-direction: column;
overflow-y: hidden;

:global {
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 15px;
}

.list-items-container {
flex: 1;
overflow-y: scroll;
border-radius: 5px;
}

.list-item {
flex: 1;
margin-right: 5px;

display: flex;
justify-content: space-between;
align-items: center;

margin: 15px 15px;
border-radius: 10px;
border: 1px solid #ccc;
padding: 10px 10px;

.list-item-info {
flex: 1;
margin-right: 15px;
}

.list-item-actions {
flex-shrink: 0;
}
}

// https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/
Expand All @@ -28,19 +57,12 @@
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
// width: max-content;
// max-width: 100%;
}
}
}

.list-component {
border-radius: 5px;

:global(.ant-list-items) {
max-height: calc(100vh - 138px);
overflow-y: scroll;
}
}

.modal {
:global {
.label {
Expand Down
232 changes: 133 additions & 99 deletions packages/ui/src/page/library-rule-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
Form,
Input,
InputNumber,
List,
Modal,
Row,
Select,
Expand All @@ -35,6 +34,7 @@ import fse from 'fs-extra'
import Yaml from 'js-yaml'
import path from 'path'
import { KeyboardEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ReactSortable } from 'react-sortablejs'
import { proxy, useSnapshot } from 'valtio'
import RuleAddModal from './AddRuleModal'
import styles from './index.module.less'
Expand Down Expand Up @@ -136,126 +136,160 @@ export default function LibraryRuleList() {
const isDark = useIsDarkMode()
const iconFill = isDark ? '#eee' : '#333'

// const listForSortable = useMemo(() => {
// return list.map((item) => {
// return { id: item.id, name: item.name }
// })
// }, [list])

type SortableListItem = { id: string; name?: string }

const [listForSortable, setListForSortable] = useState<SortableListItem[]>(() => [])
useEffect(() => {
console.log(
'call setListForSortable',
list.map((x) => x.id)
)
setListForSortable(
list.map((x) => {
return { id: x.id, name: x.name }
})
)
}, [list.map((x) => x.id).join(',')])

const onSortableSetList = useMemoizedFn((newSortableList: SortableListItem[]) => {
setListForSortable(newSortableList)

const newIdList = newSortableList.map((x) => x.id)
if (list.map((x) => x.id).join('') !== newIdList.join('')) {
const newList = list.slice().sort((a, b) => {
const aIndex = newIdList.indexOf(a.id)
const bIndex = newIdList.indexOf(b.id)
return aIndex < bIndex ? -1 : 1
})
state.list = newList
}
})

return (
<div className={styles.page}>
<ModalAddOrEdit />

<List
size='default'
header={
<div className='header'>
<div style={{ fontSize: '2em' }}>配置源管理</div>
<span>
<Button ghost onClick={addRuleConfig}>
<FileAddOutlined />
新建纯规则配置
</Button>
<Button type='primary' onClick={add} style={{ marginLeft: 5 }}>
<FileAddOutlined />
新建配置
</Button>
</span>
</div>
}
className={styles.listComponent}
bordered
dataSource={list}
rowKey='id'
renderItem={(item, index) => {
const { type, name, id } = item
return (
<List.Item style={{ display: 'flex' }}>
<div className='list-item'>
<div className='name' style={{ display: 'flex', height: 24, alignItems: 'center' }}>
<span>名称: {name}</span>
<span style={{ marginLeft: 5, marginTop: 4 }}>
<div className='header'>
<div style={{ fontSize: '2em' }}>配置源管理</div>
<span>
<Button ghost onClick={addRuleConfig}>
<FileAddOutlined />
新建纯规则配置
</Button>
<Button type='primary' onClick={add} style={{ marginLeft: 5 }}>
<FileAddOutlined />
新建配置
</Button>
</span>
</div>

<div className='list-items-container'>
<ReactSortable list={listForSortable} setList={onSortableSetList}>
{list.map((item, index) => {
const { type, name, id } = item
return (
<div style={{ display: 'flex' }} key={id} className='list-item'>
<div className='list-item-info'>
<div
className='name'
style={{ display: 'flex', height: 24, alignItems: 'center' }}
>
<span>名称: {name}</span>
<span style={{ marginLeft: 5, marginTop: 4 }}>
{type === 'local' ? (
<SdCard theme='outline' size='18' fill={iconFill} title='本地规则' />
) : (
<LinkTwo theme='outline' size='18' fill={iconFill} title='远程规则' />
)}
</span>
</div>

<div className='info'>
{type === 'local' ? (
<SdCard theme='outline' size='18' fill={iconFill} title='本地规则' />
<Tooltip
title={
<div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>
{limitLines(item.content, 10)}
</div>
}
>
<div className='ellipsis'>内容: {firstLine(item.content)}</div>
</Tooltip>
) : (
<LinkTwo theme='outline' size='18' fill={iconFill} title='远程规则' />
<Tooltip
title={
<div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>
{item.url}
{/* debug use */}
{/* <p style={{ maxWidth: 500 }}>{JSON.stringify(item)}</p> */}
</div>
}
>
<div className='ellipsis'>链接: {item.url}</div>
</Tooltip>
)}
</span>
</div>

<div className='info'>
{type === 'local' ? (
<Tooltip
title={
<div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>
{limitLines(item.content, 10)}
</div>
}
>
<div className='ellipsis'>内容: {firstLine(item.content)}</div>
</Tooltip>
) : (
<Tooltip
title={
<div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>
{item.url}
{/* debug use */}
{/* <p style={{ maxWidth: 500 }}>{JSON.stringify(item)}</p> */}
</div>
}
>
<div className='ellipsis'>链接: {item.url}</div>
</Tooltip>
)}
</div>
</div>
</div>

<div>
<Space style={{ display: 'flex', alignItems: 'center' }}>
<Button
type='primary'
onClick={(e) => edit(item, index)}
onKeyDown={disableEnterAsClick}
>
编辑
</Button>

<Button
type='default'
onClick={(e) => view(item, index)}
onKeyDown={disableEnterAsClick}
>
查看
</Button>

<Button
type='primary'
danger
onClick={() => del(index)}
onKeyDown={disableEnterAsClick}
>
删除
</Button>
</Space>

{type === 'remote' && (
<Space style={{ display: 'flex', alignItems: 'center', marginTop: 5 }}>
<div className='list-item-actions'>
<Space style={{ display: 'flex', alignItems: 'center' }}>
<Button
type='primary'
onClick={(e) => updateRmote(index)}
onClick={(e) => edit(item, index)}
onKeyDown={disableEnterAsClick}
>
更新
编辑
</Button>

<Button
type='default'
onClick={(e) => view(item, index)}
onKeyDown={disableEnterAsClick}
>
查看
</Button>

<Button
type='primary'
danger
onClick={() => del(index)}
onKeyDown={disableEnterAsClick}
onClick={(e) => viewRmoteContents(index)}
>
查看内容
删除
</Button>
</Space>
)}

{type === 'remote' && (
<Space style={{ display: 'flex', alignItems: 'center', marginTop: 5 }}>
<Button
type='primary'
onClick={(e) => updateRmote(index)}
onKeyDown={disableEnterAsClick}
>
更新
</Button>

<Button
type='default'
onKeyDown={disableEnterAsClick}
onClick={(e) => viewRmoteContents(index)}
>
查看内容
</Button>
</Space>
)}
</div>
</div>
</List.Item>
)
}}
/>
)
})}
</ReactSortable>
</div>
</div>
)
}
Expand Down
Loading

0 comments on commit 1fb0aad

Please sign in to comment.