UNPKG

sp-attachment-library

Version:

This is library is used ro do attachments realted actions on a list item in Sharepoint Angular SPA Addins.

876 lines (865 loc) 31.8 kB
import { sp } from '@pnp/sp'; import { __awaiter } from 'tslib'; import * as fa from '@fortawesome/free-solid-svg-icons'; import Swal from 'sweetalert2'; import { InjectionToken, Injectable, Inject, NgModule, Component, Input, defineInjectable, inject } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { SweetAlert2Module } from '@sweetalert2/ngx-sweetalert2'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const SpAttachmentConfigService = new InjectionToken('TestLibConfig'); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class SpAttachmentLibraryService { /** * @param {?} config */ constructor(config) { this.config = config; // setup sp sp.setup({ sp: { headers: { 'Accept': 'application/json;odata=verbose', }, baseUrl: this.config.baseUrl, } }); } /** * @param {?} listName * @param {?} itemId * @return {?} */ getAttachmentsById(listName, itemId) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items .getById(itemId); item.attachmentFiles .get() .then((/** * @param {?} response * @return {?} */ (response) => { resolve({ result: response }); })) .catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } /** * @param {?} listName * @param {?} itemId * @param {?} attachment * @return {?} */ addAttachment(listName, itemId, attachment) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items.getById(itemId); item.attachmentFiles.add(attachment.name, attachment.content).then((/** * @param {?} response * @return {?} */ response => { resolve({ result: response }); })).catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } /** * @param {?} listName * @param {?} itemId * @param {?} attachments * @return {?} */ addAttachments(listName, itemId, attachments) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items.getById(itemId); item.attachmentFiles.addMultiple(attachments).then((/** * @param {?} response * @return {?} */ response => { resolve({ result: response }); })).catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } /** * @param {?} listName * @param {?} itemId * @param {?} fileName * @return {?} */ deleteAttachment(listName, itemId, fileName) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items.getById(itemId); item.attachmentFiles.getByName(fileName).delete().then((/** * @param {?} response * @return {?} */ response => { resolve({ result: response }); })).catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } /** * @param {?} listName * @param {?} itemId * @param {?} fileNames * @return {?} */ deleteAttachments(listName, itemId, fileNames) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items.getById(itemId); item.attachmentFiles.deleteMultiple(...fileNames).then((/** * @param {?} response * @return {?} */ response => { resolve({ result: response }); })).catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } /** * @param {?} listName * @param {?} itemId * @param {?} fileName * @return {?} */ getAttachmentContent(listName, itemId, fileName) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items.getById(itemId); item.attachmentFiles.getByName(fileName).getBlob().then((/** * @param {?} response * @return {?} */ response => { resolve({ result: response }); })).catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } /** * @param {?} listName * @param {?} itemId * @param {?} fileName * @param {?} content * @return {?} */ updateAttachmentContent(listName, itemId, fileName, content) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const item = sp.web .lists .getByTitle(listName) .items.getById(itemId); item.attachmentFiles.getByName(fileName).setContent(content).then((/** * @param {?} response * @return {?} */ response => { resolve({ result: response }); })).catch((/** * @param {?} e * @return {?} */ (e) => { reject({ result: false, message: e.message }); })); })); } } SpAttachmentLibraryService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ SpAttachmentLibraryService.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [SpAttachmentConfigService,] }] } ]; /** @nocollapse */ SpAttachmentLibraryService.ngInjectableDef = defineInjectable({ factory: function SpAttachmentLibraryService_Factory() { return new SpAttachmentLibraryService(inject(SpAttachmentConfigService)); }, token: SpAttachmentLibraryService, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const blobUtil = require('blob-util'); /** @type {?} */ const fileToBlob = (/** * @param {?} file * @return {?} */ file => { /** @type {?} */ const dataUrl = file.content; return blobUtil.dataURLToBlob(dataUrl); }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class SpAttachmentLibraryComponent { /** * @param {?} spAttachmentLibraryService */ constructor(spAttachmentLibraryService) { this.spAttachmentLibraryService = spAttachmentLibraryService; this.attachments = []; this.unUpLoadedItems = 0; this.fa = fa; this.deleteSwalOptions = { title: 'Do you really want to delete this attachment?', type: 'warning', confirmButtonText: 'Yes, delete it!', cancelButtonText: 'No, keep it', showCancelButton: 'true', customClass: { confirmButton: 'btn btn-success', cancelButton: 'btn btn-danger ml-sm-2' } }; this.deleteAllSwalOptions = { title: 'Do you really want to delete all selected attachments?', message: 'All selected attachments added to this list item will be deleted.', type: 'warning', confirmButtonText: 'Yes, delete it!', cancelButtonText: 'No, keep it', showCancelButton: 'true', customClass: { confirmButton: 'btn btn-danger', cancelButton: 'btn btn-success ml-sm-2' } }; } /** * @param {?} listName * @return {?} */ set listName(listName) { this._listName = listName; } /** * @param {?} itemId * @return {?} */ set itemId(itemId) { this._itemId = itemId; } /** * @return {?} */ ngOnInit() { if (this._listName && this._itemId) { this.loadExistingFiles(); } } /** * @return {?} */ loadExistingFiles() { /** @type {?} */ const unuploaded = this.attachments.filter((/** * @param {?} x * @return {?} */ x => !x.isSelected && x.serverRelativeUrl === null)); this.spAttachmentLibraryService.getAttachmentsById(this._listName, this._itemId).then((/** * @param {?} data * @return {?} */ (data) => { this.attachments = []; data.result.forEach((/** * @param {?} element * @return {?} */ element => { this.attachments.push({ fileName: element.FileName, content: null, extension: element.FileName.substring(element.FileName.lastIndexOf('.') + 1), serverRelativeUrl: element.ServerRelativeUrl, isUploaded: false, isContentChanged: false, isLoading: false, isSelected: false, }); })); this.attachments.push(...unuploaded); })); } /** * @param {?} event * @return {?} */ onAttachmentAdded(event) { for (const file of event.target.files) { if (this.attachments.findIndex((/** * @param {?} x * @return {?} */ x => x.fileName === file.name)) < 0) { this.getBase64(file) .then((/** * @param {?} response * @return {?} */ (response) => { this.attachments.push({ fileName: (/** @type {?} */ (file.name)), content: (/** @type {?} */ (response)), extension: file.name.substring(file.name.lastIndexOf('.') + 1), serverRelativeUrl: null, isUploaded: false, isContentChanged: false, isLoading: false, isSelected: false, }); })); } else { this.promptReplace(file); } } } /** * @param {?} file * @return {?} */ promptReplace(file) { /** @type {?} */ const replaceContentSwal = Swal.mixin({ customClass: { confirmButton: 'btn btn-success', cancelButton: 'btn btn-danger ml-sm-2' }, buttonsStyling: false, }); replaceContentSwal.fire({ title: 'File already exists. Do you want to replace it?', text: 'The file content will be replaced', type: 'warning', showCancelButton: true, confirmButtonText: 'Yes, replace it!', cancelButtonText: 'No, keep it' }).then((/** * @param {?} result * @return {?} */ (result) => { if (result.value) { this.getBase64(file) .then((/** * @param {?} response * @return {?} */ (response) => { /** @type {?} */ const exitingFileIndex = this.attachments.findIndex((/** * @param {?} x * @return {?} */ x => x.fileName === file.name)); /** @type {?} */ const existingItem = this.attachments.find((/** * @param {?} x * @return {?} */ x => x.fileName === file.name)); existingItem.content = (/** @type {?} */ (response)); existingItem.extension = file.name.substring(file.name.lastIndexOf('.') + 1); existingItem.isContentChanged = true; existingItem.isUploaded = false; this.attachments.splice(exitingFileIndex, 1, existingItem); })); } else if (result.dismiss === Swal.DismissReason.cancel) { Swal.fire('Cancelled'); } })); } /** * @param {?} event * @return {?} */ resetFiles(event) { event.target.value = null; } /** * @param {?} file * @return {?} */ removeAttachment(file) { file.isLoading = true; if (!file.serverRelativeUrl) { /** @type {?} */ const index = this.attachments.findIndex((/** * @param {?} x * @return {?} */ x => x.fileName === file.fileName)); file.isLoading = false; this.attachments.splice(index, 1); } else { file.isLoading = true; this.spAttachmentLibraryService.deleteAttachment(this._listName, this._itemId, file.fileName).then((/** * @param {?} data * @return {?} */ (data) => { /** @type {?} */ const index = this.attachments.findIndex((/** * @param {?} x * @return {?} */ x => x.fileName === file.fileName)); file.isLoading = false; this.attachments.splice(index, 1); })).catch((/** * @param {?} error * @return {?} */ (error) => { console.log(error); })); } } /** * @param {?} file * @return {?} */ uploadAttachment(file) { file.isLoading = true; this._selectedUploadAttachment = { content: fileToBlob(file), name: file.fileName }; this.spAttachmentLibraryService.addAttachment(this._listName, this._itemId, this._selectedUploadAttachment).then((/** * @param {?} data * @return {?} */ (data) => { file.isLoading = false; /** @type {?} */ const fileIndex = this.attachments.findIndex((/** * @param {?} x * @return {?} */ x => x.fileName === file.fileName)); this.attachments[fileIndex].serverRelativeUrl = data.result.data.ServerRelativeUrl; this.attachments[fileIndex].isContentChanged = false; })).catch((/** * @param {?} error * @return {?} */ (error) => { console.log(error); })); } /** * @return {?} */ hasNewUnUploadedAndSelcted() { return this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.serverRelativeUrl === null && x.isSelected)).length > 0; } /** * @return {?} */ getUnUploadedCount() { return this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.serverRelativeUrl === null && x.isSelected)).length; } /** * @return {?} */ hasSelected() { return this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.isSelected)).length > 0; } /** * @return {?} */ allSelected() { return this.attachments.every((/** * @param {?} x * @return {?} */ x => x.isSelected)); } /** * @return {?} */ getSelectedCount() { return this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.isSelected)).length; } /** * @return {?} */ markOrUnMarkAll() { this.attachments.forEach((/** * @param {?} e * @return {?} */ e => { e.isSelected = e.isSelected ? false : true; })); } /** * @return {?} */ uploadNewAttachments() { /** @type {?} */ const newAttachments = Array(); /** @type {?} */ const newlyAddedAttachments = this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.serverRelativeUrl === null && x.isSelected)); newlyAddedAttachments.forEach((/** * @param {?} x * @return {?} */ x => { x.isLoading = true; })); /** @type {?} */ const promises = []; for (const attachment of newlyAddedAttachments) { promises.push(fileToBlob(attachment)); } Promise.all(promises).then((/** * @param {?} attachmentBlobs * @return {?} */ attachmentBlobs => { attachmentBlobs.forEach((/** * @param {?} blob * @param {?} index * @return {?} */ (blob, index) => __awaiter(this, void 0, void 0, function* () { yield newAttachments.push({ name: (newlyAddedAttachments[index].fileName), content: blob }); }))); this.spAttachmentLibraryService.addAttachments(this._listName, this._itemId, newAttachments).then((/** * @param {?} data * @return {?} */ (data) => { this.loadExistingFiles(); })).catch((/** * @param {?} error * @return {?} */ (error) => { console.log(error); })); })).catch((/** * @param {?} error * @return {?} */ (error) => { console.log(error); })); } /** * @param {?} file * @return {?} */ replaceAttachment(file) { file.isLoading = true; this.spAttachmentLibraryService.deleteAttachment(this._listName, this._itemId, file.fileName).then((/** * @param {?} data * @return {?} */ (data) => { file.isLoading = false; this.uploadAttachment(file); })).catch((/** * @param {?} error * @return {?} */ (error) => { console.log(error); })); } /** * @return {?} */ deleteSelected() { /** @type {?} */ const selectedLocalAttachments = this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.isSelected && x.serverRelativeUrl === null)); this.attachments.forEach((/** * @param {?} e * @return {?} */ e => { e.isLoading = e.isSelected ? true : false; })); selectedLocalAttachments.forEach((/** * @param {?} e * @return {?} */ e => { /** @type {?} */ const index = this.attachments.findIndex((/** * @param {?} a * @return {?} */ a => a.fileName === e.fileName)); this.attachments.splice(index, 1); })); /** @type {?} */ const serverFiles = this.attachments.filter((/** * @param {?} x * @return {?} */ x => x.serverRelativeUrl !== null && x.isSelected)); this.attachments.forEach((/** * @param {?} e * @return {?} */ e => { e.isLoading = e.isSelected ? true : false; })); /** @type {?} */ const fileNames = serverFiles.map((/** * @param {?} x * @return {?} */ x => x.fileName)); this.spAttachmentLibraryService.deleteAttachments(this._listName, this._itemId, fileNames).then((/** * @param {?} data * @return {?} */ (data) => { this.loadExistingFiles(); })).catch((/** * @param {?} error * @return {?} */ (error) => { console.log(error); })); } /** * @param {?} file * @return {?} */ getBase64(file) { return new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { /** @type {?} */ const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (/** * @return {?} */ () => resolve(reader.result)); reader.onerror = (/** * @param {?} error * @return {?} */ error => reject(error)); })); } } SpAttachmentLibraryComponent.decorators = [ { type: Component, args: [{ selector: 'sp-attachment', template: "<div class=\"container\">\r\n <h4>Attachments</h4>\r\n <div class=\"row\">\r\n <div class=\"col-md-12\">\r\n <div class=\"form-group\">\r\n <label class=\"control-label\">Attachments</label>\r\n <input type=\"file\" multiple size=\"50\" class=\"custom-file-input\" id=\"customFile\" name=\"filename\"\r\n base-sixty-four-input (click)=\"resetFiles($event)\" (input)=\"onAttachmentAdded($event)\">\r\n <label class=\"custom-file-label\" for=\"customFile\">choose your attachments</label>\r\n <ul class=\"list-group\">\r\n <li class=\"list-group-item\">\r\n <div class=\"row\">\r\n <div class=\"col-md-8 pull-left\">Files</div>\r\n <div class=\"col-md-4 pull-right\">Actions</div>\r\n </div>\r\n </li>\r\n </ul>\r\n <ul class=\"list-group\" *ngFor=\"let attachment of attachments\">\r\n <li *ngIf=\"!attachment.isLoading\" class=\"list-group-item\">\r\n <div class=\"row\">\r\n <div class=\"col-md-8 pull-left\">\r\n <div class=\"form-check\">\r\n <input type=\"checkbox\" [(ngModel)]=\"attachment.isSelected\" class=\"form-check-input\" id=\"{{ attachment.fileName }}\">\r\n </div>\r\n <a class=\"ml-sm-3\" href=\"{{ attachment.serverRelativeUrl }}\" target=\"_blank\">\r\n {{attachment.fileName}}\r\n </a>\r\n </div>\r\n <div class=\"col-md-4 pull-right\">\r\n <button class=\"btn btn-danger btn-xs\" [swal]=\"deleteSwalOptions\"\r\n (confirm)=\"removeAttachment(attachment)\">\r\n <fa-icon [icon]=\"fa.faTrash\"></fa-icon>\r\n </button>\r\n <button *ngIf=\"!attachment.serverRelativeUrl\" class=\"btn btn-primary btn-xs ml-sm-2\"\r\n (click)=\"uploadAttachment(attachment)\">\r\n <fa-icon [icon]=\"fa.faUpload\"></fa-icon>\r\n </button>\r\n <button *ngIf=\"attachment.isContentChanged\" class=\"btn btn-primary btn-xs ml-sm-2\"\r\n (click)=\"replaceAttachment(attachment)\">\r\n <fa-icon [icon]=\"fa.faEdit\"></fa-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n <li *ngIf=\"attachment.isLoading\" class=\"list-group-item animated-background\">\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-md-12\" *ngIf=\"attachments.length > 0\">\r\n <button type=\"button\" class=\"btn btn-info btn-sm ml-sm-2\"\r\n (click)=\"markOrUnMarkAll()\">\r\n {{ allSelected() ? 'Unmark All' : 'Mark All'}}\r\n </button>\r\n <button *ngIf=\"hasNewUnUploadedAndSelcted()\" type=\"button\" class=\"btn btn-success btn-sm ml-sm-2\"\r\n (click)=\"uploadNewAttachments()\">\r\n Upload Selected({{ getUnUploadedCount() }})\r\n </button>\r\n <button *ngIf=\"hasSelected()\" type=\"button\" class=\"btn btn-danger btn-sm ml-sm-2\" [swal]=\"deleteAllSwalOptions\"\r\n (confirm)=\"deleteSelected()\">Delete Selected({{ getSelectedCount() }})\r\n </button>\r\n </div>\r\n </div>\r\n</div>", styles: [".btn-group-xs>.btn,.btn-xs{padding:.25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.loader-container{margin:0 auto;width:400px;max-width:90%;display:flex;flex-direction:column;justify-content:center;align-items:center}@-webkit-keyframes placeholder{0%{background-position:-600px 0}100%{background-position:600px 0}}@keyframes placeholder{0%{background-position:-600px 0}100%{background-position:600px 0}}.animated-background{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:placeholder;animation-name:placeholder;-webkit-animation-timing-function:linear;animation-timing-function:linear;background:#eee;background:linear-gradient(to right,#eee 8%,#ddd 18%,#eee 33%);background-size:1200px 100px;min-height:30px;width:100%;margin:5px 0;border-radius:3px}"] }] } ]; /** @nocollapse */ SpAttachmentLibraryComponent.ctorParameters = () => [ { type: SpAttachmentLibraryService } ]; SpAttachmentLibraryComponent.propDecorators = { listName: [{ type: Input }], itemId: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class SpAttachmentLibraryModule { /** * @param {?} config * @return {?} */ static forRoot(config) { return { ngModule: SpAttachmentLibraryModule, providers: [ SpAttachmentLibraryService, { provide: SpAttachmentConfigService, useValue: config } ] }; } } SpAttachmentLibraryModule.decorators = [ { type: NgModule, args: [{ declarations: [SpAttachmentLibraryComponent], imports: [ BrowserModule, FormsModule, SweetAlert2Module.forRoot({ buttonsStyling: false, customClass: 'modal-content', confirmButtonClass: 'btn btn-primary', cancelButtonClass: 'btn' }), FontAwesomeModule, ], exports: [SpAttachmentLibraryComponent] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { SpAttachmentLibraryService, SpAttachmentLibraryComponent, SpAttachmentLibraryModule, SpAttachmentConfigService, SpAttachmentConfigService as ɵa }; //# sourceMappingURL=sp-attachment-library.js.map