Skip to content

Commit

Permalink
More composable migration
Browse files Browse the repository at this point in the history
Refs #156
  • Loading branch information
The4thLaw committed Sep 13, 2024
1 parent 180ce79 commit 17e072b
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 92 deletions.
28 changes: 0 additions & 28 deletions source/demyo-vue-frontend/src/composables/model-index.js

This file was deleted.

36 changes: 36 additions & 0 deletions source/demyo-vue-frontend/src/composables/model-index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import AbstractModelService from '@/services/abstract-model-service'
import { useUiStore } from '@/stores/ui'
import { useHead } from '@unhead/vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

/**
* Composable for simple model indexes loading data from the service.
* @param serviceInstance The service to use to fetch the data.
* @param titleKey the page title key
*/
export function useSimpleIndex<T extends IModel>(serviceInstance: AbstractModelService, titleKey: string,
fetchData: (() => Promise<T[]>) | null = null) {
//
let safeFetchData: () => Promise<T[]>
safeFetchData = fetchData || (() => serviceInstance.findForIndex())

useHead({
title: useI18n().t(titleKey)
})

const uiStore = useUiStore()
const loading = computed(() => uiStore.globalOverlay)

const modelList = ref([] as T[])

async function loadData() {
uiStore.enableGlobalOverlay()
modelList.value = await safeFetchData()
uiStore.disableGlobalOverlay()
}

loadData()

return { loading, modelList }
}
4 changes: 2 additions & 2 deletions source/demyo-vue-frontend/src/composables/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import { useReaderStore } from '@/stores/reader'
import { Dictionary } from 'lodash'
import type { Dictionary } from 'lodash'
import deburr from 'lodash/deburr'
import groupBy from 'lodash/groupBy'

Expand All @@ -19,7 +19,7 @@ function extractFirstLetter<T extends AbstractModel>(item: T, firstLetterExtract

export const emitTypes = ['page-change']

interface PaginationState<T> {
interface PaginationState<T extends AbstractModel> {
/** The current page number. */
currentPage: Ref<number>
/** The total page count. */
Expand Down
23 changes: 6 additions & 17 deletions source/demyo-vue-frontend/src/pages/albums/AlbumIndex.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
<template>
<div class="c-AlbumIndex">
<MetaSeriesIndex :items="albums" @page-change="scrollToTop" />
<Fab to="/albums/new" icon="mdi-plus" />
<Fab v-if="!loading" to="/albums/new" icon="mdi-plus" />
</div>
</template>

<script setup>
<script setup lang="ts">
import { useSimpleIndex } from '@/composables/model-index'
import { retrieveFilter } from '@/helpers/filter'
import albumService from '@/services/album-service'
import { useUiStore } from '@/stores/ui'
import { useHead } from '@unhead/vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
useHead({
title: useI18n().t('title.index.album')
})
const uiStore = useUiStore()
const route = useRoute()
const albums = ref([])
async function fetchData() {
uiStore.enableGlobalOverlay()
function fetchData() {
const filter = retrieveFilter(route)
albums.value = await albumService.findForIndex(filter)
uiStore.disableGlobalOverlay()
return albumService.findForIndex(filter)
}
void fetchData()
const { loading, modelList: albums } = useSimpleIndex(albumService, 'title.index.album', fetchData)
</script>
67 changes: 22 additions & 45 deletions source/demyo-vue-frontend/src/pages/tags/TagIndex.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,38 @@
<TagLink :model="tags" />
</SectionCard>
</v-container>
<Fab to="/tags/new" icon="mdi-plus" />
<Fab v-if="!loading" to="/tags/new" icon="mdi-plus" />
</div>
</template>

<script>
<script setup lang="ts">
import { useSimpleIndex } from '@/composables/model-index'
import tagService from '@/services/tag-service'
import { useUiStore } from '@/stores/ui'
export default {
name: 'TagIndex',
data() {
return {
tags: []
}
},
head() {
return {
title: this.$t('title.index.tag')
}
},
computed: {
maxUsageCount() {
if (this.tags.length === 0) {
return 0
}
const max = Math.max.apply(Math, this.tags.map(t => t.usageCount))
// Have a reasonable minimum else it just looks silly if there are few tags and they are seldom used
return Math.max(max, 10)
}
},
created() {
this.fetchData()
},
function getMaxUsageCount(tags: Tag[]) {
if (tags.length === 0) {
return 0
}
methods: {
async fetchData() {
const uiStore = useUiStore()
uiStore.enableGlobalOverlay()
this.tags = await tagService.findForIndex()
const max = Math.max.apply(Math, tags.map(t => t.usageCount))
// Have a reasonable minimum else it just looks silly if there are few tags and they are seldom used
return Math.max(max, 10)
}
// Post-process tags: compute the relative weight in %
// (the base is 100% and the max is 200%, which is very convenient for the font-size)
for (const tag of this.tags) {
tag.relativeWeight = Math.round(100 * tag.usageCount / this.maxUsageCount + 100)
}
async function fetchData(): Promise<ProcessedTag[]> {
const loadedTags: ProcessedTag[] = await tagService.findForIndex()
uiStore.disableGlobalOverlay()
}
// Post-process tags: compute the relative weight in %
// (the base is 100% and the max is 200%, which is very convenient for the font-size)
const maxUsageCount = getMaxUsageCount(loadedTags)
for (const tag of loadedTags) {
tag.relativeWeight = Math.round(100 * tag.usageCount / maxUsageCount + 100)
}
return Promise.resolve(loadedTags)
}
const { loading, modelList: tags } = useSimpleIndex(tagService, 'title.index.tag', fetchData)
</script>

<style lang="scss">
Expand Down

0 comments on commit 17e072b

Please sign in to comment.