updateing templates
This commit is contained in:
Родитель
216338084c
Коммит
f33470d417
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -4,7 +4,7 @@ import * as _ from 'lodash';
|
|||
// The following line is important to keep in that format so it can be rendered into the page
|
||||
export const config: IDashboardConfig = /*return*/ {
|
||||
id: 'bot_analytics_dashboard',
|
||||
name: 'Bot Analytics Dashboard',
|
||||
name: 'Bot Analytics Basic Dashboard',
|
||||
icon: "dashboard",
|
||||
url: "bot_analytics_dashboard",
|
||||
description: 'Microsoft Bot Framework based analytics',
|
||||
|
@ -154,40 +154,6 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
params: {
|
||||
table: "customEvents",
|
||||
queries: {
|
||||
conversions: {
|
||||
query: () => `
|
||||
extend successful=tostring(customDimensions.successful) |
|
||||
where name in ('MBFEvent.StartTransaction', 'MBFEvent.EndTransaction') |
|
||||
summarize event_count=count() by name, successful`,
|
||||
mappings: { successful: (val) => val === 'true',event_count: (val) => val || 0 },
|
||||
filters: [{ dependency: "selectedChannels",queryProperty: "customDimensions.channel" }],
|
||||
calculated: (conversions) => {
|
||||
|
||||
// Conversion Handling
|
||||
// ===================
|
||||
|
||||
let total, successful;
|
||||
total = _.find(conversions, { name: 'MBFEvent.StartTransaction' });
|
||||
successful = _.find(conversions, { name: 'MBFEvent.EndTransaction', successful: true }) || { event_count: 0 };
|
||||
|
||||
if (!total) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: +5 to enable true numbers in conversions
|
||||
var displayValues = [
|
||||
{ label: 'Successful', count: successful.event_count },
|
||||
{ label: 'Failed', count: total.event_count - successful.event_count + 5 },
|
||||
];
|
||||
|
||||
let conversionRate = (100 * total.event_count / (successful.event_count + 5)).toFixed(1);
|
||||
|
||||
return {
|
||||
"conversions-displayValues": displayValues,
|
||||
"conversions-rate": conversionRate + '%',
|
||||
};
|
||||
}
|
||||
},
|
||||
timeline: {
|
||||
query: (dependencies) => {
|
||||
var { granularity } = dependencies;
|
||||
|
@ -315,6 +281,40 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
return { "users-value": (users && users.length && users[0].totalUsers) || 0 };
|
||||
}
|
||||
},
|
||||
conversions: {
|
||||
query: () => `
|
||||
extend successful=tostring(customDimensions.successful) |
|
||||
where name in ('MBFEvent.StartTransaction', 'MBFEvent.EndTransaction') |
|
||||
summarize event_count=count() by name, successful`,
|
||||
mappings: { successful: (val) => val === 'true',event_count: (val) => val || 0 },
|
||||
filters: [{ dependency: "selectedChannels",queryProperty: "customDimensions.channel" }],
|
||||
calculated: (conversions) => {
|
||||
|
||||
// Conversion Handling
|
||||
// ===================
|
||||
|
||||
let total, successful;
|
||||
total = _.find(conversions, { name: 'MBFEvent.StartTransaction' });
|
||||
successful = _.find(conversions, { name: 'MBFEvent.EndTransaction', successful: true }) || { event_count: 0 };
|
||||
|
||||
if (!total) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: +5 to enable true numbers in conversions
|
||||
var displayValues = [
|
||||
{ label: 'Successful', count: successful.event_count },
|
||||
{ label: 'Failed', count: total.event_count - successful.event_count + 5 },
|
||||
];
|
||||
|
||||
let conversionRate = (100 * total.event_count / (successful.event_count + 5)).toFixed(1);
|
||||
|
||||
return {
|
||||
"conversions-displayValues": displayValues,
|
||||
"conversions-rate": conversionRate + '%',
|
||||
};
|
||||
}
|
||||
},
|
||||
mapActivity: {
|
||||
query: () => `
|
||||
where name=='Activity' |
|
||||
|
@ -408,6 +408,15 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
filters: [{ dependency: "selectedChannels",queryProperty: "customDimensions.channel" }],
|
||||
calculated: results =>
|
||||
({ retention_avg_messages_per_session: (results && results.length && results[0].avg_sessions) || 0 })
|
||||
},
|
||||
retention_top_users: {
|
||||
query: () => `
|
||||
where name == "MBFEvent.UserMessage" |
|
||||
extend userId=substring(tostring(customDimensions.userId), 0, 30), fullUserId=tostring(customDimensions.userId) |
|
||||
summarize messages=count() by fullUserId, userId |
|
||||
top 5 by messages
|
||||
`,
|
||||
filters: [{ dependency: "selectedChannels",queryProperty: "customDimensions.channel" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -695,10 +704,46 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
{
|
||||
id: "intentsDialog-data",
|
||||
type: "ApplicationInsights/Query",
|
||||
dependencies: { intent: "dialog_intentsDialog:intent",queryTimespan: "dialog_intentsDialog:queryspan" },
|
||||
dependencies: {
|
||||
intent: "dialog_intentsDialog:intent",
|
||||
queryTimespan: "dialog_intentsDialog:queryspan",
|
||||
timespan: "timespan",
|
||||
granularity: "timespan:granularity"
|
||||
},
|
||||
params: {
|
||||
table: "customEvents",
|
||||
queries: {
|
||||
"intent-usage": {
|
||||
query: ({ intent, granularity }) => `
|
||||
extend intent=(customDimensions.intent)
|
||||
| where timestamp > ago(30d) and intent =~ "${intent}"
|
||||
| summarize intent_count=count() by bin(timestamp, ${granularity})
|
||||
| order by timestamp
|
||||
`,
|
||||
calculated: (timeline, dependencies) => {
|
||||
// Timeline handling
|
||||
// =================
|
||||
|
||||
let _timeline = [];
|
||||
let { timespan } = dependencies;
|
||||
|
||||
timeline.forEach(row => {
|
||||
var { timestamp, intent_count } = row;
|
||||
var timeValue = (new Date(timestamp)).getTime();
|
||||
|
||||
_timeline.push({
|
||||
time: (new Date(timestamp)).toUTCString(),
|
||||
value: intent_count
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
"timeline-graphData": _timeline,
|
||||
"timeline-values": ["value"],
|
||||
"timeline-timeFormat": (timespan === "24 hours" ? 'hour' : 'date')
|
||||
};
|
||||
}
|
||||
},
|
||||
"entities-usage": {
|
||||
query: ({ intent }) => `
|
||||
extend conversation=tostring(customDimensions.conversationId),
|
||||
|
@ -901,7 +946,7 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
type: "BarData",
|
||||
title: "Entity count appearances in intent",
|
||||
subtitle: "Entity usage and count for the selected intent",
|
||||
size: { w: 4,h: 8 },
|
||||
size: { w: 6,h: 8 },
|
||||
dependencies: { values: "intentsDialog-data:entities-usage",bars: "intentsDialog-data:entities-usage-bars" },
|
||||
props: { nameKey: "entityType" }
|
||||
},
|
||||
|
@ -914,6 +959,19 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
cols: [{ header: "Top Utterances",width: "200px",field: "text" },{ header: "Count",field: "count_utterances",type: "number" }]
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "intent-timeline",
|
||||
type: "Timeline",
|
||||
title: "Message Rate",
|
||||
subtitle: "How many messages were sent per timeframe",
|
||||
size: { w: 8,h: 8 },
|
||||
dependencies: {
|
||||
visible: "modes:messages",
|
||||
values: "intentsDialog-data:timeline-graphData",
|
||||
lines: "intentsDialog-data:timeline-values",
|
||||
timeFormat: "intentsDialog-data:timeline-timeFormat"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "conversations-count",
|
||||
type: "Scorecard",
|
||||
|
@ -1048,7 +1106,7 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
actions: {
|
||||
openMessagesDialog: {
|
||||
action: "dialog:messages",
|
||||
params: { title: "args:id",conversation: "args:conversation",queryspan: "timespan:queryTimespan" }
|
||||
params: { title: "args:id",conversation: "args:conversation",queryspan: "timespan:queryTimespan",intent: "::" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1070,7 +1128,7 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
actions: {
|
||||
openMessagesDialog: {
|
||||
action: "dialog:messages",
|
||||
params: { title: "args:id",conversation: "args:conversation",queryspan: "timespan:queryTimespan" }
|
||||
params: { title: "args:id",conversation: "args:conversation",queryspan: "timespan:queryTimespan",intent: "::" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1300,7 +1358,7 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
{
|
||||
id: "retention-scores",
|
||||
type: "Scorecard",
|
||||
size: { w: 12,h: 3 },
|
||||
size: { w: 6,h: 3 },
|
||||
dependencies: {
|
||||
card_msgs_icon: "::chat",
|
||||
card_msgs_value: "ai:retention_total_incoming_messages",
|
||||
|
@ -1326,9 +1384,10 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
id: "user-retention-table",
|
||||
type: "Table",
|
||||
title: "User Retention",
|
||||
size: { w: 12,h: 9 },
|
||||
size: { w: 3,h: 9 },
|
||||
dependencies: { values: "retention" },
|
||||
props: {
|
||||
compact: true,
|
||||
cols: [
|
||||
{ header: "Time Span",field: "timespan" },
|
||||
{ header: "Retention",field: "retention" },
|
||||
|
@ -1336,6 +1395,76 @@ export const config: IDashboardConfig = /*return*/ {
|
|||
{ header: "Unique Users",field: "unique" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "top-users-table",
|
||||
type: "Table",
|
||||
title: "Top Users",
|
||||
size: { w: 3,h: 9 },
|
||||
dependencies: { values: "ai:retention_top_users" },
|
||||
props: {
|
||||
compact: true,
|
||||
cols: [
|
||||
{ header: "User Id",field: "userId" },
|
||||
{ header: "Messages",field: "messages" },
|
||||
{ type: "button",value: "chat",click: "openMessagesDialog" }
|
||||
]
|
||||
},
|
||||
actions: {
|
||||
openMessagesDialog: {
|
||||
action: "dialog:userConversations",
|
||||
params: { title: "args:userId",userId: "args:fullUserId",queryspan: "timespan:queryTimespan" }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "userConversations",
|
||||
width: "60%",
|
||||
params: ["title","userId","queryspan"],
|
||||
dataSources: [
|
||||
{
|
||||
id: "user-conversations-data",
|
||||
type: "ApplicationInsights/Query",
|
||||
dependencies: { userId: "dialog_userConversations:userId",queryTimespan: "dialog_userConversations:queryspan" },
|
||||
params: {
|
||||
query: ({ userId }) => `
|
||||
customEvents
|
||||
| extend conversation=tostring(customDimensions.conversationId), userId=tostring(customDimensions.userId)
|
||||
| where name=='MBFEvent.UserMessage' and userId == '${userId}'
|
||||
| summarize count=count(), maxTimestamp=max(timestamp) by conversation
|
||||
| order by maxTimestamp`,
|
||||
mappings: { id: (val, row, idx) => `Conversation ${idx}` }
|
||||
}
|
||||
}
|
||||
],
|
||||
elements: [
|
||||
{
|
||||
id: "user-conversations-list",
|
||||
type: "Table",
|
||||
title: "Conversations",
|
||||
size: { w: 12,h: 16 },
|
||||
dependencies: { values: "user-conversations-data" },
|
||||
props: {
|
||||
cols: [
|
||||
{ header: "Conversation Id",field: "id" },
|
||||
{ header: "Last Message",field: "maxTimestamp",type: "time",format: "MMM-DD HH:mm:ss" },
|
||||
{ header: "Count",field: "count" },
|
||||
{ type: "button",value: "chat",click: "openMessagesDialog" }
|
||||
]
|
||||
},
|
||||
actions: {
|
||||
openMessagesDialog: {
|
||||
action: "dialog:messages",
|
||||
params: {
|
||||
title: "args:id",
|
||||
conversation: "args:conversation",
|
||||
intent: "dialog_intentConversations:intent",
|
||||
queryspan: "timespan:queryTimespan"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ export default class Home extends React.Component<any, IHomeState> {
|
|||
return null;
|
||||
}
|
||||
|
||||
let templateCards = templates.map((temp, index) => (
|
||||
let createCard = (temp, index) => (
|
||||
<div key={index} className="md-cell" style={styles.card}>
|
||||
<Card className="md-block-centered" key={index} >
|
||||
<Media>
|
||||
|
@ -202,10 +202,22 @@ export default class Home extends React.Component<any, IHomeState> {
|
|||
</CardActions>
|
||||
</Card>
|
||||
</div>
|
||||
));
|
||||
);
|
||||
|
||||
// Finding featured
|
||||
let featuredCards = templates
|
||||
.filter(temp => temp.id === 'bot_analytics_dashboard' || temp.id === 'bot_analytics_inst')
|
||||
.map(createCard);
|
||||
let templateCards = templates.map(createCard);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Bot Analytics</h1>
|
||||
<div className="md-grid">
|
||||
{featuredCards}
|
||||
</div>
|
||||
|
||||
<h1>All Dashboards</h1>
|
||||
<div className="md-grid">
|
||||
{templateCards}
|
||||
</div>
|
||||
|
|
|
@ -146,7 +146,7 @@ export default class Table extends GenericComponent<ITableProps, ITableState> {
|
|||
{
|
||||
cols.map((col, ci) => (
|
||||
<TableColumn key={ci} className={this.fixClassName(col.field || col.value)}>
|
||||
<span className="indicator"></span>{renderColumn(col, value)}
|
||||
<span className="indicator" />{renderColumn(col, value)}
|
||||
</TableColumn>
|
||||
))
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче