diff --git a/components/import-project/index.js b/components/import-project/index.js index 25e7ad23..22e4972e 100644 --- a/components/import-project/index.js +++ b/components/import-project/index.js @@ -8,6 +8,10 @@ import { CleanupRegistry } from '../../utilities/CleanupRegistry.js' class ProjectImporter extends HTMLElement { /** @type {CleanupRegistry} Registry for cleanup handlers */ cleanup = new CleanupRegistry() + /** @type {string[]} Ordered list of manifest URLs provided via query params */ + #manifestQueue = [] + /** @type {number} Current position in the manifest queue */ + #manifestIndex = 0 constructor() { super() @@ -33,6 +37,17 @@ class ProjectImporter extends HTMLElement { gap: 10px; max-width: 400px; } + .hint { + margin: 0; + color: #4a4a4a; + font-size: 0.95rem; + line-height: 1.4; + } + .hint code { + background: #f1f1f1; + padding: 2px 4px; + border-radius: 4px; + } input, button { padding: 10px; font-size: 1rem; @@ -76,6 +91,7 @@ class ProjectImporter extends HTMLElement {

Create Project from Manifest URL

+

Tip: this page supports direct links like /project/import?manifest=https://example.com/manifest.json.

@@ -95,16 +111,56 @@ class ProjectImporter extends HTMLElement { this.feedback = this.shadowRoot.querySelector('#feedback') this.projectInfoContainer = this.shadowRoot.querySelector('#project-info-container') + this.#prefillManifestFromQuery() + const importHandler = this.handleImport.bind(this) this.cleanup.onElement(this.submitButton, 'click', importHandler) } + + /** + * Prefill the manifest URL input from inbound query params. + * Supports links like /project/import?manifest=https://example.com/manifest.json + * When multiple manifest values are provided, stores them as a queue and + * prompts the user to submit repeatedly to iterate through the list. + */ + #prefillManifestFromQuery() { + const params = new URLSearchParams(window.location.search) + this.#manifestQueue = params.getAll('manifest').map(value => value?.trim()).filter(Boolean) + + if (this.#manifestQueue.length === 0) return + + this.#manifestIndex = 0 + this.urlInput.value = this.#manifestQueue[0] + + this.feedback.className = 'loading' + if (this.#manifestQueue.length > 1) { + this.feedback.textContent = `Manifest 1 of ${this.#manifestQueue.length} loaded. Submit to import, then submit again to iterate through your list.` + } else { + this.feedback.textContent = 'Manifest URL loaded from link. Review it and click Import Project when ready.' + } + } + + /** + * Advances to the next manifest in the queue after a successful or failed import. + * Loads the next URL into the input and appends a progress note to the current feedback. + */ + #advanceQueue() { + const nextIndex = this.#manifestIndex + 1 + if (nextIndex >= this.#manifestQueue.length) return + + this.#manifestIndex = nextIndex + this.urlInput.value = this.#manifestQueue[nextIndex] + + const progressNote = document.createElement('small') + progressNote.textContent = ` — Manifest ${nextIndex + 1} of ${this.#manifestQueue.length} ready. Submit again to continue.` + this.feedback.appendChild(progressNote) + } setLoadingState(isLoading) { if (isLoading) { this.feedback.textContent = 'Importing project, please wait...' this.feedback.className = 'loading' this.submitButton.disabled = true } else { - this.feedback.textContent = '' this.submitButton.disabled = false } } @@ -150,6 +206,7 @@ class ProjectImporter extends HTMLElement { this.feedback.className = 'error' } finally { this.setLoadingState(false) + this.#advanceQueue() } }