Skip to content

Commit

Permalink
feat: create log-filters components #57
Browse files Browse the repository at this point in the history
  • Loading branch information
wazolab committed Apr 22, 2024
1 parent d680335 commit be45d67
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 169 deletions.
196 changes: 196 additions & 0 deletions components/LogFilters.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
<script setup lang="ts">
import { countBy, indexBy, intersection, sortBy, uniq } from 'underscore'
import type { Log } from '~/libs/types'
const logs = useState<Log[]>('logs')
const route = useRoute()
const filterByAction = route.query.filterByAction as string | undefined
const filterByUserGroups = route.query.filterByUserGroups as string | undefined
const filterBySelectors = route.query.filterBySelectors as string[] | undefined
const filterByUsers = route.query.filterByUsers as string | undefined
const filterByDate = route.query.filterByDate as string | undefined
const stats = computed((): [string, number][] => {
const actions = logs.value
.map((log) =>
uniq(
[
...Object.values(log.diff_attribs || {}),
...Object.values(log.diff_tags || {}),
]
.flat(1)
.map((action) => action[0]),
),
)
.flat(1)
return getStats(actions)
})
const statUserGroups = computed(() => {
const userGroups = logs.value
.map((log) => uniq(log.matches.map((m) => m.user_groups).flat(2)))
.flat(1)
return getStats(userGroups)
})
const statSelectors = computed(() => {
const matches = logs.value.map((log) => uniq(log.matches).flat()).flat(1)
return getStats(matches, (m) => m.selectors.join(';'))
})
const statUsers = computed(() => {
const users = logs.value
.map((log) =>
(log.base ? log.changesets.slice(1) : log.changesets).map(
(changeset) => changeset.user,
),
)
.flat(2)
return getStats(users)
})
const statDates = computed(() => {
const dates = logs.value.map((log) => log.change.created.substring(0, 10))
return getStats(dates).sort()
})
function getStats<Type>(
data: Type[],
key: (o: Type) => string = (i) => `${i}`,
): [Type, number][] {
const index = indexBy(data, key)
return sortBy(
Object.entries(countBy(data, key)) as [string, number][],
([_key, count]) => -count,
).map(([key, count]) => [index[key], count])
}
function matchFilterBySelectors(selectors: string[]): boolean {
return (
filterBySelectors !== undefined && intersection(selectors, filterBySelectors).length > 0
)
}
</script>

<template>
<aside>
<h3>{{ $t('logs.filters') }}</h3>
<el-row style="margin-top: 20px">
<el-badge :value="logs.length" class="item" :max="999">
<el-tag size="small">
{{ $t('logs.objects') }}
</el-tag>
</el-badge>
<el-badge
v-for="[key, count] in stats"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="danger"
:plain="filterByAction !== key"
:disabled="(filterByAction && filterByAction !== key) || false"
size="small"
@click="filterByAction = filterByAction !== key ? key : undefined"
>
{{ key }}
</el-button>
</el-badge>
</el-row>
<el-row>
<el-badge
v-for="[key, count] in statUserGroups"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="primary"
:plain="filterByUserGroups !== key"
:disabled="(filterByUserGroups && filterByUserGroups !== key) || false"
size="small"
@click="
filterByUserGroups = filterByUserGroups !== key ? key : undefined
"
>
📌 {{ key }}
</el-button>
</el-badge>
</el-row>
<el-row>
<el-badge
v-for="[match, count] in statSelectors"
:key="match.selectors.join(';')"
:value="count"
class="item"
:max="999"
>
<el-button
type="warning"
:plain="filterBySelectors !== match.selectors"
:disabled="
(filterBySelectors && !matchFilterBySelectors(match.selectors))
|| false
"
size="small"
@click="
filterBySelectors = !matchFilterBySelectors(match.selectors)
? match.selectors
: undefined
"
>
🏷️ {{ $i18nHash(match.name) || match.selectors.join(' ') }}
</el-button>
</el-badge>
</el-row>
<el-row>
<el-badge
v-for="[key, count] in statUsers.slice(0, 20)"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="info"
:plain="filterByUsers !== key"
:disabled="(filterByUsers && filterByUsers !== key) || false"
size="small"
@click="filterByUsers = filterByUsers !== key ? key : undefined"
>
👤 {{ key }}
</el-button>
</el-badge>
<span v-if="statUsers.length > 20">{{ $t('logs.tags_more') }}</span>
</el-row>
<el-row>
<el-badge
v-for="[key, count] in statDates"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="primary"
:plain="filterByDate !== key"
:disabled="(filterByDate && filterByDate !== key) || false"
size="small"
@click="filterByDate = filterByDate !== key ? key : undefined"
>
📅 {{ key }}
</el-button>
</el-badge>
</el-row>
</aside>
</template>

