Skip to content

Commit

Permalink
Support filtering records and sites without setting categories (#369)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheepzh committed Jan 18, 2025
1 parent 2e21d46 commit 760d400
Show file tree
Hide file tree
Showing 40 changed files with 429 additions and 385 deletions.
5 changes: 3 additions & 2 deletions src/database/site-database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* https://opensource.org/licenses/MIT
*/

import { CATE_NOT_SET_ID } from "@util/site"
import BaseDatabase from "./common/base-database"
import { REMAIN_WORD_PREFIX } from "./common/constant"

Expand Down Expand Up @@ -116,11 +117,11 @@ function buildFilter(condition: SiteCondition): (site: timer.site.SiteInfo) => b
let cateFilter = typeof cateIds === 'number' ? [cateIds] : (cateIds?.length ? cateIds : undefined)
let typeFilter = typeof types === 'string' ? [types] : (types?.length ? types : undefined)
return site => {
const { host: siteHost, alias: siteAlias, cate } = site || {}
const { host: siteHost, alias: siteAlias, cate, type } = site || {}
if (host && !siteHost.includes(host)) return false
if (alias && !siteAlias?.includes(alias)) return false
if (fuzzyQuery && !(siteHost?.includes(fuzzyQuery) || siteAlias?.includes(fuzzyQuery))) return false
if (cateFilter && !cateFilter.includes(cate)) return false
if (cateFilter && (!cateFilter.includes(cate ?? CATE_NOT_SET_ID) || type !== 'normal')) return false
if (typeFilter && !matchType(typeFilter, site)) return false
return true
}
Expand Down
74 changes: 39 additions & 35 deletions src/pages/app/components/Analysis/components/AnalysisFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
* https://opensource.org/licenses/MIT
*/

import TimeFormatFilterItem from "@app/components/common/TimeFormatFilterItem"
import { SELECT_WRAPPER_STYLE } from "@app/components/common/filter/common"
import TimeFormatFilterItem from "@app/components/common/filter/TimeFormatFilterItem"
import { t } from "@app/locale"
import { useManualRequest, useState } from "@hooks"
import Flex from "@pages/components/Flex"
import siteService from "@service/site-service"
import statService, { type HostSet } from "@service/stat-service"
import { ElOption, ElSelect, ElTag } from "element-plus"
Expand Down Expand Up @@ -73,7 +75,7 @@ const SiteOptionTag = defineComponent({
}
})

