├── .babelrc ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ └── release.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── .releaserc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── bundle.js ├── bundle.js.LICENSE.txt └── index.html ├── package-lock.json ├── package.json ├── src ├── docs │ ├── App.jsx │ ├── CreateReport │ │ ├── Form.jsx │ │ └── index.jsx │ ├── Dashboard │ │ ├── Form.jsx │ │ └── index.jsx │ ├── MultiplePageDemo │ │ ├── Form.jsx │ │ └── index.jsx │ ├── Report │ │ ├── Form.jsx │ │ └── index.jsx │ ├── ReportVisual │ │ ├── Form.jsx │ │ └── index.jsx │ ├── Tile │ │ ├── Form.jsx │ │ └── index.jsx │ ├── UseBootstrapDemo │ │ ├── Form.jsx │ │ └── index.jsx │ ├── UseReportDemo │ │ ├── Form.jsx │ │ └── index.jsx │ ├── common │ │ ├── Footer.jsx │ │ ├── FormButtonGroup.jsx │ │ ├── FormButtonGroupBootstrap.jsx │ │ ├── Header.jsx │ │ ├── InfoTab.jsx │ │ └── SideNav.jsx │ ├── hooks │ │ └── useLocalStorage.jsx │ ├── index.css │ ├── index.html │ ├── index.jsx │ ├── styles │ │ └── formLayoutStyles.js │ └── utils.js └── lib │ ├── Dashboard.tsx │ ├── Embed.tsx │ ├── Report.tsx │ ├── ReportVisual.tsx │ ├── Tile.tsx │ ├── hooks │ └── useReport.ts │ ├── index.tsx │ ├── types.ts │ └── utils │ ├── config.ts │ ├── index.ts │ └── onEmbedHandlers.ts ├── tsconfig.json └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/env", 4 | "@babel/react" 5 | ], 6 | "plugins": [ 7 | "@babel/plugin-proposal-class-properties", 8 | "@babel/plugin-transform-runtime" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | text=auto 2 | text eol=lf 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: akshay5995 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: '' 6 | assignees: akshay5995 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "23:30" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: antd 11 | versions: 12 | - 4.11.2 13 | - 4.12.0 14 | - 4.12.1 15 | - 4.12.2 16 | - 4.12.3 17 | - 4.13.0 18 | - 4.13.1 19 | - 4.14.0 20 | - 4.14.1 21 | - 4.15.0 22 | - 4.15.1 23 | - 4.15.2 24 | - dependency-name: css-loader 25 | versions: 26 | - 5.0.1 27 | - 5.0.2 28 | - 5.1.0 29 | - 5.1.1 30 | - 5.1.2 31 | - 5.1.3 32 | - 5.2.0 33 | - 5.2.1 34 | - dependency-name: "@babel/core" 35 | versions: 36 | - 7.12.10 37 | - 7.12.13 38 | - 7.12.16 39 | - 7.12.17 40 | - 7.13.0 41 | - 7.13.1 42 | - 7.13.10 43 | - 7.13.13 44 | - 7.13.14 45 | - 7.13.15 46 | - 7.13.8 47 | - dependency-name: concurrently 48 | versions: 49 | - 5.3.0 50 | - 6.0.0 51 | - 6.0.1 52 | - dependency-name: y18n 53 | versions: 54 | - 4.0.1 55 | - dependency-name: html-webpack-plugin 56 | versions: 57 | - 4.5.1 58 | - dependency-name: elliptic 59 | versions: 60 | - 6.5.3 61 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: '16.x' 16 | - name: Intall dependencies 17 | run: npm install --frozen-lockfile 18 | - name: Build lib 19 | run: npm run lib 20 | - name: Build docs 21 | run: npm run docs:prod 22 | - name: Deploy docs 23 | run: | 24 | git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git 25 | npx gh-pages -d docs -u "github-actions-bot " 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | - name: Publish library 29 | run: npm run publish:lib 30 | env: 31 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /lib 3 | **/.DS_Store 4 | .idea/* 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | docs 2 | src 3 | .babelrc 4 | webpack.config.js 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "printWidth": 72 7 | } 8 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "main", 4 | "next" 5 | ], 6 | "plugins": [ 7 | "@semantic-release/commit-analyzer", 8 | "@semantic-release/release-notes-generator", 9 | [ 10 | "@semantic-release/npm", 11 | { 12 | "npmPublish": true, 13 | "tarballDir": "lib" 14 | } 15 | ], 16 | [ 17 | "@semantic-release/git", 18 | { 19 | "assets": [ 20 | "lib/**/*.{js,css}", 21 | "docs", 22 | "package.json" 23 | ], 24 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 25 | } 26 | ] 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Steps to contribute 2 | 3 | 1. Fork the repo 4 | 2. Create a new PR with description of your changes and why it's needed 5 | 3. Wait ~1 day to get your changes reviewed 6 | 4. Once the comments are fixed and PR is merged new version of package will be deployed 7 | 8 | 9 | # Development 10 | 11 | `npm run dev` 12 | 13 | `lib` folder for package changes 14 | 15 | `docs` folder for demo site and testing your changes in local 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Akshay Ram Vignesh A 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerBI Report Component 2 | 3 | ![downloads](https://img.shields.io/npm/dw/powerbi-report-component?label=npm%20downloads&style=for-the-badge) 4 | ![license](https://img.shields.io/github/license/akshay5995/powerbi-report-component?color=blue&style=for-the-badge) 5 | ![vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/akshay5995/powerbi-report-component?style=for-the-badge) 6 | ![bundlephobia](https://badgen.net/bundlephobia/minzip/powerbi-report-component) 7 | 8 | It's a minimalistic React component for embedding a Microsoft PowerBI report, dashboard or tile into your React application. 9 | 10 | ## Installation 11 | 12 | `npm i powerbi-report-component` 13 | 14 | ## Usage for Report 15 | 16 | ```javascript 17 | import React, {Component} from 'react'; 18 | import { Report } from 'powerbi-report-component'; 19 | 20 | class MyComponent extends Component { 21 | constructor(props) { 22 | super(props); 23 | this.report = null; // to store the loaded report's object to perform operations like print, full screen etc.. 24 | } 25 | ... 26 | handleDataSelected = (data) => { 27 | // will be called when some chart or data element in your report clicked 28 | } 29 | 30 | handleReportLoad = (report) => { 31 | // will be called when report loads: 32 | // - scripts and data received from server, visuals are rendered on the browser 33 | // - flickering Power BI logo stops appearing but report is not fully ready to be consumed 34 | 35 | this.report = report; // get the report object from callback and store it.(optional) 36 | } 37 | 38 | handleReportRender = (report) => { 39 | // will be called when report renders: 40 | // - visuals finish rendering 41 | // - report is fully visible and ready for consumption 42 | 43 | this.report = report; // get the report object from callback and store it.(optional) 44 | } 45 | 46 | handlePageChange = (data) => { 47 | // will be called when pages in your report changes 48 | } 49 | 50 | handleTileClicked = (data) => { 51 | console.log('Data from tile', data); 52 | } 53 | 54 | render() { 55 | const reportStyle = { 56 | // style object for report component 57 | }; 58 | const extraSettings = { 59 | filterPaneEnabled: false, //true 60 | navContentPaneEnabled: false, //true 61 | hideErrors: false // Use this *only* when you want to override error experience i.e, use onError 62 | // ... more custom settings 63 | }; 64 | return ( 65 |
66 | 85 |
86 | ); 87 | } 88 | } 89 | 90 | ``` 91 | 92 | Visit [here](https://docs.microsoft.com/en-us/rest/api/power-bi/embedtoken/generatetoken#generatetokenrequestv2) for more details on creating reports with shared dataset 93 | 94 | ## Usage for Dashboard 95 | 96 | ```javascript 97 | import { Dashboard } from 'powerbi-report-component'; 98 | 99 | // inside render 100 | { 108 | console.log('Dashboard Loaded!'); 109 | this.dashboard = dashboard; // get the dashboard object from callback and store it.(optional) 110 | }} 111 | onTileClicked={(data) => { 112 | console.log('Data from tile', data); 113 | }} 114 | /> 115 | ``` 116 | 117 | ## Usage for Tile 118 | 119 | ```javascript 120 | import { Tile } from 'powerbi-report-component'; 121 | 122 | // inside render 123 | { 131 | console.log('Data from tile', data); 132 | }} 133 | onLoad={(data) => { 134 | console.log('Tile loaded', data); 135 | }} 136 | /> 137 | ``` 138 | 139 | ## Usage for ReportVisual 140 | 141 | ```javascript 142 | import { ReportVisual } from 'powerbi-report-component'; 143 | 144 | // inside render 145 | { 154 | console.log('Data from ReportVisual', data); 155 | }} 156 | onLoad={(reportVisual) => { 157 | console.log('ReportVisual loaded', data); 158 | }} 159 | onRender={(reportVisual) => { 160 | console.log('ReportVisual rendered', reportVisual); 161 | }} 162 | /> 163 | ``` 164 | 165 | ## Like hooks ? You'll love this :) 166 | 167 | ### useReport 168 | 169 | Provides a more fine grained approach for embedding. (where you're in control) 170 | 171 | ```javascript 172 | import React, { useEffect, useRef } from 'react'; 173 | import { useReport } from 'powerbi-report-component'; 174 | 175 | const MyReport = ({ accessToken, embedUrl, embedId }) => { 176 | const reportRef = useRef(null); 177 | const [report, embed] = useReport(); 178 | 179 | const myReportConfig = { 180 | embedType: 'report', 181 | tokenType: 'Embed', 182 | accessToken: accessToken, 183 | embedUrl: embedUrl, 184 | embedId: embedId, 185 | reportMode: "View", // "Edit" 186 | permissions: "View", // "All" (when using "Edit" mode) 187 | extraSettings: { 188 | filterPaneEnabled: false, 189 | navContentPaneEnabled: false, 190 | }, 191 | }; 192 | 193 | // important 194 | useEffect(() => { 195 | // call inside useEffect so the we have the reportRef (reference available) 196 | embed(reportRef, myReportConfig); 197 | }, []); 198 | 199 | const handleClick = () => { 200 | // you can use "report" from useReport like 201 | if (report) report.print(); 202 | }; 203 | 204 | return ( 205 |
206 |
207 | 208 |
209 | ); 210 | }; 211 | 212 | export default MyReport; 213 | ``` 214 | 215 | #### Passing in custom layout for useReport hook. 216 | 217 | Example is taken from powerbi js wiki: [Custom-Layout](https://github.com/Microsoft/PowerBI-JavaScript/wiki/Custom-Layout). 218 | 219 | ```javascript 220 | import { models } from 'powerbi-client'; // Import from the dependency 221 | 222 | // Example layout config 223 | const layoutSettings = { 224 | layoutType: models.LayoutType.Custom, 225 | customLayout: { 226 | pageSize: { 227 | type: models.PageSizeType.Custom, 228 | width: 1600, 229 | height: 1200, 230 | }, 231 | displayOption: models.DisplayOption.ActualSize, 232 | pagesLayout: { 233 | ReportSection1: { 234 | defaultLayout: { 235 | displayState: { 236 | mode: models.VisualContainerDisplayMode.Hidden, 237 | }, 238 | }, 239 | visualsLayout: { 240 | VisualContainer1: { 241 | x: 1, 242 | y: 1, 243 | z: 1, 244 | width: 400, 245 | height: 300, 246 | displayState: { 247 | mode: models.VisualContainerDisplayMode.Visible, 248 | }, 249 | }, 250 | VisualContainer2: { 251 | displayState: { 252 | mode: models.VisualContainerDisplayMode.Visible, 253 | }, 254 | }, 255 | }, 256 | }, 257 | }, 258 | }, 259 | }; 260 | 261 | // Create your config 262 | const myReportConfig = { 263 | embedType: 'report', 264 | tokenType: 'Embed', 265 | accessToken: accessToken, 266 | embedUrl: embedUrl, 267 | embedId: embedId, 268 | extraSettings: { 269 | filterPaneEnabled: false, 270 | navContentPaneEnabled: false, 271 | ...layoutSettings, // layout config 272 | }, 273 | }; 274 | 275 | 276 | // Inside your component 277 | useEffect(() => { 278 | embed(reportRef, myReportConfig); 279 | }, []); 280 | 281 | ``` 282 | 283 | ### useBootstrap 284 | 285 | Provided performance gains on loading in an async way 286 | 287 | ```javascript 288 | import React, { useEffect, useRef } from 'react'; 289 | import { useBootstrap } from 'powerbi-report-component'; 290 | 291 | // Your configuration from server 292 | const simulateAjaxCall = () => new Promise(function(resolve) { 293 | setTimeout(resolve.bind(null, { 294 | accessToken: "accessToken", 295 | embedUrl: "embedUrl", 296 | embedId: "embedId", 297 | reportMode: "View", // "Edit" 298 | permissions: "View", // "All" (when using "Edit" mode) 299 | }), 3000) 300 | }); 301 | 302 | 303 | const MyReport = ({ accessToken, embedUrl, embedId }) => { 304 | const reportRef = useRef(null); 305 | const [report, bootstrap, embed] = useBootstrap(); 306 | 307 | const initialReportConfig = { 308 | embedType: 'report', 309 | tokenType: 'Embed', 310 | extraSettings: { 311 | filterPaneEnabled: false, 312 | navContentPaneEnabled: false, 313 | }, 314 | }; 315 | 316 | const getMyConfigurationFromServer = () => { 317 | simulateAjaxCall().then(data => { 318 | // Embed the report once your configuration is received 319 | embed(reportRef, {...initialReportConfig, ...data}); 320 | }); 321 | } 322 | 323 | // important 324 | useEffect(() => { 325 | // call inside useEffect so the we have the reportRef (reference available) 326 | bootstrap(reportRef, initialReportConfig); 327 | }, []); 328 | 329 | return ( 330 |
331 |
332 | 333 |
334 | ); 335 | }; 336 | 337 | export default MyReport; 338 | ``` 339 | 340 | ## Report features and props you can pass into the component 341 | 342 | Inside your component where you're using { Report } component. 343 | 344 | _Constructor:_ 345 | 346 | ```javascript 347 | ... 348 | constructor(props) { 349 | super(props); 350 | this.report = null; //used to store value of returned report object 351 | } 352 | .... 353 | 354 | ``` 355 | 356 | _Callback passed to the onLoad or onRender prop_ 357 | 358 | ```javascript 359 | handleReportLoad = (report) => { 360 | this.report = report; // get the report object from callback and store it. 361 | } 362 | 363 | handleReportRender = (report) => { 364 | this.report = report; // get the report object from callback and store it. 365 | } 366 | ... 367 | ``` 368 | 369 | _using the_ this.report _to perform operations_ 370 | 371 | ```javascript 372 | ... 373 | 374 | setFullscreen = () => { 375 | if(this.report) this.report.fullscreen(); 376 | } 377 | 378 | printReport = () => { 379 | if(this.report) this.report.print(); 380 | } 381 | 382 | ... 383 | 384 | //Inside render 385 | 386 | 387 | 388 | 389 | ... 390 | 391 | ``` 392 | 393 | For Report Level Filters: 394 | 395 | ```javascript 396 | /* 397 | Example filter object used in microsoft's demo page: 398 | 399 | const filter = { 400 | $schema: "http://powerbi.com/product/schema#basic", 401 | target: { 402 | table: "Store", 403 | column: "Chain" 404 | }, 405 | operator: "In", 406 | values: ["Lindseys"] 407 | }; 408 | */ 409 | ... 410 | 411 | setFilter = (filter) => this.report.setFilters([filter]).catch(function (errors) { 412 | console.log(errors); 413 | }); 414 | 415 | getFilter = () => this.report.getFilters().then(function (filters) { 416 | console.log(filters); 417 | }).catch(function (errors) { 418 | console.log(errors); 419 | }); 420 | 421 | removeFilters = () => this.report.removeFilters() 422 | .catch(function (errors) { 423 | console.log(errors); 424 | }); 425 | 426 | ... 427 | 428 | ``` 429 | 430 | Report Page Change 431 | 432 | ```javascript 433 | onPageChange={(data) => 434 | console.log(`Page name :{data.newPage.displayName}`) 435 | } 436 | ``` 437 | 438 | Report Load 439 | 440 | ```javascript 441 | onLoad={(report) => { 442 | console.log('Report Loaded!'); 443 | this.report = report; 444 | } 445 | } 446 | ``` 447 | 448 | ```javascript 449 | onSave={(data) => { 450 | console.log('Report Saved! Event data: '+data); 451 | } 452 | } 453 | ``` 454 | 455 | Report Render 456 | 457 | ```javascript 458 | onRender={(report) => { 459 | console.log('Report Rendered!'); 460 | this.report = report; 461 | } 462 | } 463 | ``` 464 | 465 | Report Button Clicked 466 | 467 | ```javascript 468 | onButtonClicked={(data) => { 469 | console.log(`Button ${data.title} of type ${data.type} Clicked!`); 470 | } 471 | } 472 | ``` 473 | 474 | Report Command Triggered 475 | 476 | ```javascript 477 | onCommandTriggered={(extensionCommand) => { 478 | console.log('Extension Command Triggered!'); 479 | } 480 | } 481 | ``` 482 | 483 | Report Data Element Clicked 484 | 485 | ```javascript 486 | onSelectData={(data) => 487 | console.log(`You clicked on chart: ${data.visual.title}`); 488 | } 489 | ``` 490 | 491 | Report Handle Errors 492 | 493 | ```javascript 494 | onError={(data) => 495 | console.log(`Error: ${data}`); 496 | } 497 | ``` 498 | 499 | Use ‘report’ object returned to parent component or from `useReport` for: 500 | 501 | Note: you wouldn't use `this` if you're using `report` from `useReport` hook. 502 | 503 | 1. Change Report Mode to View or Edit: 504 | 505 | ```javascript 506 | //mode can be "View" or "Edit" 507 | 508 | changeMode = (mode) => this.report.switchMode(mode); 509 | ``` 510 | 511 | 2. Fullscreen 512 | 513 | ```javascript 514 | setFullscreen = () => this.report.fullscreen(); 515 | ``` 516 | 517 | 3. Print Report 518 | 519 | ```javascript 520 | printReport = () => this.report.print(); 521 | ``` 522 | 523 | 4. Set Filters 524 | 525 | ```javascript 526 | //example filter from microsoft's demo page 527 | 528 | const filter = { 529 | $schema: "http://powerbi.com/product/schema#basic", 530 | target: { 531 | table: "Store", 532 | column: "Chain" 533 | }, 534 | operator: "In", 535 | values: ["Lindseys"] 536 | }; 537 | 538 | // using event handlers 539 | 540 | setFilter = (filter) => this.report.setFilters([filter]).catch(function (errors) { 541 | console.log(errors); 542 | }); 543 | 544 | // during onload 545 | 546 | onLoad = (report) => { 547 | report.setFilters([filter]).catch(function (errors) { 548 | console.log(errors); 549 | }); 550 | this.report = report; 551 | } 552 | } 553 | 554 | ``` 555 | 556 | 5. Get Filters 557 | 558 | ```javascript 559 | getFilter = () => 560 | this.report 561 | .getFilters() 562 | .then(function (filters) { 563 | console.log(filters); 564 | }) 565 | .catch(function (errors) { 566 | console.log(errors); 567 | }); 568 | ``` 569 | 570 | 6. Remove Filters 571 | 572 | ```javascript 573 | removeFilters = () => 574 | this.report.removeFilters().catch(function (errors) { 575 | console.log(errors); 576 | }); 577 | ``` 578 | 579 | 7. Save edited report when in "Edit" mode 580 | 581 | (note: you need to have enough permissions to save the report) 582 | 583 | ```javascript 584 | async saveReport() { 585 | if (this.report) { 586 | try{ 587 | await this.report.save(); 588 | } catch (err) { 589 | console.log("Error saving report", err); 590 | } 591 | } 592 | } 593 | 594 | ``` 595 | 596 | 8. Show / Hide all visual headers: 597 | 598 | ```javascript 599 | toggleAllVisualHeaders = (bool) => { 600 | const newSettings = { 601 | visualSettings: { 602 | visualHeaders: [ 603 | { 604 | settings: { 605 | visible: bool, // boolean variable 606 | }, 607 | }, 608 | ], 609 | }, 610 | }; 611 | this.report 612 | .updateSettings(newSettings) 613 | .then(function () { 614 | console.log('Visual header toggle successful.'); 615 | }) 616 | .catch(function (errors) { 617 | console.log(errors); 618 | }); 619 | }; 620 | ``` 621 | 622 | ## Dashboard features and props you can pass into the component 623 | 624 | Dashboard Load 625 | 626 | ```javascript 627 | onLoad={(dashboard) => { 628 | console.log('Report Loaded!'); 629 | this.dashboard = dashboard; 630 | } 631 | } 632 | ``` 633 | 634 | Dashboard Tile Click 635 | 636 | ```javascript 637 | onTileClicked = {(data) => { 638 | console.log('Data from tile', data); 639 | }} 640 | ``` 641 | 642 | Use dashboard object returned to parent component for: 643 | 644 | 1. Fullscreen 645 | 646 | ```javascript 647 | setFullscreen = () => this.dashboard.fullscreen(); 648 | ``` 649 | 650 | ## Tile features and props you can pass into the component 651 | 652 | Tile Load 653 | 654 | ```javascript 655 | onLoad={(data) => { 656 | console.log('Data from tile', data); 657 | }} 658 | ``` 659 | 660 | Tile Click 661 | 662 | ```javascript 663 | onClick = {(data) => { 664 | console.log('Data from tile', data); 665 | }} 666 | ``` 667 | 668 | For playground visit: 669 | 670 | > http://akshay5995.github.io/powerbi-report-component 671 | 672 | You can find out how to generate token for your report using Powershell from [this video](https://www.youtube.com/watch?v=4KuyPNtVijo). 673 | 674 | ### Alternatives 675 | 676 | 1. https://github.com/microsoft/powerbi-client-react ![bundlephobia](https://badgen.net/bundlephobia/minzip/powerbi-client-react) 677 | -------------------------------------------------------------------------------- /docs/bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | Copyright (c) 2018 Jed Watson. 9 | Licensed under the MIT License (MIT), see 10 | http://jedwatson.github.io/classnames 11 | */ 12 | 13 | /*! 14 | * The buffer module from node.js, for the browser. 15 | * 16 | * @author Feross Aboukhadijeh 17 | * @license MIT 18 | */ 19 | 20 | /*! ./../process/browser.js */ 21 | 22 | /*! ./../webpack/buildin/global.js */ 23 | 24 | /*! ./FilterBuilders */ 25 | 26 | /*! ./advancedFilterBuilder */ 27 | 28 | /*! ./basicFilterBuilder */ 29 | 30 | /*! ./bookmarksManager */ 31 | 32 | /*! ./config */ 33 | 34 | /*! ./create */ 35 | 36 | /*! ./dashboard */ 37 | 38 | /*! ./embed */ 39 | 40 | /*! ./errors */ 41 | 42 | /*! ./factories */ 43 | 44 | /*! ./filterBuilder */ 45 | 46 | /*! ./page */ 47 | 48 | /*! ./qna */ 49 | 50 | /*! ./relativeDateFilterBuilder */ 51 | 52 | /*! ./relativeTimeFilterBuilder */ 53 | 54 | /*! ./report */ 55 | 56 | /*! ./service */ 57 | 58 | /*! ./support/isBuffer */ 59 | 60 | /*! ./tile */ 61 | 62 | /*! ./topNFilterBuilder */ 63 | 64 | /*! ./util */ 65 | 66 | /*! ./visual */ 67 | 68 | /*! ./visualDescriptor */ 69 | 70 | /*! assert */ 71 | 72 | /*! http-post-message */ 73 | 74 | /*! http-post-message v0.2.3 | (c) 2016 Microsoft Corporation MIT */ 75 | 76 | /*! inherits */ 77 | 78 | /*! no static exports found */ 79 | 80 | /*! object-assign */ 81 | 82 | /*! powerbi-models */ 83 | 84 | /*! powerbi-router */ 85 | 86 | /*! powerbi-router v0.1.5 | (c) 2016 Microsoft Corporation MIT */ 87 | 88 | /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ 89 | 90 | /*! util/ */ 91 | 92 | /*! window-post-message-proxy */ 93 | 94 | /*! window-post-message-proxy v0.2.6 | (c) 2016 Microsoft Corporation MIT */ 95 | 96 | /*!********************!*\ 97 | !*** ./src/qna.ts ***! 98 | \********************/ 99 | 100 | /*!*********************!*\ 101 | !*** ./src/page.ts ***! 102 | \*********************/ 103 | 104 | /*!*********************!*\ 105 | !*** ./src/tile.ts ***! 106 | \*********************/ 107 | 108 | /*!*********************!*\ 109 | !*** ./src/util.ts ***! 110 | \*********************/ 111 | 112 | /*!**********************!*\ 113 | !*** ./src/embed.ts ***! 114 | \**********************/ 115 | 116 | /*!***********************!*\ 117 | !*** ./src/config.ts ***! 118 | \***********************/ 119 | 120 | /*!***********************!*\ 121 | !*** ./src/create.ts ***! 122 | \***********************/ 123 | 124 | /*!***********************!*\ 125 | !*** ./src/errors.ts ***! 126 | \***********************/ 127 | 128 | /*!***********************!*\ 129 | !*** ./src/report.ts ***! 130 | \***********************/ 131 | 132 | /*!***********************!*\ 133 | !*** ./src/visual.ts ***! 134 | \***********************/ 135 | 136 | /*!************************!*\ 137 | !*** ./src/service.ts ***! 138 | \************************/ 139 | 140 | /*!**************************!*\ 141 | !*** ./src/dashboard.ts ***! 142 | \**************************/ 143 | 144 | /*!**************************!*\ 145 | !*** ./src/factories.ts ***! 146 | \**************************/ 147 | 148 | /*!*******************************!*\ 149 | !*** ./src/powerbi-client.ts ***! 150 | \*******************************/ 151 | 152 | /*!*********************************!*\ 153 | !*** ./src/bookmarksManager.ts ***! 154 | \*********************************/ 155 | 156 | /*!*********************************!*\ 157 | !*** ./src/visualDescriptor.ts ***! 158 | \*********************************/ 159 | 160 | /*!***********************************!*\ 161 | !*** (webpack)/buildin/global.js ***! 162 | \***********************************/ 163 | 164 | /*!***********************************!*\ 165 | !*** ./node_modules/util/util.js ***! 166 | \***********************************/ 167 | 168 | /*!*************************************!*\ 169 | !*** ./src/FilterBuilders/index.ts ***! 170 | \*************************************/ 171 | 172 | /*!***************************************!*\ 173 | !*** ./node_modules/assert/assert.js ***! 174 | \***************************************/ 175 | 176 | /*!*****************************************!*\ 177 | !*** ./node_modules/process/browser.js ***! 178 | \*****************************************/ 179 | 180 | /*!*********************************************!*\ 181 | !*** ./node_modules/object-assign/index.js ***! 182 | \*********************************************/ 183 | 184 | /*!*********************************************!*\ 185 | !*** ./src/FilterBuilders/filterBuilder.ts ***! 186 | \*********************************************/ 187 | 188 | /*!*************************************************!*\ 189 | !*** ./src/FilterBuilders/topNFilterBuilder.ts ***! 190 | \*************************************************/ 191 | 192 | /*!**************************************************!*\ 193 | !*** ./src/FilterBuilders/basicFilterBuilder.ts ***! 194 | \**************************************************/ 195 | 196 | /*!****************************************************!*\ 197 | !*** ./node_modules/powerbi-models/dist/models.js ***! 198 | \****************************************************/ 199 | 200 | /*!****************************************************!*\ 201 | !*** ./node_modules/powerbi-router/dist/router.js ***! 202 | \****************************************************/ 203 | 204 | /*!*****************************************************!*\ 205 | !*** ./src/FilterBuilders/advancedFilterBuilder.ts ***! 206 | \*****************************************************/ 207 | 208 | /*!******************************************************!*\ 209 | !*** ./node_modules/util/support/isBufferBrowser.js ***! 210 | \******************************************************/ 211 | 212 | /*!*********************************************************!*\ 213 | !*** ./src/FilterBuilders/relativeDateFilterBuilder.ts ***! 214 | \*********************************************************/ 215 | 216 | /*!*********************************************************!*\ 217 | !*** ./src/FilterBuilders/relativeTimeFilterBuilder.ts ***! 218 | \*********************************************************/ 219 | 220 | /*!****************************************************************!*\ 221 | !*** ./node_modules/http-post-message/dist/httpPostMessage.js ***! 222 | \****************************************************************/ 223 | 224 | /*!*********************************************************************!*\ 225 | !*** ./node_modules/util/node_modules/inherits/inherits_browser.js ***! 226 | \*********************************************************************/ 227 | 228 | /*!*******************************************************************************!*\ 229 | !*** ./node_modules/window-post-message-proxy/dist/windowPostMessageProxy.js ***! 230 | \*******************************************************************************/ 231 | 232 | /** @license React v0.20.2 233 | * scheduler.production.min.js 234 | * 235 | * Copyright (c) Facebook, Inc. and its affiliates. 236 | * 237 | * This source code is licensed under the MIT license found in the 238 | * LICENSE file in the root directory of this source tree. 239 | */ 240 | 241 | /** @license React v16.13.1 242 | * react-is.production.min.js 243 | * 244 | * Copyright (c) Facebook, Inc. and its affiliates. 245 | * 246 | * This source code is licensed under the MIT license found in the 247 | * LICENSE file in the root directory of this source tree. 248 | */ 249 | 250 | /** @license React v17.0.2 251 | * react-dom.production.min.js 252 | * 253 | * Copyright (c) Facebook, Inc. and its affiliates. 254 | * 255 | * This source code is licensed under the MIT license found in the 256 | * LICENSE file in the root directory of this source tree. 257 | */ 258 | 259 | /** @license React v17.0.2 260 | * react.production.min.js 261 | * 262 | * Copyright (c) Facebook, Inc. and its affiliates. 263 | * 264 | * This source code is licensed under the MIT license found in the 265 | * LICENSE file in the root directory of this source tree. 266 | */ 267 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Power Bi Embed Demo
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "powerbi-report-component", 3 | "version": "2.6.1", 4 | "description": "It's a minimalistic react component to embed a Microsoft PowerBI report, dashboard or tile into your react application.", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "scripts": { 8 | "dev": "concurrently \"npm run lib:watch\" \"npm run docs\"", 9 | "lib": "tsc", 10 | "lib:watch": "tsc -w", 11 | "docs": "webpack serve --mode development", 12 | "docs:prod": "webpack --mode production", 13 | "publish:demo": "gh-pages -d docs", 14 | "publish:lib": "semantic-release" 15 | }, 16 | "keywords": [ 17 | "powerbi", 18 | "react-powerbi", 19 | "react", 20 | "bi", 21 | "embed", 22 | "report", 23 | "dashboard", 24 | "tile", 25 | "report visual", 26 | "powerbi-reports" 27 | ], 28 | "license": "MIT", 29 | "peerDependencies": { 30 | "react": "^17.0.2", 31 | "react-dom": "^17.0.2" 32 | }, 33 | "devDependencies": { 34 | "@ant-design/icons": "^4.7.0", 35 | "@babel/cli": "^7.13.16", 36 | "@babel/core": "^7.14.0", 37 | "@babel/plugin-proposal-class-properties": "^7.13.0", 38 | "@babel/plugin-transform-runtime": "^7.13.15", 39 | "@babel/preset-env": "^7.14.1", 40 | "@babel/preset-react": "^7.13.13", 41 | "@semantic-release/changelog": "^6.0.1", 42 | "@semantic-release/git": "^10.0.1", 43 | "@semantic-release/npm": "^9.0.1", 44 | "@types/react": "^17.0.5", 45 | "@types/react-dom": "^17.0.3", 46 | "@types/zen-observable": "^0.8.2", 47 | "antd": "^4.15.4", 48 | "babel-loader": "^8.2.2", 49 | "concurrently": "^6.1.0", 50 | "css-loader": "^5.2.4", 51 | "gh-pages": "^4.0.0", 52 | "html-webpack-plugin": "^5.3.1", 53 | "node-sass": "^7.0.1", 54 | "react": "^17.0.2", 55 | "react-dom": "^17.0.2", 56 | "semantic-release": "^19.0.3", 57 | "style-loader": "^2.0.0", 58 | "typescript": "^4.2.4", 59 | "webpack": "^5.73.0", 60 | "webpack-cli": "^4.10.0", 61 | "webpack-dev-server": "^4.9.3" 62 | }, 63 | "author": { 64 | "name": "Akshay Ram Vignesh A", 65 | "email": "akshay5995@gmail.com" 66 | }, 67 | "homepage": "http://akshay5995.github.io/powerbi-report-component", 68 | "repository": { 69 | "type": "git", 70 | "url": "https://github.com/akshay5995/powerbi-report-component" 71 | }, 72 | "dependencies": { 73 | "powerbi-client": "^2.21.0" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/docs/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Layout } from 'antd'; 3 | import SideNav from './common/SideNav'; 4 | import Header from './common/Header'; 5 | import Footer from './common/Footer'; 6 | import CreateReport from './CreateReport'; 7 | import Report from './Report'; 8 | import Tile from './Tile'; 9 | import Dashboard from './Dashboard'; 10 | import ReportVisual from './ReportVisual'; 11 | import MultiplePageDemo from './MultiplePageDemo'; 12 | import './index.css'; 13 | import { useLocalStorage } from './hooks/useLocalStorage'; 14 | import UseReportDemo from './UseReportDemo'; 15 | import UseBootstrapDemo from './UseBootstrapDemo'; 16 | 17 | const App = () => { 18 | const [embedType, setEmbedType] = React.useState('Report'); 19 | const [darkMode, setDarkMode] = useLocalStorage('darkMode', true); 20 | 21 | const onSelect = (embedType) => setEmbedType(embedType); 22 | 23 | const renderDemo = () => { 24 | switch (embedType) { 25 | case 'Report': 26 | return ; 27 | case 'Dashboard': 28 | return ; 29 | case 'Tile': 30 | return ; 31 | case 'ReportVisual': 32 | return ; 33 | case 'Create Report': 34 | return ; 35 | case 'Multiple Pages': 36 | return ; 37 | case 'useReport': 38 | return ; 39 | case 'useBootstrap': 40 | return ; 41 | default: 42 | return null; 43 | } 44 | }; 45 | 46 | return ( 47 | 48 | 53 | 54 |
59 | {renderDemo()} 60 |