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 + +![Dashboard View](https://github.com/boldbi/samples/assets/149655444/192b6b0a-445d-424c-969c-7585af0f684b) + + + ## 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. + ![Embed Settings](https://github.com/boldbi/aspnet-core-sample/assets/91586758/b3a81978-9eb4-42b2-92bb-d1e2735ab007) + + * 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. + ![Embed Settings Download](https://github.com/boldbi/aspnet-core-sample/assets/91586758/d27d4cfc-6a3e-4c34-975e-f5f22dea6172) + ![EmbedConfig Properties](https://github.com/boldbi/aspnet-core-sample/assets/91586758/d6ce925a-0d4c-45d2-817e-24d6d59e0d63) + + * 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. + + ![EmbedConfig image](https://github.com/boldbi/aspnet-core-sample/assets/91586758/95e8e272-53e8-449a-8a46-592cf8646d7c) + +## 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). + + ![dashboard view](https://github.com/boldbi/aspnet-core-sample/assets/91586758/af9a9d3f-3ebc-49dd-9bba-a061932cb9f6) + +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. + +![multitab-linking-renderDashboard](https://github.com/boldbi/samples/assets/149655444/2bd83601-2822-4cd9-a501-5e48fb37472a) + + * 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. + + ![multitab-linking-url](https://github.com/boldbi/samples/assets/149655444/ce7b1b5a-8c97-43be-8496-d2063c083ad5) + + 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/).