/Embed/Canvas/demos/PowerParks/ClientApp/src/components/PowerAppsDetails.js

https://github.com/microsoft/PowerApps-Samples · JavaScript · 161 lines · 127 code · 21 blank · 13 comment · 5 complexity · ba4435868e27369d1048442a2e28f749 MD5 · raw file

  1. import React, { Component } from 'react';
  2. import * as PowerAppsSDK from '@microsoft/powerappsauthoringsdk';
  3. import { Stack, StackItem, mergeStyleSets, DefaultPalette, PrimaryButton } from 'office-ui-fabric-react';
  4. let gSdkInited = false;
  5. export class PowerAppsDetails extends Component {
  6. // constructor
  7. constructor(props) {
  8. super(props);
  9. this.AppName = "PowerBucketListBuildDemo";
  10. this.sessionStarted = this.sessionStarted.bind(this);
  11. this.appPublished = this.appPublished.bind(this);
  12. this.appSaved = this.appSaved.bind(this);
  13. this.componentDidMount = this.componentDidMount.bind(this);
  14. this.sessionStarted = this.sessionStarted.bind(this);
  15. this.fillMakerOptions = this.fillMakerOptions.bind(this);
  16. this.onLaunchMaker = this.onLaunchMaker.bind(this);
  17. this.getEmbeddedUrl = this.getEmbeddedUrl.bind(this);
  18. this.renderAuthoring = this.renderAuthoring.bind(this);
  19. this.renderPlayer = this.renderPlayer.bind(this);
  20. this.componentWillUnmount = this.componentWillUnmount.bind(this);
  21. this.state = {
  22. appPublished: false,
  23. appSaved: false,
  24. makerSession: null,
  25. isEditing: false
  26. };
  27. }
  28. async componentDidMount() {
  29. let appId;
  30. // Set the initial state of the component
  31. if (this.props.appID !== "")
  32. appId = window.localStorage.getItem("PowerPark_AppID");
  33. appId = appId ? appId : this.props.appId;
  34. this.setState({
  35. appId: appId ? appId : this.props.appId,
  36. item: this.props.item,
  37. appPublished: appId ? true : false
  38. });
  39. }
  40. componentWillUnmount() {
  41. if (this.state.makerSession !== null) {
  42. this.state.makerSession.disposeAsync();
  43. }
  44. }
  45. styles = mergeStyleSets({
  46. stackRoot: {
  47. },
  48. content: {
  49. display: 'flex',
  50. alignItems: 'center',
  51. justifyContent: 'center',
  52. padding: 10
  53. },
  54. header: {
  55. display: 'flex',
  56. alignItems: 'center',
  57. justifyContent: 'center',
  58. padding: 10
  59. },
  60. item: {
  61. display: 'flex',
  62. alignItems: 'center',
  63. justifyContent: 'center',
  64. padding: 10
  65. }
  66. }
  67. );
  68. appSaved(appInfo) {
  69. this.setState({ appSaved: true });
  70. }
  71. fillMakerOptions() {
  72. let makerOptions = {
  73. formFactor: PowerAppsSDK.FormFactor.Phone
  74. };
  75. if (this.state.appId !== "") {
  76. makerOptions["appId"] = this.state.appId;
  77. }
  78. return makerOptions;
  79. }
  80. // Creates a new PowerApps Studio session
  81. async onLaunchMaker() {
  82. // Step 1: Initialize the SDK
  83. if (!gSdkInited) {
  84. await PowerAppsSDK.initAsync({ hostName: this.AppName });
  85. gSdkInited = true;
  86. }
  87. // Step 2: Set the session options
  88. let sessionOptions = this.fillMakerOptions();
  89. this.setState({ isEditing: true });
  90. // Step 3: Launch the studio
  91. PowerAppsSDK.MakerSession.startAsync(sessionOptions).then(this.sessionStarted);
  92. }
  93. // Step 4: Handle the session starting - update state and subscribe to the published event
  94. sessionStarted(session) {
  95. this.setState({ makerSession: session, appSaved: false, appPublished: false });
  96. session.appPublished.subscribe(this.appPublished);
  97. session.appSaved.subscribe(this.appSaved);
  98. }
  99. // Step 5: Event handler that is called when the user publishes the app in PowerApp Studio
  100. appPublished(appInfo) {
  101. this.state.makerSession.disposeAsync();
  102. this.setState({ makerSession: null, appId: appInfo.appId, appPublished: true, isEditing: false });
  103. if (this.props.onAppUpdated !== null) {
  104. this.props.onAppUpdated(appInfo.appId);
  105. }
  106. }
  107. // Simple rendering describing what is happening with the authoring session
  108. renderAuthoring() {
  109. return (
  110. <StackItem className={this.styles.content} grow disableShrink>
  111. {this.state.makerSession !== null ? "Finish editing your app in the maker studio and publish it to see it here." : "Create a PowerApp for this view by clicking the button below."}
  112. </StackItem>
  113. );
  114. }
  115. // Step 1: Helper method that constructs the URL to the PowerApp, also adds an extra query parameter to force the iframe to refresh
  116. getEmbeddedUrl() {
  117. let rand = Math.floor((Math.random() * 1000) + 1);
  118. // Set the Bing API here
  119. let bingAPIKey = "";
  120. return "https://web.powerapps.com/webplayer/iframeapp?source=builddemo&appId=" + this.state.appId + "&Address=" + encodeURI(this.props.item.address) + "&BingAPIKey=" + bingAPIKey + "&extra=" + rand;
  121. }
  122. // Step 2: Render method for creating the iframe that will host the PowerApps player
  123. renderPlayer() {
  124. return (
  125. <iframe width="100%" height="100%" frameBorder="0" src={this.getEmbeddedUrl()} allow="geolocation https://web.powerapps.com https://preview.web.powerapps.com ; microphone; camera" />
  126. );
  127. }
  128. // Main render method that either renders a prompt to add a PowerApp, or actually renders the PowerApp
  129. render() {
  130. return (
  131. <Stack vertical disableShrink className={this.styles.stackRoot} padding={5} tokens={{ childrenGap: 10 }} >
  132. {this.state.appPublished ?
  133. <StackItem className={this.styles.content} grow disableShrink styles={{ root: { height: 500 } }}> {this.renderPlayer()} </StackItem> :
  134. <StackItem className={this.styles.content} grow disableShrink> {this.renderAuthoring()} </StackItem>
  135. }
  136. <StackItem className={this.styles.item} grow><PrimaryButton disabled={this.state.makerSession !== null} onClick={this.onLaunchMaker} >{this.state.appPublished ? "Edit this app" : "Add a PowerApp"}</PrimaryButton></StackItem>
  137. </Stack>
  138. );
  139. }
  140. }