<commit_before>import { useAppSelector } from '#A/hooks'
import { MzHeader } from '#C/header/MzHeader'
import { MzColumn, MzTable } from '#C/table/MzTable'
import { useLocal } from '#H/useLocal'
import { useOnceRequest } from '#H/useOnce'
import { thenCompare } from '#U/compare'
import { isJustUpdate } from '#U/date/check'
import { formatTimeout } from '#U/date/timeout'
import { fetchResult } from '#U/fetch/fetchResult'
import { UrlBuilder } from '#U/fetch/urlBuilder'
import { EditOutlined, UnorderedListOutlined } from '@ant-design/icons'
import { Link, useNavigate } from 'react-router-dom'
import './DiscGroups.scss'

import { apiToGroups, linkToGroups } from '#A/links'
import { viewTypes } from '#A/metas'
import { IGroupCount } from '#T/disc'
import { Button } from 'antd'
import { useState } from 'react'

const adminCols = buildColumns()
const guestCols = adminCols.filter((col) => !['edit', 'item'].includes(col.key))

const defaultSort = compareDiscGroups()

export default function DiscGroups() {
  const navigate = useNavigate()
  const hasBasic = useAppSelector((state) => state.session.hasBasic)

  const [isAdmin, setIsAdmin] = useLocal('groups-isadmin', false)
  const [hasSave, setHasSave] = useLocal('groups-hassave', false)
  const [hasMore, setHasMore] = useState(false)

  const apiUrl = new UrlBuilder(apiToGroups())
    .append('hasPrivate', hasBasic && isAdmin)
    .append('hasDisable', hasSave || hasMore)
    .toString()

  const { data: groups, ...state } = useOnceRequest(
    () => fetchResult<IGroupCount[]>(apiUrl).then((result) => result.data),
    { refreshDeps: [apiUrl] }
  )

  const lastCols = hasBasic && isAdmin ? adminCols : guestCols

  return (
    <div className="DiscGroups" style={{ maxWidth: 650 }}>
      <MzHeader
        title="推荐列表"
        state={state}
        items={[
          {
            key: 'K1',
            label: '添加列表',
            onClick: () => navigate(linkToGroups(`/add`)),
            disabled: !hasBasic,
          },
          {
            key: 'K2',
            label: isAdmin ? '浏览模式' : '管理模式',
            onClick: () => setIsAdmin(!isAdmin),
            disabled: !hasBasic,
          },
          {
            key: 'K3',
            label: hasSave ? '隐藏存档' : '显示存档',
            onClick: () => setHasSave(!hasSave),
          },
        ]}
      />
      {groups && (
        <MzTable
          tag="groups"
          rows={groups}
          cols={lastCols}
          trClass={trClass}
          defaultSort={defaultSort}
        />
      )}
      {!hasMore && (
        <Button type="link" onClick={() => setHasMore(true)} style={{ marginTop: 8 }}>
          显示停止更新的列表
        </Button>
      )}
    </div>
  )
}

function trClass(t: IGroupCount) {
  return { warning: t.viewType === 'PrivateList' }
}

function buildColumns(): MzColumn<IGroupCount>[] {
  return [
    {
      key: 'idx',
      title: '#',
      format: (row, idx) => idx + 1,
    },
    {
      key: 'title',
      title: '列表标题',
      format: (row) => {
        let color = isJustUpdate(row.modifyTime, 1) ? 'red' : '#C67532'
        return (
          <span>
            <Link to={linkToGroups(`/${row.key}/discs`)}>{row.title}</Link>
            <span style={{ color, marginLeft: 8 }}>({row.discCount})</span>
          </span><commit_msg>feat: Find groups with filter<commit_after>import { useAppSelector } from '#A/hooks'
import { MzHeader } from '#C/header/MzHeader'
import { MzColumn, MzTable } from '#C/table/MzTable'
import { useLocal } from '#H/useLocal'
import { useOnceRequest } from '#H/useOnce'
import { thenCompare } from '#U/compare'
import { fetchResult } from '#U/fetch/fetchResult'
import { EditOutlined, UnorderedListOutlined } from '@ant-design/icons'
import { Button, Radio } from 'antd'
import { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import './DiscGroups.scss'

import { apiToGroups, linkToGroups } from '#A/links'
import { viewTypes } from '#A/metas'
import { IGroupCount } from '#T/disc'
import { isJustUpdate } from '#U/date/check'
import { formatTimeout } from '#U/date/timeout'

const adminCols = buildColumns()
const guestCols = adminCols.filter((col) => !['edit', 'item'].includes(col.key))

const defaultSort = compareDiscGroups()

export default function DiscGroups() {
  const navigate = useNavigate()
  const hasBasic = useAppSelector((state) => state.session.hasBasic)

  const [filter, setFilter] = useLocal('groups-filter', 'top')
  const [isMore, setIsMore] = useState(false)

  const getPub = filter === 'top' && isMore === true
  const apiUrl = apiToGroups(`?filter=${getPub ? 'pub' : filter}`)

  const { data: groups, ...state } = useOnceRequest(
    () => fetchResult<IGroupCount[]>(apiUrl).then((result) => result.data),
    { refreshDeps: [apiUrl] }
  )

  const lastCols = hasBasic && filter === 'all' ? adminCols : guestCols

  return (
    <div className="DiscGroups" style={{ maxWidth: 650 }}>
      <MzHeader
        title="推荐列表"
        state={state}
        items={[
          {
            key: 'K1',
            label: '添加列表',
            onClick: () => navigate(linkToGroups(`/add`)),
            disabled: !hasBasic,
          },
          {
            key: 'K2',
            label: '设置过滤',
            children: [
              {
                key: 'S1',
                label: <Radio checked={filter === 'top'}>显示推荐列表</Radio>,
                onClick: () => setFilter('top'),
              },
              {
                key: 'S2',
                label: <Radio checked={filter === 'pub'}>显示公开列表</Radio>,
                onClick: () => setFilter('pub'),
              },
              {
                key: 'S3',
                label: <Radio checked={filter === 'all'}>管理所有列表</Radio>,
                onClick: () => setFilter('all'),
                disabled: !hasBasic,
              },
            ],
          },
        ]}
      />
      {groups && (
        <MzTable
          tag="groups"
          rows={groups}
          cols={lastCols}
          trClass={trClass}
          defaultSort={defaultSort}
        />
      )}
      {filter === 'top' && isMore === false && (
        <Button type="link" onClick={() => setIsMore(true)} style={{ marginTop: 8 }}>
          点击加载更多列表
        </Button>
      )}
    </div>
  )
}

function trClass(t: IGroupCount) {
  return { warning: t.viewType === 'PrivateList' }
}

function buildColumns(): MzColumn<IGroupCount>[] {
  return [
    {
      key: 'idx',
      title: '#',
      format: (row, idx) => idx + 1,
    },
    {
      key: 'title',
      title: '列表标题',
      format: (row) => {
        let color = isJustUpdate(row.modifyTime, 1) ? 'red' : '#C67532'
        return (
          <span>
            <Link to={linkToGroups(`/${row.key}/discs`)}>{row.title}</Link>
            <span style={{ color, marginLeft: 8 }}>({row.discCount})</span>
          </span>
{'fraction_non_alphanumeric': 0.16196158323632132, 'fraction_numerical': 0.004656577415599534, 'mean_word_length': 2.360880195599022, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3814854', 'n_tokens_mistral': 2224, 'n_tokens_neox': 2218, 'n_words': 476}