<style scoped>
.item {
margin-top: 0.7em;
margin-right: 1.3em;
}
</style>
167 changes: 0 additions & 167 deletions components/Logs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,50 +74,6 @@ export default defineNuxtComponent({
},
computed: {
stats(): [string, number][] {
const actions = this.logs
.map((log) =>
_.uniq(
[
...Object.values(log.diff_attribs || {}),
...Object.values(log.diff_tags || {}),
]
.flat(1)
.map((action) => action[0]),
),
)
.flat(1)
return this.count(actions)
},
statSelectors() {
const matches = this.logs.map((log) => _.uniq(log.matches).flat()).flat(1)
return this.count(matches, (m) => m.selectors.join(';'))
},
statUserGroups() {
const userGroups = this.logs
.map((log) => _.uniq(log.matches.map((m) => m.user_groups).flat(2)))
.flat(1)
return this.count(userGroups)
},
statUsers() {
const users = this.logs
.map((log) =>
(log.base ? log.changesets.slice(1) : log.changesets).map(
(changeset) => changeset.user,
),
)
.flat(2)
return this.count(users)
},
statDates() {
const dates = this.logs.map((log) => log.change.created.substring(0, 10))
return this.count(dates).sort()
},
logsWithFilter() {
return this.logs.filter((log) => {
const changesetsUsers
Expand Down Expand Up @@ -161,17 +117,6 @@ export default defineNuxtComponent({
},
methods: {
count<Type>(
data: Type[],
key: (o: Type) => string = (i) => `${i}`,
): [Type, number][] {
const index = _.indexBy(data, key)
return _.sortBy(
Object.entries(_.countBy(data, key)) as [string, number][],
([_key, count]) => -count,
).map(([key, count]) => [index[key], count])
},
accept(objectIds: ObjectId[]) {
setLogs(useRuntimeConfig().public.API, this.project, 'accept', objectIds)
.then(() => this.$emit('removeLogs', objectIds))
Expand Down Expand Up @@ -234,118 +179,6 @@ export default defineNuxtComponent({

<template>
<div>
<h3>{{ $t('logs.filters') }}</h3>
<el-row style="margin-top: 20px">
<el-badge :value="logs.length" class="item" :max="999">
<el-tag size="small">
{{ $t('logs.objects') }}
</el-tag>
</el-badge>
<el-badge
v-for="[key, count] in stats"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="danger"
:plain="filterByAction !== key"
:disabled="(filterByAction && filterByAction !== key) || false"
size="small"
@click="filterByAction = filterByAction !== key ? key : undefined"
>
{{ key }}
</el-button>
</el-badge>
</el-row>
<el-row>
<el-badge
v-for="[key, count] in statUserGroups"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="primary"
:plain="filterByUserGroups !== key"
:disabled="(filterByUserGroups && filterByUserGroups !== key) || false"
size="small"
@click="
filterByUserGroups = filterByUserGroups !== key ? key : undefined
"
>
📌 {{ key }}
</el-button>
</el-badge>
</el-row>
<el-row>
<el-badge
v-for="[match, count] in statSelectors"
:key="match.selectors.join(';')"
:value="count"
class="item"
:max="999"
>
<el-button
type="warning"
:plain="filterBySelectors !== match.selectors"
:disabled="
(filterBySelectors && !matchFilterBySelectors(match.selectors))
|| false
"
size="small"
@click="
filterBySelectors = !matchFilterBySelectors(match.selectors)
? match.selectors
: undefined
"
>
🏷️ {{ $i18nHash(match.name) || match.selectors.join(' ') }}
</el-button>
</el-badge>
</el-row>
<el-row>
<el-badge
v-for="[key, count] in statUsers.slice(0, 20)"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="info"
:plain="filterByUsers !== key"
:disabled="(filterByUsers && filterByUsers !== key) || false"
size="small"
@click="filterByUsers = filterByUsers !== key ? key : undefined"
>
👤 {{ key }}
</el-button>
</el-badge>
<span v-if="statUsers.length > 20">{{ $t('logs.tags_more') }}</span>
</el-row>
<el-row>
<el-badge
v-for="[key, count] in statDates"
:key="key"
:value="count"
class="item"
:max="999"
>
<el-button
type="primary"
:plain="filterByDate !== key"
:disabled="(filterByDate && filterByDate !== key) || false"
size="small"
@click="filterByDate = filterByDate !== key ? key : undefined"
>
📅 {{ key }}
</el-button>
</el-badge>
</el-row>

<el-button-group
v-if="
isProjectUser
Expand Down
Loading

0 comments on commit be45d67

Please sign in to comment.