Skip to content

Commit

Permalink
chore: create log-validator-bulk component #57
Browse files Browse the repository at this point in the history
  • Loading branch information
wazolab committed Apr 23, 2024
1 parent b2efe27 commit 7fbc5f8
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 102 deletions.
11 changes: 11 additions & 0 deletions components/LogValidatorBulk.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
defineEmits(['bulkValidation'])
</script>

<template>
<el-button-group>
<el-button type="primary" @click="$emit('bulkValidation')">
✓ {{ $t('logs.validate_selection') }}
</el-button>
</el-button-group>
</template>
103 changes: 5 additions & 98 deletions components/Logs.vue
Original file line number Diff line number Diff line change
@@ -1,121 +1,28 @@
<script setup lang="ts">
import { intersection, uniq } from 'underscore'
import LogsComponent from '~/components/LogsComponent.vue'
import type { Log, ObjectId, User } from '~/libs/types'
import type { Log, User } from '~/libs/types'
const props = defineProps<{
logs: Log[]
projectSlug: string
}>()
const emit = defineEmits<{
(e: 'removeLogs', objectIds: ObjectId[]): void
}>()
defineEmits(['validate'])
const logs = useState<Log[]>('logs')
const user = useState<User>('user')
const route = useRoute()
const logsWithFilter = computed(() => {
return logs.value.filter((log) => {
const changesetsUsers
= route.query.filterByUsers !== undefined
&& uniq(
(log.base ? log.changesets.slice(1) : log.changesets).map(
(changeset) => changeset.user,
),
)
return (
(route.query.filterByAction === undefined
|| Object.values(log.diff_attribs || {})
.concat(Object.values(log.diff_tags || {}))
.some(
(actions) =>
actions?.some(
(action) => action[0] === route.query.filterByAction,
) || false,
))
&& (route.query.filterByUserGroups === undefined
|| log.matches.some((match) =>
match.user_groups.includes(route.query.filterByUserGroups as string),
))
&& (route.query.filterBySelectors === undefined
|| log.matches.some((match) =>
matchFilterBySelectors(match.selectors),
))
&& (route.query.filterByUsers === undefined
|| (changesetsUsers
&& changesetsUsers.length === 1
&& changesetsUsers[0] === route.query.filterByUsers))
&& (route.query.filterByDate === undefined
|| log.change.created.substring(0, 10) === route.query.filterByDate)
)
})
})
const isProjectUser = computed(() => {
return !!user.value.projects?.includes(props.projectSlug)
})
async function accept(objectIds: ObjectId[]) {
try {
await useFetchWithCache(
'accept',
`${useRuntimeConfig().public.API}/projects/${props.projectSlug}/changes_logs/accept`,
{
credentials: 'include',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(objectIds),
},
)
emit('removeLogs', objectIds)
}
catch (err: any) {
ElMessage.error(err.message)
}
}
function accept_selection() {
const objectIds = logsWithFilter.value.map((log) => ({
objtype: log.objtype,
id: log.id,
version: log.change.version,
deleted: log.change.deleted,
}))
accept(objectIds)
}
const router = useRouter()
function reset_filter() {
router.replace({ ...route, query: undefined })
}
function validate_selection() {
accept_selection()
reset_filter()
}
const scrollCount = ref(10)
function scrollLoad() {
scrollCount.value += 10
}
function matchFilterBySelectors(selectors: string[]): boolean {
return !!(route.query.filterBySelectors && intersection(selectors, route.query.filterBySelectors?.toString()).length > 0)
}
</script>

<template>
<div>
<el-button-group v-if="isProjectUser && (Object.keys(route.query).length)">
<el-button type="primary" @click="validate_selection">
✓ {{ $t('logs.validate_selection') }}
</el-button>
</el-button-group>

