Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
fix: Simplify preview command (LPS-152388)
Browse files Browse the repository at this point in the history
In order to avoid reloading the page accidentally, the url is being updated
only if needed (adding/removing changed parameters). Moreover, now it
is not necessary to specify if the selected fragment is a composition.
  • Loading branch information
p2kmgcl authored and victorg1991 committed May 4, 2022
1 parent 7731d35 commit 0d8ff2e
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 205 deletions.
35 changes: 18 additions & 17 deletions src/preview/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,33 @@
<link rel="stylesheet" href="/preview.css" />
</head>
<body>
<form>
<div>
<label for="previewType">
Preview type:
<select id="previewType"></select>
</label>
</div>
<form id="form">
<label>
Preview type:
<select name="fieldsetId">
<option value="fragmentsPreview">Fragments</option>
<option value="pageTemplatesPreview">Page Templates</option>
</select>
</label>

<div class="hide" id="fragmentsPreview">
<label for="collection">
<fieldset disabled id="fragmentsPreview">
<label>
Collection:
<select id="collection"></select>
<select name="collection"></select>
</label>

<label for="fragment">
<label>
Fragment:
<select disabled id="fragment"></select>
<select name="fragment"></select>
</label>
</div>
</fieldset>

<div class="hide" id="pageTemplatesPreview">
<label for="pageTemplate">
<fieldset disabled id="pageTemplatesPreview">
<label>
Page Template:
<select disabled id="pageTemplate"></select>
<select name="pageTemplate"></select>
</label>
</div>
</fieldset>
</form>

<iframe id="preview" src="/fragment-preview"></iframe>
Expand Down
7 changes: 6 additions & 1 deletion src/preview/assets/preview.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ iframe {
flex-grow: 1;
}

