powerbi-visuals-tools 7.0.0 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +4 -0
- package/certs/blank +0 -0
- package/lib/CertificateTools.js +262 -0
- package/lib/CommandManager.js +75 -0
- package/lib/ConsoleWriter.js +188 -0
- package/lib/FeatureManager.js +43 -0
- package/lib/LintValidator.js +61 -0
- package/lib/Package.js +46 -0
- package/lib/TemplateFetcher.js +111 -0
- package/lib/Visual.js +29 -0
- package/lib/VisualGenerator.js +221 -0
- package/lib/VisualManager.js +316 -0
- package/lib/WebPackWrap.js +274 -0
- package/lib/features/APIVersion.js +16 -0
- package/lib/features/AdvancedEditMode.js +12 -0
- package/lib/features/AllowInteractions.js +12 -0
- package/lib/features/AnalyticsPane.js +17 -0
- package/lib/features/BaseFeature.js +9 -0
- package/lib/features/Bookmarks.js +12 -0
- package/lib/features/ColorPalette.js +12 -0
- package/lib/features/ConditionalFormatting.js +12 -0
- package/lib/features/ContextMenu.js +12 -0
- package/lib/features/DrillDown.js +16 -0
- package/lib/features/FeatureTypes.js +23 -0
- package/lib/features/FetchMoreData.js +22 -0
- package/lib/features/FileDownload.js +12 -0
- package/lib/features/FormatPane.js +12 -0
- package/lib/features/HighContrast.js +12 -0
- package/lib/features/HighlightData.js +12 -0
- package/lib/features/KeyboardNavigation.js +12 -0
- package/lib/features/LandingPage.js +12 -0
- package/lib/features/LaunchURL.js +12 -0
- package/lib/features/LocalStorage.js +12 -0
- package/lib/features/Localizations.js +12 -0
- package/lib/features/ModalDialog.js +12 -0
- package/lib/features/RenderingEvents.js +13 -0
- package/lib/features/SelectionAcrossVisuals.js +12 -0
- package/lib/features/SyncSlicer.js +12 -0
- package/lib/features/Tooltips.js +12 -0
- package/lib/features/TotalSubTotal.js +12 -0
- package/lib/features/VisualVersion.js +12 -0
- package/lib/features/WarningIcon.js +12 -0
- package/lib/features/index.js +28 -0
- package/lib/utils.js +43 -0
- package/lib/webpack.config.js +169 -0
- package/package.json +7 -6
- package/.eslintrc.json +0 -21
- package/CVClientLA.md +0 -85
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import webpack from 'webpack';
|
|
6
|
+
import util from 'util';
|
|
7
|
+
const exec = util.promisify(processExec);
|
|
8
|
+
import { exec as processExec } from 'child_process';
|
|
9
|
+
import lodashCloneDeep from 'lodash.clonedeep';
|
|
10
|
+
import ExtraWatchWebpackPlugin from 'extra-watch-webpack-plugin';
|
|
11
|
+
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
|
12
|
+
import { PowerBICustomVisualsWebpackPlugin, LocalizationLoader } from 'powerbi-visuals-webpack-plugin';
|
|
13
|
+
import ConsoleWriter from './ConsoleWriter.js';
|
|
14
|
+
import { resolveCertificate } from "./CertificateTools.js";
|
|
15
|
+
import { readJsonFromRoot, readJsonFromVisual } from './utils.js';
|
|
16
|
+
const config = await readJsonFromRoot('config.json');
|
|
17
|
+
const npmPackage = await readJsonFromRoot('package.json');
|
|
18
|
+
const visualPlugin = "visualPlugin.ts";
|
|
19
|
+
const encoding = "utf8";
|
|
20
|
+
export default class WebPackWrap {
|
|
21
|
+
pbiviz;
|
|
22
|
+
webpackConfig;
|
|
23
|
+
static async prepareFoldersAndFiles(visualPackage) {
|
|
24
|
+
const tmpFolder = path.join(visualPackage.basePath, ".tmp");
|
|
25
|
+
const precompileFolder = path.join(visualPackage.basePath, config.build.precompileFolder);
|
|
26
|
+
const dropFolder = path.join(visualPackage.basePath, config.build.dropFolder);
|
|
27
|
+
const packageDropFolder = path.join(visualPackage.basePath, config.package.dropFolder);
|
|
28
|
+
const visualPluginFile = path.join(visualPackage.basePath, config.build.precompileFolder, visualPlugin);
|
|
29
|
+
await fs.ensureDir(tmpFolder);
|
|
30
|
+
await fs.ensureDir(precompileFolder);
|
|
31
|
+
await fs.ensureDir(dropFolder);
|
|
32
|
+
await fs.ensureDir(packageDropFolder);
|
|
33
|
+
await fs.createFile(visualPluginFile);
|
|
34
|
+
}
|
|
35
|
+
static loadAPIPackage() {
|
|
36
|
+
const apiPath = path.join(process.cwd(), "node_modules", "powerbi-visuals-api");
|
|
37
|
+
const doesAPIExist = fs.pathExistsSync(apiPath);
|
|
38
|
+
if (!doesAPIExist) {
|
|
39
|
+
ConsoleWriter.error(`Can't find powerbi-visuals-api package`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
return import("file://" + path.join(apiPath, "index.js"));
|
|
43
|
+
}
|
|
44
|
+
async installAPIpackage() {
|
|
45
|
+
const apiVersion = this.pbiviz.apiVersion ? `~${this.pbiviz.apiVersion}` : "latest";
|
|
46
|
+
try {
|
|
47
|
+
ConsoleWriter.info(`Installing API: ${apiVersion}...`);
|
|
48
|
+
const { stdout, stderr } = await exec(`npm install --save powerbi-visuals-api@${apiVersion}`);
|
|
49
|
+
if (stdout)
|
|
50
|
+
ConsoleWriter.info(stdout);
|
|
51
|
+
if (stderr)
|
|
52
|
+
ConsoleWriter.warning(stderr);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
catch (ex) {
|
|
56
|
+
if (ex.message.indexOf("No matching version found for powerbi-visuals-api") !== -1) {
|
|
57
|
+
throw new Error(`Error: Invalid API version: ${apiVersion}`);
|
|
58
|
+
}
|
|
59
|
+
ConsoleWriter.error(`npm install powerbi-visuals-api@${apiVersion} failed`);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
enableOptimization() {
|
|
64
|
+
this.webpackConfig.mode = "production";
|
|
65
|
+
this.webpackConfig.optimization = {
|
|
66
|
+
concatenateModules: false,
|
|
67
|
+
minimize: true
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async configureDevServer(visualPackage, port = 8080) {
|
|
71
|
+
const options = await resolveCertificate();
|
|
72
|
+
this.webpackConfig.devServer = {
|
|
73
|
+
...this.webpackConfig.devServer,
|
|
74
|
+
hot: false,
|
|
75
|
+
port,
|
|
76
|
+
static: {
|
|
77
|
+
directory: path.join(visualPackage.basePath, config.build.dropFolder),
|
|
78
|
+
publicPath: config.server.assetsRoute
|
|
79
|
+
},
|
|
80
|
+
server: {
|
|
81
|
+
type: 'https',
|
|
82
|
+
options: {
|
|
83
|
+
key: options.key,
|
|
84
|
+
cert: options.cert,
|
|
85
|
+
pfx: options.pfx,
|
|
86
|
+
passphrase: options.passphrase
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
configureVisualPlugin(options, tsconfig, visualPackage) {
|
|
92
|
+
const visualJSFilePath = tsconfig.compilerOptions.out || tsconfig.compilerOptions.outDir;
|
|
93
|
+
this.webpackConfig.output.path = path.join(visualPackage.basePath, config.build.dropFolder);
|
|
94
|
+
this.webpackConfig.output.filename = "[name]";
|
|
95
|
+
const visualPluginPath = path.join(process.cwd(), config.build.precompileFolder, visualPlugin);
|
|
96
|
+
this.webpackConfig.watchOptions.ignored.push(visualPluginPath);
|
|
97
|
+
if (tsconfig.compilerOptions.out) {
|
|
98
|
+
this.webpackConfig.entry = {
|
|
99
|
+
"visual.js": visualJSFilePath
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.webpackConfig.entry["visual.js"] = [visualPluginPath];
|
|
104
|
+
this.webpackConfig.output.library = `${this.pbiviz.visual.guid}${options.devMode ? "_DEBUG" : ""}`;
|
|
105
|
+
this.webpackConfig.output.libraryTarget = 'var';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async getEnvironmentDetails() {
|
|
109
|
+
const env = {
|
|
110
|
+
nodeVersion: process.versions.node,
|
|
111
|
+
osPlatform: await os.platform(),
|
|
112
|
+
osVersion: await os.version ?? "undefined",
|
|
113
|
+
osReleaseVersion: await os.release(),
|
|
114
|
+
toolsVersion: npmPackage.version
|
|
115
|
+
};
|
|
116
|
+
return env;
|
|
117
|
+
}
|
|
118
|
+
async configureCustomVisualsWebpackPlugin(visualPackage, options, tsconfig) {
|
|
119
|
+
if (options.skipApiCheck) {
|
|
120
|
+
ConsoleWriter.warning(`Skipping API check. Tools started with --skipApi flag.`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
await this.configureAPIVersion();
|
|
124
|
+
}
|
|
125
|
+
const api = await WebPackWrap.loadAPIPackage();
|
|
126
|
+
const dependenciesPath = typeof this.pbiviz.dependencies === "string" && path.join(process.cwd(), this.pbiviz.dependencies);
|
|
127
|
+
let pluginConfiguration = {
|
|
128
|
+
...lodashCloneDeep(visualPackage.pbivizConfig),
|
|
129
|
+
apiVersion: api.version,
|
|
130
|
+
capabilitiesSchema: api.schemas.capabilities,
|
|
131
|
+
pbivizSchema: api.schemas.pbiviz,
|
|
132
|
+
stringResourcesSchema: api.schemas.stringResources,
|
|
133
|
+
dependenciesSchema: api.schemas.dependencies,
|
|
134
|
+
customVisualID: `CustomVisual_${this.pbiviz.visual.guid}`.replace(/[^\w\s]/gi, ''),
|
|
135
|
+
devMode: options.devMode,
|
|
136
|
+
generatePbiviz: options.generatePbiviz,
|
|
137
|
+
generateResources: options.generateResources,
|
|
138
|
+
minifyJS: options.minifyJS,
|
|
139
|
+
dependencies: fs.existsSync(dependenciesPath) ? this.pbiviz.dependencies : null,
|
|
140
|
+
modules: typeof tsconfig.compilerOptions.outDir !== "undefined",
|
|
141
|
+
visualSourceLocation: path.posix.relative(config.build.precompileFolder, tsconfig.files[0]).replace(/(\.ts)x|\.ts/, ""),
|
|
142
|
+
pluginLocation: path.join(config.build.precompileFolder, "visualPlugin.ts"),
|
|
143
|
+
compression: options.compression,
|
|
144
|
+
certificationAudit: options.certificationAudit,
|
|
145
|
+
certificationFix: options.certificationFix,
|
|
146
|
+
};
|
|
147
|
+
return pluginConfiguration;
|
|
148
|
+
}
|
|
149
|
+
async configureAPIVersion() {
|
|
150
|
+
//(?<=powerbi-visuals-api@) - positive look-behind to find version installed in visual and get 3 level version.
|
|
151
|
+
const regexFullVersion = /(?<=powerbi-visuals-api@)((?:\d+\.?){1,3})/g;
|
|
152
|
+
//get only first 2 parts of version
|
|
153
|
+
const regexMajorVersion = /\d+(?:\.\d+)?/;
|
|
154
|
+
let listResults;
|
|
155
|
+
try {
|
|
156
|
+
listResults = (await exec('npm list powerbi-visuals-api version')).stdout;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
listResults = error.stdout;
|
|
160
|
+
}
|
|
161
|
+
const installedAPIVersion = listResults.match(regexFullVersion)?.[0] ?? "not found";
|
|
162
|
+
const doesAPIExist = fs.pathExistsSync(path.join(process.cwd(), "node_modules", "powerbi-visuals-api"));
|
|
163
|
+
// if the powerbi-visual-api package wasn't installed install the powerbi-visual-api,
|
|
164
|
+
// with version from apiVersion in pbiviz.json or the latest API, if apiVersion is absent in pbiviz.json
|
|
165
|
+
const isAPIConfigured = doesAPIExist && installedAPIVersion && this.pbiviz.apiVersion;
|
|
166
|
+
if (!isAPIConfigured || this.pbiviz.apiVersion.match(regexMajorVersion)[0] != installedAPIVersion.match(regexMajorVersion)[0]) {
|
|
167
|
+
ConsoleWriter.warning(`installed "powerbi-visuals-api" version - "${installedAPIVersion}", is not match with the version specified in pbviz.json - "${this.pbiviz.apiVersion}".`);
|
|
168
|
+
await this.installAPIpackage();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async appendPlugins(options, visualPackage, tsconfig) {
|
|
172
|
+
const pluginConfiguration = await this.configureCustomVisualsWebpackPlugin(visualPackage, options, tsconfig);
|
|
173
|
+
let statsFilename = config.build.stats.split("/").pop();
|
|
174
|
+
const statsLocation = config.build.stats.split("/").slice(0, -1).join(path.sep);
|
|
175
|
+
statsFilename = statsFilename?.split(".").slice(0, -1).join(".");
|
|
176
|
+
statsFilename = `${statsFilename}.${options.devMode ? "dev" : "prod"}.html`;
|
|
177
|
+
if (options.stats) {
|
|
178
|
+
this.webpackConfig.plugins.push(new BundleAnalyzerPlugin({
|
|
179
|
+
reportFilename: path.join(statsLocation, statsFilename),
|
|
180
|
+
openAnalyzer: false,
|
|
181
|
+
analyzerMode: `static`
|
|
182
|
+
}));
|
|
183
|
+
}
|
|
184
|
+
this.webpackConfig.plugins.push(new PowerBICustomVisualsWebpackPlugin(pluginConfiguration), new ExtraWatchWebpackPlugin({
|
|
185
|
+
files: this.pbiviz.capabilities
|
|
186
|
+
}));
|
|
187
|
+
// Only add separate source map files when NOT using inline source maps
|
|
188
|
+
if (options.devMode && options.devtool && this.webpackConfig.devServer.port &&
|
|
189
|
+
options.devtool !== "inline-source-map") {
|
|
190
|
+
this.webpackConfig.plugins.push(new webpack.SourceMapDevToolPlugin({
|
|
191
|
+
filename: '[file].map',
|
|
192
|
+
publicPath: `https://localhost:${this.webpackConfig.devServer.port}/assets/`
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async configureLoaders({ fast = false, includeAllLocales = false }) {
|
|
197
|
+
this.webpackConfig.module.rules.push({
|
|
198
|
+
test: /(\.ts)x?$/,
|
|
199
|
+
use: [
|
|
200
|
+
{
|
|
201
|
+
loader: "ts-loader",
|
|
202
|
+
options: fast
|
|
203
|
+
? {
|
|
204
|
+
transpileOnly: false,
|
|
205
|
+
experimentalWatchApi: false
|
|
206
|
+
}
|
|
207
|
+
: {}
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
if (!includeAllLocales) {
|
|
212
|
+
this.webpackConfig.module.rules.push({
|
|
213
|
+
test: /powerbiGlobalizeLocales\.js$/, // path to file with all locales declared in formattingutils
|
|
214
|
+
loader: LocalizationLoader
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async prepareWebPackConfig(visualPackage, options, tsconfig) {
|
|
219
|
+
this.webpackConfig = Object.assign({}, await import('./webpack.config.js')).default;
|
|
220
|
+
// Set webpack mode based on devMode
|
|
221
|
+
if (options.devMode) {
|
|
222
|
+
this.webpackConfig.mode = "development";
|
|
223
|
+
}
|
|
224
|
+
if (options.minifyJS) {
|
|
225
|
+
this.enableOptimization();
|
|
226
|
+
}
|
|
227
|
+
if (options.devtool) {
|
|
228
|
+
this.webpackConfig.devtool = options.devtool;
|
|
229
|
+
}
|
|
230
|
+
await this.appendPlugins(options, visualPackage, tsconfig);
|
|
231
|
+
await this.configureDevServer(visualPackage, options.devServerPort);
|
|
232
|
+
await this.configureVisualPlugin(options, tsconfig, visualPackage);
|
|
233
|
+
await this.configureLoaders({
|
|
234
|
+
fast: options.fast,
|
|
235
|
+
includeAllLocales: options.allLocales
|
|
236
|
+
});
|
|
237
|
+
return this.webpackConfig;
|
|
238
|
+
}
|
|
239
|
+
async assemblyExternalJSFiles(visualPackage) {
|
|
240
|
+
const externalJSFilesContent = "";
|
|
241
|
+
const externalJSFilesPath = path.join(visualPackage.basePath, config.build.precompileFolder, "externalJS.js");
|
|
242
|
+
await fs.writeFile(externalJSFilesPath, externalJSFilesContent, {
|
|
243
|
+
encoding: encoding
|
|
244
|
+
});
|
|
245
|
+
return externalJSFilesPath;
|
|
246
|
+
}
|
|
247
|
+
async generateWebpackConfig(visualPackage, options = {
|
|
248
|
+
devMode: false,
|
|
249
|
+
generateResources: false,
|
|
250
|
+
generatePbiviz: false,
|
|
251
|
+
minifyJS: true,
|
|
252
|
+
minify: true,
|
|
253
|
+
devServerPort: 8080,
|
|
254
|
+
fast: false,
|
|
255
|
+
compression: 0,
|
|
256
|
+
stats: true,
|
|
257
|
+
skipApiCheck: false,
|
|
258
|
+
allLocales: false,
|
|
259
|
+
pbivizFile: 'pbiviz.json',
|
|
260
|
+
certificationAudit: false,
|
|
261
|
+
certificationFix: false,
|
|
262
|
+
}) {
|
|
263
|
+
const tsconfig = await readJsonFromVisual('tsconfig.json');
|
|
264
|
+
this.pbiviz = await readJsonFromVisual(options.pbivizFile);
|
|
265
|
+
const capabilitiesPath = this.pbiviz.capabilities;
|
|
266
|
+
visualPackage.pbivizConfig.capabilities = capabilitiesPath;
|
|
267
|
+
const dependenciesPath = this.pbiviz.dependencies && path.join(process.cwd(), this.pbiviz.dependencies);
|
|
268
|
+
const dependenciesFile = fs.existsSync(dependenciesPath) && JSON.parse(fs.readFileSync(dependenciesPath));
|
|
269
|
+
visualPackage.pbivizConfig.dependencies = typeof dependenciesFile === 'object' ? dependenciesFile : {};
|
|
270
|
+
await WebPackWrap.prepareFoldersAndFiles(visualPackage);
|
|
271
|
+
const webpackConfig = await this.prepareWebPackConfig(visualPackage, options, tsconfig);
|
|
272
|
+
return webpackConfig;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { readJsonFromRoot } from "../utils.js";
|
|
2
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
3
|
+
export default class APIVersion {
|
|
4
|
+
static featureName = "Api";
|
|
5
|
+
static severity = Severity.Error;
|
|
6
|
+
static stage = Stage.PreBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer;
|
|
8
|
+
static minAPIversion;
|
|
9
|
+
static errorMessage;
|
|
10
|
+
static async isSupported(visual) {
|
|
11
|
+
const globalConfig = await readJsonFromRoot('config.json');
|
|
12
|
+
this.minAPIversion = globalConfig.constants.minAPIversion;
|
|
13
|
+
this.errorMessage = `API version must be at least ${this.minAPIversion}.`;
|
|
14
|
+
return visual.doesAPIVersionMatch(this.minAPIversion);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class AdvancedEditMode {
|
|
3
|
+
static featureName = "Advanced Edit Mode";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/advanced-edit-mode";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return !packageInstance.isCapabilityEnabled({ advancedEditMode: 0 }); // 0 - Advanced edit mode is disabled
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class AllowInteractions {
|
|
3
|
+
static featureName = "Allow Interactions";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/visuals-interactions";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain('.allowInteractions');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class AnalyticsPane {
|
|
3
|
+
static featureName = "Analytics Pane";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/analytics-pane";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return (packageInstance.isCapabilityEnabled({
|
|
11
|
+
objects: {
|
|
12
|
+
objectCategory: 2
|
|
13
|
+
}
|
|
14
|
+
}) ||
|
|
15
|
+
packageInstance.contain("analyticsPane=true"));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class Bookmarks {
|
|
3
|
+
static featureName = "Bookmarks";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/bookmarks-support";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain("applySelectionFromFilter") || packageInstance.contain("registerOnSelectCallback");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class ColorPalette {
|
|
3
|
+
static featureName = "Color Palette";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/add-colors-power-bi-visual";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".colorPalette");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class ConditionalFormatting {
|
|
3
|
+
static featureName = "Conditional Formatting";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/conditional-format";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".createDataViewWildcardSelector");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class ContextMenu {
|
|
3
|
+
static featureName = "Context Menu";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/context-menu";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".showContextMenu");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class DrillDown {
|
|
3
|
+
static featureName = "Drill Down";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/drill-down-support";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({
|
|
11
|
+
drilldown: {
|
|
12
|
+
roles: []
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export var Severity;
|
|
2
|
+
(function (Severity) {
|
|
3
|
+
Severity["Error"] = "error";
|
|
4
|
+
Severity["Deprecation"] = "deprecation";
|
|
5
|
+
Severity["Warning"] = "warning";
|
|
6
|
+
Severity["Info"] = "info";
|
|
7
|
+
})(Severity || (Severity = {}));
|
|
8
|
+
export var Stage;
|
|
9
|
+
(function (Stage) {
|
|
10
|
+
Stage["PreBuild"] = "pre-build";
|
|
11
|
+
Stage["PostBuild"] = "post-build";
|
|
12
|
+
})(Stage || (Stage = {}));
|
|
13
|
+
export var VisualFeatureType;
|
|
14
|
+
(function (VisualFeatureType) {
|
|
15
|
+
VisualFeatureType[VisualFeatureType["NonSlicer"] = 2] = "NonSlicer";
|
|
16
|
+
VisualFeatureType[VisualFeatureType["Slicer"] = 4] = "Slicer";
|
|
17
|
+
VisualFeatureType[VisualFeatureType["Matrix"] = 8] = "Matrix";
|
|
18
|
+
VisualFeatureType[VisualFeatureType["All"] = 14] = "All";
|
|
19
|
+
})(VisualFeatureType || (VisualFeatureType = {}));
|
|
20
|
+
// Interaction types: Selection or filter (slicer)
|
|
21
|
+
// Slicer type: Basic, Advanced, Tuple filter, Identity filter
|
|
22
|
+
// Visual Type: TS/JS or R-Visual or RHTML
|
|
23
|
+
// Dataview Type: Single or Matrix or Table or Category or All
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class FetchMoreData {
|
|
3
|
+
static featureName = "Fetch More Data";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/fetch-more-data";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({
|
|
11
|
+
dataViewMappings: [
|
|
12
|
+
{
|
|
13
|
+
table: {
|
|
14
|
+
rows: {
|
|
15
|
+
dataReductionAlgorithm: {}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class FileDownload {
|
|
3
|
+
static featureName = "File Download";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/file-download-api";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".downloadService") && packageInstance.contain(".exportVisualsContent");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class FormatPane {
|
|
3
|
+
static featureName = "Format Pane";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/format-pane";
|
|
5
|
+
static severity = Severity.Deprecation;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.All;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain("getFormattingModel");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class HighContrast {
|
|
3
|
+
static featureName = "High Contrast";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/high-contrast-support";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".isHighContrast");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class HighlightData {
|
|
3
|
+
static featureName = "Highlight Data";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/highlight";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({ supportsHighlight: true });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class KeyboardNavigation {
|
|
3
|
+
static featureName = "Keyboard Navigation";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/supportskeyboardfocus-feature";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({ supportsKeyboardFocus: true });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class LandingPage {
|
|
3
|
+
static featureName = "Landing Page";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/landing-page";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({ supportsLandingPage: true });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class LaunchURL {
|
|
3
|
+
static featureName = "Launch URL";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/launch-url";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".launchUrl");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class LocalStorage {
|
|
3
|
+
static featureName = "Local Storage";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/local-storage";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".storageService");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class Localizations {
|
|
3
|
+
static featureName = "Localizations";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/localization";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".createLocalizationManager");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class ModalDialog {
|
|
3
|
+
static featureName = "Modal Dialog";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/create-display-dialog-box";
|
|
5
|
+
static severity = Severity.Info;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer | VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.contain(".openModalDialog");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class RenderingEvents {
|
|
3
|
+
static featureName = "Rendering Events";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/event-service";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.All;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
const keywords = [".eventService", ".renderingStarted", ".renderingFinished"];
|
|
11
|
+
return !keywords.some(keyword => !packageInstance.contain(keyword));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class SelectionAcrossVisuals {
|
|
3
|
+
static featureName = "Selection Across Visuals";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/supportsmultivisualselection-feature";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.NonSlicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({ supportsMultiVisualSelection: true });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Severity, Stage, VisualFeatureType } from "./FeatureTypes.js";
|
|
2
|
+
export default class SyncSlicer {
|
|
3
|
+
static featureName = "Sync Slicer";
|
|
4
|
+
static documentationLink = "https://learn.microsoft.com/en-us/power-bi/developer/visuals/enable-sync-slicers";
|
|
5
|
+
static severity = Severity.Warning;
|
|
6
|
+
static stage = Stage.PostBuild;
|
|
7
|
+
static visualFeatureType = VisualFeatureType.Slicer;
|
|
8
|
+
static errorMessage = `${this.featureName} - ${this.documentationLink}`;
|
|
9
|
+
static isSupported(packageInstance) {
|
|
10
|
+
return packageInstance.isCapabilityEnabled({ supportsSynchronizingFilterState: true });
|
|
11
|
+
}
|
|
12
|
+
}
|