<h3>{{ $t('logs.data') }}</h3>
<p>{{ $t('logs.data_details') }}</p>
<ul>
Expand All @@ -125,12 +32,12 @@ function matchFilterBySelectors(selectors: string[]): boolean {

<el-space v-infinite-scroll="scrollLoad" :fill="true" wrap :size="20">
<LogsComponent
v-for="log in (logsWithFilter || []).slice(0, scrollCount + 1)"
v-for="log in (logs || []).slice(0, scrollCount + 1)"
:key="log.id"
:log="log"
:project="projectSlug"
:project-user="isProjectUser"
@accept="accept([$event])"
@accept="$emit('validate', $event)"
/>
</el-space>

Expand Down
103 changes: 99 additions & 4 deletions pages/[project]/changes_logs.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<script setup lang="ts">
import { intersection, uniq } from 'underscore'
import type { Geometry } from 'geojson'
import type { Log, ObjectId, Project } from '~/libs/types'
import type { Log, ObjectId, Project, User } from '~/libs/types'
definePageMeta({
validate({ params }) {
return /^[-_:a-zA-Z0-9]+$/.test(params.project as string)
},
})
const params = useRoute().params
const projectSlug = params.project as string
const route = useRoute()
const projectSlug = route.params.project as string
const project = ref<Project>()
const logs = ref<Log[]>()
Expand All @@ -31,6 +32,47 @@ catch (err: any) {
ElMessage.error(err.message)
}
const logsFiltered = computed(() => {
if (!logs.value?.length) {
return []
}
return logs.value.filter((log) => {
const changesetsUsers
= route.query.filterByUsers !== undefined
&& uniq(
(log.base ? log.changesets.slice(1) : log.changesets).map(
(changeset) => changeset.user,
),
)
return (
(route.query.filterByAction === undefined
|| Object.values(log.diff_attribs || {})
.concat(Object.values(log.diff_tags || {}))
.some(
(actions) =>
actions?.some(
(action) => action[0] === route.query.filterByAction,
) || false,
))
&& (route.query.filterByUserGroups === undefined
|| log.matches.some((match) =>
match.user_groups.includes(route.query.filterByUserGroups as string),
))
&& (route.query.filterBySelectors === undefined
|| log.matches.some((match) =>
matchFilterBySelectors(match.selectors),
))
&& (route.query.filterByUsers === undefined
|| (changesetsUsers
&& changesetsUsers.length === 1
&& changesetsUsers[0] === route.query.filterByUsers))
&& (route.query.filterByDate === undefined
|| log.change.created.substring(0, 10) === route.query.filterByDate)
)
})
})
const baseGeoms = computed(() => {
if (!logs.value) {
return []
Expand All @@ -49,6 +91,15 @@ const changeGeoms = computed(() => {
return logs.value.map((log) => log.change.geom)
})
const user = useState<User>('user')
const isProjectUser = computed(() => {
return !!user.value.projects?.includes(projectSlug)
})
function matchFilterBySelectors(selectors: string[]): boolean {
return !!(route.query.filterBySelectors && intersection(selectors, route.query.filterBySelectors?.toString()).length > 0)
}
function removeLogs(objectIds: ObjectId[]) {
logs.value = logs.value?.filter(
(log) =>
Expand All @@ -57,6 +108,42 @@ function removeLogs(objectIds: ObjectId[]) {
) === -1,
)
}
async function validate(objectIds: ObjectId[]) {
try {
await useFetchWithCache(
'accept',
`${useRuntimeConfig().public.API}/projects/${projectSlug}/changes_logs/accept`,
{
credentials: 'include',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(objectIds),
},
)
removeLogs(objectIds)
}
catch (err: any) {
ElMessage.error(err.message)
}
}
const router = useRouter()
async function handleBulkValidation() {
const objectIds = logsFiltered.value.map((log) => ({
objtype: log.objtype,
id: log.id,
version: log.change.version,
deleted: log.change.deleted,
}))
validate(objectIds)
await router.replace({ ...route, query: undefined })
}
</script>

<template>
Expand All @@ -72,6 +159,14 @@ function removeLogs(objectIds: ObjectId[]) {
/>
</el-row>
<log-filters />
<logs :project-slug="projectSlug" @remove-logs="removeLogs($event)" />
<log-validator-bulk
v-if="isProjectUser && (Object.keys(route.query).length)"
@bulk-validation="handleBulkValidation"
/>
<logs
:logs="logsFiltered"
:project-slug="projectSlug"
@validate="validate"
/>
</el-container>
</template>

0 comments on commit 7fbc5f8

Please sign in to comment.