diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/.gitignore b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/.gitignore
new file mode 100644
index 0000000..41ffa34
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/.gitignore
@@ -0,0 +1,231 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+bin/
+Bin/
+obj/
+Obj/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Microsoft Azure ApplicationInsights config file
+ApplicationInsights.config
+
+# Windows Store app package directory
+AppPackages/
+BundleArtifacts/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+/node_modules
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+
+# FAKE - F# Make
+.fake/
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Angular-with-ASP.NETCore.csproj b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Angular-with-ASP.NETCore.csproj
new file mode 100644
index 0000000..b192d94
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Angular-with-ASP.NETCore.csproj
@@ -0,0 +1,50 @@
+
+
+
+ net7.0
+ false
+ ClientApp\
+ https://localhost:44459
+ npm start
+ Angular_with_ASP.NETCore
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ wwwroot\%(RecursiveDir)%(FileName)%(Extension)
+ PreserveNewest
+ true
+
+
+
+
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/.editorconfig b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/.editorconfig
new file mode 100644
index 0000000..5fc7188
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/.editorconfig
@@ -0,0 +1,19 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.ts]
+quote_type = single
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
+
+[*.{razor,cshtml}]
+charset = utf-8-bom
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/.gitignore b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/.gitignore
new file mode 100644
index 0000000..e1f679b
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/.gitignore
@@ -0,0 +1,40 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/dist-server
+/tmp
+/out-tsc
+
+# dependencies
+/node_modules
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+yarn-error.log
+testem.log
+/typings
+
+# System Files
+.DS_Store
+Thumbs.db
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/angular.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/angular.json
new file mode 100644
index 0000000..65b79c7
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/angular.json
@@ -0,0 +1,139 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "newProjectRoot": "projects",
+ "projects": {
+ "Angular_with_ASP.NETCore": {
+ "projectType": "application",
+ "schematics": {
+ "@schematics/angular:application": {
+ "strict": true
+ }
+ },
+ "root": "",
+ "sourceRoot": "src",
+ "prefix": "app",
+ "architect": {
+ "build": {
+ "builder": "@angular-devkit/build-angular:browser",
+ "options": {
+ "progress": false,
+ "outputPath": "dist",
+ "index": "src/index.html",
+ "main": "src/main.ts",
+ "polyfills": "src/polyfills.ts",
+ "tsConfig": "tsconfig.app.json",
+ "allowedCommonJsDependencies": [
+ "oidc-client"
+ ],
+ "assets": [
+ "src/assets"
+ ],
+ "styles": [
+ "node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "src/styles.css"
+ ],
+ "scripts": []
+ },
+ "configurations": {
+ "production": {
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "500kb",
+ "maximumError": "1mb"
+ },
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "2kb",
+ "maximumError": "4kb"
+ }
+ ],
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.prod.ts"
+ }
+ ],
+ "outputHashing": "all"
+ },
+ "development": {
+ "buildOptimizer": false,
+ "optimization": false,
+ "vendorChunk": true,
+ "extractLicenses": false,
+ "sourceMap": true,
+ "namedChunks": true
+ }
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "builder": "@angular-devkit/build-angular:dev-server",
+ "configurations": {
+ "production": {
+ "browserTarget": "Angular_with_ASP.NETCore:build:production"
+ },
+ "development": {
+ "browserTarget": "Angular_with_ASP.NETCore:build:development",
+ "proxyConfig": "proxy.conf.js"
+ }
+ },
+ "defaultConfiguration": "development"
+ },
+ "extract-i18n": {
+ "builder": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "browserTarget": "Angular_with_ASP.NETCore:build"
+ }
+ },
+ "test": {
+ "builder": "@angular-devkit/build-angular:karma",
+ "options": {
+ "main": "src/test.ts",
+ "polyfills": "src/polyfills.ts",
+ "tsConfig": "tsconfig.spec.json",
+ "karmaConfig": "karma.conf.js",
+ "assets": [
+ "src/assets"
+ ],
+ "styles": [
+ "src/styles.css"
+ ],
+ "scripts": []
+ }
+ },
+ "server": {
+ "builder": "@angular-devkit/build-angular:server",
+ "options": {
+ "outputPath": "dist-server",
+ "main": "src/main.ts",
+ "tsConfig": "tsconfig.server.json"
+ },
+ "configurations": {
+ "dev": {
+ "optimization": true,
+ "outputHashing": "all",
+ "sourceMap": false,
+ "namedChunks": false,
+ "extractLicenses": true,
+ "vendorChunk": true
+ },
+ "production": {
+ "optimization": true,
+ "outputHashing": "all",
+ "sourceMap": false,
+ "namedChunks": false,
+ "extractLicenses": true,
+ "vendorChunk": false
+ }
+ }
+ }
+ }
+ }
+ },
+ "defaultProject": "Angular_with_ASP.NETCore",
+ "cli": {
+ "analytics": false
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/aspnetcore-https.js b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/aspnetcore-https.js
new file mode 100644
index 0000000..2bde928
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/aspnetcore-https.js
@@ -0,0 +1,33 @@
+// This script sets up HTTPS for the application using the ASP.NET Core HTTPS certificate
+const fs = require('fs');
+const spawn = require('child_process').spawn;
+const path = require('path');
+
+const baseFolder =
+ process.env.APPDATA !== undefined && process.env.APPDATA !== ''
+ ? `${process.env.APPDATA}/ASP.NET/https`
+ : `${process.env.HOME}/.aspnet/https`;
+
+const certificateArg = process.argv.map(arg => arg.match(/--name=(?.+)/i)).filter(Boolean)[0];
+const certificateName = certificateArg ? certificateArg.groups.value : process.env.npm_package_name;
+
+if (!certificateName) {
+ console.error('Invalid certificate name. Run this script in the context of an npm/yarn script or pass --name=<> explicitly.')
+ process.exit(-1);
+}
+
+const certFilePath = path.join(baseFolder, `${certificateName}.pem`);
+const keyFilePath = path.join(baseFolder, `${certificateName}.key`);
+
+if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) {
+ spawn('dotnet', [
+ 'dev-certs',
+ 'https',
+ '--export-path',
+ certFilePath,
+ '--format',
+ 'Pem',
+ '--no-password',
+ ], { stdio: 'inherit', })
+ .on('exit', (code) => process.exit(code));
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/karma.conf.js b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/karma.conf.js
new file mode 100644
index 0000000..95d59d9
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/karma.conf.js
@@ -0,0 +1,44 @@
+// Karma configuration file, see link for more information
+// https://karma-runner.github.io/1.0/config/configuration-file.html
+
+module.exports = function (config) {
+ config.set({
+ basePath: '',
+ frameworks: ['jasmine', '@angular-devkit/build-angular'],
+ plugins: [
+ require('karma-jasmine'),
+ require('karma-chrome-launcher'),
+ require('karma-jasmine-html-reporter'),
+ require('karma-coverage'),
+ require('@angular-devkit/build-angular/plugins/karma')
+ ],
+ client: {
+ jasmine: {
+ // you can add configuration options for Jasmine here
+ // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
+ // for example, you can disable the random execution with `random: false`
+ // or set a specific seed with `seed: 4321`
+ },
+ clearContext: false // leave Jasmine Spec Runner output visible in browser
+ },
+ jasmineHtmlReporter: {
+ suppressAll: true // removes the duplicated traces
+ },
+ coverageReporter: {
+ dir: require('path').join(__dirname, './coverage/angularapp'),
+ subdir: '.',
+ reporters: [
+ { type: 'html' },
+ { type: 'text-summary' }
+ ]
+ },
+ reporters: ['progress', 'kjhtml'],
+ port: 9876,
+ colors: true,
+ logLevel: config.LOG_INFO,
+ autoWatch: true,
+ browsers: ['Chrome'],
+ singleRun: false,
+ restartOnFileChange: true
+ });
+};
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/package.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/package.json
new file mode 100644
index 0000000..034e528
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "angular_with_asp.netcore",
+ "version": "0.0.0",
+ "scripts": {
+ "ng": "ng",
+ "prestart": "node aspnetcore-https",
+ "start": "run-script-os",
+ "start:windows": "ng serve --port 44459 --ssl --ssl-cert \"%APPDATA%\\ASP.NET\\https\\%npm_package_name%.pem\" --ssl-key \"%APPDATA%\\ASP.NET\\https\\%npm_package_name%.key\"",
+ "start:default": "ng serve --port 44459 --ssl --ssl-cert \"$HOME/.aspnet/https/${npm_package_name}.pem\" --ssl-key \"$HOME/.aspnet/https/${npm_package_name}.key\"",
+ "build": "ng build",
+ "build:ssr": "ng run Angular_with_ASP.NETCore:server:dev",
+ "watch": "ng build --watch --configuration development",
+ "test": "ng test"
+ },
+ "private": true,
+ "dependencies": {
+ "@angular/animations": "^15.1.5",
+ "@angular/common": "^15.1.5",
+ "@angular/compiler": "^15.1.5",
+ "@angular/core": "^15.1.5",
+ "@angular/forms": "^15.1.5",
+ "@angular/platform-browser": "^15.1.5",
+ "@angular/platform-browser-dynamic": "^15.1.5",
+ "@angular/platform-server": "^15.1.5",
+ "@angular/router": "^15.1.5",
+ "bootstrap": "^5.2.3",
+ "jquery": "^3.6.3",
+ "oidc-client": "^1.11.5",
+ "popper.js": "^1.16.0",
+ "run-script-os": "^1.1.6",
+ "rxjs": "~7.8.0",
+ "tslib": "^2.5.0",
+ "zone.js": "~0.12.0"
+ },
+ "devDependencies": {
+ "@angular-devkit/build-angular": "^15.1.6",
+ "@angular/cli": "^15.1.6",
+ "@angular/compiler-cli": "^15.1.5",
+ "@types/jasmine": "~4.3.1",
+ "@types/jasminewd2": "~2.0.10",
+ "@types/node": "^18.14.0",
+ "jasmine-core": "~4.5.0",
+ "karma": "~6.4.1",
+ "karma-chrome-launcher": "~3.1.1",
+ "karma-coverage": "~2.2.0",
+ "karma-jasmine": "~5.1.0",
+ "karma-jasmine-html-reporter": "^2.0.0",
+ "typescript": "~4.9.5"
+ },
+ "overrides": {
+ "autoprefixer": "10.4.5"
+ },
+ "optionalDependencies": {}
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/proxy.conf.js b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/proxy.conf.js
new file mode 100644
index 0000000..6793460
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/proxy.conf.js
@@ -0,0 +1,19 @@
+const { env } = require('process');
+
+const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
+ env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:55063';
+
+const PROXY_CONFIG = [
+ {
+ context: [
+ "/weatherforecast",
+ ],
+ target: target,
+ secure: false,
+ headers: {
+ Connection: 'Keep-Alive'
+ }
+ }
+]
+
+module.exports = PROXY_CONFIG;
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.component.html b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.component.html
new file mode 100644
index 0000000..90c6b64
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.component.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.component.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.component.ts
new file mode 100644
index 0000000..0249491
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.component.ts
@@ -0,0 +1,36 @@
+import { Component } from '@angular/core';
+import { appService } from './app.service';
+
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+})
+
+ export class AppComponent {
+
+ //ASP.NET Core application would be run on https://localhost:5001;http://localhost:5000, which needs to be set as `apiHost`
+ public apiHost="https://localhost:7051/";
+
+ //Url of the GetDetails action in ValuesController of the ASP.NET Core application
+ public authorizationUrl= "api/boldbiembed/authorizationserver";
+
+ //Url of the GetDashboards action in ValuesController of the ASP.NET Core application
+ public getDashboardsUrl= "api/boldbiembed/getdashboards";
+
+ public getEmbedConfigUrl= "api/boldbiembed/getdata";
+
+ public embedConfig: any;
+
+ public dashboards: any;
+
+ public baseUrl: any;
+
+ public dashboardServerApiUrl!: string;
+
+ constructor(private _app: appService) {
+ }
+
+ ngOnInit() {
+
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.module.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.module.ts
new file mode 100644
index 0000000..b065c22
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.module.ts
@@ -0,0 +1,27 @@
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { HttpClientModule } from '@angular/common/http';
+import { RouterModule } from '@angular/router';
+import { appService } from './app.service';
+import { AppComponent } from './app.component';
+import { DashboardListing } from './dashboard-listing/dashboard-listing.component';
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ RouterModule.forRoot([
+ { path: '', component: DashboardListing },
+ ]
+ ),
+ HttpClientModule
+ ],
+ providers: [appService],
+ declarations: [
+ AppComponent,
+ DashboardListing,
+ ],
+
+ bootstrap: [AppComponent]
+ })
+export class AppModule { }
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.server.module.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.server.module.ts
new file mode 100644
index 0000000..cfb0e02
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.server.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { ServerModule } from '@angular/platform-server';
+import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
+import { AppComponent } from './app.component';
+import { AppModule } from './app.module';
+
+@NgModule({
+ imports: [AppModule, ServerModule, ModuleMapLoaderModule],
+ bootstrap: [AppComponent]
+})
+export class AppServerModule { }
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.service.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.service.ts
new file mode 100644
index 0000000..97cae15
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.service.ts
@@ -0,0 +1,48 @@
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
+import { HashLocationStrategy } from '@angular/common';
+
+@Injectable()
+
+export class appService {
+
+ private authUrl!: string;
+ private getDashboardsUrl!: string;
+ private header!: HttpHeaders;
+
+ constructor(private http: HttpClient) {
+ }
+
+ // public Gettoken(dashboardServerApiUrl: string,userId: string, userPassword: string) {
+ // this.header = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
+
+ // let body = new HttpParams();
+ // body = body.set('UserId', userId);
+ // body = body.set('Password', userPassword);
+
+ // return this.http.post(dashboardServerApiUrl + '/get-user-key', body, {
+ // headers: this.header,
+ // }).pipe(res => {
+ // return res;
+ // });
+ // }
+
+ public GetDashboards(getDashboardsUrl: string) {
+ this.header = new HttpHeaders();
+ this.header = this.header.append('Access-Control-Allow-Origin', '*');
+ this.header = this.header.append('Authorization', 'bearer ' + "token");
+
+ return this.http.get(getDashboardsUrl, {
+ headers: this.header
+ }).pipe(res => {
+ return res;
+ });
+ }
+
+ public GetEmbedConfig(getDashboardsUrl: string) {
+ return this.http.get(getDashboardsUrl, {
+ }).pipe(res => {
+ return res;
+ });
+ }
+}
\ No newline at end of file
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.ts
new file mode 100644
index 0000000..876e905
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/app.ts
@@ -0,0 +1,9 @@
+export class Item {
+ Name!: string;
+ Description!: string;
+ Id!: string;
+ Version!: string;
+ IsPublic!: boolean;
+ ItemLocation!: string;
+ CategoryName!: string;
+ }
\ No newline at end of file
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard-listing/dashboard-listing.component.html b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard-listing/dashboard-listing.component.html
new file mode 100644
index 0000000..cf1f6bd
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard-listing/dashboard-listing.component.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard-listing/dashboard-listing.component.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard-listing/dashboard-listing.component.ts
new file mode 100644
index 0000000..d0c0dbf
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard-listing/dashboard-listing.component.ts
@@ -0,0 +1,81 @@
+import { Component, OnInit } from '@angular/core';
+import { Item } from '../app';
+import { appService } from '../app.service';
+import { AppComponent } from '../app.component';
+import { BoldBI } from '@boldbi/boldbi-embedded-sdk';
+import { DashboardService } from '../dashboard.service';
+
+// declare var BoldBI: any;
+@Component({
+ selector: 'app-dashboard-listing',
+ templateUrl: './dashboard-listing.component.html',
+ providers: [appService]
+})
+
+export class DashboardListing implements OnInit {
+
+ public dashboardsList!: Item[];
+ result: any;
+ dashboard: any;
+ embedConfig: any;
+ constructor(private _app: appService, private _appComponent: AppComponent, private dashboardService: DashboardService) {
+ }
+
+ ngOnInit() {
+
+ this._app.GetEmbedConfig(this._appComponent.apiHost + this._appComponent.getEmbedConfigUrl).subscribe(data => {
+ this._appComponent.embedConfig = data;
+ // Transform camelCase keys to PascalCase
+ const transformedEmbedConfigData = {
+ DashboardId: this._appComponent.embedConfig.dashboardId,
+ EmbedType: this._appComponent.embedConfig.embedType,
+ Environment: this._appComponent.embedConfig.environment,
+ ServerUrl: this._appComponent.embedConfig.serverUrl,
+ SiteIdentifier: this._appComponent.embedConfig.siteIdentifier
+ };
+ this.dashboardService.setEmbedConfig(transformedEmbedConfigData);
+ if (this.dashboardService.embedConfig.Environment == "enterprise" || this.dashboardService.embedConfig.Environment == "onpremise") {
+ this._appComponent.baseUrl = this.dashboardService.embedConfig.ServerUrl + "/" + this.dashboardService.embedConfig.SiteIdentifier;
+ this._appComponent.dashboardServerApiUrl = this.dashboardService.embedConfig.ServerUrl + "/api/" + this.dashboardService.embedConfig.SiteIdentifier;
+ } else {
+ this._appComponent.baseUrl = this.dashboardService.embedConfig.ServerUrl;
+ this._appComponent.dashboardServerApiUrl = this.dashboardService.embedConfig.ServerUrl + "/api";
+ }
+ })
+
+ // this._app.Gettoken(this._appComponent.dashboardServerApiUrl,this._appComponent.userId,this._appComponent.userPassword).subscribe(data => {
+ // this.result = data;
+ // this._appComponent.token = JSON.parse(this.result.Token).access_token;
+ // this._app.GetDashboards(this._appComponent.getDashboardsUrl).subscribe(data => {
+ // this._appComponent.dashboards = data;
+ // this.dashboardsList = this._appComponent.dashboards;
+ // });
+ // });
+
+ this._app.GetDashboards(this._appComponent.apiHost + this._appComponent.getDashboardsUrl).subscribe(data => {
+ this._appComponent.dashboards = data;
+ this.dashboardsList = this._appComponent.dashboards;
+ this.renderDashboard(this.dashboardsList[0]);
+ });
+ }
+
+ renderDashboard(dashboard: Item) {
+ this.dashboard= BoldBI.create({
+ serverUrl: this._appComponent.baseUrl,
+ dashboardId: this.dashboardService.embedConfig.DashboardId,
+ embedContainerId: "dashboard",
+ embedType: this.dashboardService.embedConfig.EmbedType,
+ environment: this.dashboardService.embedConfig.Environment,
+ width:"100%",
+ height:"100%",
+ hideMultiDashboardHeader: true,
+ expirationTime:100000,
+ authorizationServer: {
+ url:this._appComponent.apiHost + this._appComponent.authorizationUrl
+ }
+ });
+
+ console.log(this.dashboard);
+ this.dashboard.loadDashboard();
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard.service.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard.service.ts
new file mode 100644
index 0000000..2c75a7b
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/app/dashboard.service.ts
@@ -0,0 +1,12 @@
+import { Injectable } from '@angular/core';
+@Injectable({
+ providedIn: 'root'
+})
+export class DashboardService {
+public embedConfig: any;
+getEmbedConfig(): any {
+return this.embedConfig;
+}
+setEmbedConfig(embedConfig: any): void {
+this.embedConfig = embedConfig; }
+}
\ No newline at end of file
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/assets/.gitkeep b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/assets/css/site.css b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/assets/css/site.css
new file mode 100644
index 0000000..2692474
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/assets/css/site.css
@@ -0,0 +1,26 @@
+body html { width: 100%; height: 100%; }
+html, body,app-root { width: 100%; height: 100%; margin: 0; font-family: Roboto; font-size: 13px;}
+ul { list-style-type: none; padding-left: 0; }
+.tab { padding-top: 2px; padding-bottom: 18px; cursor: pointer }
+.active { background-color: burlywood; }
+
+.e-dbrd-blueWaitingIndcator {
+ -webkit-animation: rotate 2s linear infinite; animation: rotate 2s linear infinite; height: 54px; width: 54px; top: 50%; left: 50%; position: relative; }
+
+.e-waiting { position: fixed; display: block; margin: 0px auto; width: 54px; height: 54px; zoom: 0.5; margin-left: 55px;}
+
+#container { width: 13%; float: left; height: 100%; float: left; background: #f4f4f4; height: 100%; box-shadow: 2px 0 4px 0 rgba(0, 0, 0, .12); overflow: auto; overflow-x: hidden; }
+
+#grid-title { font-size: 17px; border-bottom: 1px solid #333; padding: 15px;}
+#panel { width: 100%; float: left; background: #f4f4f4; overflow: auto;}
+#dashboard { width: 100%; float: left; height: 100%; display: block; }
+.dashboard-item { padding: 10px; border-bottom: 1px solid #ccc; cursor: pointer; }
+#viewer-section { width: 100%; height: 100%; float: left; }
+#viewer-header { padding: 10px; display: block; float: left; width: 100%; }
+#create-dashboard { float: right; margin-right: 20px; background: #0565ff; border: 0; border-radius: 4px; color: #fff;cursor: pointer; display: inline-block;font-size: 12px; font-weight: 600;height: 28px;line-height: 28px; min-width: 90px; outline: none; text-align: center;border: 1px solid #0450cc; }
+
+#edit-dashboard {
+float: right; background: #fff; margin-right: 20px; border: 0; border-radius: 4px; color: #333; cursor: pointer; display: inline-block; font-size: 12px; font-weight: 600; height: 28px; line-height: 28px; min-width: 90px; outline: none; text-align: center; border: 1px solid #b3b3b3; }
+#dashboardDesigner{ height: 900px; border: 2px solid #333; }
+.dashboard_container { height: 750px !important; width: 1585px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; margin-bottom: 0px !important;}
+.e-waitpopup-pane { display: none; }
\ No newline at end of file
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/environments/environment.prod.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/environments/environment.prod.ts
new file mode 100644
index 0000000..3612073
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/environments/environment.prod.ts
@@ -0,0 +1,3 @@
+export const environment = {
+ production: true
+};
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/environments/environment.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/environments/environment.ts
new file mode 100644
index 0000000..f56ff47
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/environments/environment.ts
@@ -0,0 +1,16 @@
+// This file can be replaced during build by using the `fileReplacements` array.
+// `ng build` replaces `environment.ts` with `environment.prod.ts`.
+// The list of file replacements can be found in `angular.json`.
+
+export const environment = {
+ production: false
+};
+
+/*
+ * For easier debugging in development mode, you can import the following file
+ * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
+ *
+ * This import should be commented out in production mode because it will have a negative impact
+ * on performance if an error is thrown.
+ */
+// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/index.html b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/index.html
new file mode 100644
index 0000000..f3b9302
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Embedded BI
+
+
+
+
+
+
+
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/main.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/main.ts
new file mode 100644
index 0000000..a2f708c
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/main.ts
@@ -0,0 +1,20 @@
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+export function getBaseUrl() {
+ return document.getElementsByTagName('base')[0].href;
+}
+
+const providers = [
+ { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
+];
+
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic(providers).bootstrapModule(AppModule)
+ .catch(err => console.log(err));
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/polyfills.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/polyfills.ts
new file mode 100644
index 0000000..373f538
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/polyfills.ts
@@ -0,0 +1,65 @@
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ * file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/guide/browser-support
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/**
+ * IE11 requires the following for NgClass support on SVG elements
+ */
+// import 'classlist.js'; // Run `npm install --save classlist.js`.
+
+/**
+ * Web Animations `@angular/platform-browser/animations`
+ * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
+ * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
+ */
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+/**
+ * By default, zone.js will patch all possible macroTask and DomEvents
+ * user can disable parts of macroTask/DomEvents patch by setting following flags
+ * because those flags need to be set before `zone.js` being loaded, and webpack
+ * will put import in the top of bundle, so user need to create a separate file
+ * in this directory (for example: zone-flags.ts), and put the following flags
+ * into that file, and then add the following code before importing zone.js.
+ * import './zone-flags';
+ *
+ * The flags allowed in zone-flags.ts are listed here.
+ *
+ * The following flags will work for all browsers.
+ *
+ * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
+ * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
+ * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
+ *
+ * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
+ * with the following flag, it will bypass `zone.js` patch for IE/Edge
+ *
+ * (window as any).__Zone_enable_cross_context_check = true;
+ *
+ */
+
+/***************************************************************************************************
+ * Zone JS is required by default for Angular itself.
+ */
+import 'zone.js'; // Included with Angular CLI.
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/styles.css b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/styles.css
new file mode 100644
index 0000000..0fb2d30
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/styles.css
@@ -0,0 +1,20 @@
+/* You can add global styles to this file, and also import other style files */
+
+/* Provide sufficient contrast against white background */
+a {
+ color: #0366d6;
+}
+
+.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
+ box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
+}
+
+code {
+ color: #e01a76;
+}
+
+.btn-primary {
+ color: #fff;
+ background-color: #1b6ec2;
+ border-color: #1861ac;
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/test.ts b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/test.ts
new file mode 100644
index 0000000..8e1c568
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/src/test.ts
@@ -0,0 +1,13 @@
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
+
+import 'zone.js/testing';
+import { getTestBed } from '@angular/core/testing';
+import {
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+getTestBed().initTestEnvironment(
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting()
+);
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.app.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.app.json
new file mode 100644
index 0000000..82d91dc
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.app.json
@@ -0,0 +1,15 @@
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/app",
+ "types": []
+ },
+ "files": [
+ "src/main.ts",
+ "src/polyfills.ts"
+ ],
+ "include": [
+ "src/**/*.d.ts"
+ ]
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.json
new file mode 100644
index 0000000..51bd841
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.json
@@ -0,0 +1,30 @@
+{
+ "compileOnSave": false,
+ "compilerOptions": {
+ "baseUrl": "./",
+ "outDir": "./dist/out-tsc",
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+ "sourceMap": true,
+ "declaration": false,
+ "downlevelIteration": true,
+ "experimentalDecorators": true,
+ "moduleResolution": "node",
+ "importHelpers": true,
+ "target": "es2022",
+ "module": "es2020",
+ "lib": [
+ "es2018",
+ "dom"
+ ],
+ "useDefineForClassFields": false
+ },
+ "angularCompilerOptions": {
+ "enableI18nLegacyMessageIdFormat": false,
+ "strictInjectionParameters": true,
+ "strictInputAccessModifiers": true,
+ "strictTemplates": true
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.spec.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.spec.json
new file mode 100644
index 0000000..1762d06
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/ClientApp/tsconfig.spec.json
@@ -0,0 +1,19 @@
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/spec",
+ "types": [
+ "jasmine",
+ "node"
+ ]
+ },
+ "files": [
+ "src/test.ts",
+ "src/polyfills.ts"
+ ],
+ "include": [
+ "src/**/*.spec.ts",
+ "src/**/*.d.ts"
+ ]
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Controllers/BoldBIEmbedController.cs b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Controllers/BoldBIEmbedController.cs
new file mode 100644
index 0000000..19bd712
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Controllers/BoldBIEmbedController.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Net.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Threading.Tasks;
+using System.IO;
+
+namespace Angular_with_ASP.NETCore.Controllers
+{
+ [ApiController]
+ [Route("api/[controller]")]
+ public class BoldBIEmbedController : Controller
+ {
+ [HttpGet]
+ [Route("GetData")]
+ public IActionResult GetData()
+ {
+ var jsonData = System.IO.File.ReadAllText("embedConfig.json");
+ string basePath = AppDomain.CurrentDomain.BaseDirectory;
+ string jsonString = System.IO.File.ReadAllText(Path.Combine(basePath, "embedConfig.json"));
+ GlobalAppSettings.EmbedDetails = JsonConvert.DeserializeObject(jsonString);
+
+ return Json(new
+ {
+ DashboardId = GlobalAppSettings.EmbedDetails.DashboardId,
+ ServerUrl = GlobalAppSettings.EmbedDetails.ServerUrl,
+ EmbedType = GlobalAppSettings.EmbedDetails.EmbedType,
+ Environment = GlobalAppSettings.EmbedDetails.Environment,
+ SiteIdentifier = GlobalAppSettings.EmbedDetails.SiteIdentifier
+ });
+ }
+
+ [HttpGet]
+ [Route("GetDashboards")]
+ public string GetDashboards()
+ {
+ var token = GetToken();
+
+ using (var client = new HttpClient())
+ {
+ client.BaseAddress = new Uri(GlobalAppSettings.EmbedDetails.ServerUrl);
+ client.DefaultRequestHeaders.Accept.Clear();
+ client.DefaultRequestHeaders.Add("Authorization", token.TokenType + " " + token.AccessToken);
+ var result = client.GetAsync(GlobalAppSettings.EmbedDetails.ServerUrl + "/api/" + GlobalAppSettings.EmbedDetails.SiteIdentifier + "/v2.0/items?ItemType=2").Result;
+ string resultContent = result.Content.ReadAsStringAsync().Result;
+ return resultContent;
+ }
+ }
+
+ public Token GetToken()
+ {
+ using (var client = new HttpClient())
+ {
+ client.BaseAddress = new Uri(GlobalAppSettings.EmbedDetails.ServerUrl);
+ client.DefaultRequestHeaders.Accept.Clear();
+
+ var content = new FormUrlEncodedContent(new[]
+ {
+ new KeyValuePair("grant_type", "embed_secret"),
+ new KeyValuePair("Username", GlobalAppSettings.EmbedDetails.UserEmail),
+ new KeyValuePair("embed_secret", GlobalAppSettings.EmbedDetails.EmbedSecret)
+ });
+ var result = client.PostAsync(GlobalAppSettings.EmbedDetails.ServerUrl + "/api/" + GlobalAppSettings.EmbedDetails.SiteIdentifier + "/token", content).Result;
+ string resultContent = result.Content.ReadAsStringAsync().Result;
+ var response = JsonConvert.DeserializeObject(resultContent);
+ return response;
+ }
+ }
+
+ [HttpPost]
+ [Route("AuthorizationServer")]
+ public string AuthorizationServer([FromBody] object embedQuerString)
+ {
+ var embedClass = Newtonsoft.Json.JsonConvert.DeserializeObject(embedQuerString.ToString());
+
+ var embedQuery = embedClass.embedQuerString;
+ // User your user-email as embed_user_email
+ embedQuery += "&embed_user_email=" + GlobalAppSettings.EmbedDetails.UserEmail;
+ //To set embed_server_timestamp to overcome the EmbedCodeValidation failing while different timezone using at client application.
+ double timeStamp = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
+ embedQuery += "&embed_server_timestamp=" + timeStamp;
+ var embedDetailsUrl = "/embed/authorize?" + embedQuery + "&embed_signature=" + GetSignatureUrl(embedQuery);
+
+ using (var client = new HttpClient())
+ {
+ client.BaseAddress = new Uri(embedClass.dashboardServerApiUrl);
+ client.DefaultRequestHeaders.Accept.Clear();
+
+ var result = client.GetAsync(embedClass.dashboardServerApiUrl + embedDetailsUrl).Result;
+ string resultContent = result.Content.ReadAsStringAsync().Result;
+ return resultContent;
+ }
+
+ }
+
+ public string GetSignatureUrl(string queryString)
+ {
+ if (queryString != null)
+ {
+ var encoding = new System.Text.UTF8Encoding();
+ var keyBytes = encoding.GetBytes(GlobalAppSettings.EmbedDetails.EmbedSecret);
+ var messageBytes = encoding.GetBytes(queryString);
+ using (var hmacsha1 = new HMACSHA256(keyBytes))
+ {
+ var hashMessage = hmacsha1.ComputeHash(messageBytes);
+ return Convert.ToBase64String(hashMessage);
+ }
+ }
+ return string.Empty;
+ }
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Model/DataClass.cs b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Model/DataClass.cs
new file mode 100644
index 0000000..67bdee3
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Model/DataClass.cs
@@ -0,0 +1,91 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Threading.Tasks;
+
+ [DataContract]
+ public class EmbedClass
+ {
+ [DataMember]
+ public string embedQuerString { get; set; }
+ [DataMember]
+ public string dashboardServerApiUrl { get; set; }
+ }
+
+ public class TokenObject
+ {
+ public string Message { get; set; }
+
+ public string Status { get; set; }
+
+ public string Token { get; set; }
+ }
+
+ public class Token
+ {
+ [JsonProperty("access_token")]
+ public string AccessToken
+ {
+ get;
+ set;
+ }
+
+ [JsonProperty("token_type")]
+ public string TokenType
+ {
+ get;
+ set;
+ }
+
+ [JsonProperty("expires_in")]
+ public string ExpiresIn
+ {
+ get;
+ set;
+ }
+
+ [JsonProperty("email")]
+ public string Email
+ {
+ get;
+ set;
+ }
+
+
+ public string LoginResult
+ {
+ get;
+ set;
+ }
+
+ public string LoginStatusInfo
+ {
+ get;
+ set;
+ }
+
+ [JsonProperty(".issued")]
+ public string Issued { get; set; }
+
+ [JsonProperty(".expires")]
+ public string Expires { get; set; }
+ }
+
+ public class EmbedDetails
+ {
+ public string Environment { get; set; }
+
+ public string SiteIdentifier { get; set; }
+
+ public string ServerUrl { get; set; }
+
+ public string EmbedSecret { get; set; }
+
+ public string UserEmail { get; set; }
+
+ public string EmbedType { get; set; }
+
+ public string DashboardId { get; set; }
+ }
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Model/GlobalAppSettings.cs b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Model/GlobalAppSettings.cs
new file mode 100644
index 0000000..bd15a97
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Model/GlobalAppSettings.cs
@@ -0,0 +1,4 @@
+ public class GlobalAppSettings
+ {
+ public static EmbedDetails EmbedDetails { get; set; }
+ }
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Pages/_ViewImports.cshtml b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Pages/_ViewImports.cshtml
new file mode 100644
index 0000000..77d7fbe
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Pages/_ViewImports.cshtml
@@ -0,0 +1,3 @@
+@using Angular_with_ASP.NETCore
+@namespace Angular_with_ASP.NETCore.Pages
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Program.cs b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Program.cs
new file mode 100644
index 0000000..0345a78
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Program.cs
@@ -0,0 +1,34 @@
+using Newtonsoft.Json;
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+
+builder.Services.AddControllersWithViews();
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+if (!app.Environment.IsDevelopment())
+{
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+}
+
+app.UseHttpsRedirection();
+app.UseStaticFiles();
+app.UseRouting();
+
+app.UseCors(corsPolicyBuilder => corsPolicyBuilder
+.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
+
+string basePath = AppDomain.CurrentDomain.BaseDirectory;
+string jsonString = System.IO.File.ReadAllText(Path.Combine(basePath, "embedConfig.json"));
+GlobalAppSettings.EmbedDetails = JsonConvert.DeserializeObject(jsonString);
+
+app.MapControllerRoute(
+ name: "default",
+ pattern: "{BoldBIEmbed}/{action=GetData}/{id?}");
+
+app.MapFallbackToFile("index.html");
+
+app.Run();
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Properties/launchSettings.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Properties/launchSettings.json
new file mode 100644
index 0000000..8a68c8e
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:55063",
+ "sslPort": 44365
+ }
+ },
+ "profiles": {
+ "Angular_with_ASP.NETCore": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:7051;http://localhost:5210",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
+ }
+ }
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/appsettings.Development.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/appsettings.Development.json
new file mode 100644
index 0000000..84308c9
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/appsettings.Development.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.AspNetCore.SpaProxy": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/appsettings.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/appsettings.json
new file mode 100644
index 0000000..ad75fee
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+"AllowedHosts": "*"
+}
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/package.json b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/package.json
new file mode 100644
index 0000000..58d8824
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "angular-sample",
+ "version": "0.0.0",
+ "scripts": {
+ "ng": "ng",
+ "start": "ng serve",
+ "build": "ng build",
+ "watch": "ng build --watch --configuration development",
+ "test": "ng test"
+ },
+ "private": true,
+ "dependencies": {
+ "@boldbi/boldbi-embedded-sdk": "6.15.11",
+ "@angular/animations": "^14.0.0",
+ "@angular/common": "^14.0.0",
+ "@angular/compiler": "^14.0.0",
+ "@angular/core": "^14.0.0",
+ "@angular/forms": "^14.0.0",
+ "@angular/platform-browser": "^14.0.0",
+ "@angular/platform-browser-dynamic": "^14.0.0",
+ "@angular/router": "^14.0.0",
+ "rxjs": "~7.5.0",
+ "tslib": "^2.3.0",
+ "zone.js": "~0.11.4",
+ "@angular-devkit/build-angular": "^14.0.0",
+ "@angular/cli": "^14.0.6",
+ "@angular/compiler-cli": "^14.0.0"
+ }
+ }
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/wwwroot/favicon.ico b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/wwwroot/favicon.ico
new file mode 100644
index 0000000..63e859b
Binary files /dev/null and b/Scenario Based Samples/MultitabDashboard-URL-linking/Angular-with-ASP.NETCore/wwwroot/favicon.ico differ
diff --git a/Scenario Based Samples/MultitabDashboard-URL-linking/README.md b/Scenario Based Samples/MultitabDashboard-URL-linking/README.md
new file mode 100644
index 0000000..c507ce5
--- /dev/null
+++ b/Scenario Based Samples/MultitabDashboard-URL-linking/README.md
@@ -0,0 +1,110 @@
+# Bold BI Embedded Sample in Angular with ASP.NET Core
+
+This project was created using Angular and ASP.NET Core 6.0. This application aims to demonstrate how to render the dashboard available on your Bold BI server.
+
+## Dashboard view
+
+
+
+
+ ## Requirements/Prerequisites
+
+ * [.NET Core 6.0](https://dotnet.microsoft.com/en-us/download/dotnet-core)
+ * [Node.js](https://nodejs.org/en/)
+
+ > **NOTE:** Node.js v14.20 to v18.18 are supported
+
+ #### Help link
+
+ * https://help.boldbi.com/embedded-bi/faq/where-can-i-find-the-product-version/
+
+ #### Supported browsers
+
+ * Google Chrome, Microsoft Edge, Mozilla Firefox, and Safari.
+
+ ## Configuration
+
+ * Please [get](https://github.com/boldbi/angular-with-aspnet-core-sample/tree/master/Angular-with-ASP.NETCore) the Angular with ASP.NET Core sample from GitHub.
+
+ * Please ensure you have enabled embed authentication on the `embed settings` page. If it is not currently enabled, please refer to the following image or detailed [instructions](https://help.boldbi.com/site-administration/embed-settings/#get-embed-secret-code) to enable it.
+ 
+
+ * To download the `embedConfig.json` file, please follow this [link](https://help.boldbi.com/site-administration/embed-settings/#get-embed-configuration-file) for reference. Additionally, you can refer to the following image for visual guidance.
+ 
+ 
+
+ * Copy the downloaded `embedConfig.json` file and paste it into the designated [location](https://github.com/boldbi/angular-with-aspnet-core-sample/tree/master/Angular-with-ASP.NETCore) within the application. Please ensure you have placed it in the application, as shown in the following image.
+
+ 
+
+## Run a Sample Using Command Line Interface
+
+ 1. Open the command line interface and navigate to the specified file [location](https://github.com/boldbi/angular-with-aspnet-core-sample/tree/master/Angular-with-ASP.NETCore) where the project is located.
+
+ 2. To install all dependent packages using the following command `npm install`.
+
+ 3. Execute the command `dotnet restore` to restore the necessary packages. Once the packages have been successfully restored, use the `dotnet build` command to build the project.
+
+ 4. Finally, run the application using the command `dotnet run`. After executing the command, the application will automatically launch in the default browser. You can access it at the specified port number (e.g., https://localhost:44459).
+
+ ## Developer IDE
+
+ * Visual studio code(https://code.visualstudio.com/download)
+
+ ### Run a Sample Using Visual Studio Code
+
+ 1. Open the Angular with ASP.NET Core sample in Visual Studio Code.
+
+ 2. Open the terminal in Visual Studio Code and install all dependent packages using the following command `npm install`.
+
+ 3. Execute the command `dotnet restore` to restore the required dependencies.
+
+ 4. Build your .NET project by executing the `dotnet build` command in the terminal.
+
+ 5. To run the application, use the command `dotnet run` in the terminal. After executing the command, the application will automatically launch in the default browser. You can access it at the specified port number (e.g., https://localhost:44459).
+
+ 
+
+Please refer to the [help documentation](https://help.boldbi.com/embedding-options/embedding-sdk/samples/angular-with-javascript/#how-to-run-the-sample) to know how to run the sample.
+
+## How the sample works
+
+ * In javascript based embedding the member api `hideMultiDashboardHeader` can be used to enable or disable the tab area in the header of a Multitab dashboard.Please refer to this [help documentation](https://help.boldbi.com/embedding-options/embedding-sdk/embedding-api-reference/members/#hideMultiDashboardHeader) to know more about the member.
+
+
+
+ * In this sample,when you embed a Multitab dashboard the tab area for dashboard switching will be hidden.You can navigate from first dashboard to other dashboards only by linking their URL inside widgets.
+
+ > **NOTE:** No need to hook any event in application for url linking like `beforeNavigateUrlLinking` for dashboard navigation.
+
+ > **NOTE:** This member will not hide header of a Multitab dashboard loaded using loadMultitabDashboard() method.
+
+
+### How to link URL in a Dashboard
+
+ 1. In your Bold BI application,open the dashboard in edit mode.
+
+ 2. Inside it choose a widget where you want to link another dashboard.
+
+ 3. Click settings icon of the widget and enable `Enable link` option. Provide value in the `URL` field by referring to this [link](https://help.boldbi.com/visualizing-data/working-with-widgets/linking-urls-and-dashboards/#dashboard-parameter-support-in-url-linking)
+
+ > **NOTE:** Link only a child dashboard of a multi tab dashboard to render dashboard within the application.
+
+ 
+
+ 4. In this way you can link many dashboards inside other widgets.
+
+ 5. To know more details about linking dashboards [here](https://help.boldbi.com/visualizing-data/working-with-widgets/linking-urls-and-dashboards/)
+
+## Important notes
+
+It is recommended not to store passwords and sensitive information in configuration files for security reasons in a real-world application. Instead, it would be best if you considered using a secure application, such as Key Vault, to safeguard your credentials.
+
+## Online demos
+
+Look at the Bold BI Embedding sample to live demo [here](https://samples.boldbi.com/embed).
+
+
+## Documentation
+
+A complete Bold BI Embedding documentation can be found on [Bold BI Embedding Help](https://help.boldbi.com/embedded-bi/javascript-based/).