Merge pull request #1 from qlik-oss/feature/QPE-402

[QPE-402] First take on build pipeline
This commit is contained in:
Martin Walter
2018-12-10 10:47:57 +01:00
committed by GitHub
37 changed files with 14800 additions and 2270 deletions

94
.circleci/config.yml Normal file
View File

@@ -0,0 +1,94 @@
version: 2
defaults: &defaults
working_directory: ~/qlik-smart-pivot
docker:
- image: circleci/node:stretch
environment:
GITHUB_ORG: "qlik-oss"
GITHUB_REPO: "PLSmartPivot"
PACKAGE_NAME: "qlik-smart-pivot"
jobs:
test:
docker:
- image: circleci/node:stretch-browsers
steps:
- checkout
- run:
name: Install dependencies
command: npm install
- run:
name: Run tests
command: npm run test-once
bump-version:
<<: *defaults
steps:
- checkout
- run:
name: Bump version
command: scripts/bump-version.sh $GITHUB_ORG $GITHUB_REPO
- persist_to_workspace:
root: ~/qlik-smart-pivot
paths:
- BUMPED_VERSION
build:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: ~/qlik-smart-pivot
- run:
name: Install dependencies
command: npm install
- run:
name: Build and package
command: |
export VERSION=$(scripts/get-bumped-version.sh)
echo "Version: ${VERSION}"
npm run build
environment:
NODE_ENV: production
- persist_to_workspace:
root: ~/qlik-smart-pivot
paths:
- build
- store_artifacts:
path: build
destination: build
deploy:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: ~/qlik-smart-pivot
- run:
name: Install ghr
command: scripts/install-ghr.sh
- run:
name: Create GitHub Release
command: |
export VERSION=$(scripts/get-bumped-version.sh)
echo "Version: ${VERSION}"
scripts/create-release.sh $GITHUB_ORG $GITHUB_REPO $PACKAGE_NAME $VERSION
workflows:
version: 2
master_flow:
jobs:
- test
- bump-version:
requires:
- test
- build:
requires:
- bump-version
- deploy:
requires:
- build
filters:
branches:
only:
- master

10
.editorconfig Normal file
View File

@@ -0,0 +1,10 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

65
.eslintrc.js Normal file
View File

