import React, { useState, useEffect } from 'react';
import './AEMTemplatesDashboard.css';
const AEMTemplatesDashboard = (props) => {
const { listDataProps = `{}` } = props; //props from aem/html
console.log('Properties' + JSON.stringify(listDataProps));
const { message, pattern, configurationPathPattern, liveusageQueryPath } =
listDataProps; //props from redux/state
const [loading, setLoading] = useState(false);
const [aemTemplateList, setAemTemplateList] = useState([]);
const [query, setQuery] = useState('');
const [tabWindow, setTabWindow] = useState('templates');
const [aemLiveUsageList, setAemLiveUsageList] = useState([]);
const [aemLiveUsageListSize, setAemLiveUsageListSize] = useState(0);
const [selectedTemplatePath, setSelectedTemplatePath] = useState(null);
//const [scale, setScale] = useState(0); //local state is not used, state kept in redux, allows to state sharing all components.
useEffect(() => {
getTemplates();
}, [query]);
async function getCsrfToken() {
const response = await fetch('/libs/granite/csrf/token.json');
const json = await response.json();
return json.token;
}
async function getTemplates() {
const details = {
q: query,
tp: pattern,
tcp: configurationPathPattern,
};
let formBody = [];
for (const property in details) {
if (details[property]) {
const encodedKey = encodeURIComponent(property);
const encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
}
formBody = formBody.join('&');
fetch('/bin/aemcatalog.templates.json', {
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'CSRF-Token': await getCsrfToken(),
},
method: 'POST',
body: formBody,
})
.then((response) => response.json())
.then((templates) => {
if (templates && templates.aemTemplateList) {
setAemTemplateList(templates.aemTemplateList);
} else {
setAemTemplateList([]);
console.log('No template options loaded.');
}
setLoading(false);
})
.catch((err) => {
console.log(err);
setLoading(false);
setAemTemplateList([]);
});
}
function getWsParameter() {
const search = window.location.search;
const params = new URLSearchParams(search);
const wsValue = params.get('ws');
if (wsValue) {
return wsValue;
}
return '';
}
async function getLiveUsage(templatePath, liveusageQueryPath) {
setSelectedTemplatePath(templatePath);
const details = {
qpath: liveusageQueryPath,
tpath: templatePath,
ws: getWsParameter(),
};
let formBody = [];
for (const property in details) {
if (details[property]) {
const encodedKey = encodeURIComponent(property);
const encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
}
formBody = formBody.join('&');
fetch('/bin/aemcatalog.templateusage.json', {
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'CSRF-Token': await getCsrfToken(),
},
method: 'POST',
body: formBody,
})
.then((response) => response.json())
.then((components) => {
if (components && components.aemTemplateUsageList) {
setAemLiveUsageList(components.aemTemplateUsageList);
setAemLiveUsageListSize(components.count);
} else {
setAemLiveUsageList([]);
setAemLiveUsageListSize(0);
console.log('No component options loaded.');
}
//setLoading(false);
})
.catch((err) => {
console.log(err);
//setLoading(false);
setAemLiveUsageList([]);
setAemLiveUsageListSize(0);
});
}
return (
<div className="dashboard">
{/* templates*/}
<div
className={
' ' + (tabWindow === 'templates' ? 'display-tab' : 'hide-tab')
}
>
<div className="template-controls container">
<div className="row">
<div className="col-lg-3 col-xs-6 mb-3">
<label htmlFor="filterListInput" className="form-label filter">
Filter list by name
</label>
<input
type="text"
className="form-control"
id="filterListInput"
placeholder=""
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
</div>
</div>
</div>
<div className="template-list container">
{loading && <div>Loading...</div>}
{aemTemplateList && (
<div className="component-group">
<div className="row">
{aemTemplateList.map((template, index) => (
<div
key={index}
className="col-xl-3 col-lg-4 col-md-6 col-xs-12"
>
<a
className="card"
onClick={(e) => {
setTabWindow('liveusage');
getLiveUsage(template.path, liveusageQueryPath);
}}
>
<div className="card-body">
<h5 className="card-title">{template.title}</h5>
{template.thumbnailPath && (
<img
className="card-image"
src={template.thumbnailPath}
/>
)}
{!template.thumbnailPath && (
<img
className="card-image"
src="/etc.clientlibs/aem-component-catalog/clientlibs/clientlib-react/resources/placeholder.svg"
/>
)}
<h6 className="card-subtitle">{template.name}</h6>
<p className="card-text">{template.description}</p>
<p className="card-text">{template.path}</p>
<span className="card-link">
<span className="material-symbols-rounded">info</span>{' '}
View Usage Details
</span>
</div>
</a>
</div>
))}
</div>
</div>
)}
</div>
</div>
{/* End templates*/}
{/* liveusage*/}
<div
className={
' ' + (tabWindow === 'liveusage' ? 'display-tab' : 'hide-tab')
}
>
<a
className="nav-link"
onClick={(e) => {
setTabWindow('templates');
}}
>
← Back to Templates
</a>
<table className="liveusage-list table">
<thead>
<tr>
<th scope="col">Count</th>
<th scope="col">Template</th>
</tr>
</thead>
<tbody>
<tr>
<td>{aemLiveUsageListSize}</td>
<td>{selectedTemplatePath}</td>
</tr>
</tbody>
</table>
<table className="liveusage-list table">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Page or Fragment Path</th>
</tr>
</thead>
{aemLiveUsageList && (
<tbody>
{aemLiveUsageList.map((item, index) => (
<tr key={index}>
<td>{item.title}</td>
<td>{item.path}</td>
</tr>
))}
</tbody>
)}
</table>
</div>
{/* End liveusage*/}
</div>
);
};
export { AEMTemplatesDashboard };