UNPKG

@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
/*! * 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 @dbp-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