@digital-blueprint/formalize-app
Version:
[GitHub Repository](https://github.com/digital-blueprint/formalize-app) | [npmjs package](https://www.npmjs.com/package/@digital-blueprint/formalize-app) | [Unpkg CDN](https://unpkg.com/browse/@digital-blueprint/formalize-app/) | [Formalize Bundle](https:
335 lines (306 loc) • 27.5 kB
JavaScript
/*!
* License: LGPL-2.1-or-later
* Dependencies:
*
* @webcomponents/scoped-custom-element-registry: BSD-3-Clause
* @dbp-toolkit/app-shell: LGPL-2.1-or-later
* lit-html: BSD-3-Clause
* @dbp-toolkit/language-select: LGPL-2.1-or-later
* @dbp-toolkit/auth: LGPL-2.1-or-later
* @dbp-toolkit/theme-switcher: LGPL-2.1-or-later
* universal-router: MIT
* @dbp-toolkit/matomo: LGPL-2.1-or-later
* cssfilter: MIT
* xss: MIT
* @dbp-toolkit/form-elements: LGPL-2.1-or-later
* html2pdf.js: MIT
*/
import{f as e,o as t,p as n}from"./shared/ref.DqB7ABXf.js";import{J as r,X as i,g as a,s as o}from"./shared/directive-helpers.C6Xz79AM.js";import{t as s}from"./shared/class-map.B2bFA_il.js";import{t as c}from"./shared/translated.Blxt0tjK.js";import{t as l}from"./shared/deletion-confirmation-modal.BhX5RxrE.js";import{a as u,i as d,s as f,t as p}from"./shared/string.qUj92gVq.js";import{t as m}from"./shared/string.f-jSIclt.js";import{t as h}from"./shared/courseselect.B3SACy-o.js";var g=class extends u{getUrlSlug(){return`accessible-courses`}getFormComponent(){return _}hasReadOnlyMode(){return!0}getFormIdentifier(){return`019ada3e-b7ff-7b35-b1dd-7b578d810955`}},_=class extends d{constructor(){super(),this.saveButtonEnabled=!1,this.isUserAllowedToDownloadPdf=!1,this._fetchingUserData=!1,this._userDataFetched=!1,this.wasSubmissionSuccessful=!1,this.formData=this.formData||{},this.handleFormDeleteSubmission=this.handleFormDeleteSubmission.bind(this),this.handleFormSaveSubmission=this.handleFormSaveSubmission.bind(this),this.handleValidationOnFocusOut=this.handleValidationOnFocusOut.bind(this)}static get properties(){return{...super.properties}}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>{this.addEventListener(`DbpFormalizeFormDeleteSubmission`,this.handleFormDeleteSubmission),this.renderRoot.addEventListener(`focusout`,this.handleValidationOnFocusOut,{capture:!0}),this.addEventListener(`DbpFormalizeFormSaveSubmission`,this.handleFormSaveSubmission),this.addEventListener(`DbpFormalizeFormSubmission`,async e=>{let t=e.detail.formData,n=this._i18n;t.lecturers=this.formData.lecturers||[];try{if(this.isPostingSubmission=!0,this.wasSubmissionSuccessful)return;let e={courseName:t.courseName,courseIdentifier:this.formData.courseIdentifier??``,lecturers:t.lecturers,groupAssignment:t.groupAssignment??``,adaptations:t.adaptations,matriculationNumber:t.matriculationNumber??``,studentGivenName:t.studentGivenName??``,studentFamilyName:t.studentFamilyName??``,studentEmail:t.studentEmail??``,comment:t.comment??``},r={form:`/formalize/forms/019ada3e-b7ff-7b35-b1dd-7b578d810955`,dataFeedElement:JSON.stringify(e)},i=await fetch(this.entryPointUrl+`/formalize/submissions`,{method:`POST`,headers:{"Content-Type":`application/ld+json`,Authorization:`Bearer `+this.getToken()},body:JSON.stringify(r)});return i.ok?(this.wasSubmissionSuccessful=!0,this._(`.form-title`).style.display=`none`,this._(`.description`).style.display=`none`,this._(`#accessible-courses-form`).style.display=`none`,this.disableLeavePageWarning(),o({summary:n.t(`success.success-title`),body:n.t(`success.form-saved-successfully`),type:`success`,timeout:5}),window.dispatchEvent(new CustomEvent(`dbpFormDataUpdated`,{detail:{needUpdate:!0},bubbles:!0,composed:!0}))):(this.saveButtonEnabled=!0,await this.displayErrors(i)),this.submitted=this.wasSubmissionSuccessful,i}catch(e){console.error(e.message)}finally{this.isPostingSubmission=!1}})})}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`DbpFormalizeFormSaveSubmission`,this.handleFormSaveSubmission),this.removeEventListener(`DbpFormalizeFormDeleteSubmission`,this.handleFormDeleteSubmission),this.renderRoot.removeEventListener(`focusout`,this.handleValidationOnFocusOut,{capture:!0})}async handleValidationOnFocusOut(e){let t=window.location.href;if(new URL(t).searchParams.get(`validate`)!==`true`)return;let n=this.formElement;this.isFormValid=await f(n)}static get scopedElements(){return{...super.scopedElements,"dbp-form-string-element":p,"dbp-form-string-view":m,"dbp-course-select-element":h,"dbp-deletion-confirmation-modal":l,"dbp-translated":c}}async fetchUserData(){try{let e=await fetch(this.entryPointUrl+`/base/people/`+this.getUserId()+`?includeLocal=email,matriculationNumber`,{headers:{"Content-Type":`application/ld+json`,Authorization:`Bearer `+this.getToken()}});if(!e.ok)throw Error(`Request failed with status ${e.status}: ${e.statusText}`,{cause:e});let t=await e.json();if(this.data?.identifier)return;this.formData=this.formData||{},this.formData.identifier=String(t.identifier??``),this.formData.studentGivenName=String(t.givenName??``),this.formData.studentFamilyName=String(t.familyName??``),this.formData.matriculationNumber=String(t.localData?.matriculationNumber??``),this.formData.studentEmail=String(t.localData?.email??``),this.requestUpdate()}catch(e){console.error(e.message)}}getLecturerFallbackLabel(){return String(this.lang||``).startsWith(`de`)?`Lehrende*r unbekannt`:`Unknown lecturer`}getLecturerList(e){return Array.isArray(e)?e.map(e=>String(e).trim()).filter(Boolean):typeof e==`string`?e.split(`
`).map(e=>e.trim()).filter(Boolean):[]}async handleCourseChange(e){this.saveButtonEnabled=!1,this.formData||={},this.formData.groupAssignment=``;let t=e.detail?.course;if(this.formData.courseIdentifier=t?.identifier??``,!t){this.formData.lecturers=[this.getLecturerFallbackLabel()],this.requestUpdate();return}let n=Array.isArray(t.localData?.lecturers)?t.localData.lecturers.map(e=>typeof e==`string`?e.trim():e&&typeof e==`object`?String(e.personIdentifier||``).trim():``).filter(e=>e!==``):[],r=[];if(n.length===0)r.push(this.getLecturerFallbackLabel());else for(let e of n){if(!e){r.push(this.getLecturerFallbackLabel());continue}try{let t=await fetch(`${this.entryPointUrl}/base/people/${e}?includeLocal=email`,{headers:{"Content-Type":`application/ld+json`,Authorization:`Bearer `+this.getToken()}});if(!t.ok){console.warn(`Lecturer fetch failed for`,e,t.status),r.push(this.getLecturerFallbackLabel());continue}let n=await t.json(),i=`${n.givenName??``} ${n.familyName??``}`.trim(),a=n.localData?.email??null,o=typeof e==`string`&&/^[A-Z0-9]{8,}$/.test(e)&&!/[\s@]/.test(e);if(!i&&o){r.push(this.getLecturerFallbackLabel());continue}let s=a?`${i} (${a})`:i;r.push(s||this.getLecturerFallbackLabel())}catch(t){console.error(`Error fetching lecturer`,e,t),r.push(this.getLecturerFallbackLabel())}}this.saveButtonEnabled=!0,this.formData.lecturers=r,this.requestUpdate()}async handleFormDeleteSubmission(e){let t=this._i18n,r=e.detail.submissionId;if(!r){o({summary:t.t(`errors.error-title`),body:t.t(`errors.no-submission-id-provided`),type:`danger`,timeout:0});return}if(await this._(`#deletion-modal`).confirm())try{let e=await fetch(this.entryPointUrl+`/formalize/submissions/${r}`,{method:`DELETE`,headers:{Authorization:`Bearer `+this.getToken()}});e.ok?(this.wasDeleteSubmissionSuccessful=!0,this.deleteSubmissionError=!1):(this.deleteSubmissionError=!0,o({summary:t.t(`errors.error-title`),body:t.t(`errors.failed-to-delete-submission-status`,{status:e.status}),type:`danger`,timeout:0}))}catch(e){console.error(e),o({summary:t.t(`errors.error-title`),body:t.t(`errors.unknown-error-on-delete-submission`),type:`danger`,timeout:0})}finally{if(this.wasDeleteSubmissionSuccessful){o({summary:t.t(`success.success-title`),body:t.t(`success.form-submission-deleted-successfully`),type:`success`,timeout:5});let r=n(this.formUrlSlug,this.lang);window.history.pushState({},``,r.toString()),this.resetForm(e),this.readOnly=!1,this.sendSetPropertyEvent(`routing-url`,`/${this.formUrlSlug}`)}}}async handleFormSaveSubmission(e){let t=this._i18n;if(!e.detail.submissionId)return;let n=e.detail.formData,r=new FormData;n.lecturers=this.getLecturerList(n.lecturers);let i={courseName:n.courseName,courseIdentifier:this.formData.courseIdentifier??``,lecturers:n.lecturers,groupAssignment:n.groupAssignment??``,adaptations:n.adaptations,matriculationNumber:n.matriculationNumber??``,studentGivenName:n.studentGivenName??``,studentFamilyName:n.studentFamilyName??``,studentEmail:n.studentEmail??``,comment:n.comment??``};r.append(`dataFeedElement`,JSON.stringify(i));let a=this._buildRequestOptions(r,`PATCH`),s=this._buildSubmissionUrl(e.detail.submissionId);try{let e=await fetch(s,a);e.ok?(this.dispatchEvent(new CustomEvent(`dbpFormDataUpdated`,{detail:{needUpdate:!0},bubbles:!0,composed:!0})),this.disableLeavePageWarning(),o({summary:t.t(`success.success-title`),body:t.t(`success.form-saved-successfully`),type:`success`,timeout:5})):await this.displayErrors(e)}catch(e){console.error(e),o({summary:t.t(`errors.error-title`),body:t.t(`errors.unknown-error-on-save-submission`),type:`danger`,timeout:0})}}static get styles(){return[super.styles,a(),i`
.field-note {
margin-top: 0;
font-style: italic;
}
fieldset {
margin-bottom: 20px;
}
.description a {
text-decoration: underline;
text-underline-offset: 2px;
transition: text-underline-offset 0.1s ease-in;
}
.description a:hover {
text-underline-offset: 1px;
}
`]}render(){return r`
${this.readOnly?r`
${this.renderFormViews()}
`:r`
${this.renderFormElements()}
`}
`}renderFormElements(){let e=this._i18n,t=this.formData.studentGivenName&&this.formData.studentFamilyName&&this.formData.studentEmail;!this.data?.identifier&&!t&&!this._userDataFetched&&!this._fetchingUserData&&this.getToken()&&this.getUserId()&&(this._fetchingUserData=!0,this.fetchUserData().finally(()=>{this._fetchingUserData=!1,this._userDataFetched=!0}));let n=this.formData||{},i=this.getLecturerList(n.lecturers).length>1;return r`
<form
id="accessible-courses-form"
class=${s({hidden:this.hideForm,"readonly-mode":this.readOnly,"edit-mode":!this.readOnly,"formalize-form":!0})}>
<div class="form-header">${this.getButtonRowHtml()}</div>
<h2 class="form-title">
${e.t(`render-form.forms.accessible-courses-form.title`)}
</h2>
<div class="description">
<dbp-translated subscribe="lang">
<div slot="de">
<p class="field-note">
Bitte beachten Sie, dass die Bearbeitung von Anfragen zur
barrierefreien Lehrveranstaltungsteilnahme mehrere Werktage in
Anspruch nehmen kann. Kurzfristige Anfragen und Anfragen, die sich
auf rückwirkende Anpassungen beziehen, können nicht berücksichtigt
werden. In diesen Fällen wenden Sie sich bitte direkt an
<a href="mailto:barrierefrei-studieren@tugraz.at">
barrierefrei-studieren@tugraz.at
</a>
. Anpassungen, die ausschließlich Prüfungen betreffen, bitte
rechtzeitig über das entsprechende Formular angeben:
<a
href="https://formulare.tugraz.at/de/render-form/accessible-exams"
target="_blank">
Barrierefreie Lehrveranstaltungen
</a>
. Handelt es sich um eine Lehrveranstaltung, für die Anpassungen
über die Prüfung hinaus erforderlich sind, bitte hier im Formular
alle notwendigen Anpassungen angeben.
</p>
</div>
<div slot="en">
<p class="field-note">
Please note that processing requests for accessible participation in
courses may take several business days. Last-minute requests and
requests for retroactive adjustments cannot be considered. In such
cases, please contact
<a href="mailto:barrierefrei-studieren@tugraz.at">
barrierefrei-studieren@tugraz.at
</a>
directly. Please submit requests for adjustments that pertain
exclusively to exams in a timely manner using the appropriate form:
<a
href="https://formulare.tugraz.at/de/render-form/accessible-exams"
target="_blank">
accessible exams
</a>
. If the course requires adjustments beyond the exam, please list
all necessary adjustments here in the form.
</p>
</div>
</dbp-translated>
<p>${e.t(`render-form.forms.accessible-courses-form.mandatory-fields`)}</p>
</div>
<fieldset>
<legend>
${e.t(`render-form.forms.accessible-courses-form.course-data`)}
</legend>
<dbp-course-select-element
subscribe="lang,auth,entry-point-url"
name="courseName"
label="${e.t(`render-form.forms.accessible-courses-form.course-name`)}"
value=${n.courseName||``}
course-identifier=${n.courseIdentifier||``}
required
-course-changed=${e=>this.handleCourseChange(e)}></dbp-course-select-element>
<dbp-form-string-element
subscribe="lang"
name="lecturers"
rows=${Array.isArray(n.lecturers)&&n.lecturers.length>1?String(n.lecturers.length):`1`}
label=${e.t(`render-form.forms.accessible-courses-form.lecturers`)}
value=${Array.isArray(n.lecturers)?n.lecturers.filter(Boolean).join(`
`):n.lecturers||``}
disabled></dbp-form-string-element>
${i?r`
<dbp-form-string-element
subscribe="lang"
name="groupAssignment"
label=${e.t(`render-form.forms.accessible-courses-form.group-assignment`)}
.value=${n.groupAssignment||``}></dbp-form-string-element>
`:``}
<dbp-form-string-element
subscribe="lang"
name="adaptations"
aria-describedby="adapt-descr"
label=${e.t(`render-form.forms.accessible-courses-form.adaptations`)}
.value=${n.adaptations||``}
required
rows="5">
<div slot="description">
<dbp-translated subscribe="lang">
<div slot="de">
<p>
Gutes Beispiel: Anstelle von Tafelübungen vor den
Kommiliton*innen bitte ich um eine Übung im Einzelsetting.
<br />
Schlechtes Beispiel 1: Bitte keine Tafelübungen.
<br />
Schlechtes Beispiel 2: Bitte alle ausgemachten Adaptierungen
für diese LV anfragen.
</p>
</div>
<div slot="en">
<p>
Good example: Instead of board exercises in front of my
classmates, I’d prefer to do an exercise in a one-on-one
setting.
<br />
Bad example 1: Please, no board exercises.
<br />
Bad example 2: Please ask about all the adjustments for this
course.
</p>
</div>
</dbp-translated>
</div>
</dbp-form-string-element>
</fieldset>
<fieldset>
<legend>
${e.t(`render-form.forms.accessible-courses-form.personal-data`)}
</legend>
<dbp-form-string-element
subscribe="lang"
name="matriculationNumber"
label=${e.t(`render-form.forms.accessible-courses-form.matriculation-number`)}
value=${n.matriculationNumber||``}
disabled></dbp-form-string-element>
<dbp-form-string-element
subscribe="lang"
name="studentGivenName"
label=${e.t(`render-form.forms.accessible-courses-form.given-name`)}
value=${n.studentGivenName||``}
disabled></dbp-form-string-element>
<dbp-form-string-element
subscribe="lang"
name="studentFamilyName"
label=${e.t(`render-form.forms.accessible-courses-form.family-name`)}
value=${n.studentFamilyName||``}
disabled></dbp-form-string-element>
<dbp-form-string-element
subscribe="lang"
name="studentEmail"
label=${e.t(`render-form.forms.accessible-courses-form.email`)}
value=${n.studentEmail||``}
disabled></dbp-form-string-element>
${this.isAdmin?r`
<dbp-form-string-element
subscribe="lang"
name="comment"
label=${e.t(`render-form.forms.accessible-courses-form.comment`)}
.value=${n.comment||``}
description=${e.t(`render-form.forms.accessible-courses-form.comment-placeholder`)}
rows="5"></dbp-form-string-element>
`:``}
</fieldset>
</form>
<dbp-deletion-confirmation-modal id="deletion-modal"></dbp-deletion-confirmation-modal>
${this.renderResult(this.submitted)}
`}renderFormViews(){let e=this._i18n,t=this.formData||{},n=this.getLecturerList(t.lecturers).length>1;return r`
<form
id="accessible-courses-form"
class=${s({hidden:this.hideForm,"readonly-mode":this.readOnly,"edit-mode":!this.readOnly,"formalize-form":!0})}>
<div class="form-header">${this.getButtonRowHtml()}</div>
<h2 class="form-title">
${e.t(`render-form.forms.accessible-courses-form.title`)}
</h2>
<fieldset>
<legend>
${e.t(`render-form.forms.accessible-courses-form.course-data`)}
</legend>
<dbp-form-string-view
subscribe="lang,auth,entry-point-url"
name="courseName"
label="${e.t(`render-form.forms.accessible-courses-form.course-name`)}"
value=${t.courseName||``}></dbp-form-string-view>
<dbp-form-string-view
subscribe="lang"
name="lecturers"
label=${e.t(`render-form.forms.accessible-courses-form.lecturers`)}
value=${Array.isArray(t.lecturers)?t.lecturers.filter(Boolean).join(`, `):t.lecturers||``}></dbp-form-string-view>
${n?r`
<dbp-form-string-view
subscribe="lang"
name="groupAssignment"
label=${e.t(`render-form.forms.accessible-courses-form.group-assignment`)}
.value=${t.groupAssignment||``}></dbp-form-string-view>
`:``}
<dbp-form-string-view
subscribe="lang"
name="adaptations"
description=${e.t(`render-form.forms.accessible-courses-form.description`)}
aria-describedby="adapt-descr"
label=${e.t(`render-form.forms.accessible-courses-form.adaptations`)}
.value=${t.adaptations||``}></dbp-form-string-view>
</fieldset>
<fieldset>
<legend>
${e.t(`render-form.forms.accessible-courses-form.personal-data`)}
</legend>
<dbp-form-string-view
subscribe="lang"
name="matriculationNumber"
label=${e.t(`render-form.forms.accessible-courses-form.matriculation-number`)}
value=${t.matriculationNumber||``}
disabled></dbp-form-string-view>
<dbp-form-string-view
subscribe="lang"
name="studentGivenName"
label=${e.t(`render-form.forms.accessible-courses-form.given-name`)}
value=${t.studentGivenName||``}
disabled></dbp-form-string-view>
<dbp-form-string-view
subscribe="lang"
name="studentFamilyName"
label=${e.t(`render-form.forms.accessible-courses-form.family-name`)}
value=${t.studentFamilyName||``}
disabled></dbp-form-string-view>
<dbp-form-string-view
subscribe="lang"
name="studentEmail"
label=${e.t(`render-form.forms.accessible-courses-form.email`)}
value=${t.studentEmail||``}
disabled></dbp-form-string-view>
${this.isAdmin?r`
<dbp-form-string-view
subscribe="lang"
name="comment"
label=${e.t(`render-form.forms.accessible-courses-form.comment`)}
.value=${t.comment||``}
description=${e.t(`render-form.forms.accessible-courses-form.comment-placeholder`)}
rows="5"></dbp-form-string-view>
`:``}
</fieldset>
</form>
<dbp-deletion-confirmation-modal id="deletion-modal"></dbp-deletion-confirmation-modal>
`}renderResult(t){let i=this._i18n;return t?r`
<div class="container">
<h2>
${i.t(`render-form.forms.accessible-courses-form.submission-result-thanks`)}
</h2>
<p>
${i.t(`render-form.forms.accessible-courses-form.submission-result-notification`)}
</p>
<div class="after-submission-button-container">
${this.canUserSubmitSubmission()?r`
<a
href="${n(this.formUrlSlug,this.lang)}"
class="button button--new-submission">
<dbp-icon name="plus" aria-hidden="true"></dbp-icon>
${i.t(`success.create-new-submission-button-label`)}
</a>
`:``}
${this.areSubmissionReadableAfterSubmission()?r`
<a
href="${e(this.formIdentifier,this.lang)}"
class="button button--back-to-submissions-list">
<dbp-icon name="list" aria-hidden="true"></dbp-icon>
${i.t(`success.back-to-submissions-list-button-label`)}
</a>
`:``}
</div>
</div>
`:r``}async updated(e){super.updated(e);let n=this._i18n;if((e.has(`data`)||e.has(`readOnly`))&&(this._formHeaderObserved=!1,this.stickyHeaderObserver()),e.has(`data`)&&Object.keys(this.data).length>0){switch(this.formData=JSON.parse(this.data.dataFeedElement),this.submissionId=this.data.identifier,this.currentSubmission=this.data,this.lastModifiedCreatorId=this.data.lastModifiedById,this.submissionBinaryState=this.data.submissionState,this.submissionGrantedActions=this.data.grantedActions,Number(this.submissionBinaryState)){case 1:this.currentState=t.DRAFT;break;case 4:this.currentState=t.SUBMITTED;break;default:this.currentState=null}if(this.formData)try{let e=await this.apiGetUserDetails(this.lastModifiedCreatorId);if(!e.ok)o({summary:n.t(`errors.error-title`),body:n.t(`errors.failed-to-get-last-modifier-details`,{status:e.status}),type:`danger`,timeout:0});else{let t=await e.json();this.lastModifiedCreatorName=`${t?.givenName} ${t?.familyName}`}}catch(e){console.log(e),o({summary:n.t(`errors.error-title`),body:n.t(`errors.failed-to-get-last-modifier-details`),type:`danger`,timeout:0})}this.setButtonStates(),this.isUserAllowedToDownloadPdf=!1,this.updateComplete.then(async()=>{await this.processConditionalFields();let e=new URLSearchParams(window.location.search);if(this.readOnly===!1&&e.get(`validate`)===`true`){let e=this.formElement;this.isFormValid=await f(e),this.isFormValid||(this.scrollToFirstInvalidField(e,!0),o({summary:n.t(`errors.warning-title`),body:n.t(`errors.form-validation-warning-notification-body`),type:`warning`,timeout:0}))}})}}};export{g as default};
//# sourceMappingURL=accessibleCoursesForm.js.map