Skip to content

Commit 1d9753c

Browse files
committed
#177 - Merge + code refactoring
1 parent 7c37240 commit 1d9753c

File tree

16 files changed

+321
-211
lines changed

16 files changed

+321
-211
lines changed

docs/documentation/docs/controls/ListItemAttachments.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
# List-Item-Attachments control
1+
# ListItemAttachments control
22

3-
This control allows you to manage list item attachments, you can add or delete associated attachments, the attachments are listed in tile view.
4-
3+
This control allows you to manage list item attachments, you can add or delete associated attachments. The attachments are listed in tile view.
54

65
Here is an example of the control:
76

@@ -19,7 +18,6 @@ Here is an example of the control:
1918
- Import the control into your component:
2019

2120
```TypeScript
22-
2321
import { ListItemAttachments } from '@pnp/spfx-controls-react/listItemAttachments';
2422
```
2523
- Use the `ListItemAttachments` control in your code as follows:

docs/documentation/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ nav:
1313
- "Radar Chart": 'controls/charts/RadarChart.md'
1414
- "Scatter Chart": 'controls/charts/ScatterChart.md'
1515
- FileTypeIcon: 'controls/FileTypeIcon.md'
16+
- ListItemAttachments: 'controls/ListItemAttachments.md'
1617
- ListItemPicker: 'controls/ListItemPicker.md'
1718
- ListPicker: 'controls/ListPicker.md'
1819
- ListView: 'controls/ListView.md'
Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
11

22
.ListItemAttachments {
3+
margin-bottom: 15px;
4+
35
.documentCard {
46
-webkit-font-smoothing: antialiased;
57
background-color: #ffffff;
68
border: 1px solid #eaeaea;
7-
-webkit-box-sizing: border-box;
89
box-sizing: border-box;
910
max-width: 320px;
1011
min-width: 187px;
11-
-webkit-user-select: none;
12-
-moz-user-select: none;
13-
-ms-user-select: none;
1412
user-select: none;
1513
position: relative;
1614
}
15+
1716
.documentCardWrapper {
18-
margin-top: 15px;
19-
min-Width: 187px;
20-
width: 187px;
21-
display: inline-block;
22-
margin-Left: 12px
17+
margin-top: 15px;
18+
min-Width: 187px;
19+
width: 187px;
20+
display: inline-block;
21+
margin-left: 12px
2322
}
2423

2524
.fileLabel {
26-
margin-Left: 12px;
27-
margin-Right: 12px;
28-
overflow: 'hidden';
29-
white-Space: 'nowrap';
30-
text-overflow: 'ellipsis';
31-
}
25+
margin-left: 12px;
26+
margin-right: 12px;
27+
overflow: 'hidden';
28+
white-space: 'nowrap';
29+
text-overflow: 'ellipsis';
30+
}
31+
3232
.uploadfile {
33-
background-color:transparent !important;
33+
background-color: transparent !important;
3434
font-size: 15px;
35-
}
35+
}
3636
}
3737

38+
.uploadBar {
39+
margin-top: 15px;
40+
text-align: left;
41+
}
3842

3943

src/controls/listItemAttachments/ListItemAttachments.tsx

Lines changed: 93 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
import * as React from 'react';
33
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
44
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
5-
import { Icon, IconType } from 'office-ui-fabric-react/lib/Icon';
65
import { Label } from "office-ui-fabric-react/lib/Label";
7-
import { Link } from 'office-ui-fabric-react/lib/Link';
86
import * as strings from 'ControlStrings';
97
import styles from './ListItemAttachments.module.scss';
108
import { UploadAttachment } from './UploadAttachment';
@@ -13,7 +11,6 @@ import {
1311
DocumentCard,
1412
DocumentCardActions,
1513
DocumentCardPreview,
16-
DocumentCardTitle,
1714
IDocumentCardPreviewImage
1815
} from 'office-ui-fabric-react/lib/DocumentCard';
1916
import { ImageFit } from 'office-ui-fabric-react/lib/Image';
@@ -43,65 +40,132 @@ export class ListItemAttachments extends React.Component<IListItemAttachmentsPro
4340
showPlaceHolder: false,
4441
fireUpload: false
4542
};
43+
4644
// Get SPService Factory
4745
this._spservice = new SPservice(this.props.context);
4846
this._utilities = new utilities();
47+
}
4948

