Skip to content

Commit f89d604

Browse files
committed
Merged PR 23667: Qna implementation in SDK and demo.
- SDK implementation - Demo load QnA implementation - Demo interactions are not implemented yet, in another code review.
1 parent 847d923 commit f89d604

30 files changed

+5631
-5375
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ tmp
77
.publish
88
npm-debug.log*
99
dist/powerbi.js.map
10-
10+
*.js.map

demo/code-demo/scripts/session_utils.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ const SessionKeys = {
55
EmbedUrl : "embedUrl",
66
EmbedId : "embedId",
77
GroupId : "groupId",
8-
IsSampleReport: "isSampleReport"
8+
IsSampleReport: "isSampleReport",
9+
QnaQuestion: "qnaQuestion"
910
};
1011

1112
function GetParameterByName(name, url) {

demo/v2-demo/report.html

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<div id="embedContainer"></div>
1717
<div id="dashboardContainer"></div>
1818
<div id="tileContainer"></div>
19+
<div id="qnaContainer"></div>
1920
</div>
2021
</div>
2122
</div>

demo/v2-demo/scripts/codesamples.js

+82
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,54 @@ function _Mock_Embed_Create() {
440440
});
441441
}
442442

443+
function _Embed_QnaEmbed() {
444+
// Read embed application token from textbox
445+
var txtAccessToken = $('#txtAccessToken').val();
446+
447+
// Read embed URL from textbox
448+
var txtEmbedUrl = $('#txtQnaEmbed').val();
449+
450+
// Read dataset Id from textbox
451+
var txtDatasetId = $('#txtDatasetId').val();
452+
453+
// Read question from textbox
454+
var txtQuestion = $('#txtQuestion').val();
455+
456+
// Read Qna mode
457+
var qnaMode = $("input[name='qnaMode']:checked").val();
458+
459+
// Get models. models contains enums that can be used.
460+
var models = window['powerbi-client'].models;
461+
462+
// Embed configuration used to describe the what and how to embed.
463+
// This object is used when calling powerbi.embed.
464+
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
465+
var config= {
466+
type: 'qna',
467+
tokenType: models.TokenType.Embed,
468+
accessToken: txtAccessToken,
469+
embedUrl: txtEmbedUrl,
470+
datasetIds: [txtDatasetId],
471+
viewMode: models.QnaMode[qnaMode],
472+
question: txtQuestion
473+
};
474+
475+
// Get a reference to the embedded QNA HTML element
476+
var qnaContainer = $('#qnaContainer')[0];
477+
478+
// Embed the QNA and display it within the div container.
479+
var qna = powerbi.embed(qnaContainer, config);
480+
481+
// qna.off removes a given event handler if it exists.
482+
qna.off("loaded");
483+
484+
// qna.on will add an event handler which prints to Log window.
485+
qna.on("loaded", function(event) {
486+
Log.logText("QNA loaded event");
487+
Log.log(event.detail);
488+
});
489+
}
490+
443491
// ---- Report Operations ----------------------------------------------------
444492