.hide {
fieldset {
border: none;
padding: 0;
}

fieldset[disabled] {
display: none;
}
252 changes: 98 additions & 154 deletions src/preview/assets/preview.js
Original file line number Diff line number Diff line change
@@ -1,192 +1,136 @@
// @ts-nocheck
/* global SOCKET_SERVER_PORT */

/** @type {HTMLSelectElement} */
const collectionSelect = document.getElementById('collection');

/** @type {HTMLSelectElement} */
const fragmentSelect = document.getElementById('fragment');

/** @type {HTMLSelectElement} */
const pageTemplateSelect = document.getElementById('pageTemplate');

/** @type {HTMLSelectElement} */
const previewTypeSelect = document.getElementById('previewType');

/** @type {HTMLElement} */
const fragmentsPreview = document.getElementById('fragmentsPreview');

/** @type {HTMLElement} */
const pageTemplatesPreview = document.getElementById('pageTemplatesPreview');

/** @type {HTMLIFrameElement} */
const form = document.getElementById('form');
const preview = document.getElementById('preview');

const socket = new WebSocket(`ws://${location.hostname}:${SOCKET_SERVER_PORT}`);

let currentCollection = '';
let projectContent = {};
let initialized = false;

/**
* @param {HTMLSelectElement} selectElement Select element
*/
function syncSelectFieldURL(selectElement) {
const url = new URL(location.href);
url.searchParams.set(selectElement.id, selectElement.value);
history.pushState(null, null, url.href);
function isDisabled(element) {
return element
? element.disabled || isDisabled(element.parentElement)
: false;
}

collectionSelect.addEventListener('change', () => {
const collectionId = collectionSelect.value;

if (collectionId) {
syncSelectFieldURL(collectionSelect);

const collection = projectContent.collections.find(
(collection) => collection.slug === collectionId
);

renderSelect(
fragmentSelect,
collection.fragments
.map((fragment) => ({
value: fragment.slug,
label: fragment.metadata.name,
type: 'fragment',
}))
.concat(
collection.fragmentCompositions.map((composition) => ({
value: composition.slug,
label: composition.metadata.name,
type: 'composition',
}))
)
);
}
});

fragmentSelect.addEventListener('change', () => {
if (fragmentSelect.value) {
syncSelectFieldURL(fragmentSelect);
function updateOptions(list, select) {
const previousValue = select.value;
select.innerHTML = '';

const type = fragmentSelect.selectedOptions[0].dataset.type;
for (const item of list) {
const option = document.createElement('option');
option.value = item.slug;
option.innerHTML = item.metadata.name;
select.appendChild(option);
}

preview.src = `/fragment-preview?collection=${collectionSelect.value}&fragment=${fragmentSelect.value}&type=${type}`;
if (list.some((item) => item.slug === previousValue)) {
select.value = previousValue;
}
});
}

pageTemplateSelect.addEventListener('change', () => {
if (pageTemplateSelect.value) {
syncSelectFieldURL(pageTemplateSelect);
function updateCurrentCollection() {
currentCollection = form.elements.collection.value;

const type = 'page-template';
const collection = projectContent.collections.find(
(collection) => collection.slug === currentCollection
);

preview.src = `/fragment-preview?pageTemplate=${pageTemplateSelect.value}&type=${type}`;
if (!collection) {
return;
}
});

previewTypeSelect.addEventListener('change', () => {
const changeEvent = new Event('change');
const url = new URL(location.href);
updateOptions(
[...collection.fragments, ...collection.fragmentCompositions],
form.elements.fragment
);
}

url.searchParams.forEach((_, key) => {
url.searchParams.delete(key);
});
function handleFormChange() {
const fieldsetId = form.elements.fieldsetId.value;

url.searchParams.set(previewTypeSelect.id, previewTypeSelect.value);
for (const fieldset of form.querySelectorAll('fieldset')) {
if (fieldset.id === fieldsetId) {
fieldset.disabled = false;
} else {
fieldset.disabled = true;
}
}

history.pushState(null, null, url.href);
if (form.elements.collection.value !== currentCollection) {
updateCurrentCollection();
}

if (previewTypeSelect.value === 'page-template') {
fragmentsPreview.className = 'hide';
pageTemplatesPreview.className = '';
const url = new URL(location.href);

renderSelect(
pageTemplateSelect,
projectContent.pageTemplates.map((pageTemplate) => ({
value: pageTemplate.slug,
label: pageTemplate.metadata.name,
}))
);
for (const element of form.elements) {
if (element.name) {
if (element.value && !isDisabled(element)) {
if (url.searchParams.get(element.name) !== element.value) {
url.searchParams.set(element.name, element.value);
history.pushState(null, null, url.href);
}
} else if (url.searchParams.has(element.name)) {
url.searchParams.delete(element.name);
history.pushState(null, null, url.href);
}
}
}

pageTemplateSelect.dispatchEvent(changeEvent);
if (
fieldsetId === 'fragmentsPreview' &&
form.elements.collection.value &&
form.elements.fragment.value
) {
const collectionSlug = form.elements.collection.value;
const fragmentSlug = form.elements.fragment.value;

preview.src = `/fragment-preview?collection=${collectionSlug}&fragment=${fragmentSlug}`;
} else if (
fieldsetId === 'pageTemplatesPreview' &&
form.elements.pageTemplate.value
) {
const pageTemplateSlug = form.elements.pageTemplate.value;
preview.src = `/fragment-preview?pageTemplate=${pageTemplateSlug}`;
} else {
fragmentsPreview.className = '';
pageTemplatesPreview.className = 'hide';
preview.src = '/fragment-preview';
}
}

renderSelect(fragmentSelect, []);
function handleMessage(event) {
projectContent = JSON.parse(event.data);

renderSelect(
collectionSelect,
projectContent.collections.map((collection) => ({
value: collection.slug,
label: collection.metadata.name,
}))
);
updateOptions(projectContent.collections, form.elements.collection);
updateOptions(projectContent.pageTemplates, form.elements.pageTemplate);

collectionSelect.dispatchEvent(changeEvent);
}
});
if (!initialized) {
initialized = true;
preview.src = '/fragment-preview';

function renderSelect(selectElement, options) {
const selectedOption = new URL(location.href).searchParams.get(
selectElement.id
);
const url = new URL(window.location.href);

selectElement.innerHTML = '';
form.elements.fieldsetId.value =
url.searchParams.get('fieldsetId') || form.elements.fieldsetId.value;

options.forEach((option) => {
const optionElement = document.createElement('option');
form.elements.pageTemplate.value =
url.searchParams.get('pageTemplate') || form.elements.pageTemplate.value;

optionElement.value = option.value;
optionElement.innerHTML = option.label;
optionElement.setAttribute('data-type', option.type);
form.elements.collection.value =
url.searchParams.get('collection') || form.elements.collection.value;

selectElement.appendChild(optionElement);
});
updateCurrentCollection();

if (options.length) {
selectElement.removeAttribute('disabled');
} else {
selectElement.setAttribute('disabled', 'disabled');
}
form.elements.fragment.value =
url.searchParams.get('fragment') || form.elements.fragment.value;

if (selectedOption) {
selectElement.value = selectedOption;
} else if (options.length === 1) {
selectElement.value = options[0].value;
handleFormChange();
} else if (preview.src) {
// eslint-disable-next-line no-self-assign
preview.src = preview.src;
}

const changeEvent = new Event('change');
selectElement.dispatchEvent(changeEvent);
}

socket.addEventListener('message', (event) => {
projectContent = JSON.parse(event.data);

preview.src = '/fragment-preview';

renderSelect(previewTypeSelect, [
{ value: 'fragment', label: 'Fragments' },
{ value: 'page-template', label: 'Page Templates' },
]);

if (previewTypeSelect.value === 'fragment') {
renderSelect(fragmentSelect, []);

renderSelect(
collectionSelect,
projectContent.collections.map((collection) => ({
value: collection.slug,
label: collection.metadata.name,
}))
);
} else {
renderSelect(
pageTemplateSelect,
projectContent.pageTemplates.map((pageTemplate) => ({
value: pageTemplate.slug,
label: pageTemplate.metadata.name,
}))
);
}
});
socket.addEventListener('message', handleMessage);
form.addEventListener('change', handleFormChange);
Loading

0 comments on commit 0d8ff2e

Please sign in to comment.