From 864572b0bfb1323388f388fb4de9adcef837cea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OLIVIER?= Date: Mon, 17 Aug 2020 14:43:16 +0200 Subject: [PATCH 01/10] adding support of decimal + double field types --- QuickEditForm/QuickEditForm/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/QuickEditForm/QuickEditForm/index.ts b/QuickEditForm/QuickEditForm/index.ts index fe4c134..c59df92 100644 --- a/QuickEditForm/QuickEditForm/index.ts +++ b/QuickEditForm/QuickEditForm/index.ts @@ -709,6 +709,8 @@ export class QuickEditForm implements ComponentFramework.StandardControl { if(dataFieldDefinitionsDetails != undefined && fieldDefinition != undefined){ dataFieldDefinitionsDetails.isDirty = true; @@ -733,7 +735,6 @@ export class QuickEditForm implements ComponentFramework.StandardControl Date: Mon, 17 Aug 2020 18:25:21 +0200 Subject: [PATCH 02/10] grab readonly field from qvf for the rendering --- .../QuickEditForm/components/TextFieldControl.tsx | 2 +- QuickEditForm/QuickEditForm/index.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx b/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx index 66b733a..b19b3a9 100644 --- a/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx +++ b/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx @@ -33,7 +33,7 @@ export default class TextFieldControl extends React.Component { if(dataFieldDefinitionsDetails != undefined && fieldDefinition != undefined){ dataFieldDefinitionsDetails.isDirty = true; From fdc2d36f11797b149a0ee9b311912171154c52d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OLIVIER?= Date: Tue, 25 Aug 2020 12:55:41 +0200 Subject: [PATCH 03/10] adding button to open quick create - to be completed --- .../components/MessageBarControl.tsx | 7 ++++++ QuickEditForm/QuickEditForm/index.ts | 22 ++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx b/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx index 251a6f3..ac96e00 100644 --- a/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx +++ b/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; import {MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar'; +import { MessageBarButton } from '@fluentui/react/lib/Button'; export interface IMessageProps { messageType? : MessageBarType; messageText? : string; showMessageBar : boolean; + onClickQuickCreate: () => void; } export interface IMessageState { @@ -34,6 +36,11 @@ export default class MessageBarControl extends React.Component {this.state.showMessageBar && + Open Quick Create Form + + : undefined} messageBarType={this.state.messageType} isMultiline={false} dismissButtonAriaLabel="Close" diff --git a/QuickEditForm/QuickEditForm/index.ts b/QuickEditForm/QuickEditForm/index.ts index e027f6b..5b9208d 100644 --- a/QuickEditForm/QuickEditForm/index.ts +++ b/QuickEditForm/QuickEditForm/index.ts @@ -87,10 +87,10 @@ export class QuickEditForm implements ComponentFramework.StandardControl) { // Add code to update control view - ReactDOM.unmountComponentAtNode(this._container); + /*if(this._context.updatedProperties.length === 1 && this._context.updatedProperties[0] === "layout"){ + return; + }*/ if(this._context.updatedProperties.includes("FieldToAttachControl")){ - //if(this._forceRecordId == context.parameters.FieldToAttachControl.raw! || !this._useTextFieldAsLookup) - // return; if(this._useTextFieldAsLookup) this._forceRecordId = context.parameters.FieldToAttachControl.raw!; } @@ -334,7 +334,19 @@ export class QuickEditForm implements ComponentFramework.StandardControl { + this._context.navigation.openForm({ + entityName : "contact", + useQuickCreateForm: true, + createFromEntity : { + // @ts-ignore + id : this._parentRecordDetails.Id, + name : this._parentRecordDetails.Name, + entityType : this._parentRecordDetails.EntityName + } + }); + } }; if(this._messageComponent != undefined || this._messageComponent != null){ @@ -489,7 +501,7 @@ export class QuickEditForm implements ComponentFramework.StandardControl Date: Tue, 25 Aug 2020 23:07:57 +0200 Subject: [PATCH 04/10] fully functional ! --- .../QuickEditForm/EntitiesDefinition.ts | 2 + .../components/MessageBarControl.tsx | 4 +- .../components/TextFieldControl.tsx | 13 ++-- QuickEditForm/QuickEditForm/index.ts | 66 +++++++++++++++---- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/QuickEditForm/QuickEditForm/EntitiesDefinition.ts b/QuickEditForm/QuickEditForm/EntitiesDefinition.ts index ccb0cf1..18b6d16 100644 --- a/QuickEditForm/QuickEditForm/EntitiesDefinition.ts +++ b/QuickEditForm/QuickEditForm/EntitiesDefinition.ts @@ -3,6 +3,8 @@ export class EntityReferenceInfo{ public Id:string; public Name:string; public Attributes?: any; + public SchemaName?: string; + public QuickCreateEnabled?: boolean; } export class EntityReferenceIdName{ diff --git a/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx b/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx index ac96e00..593846a 100644 --- a/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx +++ b/QuickEditForm/QuickEditForm/components/MessageBarControl.tsx @@ -2,12 +2,12 @@ import * as React from 'react'; import {MessageBar, MessageBarType } from '@fluentui/react/lib/MessageBar'; import { MessageBarButton } from '@fluentui/react/lib/Button'; - export interface IMessageProps { messageType? : MessageBarType; messageText? : string; showMessageBar : boolean; onClickQuickCreate: () => void; + showQuickCreateButton?: boolean; } export interface IMessageState { @@ -36,7 +36,7 @@ export default class MessageBarControl extends React.Component {this.state.showMessageBar && + actions={this.state.messageType == MessageBarType.info && this.props.showQuickCreateButton ?
Open Quick Create Form diff --git a/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx b/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx index b19b3a9..51fdbb9 100644 --- a/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx +++ b/QuickEditForm/QuickEditForm/components/TextFieldControl.tsx @@ -33,7 +33,7 @@ export default class TextFieldControl extends React.Component { - if(this.state.fieldDefinition?.fieldValue?.Name !== undefined) - return this.state.fieldDefinition?.fieldValue?.Name; + let result = ""; + if(this.state.fieldDefinition?.fieldValue?.Name != undefined) { + result = this.state.fieldDefinition?.fieldValue?.Name; + } + else { + result = this.state.fieldDefinition?.fieldValue; + } - return this.state.fieldDefinition?.fieldValue; + return result; } private onDoubleClick = (event: React.MouseEvent) : void => { diff --git a/QuickEditForm/QuickEditForm/index.ts b/QuickEditForm/QuickEditForm/index.ts index 5b9208d..8837dd0 100644 --- a/QuickEditForm/QuickEditForm/index.ts +++ b/QuickEditForm/QuickEditForm/index.ts @@ -13,6 +13,7 @@ import { IDropdownOption } from "@fluentui/react/lib/Dropdown"; import { MessageBarType } from "@fluentui/react/lib/MessageBar"; import { EntityReferenceInfo, DataFieldDefinition} from "./EntitiesDefinition"; +import { unwatchFile } from "fs"; export class QuickEditForm implements ComponentFramework.StandardControl { @@ -87,9 +88,10 @@ export class QuickEditForm implements ComponentFramework.StandardControl) { // Add code to update control view - /*if(this._context.updatedProperties.length === 1 && this._context.updatedProperties[0] === "layout"){ + if(this._context.updatedProperties.length === 1 && this._context.updatedProperties[0] === "layout"){ return; - }*/ + } + if(this._context.updatedProperties.includes("FieldToAttachControl")){ if(this._useTextFieldAsLookup) this._forceRecordId = context.parameters.FieldToAttachControl.raw!; @@ -330,14 +332,15 @@ export class QuickEditForm implements ComponentFramework.StandardControl { this._context.navigation.openForm({ - entityName : "contact", + entityName : _this._recordToUpdate.EntityName, useQuickCreateForm: true, createFromEntity : { // @ts-ignore @@ -345,6 +348,30 @@ export class QuickEditForm implements ComponentFramework.StandardControl 1){ + return; + } + + let savedRecord = data.savedEntityReference[0]; + let dataToUpdate : any = {}; + dataToUpdate[_this._recordToUpdate.SchemaName!+"@odata.bind"] = `/${_this.getEntityPluralName(savedRecord.entityType)}(${savedRecord.id.slice(1,-1)})`; + _this._context.webAPI.updateRecord(_this._parentRecordDetails.EntityName, _this._parentRecordDetails.Id, dataToUpdate).then( + function success(result){ + console.log(result); + _this.displayMessage(MessageBarType.success, "Record successfully created, please refresh in order to see the newly created record."); + }, + function (error){ + // Error.code for privilege + if(error.code != undefined && error.code == 2147746336){ + _this.displayMessage(MessageBarType.blocked, `${_this._context.resources.getString("UpdateErrorMessage")}\n\r${_this._context.resources.getString("MissingPrivilegeOnRecordMessage")}.\n\r${error.message}`); + } else{ + _this.displayMessage(MessageBarType.blocked, `${_this._context.resources.getString("UpdateErrorMessage")}\n\r${error.message}`); + } + + _this._updateError = true; + } + ); }); } }; @@ -358,7 +385,6 @@ export class QuickEditForm implements ComponentFramework.StandardControl { + let relationships = em.ManyToOneRelationships.getAll(); + let relationshipDetails = relationships.filter(function(relation : any){ + return relation._referencingAttribute === lookupCleaned; + })[0]; + + this._recordToUpdate.SchemaName = relationshipDetails?.ReferencingEntityNavigationPropertyName; + this._recordToUpdate.EntityName = relationshipDetails?.ReferencedEntity; + this._recordToUpdate.QuickCreateEnabled = em.IsQuickCreateEnabled as boolean; + + // displaying message to warn user that lookup is empty + this.displayMessage(MessageBarType.info, _this._context.resources.getString("LookupFieldHasNoValue").replace("{0}", this._context.parameters.LookupFieldMapped.raw!)); + this._renderingInProgress = false; + this.showLoading(false); + }); } } @@ -633,7 +677,7 @@ export class QuickEditForm implements ComponentFramework.StandardControl Date: Wed, 26 Aug 2020 22:55:48 +0200 Subject: [PATCH 05/10] handling multi columns --- .../QuickEditForm/ControlManifest.Input.xml | 1 + QuickEditForm/QuickEditForm/index.ts | 76 ++++++++++++------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/QuickEditForm/QuickEditForm/ControlManifest.Input.xml b/QuickEditForm/QuickEditForm/ControlManifest.Input.xml index 3e80fab..0965929 100644 --- a/QuickEditForm/QuickEditForm/ControlManifest.Input.xml +++ b/QuickEditForm/QuickEditForm/ControlManifest.Input.xml @@ -9,6 +9,7 @@ true false + @@ -20,6 +20,9 @@ SingleLine.Email SingleLine.Text SingleLine.Phone + SingleLine.TextArea + SingleLine.URL + Multiple diff --git a/AnyCompositeFields/AnyCompositeFIelds/components/CompositeControl.tsx b/AnyCompositeFields/AnyCompositeFIelds/components/CompositeControl.tsx index b5ed21c..540e70c 100644 --- a/AnyCompositeFields/AnyCompositeFIelds/components/CompositeControl.tsx +++ b/AnyCompositeFields/AnyCompositeFIelds/components/CompositeControl.tsx @@ -56,7 +56,7 @@ export default class CompositeControl extends React.Component this.setState({ showCallout : false }) } + onDismiss={this.onDismissCallout} styles={calloutStyles} directionalHint={DirectionalHint.topCenter} > @@ -91,6 +91,12 @@ export default class CompositeControl extends React.Component { + if(this.props.context?.client.getClient() !== "Mobile"){ + this.setState({ showCallout : false }); + } + } + private onChangeField = (event: React.FormEvent, newValue?: string | undefined) : void => { // @ts-ignore let target = event.target.id.replace('acf_', ''); @@ -130,6 +136,7 @@ export default class CompositeControl extends React.Component