Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to preview files in Lightning Community using LWC
<!--
@description :
@author : Amit Singh
@group :
@last modified on : 12-02-2020
@last modified by : Amit Singh
Modifications Log
Ver Date Author Modification
1.0 11-26-2020 Amit Singh Initial Version
-->
<template>
<lightning-card variant="Narrow" title={title} icon-name="standard:document">
<template if:true={isLoading}>
<lightning-spinner alternative-text="Loading" size="small" variant="brand"></lightning-spinner>
</template>
<lightning-button if:true={showsync} variant="brand" title="Content Sync" icon-name="utility:sync"
onclick={handleSync} slot="actions" >
</lightning-button>
<div class="slds-var-p-around_small" >
<div class="slds-grid slds-wrap">
<div class="slds-col slds-size_1-of-4" if:true={showFilters}>
<lightning-input if:true={showFilters} type="search" variant="standard" name="Title" label="Title" onchange={handleSearch} >
</lightning-input>
</div>
<div class="slds-col slds-size_1-of-4" if:true={showFilters}>
<lightning-input if:true={showFilters} type="search" variant="standard" name="Created By" label="Created By" onchange={handleSearch}>\
</lightning-input>
</div>
<div class="slds-col slds-size_2-of-4 slds-var-p-left_small">
<lightning-file-upload if:true={showFileUpload}
label="Upload New File"
name="fileUploader"
accept={accept}
record-id={recordId}
onuploadfinished={handleUploadFinished}
multiple>
</lightning-file-upload>
</div>
</div>
</div>
<div class="slds-var-p-around_small">
<lightning-datatable
key-field="id"
data={dataList}
hide-checkbox-column
columns={columnsList}
onrowaction={handleRowAction}>
</lightning-datatable>
</div>
</lightning-card>
</template>
import { api, LightningElement, track, wire } from 'lwc';
import getContentDetails from '@salesforce/apex/ContentManagerService.getContentDetails';
import deleteContentDocument from '@salesforce/apex/ContentManagerService.deleteContentDocument';
import { NavigationMixin } from 'lightning/navigation';
const columns = [
{ label: 'Title', fieldName: 'Title', wrapText : true,
cellAttributes: {
iconName: { fieldName: 'icon' }, iconPosition: 'left'
}
},
{ label: 'Created By', fieldName: 'CREATED_BY',
cellAttributes: {
iconName: 'standard:user', iconPosition: 'left'
}
},
{ label: 'File Size', fieldName: 'Size' },
{ label: 'Preview', type: 'button', typeAttributes: {
label: 'Preview', name: 'Preview', variant: 'brand-outline',
iconName: 'utility:preview', iconPosition: 'right'
}
},
{ label: 'Download', type: 'button', typeAttributes: {
label: 'Download', name: 'Download', variant: 'brand', iconName: 'action:download',
iconPosition: 'right'
}
},
{ label: 'Delete', type: 'button', typeAttributes: {
label: 'Delete', name: 'Delete', variant: 'destructive',iconName: 'standard:record_delete',
iconPosition: 'right'
}
}
];
export default class ContentManager extends NavigationMixin(LightningElement) {
@api title;
@api showDetails;
@api showFileUpload;
@api showsync;
@api recordId;
@api usedInCommunity;
@api showFilters;
@api accept = '.csv,.doc,.xsl,.pdf,.png,.jpg,.jpeg,.docx,.doc';
@track dataList;
@track columnsList = columns;
isLoading = false;
wiredFilesResult;
connectedCallback() {
this.handleSync();
}
getBaseUrl(){
let baseUrl = 'https://'+location.host+'/';
return baseUrl;
}
handleRowAction(event){
const actionName = event.detail.action.name;
const row = event.detail.row;
switch (actionName) {
case 'Preview':
this.previewFile(row);
break;
case 'Download':
this.downloadFile(row);
break;
case 'Delete':
this.handleDeleteFiles(row);
break;
default:
}
}
previewFile(file){
if(!this.usedInCommunity){
this[NavigationMixin.Navigate]({
type: 'standard__namedPage',
attributes: {
pageName: 'filePreview'
},
state : {
selectedRecordId: file.ContentDocumentId
}
});
} else if(this.usedInCommunity){
this[NavigationMixin.Navigate]({
type: 'standard__webPage',
attributes: {
url: file.fileUrl
}
}, false );
}
}
downloadFile(file){
this[NavigationMixin.Navigate]({
type: 'standard__webPage',
attributes: {
url: file.downloadUrl
}
}, false
);
}
handleDeleteFiles(row){
this.isLoading = true;
deleteContentDocument({
recordId : row.ContentDocumentId
})
.then(result => {
this.dataList = this.dataList.filter(item => {
return item.ContentDocumentId !== row.ContentDocumentId ;
});
})
.catch(error => {
console.error('**** error **** \n ',error)
})
.finally(()=>{
this.isLoading = false;
});
}
handleSync(){
let imageExtensions = ['png','jpg','gif'];
let supportedIconExtensions = ['ai','attachment','audio','box_notes','csv','eps','excel','exe',
'flash','folder','gdoc','gdocs','gform','gpres','gsheet','html','image','keynote','library_folder',
'link','mp4','overlay','pack','pages','pdf','ppt','psd','quip_doc','quip_sheet','quip_slide',
'rtf','slide','stypi','txt','unknown','video','visio','webex','word','xml','zip'];
this.isLoading = true;
getContentDetails({
recordId : this.recordId
})
.then(result => {
let parsedData = JSON.parse(result);
let stringifiedData = JSON.stringify(parsedData);
let finalData = JSON.parse(stringifiedData);
let baseUrl = this.getBaseUrl();
finalData.forEach(file => {
file.downloadUrl = baseUrl+'sfc/servlet.shepherd/document/download/'+file.ContentDocumentId;
file.fileUrl = baseUrl+'sfc/servlet.shepherd/version/renditionDownload?rendition=THUMB720BY480&versionId='+file.Id;
file.CREATED_BY = file.ContentDocument.CreatedBy.Name;
file.Size = this.formatBytes(file.ContentDocument.ContentSize, 2);
let fileType = file.ContentDocument.FileType.toLowerCase();
if(imageExtensions.includes(fileType)){
file.icon = 'doctype:image';
}else{
if(supportedIconExtensions.includes(fileType)){
file.icon = 'doctype:' + fileType;
}
}
});
this.dataList = finalData;
})
.catch(error => {
console.error('**** error **** \n ',error)
})
.finally(()=>{
this.isLoading = false;
});
}
handleUploadFinished(){
this.handleSync();
//eval("$A.get('e.force:refreshView').fire();");
}
formatBytes(bytes,decimals) {
if(bytes == 0) return '0 Bytes';
var k = 1024,
dm = decimals || 2,
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
handleSearch(event){
let value = event.target.value;
let name = event.target.name;
if( name === 'Title' ){
this.dataList = this.dataList.filter( file => {
return file.Title.toLowerCase().includes(value.toLowerCase());
});
} else if( name === 'Created By' ){
this.dataList = this.dataList.filter( file => {
return file.CREATED_BY.toLowerCase().includes(value.toLowerCase());
});
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>50.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>Content Manager</masterLabel>
<targets>
<target>lightning__RecordPage</target>
<target>lightning__UtilityBar</target>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
<!-- Configuring the design attributes -->
<targetConfigs>
<targetConfig targets="lightning__RecordPage, lightningCommunity__Default">
<property name="title" type="String" label="Title" default="Content Manager" required="true"/>
<property name="recordId" type="String" default="recordId" label="Record Id" required="true"/>
<property name="showDetails" type="Boolean" default="true" label="Do you want to Show Details ?"/>
<property name="accept" type="String" default=".csv,.doc,.xsl,.pdf,.png,.jpg,.jpeg,.docx,.doc"
label="User can upload the files in format?" />
<property name="showsync" type="Boolean" default="true" label="User can sync the files from Salesforce?" />
<property name="showFileUpload" type="Boolean" default="true" label="Do you want the users to upload a new file ?"/>
<property name="usedInCommunity" type="Boolean" default="false" label="Component is used in Community?" />
<property name="showFilters" type="Boolean" default="true" label="Show Filters?" />
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
/**
* @description :
* @author : Amit Singh
* @group :
* @last modified on : 12-02-2020
* @last modified by : Amit Singh
* Modifications Log
* Ver Date Author Modification
* 1.0 11-26-2020 Amit Singh Initial Version
**/
public with sharing class ContentManagerService {
@AuraEnabled
public static String getContentDetails(String recordId) {
List<ContentDocumentLink> contentDocumentList = [SELECT ContentDocumentId, LinkedEntityId
FROM ContentDocumentLink
WHERE LinkedEntityId =: recordId];
Set<Id> contentDocumentId = new Set<Id>();
for(ContentDocumentLink cdl : contentDocumentList){
contentDocumentId.add(cdl.ContentDocumentId);
}
List<ContentVersion> contentVersionList = [SELECT Id, VersionData, FileType, Title, FileExtension,
ContentDocument.CreatedBy.Name, ContentDocument.ContentSize,
CreatedDate, ContentDocumentId, ContentDocument.FileType
FROM ContentVersion
WHERE ContentDocumentId IN : contentDocumentId];
return JSON.serialize(contentVersionList);
}
@AuraEnabled
public static void deleteContentDocument(String recordId) {
Database.delete(recordId);
}
public static string ContentType(String fileType) {
switch on fileType.toLowerCase(){
when 'docx' {
return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
}
when 'csv' {
return 'application/vnd.ms-excel';
}
when 'wav' {
return 'audio/wav';
}
when 'wmv' {
return 'video/x-ms-wmv';
}
when 'mp3' {
return 'audio/mpeg';
}
when 'mp4' {
return 'video/mp4';
}
when 'png' {
return 'image/png';
}
when 'pdf' {
return 'application/pdf';
}
when else {
return 'image/jpeg';
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment