jitz-sharepoint-utilities 1.11.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/@types/allTypes.d.ts +1 -0
  2. package/controls/JitzGrid.tsx +639 -0
  3. package/controls/JitzImage.tsx +38 -0
  4. package/controls/JitzPeoplePicker.tsx +419 -0
  5. package/controls/JitzPersonInfo.tsx +114 -0
  6. package/controls/JitzPersona.tsx +53 -0
  7. package/data/context/CommonRepository.ts +287 -0
  8. package/data/context/JitzContext.ts +33 -0
  9. package/data/context/JitzSPContext.ts +16 -0
  10. package/data/context/JitzSPHttpClient.ts +133 -0
  11. package/data/context/List.ts +429 -0
  12. package/data/context/Repository.ts +395 -0
  13. package/data/interfaces/ICommonRepository.ts +7 -0
  14. package/data/interfaces/IJitzContext.ts +11 -0
  15. package/data/interfaces/IJitzSPContext.ts +7 -0
  16. package/data/interfaces/IJitzSPHttpClient.ts +6 -0
  17. package/data/interfaces/IList.ts +41 -0
  18. package/data/interfaces/IModels.ts +33 -0
  19. package/data/interfaces/IRepository.ts +31 -0
  20. package/lib/common/IModels.d.ts +9 -1
  21. package/lib/common/IObjects.d.ts +72 -0
  22. package/lib/common/IObjects.js +30 -0
  23. package/lib/controls/JitzGrid.d.ts +75 -0
  24. package/lib/controls/JitzGrid.js +606 -0
  25. package/lib/controls/JitzImage.d.ts +14 -0
  26. package/lib/controls/JitzImage.js +37 -0
  27. package/lib/controls/JitzPeoplePicker.d.ts +49 -0
  28. package/lib/controls/JitzPeoplePicker.js +311 -0
  29. package/lib/controls/JitzPersonInfo.d.ts +32 -0
  30. package/lib/controls/JitzPersonInfo.js +98 -0
  31. package/lib/controls/JitzPersona.d.ts +23 -0
  32. package/lib/controls/JitzPersona.js +48 -0
  33. package/lib/data/Activities.d.ts +6 -0
  34. package/lib/data/Activities.js +36 -0
  35. package/lib/data/Attachments.d.ts +6 -0
  36. package/lib/data/Attachments.js +30 -0
  37. package/lib/data/Configurations.d.ts +6 -0
  38. package/lib/data/Configurations.js +30 -0
  39. package/lib/data/CustomStylesheet.d.ts +6 -0
  40. package/lib/data/CustomStylesheet.js +30 -0
  41. package/lib/data/EmailTemplates.d.ts +6 -0
  42. package/lib/data/EmailTemplates.js +31 -0
  43. package/lib/data/FAQs.d.ts +6 -0
  44. package/lib/data/FAQs.js +30 -0
  45. package/lib/data/HomePageTexts.d.ts +6 -0
  46. package/lib/data/HomePageTexts.js +30 -0
  47. package/lib/data/TicketCategories.d.ts +6 -0
  48. package/lib/data/TicketCategories.js +26 -0
  49. package/lib/data/TicketComments.d.ts +6 -0
  50. package/lib/data/TicketComments.js +32 -0
  51. package/lib/data/TicketPriorities.d.ts +6 -0
  52. package/lib/data/TicketPriorities.js +31 -0
  53. package/lib/data/TicketStatuses.d.ts +6 -0
  54. package/lib/data/TicketStatuses.js +31 -0
  55. package/lib/data/TicketSubcategories.d.ts +6 -0
  56. package/lib/data/TicketSubcategories.js +26 -0
  57. package/lib/data/Tickets.d.ts +6 -0
  58. package/lib/data/Tickets.js +45 -0
  59. package/lib/data/context/CommonRepository.d.ts +17 -0
  60. package/lib/data/context/CommonRepository.js +288 -0
  61. package/lib/data/context/JitzContext.d.ts +13 -0
  62. package/lib/data/context/JitzContext.js +80 -0
  63. package/lib/data/context/JitzSPContext.d.ts +8 -0
  64. package/lib/data/context/JitzSPContext.js +58 -0
  65. package/lib/data/context/JitzSPHttpClient.d.ts +14 -0
  66. package/lib/data/context/JitzSPHttpClient.js +173 -0
  67. package/lib/data/context/List.d.ts +36 -0
  68. package/lib/data/context/List.js +450 -0
  69. package/lib/data/context/Repository.d.ts +19 -0
  70. package/lib/data/context/Repository.js +421 -0
  71. package/lib/data/interfaces/ICommonRepository.d.ts +6 -0
  72. package/lib/data/interfaces/ICommonRepository.js +2 -0
  73. package/lib/data/interfaces/IJitzContext.d.ts +10 -0
  74. package/lib/data/interfaces/IJitzContext.js +2 -0
  75. package/lib/data/interfaces/IJitzSPContext.d.ts +6 -0
  76. package/lib/data/interfaces/IJitzSPContext.js +2 -0
  77. package/lib/data/interfaces/IJitzSPHttpClient.d.ts +6 -0
  78. package/lib/data/interfaces/IJitzSPHttpClient.js +2 -0
  79. package/lib/data/interfaces/IList.d.ts +25 -0
  80. package/lib/data/interfaces/IList.js +2 -0
  81. package/lib/data/interfaces/IModels.d.ts +32 -0
  82. package/lib/data/interfaces/IModels.js +2 -0
  83. package/lib/data/interfaces/IRepository.d.ts +14 -0
  84. package/lib/data/interfaces/IRepository.js +2 -0
  85. package/lib/jitzSPHttpClient.js +5 -3
  86. package/lib/repositories/CommonRepository.js +17 -16
  87. package/lib/repositories/Repository.js +22 -21
  88. package/lib/services/GraphService.d.ts +10 -0
  89. package/lib/services/GraphService.js +105 -0
  90. package/lib/services/UserService.d.ts +1 -1
  91. package/lib/services/UserService.js +9 -9
  92. package/lib/services/UtilityService.d.ts +18 -12
  93. package/lib/services/UtilityService.js +157 -58
  94. package/package.json +7 -5