50-
// registo de event handlers
51-
this._onDeleteAttachment = this._onDeleteAttachment.bind(this);
52-
this._closeDialog = this._closeDialog.bind(this);
53-
this._onAttachmentpload = this._onAttachmentpload.bind(this);
54-
this._onConfirmedDeleteAttachment = this._onConfirmedDeleteAttachment.bind(this);
49+
/**
50+
* componentDidMount lifecycle hook
51+
*/
52+
public componentDidMount() {
53+
this.loadAttachments();
5554
}
56-
// Load Item Attachments
57-
private async _loadAttachments() {
55+
56+
/**
57+
* Load Item Attachments
58+
*/
59+
private async loadAttachments() {
5860
this.previewImages = [];
5961
try {
6062
const files: IListItemAttachmentFile[] = await this._spservice.getListItemAttachments(this.props.listId, this.props.itemId);
61-
for (const _file of files) {
6263

63-
const _previewImage = await this._utilities.GetFileImageUrl(_file);
64+
for (const file of files) {
65+
const _previewImage = await this._utilities.GetFileImageUrl(file);
6466
this.previewImages.push({
65-
name: _file.FileName,
67+
name: file.FileName,
6668
previewImageSrc: _previewImage,
6769
iconSrc: '',
6870
imageFit: ImageFit.center,
6971
width: 187,
7072
height: 130,
7173
});
7274
}
75+
7376
this.setState({
7477
hideDialog: true,
7578
dialogMessage: '',
7679
attachments: files,
7780
showPlaceHolder: files.length === 0 ? true : false
78-
7981
});
80-
}
81-
catch (error) {
82+
} catch (error) {
8283
this.setState({
8384
hideDialog: true,
8485
dialogMessage: strings.ListItemAttachmentserrorLoadAttachments.replace('{0}', error.message)
8586
});
8687
}
8788
}
88-
// LoadAttachments
89-
public componentDidMount() {
9089

91-
this._loadAttachments();
90+
/**
91+
* Close the dialog
92+
*/
93+
private _closeDialog = () => {
94+
this.setState({
95+
hideDialog: true,
96+
dialogMessage: '',
97+
file: null,
98+
deleteAttachment: false,
99+
});
100+
101+
this.loadAttachments();
102+
}
103+
104+
/**
105+
* Attachment uploaded event handler
106+
*/
107+
private _onAttachmentUpload = () => {
108+
// load Attachments
109+
this.loadAttachments();
110+
}
111+
112+
/**
113+
* On delete attachment event handler
114+
*
115+
* @param file
116+
*/
117+
private onDeleteAttachment = (file: IListItemAttachmentFile) => {
118+
this.setState({
119+
hideDialog: false,
120+
deleteAttachment: true,
121+
file: file,
122+
dialogMessage: strings.ListItemAttachmentsconfirmDelete.replace('{0}', file.FileName),
123+
});
124+
}
125+
126+
/**
127+
* Delete the attachment once it was confirmed
128+
*/
129+
private onConfirmedDeleteAttachment = async () => {
130+
// Delete Attachment
131+
const { file } = this.state;
132+
133+
this.setState({
134+
disableButton: true,
135+
});
136+
137+
try {
138+
await this._spservice.deleteAttachment(file.FileName, this.props.listId, this.props.itemId, this.props.webUrl);
139+
140+
this.setState({
141+
hideDialog: false,
142+
deleteAttachment: false,
143+
disableButton: false,
144+
file: null,
145+
dialogMessage: strings.ListItemAttachmentsfileDeletedMsg.replace('{0}', file.FileName),
146+
});
147+
} catch (error) {
148+
this.setState({
149+
hideDialog: false,
150+
file: null,
151+
deleteAttachment: false,
152+
dialogMessage: strings.ListItemAttachmentsfileDeleteError.replace('{0}', file.FileName).replace('{1}', error.message)
153+
});
154+
}
92155
}
93156

94-
// Render Attachments
157+
/**
158+
* Default React render method
159+
*/
95160
public render() {
96161
return (
97-
98162
<div className={styles.ListItemAttachments}>
99163
<UploadAttachment
100164
listId={this.props.listId}
101165
itemId={this.props.itemId}
102166
disabled={this.props.disabled}
103167
context={this.props.context}
104-
onAttachmentUpload={this._onAttachmentpload}
168+
onAttachmentUpload={this._onAttachmentUpload}
105169
fireUpload={this.state.fireUpload}
106170
/>
107171

@@ -115,21 +179,21 @@ export class ListItemAttachments extends React.Component<IListItemAttachmentsPro
115179
onConfigure={() => this.setState({ fireUpload: true })} />
116180
:
117181

118-
this.state.attachments.map((_file, i: number) => {
182+
this.state.attachments.map((file, i: number) => {
119183
return (
120184
<div className={styles.documentCardWrapper}>
121185
<TooltipHost
122-
content={_file.FileName}
186+
content={file.FileName}
123187
calloutProps={{ gapSpace: 0, isBeakVisible: true }}
124188
closeDelay={200}
125189
directionalHint={DirectionalHint.rightCenter}>
126190

127191
<DocumentCard
128-
onClickHref={`${_file.ServerRelativeUrl}?web=1`}
192+
onClickHref={`${file.ServerRelativeUrl}?web=1`}
129193
className={styles.documentCard}>
130194
<DocumentCardPreview previewImages={[this.previewImages[i]]} />
131195
<Label className={styles.fileLabel}>
132-
{_file.FileName}
196+
{file.FileName}
133197
</Label>
134198
<DocumentCardActions
135199
actions={
@@ -145,7 +209,7 @@ export class ListItemAttachments extends React.Component<IListItemAttachmentsPro
145209
onClick: (ev) => {
146210
ev.preventDefault();
147211
ev.stopPropagation();
148-
this._onDeleteAttachment(_file);
212+
this.onDeleteAttachment(file);
149213
}
150214
},
151215
]
@@ -174,11 +238,11 @@ export class ListItemAttachments extends React.Component<IListItemAttachmentsPro
174238
<DialogFooter>
175239
<div style={{ marginBottom: 7 }}>
176240
{
177-
this.state.disableButton ? <Spinner size={SpinnerSize.medium} /> : ''
241+
this.state.disableButton ? <Spinner size={SpinnerSize.medium} /> : null
178242
}
179243
</div>
180244
{
181-
this.state.deleteAttachment ? (<PrimaryButton disabled={this.state.disableButton} onClick={this._onConfirmedDeleteAttachment}>{strings.ListItemAttachmentsdialogOKbuttonLabelOnDelete}</PrimaryButton>) : ""
245+
this.state.deleteAttachment ? (<PrimaryButton disabled={this.state.disableButton} onClick={this.onConfirmedDeleteAttachment}>{strings.ListItemAttachmentsdialogOKbuttonLabelOnDelete}</PrimaryButton>) : null
182246
}
183247
{
184248
this.state.deleteAttachment ? (<DefaultButton disabled={this.state.disableButton} onClick={this._closeDialog}>{strings.ListItemAttachmentsdialogCancelButtonLabel}</DefaultButton>)
@@ -190,68 +254,4 @@ export class ListItemAttachments extends React.Component<IListItemAttachmentsPro
190254
</div>
191255
);
192256
}
193-
194-
// close dialog
195-
private _closeDialog(e) {
196-
e.preventDefault();
197-
198-
this.setState({
199-
hideDialog: true,
200-
dialogMessage: '',
201-
file: null,
202-
deleteAttachment: false,
203-
});
204-
this._loadAttachments();
205-
}
206-
207-
// On onAttachmentpload
208-
private _onAttachmentpload() {
209-
// load Attachments
210-
this._loadAttachments();
211-
}
212-
213-
// On _onDeleteAttachment
214-
private _onDeleteAttachment(_file: IListItemAttachmentFile) {
215-
this.setState({
216-
hideDialog: false,
217-
deleteAttachment: true,
218-
file: _file,
219-
dialogMessage: strings.ListItemAttachmentsconfirmDelete.replace('{0}', _file.FileName),
220-
});
221-
}
222-
/*
223-
* Confirmed Delete
224-
*/
225-
private _onConfirmedDeleteAttachment() {
226-
// Delete Attachment
227-
const _file = this.state.file;
228-
229-
this.setState({
230-
disableButton: true,
231-
});
232-
233-
this._spservice.deleteAttachment(_file.FileName, this.props.listId, this.props.itemId, this.props.webUrl)
234-
.then(() => {
235-
236-
this.setState({
237-
hideDialog: false,
238-
deleteAttachment: false,
239-
disableButton: false,
240-
file: null,
241-
dialogMessage: strings.ListItemAttachmentsfileDeletedMsg.replace('{0}', _file.FileName),
242-
});
243-
244-
})
245-
.catch((reason) => {
246-
247-
this.setState({
248-
hideDialog: false,
249-
file: null,
250-
deleteAttachment: false,
251-
dialogMessage: strings.ListItemAttachmentsfileDeleteError.replace('{0}', _file.FileName).replace('{1}', reason)
252-
});
253-
254-
});
255-
}
256257
}
257-
export default ListItemAttachments;

0 commit comments

Comments
 (0)