refactor: types and functional improvements

Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
liyasthomas 2022-04-07 18:39:12 +05:30
parent ebc536b835
commit d634828eca
2 changed files with 70 additions and 39 deletions

View file

@ -36,7 +36,7 @@
open open
> >
<summary <summary
class="flex items-center justify-between flex-1 min-w-0 cursor-pointer transition focus:outline-none text-secondaryLight text-tiny group" class="flex items-center justify-between flex-1 min-w-0 transition cursor-pointer focus:outline-none text-secondaryLight text-tiny group"
> >
<span <span
class="px-4 py-2 truncate transition group-hover:text-secondary capitalize-first" class="px-4 py-2 truncate transition group-hover:text-secondary capitalize-first"
@ -49,7 +49,7 @@
color="red" color="red"
:title="$t('action.remove')" :title="$t('action.remove')"
class="hidden group-hover:inline-flex" class="hidden group-hover:inline-flex"
@click.native="deleteBattleHistoryEntry(filteredHistoryGroup)" @click.native="deleteBatchHistoryEntry(filteredHistoryGroup)"
/> />
</summary> </summary>
<div <div
@ -59,11 +59,11 @@
<component <component
:is="page == 'rest' ? 'HistoryRestCard' : 'HistoryGraphqlCard'" :is="page == 'rest' ? 'HistoryRestCard' : 'HistoryGraphqlCard'"
:id="index" :id="index"
:entry="entry" :entry="entry.entry"
:show-more="showMore" :show-more="showMore"
@toggle-star="toggleStar(entry)" @toggle-star="toggleStar(entry.entry)"
@delete-entry="deleteHistory(entry)" @delete-entry="deleteHistory(entry.entry)"
@use-entry="useHistory(entry)" @use-entry="useHistory(entry.entry)"
/> />
</div> </div>
</details> </details>
@ -101,9 +101,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from "@nuxtjs/composition-api" import { computed, ref, Ref } from "@nuxtjs/composition-api"
import { useTimeAgo } from "@vueuse/core"
import { safelyExtractRESTRequest } from "@hoppscotch/data" import { safelyExtractRESTRequest } from "@hoppscotch/data"
import groupBy from "lodash/groupBy"
import { useTimeAgo } from "@vueuse/core"
import { pipe } from "fp-ts/function"
import * as A from "fp-ts/Array"
import { import {
useI18n, useI18n,
useReadonlyStream, useReadonlyStream,
@ -133,11 +136,11 @@ const confirmRemove = ref(false)
const toast = useToast() const toast = useToast()
const t = useI18n() const t = useI18n()
const groupByDate = (array: any[], key: string) => { type HistoryEntry = GQLHistoryEntry | RESTHistoryEntry
return array.reduce((rv: any, x: any) => {
;(rv[useTimeAgo(x[key]).value] = rv[useTimeAgo(x[key]).value] || []).push(x) type TimedHistoryEntry = {
return rv entry: HistoryEntry
}, {}) timeAgo: Ref<string>
} }
const history = useReadonlyStream<RESTHistoryEntry[] | GQLHistoryEntry[]>( const history = useReadonlyStream<RESTHistoryEntry[] | GQLHistoryEntry[]>(
@ -145,27 +148,49 @@ const history = useReadonlyStream<RESTHistoryEntry[] | GQLHistoryEntry[]>(
[] []
) )
const filteredHistory = computed(() => { const deepCheckForRegex = (value: unknown, regExp: RegExp): boolean => {
const regExp = new RegExp(filterText.value, "gi") if (value === null || value === undefined) return false
const check = (obj: any) => {
if (obj !== null && typeof obj === "object") { if (typeof value === "string") return regExp.test(value)
return Object.values(obj).some(check) if (typeof value === "number") return regExp.test(value.toString())
}
if (Array.isArray(obj)) { if (typeof value === "object")
return obj.some(check) return Object.values(value).some((input) =>
} deepCheckForRegex(input, regExp)
return ( )
(typeof obj === "string" || typeof obj === "number") && if (Array.isArray(value))
regExp.test(obj as string) return value.some((input) => deepCheckForRegex(input, regExp))
return false
}
const filteredHistory = computed(() =>
pipe(
history.value as HistoryEntry[],
A.filter(
(
input
): input is HistoryEntry & {
updatedOn: NonNullable<HistoryEntry["updatedOn"]>
} => {
return (
!!input.updatedOn &&
(filterText.value.length === 0 ||
deepCheckForRegex(input, new RegExp(filterText.value, "gi")))
)
}
),
A.map(
(entry): TimedHistoryEntry => ({
entry,
timeAgo: useTimeAgo(entry.updatedOn),
})
) )
}
return (history.value as Array<RESTHistoryEntry | GQLHistoryEntry>).filter(
check
) )
}) )
const filteredHistoryGroups = computed(() => const filteredHistoryGroups = computed(() =>
groupByDate(filteredHistory.value, "updatedOn") groupBy(filteredHistory.value, (entry) => entry.timeAgo.value)
) )
const clearHistory = () => { const clearHistory = () => {
@ -181,14 +206,20 @@ const useHistory = (entry: any) => {
) )
} }
const deleteBattleHistoryEntry = (entries: number[]) => { const isRESTHistoryEntry = (
if (props.page === "rest") { entries: TimedHistoryEntry[]
entries.forEach((entry: any) => { ): entries is Array<TimedHistoryEntry & { entry: RESTHistoryEntry }> =>
deleteRESTHistoryEntry(entry) // If the page is rest, then we can guarantee what we have is a RESTHistoryEnry
props.page === "rest"
const deleteBatchHistoryEntry = (entries: TimedHistoryEntry[]) => {
if (isRESTHistoryEntry(entries)) {
entries.forEach((entry) => {
deleteRESTHistoryEntry(entry.entry)
}) })
} else { } else {
entries.forEach((entry: any) => { entries.forEach((entry) => {
deleteGraphqlHistoryEntry(entry) deleteGraphqlHistoryEntry(entry.entry as GQLHistoryEntry)
}) })
} }
toast.success(`${t("state.deleted")}`) toast.success(`${t("state.deleted")}`)

View file

@ -68,14 +68,14 @@ type TypeFromPrimitiveArray<P extends JSPrimitive | undefined> =
: unknown[] : unknown[]
export const objHasProperty = export const objHasProperty =
<O extends object, K extends string, P extends JSPrimitive>( <O extends object, K extends string, P extends JSPrimitive | undefined>(
prop: K, prop: K,
type: P type?: P
) => ) =>
// eslint-disable-next-line // eslint-disable-next-line
(obj: O): obj is O & { [_ in K]: TypeFromPrimitive<P> } => (obj: O): obj is O & { [_ in K]: TypeFromPrimitive<P> } =>
// eslint-disable-next-line // eslint-disable-next-line
prop in obj && typeof (obj as any)[prop] === type prop in obj && (type === undefined || typeof (obj as any)[prop] === type)
export const objHasArrayProperty = export const objHasArrayProperty =
<O extends object, K extends string, P extends JSPrimitive>( <O extends object, K extends string, P extends JSPrimitive>(