| 
							
							
							
						 |  |  | @@ -1,5 +1,6 @@ | 
		
	
		
			
				|  |  |  |  | <script> | 
		
	
		
			
				|  |  |  |  |   import { getLocaleFromNavigator, json, _ } from "svelte-i18n"; | 
		
	
		
			
				|  |  |  |  |   import InfiniteLoading from 'svelte-infinite-loading'; | 
		
	
		
			
				|  |  |  |  |   import { RunnerCardService } from "@odit/lfk-client-js"; | 
		
	
		
			
				|  |  |  |  |   import store from "../../store"; | 
		
	
		
			
				|  |  |  |  |   import Toastify from "toastify-js"; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -11,11 +12,21 @@ | 
		
	
		
			
				|  |  |  |  |   export let editable = {}; | 
		
	
		
			
				|  |  |  |  |   export let original_data = {}; | 
		
	
		
			
				|  |  |  |  |   export let current_cards = []; | 
		
	
		
			
				|  |  |  |  |   $: filtered_cards = current_cards.filter(function (c) { | 
		
	
		
			
				|  |  |  |  |     if ( | 
		
	
		
			
				|  |  |  |  |       c.code.toLowerCase().includes(searchvalue_lowercase) || | 
		
	
		
			
				|  |  |  |  |       c.runner?.firstname.toLowerCase().includes(searchvalue_lowercase) || | 
		
	
		
			
				|  |  |  |  |       c.runner?.middlename.toLowerCase().includes(searchvalue_lowercase) || | 
		
	
		
			
				|  |  |  |  |       c.runner?.lastname.toLowerCase().includes(searchvalue_lowercase) || | 
		
	
		
			
				|  |  |  |  |       should_display_based_on_id(c.id) | 
		
	
		
			
				|  |  |  |  |     ) { | 
		
	
		
			
				|  |  |  |  |       return true; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   }); | 
		
	
		
			
				|  |  |  |  |   $: searchvalue = ""; | 
		
	
		
			
				|  |  |  |  |   $: searchvalue_lowercase = searchvalue.toLowerCase(); | 
		
	
		
			
				|  |  |  |  |   $: active_deletes = []; | 
		
	
		
			
				|  |  |  |  |   $: cards_show = current_cards.some( | 
		
	
		
			
				|  |  |  |  |     (r) => r.is_selected === true | 
		
	
		
			
				|  |  |  |  |   ); | 
		
	
		
			
				|  |  |  |  |   $: cards_show = current_cards.some((r) => r.is_selected === true); | 
		
	
		
			
				|  |  |  |  |   $: generate_cards = current_cards.filter((r) => r.is_selected === true); | 
		
	
		
			
				|  |  |  |  |   const cards_promise = RunnerCardService.runnerCardControllerGetAll().then( | 
		
	
		
			
				|  |  |  |  |     (val) => { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -46,8 +57,38 @@ | 
		
	
		
			
				|  |  |  |  |     original_data = Object.assign(original_data, card); | 
		
	
		
			
				|  |  |  |  |     edit_modal_open = true; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | // ----------------- | 
		
	
		
			
				|  |  |  |  |   let scrollTop = 0; | 
		
	
		
			
				|  |  |  |  |   $: rendered = filtered_cards; | 
		
	
		
			
				|  |  |  |  |   let innerHeight = 0; | 
		
	
		
			
				|  |  |  |  |   let ele; | 
		
	
		
			
				|  |  |  |  |   $: updateSlice(scrollTop); | 
		
	
		
			
				|  |  |  |  |   $: innerHeight = `${filtered_cards.length * 25}px`; | 
		
	
		
			
				|  |  |  |  |   $: if (ele) updateSlice(); | 
		
	
		
			
				|  |  |  |  |   function updateSlice() { | 
		
	
		
			
				|  |  |  |  |     const height = ele ? parseInt(ele.clientHeight) : 100; | 
		
	
		
			
				|  |  |  |  |     const init = scrollTop / 25; | 
		
	
		
			
				|  |  |  |  |     const end = Math.ceil((scrollTop + height) / 25); | 
		
	
		
			
				|  |  |  |  |     rendered = filtered_cards.slice(init, end + 15); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   function updateScroll($event) { | 
		
	
		
			
				|  |  |  |  |     scrollTop = $event.target.scrollTop; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | </script> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | <style> | 
		
	
		
			
				|  |  |  |  |   table tbody { | 
		
	
		
			
				|  |  |  |  |   display: block; | 
		
	
		
			
				|  |  |  |  |   overflow-y: scroll; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | table thead, table tbody tr { | 
		
	
		
			
				|  |  |  |  |   display: table; | 
		
	
		
			
				|  |  |  |  |   width: 100%; | 
		
	
		
			
				|  |  |  |  |   table-layout: fixed; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | </style> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')} | 
		
	
		
			
				|  |  |  |  |   <CardDetailModal | 
		
	
		
			
				|  |  |  |  |     bind:current_cards | 
		
	
	
		
			
				
					
					|  |  |  | @@ -121,107 +162,111 @@ | 
		
	
		
			
				|  |  |  |  |               </th> | 
		
	
		
			
				|  |  |  |  |             </tr> | 
		
	
		
			
				|  |  |  |  |           </thead> | 
		
	
		
			
				|  |  |  |  |           <tbody class="divide-y divide-gray-200"> | 
		
	
		
			
				|  |  |  |  |             {#each current_cards as card} | 
		
	
		
			
				|  |  |  |  |               {#if card.code | 
		
	
		
			
				|  |  |  |  |                 .toLowerCase() | 
		
	
		
			
				|  |  |  |  |                 .includes( | 
		
	
		
			
				|  |  |  |  |                   searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |                 ) || card.runner?.firstname | 
		
	
		
			
				|  |  |  |  |                   .toLowerCase() | 
		
	
		
			
				|  |  |  |  |                   .includes( | 
		
	
		
			
				|  |  |  |  |                     searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |                   ) || card.runner?.middlename | 
		
	
		
			
				|  |  |  |  |                   .toLowerCase() | 
		
	
		
			
				|  |  |  |  |                   .includes( | 
		
	
		
			
				|  |  |  |  |                     searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |                   ) || card.runner?.lastname | 
		
	
		
			
				|  |  |  |  |                   .toLowerCase() | 
		
	
		
			
				|  |  |  |  |                   .includes( | 
		
	
		
			
				|  |  |  |  |                     searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |                   ) || should_display_based_on_id(card.id)} | 
		
	
		
			
				|  |  |  |  |                 <tr data-rowid="card_{card.id}"> | 
		
	
		
			
				|  |  |  |  |                   <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |                     <input | 
		
	
		
			
				|  |  |  |  |                       bind:checked={card.is_selected} | 
		
	
		
			
				|  |  |  |  |                       type="checkbox" | 
		
	
		
			
				|  |  |  |  |                       class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" /> | 
		
	
		
			
				|  |  |  |  |                   </td> | 
		
	
		
			
				|  |  |  |  |                   <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |                     <div class="flex items-center">{card.code}</div> | 
		
	
		
			
				|  |  |  |  |                   </td> | 
		
	
		
			
				|  |  |  |  |                   <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |                     <div class="flex items-center"> | 
		
	
		
			
				|  |  |  |  |                       {#if card.runner} | 
		
	
		
			
				|  |  |  |  |                         <a | 
		
	
		
			
				|  |  |  |  |                           href="../runners/{card.runner.id}" | 
		
	
		
			
				|  |  |  |  |                           class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname} | 
		
	
		
			
				|  |  |  |  |                           {card.runner.middlename || ''} | 
		
	
		
			
				|  |  |  |  |                           {card.runner.lastname}</a> | 
		
	
		
			
				|  |  |  |  |                       {:else}{$_('non-blanko')}{/if} | 
		
	
		
			
				|  |  |  |  |                     </div> | 
		
	
		
			
				|  |  |  |  |                   </td> | 
		
	
		
			
				|  |  |  |  |                   <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |                     <div class="flex items-center"> | 
		
	
		
			
				|  |  |  |  |                       {#if card.enabled} | 
		
	
		
			
				|  |  |  |  |                         <span | 
		
	
		
			
				|  |  |  |  |                           class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span> | 
		
	
		
			
				|  |  |  |  |                       {:else} | 
		
	
		
			
				|  |  |  |  |                         <span | 
		
	
		
			
				|  |  |  |  |                           class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span> | 
		
	
		
			
				|  |  |  |  |                       {/if} | 
		
	
		
			
				|  |  |  |  |                     </div> | 
		
	
		
			
				|  |  |  |  |                   </td> | 
		
	
		
			
				|  |  |  |  |           <tbody class="divide-y divide-gray-200 virtual-wrapper" | 
		
	
		
			
				|  |  |  |  |   on:scroll={updateScroll} | 
		
	
		
			
				|  |  |  |  |   style="height: 70vh; width:100%" | 
		
	
		
			
				|  |  |  |  |   bind:this={ele} | 
		
	
		
			
				|  |  |  |  |           > | 
		
	
		
			
				|  |  |  |  |     {#each filtered_cards as card, index} | 
		
	
		
			
				|  |  |  |  |     {#if card.code | 
		
	
		
			
				|  |  |  |  |       .toLowerCase() | 
		
	
		
			
				|  |  |  |  |       .includes( | 
		
	
		
			
				|  |  |  |  |         searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |       ) || card.runner?.firstname | 
		
	
		
			
				|  |  |  |  |         .toLowerCase() | 
		
	
		
			
				|  |  |  |  |         .includes( | 
		
	
		
			
				|  |  |  |  |           searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |         ) || card.runner?.middlename | 
		
	
		
			
				|  |  |  |  |         .toLowerCase() | 
		
	
		
			
				|  |  |  |  |         .includes( | 
		
	
		
			
				|  |  |  |  |           searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |         ) || card.runner?.lastname | 
		
	
		
			
				|  |  |  |  |         .toLowerCase() | 
		
	
		
			
				|  |  |  |  |         .includes( | 
		
	
		
			
				|  |  |  |  |           searchvalue.toLowerCase() | 
		
	
		
			
				|  |  |  |  |         ) || should_display_based_on_id(card.id)} | 
		
	
		
			
				|  |  |  |  |       <tr data-rowid="card_{card.id}"> | 
		
	
		
			
				|  |  |  |  |         <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |           <input | 
		
	
		
			
				|  |  |  |  |             bind:checked={card.is_selected} | 
		
	
		
			
				|  |  |  |  |             type="checkbox" | 
		
	
		
			
				|  |  |  |  |             class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" /> | 
		
	
		
			
				|  |  |  |  |         </td> | 
		
	
		
			
				|  |  |  |  |         <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |           <div class="flex items-center">{card.code}</div> | 
		
	
		
			
				|  |  |  |  |         </td> | 
		
	
		
			
				|  |  |  |  |         <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |           <div class="flex items-center"> | 
		
	
		
			
				|  |  |  |  |             {#if card.runner} | 
		
	
		
			
				|  |  |  |  |               <a | 
		
	
		
			
				|  |  |  |  |                 href="../runners/{card.runner.id}" | 
		
	
		
			
				|  |  |  |  |                 class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname} | 
		
	
		
			
				|  |  |  |  |                 {card.runner.middlename || ''} | 
		
	
		
			
				|  |  |  |  |                 {card.runner.lastname}</a> | 
		
	
		
			
				|  |  |  |  |             {:else}{$_('non-blanko')}{/if} | 
		
	
		
			
				|  |  |  |  |           </div> | 
		
	
		
			
				|  |  |  |  |         </td> | 
		
	
		
			
				|  |  |  |  |         <td class="px-6 py-4 whitespace-nowrap"> | 
		
	
		
			
				|  |  |  |  |           <div class="flex items-center"> | 
		
	
		
			
				|  |  |  |  |             {#if card.enabled} | 
		
	
		
			
				|  |  |  |  |               <span | 
		
	
		
			
				|  |  |  |  |                 class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span> | 
		
	
		
			
				|  |  |  |  |             {:else} | 
		
	
		
			
				|  |  |  |  |               <span | 
		
	
		
			
				|  |  |  |  |                 class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span> | 
		
	
		
			
				|  |  |  |  |             {/if} | 
		
	
		
			
				|  |  |  |  |           </div> | 
		
	
		
			
				|  |  |  |  |         </td> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |                   {#if active_deletes[card.id] === true} | 
		
	
		
			
				|  |  |  |  |                     <td | 
		
	
		
			
				|  |  |  |  |                       class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | 
		
	
		
			
				|  |  |  |  |                       <button | 
		
	
		
			
				|  |  |  |  |                         on:click={() => { | 
		
	
		
			
				|  |  |  |  |                           active_deletes[card.id] = false; | 
		
	
		
			
				|  |  |  |  |                         }} | 
		
	
		
			
				|  |  |  |  |                         tabindex="0" | 
		
	
		
			
				|  |  |  |  |                         class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button> | 
		
	
		
			
				|  |  |  |  |                       <button | 
		
	
		
			
				|  |  |  |  |                         on:click={() => { | 
		
	
		
			
				|  |  |  |  |                           RunnerCardService.runnerCardControllerRemove(card.id, false).then( | 
		
	
		
			
				|  |  |  |  |                             (resp) => { | 
		
	
		
			
				|  |  |  |  |                               current_cards = current_cards.filter( | 
		
	
		
			
				|  |  |  |  |                                 (obj) => obj.id !== card.id | 
		
	
		
			
				|  |  |  |  |                               ); | 
		
	
		
			
				|  |  |  |  |                               Toastify({ | 
		
	
		
			
				|  |  |  |  |                                 text: $_('card-deleted'), | 
		
	
		
			
				|  |  |  |  |                                 duration: 500, | 
		
	
		
			
				|  |  |  |  |                                 backgroundColor: | 
		
	
		
			
				|  |  |  |  |                                   'linear-gradient(to right, #00b09b, #96c93d)', | 
		
	
		
			
				|  |  |  |  |                               }).showToast(); | 
		
	
		
			
				|  |  |  |  |                             } | 
		
	
		
			
				|  |  |  |  |                           ); | 
		
	
		
			
				|  |  |  |  |                         }} | 
		
	
		
			
				|  |  |  |  |                         tabindex="0" | 
		
	
		
			
				|  |  |  |  |                         class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button> | 
		
	
		
			
				|  |  |  |  |                     </td> | 
		
	
		
			
				|  |  |  |  |                   {:else} | 
		
	
		
			
				|  |  |  |  |                     <td | 
		
	
		
			
				|  |  |  |  |                       class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | 
		
	
		
			
				|  |  |  |  |                       <button | 
		
	
		
			
				|  |  |  |  |                         on:click={() => { | 
		
	
		
			
				|  |  |  |  |                           open_edit_modal(card); | 
		
	
		
			
				|  |  |  |  |                         }} | 
		
	
		
			
				|  |  |  |  |                         class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button> | 
		
	
		
			
				|  |  |  |  |                       {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')} | 
		
	
		
			
				|  |  |  |  |                         <button | 
		
	
		
			
				|  |  |  |  |                           on:click={() => { | 
		
	
		
			
				|  |  |  |  |                             active_deletes[card.id] = true; | 
		
	
		
			
				|  |  |  |  |                           }} | 
		
	
		
			
				|  |  |  |  |                           tabindex="0" | 
		
	
		
			
				|  |  |  |  |                           class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button> | 
		
	
		
			
				|  |  |  |  |                       {/if} | 
		
	
		
			
				|  |  |  |  |                     </td> | 
		
	
		
			
				|  |  |  |  |                   {/if} | 
		
	
		
			
				|  |  |  |  |                 </tr> | 
		
	
		
			
				|  |  |  |  |               {/if} | 
		
	
		
			
				|  |  |  |  |             {/each} | 
		
	
		
			
				|  |  |  |  |         {#if active_deletes[card.id] === true} | 
		
	
		
			
				|  |  |  |  |           <td | 
		
	
		
			
				|  |  |  |  |             class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | 
		
	
		
			
				|  |  |  |  |             <button | 
		
	
		
			
				|  |  |  |  |               on:click={() => { | 
		
	
		
			
				|  |  |  |  |                 active_deletes[card.id] = false; | 
		
	
		
			
				|  |  |  |  |               }} | 
		
	
		
			
				|  |  |  |  |               tabindex="0" | 
		
	
		
			
				|  |  |  |  |               class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button> | 
		
	
		
			
				|  |  |  |  |             <button | 
		
	
		
			
				|  |  |  |  |               on:click={() => { | 
		
	
		
			
				|  |  |  |  |                 RunnerCardService.runnerCardControllerRemove(card.id, false).then( | 
		
	
		
			
				|  |  |  |  |                   (resp) => { | 
		
	
		
			
				|  |  |  |  |                     current_cards = current_cards.filter( | 
		
	
		
			
				|  |  |  |  |                       (obj) => obj.id !== card.id | 
		
	
		
			
				|  |  |  |  |                     ); | 
		
	
		
			
				|  |  |  |  |                     Toastify({ | 
		
	
		
			
				|  |  |  |  |                       text: $_('card-deleted'), | 
		
	
		
			
				|  |  |  |  |                       duration: 500, | 
		
	
		
			
				|  |  |  |  |                       backgroundColor: | 
		
	
		
			
				|  |  |  |  |                         'linear-gradient(to right, #00b09b, #96c93d)', | 
		
	
		
			
				|  |  |  |  |                     }).showToast(); | 
		
	
		
			
				|  |  |  |  |                   } | 
		
	
		
			
				|  |  |  |  |                 ); | 
		
	
		
			
				|  |  |  |  |               }} | 
		
	
		
			
				|  |  |  |  |               tabindex="0" | 
		
	
		
			
				|  |  |  |  |               class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button> | 
		
	
		
			
				|  |  |  |  |           </td> | 
		
	
		
			
				|  |  |  |  |         {:else} | 
		
	
		
			
				|  |  |  |  |           <td | 
		
	
		
			
				|  |  |  |  |             class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | 
		
	
		
			
				|  |  |  |  |             <button | 
		
	
		
			
				|  |  |  |  |               on:click={() => { | 
		
	
		
			
				|  |  |  |  |                 open_edit_modal(card); | 
		
	
		
			
				|  |  |  |  |               }} | 
		
	
		
			
				|  |  |  |  |               class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button> | 
		
	
		
			
				|  |  |  |  |             {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')} | 
		
	
		
			
				|  |  |  |  |               <button | 
		
	
		
			
				|  |  |  |  |                 on:click={() => { | 
		
	
		
			
				|  |  |  |  |                   active_deletes[card.id] = true; | 
		
	
		
			
				|  |  |  |  |                 }} | 
		
	
		
			
				|  |  |  |  |                 tabindex="0" | 
		
	
		
			
				|  |  |  |  |                 class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button> | 
		
	
		
			
				|  |  |  |  |             {/if} | 
		
	
		
			
				|  |  |  |  |           </td> | 
		
	
		
			
				|  |  |  |  |         {/if} | 
		
	
		
			
				|  |  |  |  |       </tr> | 
		
	
		
			
				|  |  |  |  |     {/if} | 
		
	
		
			
				|  |  |  |  |     {/each} | 
		
	
		
			
				|  |  |  |  |           </tbody> | 
		
	
		
			
				|  |  |  |  |         </table> | 
		
	
		
			
				|  |  |  |  |       </div> | 
		
	
	
		
			
				
					
					|  |  |  |   |