Skip to content

Bulk Device Registration Component Documentation

File: src/pages/private/admin/devices/bulkDevice.svelte

Overview

This component enables bulk registration of Headset devices by automatically generating sequential device names when scanning multiple QR codes. It maintains state between device registrations to streamline the bulk addition process.

Component Script

Props

ts
export let qrCodeUrl: string = ""; // URL for generated QR code
export let loading: boolean = false; // Loading state
export let regRef: string = ""; // Registration reference token

State Variables

ts
let deviceName: string = ""; // Base device name input
let notes: string = ""; // Device notes input
let unsubscribe: { unsubscribe: () => void } | null = null; // Subscription cleanup
let deviceCount: number = 0; // Counter for sequential naming

Lifecycle Methods

ts
onMount(() => {
  // Subscribe to device addition events
  const client = getClient();
  const token = get(accessToken);
  
  const subscription$ = client.subscription(DEVICE_ADDED_SUBSCRIPTION, { token });
  
  unsubscribe = subscribe((result) => {
    if (result.data?.onDeviceAdded?.deviceRefToken === regRef) {
      // Extract base name and current number from device name
      const match = deviceName.match(/(.*?)(\d+)$/);
      const baseName = match ? match[1].trim() : deviceName.trim();
      const currentNumber = match ? parseInt(match[2]) : 0;

      // Increment counter and update name
      deviceCount = currentNumber + 1;
      deviceName = `${baseName} ${deviceCount}`.trim();

      // Trigger next generation
      dispatch("submit", { name: deviceName, notes });
    }
  })(subscription$);
});

onDestroy(() => {
  // Clean up subscription
  if (unsubscribe?.unsubscribe) {
    unsubscribe.unsubscribe();
  }
});

Event Handlers

ts
function handleSubmit() {
  // Trigger QR code generation
  dispatch("submit", { name: deviceName, notes });
}

UI Structure

svelte
<div class="p-6 w-full">
  <form on:submit|preventDefault={handleSubmit} class="flex gap-4 w-full">
    <!-- Left Column: Form Inputs -->
    <div class="flex flex-col gap-4 w-full">
      <!-- Device Name Input -->
      <div>
        <label for="deviceName">Device Name</label>
        <input
          id="deviceName"
          type="text"
          bind:value={deviceName}
          placeholder="Enter base device name"
          required
        />
      </div>
      
      <!-- Notes Textarea -->
      <div>
        <label for="notes">Notes</label>
        <textarea
          id="notes"
          bind:value={notes}
          placeholder="Enter notes for all devices"
          rows={8}
        ></textarea>
      </div>
    </div>
    
    <!-- Right Column: QR Code Generation -->
    <div class="w-[700px]">
      <label for="qrCode">QR Code</label>
      <div class="flex flex-col items-center space-y-2 p-4 border-2 border-dashed border-gray-300 rounded-md">
        {#if loading}
          <!-- Loading state -->
          <div class="flex-grow grid place-content-center my-3 py-3 h-[175px]">
            <Chasing />
          </div>
        {:else if qrCodeUrl}
          <!-- QR Code display -->
          <img src={qrCodeUrl} alt="Device QR Code" />
          <p class="text-sm text-gray-500">
            Scanning this will add device: {deviceName}
          </p>
        {:else}
          <!-- Empty state -->
          <div class="text-center p-8">
            <!-- Placeholder icon -->
            <p class="mt-2 text-sm text-gray-500">QR Code</p>
          </div>
        {/if}
      </div>
      <button type="submit">Generate</button>
    </div>
  </form>
</div>

Key Features

  1. Sequential Naming:

    • Automatically increments device numbers (e.g., "Device 1", "Device 2")
    • Maintains base name while updating counter
  2. Continuous Registration:

    • Automatically generates next QR code after successful scan
    • Maintains notes and base name between registrations
  3. Real-time Feedback:

    • Shows which device name will be registered next
    • Clear visual states for loading/empty/active QR codes
  4. Bulk Optimization:

    • Single form submission for multiple devices
    • Persistent notes apply to all devices in batch

Events

Event NameDescriptionPayload
submitTrigger QR code generation{ name: string, notes: string }

Usage Example

svelte
<script>
  import BulkDevice from "./bulkDevice.svelte";
  
  let qrCode = "";
  let loading = false;
  let regRef = "";
  
  function handleBulkSubmit({ detail }) {
    // Call API to generate QR code
    loading = true;
    generateBulkDeviceQR(detail.name, detail.notes)
      .then(result => {
        qrCode = result.qrCodeUrl;
        regRef = result.regRef;
      })
      .finally(() => loading = false);
  }
</script>

<BulkDevice 
  bind:qrCodeUrl={qrCode}
  bind:loading
  bind:regRef
  on:submit={handleBulkSubmit}
/>

Styling Notes

  • Two-column layout: Form inputs on left, QR code on right
  • Consistent styling: Matches single device form for familiarity
  • Clear visual states: Distinct UI for loading/empty/active states
  • Responsive: Adapts to container width while maintaining readability

Error Handling

  • Automatic subscription cleanup on component destruction
  • Required field validation for device name
  • Loading states prevent duplicate submissions

Released under the MIT License.