445493
function _Report_GetId() {
@@ -939,4 +987,38 @@ function _DashboardEvents_TileClicked() {
939987
dashboard.on("tileClicked", function(event) {
940988
Log.log(event.detail);
941989
});
990+
}
991+
992+
// ---- Qna Events Listener ----------------------------------------------------
993+
994+
function _Qna_SetQuestion() {
995+
// Get a reference to the embedded Q&A HTML element
996+
var qnaContainer = $('#qnaContainer')[0];
997+
998+
// Get a reference to the embedded Q&A.
999+
qna = powerbi.get(qnaContainer);
1000+
1001+
qna.setQuestion("This year sales")
1002+
.then(function (result) {
1003+
log.log(result);
1004+
})
1005+
.catch(function (errors) {
1006+
Log.log(errors);
1007+
});
1008+
}
1009+
1010+
function _Qna_QuestionChanged() {
1011+
// Get a reference to the embedded Q&A HTML element
1012+
var qnaContainer = $('#qnaContainer')[0];
1013+
1014+
// Get a reference to the embedded Q&A.
1015+
qna = powerbi.get(qnaContainer);
1016+
1017+
// qna.off removes a given event listener if it exists.
1018+
qna.off("visualRendered");
1019+
1020+
// qna.on will add an event listener.
1021+
qna.on("visualRendered", function(event) {
1022+
Log.log(event.detail);
1023+
});
9421024
}

demo/v2-demo/scripts/function_mapping.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ function IsNotSupported(funcName) {
4747
return false
4848
}
4949

50-
const dashboardOrTileMatch = funcName.match(/Dashboard|Tile/);
51-
if (dashboardOrTileMatch) {
50+
const dashboardOrTileOrQnaMatch = funcName.match(/Dashboard|Tile|Qna/);
51+
if (dashboardOrTileOrQnaMatch) {
5252
return false;
5353
}
5454

demo/v2-demo/scripts/report.js

+63-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ function OpenEmbedStep(mode, entityType) {
3939
var embedContainer = $("#embedContainer");
4040
var dashboardContainer = $("#dashboardContainer");
4141
var tileContainer = $("#tileContainer");
42+
var qnaContainer = $("#qnaContainer");
4243

4344
if (entityType == EntityType.Report)
4445
{
@@ -51,6 +52,7 @@ function OpenEmbedStep(mode, entityType) {
5152
embedContainer.show();
5253
dashboardContainer.hide();
5354
tileContainer.hide();
55+
qnaContainer.hide();
5456
});
5557
}
5658
else if (entityType == EntityType.Dashboard)
@@ -64,9 +66,10 @@ function OpenEmbedStep(mode, entityType) {
6466
embedContainer.hide();
6567
dashboardContainer.show();
6668
tileContainer.hide();
69+
qnaContainer.hide();
6770
});
6871
}
69-
else
72+
else if (entityType == EntityType.Tile)
7073
{
7174
$("#settings").load("settings_embed_tile.html", function() {
7275
OpenEmbedMode(mode, entityType);
@@ -76,6 +79,20 @@ function OpenEmbedStep(mode, entityType) {
7679
embedContainer.hide();
7780
dashboardContainer.hide();
7881
tileContainer.show();
82+
qnaContainer.hide();
83+
});
84+
}
85+
else if (entityType == EntityType.Qna)
86+
{
87+
$("#settings").load("settings_embed_qna.html", function() {
88+
OpenEmbedMode(mode, entityType);
89+
90+
qnaContainer.height(qnaContainer.width() * 0.59);
91+
92+
embedContainer.hide();
93+
dashboardContainer.hide();
94+
tileContainer.hide();
95+
qnaContainer.show();
7996
});
8097
}
8198
}
@@ -108,6 +125,14 @@ function OpenInteractStep() {
108125
LoadCodeArea("#embedCodeDiv", _Dashboard_GetId);
109126
});
110127
}
128+
else if (entityType == EntityType.Qna)
129+
{
130+
$("#settings").load("settings_interact_qna.html", function() {
131+
SetToggleHandler("qna-operations-div");
132+
SetToggleHandler("qna-events-operations-div");
133+
LoadCodeArea("#embedCodeDiv", _Qna_SetQuestion);
134+
});
135+
}
111136
else
112137
{
113138
$("#settings").load("settings_interact.html", function() {
@@ -141,10 +166,14 @@ function setCodeArea(mode, entityType)
141166
{
142167
LoadCodeArea("#embedCodeDiv", _Embed_DashboardEmbed);
143168
}
144-
else
169+
else if (entityType == EntityType.Tile)
145170
{
146171
LoadCodeArea("#embedCodeDiv", _Embed_TileEmbed);
147172
}
173+
else if (entityType == EntityType.Qna)
174+
{
175+
LoadCodeArea("#embedCodeDiv", _Embed_QnaEmbed);
176+
}
148177
}
149178

150179
function showEmbedSettings(mode, entityType)
@@ -222,7 +251,7 @@ function OpenEmbedMode(mode, entityType)
222251
setCodeAndShowEmbedSettings(mode, entityType);
223252
}
224253
}
225-
else
254+
else if (entityType == EntityType.Tile)
226255
{
227256
if (IsEmbeddingSampleTile())
228257
{
@@ -237,6 +266,21 @@ function OpenEmbedMode(mode, entityType)
237266
setCodeAndShowEmbedSettings(mode, entityType);
238267
}
239268
}
269+
else if (entityType == EntityType.Qna)
270+
{
271+
if (IsEmbeddingSampleQna())
272+
{
273+
LoadSampleQnaIntoSession().then(function (response) {
274+
SetTextBoxesFromSessionOrUrlParam("#txtAccessToken", "#txtQnaEmbed", "#txtDatasetId");
275+
setCodeAndShowEmbedSettings(mode, entityType);
276+
});
277+
}
278+
else
279+
{
280+
SetTextBoxesFromSessionOrUrlParam("#txtAccessToken", "#txtQnaEmbed", "#txtDatasetId");
281+
setCodeAndShowEmbedSettings(mode, entityType);
282+
}
283+
}
240284
}
241285