@@ -0,0 +1,65 @@
module.exports = {
parserOptions: {
ecmaVersion: 6,
ecmaFeatures: {
jsx: true,
modules: true
},
sourceType: "module"
},
parser: "babel-eslint",
env: {
browser: true,
es6: true,
node: true
},
globals: {
angular: false,
define: false,
describe: false,
document: false,
expect: false,
it: false,
require: false
},
rules: {
"indent": ["error", 2, { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"object-curly-spacing": ["error", "always"],
"max-lines": ["warn", 300],
"max-len": ["warn", { "code": 120, "ignoreComments": true, "ignoreTrailingComments": false }],
"no-console": ["warn"],
"no-mixed-operators": ["warn", {
"groups": [
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
["&&", "||"],
["in", "instanceof"]
],
"allowSamePrecedence": true
}],
"no-multi-spaces": ["error"],
"no-cond-assign": ["warn"],
"no-fallthrough": ["warn"],
"no-undef": ["error"],
"no-unused-vars": ["warn"],
"no-use-before-define": ["warn", { "functions": false, "classes": false, "variables": false }],
"no-useless-escape": ["warn"],
"no-useless-return": ["warn"],
"no-underscore-dangle": ["warn", { "allow": ["_id"] }],
"no-redeclare": ["warn"],
"no-restricted-syntax": ["warn"],
"operator-linebreak": ["warn", "before"],
"prefer-promise-reject-errors": ["warn"],
"padded-blocks": ["warn", { "blocks": "never", "switches": "never", "classes": "never" }],
"semi": ["error", "always"],
"valid-typeof": ["warn"],
"no-eval": ["error"],
"no-implied-eval": ["error"],
"no-debugger": ["warn"],
"no-unreachable": ["warn"],
"quotes": ["warn", "single", { "avoidEscape": true }]
},
extends: [
"eslint:recommended"
]
}

12
.gitattributes vendored
View File

@@ -15,3 +15,15 @@
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
* text=auto
.* text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.html text eol=lf
*.js text eol=lf
*.json text eol=lf
*.md text eol=lf
*.sh text eol=lf
*.txt text eol=lf
*.svg text eol=lf

6
.gitignore vendored
View File

@@ -17,6 +17,11 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
# Temporary build files
node_modules/
build/
BUMPED_VERSION
# =========================
# Operating System Files
# =========================
@@ -41,4 +46,3 @@ $RECYCLE.BIN/
Network Trash Folder
Temporary Items
.apdisk
dist/

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
save-exact=true

22
LICENSE Normal file
View File

@@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2018-present QlikTech International AB
Copyright (c) 2016-2018 Ivan Felipe Asensio
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
{
"name" : "P&L Smart Pivot",
"description" : "Formatted table for P&L reports",
"icon" : "table",
"type" : "visualization",
"version": "1.0",
"preview" : "table",
"author": "Ivan Felipe - QlikTech Iberia"
}

View File

@@ -1,24 +1,7 @@
P&L Smart Pivot, a Qlik Sense Extension for Financial reporting
# P&L Smart Pivot, a Qlik Sense Extension for Financial reporting
[![CircleCI](https://circleci.com/gh/qlik-oss/PLSmartPivot.svg?style=svg)](https://circleci.com/gh/qlik-oss/PLSmartPivot)
=============================
==================================
Available in https://github.com/iviasensio/PLSmartPivot
Current version 2.1. Compatible with QS Sep 2017
(from sep'17 color-picker is no more an integer but an object)
Based on P&LSmart.
Author Ivan Felipe Asensio QlikTech Iberia,s.l.
This extension is useful to create reports where the look&feel is rellevantand and pivot a second dimension is needed.
This extension is useful to create reports where the look&feel is rellevantand and pivot a second dimension is needed. Based on P&L Smart.
It's specifically focused on financial reports, trying to solve some common needs of this area:
- smart export to excel
@@ -27,28 +10,48 @@ It's specifically focused on financial reports, trying to solve some common need
- selections inside the reports
- custom external templates
- analytical reports
- ...
You'll find a manual 'P&LSmart Pivot Extension Manual.pdf' and one app example 'P&LSmartPivot_demo.qvf
'.
# Manual
You'll find a manual [Qlik Sense P&LSmart Pivot Extension Manual.pdf](resources/Qlik Sense P&LSmart Pivot Extension Manual.pdf) and one app example [P&LSmartPivot_demo.qvf](resources/P&LSmartPivot_demo.qvf).
*Install in Server:
- before import the extension from the server remember to remove all the non functional files.
- remove:
.gitattributes,
.gitignore, P&LSmartPivot_demo.qvf, 'Qlik Sense P&LSmart Pivot Extension Manual.pdf'
# If the import does not work at first time
- remove [Accounts.csv](resources/Accounts.csv), [Accounts2.csv](resources/Accounts2.csv) and [Excel.png](resources/Excel.png), zip it again and import.
- Then reintroduce [Accounts.csv](resources/Accounts.csv), [Accounts2.csv](resources/Accounts2.csv) and [Excel.png](resources/Excel.png), zip it again and import.
**If the import does not work at first time:
- remove Accounts.csv, Accounts2.csv and Excel.png, zip it again and import.
- Then reintroduce Accounts.csv, Accounts2.csv and Excel.png, zip it again and import.
# Installation
1. Download the extension zip, `qlik-smart-pivot_<version>.zip`, from the latest release(https://github.com/qlik-oss/PLSmartPivot/releases/latest)
2. Install the extension:
a. **Qlik Sense Desktop**: unzip to a directory under [My Documents]/Qlik/Sense/Extensions.
b. **Qlik Sense Server**: import the zip file in the QMC.
*Install in Desktop
- unzip and copy the folder in C:\Users\'username'\Documents\Qlik\Sense\Extensions
- copy the example P&LSmartPivot_demo.qvf in C:\Users\'username'\Documents\Qlik\Sense\Apps
# Developing the extension
If you want to do code changes to the extension follow these simple steps to get going.
1. Get Qlik Sense Desktop
1. Create a new app and add the extension to a sheet.
2. Clone the repository
3. Run `npm install`
4. Set the environment variable `BUILD_PATH` to your extensions directory. It will be something like `C:/Users/<user>/Documents/Qlik/Sense/Extensions/<extension_name>`.
5. You now have two options. Either run the watch task or the build task. They are explained below. Both of them default to development mode but can be run in production by setting `NODE_ENV=production` before running the npm task.
a. **Watch**: `npm run watch`. This will start a watcher which will rebuild the extension and output all needed files to the `buildFolder` for each code change you make. See your changes directly in your Qlik Sense app.
b. **Build**: `npm run build`. If you want to build the extension package. The output zip-file can be found in the `buildFolder`.
# Original authors
[github.com/iviasensio](https://github.com/iviasensio)
# License
Released under the [MIT License](LICENSE).

BIN
assets/qlik-smart-pivot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

View File

@@ -0,0 +1,16 @@
{
"name": "Smart pivot",
"description": "Formatted table for P&L reports.",
"type": "visualization",
"version": "X.Y.Z",
"icon": "table",
"preview": "",
"author": "Ivan Felipe Asensio <ivan.felipe@qlik.com>",
"homepage": "",
"keywords": "qlik-sense, visualization",
"license": "MIT",
"repository": "https://github.com/qlik-oss/PLSmartPivot",
"dependencies": {
"qlik-sense": ">=5.5.x"
}
}

3
assets/wbfolder.wbl Normal file
View File

@@ -0,0 +1,3 @@
qlik-smart-pivot.js;
qlik-smart-pivot.css;
qlik-smart-pivot.qext

75
gulpfile.js Normal file
View File

@@ -0,0 +1,75 @@
var gulp = require('gulp');
var zip = require('gulp-zip');
var del = require('del');
var path = require('path');
var settings = require('./settings');
var webpackConfig = require('./webpack.config');
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var jeditor = require("gulp-json-editor");
var srcFiles = path.resolve('./src/**/*.*');
gulp.task('remove-build-folder', function(){
return del([settings.buildDestination], { force: true });
});
gulp.task('zip-build', function(){
return gulp.src(settings.buildDestination + '/**/*')
.pipe(zip(`${settings.name}_${settings.version}.zip`))
.pipe(gulp.dest(settings.buildDestination));
});
gulp.task('webpack-build', done => {
webpack(webpackConfig, (error, statistics) => {
const compilationErrors = statistics && statistics.compilation.errors;
const hasCompilationErrors = !statistics || (compilationErrors && compilationErrors.length > 0);
console.log(statistics && statistics.toString({ chunks: false, colors: true })); // eslint-disable-line no-console
if (error || hasCompilationErrors) {
console.log('Build has errors or eslint errors, fail it'); // eslint-disable-line no-console
process.exit(1);
}
done();
});
});
gulp.task('update-qext-version', function () {
return gulp.src(`${settings.buildDestination}/${settings.name}.qext`)
.pipe(jeditor({
'version': settings.version
}))
.pipe(gulp.dest(settings.buildDestination));
});
gulp.task('build',
gulp.series('remove-build-folder', 'webpack-build', 'update-qext-version', 'zip-build')
);
gulp.task('default',
gulp.series('build')
);
gulp.task('watch', () => new Promise((resolve, reject) => {
webpackConfig.entry.unshift('webpack-dev-server/client?http://localhost:' + settings.port);
const compiler = webpack(webpackConfig);
const originalOutputFileSystem = compiler.outputFileSystem;
const devServer = new WebpackDevServer(compiler, {
headers: {
"Access-Control-Allow-Origin": "*"
},
}).listen(settings.port, 'localhost', error => {
compiler.outputFileSystem = originalOutputFileSystem;
if (error) {
console.error(error); // eslint-disable-line no-console
return reject(error);
}
// eslint-disable-next-line no-console
console.log('Listening at localhost:' + settings.port);
resolve(null, devServer);
});
}));

43
karma.conf.js Normal file
View File

@@ -0,0 +1,43 @@
const settings = require('./settings');
module.exports = (config) => {
config.set({
browsers: ['SlimChromeHeadless'],
customLaunchers: {
SlimChromeHeadless: {
base: 'ChromeHeadless',
flags: ['--headless', '--disable-gpu', '--disable-translate', '--disable-extensions']
}
},
files: [
{ pattern: 'src/*.spec.js', watched: false }
],
frameworks: ['jasmine'],
preprocessors: {
'src/*.spec.js': ['webpack', 'sourcemap']
},
webpack: {
devtool: 'source-map',
mode: settings.mode,
externals: {
jquery: {
amd: 'jquery',
commonjs: 'jquery',
commonjs2: 'jquery',
root: '_'
},
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules/],
loaders: ['babel-loader']
},
{ test: /\.less$/, loader: 'ignore-loader' },
{ test: /\.json$/, loader: 'ignore-loader' }
]
}
}
});
};

11999
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

48
package.json Normal file
View File

@@ -0,0 +1,48 @@
{
"name": "qlik-smart-pivot",
"version": "0.0.1",
"description": "Formatted table for P&L reports.",
"keywords": "smart pivot qliksense extension",
"repository": "https://github.com/iviasensio/PLSmartPivot",
"author": "Ivan Felipe Asensio <ivan.felipe@qlik.com>",
"license": "MIT",
"scripts": {
"build": "gulp build",
"eslint": "eslint src",
"eslint:fix": "eslint --fix src",
"test": "karma start karma.conf.js",
"test-once": "karma start karma.conf.js --single-run",
"watch": "gulp watch"
},
"devDependencies": {
"@babel/core": "7.1.2",
"@babel/polyfill": "7.0.0",
"@babel/preset-env": "7.1.0",
"babel-eslint": "10.0.1",
"babel-loader": "8.0.4",
"copy-webpack-plugin": "4.5.3",
"css-loader": "1.0.0",
"del": "2.0.2",
"eslint": "5.7.0",
"eslint-loader": "2.1.1",
"gulp": "4.0.0",
"gulp-json-editor": "2.4.3",
"gulp-zip": "3.0.2",
"jasmine-core": "3.2.1",
"jquery": "3.3.1",
"karma": "3.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-jasmine": "1.1.2",
"karma-sourcemap-loader": "0.3.7",
"karma-webpack": "3.0.5",
"less": "3.8.1",
"less-loader": "4.1.0",
"style-loader": "0.23.1",
"stylelint": "8.4.0",
"stylelint-webpack-plugin": "0.10.5",
"text-loader": "0.0.1",
"webpack": "4.20.2",
"webpack-cli": "3.1.2",
"webpack-dev-server": "3.1.10"
}
}

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

32
scripts/bump-version.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
set -o errexit
join_by () {
local IFS="$1"; shift; echo "$*";
}
if [ "${CIRCLE_BRANCH}" == "master" ]; then
# get version from repo
OLD_VERSION="$(scripts/get-latest-version.sh $1 $2)"
echo "Latest GitHub release version: ${OLD_VERSION}"
# split into array
IFS='.' read -ra ARRAY_VERSION <<< "$OLD_VERSION"
# bump minor
ARRAY_VERSION[1]=$((ARRAY_VERSION[1]+1))
# join into string
NEW_VERSION=$(join_by . ${ARRAY_VERSION[@]})
elif [[ ! -z "${CIRCLE_BRANCH}" && ! -z "${CIRCLE_BUILD_NUM}" ]]; then
NEW_VERSION="$(echo ${CIRCLE_BRANCH} | sed -e 's/\//-/g')_${CIRCLE_BUILD_NUM}"
else
NEW_VERSION="dev"
fi
echo "Bumped version: ${NEW_VERSION}"
echo "${NEW_VERSION}" > BUMPED_VERSION
# Usage
# $ bump-version.sh qlik-oss qsSimpleKPI

10
scripts/create-release.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
set -o errexit
echo "Creating release for version: $VERSION"
echo "Artifact name: ./build/${3}_${VERSION}.zip"
$HOME/bin/ghr -t ${ghoauth} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${VERSION} "./build/${3}_${4}.zip"
# Usage
# $ create-release.sh qlik-oss qsSimpleKPI qlik-multi-kpi 0.3.1

7
scripts/get-bumped-version.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -o errexit
echo "$(head -n 1 BUMPED_VERSION)"
# Usage
# $ get-bumped-version.sh

17
scripts/get-latest-version.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
set -o errexit
VERSION=$(curl --silent "https://api.github.com/repos/$1/$2/releases/latest" | # Get latest release from GitHub api
grep '"tag_name":' | # Get tag line
sed -E 's/.*"([^"]+)".*/\1/') # Pluck JSON value
if [ -z "${VERSION}" ]; then
VERSION="0.1.0"
fi
echo "${VERSION}"
### Inspired by https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c
# Usage
# $ get-latest-version.sh qlik-oss qsSimpleKPI
# 0.12.0

12
scripts/install-ghr.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
set -o errexit -o verbose
URL="https://github.com/tcnksm/ghr/releases/download/v0.5.4/ghr_v0.5.4_linux_386.zip"
echo "Version to install: $URL"
echo "Installing ghr"
curl -L ${URL} > ghr.zip
mkdir -p "$HOME/bin"
export PATH="$HOME/bin:$PATH"
unzip ghr.zip -d "$HOME/bin"
rm ghr.zip

13
settings.js Normal file
View File

@@ -0,0 +1,13 @@
const path = require('path');
const packageJSON = require('./package.json');
const defaultBuildDestination = path.resolve("./build");
module.exports = {
buildDestination: process.env.BUILD_PATH || defaultBuildDestination,
mode: process.env.NODE_ENV || 'development',
name: packageJSON.name,
version: process.env.VERSION || 'local-dev',
url: process.env.BUILD_URL || defaultBuildDestination,
port: process.env.PORT || 8085
};

9
src/haiku.spec.js Normal file
View File

@@ -0,0 +1,9 @@
/* https://randomhaiku.com */
describe('behind the money', () => {
describe('Canada and Panda work.', () => {
it('Tiger starts blowing.', () => {
expect(true).toBeTruthy();
});
});
});

791
src/index.js Normal file
View File

@@ -0,0 +1,791 @@
import $ from 'jquery';
import style from 'text-loader!./PLSmartPivot.css';
import paint from './paint';
$('<style>').html(style).appendTo('head');
export default {
initialProperties: {
version: 1.0,
qHyperCubeDef: {
qDimensions: [],
qMeasures: [],
qInitialDataFetch: [{
qWidth: 10,
qHeight: 1000
}]
},
},
definition: {
type: 'items',
component: 'accordion',
items: {
dimensions: {
uses: 'dimensions',
min: 1,
max: 2
},
measures: {
uses: 'measures',
min: 1,
max: 9
},
sorting: {
uses: 'sorting'
},
settings: {
uses: 'settings',
items: {
Pagination: {
type: 'items',
label: 'Pagination',
items: {
MaxPaginationLoops: {
ref: 'maxloops',
type: 'number',
component: 'dropdown',
label: 'Max Pagination Loops',
options:
[{
value: 1,
label: '10k cells'
}, {
value: 2,
label: '20k cells'
}, {
value: 3,
label: '30k cells'
}, {
value: 4,
label: '40k cells'
}, {
value: 5,
label: '50k cells'
}, {
value: 6,
label: '60k cells'
}, {
value: 7,
label: '70k cells'
}, {
value: 8,
label: '80k cells'
}, {
value: 9,
label: '90k cells'
}, {
value: 10,
label: '100k cells'
}
],
defaultValue: 2,
},
ErrorMessage: {
ref: 'errormessage',
label: 'Default error message',
type: 'string',
defaultValue: 'Ups! It seems you asked for too many data. Please filter more to see the whole picture.',
},
},
},
Header: {
type: 'items',
label: 'Header Format',
items: {
Align: {
ref: 'HeaderAlign',
translation: 'Header Alignment',
type: 'number',
component: 'buttongroup',
options: [{
value: 1,
label: 'Left'
}, {
value: 2,
label: 'Center'
}, {
value: 3,
label: 'Right'
}],
defaultValue: 2,
},
headercolors: {
ref: 'HeaderColorSchema',
type: 'string',
component: 'dropdown',
label: 'BackGround Header Color',
options:
[{
value: 'Clean',
label: 'Clean'
}, {
value: 'Soft',
label: 'Soft'
}, {
value: 'Dark',
label: 'Dark'
}, {
value: 'Night',
label: 'Night'
}, {
value: 'Blue',
label: 'Blue'
}, {
value: 'Orange',
label: 'Orange'
}, {
value: 'Red',
label: 'Red'
}, {
value: 'Green',
label: 'Green'
}, {
value: 'Violete',
label: 'Violete'
}, {
value: 'Custom',
label: 'Custom'
}
],
defaultValue: 'Night',
},
HeaderTextColor: {
ref: 'HeaderTextColorSchema',
type: 'string',
component: 'dropdown',
label: 'Text Header Color',
options:
[{
value: 'Black',
label: 'Black'
}, {
value: 'DimGray',
label: 'DimGray'
}, {
value: 'ForestGreen',
label: 'ForestGreen'
}, {
value: 'Gainsboro',
label: 'Gainsboro'
}, {
value: 'Indigo',
label: 'Indigo'
}, {
value: 'Navy',
label: 'Navy'
}, {
value: 'Purple',
label: 'Purple'
}, {
value: 'WhiteSmoke',
label: 'WhiteSmoke'
}, {
value: 'White',
label: 'White'
}, {
value: 'YellowGreen',
label: 'YellowGreen'
}
],
defaultValue: 'WhiteSmoke',
},
HeaderFontSize: {
ref: 'lettersizeheader',
translation: 'Font Size',
type: 'number',
component: 'buttongroup',
options: [{
value: 1,
label: 'Small'
}, {
value: 2,
label: 'Medium'
//}, {
// value: 3,
// label: "Large"
}],
defaultValue: 2
},
}
},
Formatted: {
type: 'items',
label: 'Table Format',
items: {
IndentBool: {
ref: 'indentbool',
type: 'boolean',
label: 'Indent',
defaultValue: true
},
SeparatorColumns: {
ref: 'separatorcols',
type: 'boolean',
label: 'Separator Columns',
defaultValue: false
},
CustomFileBool: {
ref: 'customfilebool',
type: 'boolean',
label: 'Include External File',
defaultValue: false
},
CustomFile: {
ref: 'customfile',
label: 'Name of CSV file (; separated)',
type: 'string',
defaultValue: '',
show: function (data) {
return data.customfilebool;
}
},
colors: {
ref: 'ColorSchema',
type: 'string',
component: 'dropdown',
label: 'BackGround Style',
options:
[{
value: 'Clean',
label: 'Clean'
}, {
value: 'Soft',
label: 'Soft'
}, {
value: 'Dark',
label: 'Dark'
}, {
value: 'Night',
label: 'Night'
}, {
value: 'Blue',
label: 'Blue'
}, {
value: 'Orange',
label: 'Orange'
}, {
value: 'Red',
label: 'Red'
}, {
value: 'Green',
label: 'Green'
}, {
value: 'Violete',
label: 'Violete'
}, {
value: 'Custom',
label: 'Custom'
}
],
defaultValue: 'Clean',
show: function (data) {
return data.customfilebool == false;
}
},
BodyTextColor: {
ref: 'BodyTextColorSchema',
type: 'string',
component: 'dropdown',
label: 'Text Body Color',
options:
[{
value: 'Black',
label: 'Black'
}, {
value: 'DimGray',
label: 'DimGray'
}, {
value: 'ForestGreen',
label: 'ForestGreen'
}, {
value: 'Gainsboro',
label: 'Gainsboro'
}, {
value: 'Indigo',
label: 'Indigo'
}, {
value: 'Navy',
label: 'Navy'
}, {
value: 'Purple',
label: 'Purple'
}, {
value: 'WhiteSmoke',
label: 'WhiteSmoke'
}, {
value: 'White',
label: 'White'
}, {
value: 'YellowGreen',
label: 'YellowGreen'
}
],
defaultValue: 'Black',
show: function (data) {
return data.customfilebool == false;
}
},
FontFamily: {
ref: 'FontFamily',
type: 'string',
component: 'dropdown',
label: 'FontFamily',
options:
[{
value: 'Arial',
label: 'Arial'
}, {
value: 'Calibri',
label: 'Calibri'
}, {
value: 'Comic Sans MS',
label: 'Comic Sans MS'
}, {
value: 'MS Sans Serif',
label: 'MS Sans Serif'
}, {
value: 'Tahoma',
label: 'Tahoma'
}, {
value: 'Verdana',
label: 'Verdana'
}
],
defaultValue: 'Calibri'
},
DataFontSize: {
ref: 'lettersize',
translation: 'Font Size',
type: 'number',
component: 'buttongroup',
options: [{
value: 1,
label: 'Small'
}, {
value: 2,
label: 'Medium'
//}, {
// value: 3,
// label: "Large"
}],
defaultValue: 2
},
ColumnWidthSlider: {
type: 'number',
component: 'slider',
label: 'Column Width',
ref: 'columnwidthslider',
min: 1,
max: 3,
step: 1,
defaultValue: 2
},
SymbolForNulls: {
ref: 'symbolfornulls',
label: 'Symbol for Nulls',
type: 'string',
defaultValue: ' '
},
AllowExportXLS: {
ref: 'allowexportxls',
type: 'boolean',
component: 'switch',
label: 'Allow export to Excel',
options: [{
value: true,
label: 'On'
}, {
value: false,
label: 'Off'
}],
defaultValue: true
},
FilterOnCellClick: {
ref: 'filteroncellclick',
type: 'boolean',
component: 'switch',
label: 'Filter data when cell clicked',
options: [{
value: true,
label: 'On'
}, {
value: false,
label: 'Off'
}],
defaultValue: true
}
}
},
ConceptSemaphores: {
type: 'items',
label: 'Concept Semaphores',
items: {
AllConcepts: {
ref: 'allsemaphores',
type: 'boolean',
component: 'switch',
label: 'All concepts affected',
options: [{
value: true,
label: 'On'
}, {
value: false,
label: 'Off'
}],
defaultValue: true
},
ConceptsAffected1: {
ref: 'conceptsemaphore1',
translation: 'Concept 1',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected2: {
ref: 'conceptsemaphore2',
translation: 'Concept 2',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected3: {
ref: 'conceptsemaphore3',
translation: 'Concept 3',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected4: {
ref: 'conceptsemaphore4',
translation: 'Concept 4',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected5: {
ref: 'conceptsemaphore5',
translation: 'Concept 5',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected6: {
ref: 'conceptsemaphore6',
translation: 'Concept 6',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected7: {
ref: 'conceptsemaphore7',
translation: 'Concept 7',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected8: {
ref: 'conceptsemaphore8',
translation: 'Concept 8',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected9: {
ref: 'conceptsemaphore9',
translation: 'Concept 9',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
ConceptsAffected10: {
ref: 'conceptsemaphore10',
translation: 'Concept 10',
type: 'string',
defaultValue: '',
show: function (data) {
return data.allsemaphores == false;
}
},
}
},
MetricSemaphores: {
type: 'items',
label: 'Metric Semaphores',
items: {
AllMetrics: {
ref: 'allmetrics',
type: 'boolean',
component: 'switch',
label: 'All metrics affected',
options: [{
value: true,
label: 'On'
}, {
value: false,
label: 'Off'
}],
defaultValue: false
},
MetricsAffected: {
ref: 'metricssemaphore',
translation: 'Metrics affected (1,2,4,...)',
type: 'string',
defaultValue: '0',
show: function (data) {
return data.allmetrics == false;
}
},
MetricStatus1: {
ref: 'metricsstatus1',
translation: 'Critic is less than',
type: 'number',
defaultValue: -0.1
},
ColorStatus1: {
ref: 'colorstatus1',
label: 'Critic Color Fill',
type: 'object',
component: 'color-picker',
defaultValue: {
index: 7,
color: '#f93f17'
}
},
ColorStatus1Text: {
ref: 'colorstatus1text',
label: 'Critic Color Text',
type: 'object',
component: 'color-picker',
defaultValue: {
index: 10,
color: '#ffffff'
}
},
MetricStatus2: {
ref: 'metricsstatus2',
translation: 'Medium is less than',
type: 'number',
defaultValue: 0
},
ColorStatus2: {
ref: 'colorstatus2',
label: 'Medium Color Fill',
type: 'object',
component: 'color-picker',
defaultValue: {
index: 8,
color: '#ffcf02'
}
},
ColorStatus2Text: {
ref: 'colorstatus2text',
label: 'Medium Color Text',
type: 'object',
component: 'color-picker',
defaultValue: {
index: 11,
color: '#000000'
}
},
ColorStatus3: {
ref: 'colorstatus3',
label: 'Success Color Fill',
type: 'object',
component: 'color-picker',
defaultValue: {
index: 9,
color: '#276e27'
}
},
ColorStatus3Text: {
ref: 'colorstatus3text',
label: 'Success Color Text',
type: 'object',
component: 'color-picker',
defaultValue: {
index: 10,
color: '#ffffff'
}
},
}
},
ColorLibrary: {
type: 'items',
label: 'Primary Colors Library',
items: {
ColLibClean: {
ref: 'collibclean',
translation: 'Clean',
type: 'string',
defaultValue: '#ffffff',
},
ColLibSoft: {
ref: 'collibsoft',
translation: 'Soft',
type: 'string',
defaultValue: '#efefef',
},
ColLibDark: {
ref: 'collibdark',
translation: 'Dark',
type: 'string',
defaultValue: '#c4c4c4',
},
ColLibNight: {
ref: 'collibnight',
translation: 'Night',
type: 'string',
defaultValue: '#808080',
},
ColLibRed: {
ref: 'collibred',
translation: 'Red',
type: 'string',
defaultValue: '#d58b94',
},
ColLibOrange: {
ref: 'colliborange',
translation: 'Orange',
type: 'string',
defaultValue: '#fd6600',
},
ColLibViolete: {
ref: 'collibviolete',
translation: 'Violete',
type: 'string',
defaultValue: '#ccc0ff',
},
ColLibBlue: {
ref: 'collibblue',
translation: 'Blue',
type: 'string',
defaultValue: '#4575b4',
},
ColLibGreen: {
ref: 'collibgreen',
translation: 'Green',
type: 'string',
defaultValue: '#7bb51c',
},
ColLibCustom: {
ref: 'collibcustom',
label: 'Custom',
type: 'string',
defaultValue: '#ffcccc',
},
}
},
PijamaColorLibrary: {
type: 'items',
label: 'Pijama Colors Library',
items: {
ColLibCleanP: {
ref: 'collibcleanp',
translation: 'Clean',
type: 'string',
defaultValue: '#ffffff',
},
ColLibSoftP: {
ref: 'collibsoftp',
translation: 'Soft',
type: 'string',
defaultValue: '#ffffff',
},
ColLibDarkP: {
ref: 'collibdarkp',
translation: 'Dark',
type: 'string',
defaultValue: '#efefef',
},
ColLibNightP: {
ref: 'collibnightp',
translation: 'Night',
type: 'string',
defaultValue: '#c4c4c4',
},
ColLibRedP: {
ref: 'collibredp',
translation: 'Red',
type: 'string',
defaultValue: '#ffcccc',
},
ColLibOrangeP: {
ref: 'colliborangep',
translation: 'Orange',
type: 'string',
defaultValue: '#ffcc66',
},
ColLibVioleteP: {
ref: 'collibvioletep',
translation: 'Violete',
type: 'string',
defaultValue: '#e6e6ff',
},
ColLibBlueP: {
ref: 'collibbluep',
translation: 'Blue',
type: 'string',
defaultValue: '#b3d9ff',
},
ColLibGreenP: {
ref: 'collibgreenp',
translation: 'Green',
type: 'string',
defaultValue: '#98fb98',
},
ColLibCustomP: {
ref: 'collibcustomp',
label: 'Custom',
type: 'string',
defaultValue: '#ffffff',
},
}
}
}
}
}
},
snapshot: {
canTakeSnapshot: true
},
controller: [
'$scope',
'$timeout',
function () { }
],
paint: function ($element) {
try {
paint($element, this);
}
catch (e) {
console.error(e); // eslint-disable-line no-console
throw e;
}
}
};

1373
src/paint.js Normal file

File diff suppressed because it is too large Load Diff

35
stylelint.config.js Normal file
View File

@@ -0,0 +1,35 @@
"use strict";
module.exports = {
rules: {
"at-rule-no-unknown": true,
"block-no-empty": true,
"color-no-invalid-hex": true,
"comment-no-empty": true,
"declaration-block-no-duplicate-properties": [
true,
{
ignore: ["consecutive-duplicates-with-different-values"]
}
],
"declaration-block-no-shorthand-property-overrides": true,
"font-family-no-duplicate-names": true,
"font-family-no-missing-generic-family-keyword": true,
"function-calc-no-unspaced-operator": true,
"function-linear-gradient-no-nonstandard-direction": true,
"keyframe-declaration-no-important": true,
"media-feature-name-no-unknown": true,
"no-descending-specificity": true,
"no-duplicate-at-import-rules": true,
"no-duplicate-selectors": true,
"no-empty-source": true,
"no-extra-semicolons": true,
"no-invalid-double-slash-comments": true,
"property-no-unknown": true,
"selector-pseudo-class-no-unknown": true,
"selector-pseudo-element-no-unknown": true,
"selector-type-no-unknown": true,
"string-no-newline": true,
"unit-no-unknown": true
}
};

View File

@@ -1,3 +0,0 @@
PLSmartPivot.js;
PLSmartPivot.css;
PLSmartPivot.qext

69
webpack.config.js Normal file
View File

@@ -0,0 +1,69 @@
const CopyWebpackPlugin = require('copy-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const settings = require('./settings');
console.log('Webpack mode:', settings.mode); // eslint-disable-line no-console
const config = {
devtool: 'source-map',
entry: [
'./src/index.js'
],
mode: settings.mode,
output: {
path: settings.buildDestination,
filename: settings.name + '.js',
libraryTarget: 'amd'
},
externals: {
jquery: {
amd: 'jquery',
commonjs: 'jquery',
commonjs2: 'jquery',
root: '_'
},
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
exclude: /(node_modules|Library)/,
loader: 'eslint-loader',
options: {
failOnError: true
}
},
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
},
plugins: [
new CopyWebpackPlugin([
'assets/' + settings.name + '.qext',
'assets/' + settings.name + '.png',
'assets/wbfolder.wbl',
// TODO: remove entries below this line
'resources/Accounts.csv',
'resources/Accounts2.csv',
'resources/QlikLook.csv',
'resources/Excel.png',
], {}),
new StyleLintPlugin()
]
};
module.exports = config;