Amend dynamic imports

This commit is contained in:
2025-07-15 11:04:21 +02:00
parent bb114f16e0
commit 79814b18b1
21 changed files with 203 additions and 98 deletions

View File

@@ -9,7 +9,7 @@ Name | Type | Description | Notes
**cardType** | [**CardType**](CardType.md) | | [default to undefined]
**description** | **string** | | [default to undefined]
**name** | **string** | | [default to undefined]
**cardPrints** | [**Set<CardPrint>**](CardPrint.md) | | [default to undefined]
**cardPrints** | [**Array<CardPrint>**](CardPrint.md) | | [default to undefined]
**monsterEffect** | **string** | | [optional] [default to undefined]
**attack** | **number** | | [optional] [default to undefined]
**defense** | **number** | | [optional] [default to undefined]

View File

@@ -9,7 +9,7 @@ Name | Type | Description | Notes
**cardType** | [**CardType**](CardType.md) | | [default to undefined]
**description** | **string** | | [default to undefined]
**name** | **string** | | [default to undefined]
**cardPrints** | [**Set<CardPrint>**](CardPrint.md) | | [default to undefined]
**cardPrints** | [**Array<CardPrint>**](CardPrint.md) | | [default to undefined]
**monsterEffect** | **string** | | [optional] [default to undefined]
**attack** | **number** | | [optional] [default to undefined]
**defense** | **number** | | [optional] [default to undefined]

View File

@@ -9,7 +9,7 @@ Name | Type | Description | Notes
**cardType** | [**CardType**](CardType.md) | | [default to undefined]
**description** | **string** | | [default to undefined]
**name** | **string** | | [default to undefined]
**cardPrints** | [**Set<CardPrint>**](CardPrint.md) | | [default to undefined]
**cardPrints** | [**Array<CardPrint>**](CardPrint.md) | | [default to undefined]
**type** | [**SpellCardType**](SpellCardType.md) | | [default to undefined]
## Example

View File

@@ -9,7 +9,7 @@ Name | Type | Description | Notes
**cardType** | [**CardType**](CardType.md) | | [default to undefined]
**description** | **string** | | [default to undefined]
**name** | **string** | | [default to undefined]
**cardPrints** | [**Set<CardPrint>**](CardPrint.md) | | [default to undefined]
**cardPrints** | [**Array<CardPrint>**](CardPrint.md) | | [default to undefined]
**type** | [**TrapCardType**](TrapCardType.md) | | [default to undefined]
## Example

View File

@@ -67,10 +67,10 @@ export interface MonsterCard {
'name': string;
/**
*
* @type {Set<CardPrint>}
* @type {Array<CardPrint>}
* @memberof MonsterCard
*/
'cardPrints': Set<CardPrint>;
'cardPrints': Array<CardPrint>;
/**
*
* @type {string}

View File

@@ -55,10 +55,10 @@ export interface SpellCard {
'name': string;
/**
*
* @type {Set<CardPrint>}
* @type {Array<CardPrint>}
* @memberof SpellCard
*/
'cardPrints': Set<CardPrint>;
'cardPrints': Array<CardPrint>;
/**
*
* @type {SpellCardType}

View File

@@ -55,10 +55,10 @@ export interface TrapCard {
'name': string;
/**
*
* @type {Set<CardPrint>}
* @type {Array<CardPrint>}
* @memberof TrapCard
*/
'cardPrints': Set<CardPrint>;
'cardPrints': Array<CardPrint>;
/**
*
* @type {TrapCardType}

16
src/components.d.ts vendored
View File

@@ -8,50 +8,36 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
Accordion: typeof import('primevue/accordion')['default']
Avatar: typeof import('primevue/avatar')['default']
Badge: typeof import('primevue/badge')['default']
Button: typeof import('primevue/button')['default']
Card: typeof import('primevue/card')['default']
CardFilterPanel: typeof import('./components/CardFilterPanel.vue')['default']
CardListComponent: typeof import('./components/CardListComponent.vue')['default']
CardListExpansion: typeof import('./components/CardListExpansion.vue')['default']
CardTable: typeof import('./components/CardTable.vue')['default']
Carousel: typeof import('primevue/carousel')['default']
Checkbox: typeof import('primevue/checkbox')['default']
Column: typeof import('primevue/column')['default']
CustomTag: typeof import('./components/CustomTag.vue')['default']
DataTable: typeof import('primevue/datatable')['default']
DataView: typeof import('primevue/dataview')['default']
DeckIcon: typeof import('./components/DeckIcon.vue')['default']
Divider: typeof import('primevue/divider')['default']
DynamicAsset: typeof import('./components/DynamicAsset.vue')['default']
Fieldset: typeof import('primevue/fieldset')['default']
FloatLabel: typeof import('primevue/floatlabel')['default']
HelloWorld: typeof import('./components/HelloWorld.vue')['default']
IconField: typeof import('primevue/iconfield')['default']
Image: typeof import('primevue/image')['default']
InputIcon: typeof import('primevue/inputicon')['default']
InputNumber: typeof import('primevue/inputnumber')['default']
InputText: typeof import('primevue/inputtext')['default']
LinkArrowsComponent: typeof import('./components/LinkArrowsComponent.vue')['default']
Listbox: typeof import('primevue/listbox')['default']
Menubar: typeof import('primevue/menubar')['default']
MonsterCardTypeTag: typeof import('./components/MonsterCardTypeTag.vue')['default']
MultiSelect: typeof import('primevue/multiselect')['default']
Panel: typeof import('primevue/panel')['default']
ProgressBar: typeof import('primevue/progressbar')['default']
Rating: typeof import('primevue/rating')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
ScrollPanel: typeof import('primevue/scrollpanel')['default']
SelectButton: typeof import('primevue/selectbutton')['default']
Slider: typeof import('primevue/slider')['default']
SplitButton: typeof import('primevue/splitbutton')['default']
Splitter: typeof import('primevue/splitter')['default']
SplitterPanel: typeof import('primevue/splitterpanel')['default']
TabPanel: typeof import('primevue/tabpanel')['default']
Tag: typeof import('primevue/tag')['default']
Textarea: typeof import('primevue/textarea')['default']
VirtualScroller: typeof import('primevue/virtualscroller')['default']
}
}

View File

@@ -94,11 +94,12 @@
>
<template #option="slotProps" class="">
<img
class="size-5"
alt="Attribute Icon"
:src="'/src/assets/' + slotProps.option + '.svg'"
>
<!-- <img-->
<!-- class="size-5"-->
<!-- alt="Attribute Icon"-->
<!-- :src="'/assets/' + slotProps.option + '.svg'"-->
<!-- >-->
<DynamicAsset :attribute="slotProps.option" class="size-5"/>
</template>
</SelectButton>
@@ -174,12 +175,12 @@
<script setup lang="ts">
import {type Ref, ref} from "vue";
import {
Attribute, type CardServiceGetCardPageRequest,
Attribute,
type CardServiceGetCardPageRequest,
MonsterCardSubType,
MonsterCardType,
SpellCardType,
TrapCardType
MonsterCardType
} from "../api/openapi";
import DynamicAsset from "@/components/DynamicAsset.vue";
const filters: Ref<CardServiceGetCardPageRequest> = defineModel({
required: true,
@@ -189,13 +190,6 @@ const emit = defineEmits(['update:modelValue', 'search'])
const linkArrows = ref([])
const selectedCardTypes: Ref<string[]> = ref([]);
const selectedMonsterCardTypes: Ref<string[]> = ref([]);
const selectedMonsterCardSubTypes: Ref<string[]> = ref([]);
const selectedMonsterAttributes: Ref<string[]> = ref([]);
const selectedSpellCardTypes: Ref<string[]> = ref([]);
const selectedTrapCardTypes: Ref<string[]> = ref([]);
const cardTypes: Ref<string[]> = ref([
'MONSTER',
'SPELL',
@@ -215,14 +209,6 @@ const monsterCardSubTypes: Ref<string[]> = ref(
Object.values(MonsterCardSubType)
);
const spellCardTypes: Ref<string[]> = ref(
Object.values(SpellCardType)
);
const trapCardTypes: Ref<string[]> = ref(
Object.values(TrapCardType)
);
const updateField = (field: string, value?: any) => {
emit('update:modelValue', {
...filters.value,

View File

@@ -28,16 +28,17 @@
<!-- Monster Card properties-->
<template v-if="isMonsterCard(card)">
<div class="flex items-center gap-2" v-if="card.subTypes.length > 0">
<div class="flex items-center gap-2" v-if="(card.subTypes as any).length > 0">
<i class="size-5 text-center pi pi-asterisk"/>
<Tag severity="danger" :value="getFormattedMonsterCardSubTypes(card)"/>
</div>
<div class="flex items-center gap-2">
<img
class="size-5"
alt="Attribute Icon"
:src="'/src/assets/' + card.attribute + '.svg'"
>
<!-- <img-->
<!-- class="size-5"-->
<!-- alt="Attribute Icon"-->
<!-- :src="'/assets/' + card.attribute + '.svg'"-->
<!-- >-->
<DynamicAsset :attribute="card.attribute" class="size-5"/>
<Tag severity="danger" :value="card.attribute"/>
</div>
<div class="flex items-center gap-2">
@@ -128,8 +129,9 @@ import TabPanel from "primevue/tabpanel";
import Tab from "primevue/tab";
import TabList from "primevue/tablist";
import {type Card, type MonsterCard} from "../api/openapi";
import type {Ref} from "vue";
import {type Ref} from "vue";
import {isMonsterCard} from "../util/card-type-util.ts";
import DynamicAsset from "@/components/DynamicAsset.vue";
const card: Ref<Card> = defineModel({
required: true
@@ -141,4 +143,5 @@ const getFormattedMonsterCardSubTypes = (monsterCard: MonsterCard) => {
]
return subTypeArray.join(" / ")
}
</script>

View File

@@ -31,7 +31,11 @@
<img src="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg" alt="image" width="75" />
</template>
<template #preview="slotProps">
<img src="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg" alt="preview" :style="slotProps.style" @click="slotProps.onClick" />
<img
src="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg"
alt="preview"
:style="slotProps.style"
/>
</template>
</Image>
<!-- <Avatar image="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg" class="mr-2" size="xlarge" shape="circle" />-->
@@ -117,11 +121,11 @@ const handlePaging = async (e: DataTablePageEvent) => {
}
const handleSorting = (e: DataTableSortEvent) => {
const handleSorting = (_: DataTableSortEvent) => {
console.log('sort')
}
const handleFiltering = (e: DataTableFilterEvent) => {
const handleFiltering = (_: DataTableFilterEvent) => {
console.log('filter')
}

View File

@@ -0,0 +1,66 @@
<template>
<!-- Best approach: Use pre-loaded assets -->
<img v-if="assetSrc" :src="assetSrc" :alt="attribute" />
<!-- Fallback: Dynamic import -->
<img v-else-if="assetUrl" :src="assetUrl" :alt="attribute" />
<!-- Error state -->
<div v-else class="asset-error">
Missing asset: {{ attribute }}.svg
</div>
</template>
<script setup lang="ts">
import {computed, onMounted, ref} from 'vue';
interface ModuleImportInterface {
default: string;
}
const props = defineProps({
attribute: {
type: String,
required: true
}
});
const assetUrl = ref('');
// Better solution: Pre-import known assets at build time
const knownAssets: Record<string, ModuleImportInterface> = import.meta.glob('@/assets/*.svg', { eager: true });
const getAssetUrl = (name: string) => {
const assetKey = Object.keys(knownAssets).find(key =>
key.includes(`/${name}.svg`)
);
if (assetKey && knownAssets[assetKey]) {
return knownAssets[assetKey]?.default ?? ''
} else {
return ''
}
};
const loadAsset = async () => {
try {
const module = await import(/* @vite-ignore */ `../assets/${props.attribute}.svg`);
assetUrl.value = module.default;
} catch (e) {
console.error(`Error loading asset: ${props.attribute}.svg`, e);
}
};
const assetSrc = computed(() => getAssetUrl(props.attribute));
onMounted(() => {
if (!assetSrc.value) loadAsset();
});
</script>
<style scoped>
.asset-error {
color: #ff5252;
border: 1px dashed currentColor;
padding: 0.5rem;
}
</style>

19
src/util/assets.ts Normal file
View File

@@ -0,0 +1,19 @@
import darkAttribute from "/src/assets/DARK.svg"
import divineAttribute from "/src/assets/DIVINE.svg"
import earthAttribute from "/src/assets/EARTH.svg"
import fireAttribute from "/src/assets/FIRE.svg"
import laughAttribute from "/src/assets/LAUGH.svg"
import lightAttribute from "/src/assets/LIGHT.svg"
import waterAttribute from "/src/assets/WATER.svg"
import windAttribute from "/src/assets/WIND.svg"
export {
darkAttribute,
divineAttribute,
earthAttribute,
fireAttribute,
laughAttribute,
lightAttribute,
waterAttribute,
windAttribute
}

View File

@@ -1,14 +1,12 @@
import type {
Card,
CardType,
MonsterCard, MonsterCardSubType,
MonsterCard,
MonsterCardType,
SpellCard, SpellCardType,
TrapCard, TrapCardType
} from "../api/openapi";
type CardSubTypes = MonsterCardType | TrapCardType | SpellCardType
export const getCardType = (card: Card) => {
switch (card.cardType) {
case "MONSTER":
@@ -26,14 +24,6 @@ export const isMonsterCard = (card: Card): card is MonsterCard => {
return card.cardType === "MONSTER"
}
export const isTrapCard = (card: Card): card is TrapCard => {
return card.cardType === "TRAP"
}
export const isSpellCard = (card: Card): card is SpellCard => {
return card.cardType === "SPELL"
}
export const getMonsterCardType = (monsterCard: MonsterCard) => {
return `${monsterCard.type} MONSTER `
}

View File

@@ -44,7 +44,7 @@ const jobTypeOptions: Ref<JobType[]> = ref(
Object.values(JobType)
)
const getJobTypeSeverity = (job: JobDto) => {
const getJobTypeSeverity = (_: JobDto) => {
return "primary"
}
@@ -70,9 +70,10 @@ const getCompletionPercentage = (job: JobDto) => {
}
onMounted(async () => {
jobs.value = (await jobService.getCardSetImportJobPage(
page.value,
pageSize.value
jobs.value = (await jobService.getCardSetImportJobPage({
page: page.value,
pageSize: pageSize.value
}
)).data.content
console.log(jobs.value)

View File

@@ -34,7 +34,11 @@
<img src="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg" alt="image" width="75" />
</template>
<template #preview="slotProps">
<img src="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg" alt="preview" :style="slotProps.style" @click="slotProps.onClick" />
<img
src="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg"
alt="preview"
:style="slotProps.style"
/>
</template>
</Image>
<!-- <Avatar image="https://upload.wikimedia.org/wikipedia/en/2/2b/Yugioh_Card_Back.jpg" class="mr-2" size="xlarge" shape="circle" />-->
@@ -100,14 +104,11 @@ import type {MutableCardRequest} from "../../api/mutableTypes.ts";
const cardService: CardService = inject(CardServiceKey) as CardService;
const cards: Ref<Card[]> = ref([])
const page: Ref<number> = ref(0);
const pageSize = ref(10);
const pageCount: Ref<number> = ref(0);
const totalRecords: Ref<number> = ref(0);
const loading: Ref<boolean> = ref(true);
const first = ref(0);
const expandedCardRows: Ref<Card[]> = ref([]);
const searchValue: Ref<string> = ref("");
const filters: Ref<MutableCardRequest> = ref({
name: null,
@@ -158,11 +159,11 @@ const handlePaging = async (e: DataTablePageEvent) => {
await getGetCardPage(filters.value)
}
const handleSorting = (e: DataTableSortEvent) => {
const handleSorting = (_: DataTableSortEvent) => {
console.log('sort')
}
const handleFiltering = (e: DataTableFilterEvent) => {
const handleFiltering = (_: DataTableFilterEvent) => {
console.log('filter')
}

View File

@@ -28,7 +28,12 @@
</div>
</template>
<template #preview="slotProps">
<img src="https://comicbook.com/wp-content/uploads/sites/4/2024/11/YuGiOh-Early-Days-Collection.png?resize=2000,1125" alt="preview" :style="slotProps.style" @click="slotProps.onClick" />
<!--suppress TypeScriptUnresolvedReference -->
<img
src="https://comicbook.com/wp-content/uploads/sites/4/2024/11/YuGiOh-Early-Days-Collection.png?resize=2000,1125"
alt="preview"
:style="slotProps.style"
/>
</template>
</Image>
</template>
@@ -67,10 +72,11 @@ const first = ref(0);
const fetchCardSetPage = async (page: number, pageSize: number): Promise<void> => {
loading.value = true;
const cardPage = (await setService.getCardSetPage(
null,
page,
pageSize
const cardPage = (await setService.getCardSetPage({
name: null,
page: page,
pageSize: pageSize
}
)).data
sets.value = cardPage.content
@@ -85,7 +91,7 @@ const handlePaging = async (e: DataTablePageEvent) => {
await fetchCardSetPage(page.value, pageSize.value)
}
const handleSorting = (e: DataTableSortEvent) => {
const handleSorting = (_: DataTableSortEvent) => {
console.log('sort')
}