@@ -0,0 +1 @@
1
+ declare module "@microsoft/sp-core-library";
@@ -0,0 +1,639 @@
1
+ import * as React from "react";
2
+ import IJitzSPContext from "../data/interfaces/IJitzSPContext";
3
+ import UtilityService from "../services/UtilityService";
4
+ import {
5
+ buildColumns,
6
+ CommandBar,
7
+ DetailsList,
8
+ IColumn,
9
+ IconButton,
10
+ Label,
11
+ SelectionMode,
12
+ TooltipHost,
13
+ Selection,
14
+ ActionButton,
15
+ Spinner,
16
+ } from "@fluentui/react";
17
+ import CommonRepository from "../data/context/CommonRepository";
18
+ import { IList } from "../data/interfaces/IList";
19
+ import { IModel } from "../common/IModels";
20
+ import IJitzContext from "../data/interfaces/IJitzContext";
21
+
22
+ export enum SortOrder {
23
+ Asc = "asc",
24
+ Desc = "desc",
25
+ }
26
+
27
+ export enum DisplayMode {
28
+ Grid = "Grid",
29
+ Tile = "Tile",
30
+ }
31
+
32
+ export interface IJitzGridState<T extends IModel> {
33
+ list: IList<T>;
34
+ listForDownload: IList<T>;
35
+ items: any[];
36
+ showingItems: any[];
37
+ rawData: any[];
38
+ showingRawData: any[];
39
+ exportData: any[];
40
+ totalCount: number;
41
+ columns?: IColumn[];
42
+ selectedItems?: {};
43
+
44
+ displayMode?: DisplayMode;
45
+ filterQuery?: string;
46
+
47
+ isItIndexedSearch?: boolean;
48
+ isItIndexedDownload?: boolean;
49
+ hasNextPage?: boolean;
50
+ hasNextPageToDownload?: boolean;
51
+ processing?: boolean;
52
+ downloading?: boolean;
53
+ }
54
+
55
+ export interface IJitzGridProps<T extends IModel> {
56
+ context: IJitzContext;
57
+ list: IList<T>;
58
+ filterQuery?: string;
59
+ orderBy?: string;
60
+ displayFields?: string[];
61
+ exportFields?: string[];
62
+ hasExport?: boolean;
63
+ pageSize?: number;
64
+ renderCustomColumns?: (
65
+ content: any,
66
+ fieldName: string,
67
+ rowItem?: any
68
+ ) => React.ReactElement<{}>;
69
+ modifyColumns?: (columns: IColumn[]) => IColumn[];
70
+ onItemSelect?: (items: any) => void;
71
+ onItemInvoked?: (item: any, index: number | undefined) => void;
72
+ selectionMode?: SelectionMode;
73
+ noRecordsMessage?: string;
74
+ noRecordsMessageCssClass?: string;
75
+ tileComponent?: (content: any) => React.ReactElement<{}>;
76
+ refreshedOn?: Date;
77
+ displayMode?: DisplayMode;
78
+ downloadFileName?: string;
79
+ }
80
+
81
+ export class JitzGrid<T extends IModel> extends React.Component<
82
+ IJitzGridProps<T>,
83
+ IJitzGridState<T>
84
+ > {
85
+ private _selection: Selection;
86
+
87
+ constructor(props: IJitzGridProps<T>) {
88
+ super(props);
89
+
90
+ let item: any = {};
91
+ if (props.displayFields) {
92
+ props.displayFields.map((field: any) => {
93
+ item[field] = "";
94
+ });
95
+ }
96
+
97
+ this.state = {
98
+ list: this.props.list,
99
+ listForDownload: this.props.list,
100
+ items: [],
101
+ showingItems: [],
102
+ rawData: [],
103
+ showingRawData: [],
104
+ exportData: [],
105
+ totalCount: 0,
106
+ columns: [],
107
+ displayMode: props.displayMode || DisplayMode.Tile,
108
+ filterQuery: props.filterQuery,
109
+ isItIndexedSearch: false,
110
+ isItIndexedDownload: false,
111
+ processing: false,
112
+ downloading: false,
113
+ hasNextPage: false,
114
+ hasNextPageToDownload: false,
115
+ };
116
+
117
+ this._selection = new Selection({
118
+ onSelectionChanged: () =>
119
+ this.setState({ selectedItems: this._getSelectedItems() }),
120
+ });
121
+ }
122
+
123
+ private _getSelectedItems = () => {
124
+ if (this.props.onItemSelect != undefined) {
125
+ this.props.onItemSelect(this._selection.getSelection());
126
+ }
127
+ return {};
128
+ };
129
+
130
+ private getSortOrderString = (
131
+ sortOrder: SortOrder,
132
+ isPreviousNavigation: boolean
133
+ ): string => {
134
+ if (sortOrder == SortOrder.Asc) {
135
+ return isPreviousNavigation ? "desc" : "asc";
136
+ } else {
137
+ return isPreviousNavigation ? "asc" : "desc";
138
+ }
139
+ };
140
+
141
+ // private hasKey<O>(obj: O, key: keyof any): key is keyof O {
142
+ // return key in obj;
143
+ // }
144
+
145
+ private hasKey(obj: object, key: string): boolean {
146
+ return key in obj;
147
+ }
148
+
149
+ private initalLoad = async () => {
150
+ await this.setState({
151
+ items: [],
152
+ showingItems: [],
153
+ rawData: [],
154
+ showingRawData: [],
155
+ });
156
+ var list = this.props.list;
157
+ var data: T[] = [];
158
+ let items: any[] = [];
159
+ await list
160
+ .getItems(
161
+ this.props.filterQuery,
162
+ this.props.orderBy,
163
+ this.props.pageSize || 100
164
+ )
165
+ .then((results: any) => {
166
+ data = results;
167
+ this.setState({ isItIndexedSearch: false });
168
+ })
169
+ .catch(async (err: any) => {
170
+ data = await list.getItemsIndexed(
171
+ this.props.filterQuery,
172
+ this.props.orderBy,
173
+ this.props.pageSize || 100
174
+ );
175
+ this.setState({ isItIndexedSearch: true });
176
+ });
177
+
178
+ if (this.props.displayFields != undefined) {
179
+ let rawShowingData: any[] = [];
180
+ data.map((record: any) => {
181
+ let item: any = {};
182
+ if (this.props.displayFields != undefined) {
183
+ this.props.displayFields.map((field) => {
184
+ if (this.hasKey(record, field)) {
185
+ item[field] =
186
+ typeof record[field] == "object"
187
+ ? JSON.stringify(record[field])
188
+ : record[field]; // works fine!
189
+ }
190
+ });
191
+ items.push(item);
192
+ rawShowingData.push(record);
193
+ }
194
+ });
195
+
196
+ this.setState(
197
+ {
198
+ items: items,
199
+ showingItems: items,
200
+ rawData: items,
201
+ showingRawData: rawShowingData,
202
+ columns: this._buildColumns(items),
203
+ list: list,
204
+ hasNextPage:
205
+ (list._nextPageLink != undefined &&
206
+ list._nextPageLink.length > 0) ||
207
+ list.lowerId > 0,
208
+ },
209
+ () => {}
210
+ );
211
+ }
212
+ };
213
+
214
+ private loadMore = async () => {
215
+ try {
216
+ var list = this.state.list;
217
+ var data: T[] = [];
218
+ if (this.state.isItIndexedSearch) data = await list.loadMoreIndexed();
219
+ else {
220
+ data = await list.loadMore();
221
+ }
222
+ if (this.props.displayFields != undefined) {
223
+ let items: any[] = [];
224
+ let rawShowingData: any[] = [];
225
+ data.map((record: any) => {
226
+ let item: any = {};
227
+ if (this.props.displayFields != undefined) {
228
+ this.props.displayFields.map((field) => {
229
+ if (this.hasKey(record, field)) {
230
+ item[field] =
231
+ typeof record[field] == "object"
232
+ ? JSON.stringify(record[field])
233
+ : record[field]; // works fine!
234
+ }
235
+ });
236
+ items.push(item);
237
+ rawShowingData.push(record);
238
+ }
239
+ });
240
+
241
+ if (data.length == 0) {
242
+ //TODO: No more records message
243
+ }
244
+
245
+ await this.setState(
246
+ {
247
+ items: [...this.state.items, ...items],
248
+ showingItems: [...this.state.showingItems, ...items],
249
+ rawData: items,
250
+ showingRawData: [...this.state.showingRawData, ...rawShowingData],
251
+ list: list,
252
+ hasNextPage:
253
+ (list._nextPageLink != undefined &&
254
+ list._nextPageLink.length > 0) ||
255
+ list.lowerId > 0,
256
+ },
257
+ () => {}
258
+ );
259
+ }
260
+ } catch {}
261
+ };
262
+
263
+ public componentDidMount(): void {
264
+ this.initalLoad();
265
+ }
266
+
267
+ public async componentWillReceiveProps(nextProps: IJitzGridProps<T>) {
268
+ if (
269
+ nextProps.filterQuery != this.state.filterQuery
270
+ // ||
271
+ // nextProps.refreshedOn != this.props.refreshedOn
272
+ ) {
273
+ await this.setState({ filterQuery: nextProps.filterQuery });
274
+ this.initalLoad();
275
+ }
276
+ }
277
+
278
+ public downloadData = async () => {
279
+ try {
280
+ await this.setState({ downloading: true });
281
+ await this.initiateDownload();
282
+ let items: any[] = [];
283
+ var data: any[] = this.state.exportData;
284
+ data.map((record: any) => {
285
+ let item: any = {};
286
+ if (this.props.exportFields != undefined) {
287
+ this.props.exportFields.map((field: string) => {
288
+ if (this.hasKey(record, field)) {
289
+ if (typeof record[field] == "object") {
290
+ if (record[field] == null || record[field] == undefined) {
291
+ item[field] = "";
292
+ } else if (record[field].EMail != undefined) {
293
+ if (record[field].Title != undefined) {
294
+ item[field + "_Title"] = record[field].Title || "";
295
+ }
296
+ item[field + "_Email"] = record[field].EMail || "";
297
+ } else if (record[field].Name != undefined) {
298
+ item[field + "_Name"] = record[field].Name || "";
299
+ }
300
+ } else {
301
+ item[field] = record[field];
302
+ }
303
+ // item[field] =
304
+ // typeof record[field] == "object"
305
+ // ? JSON.stringify(record[field])
306
+ // : record[field]; // works fine!
307
+ } else if ((field as string).indexOf("/") > 0) {
308
+ let lookUpField: string = (field as string).split("/")[0];
309
+ let lookUpValueColumn: string = (field as string).split("/")[1];
310
+ if (typeof record[lookUpField] == "object") {
311
+ item[field] = record[lookUpField][lookUpValueColumn];
312
+ }
313
+ }
314
+ });
315
+ items.push(item);
316
+ }
317
+ });
318
+ UtilityService.exportJsonAsExcelSheet(
319
+ items,
320
+ this.props.downloadFileName || "export"
321
+ );
322
+ } catch {}
323
+ this.setState({ downloading: false });
324
+ };
325
+
326
+ initiateDownload = async () => {
327
+ var list = this.props.list;
328
+ var data: T[] = [];
329
+ let items: any[] = [];
330
+ await list
331
+ .getItems(this.props.filterQuery, this.props.orderBy, 5000)
332
+ .then((results: any) => {
333
+ data = results;
334
+ this.setState({ isItIndexedDownload: false });
335
+ })
336
+ .catch(async (err: any) => {
337
+ data = await list.getItemsIndexed(
338
+ this.props.filterQuery,
339
+ this.props.orderBy,
340
+ 5000
341
+ );
342
+ this.setState({ isItIndexedDownload: true });
343
+ });
344
+ await this.setState({
345
+ exportData: data,
346
+ hasNextPageToDownload:
347
+ (list._nextPageLink != undefined && list._nextPageLink.length > 0) ||
348
+ list.lowerId > 0,
349
+ });
350
+ if (this.state.hasNextPageToDownload === true) {
351
+ await this.continueDownload(list);
352
+ }
353
+ };
354
+
355
+ continueDownload = async (list: IList<T>) => {
356
+ try {
357
+ var data: T[] = [];
358
+ if (this.state.isItIndexedDownload) data = await list.loadMoreIndexed();
359
+ else {
360
+ data = await list.loadMore();
361
+ }
362
+ await this.setState({
363
+ exportData: [...this.state.exportData, ...data],
364
+ hasNextPageToDownload:
365
+ (list._nextPageLink != undefined && list._nextPageLink.length > 0) ||
366
+ list.lowerId > 0,
367
+ });
368
+ if (this.state.hasNextPageToDownload === true) {
369
+ await this.continueDownload(list);
370
+ }
371
+ } catch {}
372
+ };
373
+
374
+ public render() {
375
+ return (
376
+ <div className="ms-Grid" dir="ltr">
377
+ {/* <div style={{ display: "none" }}>{this.props.refreshedOn}</div> */}
378
+ {this.props.hasExport == true &&
379
+ this.state.showingItems != undefined &&
380
+ this.state.showingItems.length > 0 && (
381
+ <div className="ms-Grid-row">
382
+ <div className="ms-Grid-col ms-sm12 ms-md12 ms-lg12">
383
+ <CommandBar
384
+ farItems={[
385
+ {
386
+ key: "grid",
387
+ text: "",
388
+ title: "Grid View",
389
+ disabled: this.state.displayMode === DisplayMode.Grid,
390
+ iconProps: { iconName: "Table" },
391
+ onClick: () => {
392
+ this.setState({ displayMode: DisplayMode.Grid });
393
+ },
394
+ },
395
+ {
396
+ key: "tile",
397
+ text: "",
398
+ title: "Tile View",
399
+ disabled: this.state.displayMode === DisplayMode.Tile,
400
+ iconProps: { iconName: "Tiles" },
401
+ onClick: () => {
402
+ this.setState({ displayMode: DisplayMode.Tile });
403
+ },
404
+ },
405
+ {
406
+ key: "export",
407
+ text: "",
408
+ title: "Download",
409
+ iconProps: { iconName: "Download" },
410
+ onClick: () => {
411
+ this.downloadData();
412
+ },
413
+ },
414
+ ]}
415
+ items={[
416
+ {
417
+ key: "total",
418
+ text: `Showing ${this.state.items.length} records`,
419
+ title: `Showing ${this.state.items.length} records`,
420
+ onClick: () => {},
421
+ },
422
+ // {
423
+ // key: "loadMore",
424
+ // text: "Try to get more older records",
425
+ // title: "Try to get more older records",
426
+ // iconProps: { iconName: "DoubleChevronDown" },
427
+ // onClick: () => {
428
+ // if (this.state.processing != true)
429
+ // this.setState({ processing: true }, async () => {
430
+ // await this.loadMore();
431
+ // this.setState({ processing: false });
432
+ // });
433
+ // },
434
+ // },
435
+ ]}
436
+ />
437
+ {this.state.downloading && <Spinner label="Please wait..." />}
438
+ </div>
439
+ </div>
440
+ )}
441
+
442
+ {(this.state.showingItems == undefined ||
443
+ this.state.showingItems.length > 0) && (
444
+ <div className="ms-Grid-row">
445
+ <div className="ms-Grid-col ms-sm12 ms-md12 ms-lg12">
446
+ {this.state.displayMode === DisplayMode.Grid && (
447
+ <DetailsList
448
+ items={
449
+ this.state.showingItems != undefined
450
+ ? this.state.showingItems
451
+ : []
452
+ }
453
+ setKey={"Id"}
454
+ columns={this.state.columns}
455
+ onRenderItemColumn={this._renderItemColumn}
456
+ onColumnHeaderClick={this._onColumnClick}
457
+ onItemInvoked={this._onItemInvoked}
458
+ onShouldVirtualize={() => false}
459
+ onColumnHeaderContextMenu={this._onColumnHeaderContextMenu}
460
+ onActiveItemChanged={(item: any, index?: number) => {
461
+ this.itemSelected(item, index);
462
+ }}
463
+ selectionMode={this.props.selectionMode || SelectionMode.none}
464
+ selection={this._selection}
465
+ />
466
+ )}
467
+ {this.state.displayMode === DisplayMode.Tile &&
468
+ this.state.showingItems != undefined &&
469
+ this.state.showingItems.length > 0 &&
470
+ this.state.showingItems.map((item: any) => {
471
+ return this.props.tileComponent != undefined ? (
472
+ this.props.tileComponent(item)
473
+ ) : (
474
+ <></>
475
+ );
476
+ })}
477
+ </div>
478
+ </div>
479
+ )}
480
+ {(this.state.showingItems == undefined ||
481
+ this.state.showingItems.length == 0) && (
482
+ <div className="ms-Grid-row">
483
+ <div
484
+ className={`ms-Grid-col ms-sm12 ms-md12 ms-lg12 centralizeContent ${
485
+ this.props.noRecordsMessageCssClass || ""
486
+ }`}
487
+ >
488
+ {this.props.noRecordsMessage || "No records found"}
489
+ </div>
490
+ </div>
491
+ )}
492
+ <div className="ms-Grid-row">
493
+ <div
494
+ className={`ms-Grid-col ms-sm12 ms-md12 ms-lg12 centralizeContent loadMoreGrid ${
495
+ this.props.noRecordsMessageCssClass || ""
496
+ }`}
497
+ >
498
+ {this.state.processing !== true && this.state.hasNextPage && (
499
+ <ActionButton
500
+ iconProps={{ iconName: "DoubleChevronDown" }}
501
+ onClick={() => {
502
+ this.setState({ processing: true }, async () => {
503
+ await this.loadMore();
504
+ this.setState({ processing: false });
505
+ });
506
+ }}
507
+ >
508
+ Try to get more older records
509
+ </ActionButton>
510
+ )}
511
+ {this.state.processing && <Spinner label="Please wait..." />}
512
+ </div>
513
+ </div>
514
+ </div>
515
+ );
516
+ }
517
+
518
+ private itemSelected = (item: any, index?: number) => {};
519
+
520
+ private _buildColumns = (items: any[]) => {
521
+ var columns: IColumn[] = [];
522
+ if (items != null && items.length > 0) {
523
+ columns = buildColumns(items);
524
+ } else if (
525
+ this.state.items != null &&
526
+ this.state.items != undefined &&
527
+ this.state.items.length > 0
528
+ ) {
529
+ columns = buildColumns(this.state.items);
530
+ }
531
+ var idIndex = 0;
532
+ columns.map((raw, i) => {
533
+ raw.name = raw.name.split("_").join(" ");
534
+ raw.name = raw.name.replace(/\b\w/g, (l) => {
535
+ return l.toUpperCase();
536
+ });
537
+ if (raw.name == "Id") {
538
+ idIndex = i;
539
+ }
540
+ });
541
+ // columns = columns.filter(matchedColumns => matchedColumns.name != "Id" && matchedColumns.name !="ID");
542
+ if (
543
+ this.props.modifyColumns != undefined &&
544
+ this.props.modifyColumns != null
545
+ ) {
546
+ columns = this.props.modifyColumns(columns);
547
+ }
548
+ return columns;
549
+ };
550
+
551
+ private _renderItemColumn = (
552
+ item?: any,
553
+ index?: number,
554
+ column?: IColumn
555
+ ) => {
556
+ if (
557
+ this.state.showingRawData != null &&
558
+ this.state.showingRawData != undefined &&
559
+ this.state.showingRawData.length > 0
560
+ ) {
561
+ if (column != undefined && column.fieldName != undefined) {
562
+ const fieldContent = item[column.fieldName];
563
+ if (
564
+ this.props.renderCustomColumns != undefined &&
565
+ this.props.renderCustomColumns != undefined
566
+ ) {
567
+ return this.props.renderCustomColumns(
568
+ fieldContent,
569
+ column.key,
570
+ this.state.showingRawData[index || 0]
571
+ );
572
+ } else {
573
+ return <span>{fieldContent}</span>;
574
+ }
575
+ }
576
+ }
577
+ };
578
+
579
+ private _onColumnClick = (
580
+ event?: React.MouseEvent<HTMLElement>,
581
+ column?: IColumn
582
+ ): void => {
583
+ const { columns } = this.state;
584
+ let { items } = this.state;
585
+
586
+ if (column != undefined && column.fieldName != undefined) {
587
+ let isSortedDescending = column.isSortedDescending;
588
+
589
+ // If we've sorted this column, flip it.
590
+ if (column.isSorted) {
591
+ isSortedDescending = !isSortedDescending;
592
+ }
593
+
594
+ // Sort the items.
595
+ items = items!.concat([]).sort((a, b) => {
596
+ const firstValue =
597
+ column.fieldName != undefined ? a[column.fieldName] : undefined;
598
+ const secondValue =
599
+ column.fieldName != undefined ? b[column.fieldName] : undefined;
600
+
601
+ if (isSortedDescending) {
602
+ return firstValue > secondValue ? -1 : 1;
603
+ } else {
604
+ return firstValue > secondValue ? 1 : -1;
605
+ }
606
+ });
607
+
608
+ // Reset the items and columns to match the state.
609
+ this.setState({
610
+ items: items,
611
+ columns: columns!.map((col) => {
612
+ col.isSorted = col.key === column.key;
613
+
614
+ if (col.isSorted) {
615
+ col.isSortedDescending = isSortedDescending;
616
+ }
617
+
618
+ return col;
619
+ }),
620
+ });
621
+ }
622
+ };
623
+
624
+ private _onColumnHeaderContextMenu(
625
+ column: IColumn | undefined,
626
+ ev: React.MouseEvent<HTMLElement> | undefined
627
+ ): void {
628
+ // console.log(`column ${column!.key} contextmenu opened.`);
629
+ }
630
+
631
+ private _onItemInvoked = (item: any, index: number | undefined): void => {
632
+ if (
633
+ this.props.onItemInvoked != undefined &&
634
+ this.props.onItemInvoked != null
635
+ ) {
636
+ this.props.onItemInvoked(item, index);
637
+ }
638
+ };
639
+ }
@@ -0,0 +1,38 @@
1
+ import * as React from "react";
2
+ import { Image } from "@fluentui/react";
3
+
4
+ export interface IJitzImageProps {
5
+ email?: string;
6
+ siteUrl: string;
7
+ width?: number;
8
+ height?: number;
9
+ className?: string;
10
+ }
11
+
12
+ export interface IJitzImageState {}
13
+
14
+ export class JitzImage1 extends React.Component<
15
+ IJitzImageProps,
16
+ IJitzImageState
17
+ > {
18
+ constructor(props: IJitzImageProps, state: IJitzImageState) {
19
+ super(props);
20
+ this.state = {};
21
+ }
22
+
23
+ public render(): React.ReactElement<IJitzImageProps> {
24
+ return (
25
+ <Image
26
+ src={`${encodeURIComponent(this.props.email || "")}`}
27
+ alt={""}
28
+ onError={(e: any) => {
29
+ e.target.onerror = null;
30
+ e.target.src = `${this.props.siteUrl}/_layouts/15/userphoto.aspx?size=L&accountname=${this.props.email}`;
31
+ }}
32
+ width={this.props.width}
33
+ height={this.props.height}
34
+ className={this.props.className}
35
+ />
36
+ );
37
+ }
38
+ }