const _default = defineComponent({
const AnalysisFilter = defineComponent({
props: {
site: Object as PropType<timer.site.SiteKey>,
timeFormat: String as PropType<timer.app.TimeFormat>
Expand All @@ -93,39 +95,41 @@ const _default = defineComponent({
watch(domainKey, () => ctx.emit('siteChange', calcSite(domainKey.value)))
watch(timeFormat, () => ctx.emit('timeFormatChange', timeFormat.value))

return () => <>
<ElSelect
placeholder={HOST_PLACEHOLDER}
class="filter-item"
modelValue={domainKey.value}
filterable
remote
loading={trendSearching.value}
clearable
remoteMethod={searchRemote}
onChange={setDomainKey}
onClear={() => setDomainKey()}
>
{(trendDomainOptions.value || [])?.map(
site => (
<ElOption
value={calcKey(site)}
label={labelOfHostInfo(site)}
>
<span>{site.host}</span>
{site.alias && <ElTag size="small" type="info">{site.alias}</ElTag>}
{site.type === 'merged' && <SiteOptionTag text={MERGED_TAG_TXT} />}
{site.type === 'virtual' && <SiteOptionTag text={VIRTUAL_TAG_TXT} />}
</ElOption>
)
)}
</ElSelect>
<TimeFormatFilterItem
defaultValue={timeFormat.value}
onChange={setTimeFormat}
/>
</>
return () => (
<Flex gap={10}>
<ElSelect
placeholder={HOST_PLACEHOLDER}
modelValue={domainKey.value}
filterable
remote
loading={trendSearching.value}
clearable
remoteMethod={searchRemote}
onChange={setDomainKey}
onClear={() => setDomainKey()}
style={SELECT_WRAPPER_STYLE}
>
{(trendDomainOptions.value || [])?.map(
site => (
<ElOption
value={calcKey(site)}
label={labelOfHostInfo(site)}
>
<span>{site.host}</span>
{site.alias && <ElTag size="small" type="info">{site.alias}</ElTag>}
{site.type === 'merged' && <SiteOptionTag text={MERGED_TAG_TXT} />}
{site.type === 'virtual' && <SiteOptionTag text={VIRTUAL_TAG_TXT} />}
</ElOption>
)
)}
</ElSelect>
<TimeFormatFilterItem
defaultValue={timeFormat.value}
onChange={setTimeFormat}
/>
</Flex>
)
}
})

export default _default
export default AnalysisFilter
5 changes: 2 additions & 3 deletions src/pages/app/components/Analysis/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import { defineComponent } from "vue"
import { useRoute, useRouter } from "vue-router"
import ContentContainer from "../common/ContentContainer"
import { type AnalysisQuery } from "./common"
import Filter from "./components/AnalysisFilter"
import AnalysisFilter from "./components/AnalysisFilter"
import Summary from "./components/Summary"
import Trend from "./components/Trend"
import { initProvider } from "./context"
import './style.sass'

function getSiteFromQuery(): timer.site.SiteKey {
// Process the query param
Expand Down Expand Up @@ -48,7 +47,7 @@ const _default = defineComponent(() => {
initProvider(site, timeFormat, rows)
return () => <ContentContainer
v-slots={{
filter: () => <Filter
filter: () => <AnalysisFilter
site={site.value}
timeFormat={timeFormat.value}
onSiteChange={setSite}
Expand Down
3 changes: 0 additions & 3 deletions src/pages/app/components/Analysis/style.sass

This file was deleted.

31 changes: 17 additions & 14 deletions src/pages/app/components/Habit/components/HabitFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
* https://opensource.org/licenses/MIT
*/

import DateRangeFilterItem from "@app/components/common/DateRangeFilterItem"
import TimeFormatFilterItem from "@app/components/common/TimeFormatFilterItem"
import DateRangeFilterItem from "@app/components/common/filter/DateRangeFilterItem"
import TimeFormatFilterItem from "@app/components/common/filter/TimeFormatFilterItem"
import { t } from "@app/locale"
import { useState } from "@hooks"
import Flex from "@pages/components/Flex"
import { type ElementDatePickerShortcut } from "@pages/element-ui/date"
import { daysAgo } from "@util/time"
import { defineComponent, watch, type PropType } from "vue"
Expand Down Expand Up @@ -47,18 +48,20 @@ const _default = defineComponent({
timeFormat: timeFormat.value,
}))

return () => <>
<DateRangeFilterItem
clearable={false}
defaultRange={dateRange.value}
shortcuts={SHORTCUTS}
onChange={setDateRange}
/>
<TimeFormatFilterItem
defaultValue={timeFormat.value}
onChange={setTimeFormat}
/>
</>
return () => (
<Flex gap={10}>
<DateRangeFilterItem
clearable={false}
defaultRange={dateRange.value}
shortcuts={SHORTCUTS}
onChange={setDateRange}
/>
<TimeFormatFilterItem
defaultValue={timeFormat.value}
onChange={setTimeFormat}
/>
</Flex>
)
}
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* https://opensource.org/licenses/MIT
*/

import SelectFilterItem from '@app/components/common/SelectFilterItem'
import SelectFilterItem from '@app/components/common/filter/SelectFilterItem'
import { t } from '@app/locale'
import { useCached } from '@hooks'
import { type HabitMessage } from '@i18n/message/app/habit'
Expand Down
75 changes: 41 additions & 34 deletions src/pages/app/components/Limit/LimitFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
*/

import { createTabAfterCurrent } from "@api/chrome/tab"
import ButtonFilterItem from "@app/components/common/ButtonFilterItem"
import InputFilterItem from "@app/components/common/InputFilterItem"
import SwitchFilterItem from "@app/components/common/SwitchFilterItem"
import ButtonFilterItem from "@app/components/common/filter/ButtonFilterItem"
import InputFilterItem from "@app/components/common/filter/InputFilterItem"
import SwitchFilterItem from "@app/components/common/filter/SwitchFilterItem"
import { t } from "@app/locale"
import { OPTION_ROUTE } from "@app/router/constants"
import { Operation, Plus, SetUp } from "@element-plus/icons-vue"
import { useState } from "@hooks"
import { getAppPageUrl } from "@util/constant/url"
import { defineComponent, watch, type PropType } from "vue"
import type { LimitFilterOption } from "./types"
import Flex from "@pages/components/Flex"

const optionPageUrl = getAppPageUrl(OPTION_ROUTE, { i: 'dailyLimit' })

Expand All @@ -32,37 +33,43 @@ const _default = defineComponent({
const [url, setUrl] = useState(props.defaultValue?.url)
const [onlyEnabled, setOnlyEnabled] = useState(props.defaultValue?.onlyEnabled)
watch([url, onlyEnabled], () => ctx.emit("change", { url: url.value, onlyEnabled: onlyEnabled.value }))
return () => <>
<InputFilterItem
defaultValue={url.value}
placeholder="URL + ↵"
onSearch={setUrl}
/>
<SwitchFilterItem
historyName="onlyEnabled"
label={t(msg => msg.limit.filterDisabled)}
defaultValue={onlyEnabled.value}
onChange={setOnlyEnabled}
/>
<ButtonFilterItem
text={t(msg => msg.limit.button.test)}
type="primary"
icon={<Operation />}
onClick={() => ctx.emit("test")}
/>
<ButtonFilterItem
text={t(msg => msg.base.option)}
icon={<SetUp />}
type="primary"
onClick={() => createTabAfterCurrent(optionPageUrl)}
/>
<ButtonFilterItem
text={t(msg => msg.button.create)}
type="success"
icon={<Plus />}
onClick={() => ctx.emit("create")}
/>
</>
return () => (
<Flex justify="space-between" gap={10}>
<Flex gap={10}>
<InputFilterItem
defaultValue={url.value}
placeholder="URL + ↵"
onSearch={setUrl}
/>
<SwitchFilterItem
historyName="onlyEnabled"
label={t(msg => msg.limit.filterDisabled)}
defaultValue={onlyEnabled.value}
onChange={setOnlyEnabled}
/>
</Flex>
<Flex gap={10}>
<ButtonFilterItem
text={t(msg => msg.limit.button.test)}
type="primary"
icon={<Operation />}
onClick={() => ctx.emit("test")}
/>
<ButtonFilterItem
text={t(msg => msg.base.option)}
icon={<SetUp />}
type="primary"
onClick={() => createTabAfterCurrent(optionPageUrl)}
/>
<ButtonFilterItem
text={t(msg => msg.button.create)}
type="success"
icon={<Plus />}
onClick={() => ctx.emit("create")}
/>
</Flex>
</Flex>
)
}
})

Expand Down
4 changes: 2 additions & 2 deletions src/pages/app/components/Report/ReportFilter/DownloadFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Download } from "@element-plus/icons-vue"
import { ElButton, ElDropdown, ElDropdownItem, ElDropdownMenu, ElIcon } from "element-plus"
import { defineComponent } from "vue"
import type { FileFormat } from "../types"
import { ICON_BTN_STYLE } from "./common"

const ALL_FILE_FORMATS: FileFormat[] = ["json", "csv"]

Expand All @@ -20,7 +21,6 @@ const _default = defineComponent({
const handleClick = (format: FileFormat) => ctx.emit('download', format)
return () => (
<ElDropdown
class="export-dropdown"
showTimeout={100}
v-slots={{
dropdown: () => <ElDropdownMenu>
Expand All @@ -32,7 +32,7 @@ const _default = defineComponent({
</ElDropdownMenu>
}}
>
<ElButton size="small" class="record-filter-icon-button">
<ElButton size="small" style={ICON_BTN_STYLE}>
<ElIcon size={17} style={{ padding: "0 1px" }}>
<Download />
</ElIcon>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { t } from "@app/locale"
import { useCached } from "@hooks/index"
import { useCached } from "@hooks"
import Flex from "@pages/components/Flex"
import { ALL_MERGE_METHODS, processNewMethod } from "@util/merge"
import { ElCheckboxButton, ElCheckboxGroup, ElText } from "element-plus"
import { defineComponent, type PropType, watch } from "vue"
import "./merge-filter-item.sass"

const MergeFilterItem = defineComponent({
props: {
Expand All @@ -23,8 +24,10 @@ const MergeFilterItem = defineComponent({
}

return () => (
<Flex gap={9} class="merge-filter-item-wrapper">
<ElText>{t(msg => msg.shared.merge.mergeBy)}</ElText>
<Flex gap={9} class="merge-filter-item">
<ElText tag="b" type="info">
{t(msg => msg.shared.merge.mergeBy)}
</ElText>
<ElCheckboxGroup modelValue={data.value} onChange={handleChange}>
{ALL_MERGE_METHODS.filter(m => m !== 'cate' || !props.hideCate).map(method => (
<ElCheckboxButton value={method}>
Expand Down
5 changes: 3 additions & 2 deletions src/pages/app/components/Report/ReportFilter/RemoteClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useRequest } from "@hooks"
import statService from "@service/stat-service"
import { ElButton, ElIcon, ElTooltip } from "element-plus"
import { computed, defineComponent, ref, watch } from "vue"
import { ICON_BTN_STYLE } from "./common"

const _default = defineComponent({
emits: {
Expand All @@ -25,10 +26,10 @@ const _default = defineComponent({
return () => (
<ElTooltip trigger="hover" placement="bottom-start" effect="dark" content={content.value}>
<ElButton
v-show={visible.value}
size="small"
style={{ display: visible.value ? 'inline-flex' : 'none' }}
style={ICON_BTN_STYLE}
type={readRemote.value ? 'primary' : null}
class="record-filter-icon-button"
onClick={() => readRemote.value = !readRemote.value}
>
<ElIcon size={17} style={{ padding: "0 1px" }}>
Expand Down
7 changes: 7 additions & 0 deletions src/pages/app/components/Report/ReportFilter/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { type StyleValue } from "vue"

export const ICON_BTN_STYLE: StyleValue = {
width: '30px',
height: '30px',
padding: '7px',
}
Loading

0 comments on commit 760d400

Please sign in to comment.