F7: Deduplicate the four CRUD composables
useExercises/useCombos/useSessions/useCollections were the same 54 lines with a different repository (~160 duplicated lines). They are now one-liners over a createCrudComposable(repository, itemsKey) factory; the returned API is identical so no call site changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a6b4723ac6
commit
e3847edae1
71
src/composables/createCrudComposable.js
Normal file
71
src/composables/createCrudComposable.js
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for the four identical CRUD composables (exercises, combos,
|
||||||
|
* sessions, collections). Returns a composable exposing the reactive item
|
||||||
|
* list under `itemsKey` plus the shared loading/error/CRUD API, so
|
||||||
|
* useExercises & co. stay one-liners with unchanged call sites.
|
||||||
|
*/
|
||||||
|
export function createCrudComposable(repository, itemsKey) {
|
||||||
|
return function useCrud() {
|
||||||
|
const items = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const error = ref(null)
|
||||||
|
|
||||||
|
async function fetchAll() {
|
||||||
|
loading.value = true
|
||||||
|
error.value = null
|
||||||
|
try {
|
||||||
|
items.value = await repository.getAll()
|
||||||
|
} catch (e) {
|
||||||
|
error.value = e.message
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function create(data) {
|
||||||
|
const id = await repository.create(data)
|
||||||
|
await fetchAll()
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update(id, data) {
|
||||||
|
await repository.update(id, data)
|
||||||
|
await fetchAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function remove(id) {
|
||||||
|
await repository.delete(id)
|
||||||
|
await fetchAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function search(query) {
|
||||||
|
loading.value = true
|
||||||
|
error.value = null
|
||||||
|
try {
|
||||||
|
items.value = await repository.search(query)
|
||||||
|
} catch (e) {
|
||||||
|
error.value = e.message
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getById(id) {
|
||||||
|
return repository.getById(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
[itemsKey]: items,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
fetchAll,
|
||||||
|
create,
|
||||||
|
update,
|
||||||
|
remove,
|
||||||
|
search,
|
||||||
|
getById,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,54 +1,4 @@
|
||||||
import { ref } from 'vue'
|
|
||||||
import { collectionRepository } from '../db/repositories/collectionRepository.js'
|
import { collectionRepository } from '../db/repositories/collectionRepository.js'
|
||||||
|
import { createCrudComposable } from './createCrudComposable.js'
|
||||||
|
|
||||||
export function useCollections() {
|
export const useCollections = createCrudComposable(collectionRepository, 'collections')
|
||||||
const collections = ref([])
|
|
||||||
const loading = ref(false)
|
|
||||||
const error = ref(null)
|
|
||||||
|
|
||||||
async function fetchAll() {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
collections.value = await collectionRepository.getAll()
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create(data) {
|
|
||||||
const id = await collectionRepository.create(data)
|
|
||||||
await fetchAll()
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
async function update(id, data) {
|
|
||||||
await collectionRepository.update(id, data)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function remove(id) {
|
|
||||||
await collectionRepository.delete(id)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function search(query) {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
collections.value = await collectionRepository.search(query)
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getById(id) {
|
|
||||||
return collectionRepository.getById(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { collections, loading, error, fetchAll, create, update, remove, search, getById }
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,4 @@
|
||||||
import { ref } from 'vue'
|
|
||||||
import { comboRepository } from '../db/repositories/comboRepository.js'
|
import { comboRepository } from '../db/repositories/comboRepository.js'
|
||||||
|
import { createCrudComposable } from './createCrudComposable.js'
|
||||||
|
|
||||||
export function useCombos() {
|
export const useCombos = createCrudComposable(comboRepository, 'combos')
|
||||||
const combos = ref([])
|
|
||||||
const loading = ref(false)
|
|
||||||
const error = ref(null)
|
|
||||||
|
|
||||||
async function fetchAll() {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
combos.value = await comboRepository.getAll()
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create(data) {
|
|
||||||
const id = await comboRepository.create(data)
|
|
||||||
await fetchAll()
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
async function update(id, data) {
|
|
||||||
await comboRepository.update(id, data)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function remove(id) {
|
|
||||||
await comboRepository.delete(id)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function search(query) {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
combos.value = await comboRepository.search(query)
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getById(id) {
|
|
||||||
return comboRepository.getById(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { combos, loading, error, fetchAll, create, update, remove, search, getById }
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,4 @@
|
||||||
import { ref } from 'vue'
|
|
||||||
import { exerciseRepository } from '../db/repositories/exerciseRepository.js'
|
import { exerciseRepository } from '../db/repositories/exerciseRepository.js'
|
||||||
|
import { createCrudComposable } from './createCrudComposable.js'
|
||||||
|
|
||||||
export function useExercises() {
|
export const useExercises = createCrudComposable(exerciseRepository, 'exercises')
|
||||||
const exercises = ref([])
|
|
||||||
const loading = ref(false)
|
|
||||||
const error = ref(null)
|
|
||||||
|
|
||||||
async function fetchAll() {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
exercises.value = await exerciseRepository.getAll()
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create(data) {
|
|
||||||
const id = await exerciseRepository.create(data)
|
|
||||||
await fetchAll()
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
async function update(id, data) {
|
|
||||||
await exerciseRepository.update(id, data)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function remove(id) {
|
|
||||||
await exerciseRepository.delete(id)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function search(query) {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
exercises.value = await exerciseRepository.search(query)
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getById(id) {
|
|
||||||
return exerciseRepository.getById(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { exercises, loading, error, fetchAll, create, update, remove, search, getById }
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,4 @@
|
||||||
import { ref } from 'vue'
|
|
||||||
import { sessionRepository } from '../db/repositories/sessionRepository.js'
|
import { sessionRepository } from '../db/repositories/sessionRepository.js'
|
||||||
|
import { createCrudComposable } from './createCrudComposable.js'
|
||||||
|
|
||||||
export function useSessions() {
|
export const useSessions = createCrudComposable(sessionRepository, 'sessions')
|
||||||
const sessions = ref([])
|
|
||||||
const loading = ref(false)
|
|
||||||
const error = ref(null)
|
|
||||||
|
|
||||||
async function fetchAll() {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
sessions.value = await sessionRepository.getAll()
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create(data) {
|
|
||||||
const id = await sessionRepository.create(data)
|
|
||||||
await fetchAll()
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
async function update(id, data) {
|
|
||||||
await sessionRepository.update(id, data)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function remove(id) {
|
|
||||||
await sessionRepository.delete(id)
|
|
||||||
await fetchAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function search(query) {
|
|
||||||
loading.value = true
|
|
||||||
error.value = null
|
|
||||||
try {
|
|
||||||
sessions.value = await sessionRepository.search(query)
|
|
||||||
} catch (e) {
|
|
||||||
error.value = e.message
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getById(id) {
|
|
||||||
return sessionRepository.getById(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { sessions, loading, error, fetchAll, create, update, remove, search, getById }
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue