3232 {{ cardPreview[c.id] }}
3333 </v-list-item-title >
3434 <v-list-item-subtitle >
35- {{ c.id.split('-').length === 3 ? c.id.split('-')[2] : ' ' }}
35+ ELO: {{ cardElos[idParse( c.id)]?.global.score || '(unknown) ' }}
3636 </v-list-item-subtitle >
3737 </div >
3838 </template >
118118
119119<script lang="ts">
120120import { defineComponent , PropType } from ' vue' ;
121- import { displayableDataToViewData , Status } from ' @vue-skuilder/common' ;
121+ import { displayableDataToViewData , Status , CourseElo } from ' @vue-skuilder/common' ;
122122import { getDataLayer , CourseDBInterface , CardData , DisplayableData , Tag } from ' @vue-skuilder/db' ;
123123// local imports
124124import TagsInput from ' ./TagsInput.vue' ;
@@ -127,16 +127,7 @@ import { ViewComponent } from '../composables/Displayable';
127127import CardLoader from ' ./cardRendering/CardLoader.vue' ;
128128import { alertUser } from ' ./SnackbarService' ;
129129
130- function isConstructor(obj : unknown ) {
131- try {
132- // @ts-expect-error - we are specifically probing an unknown object
133- new obj ();
134- return true ;
135- } catch (e ) {
136- console .warn (` not a constructor: ${obj }, err: ${e } ` );
137- return false ;
138- }
139- }
130+ // Legacy isConstructor function removed - no longer needed for Vue 3 components
140131
141132export default defineComponent ({
142133 name: ' CourseCardBrowser' ,
@@ -180,6 +171,7 @@ export default defineComponent({
180171 cards: [] as { id: string ; isOpen: boolean ; delBtn: boolean }[],
181172 cardData: {} as { [card : string ]: string [] },
182173 cardPreview: {} as { [card : string ]: string },
174+ cardElos: {} as Record <string , CourseElo >,
183175 internalEditMode: ' none' as ' tags' | ' flag' | ' none' ,
184176 delBtn: false ,
185177 updatePending: true ,
@@ -213,6 +205,15 @@ export default defineComponent({
213205 },
214206
215207 methods: {
208+ idParse(id : string ): string {
209+ const delimiters = id .includes (' -' );
210+ if (delimiters ) {
211+ return id .split (' -' )[1 ];
212+ } else {
213+ return id ;
214+ }
215+ },
216+
216217 first() {
217218 this .page = 1 ;
218219 this .populateTableData ();
@@ -244,7 +245,7 @@ export default defineComponent({
244245 },
245246 async deleteCard(cID : string ) {
246247 console .log (` Deleting card ${cID } ` );
247- const res = await this .courseDB ! .removeCard (idParse (cID ));
248+ const res = await this .courseDB ! .removeCard (this . idParse (cID ));
248249 if (res .ok ) {
249250 this .cards = this .cards .filter ((card ) => card .id != cID );
250251 this .clearSelections ();
@@ -276,7 +277,7 @@ export default defineComponent({
276277 const toRemove: string [] = [];
277278 const hydratedCardData = (
278279 await this .courseDB ! .getCourseDocs <CardData >(
279- this .cards .map ((c ) => idParse (c .id )),
280+ this .cards .map ((c ) => this . idParse (c .id )),
280281 {
281282 include_docs: true ,
282283 }
@@ -296,7 +297,7 @@ export default defineComponent({
296297 })
297298 .map ((r ) => r .doc ! );
298299
299- this .cards = this .cards .filter ((c ) => ! toRemove .includes (idParse (c .id )));
300+ this .cards = this .cards .filter ((c ) => ! toRemove .includes (this . idParse (c .id )));
300301
301302 hydratedCardData .forEach ((c ) => {
302303 if (c && c .id_displayable_data ) {
@@ -307,7 +308,7 @@ export default defineComponent({
307308 try {
308309 await Promise .all (
309310 this .cards .map (async (c ) => {
310- const _cardID: string = idParse (c .id );
311+ const _cardID: string = this . idParse (c .id );
311312
312313 const tmpCardData = hydratedCardData .find ((c ) => c ._id == _cardID );
313314 if (! tmpCardData || ! tmpCardData .id_displayable_data ) {
@@ -331,20 +332,24 @@ export default defineComponent({
331332 const tmpData = [];
332333 tmpData .unshift (displayableDataToViewData (doc ));
333334
334- // [ ] remove/replace this after the vue 3 migration is complete
335- // see PR #510
336- if (isConstructor (tmpView )) {
337- const view = new tmpView ();
338- view .data = tmpData ;
339-
340- this .cardPreview [c .id ] = view .toString ();
341- } else {
342- this .cardPreview [c .id ] = tmpView .name ? tmpView .name : ' Unknown' ;
343- }
335+ // Vue 3: Use component name for preview (legacy constructor code removed)
336+ this .cardPreview [c .id ] = tmpView .name ? tmpView .name : ' Unknown' ;
344337 })
345338 );
346339 })
347340 );
341+
342+ // Load ELO data for all cards
343+ const cardIds = this .cards .map ((c ) => this .idParse (c .id ));
344+ const eloData =
345+ this .cards [0 ].id .split (' -' ).length === 3
346+ ? this .cards .map ((c ) => c .id .split (' -' )[2 ]) // for platform-ui crs-card-elo IDs
347+ : await this .courseDB ! .getCardEloData (cardIds ); // general case lookup
348+
349+ // Store ELO data indexed by card ID
350+ cardIds .forEach ((cardId , index ) => {
351+ this .cardElos [cardId ] = eloData [index ];
352+ });
348353 } catch (error ) {
349354 console .error (' Error populating table data:' , error );
350355 } finally {
@@ -354,15 +359,6 @@ export default defineComponent({
354359 },
355360 },
356361});
357-
358- function idParse(id : string ): string {
359- const delimiters = id .includes (' -' );
360- if (delimiters ) {
361- return id .split (' -' )[1 ];
362- } else {
363- return id ;
364- }
365- }
366362 </script >
367363
368364<style scoped>
0 commit comments