@digital-blueprint/dispatch-app
Version:
[GitHub Repository](https://github.com/digital-blueprint/dispatch-app) | [npmjs package](https://www.npmjs.com/package/@digital-blueprint/dispatch-app) | [Unpkg CDN](https://unpkg.com/browse/@digital-blueprint/dispatch-app/) | [Dispatch Bundle](https://gi
1,369 lines (1,235 loc) • 205 kB
JavaScript
import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
import {createInstance} from './i18n';
import {unsafeHTML} from 'lit/directives/unsafe-html.js';
import {send} from '@dbp-toolkit/common/notification';
import MicroModal from './micromodal.es';
import {FileSource, FileSink} from '@dbp-toolkit/file-handling';
import {html} from 'lit';
import * as dispatchHelper from './utils';
import {CustomPersonSelect} from './person-select';
import {ResourceSelect} from '@dbp-toolkit/resource-select';
import {IconButton, LoadingButton} from '@dbp-toolkit/common';
import {humanFileSize} from '@dbp-toolkit/common/i18next';
import {classMap} from 'lit/directives/class-map.js';
import {PdfViewer} from '@dbp-toolkit/pdf-viewer';
import {getReferenceNumberFromPDF} from './utils';
import {TabulatorTable} from '@dbp-toolkit/tabulator-table';
export default class DBPDispatchLitElement extends DBPLitElement {
constructor() {
super();
this.isSessionRefreshed = false;
this.auth = {};
this._i18n = createInstance();
this.lang = this._i18n.language;
this.entryPointUrl = '';
this.fileHandlingEnabledTargets = 'local';
this.nextcloudWebAppPasswordURL = '';
this.nextcloudWebDavURL = '';
this.nextcloudName = '';
this.nextcloudFileURL = '';
this.nextcloudAuthInfo = '';
this.currentItem = {};
this.currentItemTabulator = {};
this.currentRecipient = {};
this.subject = '';
this.groupId = '';
this.groupValue = this.loadGroupValue();
this.personSelectorIsDisabled = false;
this.singleFileProcessing = false;
this.totalNumberOfCreatedRequestItems = 0;
this.currentTable = {};
this.currentRowIndex = '';
this.createdRequestsList = [];
this.tempItem = {};
this.tempValue = {};
this.tempChange = false;
}
static get scopedElements() {
return {
'dbp-file-source': FileSource,
'dbp-file-sink': FileSink,
'dbp-person-select': CustomPersonSelect,
'dbp-resource-select': ResourceSelect,
'dbp-icon-button': IconButton,
'dbp-pdf-viewer': PdfViewer,
};
}
static get properties() {
return {
...super.properties,
auth: {type: Object},
currentItem: {type: Object, attribute: false},
currentItemTabulator: {type: Object, attribute: false},
currentRecipient: {type: Object, attribute: false},
personSelectorIsDisabled: {type: Boolean, attribute: false},
subject: {type: String, attribute: false},
groupId: {type: String, attribute: false},
tempItem: {type: Object, attribute: false},
tempValue: {type: Object, attribute: false},
createdRequestsList: {type: Array, attribute: false},
fileHandlingEnabledTargets: {type: String, attribute: 'file-handling-enabled-targets'},
nextcloudWebAppPasswordURL: {type: String, attribute: 'nextcloud-web-app-password-url'},
nextcloudWebDavURL: {type: String, attribute: 'nextcloud-webdav-url'},
nextcloudName: {type: String, attribute: 'nextcloud-name'},
nextcloudFileURL: {type: String, attribute: 'nextcloud-file-url'},
nextcloudAuthInfo: {type: String, attribute: 'nextcloud-auth-info'},
};
}
connectedCallback() {
super.connectedCallback();
this._loginStatus = '';
this._loginState = [];
}
/**
* Request a re-rendering every time isLoggedIn()/isLoading() changes
*/
_updateAuth() {
this._loginStatus = this.auth['login-status'];
let newLoginState = [this.isLoggedIn(), this.isLoading()];
if (this._loginState.toString() !== newLoginState.toString()) {
this.requestUpdate();
}
this._loginState = newLoginState;
}
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
case 'auth':
this._updateAuth();
break;
}
});
super.update(changedProperties);
}
/**
* Returns if a person is set in or not
* @returns {boolean} true or false
*/
isLoggedIn() {
return this.auth.person !== undefined && this.auth.person !== null;
}
/**
* Returns true if a person has successfully logged in
* @returns {boolean} true or false
*/
isLoading() {
if (this._loginStatus === 'logged-out') return false;
return !this.isLoggedIn() && this.auth.token !== undefined;
}
/**
* Send a fetch to given url with given options
* @param url
* @param options
* @returns {Promise<object>} response (error or result)
*/
async httpGetAsync(url, options) {
let response = await fetch(url, options)
.then((result) => {
if (!result.ok) throw result;
return result;
})
.catch((error) => {
return error;
});
return response;
}
/**
* Gets the list of all dispatch requests of the current logged-in user
* @param groupId
* @returns {Promise<object>} response
*/
async getListOfDispatchRequests(groupId) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/requests?perPage=9999&groupId=' + groupId,
options,
);
}
/**
* Gets the dispatch request of the current logged-in user with the given identifier
* @param identifier
* @returns {Promise<object>} response
*/
async getDispatchRequest(identifier) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/requests/' + identifier,
options,
);
}
/**
* Gets the dispatch recipient of the given ID
* @param identifier
* @returns {Promise<object>} response
*/
async getDispatchRecipient(identifier) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/request-recipients/' + identifier,
options,
);
}
/**
* @returns {string}
*/
getDefaultReferenceNumber() {
const i18n = this._i18n;
return i18n.t('create-request.default-reference-number');
}
/**
* Sends a dispatch post request
* @returns {Promise<object>} response
*/
async sendCreateDispatchRequest() {
const i18n = this._i18n;
let body = {
name:
this.subject && this.subject !== ''
? this.subject
: i18n.t('create-request.default-subject'),
senderOrganizationName: this.currentItem.senderOrganizationName,
senderFullName: this.currentItem.senderFullName
? this.currentItem.senderFullName
: i18n.t('create-request.sender-full-name')
? i18n.t('create-request.sender-full-name')
: '',
senderAddressCountry: this.currentItem.senderAddressCountry,
senderPostalCode: this.currentItem.senderPostalCode,
senderAddressLocality: this.currentItem.senderAddressLocality,
senderStreetAddress: this.currentItem.senderStreetAddress,
senderBuildingNumber: '', //this.currentItem.senderBuildingNumber,
groupId: this.groupId,
referenceNumber: this.getDefaultReferenceNumber(),
};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
body: JSON.stringify(body),
};
return await this.httpGetAsync(this.entryPointUrl + '/dispatch/requests', options);
}
/**
* Sends a delete dispatch request
* @param identifier
* @returns {Promise<object>} response
*/
async sendDeleteDispatchRequest(identifier) {
const options = {
method: 'DELETE',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/requests/' + identifier,
options,
);
}
/**
* Updates (PATCHes) a dispatch request
* @param identifier
* @param body
* @returns {Promise<object>} response
*/
async sendPatchDispatchRequest(identifier, body) {
const options = {
method: 'PATCH',
headers: {
'Content-Type': 'application/merge-patch+json',
Authorization: 'Bearer ' + this.auth.token,
},
body: JSON.stringify(body),
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/requests/' + encodeURIComponent(identifier),
options,
);
}
/**
* Sends a put dispatch request
* @param identifier
* @param senderOrganizationName
* @param senderFullName
* @param senderAddressCountry
* @param senderPostalCode
* @param senderAddressLocality
* @param senderStreetAddress
* @param senderBuildingNumber
* @param groupId
* @returns {Promise<object>} response
*/
async sendEditDispatchRequest(
identifier,
senderOrganizationName,
senderFullName,
senderAddressCountry,
senderPostalCode,
senderAddressLocality,
senderStreetAddress,
senderBuildingNumber,
groupId,
) {
let body = {
senderOrganizationName: senderOrganizationName,
senderFullName: senderFullName,
senderAddressCountry: senderAddressCountry,
senderPostalCode: senderPostalCode,
senderAddressLocality: senderAddressLocality,
senderStreetAddress: senderStreetAddress,
senderBuildingNumber: senderBuildingNumber,
groupId: groupId,
};
return await this.sendPatchDispatchRequest(identifier, body);
}
/**
* Sends a submit dispatch request
* @param identifier
* @returns {Promise<object>} response
*/
async sendSubmitDispatchRequest(identifier) {
let body = {};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
body: JSON.stringify(body),
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/requests/' + identifier + '/submit',
options,
);
}
/**
* Sends a dispatch request-recipients post request
* @param id
* @param personIdentifier
* @param givenName
* @param familyName
* @param birthDate
* @param addressCountry
* @param postalCode
* @param addressLocality
* @param streetAddress
* @returns {Promise<object>} response
*/
async sendAddRequestRecipientsRequest(
id,
personIdentifier,
givenName,
familyName,
birthDate,
addressCountry,
postalCode,
addressLocality,
streetAddress,
) {
let body;
if (personIdentifier === null) {
if (birthDate !== '') {
body = {
dispatchRequestIdentifier: id,
givenName: givenName,
familyName: familyName,
addressCountry: addressCountry,
postalCode: postalCode,
addressLocality: addressLocality,
streetAddress: streetAddress,
buildingNumber: '',
birthDate: birthDate,
};
} else {
body = {
dispatchRequestIdentifier: id,
givenName: givenName,
familyName: familyName,
addressCountry: addressCountry,
postalCode: postalCode,
addressLocality: addressLocality,
streetAddress: streetAddress,
buildingNumber: '',
};
}
} else {
body = {
dispatchRequestIdentifier: id,
personIdentifier: personIdentifier,
buildingNumber: '',
};
}
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
body: JSON.stringify(body),
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/request-recipients',
options,
);
}
async sendDeleteRecipientRequest(id) {
const options = {
method: 'DELETE',
headers: {
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/request-recipients/' + id,
options,
);
}
async sendAddFileToRequest(id, file) {
let formData = new FormData();
formData.append('dispatchRequestIdentifier', id);
formData.append('file', file);
const options = {
method: 'POST',
headers: {
Authorization: 'Bearer ' + this.auth.token,
},
body: formData,
};
return await this.httpGetAsync(this.entryPointUrl + '/dispatch/request-files', options);
}
async sendDeleteFileRequest(id) {
const options = {
method: 'DELETE',
headers: {
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/request-files/' + id,
options,
);
}
async sendGetPersonDetailsRequest(identifier) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl +
'/base/people/' +
identifier +
'?includeLocal=streetAddress%2CaddressLocality%2CpostalCode%2CaddressCountry',
options,
);
}
async sendGetPersonRequest(identifier) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(this.entryPointUrl + '/base/people/' + identifier, options);
}
async sendChangeSubjectRequest(identifier, subject) {
let body = {
name: subject,
};
return await this.sendPatchDispatchRequest(identifier, body);
}
/**
* Send a PATCH request to the API to change the reference number of a request
* @param identifier The identifier of the dispatch request
* @param referenceNumber The new reference number
*/
async sendChangeReferenceNumberRequest(identifier, referenceNumber) {
let body = {
referenceNumber: referenceNumber,
};
return await this.sendPatchDispatchRequest(identifier, body);
}
async sendGetStatusChangeRequest(identifier) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/request-status-changes/' + identifier,
options,
);
}
async sendGetFileRequest(identifier) {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
};
return await this.httpGetAsync(
this.entryPointUrl + '/dispatch/request-files/' + identifier,
options,
);
}
async getCreatedDispatchRequests() {
this.createRequestsLoading = !this._initialFetchDone;
this.tableLoading = true;
this.createdRequestsList = [];
let createdRequestsIds = this.createdRequestsIds;
if (createdRequestsIds !== undefined) {
for (let i = 0; i < createdRequestsIds.length; i++) {
try {
let response = await this.getDispatchRequest(createdRequestsIds[i]);
let responseBody = await response.json();
if (responseBody !== undefined && responseBody.status !== 403) {
this.createdRequestsList.push(responseBody);
} else {
if (response.status === 500) {
send({
summary: 'Error!',
body: 'Could not fetch dispatch requests. Response code: 500',
type: 'danger',
timeout: 5,
});
} else if (response.status === 403) {
//TODO
}
}
} catch (e) {
console.error(`${e.name}: ${e.message}`);
send({
summary: 'Error!',
body: 'Could not fetch dispatch requests.',
type: 'danger',
timeout: 5,
});
}
}
}
this.tableLoading = false;
this.createRequestsLoading = false;
this._initialFetchDone = true;
this.showListView = true;
return this.createdRequestsList;
}
/*
* Open file source
*
*/
openFileSource() {
this.fileUploadFinished = false;
const fileSource = /** @type {FileSource} */ (this._('#file-source'));
if (fileSource) {
fileSource.openDialog();
}
if (this.singleFileProcessing && !this.requestCreated) {
this.processCreateDispatchRequest().then(() => {
this.showDetailsView = true;
this.hasSubject = true;
this.hasSender = true;
});
}
this.currentItemTabulator = this.currentItem;
}
onFileUploadFinished(event) {
this.fileUploadFinished = true;
this.uploadedNumberOfFiles = event.detail.count;
this.currentFileIndex = 0;
const i18n = this._i18n;
if (!this.errorCreatingRequest && this.uploadedNumberOfFiles > 0) {
send({
summary: i18n.t('create-request.successfully-requested-title'),
body: this.singleFileProcessing
? i18n.t('create-request.successfully-requested-text')
: i18n.t('create-request.successfully-requested-text-multiple'),
type: 'success',
timeout: 5,
});
} else {
send({
summary: i18n.t('create-request.error-requested-title'),
body: i18n.t('create-request.error-requested-text'),
type: 'danger',
timeout: 5,
});
}
this.errorCreatingRequest = false;
}
async onFileSelected(event) {
this.tableLoading = true;
this.fileUploadFinished = false;
if (!this.singleFileProcessing && !this.requestCreated) {
this.processCreateDispatchRequest().then(async () => {
this.showDetailsView = false;
this.showListView = true;
this.hasSubject = true;
this.hasSender = true;
this.createdRequestsIds.push(this.currentItem.identifier);
this.totalNumberOfCreatedRequestItems++;
await this.addFile(event.detail.file);
this.filesAdded = true;
});
} else {
await this.addFile(event.detail.file);
}
}
async addFile(file) {
const addFileButton = /** @type {LoadingButton} */ (this._('#add-files-btn'));
addFileButton.start();
try {
let id = this.currentItem.identifier;
await this.addFileToRequest(id, file);
} catch (e) {
console.error(`${e.name}: ${e.message}`);
send({
summary: 'Error!',
body: 'There was an error.',
type: 'danger',
timeout: 5,
});
} finally {
this.tableLoading = false;
addFileButton.stop();
}
}
async addFileToRequest(id, file) {
const i18n = this._i18n;
// Get the reference number from the PDF
const referenceNumber = await getReferenceNumberFromPDF(file);
// We override the existing reference number if it isn't set or is equal to the default one
let shouldOverrideReferenceNumber = false;
if (
!this.currentItem.referenceNumber ||
this.currentItem.referenceNumber === this.getDefaultReferenceNumber()
) {
shouldOverrideReferenceNumber = true;
}
// Set the reference number if it is not set yet, and we have a valid one
if (referenceNumber !== null && shouldOverrideReferenceNumber) {
const response = await this.sendChangeReferenceNumberRequest(id, referenceNumber);
if (response.status !== 200) {
console.error('Could not set reference number!');
send({
summary: i18n.t(
'show-requests.error-reference-number-auto-update-failed-title',
),
body: i18n.t('show-requests.error-reference-number-auto-update-failed-text'),
type: 'danger',
timeout: 5,
});
} else {
this.currentItem.referenceNumber = referenceNumber;
send({
summary: i18n.t(
'show-requests.error-reference-number-auto-update-success-title',
),
body: i18n.t('show-requests.error-reference-number-auto-update-success-text'),
type: 'info',
timeout: 5,
});
}
}
let response = await this.sendAddFileToRequest(id, file);
let responseBody = await response.json();
if (responseBody !== undefined && response.status === 201) {
if (this.singleFileProcessing) {
//TODO
send({
summary: i18n.t('show-requests.successfully-added-file-title'),
body: i18n.t('show-requests.successfully-added-file-text'),
type: 'success',
timeout: 5,
});
}
let resp = await this.getDispatchRequest(id);
let responseBody = await resp.json();
if (responseBody !== undefined && response.status !== 403) {
this.currentItem = responseBody;
}
this.currentFileIndex++;
//call this only when you create a request
//update show requests tabulator
if (this.uploadedNumberOfFiles === this.currentFileIndex && !this.addFileViaButton) {
this.newRequests = await this.getCreatedDispatchRequests();
if (this.newRequests !== null) {
this.setTabulatorData(this.newRequests);
}
} else if (this.addFileViaButton) {
// If added via "Edit request" "add Files" button
let rows = this.currentTable.getRows();
if (Array.isArray(rows) && rows.length > 0) {
this.currentTable.updateRow(rows[this.currentRowIndex], {
files: this.createFormattedFilesList(this.currentItem.files),
});
}
}
} else {
// TODO error handling
if (this.singleFileProcessing) {
send({
summary: 'Error!',
body: 'File could not be added.',
type: 'danger',
timeout: 5,
});
}
}
}
async deleteFile(event, file) {
const i18n = this._i18n;
let button = event.target;
if (confirm(i18n.t('show-requests.delete-dialog-file'))) {
button.start();
try {
let response = await this.sendDeleteFileRequest(file.identifier);
if (response.status === 204) {
send({
summary: i18n.t('show-requests.successfully-deleted-file-title'),
body: i18n.t('show-requests.successfully-deleted-file-text'),
type: 'success',
timeout: 5,
});
let id = this.currentItem.identifier;
let resp = await this.getDispatchRequest(id);
let responseBody = await resp.json();
if (responseBody !== undefined && responseBody.status !== 403) {
this.currentItem = responseBody;
let rows = this.currentTable.getRows();
this.currentTable.updateRow(rows[this.currentRowIndex], {
files: this.createFormattedFilesList(this.currentItem.files),
});
}
} else {
// TODO error handling
send({
summary: 'Error!',
body: 'File could not be deleted.',
type: 'danger',
timeout: 5,
});
}
} finally {
button.stop();
}
}
}
/**
* Open Filesink for a single File
* @param fileContentUrl
* @param fileName
*/
async downloadFileClickHandler(fileContentUrl, fileName) {
let files = [];
const arr = dispatchHelper.convertDataURIToBinary(fileContentUrl);
const binaryFile = new File([arr], fileName, {
type: dispatchHelper.getDataURIContentType(fileContentUrl),
});
files.push(binaryFile);
// this.signedFilesToDownload = files.length;
/** @type {FileSink} */ (this._('#file-sink')).files = [...files];
}
async _onDownloadFileClicked(event, statusRequestId) {
const i18n = this._i18n;
let button = event.target;
button.start();
try {
let response = await this.sendGetStatusChangeRequest(statusRequestId);
let responseBody = await response.json();
if (responseBody !== undefined && response.status === 200) {
let fileContentUrl = responseBody['fileContentUrl'];
let fileName = 'DeliveryNotification';
await this.downloadFileClickHandler(fileContentUrl, fileName);
} else {
send({
summary: 'Error',
body: i18n.t('show-requests.error-file-donwload'),
type: 'success',
timeout: 5,
});
}
} finally {
button.stop();
}
}
parseListOfRequests(response) {
let list = [];
response['hydra:member'].forEach((item) => {
list.push(item);
});
list.sort(this.compareListItems);
return list;
}
async addRecipientToRequest(button) {
const addRecipientButton = /** @type {LoadingButton} */ (this._('#add-recipient-btn'));
addRecipientButton.start();
try {
const i18n = this._i18n;
let id = this.currentItem.identifier;
let givenName = this.currentRecipient.givenName;
let familyName = this.currentRecipient.familyName;
let addressCountry = this.currentRecipient.addressCountry;
let postalCode = this.currentRecipient.postalCode;
let addressLocality = this.currentRecipient.addressLocality;
let streetAddress = this.currentRecipient.streetAddress;
let personIdentifier = this.currentRecipient.personIdentifier
? this.currentRecipient.personIdentifier
: null;
let birthDate = '';
if (
this.currentRecipient.birthDateDay &&
this.currentRecipient.birthDateMonth &&
this.currentRecipient.birthDateYear &&
this.currentRecipient.birthDateDay !== '' &&
this.currentRecipient.birthDateMonth !== '' &&
this.currentRecipient.birthDateYear !== ''
) {
birthDate =
this.currentRecipient.birthDateDay +
'.' +
this.currentRecipient.birthDateMonth +
'.' +
this.currentRecipient.birthDateYear;
}
let response = await this.sendAddRequestRecipientsRequest(
id,
personIdentifier,
givenName,
familyName,
birthDate,
addressCountry,
postalCode,
addressLocality,
streetAddress,
);
let responseBody = await response.json();
if (responseBody !== undefined && response.status === 201) {
send({
summary: i18n.t('show-requests.successfully-added-recipient-title'),
body: i18n.t('show-requests.successfully-added-recipient-text'),
type: 'success',
timeout: 5,
});
let resp = await this.getDispatchRequest(id);
let responseBody = await resp.json();
if (responseBody !== undefined && responseBody.status !== 403) {
this.currentItem = responseBody;
this.currentRecipient = {};
let rows = this.currentTable.getRows();
this.currentTable.updateRow(rows[this.currentRowIndex], {
recipients: this.createFormattedRecipientsList(this.currentItem.recipients),
});
}
this.currentRecipient.personIdentifier = '';
this.currentRecipient.givenName = '';
this.currentRecipient.familyName = '';
this.currentRecipient.postalCode = '';
this.currentRecipient.addressLocality = '';
this.currentRecipient.streetAddress = '';
this.currentRecipient.birthDateDay = '';
this.currentRecipient.birthDateMonth = '';
this.currentRecipient.birthDateYear = '';
this.currentRecipient.addressCountry = dispatchHelper.getEnglishCountryMapping();
console.log(
'addRecipientToRequest this.currentRecipient.addressCountry ' +
this.currentRecipient.addressCountry,
);
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-gn-dialog')).value =
this.currentRecipient.givenName;
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-fn-dialog')).value =
this.currentRecipient.familyName;
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-pc-dialog')).value =
this.currentRecipient.postalCode;
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-al-dialog')).value =
this.currentRecipient.addressLocality;
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-sa-dialog')).value =
this.currentRecipient.streetAddress;
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-birthdate-day')).value =
this.currentRecipient.birthDateDay;
/** @type {HTMLInputElement} */ (
this._('#tf-add-recipient-birthdate-month')
).value = this.currentRecipient.birthDateMonth;
/** @type {HTMLInputElement} */ (this._('#tf-add-recipient-birthdate-year')).value =
this.currentRecipient.birthDateYear;
/** @type {HTMLInputElement} */ (this._('#add-recipient-country-select')).value =
'AT';
this.requestUpdate();
} else {
// TODO error handling
send({
summary: 'Error!',
body: 'Could not add recipient. Response code: ' + response.status,
type: 'danger',
timeout: 5,
});
}
} catch (e) {
console.error(`${e.name}: ${e.message}`);
send({
summary: 'Error!',
body: 'Could not add recipient.',
type: 'danger',
timeout: 5,
});
} finally {
/** @type {CustomPersonSelect} */ (this._('#recipient-selector')).clear();
addRecipientButton.stop();
button.disabled = false;
}
}
async updateRecipient() {
const i18n = this._i18n;
let hasError = false;
try {
let id = this.currentItem.identifier;
let givenName = this.currentRecipient.givenName;
let familyName = this.currentRecipient.familyName;
let addressCountry = this.currentRecipient.addressCountry;
let postalCode = this.currentRecipient.postalCode;
let addressLocality = this.currentRecipient.addressLocality;
let streetAddress = this.currentRecipient.streetAddress;
let birthDate = '';
if (
this.currentRecipient.birthDateDay &&
this.currentRecipient.birthDateMonth &&
this.currentRecipient.birthDateYear &&
this.currentRecipient.birthDateDay !== '' &&
this.currentRecipient.birthDateMonth !== '' &&
this.currentRecipient.birthDateYear !== ''
) {
birthDate =
this.currentRecipient.birthDateDay +
'.' +
this.currentRecipient.birthDateMonth +
'.' +
this.currentRecipient.birthDateYear;
}
let personIdentifier = null;
// Only set personIdentifier if electronic of postal delivery is possible.
// Otherwise, allow to add address to recipient trough the edit recipient modal.
if (
this.currentRecipient.electronicallyDeliverable ||
this.currentRecipient.postalDeliverable
) {
personIdentifier = this.currentRecipient.personIdentifier;
}
let recipientId = this.currentRecipient.identifier;
// First, send a delete requests to remove the old recipient
let response = await this.sendDeleteRecipientRequest(recipientId);
if (response.status === 204) {
// Then, send a new add request to add the updated recipient
let innerResponse = await this.sendAddRequestRecipientsRequest(
id,
personIdentifier,
givenName,
familyName,
birthDate,
addressCountry,
postalCode,
addressLocality,
streetAddress,
);
let innerResponseBody = await innerResponse.json();
if (innerResponseBody !== undefined && innerResponse.status === 201) {
send({
summary: i18n.t('show-requests.successfully-edited-recipient-title'),
body: i18n.t('show-requests.successfully-edited-recipient-text'),
type: 'success',
timeout: 5,
});
this.currentRecipient = innerResponseBody;
let resp = await this.getDispatchRequest(id);
let responseBody = await resp.json();
if (responseBody !== undefined && responseBody.status !== 403) {
this.currentItem = responseBody;
this.currentRecipient = {};
let rows = this.currentTable.getRows();
this.currentTable.updateRow(rows[this.currentRowIndex], {
recipients: this.createFormattedRecipientsList(
this.currentItem.recipients,
),
});
}
this.currentRecipient.personIdentifier = '';
this.currentRecipient.givenName = '';
this.currentRecipient.familyName = '';
this.currentRecipient.postalCode = '';
this.currentRecipient.addressLocality = '';
this.currentRecipient.streetAddress = '';
this.currentRecipient.birthDateDay = '';
this.currentRecipient.birthDateMonth = '';
this.currentRecipient.birthDateYear = '';
this.currentRecipient.addressCountry =
dispatchHelper.getEnglishCountryMapping();
/** @type {HTMLInputElement} */ (this._('#tf-edit-recipient-gn-dialog')).value =
this.currentRecipient.givenName;
/** @type {HTMLInputElement} */ (this._('#tf-edit-recipient-fn-dialog')).value =
this.currentRecipient.familyName;
/** @type {HTMLInputElement} */ (this._('#tf-edit-recipient-pc-dialog')).value =
this.currentRecipient.postalCode;
/** @type {HTMLInputElement} */ (this._('#tf-edit-recipient-al-dialog')).value =
this.currentRecipient.addressLocality;
/** @type {HTMLInputElement} */ (this._('#tf-edit-recipient-sa-dialog')).value =
this.currentRecipient.streetAddress;
/** @type {HTMLInputElement} */ (
this._('#tf-edit-recipient-birthdate-day')
).value = this.currentRecipient.birthDateDay;
/** @type {HTMLInputElement} */ (
this._('#tf-edit-recipient-birthdate-month')
).value = this.currentRecipient.birthDateMonth;
/** @type {HTMLInputElement} */ (
this._('#tf-edit-recipient-birthdate-year')
).value = this.currentRecipient.birthDateYear;
/** @type {HTMLInputElement} */ (
this._('#edit-recipient-country-select')
).value = 'AT';
} else {
hasError = true;
}
} else {
hasError = true;
}
} catch (e) {
console.error(`${e.name}: ${e.message}`);
send({
summary: 'Error!',
body: 'Could not add recipient.',
type: 'danger',
timeout: 5,
});
} finally {
if (hasError) {
send({
summary: 'Error!',
body: 'Could not add recipient.',
type: 'danger',
timeout: 5,
});
}
this.requestUpdate();
}
}
async deleteRecipient(event, recipient) {
const i18n = this._i18n;
let button = event.target;
if (confirm(i18n.t('show-requests.delete-dialog-recipient'))) {
button.start();
try {
let response = await this.sendDeleteRecipientRequest(recipient.identifier);
if (response.status === 204) {
send({
summary: i18n.t('show-requests.successfully-deleted-recipient-title'),
body: i18n.t('show-requests.successfully-deleted-recipient-text'),
type: 'success',
timeout: 5,
});
let id = this.currentItem.identifier;
let resp = await this.getDispatchRequest(id);
let responseBody = await resp.json();
if (responseBody !== undefined && responseBody.status !== 403) {
this.currentItem = responseBody;
this.requestCreated = false;
let rows = this.currentTable.getRows();
this.currentTable.updateRow(rows[this.currentRowIndex], {
recipients: this.createFormattedRecipientsList(
this.currentItem.recipients,
),
});
}
} else {
send({
summary: 'Error!',
body: 'Could not delete recipient. Response code: ' + response.status,
type: 'danger',
timeout: 5,
});
}
} finally {
button.stop();
}
}
}
async fetchStatusOfRecipient(recipient) {
let response = await this.getDispatchRecipient(recipient.identifier);
let responseBody = await response.json();
if (responseBody !== undefined && response.status === 200) {
this.currentRecipient.statusType = responseBody['statusType'];
this.currentRecipient.statusDescription = responseBody['description'];
} else {
// TODO error handling
}
}
async editRequest(event, item, index = 0) {
let button = event.target;
button.start();
try {
let resp = await this.getDispatchRequest(item.identifier);
let responseBody = await resp.json();
if (responseBody !== undefined && responseBody.status !== 403) {
this.currentItem = responseBody;
}
this.currentItem.recipients.forEach((element) => {
this.fetchDetailedRecipientInformation(element.identifier).then((result) => {
//TODO
});
});
await this.loadLastModifiedName(this.currentItem.personIdentifier);
this.showListView = false;
this.showDetailsView = true;
this.expanded = false;
} finally {
button.stop();
}
}
async deleteRequest(table, event, item, index = 0) {
const i18n = this._i18n;
let button = event.target;
if (item.dateSubmitted) {
send({
summary: i18n.t('show-requests.delete-not-allowed-title'),
body: i18n.t('show-requests.delete-not-allowed-text'),
type: 'danger',
timeout: 5,
});
return;
}
if (confirm(i18n.t('show-requests.delete-dialog-text', {count: 1}))) {
button.start();
try {
let response = await this.sendDeleteDispatchRequest(item.identifier);
if (response.status === 204) {
send({
summary: i18n.t('show-requests.successfully-deleted-title'),
body: i18n.t('show-requests.successfully-deleted-text'),
type: 'success',
timeout: 5,
});
let rows = table.getRows();
table.deleteRow(rows[index]);
this.clearAll();
} else {
send({
summary: 'Error!',
body: 'Could not delete request. Response code: ' + response.status,
type: 'danger',
timeout: 5,
});
}
} catch (e) {
console.error(`${e.name}: ${e.message}`);
} finally {
button.stop();
}
}
}
/**
* Returns if the request can be submitted or not. And if not, it shows a UI message.
* @param {object} request
* @returns {boolean} if the request can be submitted or not
*/
checkCanSubmit(request) {
const i18n = this._i18n;
// No files attached
if (!request.files || request.files.length === 0) {
send({
summary: i18n.t('show-requests.missing-files.title'),
body: i18n.t('show-requests.missing-files.text'),
type: 'danger',
timeout: 5,
});
return false;
}
// No recipients
// if (!recipients || recipients.length === 0 || recipients === i18n.t('show-requests.no-recipients-added')) {
if (!request.recipients || request.recipients.length === 0) {
send({
summary: i18n.t('show-requests.missing-recipients.title'),
body: i18n.t('show-requests.missing-recipients.text'),
type: 'danger',
timeout: 5,
});
return false;
}
// Missing or empty referenceNumber
if (!request.referenceNumber || !request.referenceNumber.trim()) {
send({
summary: i18n.t('show-requests.missing-reference-number.title'),
body: i18n.t('show-requests.missing-reference-number.text'),
type: 'danger',
timeout: 5,
});
return false;
}
// Missing or empty subject
if (!request.name || !request.name.trim()) {
send({
summary: i18n.t('show-requests.missing-subject.title'),
body: i18n.t('show-requests.missing-subject.text'),
type: 'danger',
timeout: 5,
});
return false;
}
return true;
}
async submitRequest(table, event, item, index = 0) {
const i18n = this._i18n;
let button = event.target;
if (item.dateSubmitted) {
send({
summary: i18n.t('show-requests.submit-not-allowed-title'),
body: i18n.t('show-requests.submit-not-allowed-text'),
type: 'danger',
timeout: 5,
});
return;
}
let rows = table.getRows();
let row = rows[index];
if (!this.checkCanSubmit(this.currentItem)) {
return;
}
if (confirm(i18n.t('show-requests.submit-dialog-text', {count: 1}))) {
try {
button.start();
let response = await this.sendSubmitDispatchRequest(item.identifier);
if (response.status === 201) {
let responseBody = await response.json();
let Recipientstatus = i18n.t('show-requests.pending');
let submitted = this.convertToReadableDate(responseBody['dateSubmitted']);
let controls_div = this.createScopedElement('div');
let btn_research = this.createScopedElement('dbp-icon-button');
btn_research.setAttribute('icon-name', 'keyword-research');
btn_research.addEventListener('click', async (event) => {
this.editRequest(event, item, index);
event.stopPropagation();
});
controls_div.appendChild(btn_research);
table.up