169 lines
6.1 KiB
JavaScript
169 lines
6.1 KiB
JavaScript
import {Controller} from '@hotwired/stimulus'
|
||
import Quill from 'quill'
|
||
|
||
export default class extends Controller {
|
||
static values = {
|
||
application: String,
|
||
organization: String,
|
||
user: Number,
|
||
}
|
||
static targets = ['hidden', 'submitBtn', 'appList']
|
||
|
||
connect() {
|
||
// Map each editor to its toolbar and hidden field
|
||
if (document.querySelector('#editor-description')) {
|
||
this.editors = [
|
||
{
|
||
editorSelector: '#editor-description',
|
||
toolbarSelector: '#toolbar-description',
|
||
hiddenTarget: this.hiddenTargets[0],
|
||
},
|
||
{
|
||
editorSelector: '#editor-descriptionSmall',
|
||
toolbarSelector: '#toolbar-descriptionSmall',
|
||
hiddenTarget: this.hiddenTargets[1],
|
||
},
|
||
]
|
||
|
||
this.editors.forEach(({editorSelector, toolbarSelector, hiddenTarget}) => {
|
||
const quill = new Quill(editorSelector, {
|
||
modules: {
|
||
toolbar: toolbarSelector,
|
||
},
|
||
theme: 'snow',
|
||
placeholder: 'Écrivez votre texte...',
|
||
})
|
||
|
||
quill.on('text-change', () => {
|
||
hiddenTarget.value = quill.root.innerHTML
|
||
})
|
||
|
||
hiddenTarget.value = quill.root.innerHTML
|
||
})
|
||
}
|
||
if(this.userValue){
|
||
this.loadApplications();
|
||
}
|
||
}
|
||
|
||
handleAuthorizeSubmit(event) {
|
||
event.preventDefault();
|
||
|
||
const originalText = this.submitBtnTarget.textContent;
|
||
|
||
if (!confirm(`Vous vous apprêtez à donner l'accès à ${this.organizationValue} pour ${this.applicationValue}. Êtes‑vous sûr(e) ?`)) {
|
||
return;
|
||
}
|
||
|
||
this.submitBtnTarget.textContent = 'En cours...';
|
||
this.submitBtnTarget.disabled = true;
|
||
|
||
fetch(event.target.action, {
|
||
method: 'POST',
|
||
body: new FormData(event.target)
|
||
})
|
||
.then(response => {
|
||
if (response.ok) {
|
||
this.submitBtnTarget.textContent = 'Autorisé ✓';
|
||
this.submitBtnTarget.classList.replace('btn-secondary', 'btn-success');
|
||
} else {
|
||
this.submitBtnTarget.textContent = originalText;
|
||
this.submitBtnTarget.disabled = false;
|
||
alert('Erreur lors de l\'action');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
this.submitBtnTarget.textContent = originalText;
|
||
this.submitBtnTarget.disabled = false;
|
||
alert('Erreur lors de l\'action');
|
||
});
|
||
}
|
||
|
||
handleRemoveSubmit(event) {
|
||
event.preventDefault();
|
||
|
||
const originalText = this.submitBtnTarget.textContent;
|
||
|
||
if (!confirm(`Vous vous apprêtez à retirer l'accès à ${this.applicationValue} pour ${this.organizationValue}. Êtes‑vous sûr(e) ?`)) {
|
||
return;
|
||
}
|
||
|
||
this.submitBtnTarget.textContent = 'En cours...';
|
||
this.submitBtnTarget.disabled = true;
|
||
|
||
fetch(event.target.action, {
|
||
method: 'POST',
|
||
body: new FormData(event.target)
|
||
})
|
||
.then(response => {
|
||
if (response.ok) {
|
||
this.submitBtnTarget.textContent = 'Retiré ✓';
|
||
this.submitBtnTarget.classList.replace('btn-secondary', 'btn-danger');
|
||
} else {
|
||
this.submitBtnTarget.textContent = originalText;
|
||
this.submitBtnTarget.disabled = false;
|
||
alert('Erreur lors de l\'action');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
this.submitBtnTarget.textContent = originalText;
|
||
this.submitBtnTarget.disabled = false;
|
||
alert('Erreur lors de l\'action');
|
||
});
|
||
}
|
||
|
||
async loadApplications() {
|
||
if (!this.userValue) return;
|
||
|
||
try {
|
||
// Note: Ensure the URL matches your route prefix (e.g. /application/user/123)
|
||
// Adjust the base path below if your controller route is prefixed!
|
||
const response = await fetch(`/application/user/${this.userValue}`);
|
||
|
||
if (!response.ok) throw new Error("Failed to load apps");
|
||
|
||
const apps = await response.json();
|
||
this.renderApps(apps);
|
||
|
||
} catch (error) {
|
||
console.error(error);
|
||
this.appListTarget.innerHTML = `<span class="text-danger small">Erreur</span>`;
|
||
}
|
||
}
|
||
|
||
renderApps(apps) {
|
||
if (apps.length === 0) {
|
||
// Span 2 columns if empty so the message is centered
|
||
this.appListTarget.innerHTML = `<span class="text-muted small" style="grid-column: span 2; text-align: center;">Aucune application</span>`;
|
||
return;
|
||
}
|
||
|
||
const html = apps.map(app => {
|
||
const url = `https://${app.subDomain}.solutions-easy.com`;
|
||
|
||
// Check for logo string vs object
|
||
const logoSrc = (typeof app.logoMiniUrl === 'string') ? app.logoMiniUrl : '';
|
||
|
||
// Render Icon (Image or Fallback)
|
||
const iconHtml = logoSrc
|
||
? `<img src="${logoSrc}" style="width:32px; height:32px; object-fit:contain; margin-bottom: 5px;">`
|
||
: `<i class="bi bi-box-arrow-up-right text-primary" style="font-size: 24px; margin-bottom: 5px;"></i>`;
|
||
|
||
// Return a Card-like block
|
||
return `
|
||
<a href="${url}" target="_blank"
|
||
class="d-flex flex-column align-items-center justify-content-center p-3 rounded text-decoration-none text-dark bg-light-hover"
|
||
style="transition: background 0.2s; height: 100%;">
|
||
|
||
${iconHtml}
|
||
|
||
<span class="fw-bold text-center text-truncate w-100" style="font-size: 0.85rem;">
|
||
${app.name}
|
||
</span>
|
||
</a>
|
||
`;
|
||
}).join('');
|
||
|
||
this.appListTarget.innerHTML = html;
|
||
}
|
||
} |