242286
function setCodeAndShowEmbedSettings(mode, entityType) {
@@ -270,3 +314,19 @@ function IsEmbeddingSampleDashboard() {
270314
function IsEmbeddingSampleTile() {
271315
return GetSession(SessionKeys.IsSampleTile) == true;
272316
}
317+
318+
function IsEmbeddingSampleQna() {
319+
return GetSession(SessionKeys.IsSampleQna) == true;
320+
}
321+
322+
function ToggleQuestionBox(enabled) {
323+
let txtQuestion = $("#txtQuestion");
324+
if (enabled === true) {
325+
txtQuestion.val("This year sales by store type by postal code as map");
326+
txtQuestion.prop('disabled', false);
327+
}
328+
else {
329+
txtQuestion.val("");
330+
txtQuestion.prop('disabled', true);
331+
}
332+
}

demo/v2-demo/scripts/session_utils.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const SessionKeys = {
99
IsSampleReport: "isSampleReport",
1010
IsSampleDashboard: "IsSampleDashboard",
1111
IsSampleTile: "IsSampleTile",
12+
IsSampleQna: "IsSampleQna",
1213
EmbedMode: "embedMode",
1314
EntityType: "entityType",
1415
SampleId: "SampleId"

demo/v2-demo/scripts/step_authorize.js

+33-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ var reportUrl = 'https://powerbilivedemobe.azurewebsites.net/api/Reports/SampleR
22
var datasetUrl = 'https://powerbilivedemobe.azurewebsites.net/api/Reports/SampleCreate';
33
var dashboardUrl = 'https://powerbilivedemobe.azurewebsites.net/api/Dashboards/SampleDashboard';
44
var tileUrl = 'https://powerbilivedemobe.azurewebsites.net/api/Tiles/SampleTile';
5+
var qnaUrl = 'https://powerbilivedemobe.azurewebsites.net/api/Datasets/SampleQna';
56

67
var LastReportSampleUrl = null;
78
var ReportRefreshTokenTimer = 0;
89
var DashboardRefreshTokenTimer = 0;
910
var TileRefreshTokenTimer = 0;
11+
var QnaRefreshTokenTimer = 0;
1012

1113
const EntityType = {
1214
Report : "Report",
1315
Dashboard : "Dashboard",
14-
Tile : "Tile"
16+
Tile : "Tile",
17+
Qna: "Qna"
1518
};
1619

1720
function FetchUrlIntoSession(url, updateCurrentToken) {
@@ -46,6 +49,10 @@ function FetchUrlIntoSession(url, updateCurrentToken) {
4649
{
4750
TokenExpirationRefreshListener(embedConfig.minutesToExpiration, EntityType.Dashboard);
4851
}
52+
else if (embedConfig.type === "qna")
53+
{
54+
TokenExpirationRefreshListener(embedConfig.minutesToExpiration, EntityType.Qna);
55+
}
4956
else
5057
{
5158
TokenExpirationRefreshListener(embedConfig.minutesToExpiration, EntityType.Tile);
@@ -85,7 +92,20 @@ function TokenExpirationRefreshListener(minutesToExpiration, entityType) {
8592
FetchUrlIntoSession(dashboardUrl, true /* updateCurrentToken */);
8693
}, updateAfterMilliSeconds);
8794
}
88-
else
95+
else if (entityType == EntityType.Qna)
96+
{
97+
if (QnaRefreshTokenTimer)
98+
{
99+
console.log("step current Q&A Embed Token update threads.");
100+
clearTimeout(QnaRefreshTokenTimer);
101+
}
102+
103+
console.log("Q&A Embed Token will be updated in " + updateAfterMilliSeconds + " milliseconds.");
104+
QnaRefreshTokenTimer = setTimeout(function() {
105+
FetchUrlIntoSession(qnaUrl, true /* updateCurrentToken */);
106+
}, updateAfterMilliSeconds);
107+
}
108+
else
89109
{
90110
if (TileRefreshTokenTimer)
91111
{
@@ -120,6 +140,11 @@ function LoadSampleTileIntoSession() {
120140
return FetchUrlIntoSession(tileUrl, false /* updateCurrentToken */);
121141
}
122142

143+
function LoadSampleQnaIntoSession() {
144+
SetSession(SessionKeys.EntityType, EntityType.Qna);
145+
return FetchUrlIntoSession(qnaUrl, false /* updateCurrentToken */);
146+
}
147+
123148
function OpenEmbedStepWithSample(entityType) {
124149
SetSession(SessionKeys.EntityType, entityType);
125150

@@ -133,11 +158,16 @@ function OpenEmbedStepWithSample(entityType) {
133158
SetSession(SessionKeys.IsSampleDashboard, true);
134159
OpenEmbedStep(EmbedViewMode, EntityType.Dashboard);
135160
}
136-
else
161+
else if (entityType == EntityType.Tile)
137162
{
138163
SetSession(SessionKeys.IsSampleTile, true);
139164
OpenEmbedStep(EmbedViewMode, EntityType.Tile)
140165
}
166+
else if (entityType == EntityType.Qna)
167+
{
168+
SetSession(SessionKeys.IsSampleQna, true);
169+
OpenEmbedStep(EmbedViewMode, EntityType.Qna)
170+
}
141171
}
142172

143173
function OpenEmbedStepCreateWithSample() {

demo/v2-demo/scripts/step_embed.js

+10
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,13 @@ function Dashboard_ExitFullScreen() {
118118
function DashboardEvents_TileClicked() {
119119
SetCode(_DashboardEvents_TileClicked);
120120
}
121+
122+
// ---- Q&A Events Listener ----------------------------------------------------
123+
124+
function Qna_SetQuestion() {
125+
SetCode(_Qna_SetQuestion);
126+
}
127+
128+
function Qna_QuestionChanged() {
129+
SetCode(_Qna_QuestionChanged);
130+
}

demo/v2-demo/scripts/step_interact.js

+8
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ function OpenTileOperations() {
6969
$("#selected-catogory-button").html("Tile operations");
7070
}
7171

72+
function OpenQnaOperations() {
73+
$("#qna-operations-div").show();
74+
$("#qna-operations-li").addClass('active');
75+
76+
$("#qna-operations-div .function-ul li.active").click()
77+
$("#selected-catogory-button").html("QNA operations");
78+
}
79+
7280
function OpenDashboardOperations() {
7381
$("#dashboard-operations-div").show();
7482
$("#dashboard-events-operations-div").hide();

0 commit comments

Comments
 (0)