@mikezimm/fps-library-v2
Version:
Library of reusable typescript/javascript functions, interfaces and constants
864 lines (860 loc) • 50.3 kB
JavaScript
/**
* CodeAnalizerComment: Updated 5 imports on 2024-09-22 14:49:52
* Update:: import { PanelType } to '@mikezimm/fps-core-v7/lib/types/@fluentUI/@7.199.1/Panel;'
* Update:: import { replaceHandleBarsValues } to '@mikezimm/fps-core-v7/lib/logic/Strings/handleBarsSub;'
* Update:: import { IDrillItemInfo } to '@mikezimm/fps-core-v7/lib/components/webparts/Drilldown/IDrillItem;'
* Update:: import { IQuickButton } to '@mikezimm/fps-core-v7/lib/components/webparts/Drilldown/QuickCommands/IQuickCommands;'
* Update:: import { IAnySourceItemAny } to '@mikezimm/fps-core-v7/lib/components/molecules/AnyContent/IAnyContent;'
*/
/**
* CodeAnalizerComment: Updated 3 imports on 2024-09-21 23:07:24
* Update:: import { doesObjectExistInArray } to '@mikezimm/fps-core-v7/lib/logic/Arrays/searching/objectfind;'
* Update:: import { check4This } to '@mikezimm/fps-core-v7/lib/logic/Links/CheckSearch;'
* Update:: import { IAnySourceItemAny } to '@mikezimm/fps-core-v7/lib/components/molecules/AnyContent/IAnyContent;'
*/
import * as React from 'react';
import { Icon, } from '@fluentui/react/lib/Icon';
import { Pivot, PivotItem, } from '@fluentui/react/lib/Pivot';
import ReactJson from '@microlink/react-json-view';
import { getMaxRichHeightNum } from '../functions/richHeight';
import { SelectionMode } from '@mikezimm/fps-core-v7/lib/types/spfxControlsReact/@3.12.0/SelectionMode';
import { Panel, PanelType } from '@fluentui/react/lib/Panel';
import { PrimaryButton, DefaultButton } from '@fluentui/react/lib/Button';
import PageArrows from '../../Arrows/PageArrows';
import { replaceHandleBarsValues } from '@mikezimm/fps-core-v7/lib/logic/Strings/handleBarsSub';
import { buildConfirmDialogBig } from '../../../atoms/Elements/confirmDialogBig';
import { makeToggles } from '../atoms/toggleFieldBuilder';
import { autoDetailsList } from '../atoms/detailsList';
import { findParentElementPropLikeThis } from '@mikezimm/fps-core-v7/lib/logic/DOM/Search/domSearch';
import { updateReactListItem } from '../functions/updateReactListItem';
import { doesObjectExistInArray } from '@mikezimm/fps-core-v7/lib/logic/Arrays/searching/objectfind';
import { createPanelButtonsV2 } from '../atoms/createPanelButtonsV2';
import { createPanelAttachmentElements } from '../functions/fetchAttachments';
import { check4This, Check4 } from '@mikezimm/fps-core-v7/lib/logic/Links/CheckSearch';
import { createItemSharingTable } from '../../../atoms/SharedItems/createItemSharingTable';
import { makeAbsoluteUrl } from '@mikezimm/fps-core-v7/lib/logic/Strings/getSiteCollectionUrlFromLink';
import { ReactViewSpecialKeys } from '../interfaces/SpecialViewKeys';
import { getWebPartVersionElement } from '../../../../banner/bannerX/VersionElement';
import { renderPermsStandalone, renderAttachStandalone } from './specialRenders';
require('@mikezimm/fps-styles/dist/reactListView.css');
export default class ReactListItems extends React.Component {
/**
* createPanelAttachments is identical on ActionNews and Drilldown7 except panelItem interface
* @param thisId
* @param panelItem
*/
async _createPanelAttachments(thisId, panelItem) {
const attachments = await createPanelAttachmentElements(this.props.bannerProps.fpsSpService, this.props.webUrl, this.props.listTitle, panelItem);
this.setState({
panelAttachments: attachments,
lastAttachId: thisId,
});
}
handleExpandedFieldInfoToIViewFields(viewFields) {
//Before this line was added, I think it was mutating props causing double render
viewFields = JSON.parse(JSON.stringify(viewFields));
viewFields.map(vf => {
//2022-03-18: MEMO TO SELF... SOMETHING SEEMS OFF about this replace...
vf.name = vf.name.replace(/\//g, '');
});
return viewFields;
}
createBlankDialog() {
let myDialog = {
title: '',
dialogMessage: '',
showDialog: false,
confirmButton: '',
_confirmDialog: this._confirmUpdateDialog.bind(this),
_closeDialog: this._closeDialog.bind(this),
};
return myDialog;
}
constructor(props) {
super(props);
this._componentWidth = null;
this.delim = '|||';
/***
* .o88b. .d88b. d8b db .d8888. d888888b d8888b. db db .o88b. d888888b .d88b. d8888b.
* d8P Y8 .8P Y8. 888o 88 88' YP `~~88~~' 88 `8D 88 88 d8P Y8 `~~88~~' .8P Y8. 88 `8D
* 8P 88 88 88V8o 88 `8bo. 88 88oobY' 88 88 8P 88 88 88 88oobY'
* 8b 88 88 88 V8o88 `Y8b. 88 88`8b 88 88 8b 88 88 88 88`8b
* Y8b d8 `8b d8' 88 V888 db 8D 88 88 `88. 88b d88 Y8b d8 88 `8b d8' 88 `88.
* `Y88P' `Y88P' VP V8P `8888Y' YP 88 YD ~Y8888P' `Y88P' YP `Y88P' 88 YD
*
*
*/
this._ListViewFontSizes = [`default-font-size`, `larger-font-size`, `large-font-size`];
this._onGoToList = () => {
if (!this.props.listUrl || this.props.listUrl === null || this.props.listUrl === undefined || this.props.listUrl.length === 0) {
return; // Do nothing
}
let e = event;
let isAltClick = e.altKey;
let isShfitClick = e.shiftKey;
let isCtrlClick = e.ctrlKey;
console.log('AltClick, ShfitClick, CtrlClick:', isAltClick, isShfitClick, isCtrlClick);
window.open(`${this.props.listUrl}?Source=${window.location.pathname}`, "_blank");
};
this._CreateNewItem = () => {
if (this.props.isLibrary === true) {
window.open(`${this.props.listUrl}`, "_blank");
}
else {
// https://github.com/mikezimm/drilldown7/issues/422
if (this.props.listNewForm.indexOf('/sites/') === 0 || this.props.listNewForm.indexOf('http') === 0) {
window.open(`${this.props.listNewForm}.aspx?Source=${this.props.itemLinkSource}`, "_blank");
}
else {
// window.open(`${this.props.listUrl}/NewForm.aspx?Source=${window.location.pathname}&${window.location.search}`, "_blank");
window.open(`${this.props.listUrl}/${this.props.listNewForm}.aspx?Source=${this.props.itemLinkSource}`, "_blank");
}
}
};
/**
* Close the dialog
*/
this._closeDialog = () => {
this.setState({
myDialog: this.createBlankDialog(),
});
};
/**
* Render permissions / sharing icon cell. Extracted for reuse elsewhere.
* fieldName: either 'HasUniqueRoleAssignments' or 'ItemSharingInfo'
*/
this._renderPerms = (fieldName, item) => {
return renderPermsStandalone(fieldName, item, this.props, this._onShowPanel.bind(this));
};
/**
* Render attachments icon cell. Reusable for Attach column.
*/
this._renderAttach = (item) => {
return renderAttachStandalone(item, this.props, this._onShowPanel.bind(this));
};
this._onClosePanel = () => {
this.setState({
showPanel: false,
showAttach: false,
clickedAttach: false,
});
};
/***
* d8888b. .d8b. d8b db d88888b db d88888b .d88b. .d88b. d888888b d88888b d8888b.
* 88 `8D d8' `8b 888o 88 88' 88 88' .8P Y8. .8P Y8. `~~88~~' 88' 88 `8D
* 88oodD' 88ooo88 88V8o 88 88ooooo 88 88ooo 88 88 88 88 88 88ooooo 88oobY'
* 88~~~ 88~~~88 88 V8o88 88~~~~~ 88 88~~~ 88 88 88 88 88 88~~~~~ 88`8b
* 88 88 88 88 V888 88. 88booo. 88 `8b d8' `8b d8' 88 88. 88 `88.
* 88 YP YP VP V8P Y88888P Y88888P YP `Y88P' `Y88P' YP Y88888P 88 YD
*
*
*/
/**
* This was copied from codepen example code to render a footer with buttons:
* https://fabricweb.z5.web.core.windows.net/oufr/6.50.2/#/examples/panel
*
*/
this._onRenderFooterContent = () => {
return null;
return (React.createElement("div", null,
React.createElement(PrimaryButton, { onClick: this._onClosePanel, style: { marginRight: '8px' } }, "Save"),
React.createElement(DefaultButton, { onClick: this._onClosePanel }, "Cancel")));
};
if (check4This(Check4.sourceResults_Eq_true, false) === true)
console.log('listView PROPS: ', this.props);
let viewFields = [];
if (this.props.viewFields.length > 0) {
viewFields = this.handleExpandedFieldInfoToIViewFields(this.props.viewFields);
}
let groupByFields = [];
if (this.props.groupByFields && this.props.groupByFields.length > 0) {
//Added this reparse to prevent mutating props
groupByFields = JSON.parse(JSON.stringify(this.props.groupByFields));
groupByFields.map(gF => { gF.name = gF.name.replace(/\//g, ''); });
}
const richHeightNum = getMaxRichHeightNum(this.props.autoRichHeight, this.props.richHeights[0], this.props.items);
this.state = {
fontSize: this._ListViewFontSizes[0],
maxChars: this.props.maxChars ? this.props.maxChars : 50,
viewFields: viewFields,
groupByFields: groupByFields,
showPanel: false,
showAttach: false,
panelId: null,
lastPanelId: null,
panelItem: null,
panelAttachments: [],
panelRollAssignments: [],
lastAttachId: null,
clickedAttach: false,
myDialog: this.createBlankDialog(),
pickedCommand: null,
panelWidth: PanelType.medium,
richHeightNum: richHeightNum,
richHeightStr: `${richHeightNum}em`,
firstVisible: 0,
lastVisible: this.props.itemsPerPage - 1,
commandResult: null,
commandError: false,
showCommandCode: false,
};
}
componentDidMount() {
//this._getListItems();
}
/***
* d8888b. d888888b d8888b. db db d8888b. d8888b. .d8b. d888888b d88888b
* 88 `8D `88' 88 `8D 88 88 88 `8D 88 `8D d8' `8b `~~88~~' 88'
* 88 88 88 88 88 88 88 88oodD' 88 88 88ooo88 88 88ooooo
* 88 88 88 88 88 88 88 88~~~ 88 88 88~~~88 88 88~~~~~
* 88 .8D .88. 88 .8D 88b d88 88 88 .8D 88 88 88 88.
* Y8888D' Y888888P Y8888D' ~Y8888P' 88 Y8888D' YP YP YP Y88888P
*
*
*/
componentDidUpdate(prevProps, prevState) {
/* eslint-disable @typescript-eslint/no-unused-vars */
let redraw = false;
let updateViewFields = false;
let resetArrows = false;
if (JSON.stringify(prevProps.viewFields) !== JSON.stringify(this.props.viewFields)) {
updateViewFields = true;
redraw = true;
}
if (JSON.stringify(prevProps.groupByFields) !== JSON.stringify(this.props.groupByFields)) {
updateViewFields = true;
redraw = true;
}
if (prevProps.resetArrows !== this.props.resetArrows) {
// updateViewFields = true;
resetArrows = true;
this.setState({
firstVisible: 0,
lastVisible: this.props.itemsPerPage - 1,
});
}
if (prevProps.richHeights.join('') !== this.props.richHeights.join('')) {
updateViewFields = true;
redraw = true;
}
// if ( prevProps.items.length !== this.props.items.length ) {
// this._setMaxRichHeight( this.props.autoRichHeight, this.props.richHeight, this.props.items );
// redraw = true; }
if (prevProps.listUrl !== this.props.listUrl) {
redraw = true;
}
/* eslint-enable @typescript-eslint/no-unused-vars */
this._updateStateOnPropsChange(updateViewFields);
}
/***
* d8888b. d88888b d8b db d8888b. d88888b d8888b.
* 88 `8D 88' 888o 88 88 `8D 88' 88 `8D
* 88oobY' 88ooooo 88V8o 88 88 88 88ooooo 88oobY'
* 88`8b 88~~~~~ 88 V8o88 88 88 88~~~~~ 88`8b
* 88 `88. 88. 88 V888 88 .8D 88. 88 `88.
* 88 YD Y88888P VP V8P Y8888D' Y88888P 88 YD
*
*
*/
render() {
let ListView = this.props.ListView;
//console.log( 'ReactListItems props & state: ', this.props, this.state );
// let thisLog = null;
let showRichHeightButton = false;
//2022-02-01: Updated this from drilldown7
if (this.props.items === null || this.props.items.length === 0) {
return (React.createElement("div", { className: '' }, "List View has NO Items to show"));
}
else {
const { bannerProps } = this.props;
let attachments = this.state.panelAttachments.length > 0 ? this.state.panelAttachments : null;
let dialog = !this.state.myDialog.showDialog ? null : buildConfirmDialogBig(this.state.myDialog);
const { quickCommands, } = this.props;
const { commandError, commandResult } = this.state;
/***
* d888888b .d88b. d888b d888b db d88888b .d8888.
* `~~88~~' .8P Y8. 88' Y8b 88' Y8b 88 88' 88' YP
* 88 88 88 88 88 88 88ooooo `8bo.
* 88 88 88 88 ooo 88 ooo 88 88~~~~~ `Y8b.
* 88 `8b d8' 88. ~8~ 88. ~8~ 88booo. 88. db 8D
* YP `Y88P' Y888P Y888P Y88888P Y88888P `8888Y'
*
*
*/
let toggles = !this.state.showPanel ? null : React.createElement("div", { style: { float: 'right' } },
" ",
makeToggles(this.getPageToggles()),
" ");
const itemLink = React.createElement("div", { style: { cursor: 'pointer', fontSize: 'larger', 'fontWeight': 600, color: 'darkblue', padding: '10px 10px 10px 0px', margin: '20px 0px' }, onClick: () => { window.open(this.state.panelItem.goToPropsLink, '_blank'); } }, "Click to open item");
let UniquePermsElement = !this.state.panelItem || !this.state.panelItem.HasUniqueRoleAssignments ? undefined : React.createElement("div", null,
React.createElement("h3", null,
renderPermsStandalone('HasUniqueRoleAssignments', this.state.panelItem, this.props, null),
"Item has Unique Permissions"));
let SharingElement = !this.state.panelItem || !this.state.panelItem.ItemSharingInfo ? undefined : React.createElement("div", null,
React.createElement("h3", null, "Sharing History"),
createItemSharingTable(this.state.panelItem, true));
let fullPanel = null;
if (this.state.showPanel === true && this.state.panelId) {
fullPanel = React.createElement(Panel, { isOpen: this.state.showPanel, type: this.state.panelWidth, onDismiss: this._onClosePanel, headerText: this.state.panelId.toString(), closeButtonAriaLabel: "Close", onRenderFooterContent: this._onRenderFooterContent, isLightDismiss: true, isFooterAtBottom: true },
toggles,
React.createElement(Pivot, { "aria-label": "React List View Panel", defaultSelectedIndex: 0, style: { paddingTop: '16px' } },
React.createElement(PivotItem, { headerText: "Commands", itemKey: "Commands" },
React.createElement("div", null,
itemLink,
React.createElement("div", { id: '20pxSpacer', style: { height: '20px' } }),
attachments,
createPanelButtonsV2(this.props.quickCommands, this.state.panelItem, this.props.sourceUserInfo, this._panelButtonClickedv2.bind(this), this.delim, this.state.showCommandCode),
UniquePermsElement,
SharingElement)),
React.createElement(PivotItem, { headerText: "Details", itemKey: "Details" },
itemLink,
UniquePermsElement,
SharingElement,
autoDetailsList(this.state.panelItem, ["Title", "refiners"], ["search", "meta", "searchString"], true)),
React.createElement(PivotItem, { headerText: "JSON", itemKey: "JSON" },
React.createElement("div", { id: "CommandsJSONPanel", style: { paddingTop: '20px' } },
itemLink,
React.createElement(ReactJson, { src: this.state.panelItem, name: 'panelItem', collapsed: true, displayDataTypes: true, displayObjectSize: true, enableClipboard: true, style: { padding: '20px 0px' } }),
SharingElement))),
getWebPartVersionElement(this.props.bannerProps, { paddingTop: '4em' }));
}
/**
* 2022-02-01: This was copied/updated from drilldown7 to actionnews
*/
let attachPanel = null;
if (this.state.showAttach === true && this.state.panelId) {
attachPanel = React.createElement(Panel, { isOpen: this.state.showAttach, type: this.state.panelWidth, onDismiss: this._onClosePanel, headerText: this.state.panelId.toString(), closeButtonAriaLabel: "Close", onRenderFooterContent: this._onRenderFooterContent, isLightDismiss: true, isFooterAtBottom: true },
attachments,
SharingElement);
}
let viewFieldsBase = this.state.viewFields;
let preFields = [];
if (this.props.includePerms) {
//Add permissions column:
const thisFieldName = `HasUniqueRoleAssignments`;
preFields.push({
name: thisFieldName,
displayName: 'Perms',
sorting: true,
minWidth: 25,
maxWidth: 35,
linkPropertyName: 'goToPermsLink',
render: (item) => { return this._renderPerms(thisFieldName, item); },
});
}
if (this.props.includeAttach) {
//Add attachments column:
preFields.push({
name: 'Attachments',
displayName: 'Attach',
sorting: true,
minWidth: 25,
maxWidth: 35,
render: (item) => { return this._renderAttach(item); },
});
}
let viewFields = preFields.concat(viewFieldsBase);
let filtered = [];
this.props.items.map((item, idx) => {
if (idx >= this.state.firstVisible && idx <= this.state.lastVisible) {
filtered.push(item);
}
});
const pageArrows = React.createElement(PageArrows, { itemCount: this.props.items.length, itemsPerPage: this.props.itemsPerPage, setParentStateFirstLast: this._updateFirstLastVisible.bind(this), debugMode: this.props.debugMode, fontSize: this._componentWidth && this._componentWidth > 800 ? 28 : 24, resetArrows: this.props.resetArrows, pageArrowStyles: { marginTop: '-7px' } });
viewFields.map(field => {
// https://github.com/mikezimm/drilldown7/issues/337
if (field.name === 'HasUniqueRoleAssignments' || field.name === 'ItemSharingInfo') { // ContactLock
field.render = (item) => { return this._renderPerms(field.name, item); };
//This is for: https://github.com/mikezimm/drilldown7/issues/224
}
else if (this.props.richColumns.indexOf(field.name) > -1) {
showRichHeightButton = true;
const fieldStyles = [`list-view-rt`];
if (this.props.richMarginAuto === true)
fieldStyles.push('list-view-rt-start');
// fieldStyles.push( this._RichTextRowHeight[ this.state.richHeight ] );
field.render = (item, index) => { return React.createElement("div", { style: { maxHeight: this.state.richHeightStr }, className: fieldStyles.join(' '), dangerouslySetInnerHTML: { __html: item[field.name] } }); };
// field.render = ( item, index ) => { this._renderRich( item, field.name ) }
}
else if (field.linkSubstitute || field.textSubstitute) {
// Testing to see if Url value is valid... has a value, is a string, and either starts with http or /sites/
// Testing to see if Url value is valid... has a value, is a string, and either starts with http or /sites/
// 2025-03-04: added .indexOf('{{') for https://github.com/mikezimm/drilldown7/issues/484
const isValidSubLink = typeof field.linkSubstitute === "string" &&
(field.linkSubstitute.indexOf("/sites/") === 0 || field.linkSubstitute.indexOf("/teams/") === 0 || field.linkSubstitute.indexOf("http") === 0) || field.linkSubstitute.indexOf('{{') > -1 ? true : false;
// Testing to see if Url value is valid... has a value, is a string, and either starts with http or /sites/
const isValidText = typeof field.textSubstitute === "string" ? true : false;
if (isValidSubLink !== true && isValidText !== true) {
return;
}
else {
// Start on https://github.com/mikezimm/drilldown7/issues/70, https://github.com/mikezimm/drilldown7/issues/268
field.render = (item, index) => {
const linkSubstitute = isValidSubLink === true ? replaceHandleBarsValues(item, field.linkSubstitute, true, 20, field.linkSubEmptyHandling) : '';
const textSubstitute = isValidText === true ? replaceHandleBarsValues(item, field.textSubstitute, field.showEmptyAsEmpty === true ? true : false) : item[field.name];
// Return element as a link if the Url passes simple validation. Else just return the displayed value as normal span
if (isValidSubLink === true && linkSubstitute) {
return React.createElement("a", { href: linkSubstitute }, textSubstitute);
}
else {
return React.createElement("span", null, textSubstitute);
}
}; // close: field.render = ( item, index ) => {
} // close if ( isValid === true ) {
/**
* 2025-01-27: Added this loop for rendering better link labels
* https://github.com/mikezimm/drilldown7/issues/463
*/
}
else if (field.name.indexOf(`${field.displayName}Show`) === 0) { // This is a special column like
const { linkPropertyName, displayName } = field;
if (linkPropertyName && ReactViewSpecialKeys.indexOf(linkPropertyName) > -1) {
field.render = (item) => {
// use the actual column value (strigified) if it exists, else use a
const title = displayName && item[displayName] ? JSON.stringify(item[displayName]) : linkPropertyName.replace('goTo', '');
// return <Icon style={{ fontSize: fontSize, color: unique === true ? 'red' : 'gray' }} iconName={ itemIcon } title={ title } />;
return React.createElement("a", { style: {}, href: item[linkPropertyName], onClick: (event) => {
event.preventDefault(); // Prevent default navigation
window.open(item[linkPropertyName], '_blank');
}, title: title }, title);
};
}
} // close: } else if ( field.linkSubstitute ) {
}); // close: viewFields.map ( field => {
//=>> address: https://github.com/mikezimm/drilldown7/issues/270
const changeRichHeight = showRichHeightButton !== true ? null :
React.createElement("div", { title: `Change row height from ${this.state.richHeightStr}`, onClick: this._updateRichHeightState.bind(this), style: { fontSize: 'larger', fontWeight: 'bolder', width: '25px', textAlign: 'center', cursor: 'pointer' } },
React.createElement(Icon, { iconName: 'CollapseMenu' }));
// determine iconFieldName https://github.com/mikezimm/drilldown7/issues/163
const iconFieldName = this.props.isLibrary === true ? 'FileRef' : undefined;
//=>> address: https://github.com/mikezimm/drilldown7/issues/169
const changeFont = React.createElement("div", { title: "Change font size", onClick: this._changeFontSize.bind(this), style: { fontSize: 'larger', fontWeight: 'bolder', width: '25px', textAlign: 'center', cursor: 'pointer' } },
React.createElement(Icon, { iconName: 'FontSize' }));
let listView = React.createElement("div", { className: this.state.fontSize },
React.createElement(ListView, { items: filtered, viewFields: viewFields,
// className={ 'font-size-14' }
// listClassName={ stylesL.fontSizeLarger }
compact: true, selectionMode: this.props.includeDetails ? SelectionMode.single : SelectionMode.none,
/**
* https://github.com/mikezimm/drilldown7/issues/519
* This actually works when in the compiled JS but can't figure out the correct way to type it
*
selection: (item, e) => this._onShowPanel(item, 'Panel', e)
or this in JSX:
selection={ (item, e) => this._onShowPanel(item, 'Panel', e) }
*/
selection: this._onShowPanel.bind(this, 'Panel'), showFilter: false, iconFieldName: iconFieldName,
//defaultFilter="John"
filterPlaceHolder: "Search...", groupByFields: this.props.groupByFields }));
// let logTable = itemRows === null ? <div>Nothing to show</div> : <table style={{ display: 'block'}} className={stylesInfo.infoTable}>
let barText = this.props.blueBar && this.props.blueBar != null ? this.props.blueBar : React.createElement("span", null, "Items"); // eslint-disable-line eqeqeq
let webTitle = null;
let listLink = !this.props.includeListLink ? null : React.createElement("div", { className: `info-heading`, onClick: this._onGoToList.bind(this), style: { marginRight: 30, whiteSpace: 'nowrap', paddingTop: 0, cursor: 'pointer', fontSize: 'smaller', background: 'transparent' } },
React.createElement("span", { style: { background: 'transparent' }, className: ['fps-gen-inBlockNoWrap', 'fps-gen-goToLink-theme'].join(' ') }, "Go to list"));
let createItemLink = !this.props.createItemLink ? null : React.createElement("div", { title: "Create new item", className: `info-heading`, onClick: this._CreateNewItem.bind(this), style: { marginRight: 30, whiteSpace: 'nowrap', paddingTop: 0, cursor: 'pointer', fontSize: 'larger', background: 'transparent' } },
React.createElement("span", { style: { background: 'transparent' }, className: `` },
React.createElement(Icon, { iconName: "AddTo" })));
// https://github.com/mikezimm/drilldown7/issues/249
let maxBlueBarLeft = createItemLink ? 35 : 40;
if (!listLink)
maxBlueBarLeft += 15;
const headerBarClass = [`info-heading`, `inner-shadow`, `fps-list-header-bar`, this.props.themeClass];
let headerBarStyles = { display: 'flex', justifyContent: 'space-between', };
if (bannerProps.bannerPillShape === true)
headerBarStyles = { ...headerBarStyles, ...{ borderRadius: '50px' } };
if (barText !== null) {
webTitle = React.createElement("div", { style: headerBarStyles, className: headerBarClass.join(' ') },
React.createElement("span", { className: `blue-bar-left`, style: { maxWidth: `${maxBlueBarLeft}%` }, title: this.props.blueBarTitleText },
"( ",
this.props.items.length,
" ) ",
barText),
pageArrows,
React.createElement("span", { style: { gridRow: 'nowrap', display: 'inline-flex', gridGap: '.75em', marginRight: '25px' } },
changeFont,
changeRichHeight),
React.createElement("span", { style: { whiteSpace: 'nowrap', display: 'flex', marginRight: '25px' } },
createItemLink,
listLink));
/**
* Brought this in directly from Drilldown web part
* added quickCommands && due to testing on spfx-v2-tester
*/
const createFooter = quickCommands && quickCommands.successBanner > 0 ? true : false; //CommandItemNotUpdatedMessage
const footerEleClasses = ['quickCommandFooterStyles', commandResult ? 'quickCommandShow' : 'quickCommandHide'];
if (!commandResult) {
//Do nothing if no result
}
else if (commandResult.status === 'Success') {
}
else if (commandResult.status === 'Unknown') {
footerEleClasses.push('quickCommandWarn');
}
else {
footerEleClasses.push('quickCommandError');
}
const footerInfo = !commandResult ? '' :
commandResult.statusElement ? commandResult.statusElement :
commandResult.errorInfo ? commandResult.errorInfo.returnMess : '';
/**
* NOTE: You ALWAYS need a footer element if it's active, even if there is nothing to show.
* If not, then you do not get the smooth transitions when it is visible.
*/
const footerElement = createFooter === false ? null : React.createElement("div", { className: footerEleClasses.join(' ') }, footerInfo);
/*stylesL.reactListView*/
return (React.createElement("div", { className: '', ref: el => {
// el can be null - see https://reactjs.org/docs/refs-and-the-dom.html#caveats-with-callback-refs
if (!el)
return;
this._componentWidth = el.getBoundingClientRect().width;
// console.log('componentWidth', this._componentWidth ) ;
} },
React.createElement("div", { style: { paddingTop: 10 }, className: `info-pane-tight` },
webTitle,
fullPanel,
attachPanel,
dialog,
footerElement,
listView)));
}
} //if ( this.props.items != null && this.props.items.length > 0 ) {
} // Render
/***
* db db d8888b. d8888b. .d8b. d888888b d88888b .d8888. d888888b .d8b. d888888b d88888b
* 88 88 88 `8D 88 `8D d8' `8b `~~88~~' 88' 88' YP `~~88~~' d8' `8b `~~88~~' 88'
* 88 88 88oodD' 88 88 88ooo88 88 88ooooo `8bo. 88 88ooo88 88 88ooooo
* 88 88 88~~~ 88 88 88~~~88 88 88~~~~~ `Y8b. 88 88~~~88 88 88~~~~~
* 88b d88 88 88 .8D 88 88 88 88. db 8D 88 88 88 88 88.
* ~Y8888P' 88 Y8888D' YP YP YP Y88888P `8888Y' YP YP YP YP Y88888P
*
*
*/
_updateRichHeightState() {
const oldValue = this.state.richHeightNum;
const oldIdx = this.props.richHeights.indexOf(oldValue);
const nextIdx = oldIdx === this.props.richHeights.length - 1 ? 0 : oldIdx + 1;
const richHeightNum = this.props.richHeights[nextIdx];
this.setState({ richHeightNum: richHeightNum, richHeightStr: `${richHeightNum}em` });
}
_updateStateOnPropsChange(pushViewFieldsToState) {
let viewFields = [];
if (this.props.viewFields.length > 0) {
viewFields = this.handleExpandedFieldInfoToIViewFields(this.props.viewFields);
}
let groupByFields = [];
if (this.props.groupByFields && this.props.groupByFields.length > 0) {
groupByFields = JSON.parse(JSON.stringify(this.props.groupByFields));
groupByFields.map(gF => { gF.name = gF.name.replace(/\//g, ''); });
}
if (pushViewFieldsToState === true) {
this.setState({
viewFields: viewFields,
groupByFields: groupByFields,
});
}
}
/***
* d8888b. db db d888888b d888888b .d88b. d8b db .o88b. db d888888b .o88b. db dD
* 88 `8D 88 88 `~~88~~' `~~88~~' .8P Y8. 888o 88 d8P Y8 88 `88' d8P Y8 88 ,8P'
* 88oooY' 88 88 88 88 88 88 88V8o 88 8P 88 88 8P 88,8P
* 88~~~b. 88 88 88 88 88 88 88 V8o88 8b 88 88 8b 88`8b
* 88 8D 88b d88 88 88 `8b d8' 88 V888 Y8b d8 88booo. .88. Y8b d8 88 `88.
* Y8888P' ~Y8888P' YP YP `Y88P' VP V8P `Y88P' Y88888P Y888888P `Y88P' YP YD
*
*
*/
async _panelButtonClickedv2(b, item, event) {
console.log('_panelButtonClickedv2', item);
if (!item) {
alert('Whoops! Can not find ID of _panelButtonClicked!');
return null;
}
else {
// Add Command Code to panel https://github.com/mikezimm/drilldown7/issues/252
if (event.ctrlKey === true || event.altKey === true) {
this.setState({ showCommandCode: !this.state.showCommandCode });
}
else {
try {
await this.startThisQuickUpdate2(b, item);
}
catch (ev) {
console.log('_panelButtonClicked error:', ev);
}
}
}
}
/**
* Open the dialog
*/
//private _confirmUpdateDialog = () => {
async _confirmUpdateDialog(item) {
let e = event; // eslint-disable-line @typescript-eslint/no-unused-vars
let thisButtonObject = this.state.pickedCommand;
await this.completeThisQuickUpdate(this.state.panelId.toString(), thisButtonObject);
this.setState({
myDialog: this.createBlankDialog(),
});
}
//=>> address: https://github.com/mikezimm/drilldown7/issues/169
_changeFontSize() {
const oldValue = this.state.fontSize;
const oldIdx = this._ListViewFontSizes.indexOf(oldValue);
const nextIdx = oldIdx === this._ListViewFontSizes.length - 1 ? 0 : oldIdx + 1;
this.setState({ fontSize: this._ListViewFontSizes[nextIdx] });
}
async startThisQuickUpdate2(thisButtonObject, item) {
const itemId = item.Id;
if (!thisButtonObject) {
alert('_panelButtonClicked - can not find thisButtonObject - ' + itemId);
}
else {
if (thisButtonObject.updateItem) {
let readyToUpdate = true;
if (!this.props.webUrl) {
alert('Missing listWebUrl for quickCommands');
readyToUpdate = false;
}
if (!this.props.listTitle) {
alert('Missing listTitle for quickCommands');
readyToUpdate = false;
}
if (readyToUpdate === true) {
//Attempt to update item:
if (thisButtonObject.confirm && thisButtonObject.confirm.length > 0) {
let myDialog = this.createBlankDialog();
myDialog.title = "Are you sure you want to make this update?";
myDialog.dialogMessage = thisButtonObject.confirm + '';
myDialog.confirmButton = thisButtonObject.label + '';
myDialog.showDialog = true;
myDialog.maxWidth = 600;
this.setState({
pickedCommand: thisButtonObject,
myDialog: myDialog,
});
}
else {
await this.completeThisQuickUpdate(itemId, thisButtonObject);
}
}
else {
//Don't update item:
}
}
if (thisButtonObject.panelMessage) {
this.setState({
panelMessage: thisButtonObject.panelMessage,
});
}
}
}
async completeThisQuickUpdate(itemId, thisButtonObject) {
/**
* https://github.com/mikezimm/drilldown7/issues/407
* added useWeb update to solve this issue here...
* will also look upstream as well
*/
const { webUrl, listTitle, sourceUserInfo, quickCommands, bannerProps } = this.props;
const useWeb = makeAbsoluteUrl(webUrl);
const result = await updateReactListItem(bannerProps.fpsSpService, useWeb, listTitle, parseInt(itemId), thisButtonObject, sourceUserInfo, this.state.panelItem);
//If success (result is error message and null by default )
// if ( result === null && quickCommands.onUpdateReload === true ) {
/**
* Updated this logic based on returning resultInfo not null for errors:
* https://github.com/mikezimm/fps-library-v2/issues/20
*/
if (quickCommands.successBanner > 0 && result.status === 'Success') {
let updates = Object.keys(thisButtonObject.updateItem).map(k => {
return k;
});
result.statusElement = React.createElement("div", { style: { marginTop: '5px' } },
" ",
[
React.createElement("h3", { key: "h3Finished", style: { paddingTop: '10px' } },
"Finished updating item [ ",
itemId,
" ]"),
React.createElement("div", { key: "bannerIncluding" },
"Including: ",
updates.join(', '),
" ")
]);
quickCommands.refreshCallback(result, false);
//https://github.com/mikezimm/fps-library-v2/issues/20
}
else if (result) {
quickCommands.refreshCallback(result, true);
}
this.setState({
/**
* Added 'as any' to commandResult: result, due to typescript error:
* Types of property 'statusElement' are incompatible.
Type 'IJsxElement' is not assignable to type 'Element'.
Property 'key' is optional in type 'IJsxElement' but required in type 'Element'.ts(2322)
*/
commandResult: result,
commandError: result.status === 'Success' ? false : true,
});
if (result) {
const delay = result.status !== 'Success' ? 10000 : quickCommands.successBanner;
setTimeout(() => {
this.setState({
commandResult: null,
commandError: false,
});
}, delay);
}
}
/**
* private._renderSecurity is found in these two places just slightly different... Going to comment out one in reactListView
* @mikezimm/fps-library-v2/lib\components\molecules\ReactListV1\component\reactListView.tsx
* drilldownwebpart/src\webparts\drilldownV2\components\Drill\drillComponent.tsx
*
* @param item
* @param fieldName
* @returns
*/
/**
* Original from reactListView
*/
// private _renderSecurity = ( item: IAnySourceItemAny , fieldName: string, ) => {
// if ( check4This( Check4.fpsReactRender_Eq_true, false ) ) console.log('_renderSecurity: ', fieldName, item );
// const unique : boolean = item.HasUniqueRoleAssignments === true ? true : false;
// const itemIcon: string = item.HasUniqueRoleAssignments === true ? 'Shield' : item.ItemSharingInfo ? 'Share' : '';
// return ( item: any, index: number ) => {
// const unique = item.HasUniqueRoleAssignments === true ? true : false;
// const itemIcon = item.HasUniqueRoleAssignments === true ? 'Shield' : item.ItemSharingInfo ? 'Share' : '';
// if (check4This( Check4.fpsReactRender_Eq_true, false ) )
// console.log('_renderSecurity: ', fieldName, unique, itemIcon, item);
// return <Icon style={{ color: unique === true ? 'red' : 'gray' }} iconName={ itemIcon } />
// };
// }
/**
* Original from Drilldown
*/
// private _renderSecurity = ( item , fieldName, ) => {
// if ( check4This( 'fpsReactRender=true', false) === true ) console.log('renderExecuted: ', fieldName, item );
// const unique : boolean = item.HasUniqueRoleAssignments === true ? true : false;
// const itemIcon: string = item.HasUniqueRoleAssignments === true ? 'HasUniqueRoleAssignments' : item.ItemSharingInfo ? 'Share' : '';
// return ( item: any, index: number ) => { return <Icon style={{ color: unique === true ? 'red' : 'gray' }} iconName={ itemIcon } /> };
// }
/***
* .d8888. db db .d88b. db d8b db d8888b. .d8b. d8b db d88888b db
* 88' YP 88 88 .8P Y8. 88 I8I 88 88 `8D d8' `8b 888o 88 88' 88
* `8bo. 88ooo88 88 88 88 I8I 88 88oodD' 88ooo88 88V8o 88 88ooooo 88
* `Y8b. 88~~~88 88 88 Y8 I8I 88 88~~~ 88~~~88 88 V8o88 88~~~~~ 88
* db 8D 88 88 `8b d8' `8b d8'8b d8' 88 88 88 88 V888 88. 88booo.
* `8888Y' YP YP `Y88P' `8b8' `8d8' 88 YP YP VP V8P Y88888P Y88888P
*
*
*/
async _onShowPanel(clickType, item, e) {
var _a, _b, _c;
/**
* Had to use this in actual drilldown compiled code or it would not build
var ev = e !== undefined && e !== null
? e
: (window.event !== undefined && window.event !== null
? window.event
: undefined);
*/
const ev = (_a = e !== null && e !== void 0 ? e : window.event) !== null && _a !== void 0 ? _a : undefined;
let isLink = ev && ev.srcElement && ev.srcElement.href && ev.srcElement.href.length > 0 ? true : false;
/*
https://github.com/mikezimm/drilldown7/issues/519
Added this part to trap special triggers like clicking on the Permissions icon
*/
if (clickType === 'Perms' && item.length > 0 && item[0].goToPermsLink) {
ev.preventDefault();
ev.stopPropagation();
window.open(item[0].goToPermsLink, '_blank');
/**
* Added to solve https://github.com/mikezimm/drilldown7/issues/159
* on /sites/ChinaSustainabilitySteeringCommittee/SitePages/Climate-Articles.aspx
* Have never seen this error before. Tried same exact config to same list on another site and do not get the error.
*
*/
}
else if (ev === undefined) {
return;
}
else if ((ev.isCtrlClick === true || ev.ctrlKey === true) && clickType === 'Panel') {
// Skip the initial click and hopefully the onClick from the component kicks in
return;
}
else if (isLink === true) {
window.open(ev.srcElement.href, '_blank');
}
else {
let clickedAttachIcon = ((_c = (_b = ev === null || ev === void 0 ? void 0 : ev.target) === null || _b === void 0 ? void 0 : _b.dataset) === null || _c === void 0 ? void 0 : _c.iconName) === 'Attach' ? true : false;
if (clickedAttachIcon === true || item.length > 0) {
let thisID = clickedAttachIcon === true ? findParentElementPropLikeThis(ev.target, 'id', 'ButtonID', 5, 'begins') : item[0].Id;
thisID = typeof thisID === 'string' ? thisID.replace('ButtonID', '') : thisID;
let panelItem = this._getItemFromId(this.props.items, 'Id', thisID);
let lastPanelId = this.state.panelId;
let clickedAttach = false;
if (ev.srcElement.dataset && ev.srcElement.dataset.iconName === 'Attach') {
clickedAttach = true;
}
await this._createPanelAttachments(thisID, panelItem);
let canShowAPanel = thisID === null || thisID === undefined || panelItem === null ? false : true;
let showFullPanel = canShowAPanel === true && clickedAttach !== true ? true : false;
// 2020-10-13: The last check in this row just didn't seem right... was && this.props.includeListLink === true ? true : false;
let showAttachPanel = canShowAPanel === true && clickedAttach === true && this.props.includeAttach === true ? true : false;
this.setState({
showPanel: showFullPanel,
showAttach: showAttachPanel,
clickedAttach: clickedAttach,
panelId: thisID,
panelItem: panelItem,
lastPanelId: lastPanelId,
panelAttachments: this.state.lastAttachId === thisID ? this.state.panelAttachments : [],
});
}
}
}
_getItemFromId(items, key, val) {
let panelItem = null;
let showIndex = doesObjectExistInArray(this.props.items, key, val, false);
if (showIndex !== false) {
panelItem = this.props.items[showIndex];
// console.log('showPanelPropsItem', panelItem );
}
return panelItem;
}
/***
* d888888b .d88b. d888b d888b db d88888b .d8888.
* `~~88~~' .8P Y8. 88' Y8b 88' Y8b 88 88' 88' YP
* 88 88 88 88 88 88 88ooooo `8bo.
* 88 88 88 88 ooo 88 ooo 88 88~~~~~ `Y8b.
* 88 `8b d8' 88. ~8~ 88. ~8~ 88booo. 88. db 8D
* YP `Y88P' Y888P Y888P Y88888P Y88888P `8888Y'
*
*
*/
getPageToggles() {
let togRefinerCounts = {
//label: <span style={{ color: 'red', fontWeight: 900}}>Rails Off!</span>,
label: React.createElement("span", null, "Panel width"),
key: 'togggleWidth',
_onChange: this.updatePanelWidth.bind(this),
checked: this.state.panelWidth === PanelType.medium ? false : true,
onText: 'Wide',
offText: 'Medium',
className: '',
styles: '',
};
let theseToggles = [];
theseToggles.push(togRefinerCounts);
let pageToggles = {
toggles: theseToggles,
childGap: 10,
vertical: false,
hAlign: 'end',
vAlign: 'start',
rootStyle: { width: 100, paddingTop: 0, paddingRight: 0, }, //This defines the styles on each toggle
};
return pageToggles;
}
updatePanelWidth() {
this.setState({