;
24 |
25 | public getFirstLabel(): Label;
26 | }
27 |
--------------------------------------------------------------------------------
/lib/gulp/model/data/label.d.ts:
--------------------------------------------------------------------------------
1 | import { Tooltip } from './tooltip';
2 | import { Criteria } from '../criteria/criteria';
3 |
4 | export class Label {
5 | public name: string;
6 | public tooltip: Tooltip;
7 |
8 | public clazz: string;
9 | public color: string;
10 | public backgroundColor: string;
11 |
12 | public stars: number;
13 | public comment: string;
14 |
15 | constructor(name: string, tooltip?: string, clazz?: string, color?: string, backgroundColor?: string, stars?: number, comment?: string);
16 |
17 | public static loadJson(json, criteria: Criteria): Label;
18 |
19 | public json();
20 |
21 | public markdown(): string;
22 |
23 | public repositoryMarkdown(): string;
24 |
25 | public setClazz(clazz: string): void;
26 |
27 | public setColor(color: string): void;
28 |
29 | public setBackgroundColor(backgroundColor: string): void;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/components/polymer/paper-item/paper-item.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | position: relative;
4 | padding: 0px 16px;
5 | }
6 |
7 | :host(.item-selected) {
8 | font-weight: bold;
9 | }
10 |
11 | :host ::ng-deep pbutton {
12 | display: inline-block;
13 | padding: 0;
14 | font-size: 1em;
15 | text-transform: none;
16 | border-top-width: 1px;
17 | border-right-width: 1px;
18 | box-shadow: none;
19 | margin: 0;
20 | }
21 |
22 | :host ::ng-deep pbutton:active {
23 | box-shadow: none;
24 | }
25 |
26 | :host ::ng-deep .icon {
27 | display: inline-block;
28 | box-sizing: border-box;
29 | height: 18px;
30 | width: 18px;
31 | border-radius: 2px;
32 | border: 2px solid rgb(63, 81, 181);
33 | margin-right: 8px;
34 | background-color: rgb(63, 81, 181);
35 | }
36 |
37 | :host ::ng-deep .icon > svg {
38 | margin: 1px auto;
39 | }
40 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: Checks
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | javatests:
7 | name: md-to-json unit tests
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Checkout source
11 | uses: actions/checkout@v2
12 | with:
13 | depth: 1
14 | - name: Set up JDK
15 | uses: actions/setup-java@v1
16 | with:
17 | java-version: 12
18 | - name: Run java tests
19 | run: |
20 | cd lib/md-to-json
21 | ./gradlew check
22 | jstests:
23 | name: js unit tests
24 | runs-on: ubuntu-latest
25 | steps:
26 | - name: Checkout source
27 | uses: actions/checkout@v2
28 | with:
29 | depth: 1
30 | - uses: actions/setup-node@v1
31 | with:
32 | node-version: '10.x'
33 | - run: npm install
34 | - run: npm test
35 |
--------------------------------------------------------------------------------
/lib/gulp/model/data/tooltip.js:
--------------------------------------------------------------------------------
1 | import * as Showdown from "showdown";
2 |
3 | class Tooltip {
4 | constructor(text, plain, html, latex) {
5 | this.text = text;
6 | this.plain = plain;
7 | this.html = html;
8 | this.latex = latex;
9 | }
10 |
11 | static fromHtmlString(string) {
12 | let html = string;
13 |
14 | // if string contains only one item ("\n-"|"\n*" can not be found) remove the prefix "- "
15 | html = /^[-*] /.test(html) && !/\n[-*] /.test(html) ? html.substring(1).trim() : html;
16 |
17 | // build latex string (replace [@BIBKEY] with \cite{BIBKEY})
18 | const latex = (html.replace(/(?:\[@)([^\]]*)(?:])/g, (match, dec) => '\\cite{' + dec + '}') || "").trim();
19 |
20 | // convert plain markdown string to html
21 | html = new Showdown.Converter().makeHtml(html);
22 |
23 | return new Tooltip("", string, html, latex);
24 | }
25 | }
26 |
27 | export { Tooltip };
28 |
--------------------------------------------------------------------------------
/docs/adr/0001-Selection-Framework.md:
--------------------------------------------------------------------------------
1 | # Choose selection framework
2 |
3 | **User Story:** #27
4 |
5 | During the implementation of `Clicking on a tag should search for it` (issue #27) we noticed that we could not get the value of the
6 | tag into the elements in the GUI.
7 | We needed a framework that allowed to add values to the elements via code.
8 | Thus `angular2-select` is deprecated.
9 |
10 | ## Considered Alternatives
11 |
12 | - angular2-select
13 | - ng2-select
14 | - ng2-select-custom
15 |
16 | ## Decision Outcome
17 |
18 | `ng2-select`
19 |
20 | Because it allows adding selected items programmatically.
21 |
22 | ## Pros and Cons of Alternatives
23 |
24 | ### `angular2-select`
25 |
26 | * Does not allow adding elements programmatically
27 |
28 | ### `ng2-select`
29 |
30 | * Does allow adding elements programmatically
31 |
32 | ### `ng2-select-custom`
33 |
34 | * Does allow adding elements programmatically
35 | * Is a fork of ng2-select
--------------------------------------------------------------------------------
/src/app/components/pipes/sanitizer-pipe/sanitizer.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
3 |
4 | @Pipe({
5 | name: 'sanitizeHtml',
6 | pure: false
7 | })
8 | export class SanitizerPipe implements PipeTransform {
9 |
10 | constructor(private _sanitizer: DomSanitizer) {
11 | }
12 |
13 | transform(v: string): SafeHtml {
14 | const html = this._sanitizer.bypassSecurityTrustHtml(v);
15 | if (html.hasOwnProperty('changingThisBreaksApplicationSecurity') &&
16 | /^\d+\./.test(html['changingThisBreaksApplicationSecurity'])) {
17 | html['changingThisBreaksApplicationSecurity'] =
18 | '
' + html['changingThisBreaksApplicationSecurity']
19 | .substr(html['changingThisBreaksApplicationSecurity'].indexOf('.') + 1);
20 | }
21 | return html;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/components/polymer/paper-button/paper-button.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | color: #3f51b5;
3 | display: inline-block;
4 | position: relative;
5 | box-sizing: border-box;
6 | min-width: 5.14em;
7 | margin: 0 0.29em;
8 | background: transparent;
9 | text-align: center;
10 | font: inherit;
11 | text-transform: uppercase;
12 | outline-width: 0;
13 | border-radius: 3px;
14 | -moz-user-select: none;
15 | -ms-user-select: none;
16 | -webkit-user-select: none;
17 | cursor: pointer;
18 | z-index: 0;
19 | padding: 0.7em 0.57em;
20 |
21 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
22 | 0 1px 5px 0 rgba(0, 0, 0, 0.12),
23 | 0 3px 1px -2px rgba(0, 0, 0, 0.2);
24 |
25 | transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
26 | }
27 |
28 | :host:active {
29 | box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
30 | 0 3px 14px 2px rgba(0, 0, 0, 0.12),
31 | 0 5px 5px -3px rgba(0, 0, 0, 0.4);
32 | }
--------------------------------------------------------------------------------
/lib/uc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "##name",
3 | "description": "##description",
4 | "version": "##version",
5 | "scripts": {
6 | "start": "npm run gulp:compile && npm run server:start",
7 | "build": "npm run gulp:compile",
8 | "dev": "concurrently \"npm run gulp:development\" \"npm run server:start\" ",
9 | "gulp:compile": "./node_modules/.bin/gulp default --gulpfile=./node_modules/ultimate-comparison/lib/gulp/gulpfile.js --dir=node_modules/ultimate-comparison",
10 | "gulp:development": "node ./node_modules/gulp/bin/gulp.js dev --gulpfile=./node_modules/ultimate-comparison/lib/gulp/gulpfile.js --dir=node_modules/ultimate-comparison",
11 | "server:start": "./node_modules/.bin/angular-http-server --path dist --p 3001 --open"
12 | },
13 | "babel": {
14 | "presets": [
15 | "@babel/preset-env"
16 | ]
17 | },
18 | "dependencies": {
19 | "concurrently": "^3.5.1",
20 | "gulp": "^4.0.0",
21 | "gulp-exec": "^3.0.1"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/components/polymer/paper-dialog/paper-dialog.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'pdialog',
5 | templateUrl: './paper-dialog.component.html',
6 | styleUrls: ['./paper-dialog.component.css']
7 | })
8 | export class PaperDialogComponent {
9 | @Input() opened = false;
10 | @Input() heading: string;
11 |
12 | @Output() openedChange: EventEmitter = new EventEmitter();
13 |
14 | @HostListener('click', ['$event.target']) onClick(target) {
15 | if (target.localName === 'pdialog') {
16 | this.close();
17 | }
18 | }
19 |
20 | public close() {
21 | this.opened = false;
22 | this.openedChange.emit();
23 | }
24 |
25 | @HostListener('window:keydown', ['$event']) onKeydown(event) {
26 | if (this.opened && event.key.toLowerCase() === 'escape') {
27 | this.close();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/gulp/model/model.module.js:
--------------------------------------------------------------------------------
1 | import { Criteria, CriteriaTypeKeys, CriteriaTypes } from "./criteria/criteria";
2 | import { Citation } from "./citation/citation";
3 | import { CitationFiles } from "./citation/citationFiles";
4 | import { Configuration } from "./configuration/configuration";
5 | import { Details } from "./details/details";
6 | import { Body } from "./details/body";
7 | import { Header } from "./details/header";
8 | import { CriteriaData } from "./data/criteriaData";
9 | import { Data } from "./data/data";
10 | import { DataElement } from "./data/dataElement";
11 | import { Label } from "./data/label";
12 | import { Tooltip } from "./data/tooltip";
13 | import { CriteriaValue } from "./criteria/criteriaValue";
14 | import { isNullOrUndefined } from "util";
15 |
16 | export { Criteria, CriteriaTypes, CriteriaTypeKeys, Citation, CitationFiles, Configuration, Details, Body, Header };
17 | export { CriteriaData, CriteriaValue, Data, DataElement, Label, Tooltip }
18 |
19 | export { isNullOrUndefined }
20 |
--------------------------------------------------------------------------------
/lib/gulp/model/model.module.d.ts:
--------------------------------------------------------------------------------
1 | import { Criteria, CriteriaTypeKeys, CriteriaTypes } from './criteria/criteria';
2 | import { Citation } from './citation/citation';
3 | import { CitationFiles } from './citation/citationFiles';
4 | import { Configuration } from './configuration/configuration';
5 | import { Details } from './details/details';
6 | import { Body } from './details/body';
7 | import { Header } from './details/header';
8 | import { CriteriaData } from './data/criteriaData';
9 | import { Data } from './data/data';
10 | import { DataElement } from './data/dataElement';
11 | import { Label } from './data/label';
12 | import { Tooltip } from './data/tooltip';
13 | import { CriteriaValue } from './criteria/criteriaValue';
14 | import { isNullOrUndefined } from 'util';
15 |
16 | export { Criteria, CriteriaTypes, CriteriaTypeKeys, Citation, CitationFiles, Configuration, Details, Body, Header };
17 | export { CriteriaData, CriteriaValue, Data, DataElement, Label, Tooltip }
18 |
19 | export { isNullOrUndefined }
20 |
--------------------------------------------------------------------------------
/lib/gulp/model/criteria/criteriaValue.d.ts:
--------------------------------------------------------------------------------
1 | export class CriteriaValue {
2 | public criteriaName: string;
3 | public name: string;
4 | public description: string;
5 | public clazz: string;
6 | public color: string;
7 | public backgroundColor: string;
8 | public weight: number;
9 | public minAge: number;
10 | public maxAge: number;
11 | public minAgeUnit: string;
12 | public maxAgeUnit: string;
13 |
14 | constructor(criteriaName: string,
15 | name: string,
16 | description?: string,
17 | clazz?: string,
18 | color?: string,
19 | backgroundColor?: string,
20 | weight?: number,
21 | minAge?: number,
22 | maxAge?: number,
23 | minAgeUnit?: string,
24 | maxAgeUnit?: string);
25 |
26 | public static loadJson(criteriaName, name, json);
27 |
28 | public json(): string;
29 |
30 | public hasColor(): boolean;
31 |
32 | public combine(other: CriteriaValue): CriteriaValue;
33 | }
34 |
--------------------------------------------------------------------------------
/lib/md-to-json/.gitignore:
--------------------------------------------------------------------------------
1 | # Android built artifacts
2 | *.apk
3 | *.ap_
4 | *.dex
5 |
6 | # Java build artifacts class files
7 | *.class
8 |
9 | # other generated files
10 | bin/
11 | gen/
12 | build/
13 | out/
14 |
15 | # local configuration file (for Android sdk path, etc)
16 | local.properties
17 |
18 | # OSX files
19 | .DS_Store
20 |
21 | # Eclipse project files
22 | .classpath
23 | .project
24 |
25 | # Android Studio
26 | *.iml
27 | .idea
28 |
29 |
30 | #NDK
31 | obj/
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | # Created by https://www.gitignore.io/api/gradle
41 |
42 | ### Gradle ###
43 | .gradle
44 | **/build/
45 |
46 | # Ignore Gradle GUI config
47 | gradle-app.setting
48 |
49 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
50 | !gradle-wrapper.jar
51 |
52 | # Cache of project
53 | .gradletasknamecache
54 |
55 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
56 | # gradle/wrapper/gradle-wrapper.properties
57 |
58 |
59 | # End of https://www.gitignore.io/api/gradle
60 |
--------------------------------------------------------------------------------
/src/app/components/output/references-table/references-table.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
2 | import { Citation } from '../../../../../lib/gulp/model/model.module';
3 |
4 | @Component({
5 | selector: 'referencestable',
6 | templateUrl: './references-table.component.html',
7 | styleUrls: ['./references-table.component.css'],
8 | changeDetection: ChangeDetectionStrategy.OnPush
9 | })
10 | export class ReferencesTableComponent implements OnChanges {
11 | @Input() changeNum: number = 0;
12 | @Input() citationMap: Map = new Map;
13 | @Input() prefix = '';
14 |
15 | @Input() citations: Array = [];
16 |
17 | ngOnChanges(changes: SimpleChanges): void {
18 | let citations: Array = [];
19 | this.citationMap.forEach((citation) => citations.push(citation));
20 |
21 | citations.sort((a, b) => a.index - b.index);
22 | this.citations = citations;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/components/output/output.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from "@angular/core";
2 | import { BrowserModule } from "@angular/platform-browser";
3 | import { PipesModule } from "./../pipes/pipes.module";
4 | import { PolymerModule } from "./../polymer/polymer.module";
5 | import { GenericTableComponent } from "./generic-table/generic-table.component";
6 | import { ReferencesTableComponent } from "./references-table/references-table.component";
7 | import { LatexTableComponent } from './latex-table/latex-table.component';
8 | import { FootnoteComponent } from "./footnote/footnote.component";
9 |
10 | @NgModule({
11 | imports: [
12 | BrowserModule,
13 | PipesModule,
14 | PolymerModule
15 | ],
16 | exports: [
17 | GenericTableComponent,
18 | ReferencesTableComponent,
19 | PolymerModule,
20 | LatexTableComponent
21 | ],
22 | declarations: [
23 | FootnoteComponent,
24 | GenericTableComponent,
25 | ReferencesTableComponent,
26 | LatexTableComponent
27 | ],
28 | providers: []
29 | })
30 | export class OutputModule {
31 | }
--------------------------------------------------------------------------------
/lib/webpack/config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const projectRoot = path.resolve(__dirname, '../..');
4 | const processRoot = process.cwd();
5 |
6 | const folders = {
7 | dist: path.join(processRoot, 'dist'),
8 | nodeModules: path.join(projectRoot, 'node_modules')
9 | };
10 |
11 | const files = {
12 | main: path.join(projectRoot, 'src/main.ts'),
13 | polyfills: path.join(projectRoot, "src/polyfills.ts"),
14 | index: path.join(projectRoot, 'src/index.html'),
15 | favicon: path.join(projectRoot, "src/favicon.ico"),
16 | tsConfigAppJson: path.join(projectRoot, "src/tsconfig.app.json")
17 | };
18 |
19 | const styles = [
20 | path.join(projectRoot, "src/styles.css"),
21 | path.join(projectRoot, "src/assets/bootstrap.css")
22 | ];
23 |
24 | const clean = {
25 | root: projectRoot,
26 | path: path.join(folders.dist),
27 | exclude: [
28 | 'data.json',
29 | 'comparison.json',
30 | 'description.md',
31 | 'style.css'
32 |
33 | ]
34 | };
35 |
36 | module.exports = {
37 | folders: folders,
38 | files: files,
39 | styles: styles,
40 | clean: clean
41 | };
42 |
--------------------------------------------------------------------------------
/data/Template.md:
--------------------------------------------------------------------------------
1 | # Template - http://www.example.com
2 | Default short description (with bibkey: [@esper-reference])
3 |
4 | - a
5 | - b
6 |
7 | ## Performance
8 | - slow
9 | - fast
10 |
11 | ## License
12 | - MIT
13 | - Apache-2.0
14 | - MPL-2.0
15 |
16 | ## Showcase 2.0
17 | - red 1
18 | - red 2
19 | - green
20 | - [@eckertThesisCEP]
21 | - yellow
22 | - yellow property
23 | - n64
24 | - n76
25 | - dark blue
26 | - [@eckertThesisCEP]
27 | - more properties:
28 | - 3lvl Property
29 | - t4
30 | - grey
31 | - light blue
32 | - Super_long_tooltip_without_separators_which_should_not_extend_the_tooltip_area
33 | - black
34 |
35 | ## Description
36 | Default long description in __markdown__.
37 |
38 | - Bibkey example [@Adi:2004:ASM:988145.988150]
39 | - [Link example](http://example.com).
40 |
41 | ## Rating
42 | - [5] Template is perfect
43 | - [1] I don't understand nothing
44 | - [3] It works
45 |
46 | ## Uncolored
47 | - Color 1
48 |
49 | ## NumberColumn
50 | - 200
51 |
52 | ## Repository
53 | https://github.com/SitOPT/SitOPT-Installation-Script
54 | https://github.com/SitOPT/SitOPT-Installation-Script
--------------------------------------------------------------------------------
/lib/md-to-json/src/test/java/wrapper/ConverterTest.java:
--------------------------------------------------------------------------------
1 | package wrapper;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.nio.file.Path;
6 | import java.nio.file.Paths;
7 | import java.util.Objects;
8 |
9 | public class ConverterTest {
10 |
11 | private Path getResourcePath(String name) throws Exception {
12 | return Paths.get(Objects.requireNonNull(this.getClass().getClassLoader().getResource(name)).toURI());
13 | }
14 |
15 | @Test
16 | public void testMain() throws Exception {
17 | String[] args = {
18 | "--input", getResourcePath("test.md").toString(),
19 | "--plainChildren", "{item:{1:true}}",
20 | "--children", "{item:{1:false}}"
21 | };
22 |
23 | Converter.main(args);
24 | }
25 |
26 | @Test
27 | public void testMultipleMain() throws Exception {
28 | String[] args = {
29 | "--input", getResourcePath("test.md").getParent().toString(),
30 | "--plainChildren", "{item:{1:true}}",
31 | "--children", "{item:{1:false}}"
32 | };
33 |
34 | Converter.main(args);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/docs/adr/0000-use-markdown-architectural-decision-records.md:
--------------------------------------------------------------------------------
1 | # Use Markdown Architectural Decision Records (MADR)
2 |
3 | Should we record the architectural decisions made in this project?
4 | And if we do, wow to structure these recordings?
5 |
6 | ## Considered Alternatives
7 |
8 | * [MADR](https://github.com/adr/madr) - Markdown Architectural Decision Records
9 | * [Michael Nygard's template](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions) - The first incarnation of the term "ADR". Maintainable by [adr-tools](https://github.com/npryce/adr-tools).
10 | * [Sustainable Architectural Decisions](https://www.infoq.com/articles/sustainable-architectural-design-decisions) - The Y-Statements
11 | * [DecisionRecord](https://github.com/schubmat/DecisionCapture) - Agile records by [@schubmat](https://github.com/schubmat/)
12 | * Other templates listed at
13 | * No records
14 |
15 | ## Decision Outcome
16 |
17 | * Chosen Alternative: MADR
18 | * The MADR template is lean and fits our development style.
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/md-to-json/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.github.johnrengelman.shadow' version '5.2.0'
3 | id 'java'
4 | id 'application'
5 | }
6 |
7 | repositories {
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | compile group: 'commons-cli', name: 'commons-cli', version: '1.4'
13 | compile 'com.google.code.gson:gson:2.6.2'
14 | compile group: 'com.vladsch.flexmark', name: 'flexmark', version: '0.32.24'
15 | compile 'org.tinylog:tinylog-api:2.1.0-RC3'
16 | compile 'org.tinylog:tinylog-impl:2.1.0-RC3'
17 | compile 'org.eclipse.collections:eclipse-collections-api:9.2.0'
18 | compile 'org.eclipse.collections:eclipse-collections:9.2.0'
19 | compile 'org.apache.commons:commons-text:1.8'
20 |
21 | testCompile('org.junit.jupiter:junit-jupiter-api:5.2.0')
22 | testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.0')
23 | testCompile('org.skyscreamer:jsonassert:1.5.0')
24 | }
25 |
26 | test {
27 | useJUnitPlatform()
28 |
29 | testLogging {
30 | events "passed", "skipped", "failed"
31 | }
32 |
33 | reports {
34 | html.enabled = true
35 | }
36 | }
37 |
38 | application {
39 | mainClassName = 'wrapper.Converter'
40 | }
41 |
--------------------------------------------------------------------------------
/src/app/components/polymer/paper-dialog/paper-dialog.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | position: fixed;
3 | overflow-x: hidden;
4 | overflow-y: auto;
5 | top: 0;
6 | right: 0;
7 | left: 0;
8 | bottom: 0;
9 | display: none;
10 | z-index: 2000;
11 | background: rgba(0, 0, 0, 0.5);
12 | grid-template-columns: minmax(10px, 1fr) auto minmax(10px, 1fr);
13 | grid-template-rows: 15px min-content minmax(10px, auto);
14 | grid-template-areas: ". . ." ". dialog ." ". . .";
15 | }
16 |
17 | .dialog {
18 | grid-area: dialog;
19 | display: grid;
20 | padding: 16px;
21 | border-radius: 5px;
22 | box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.4);
23 | grid-template-areas: "header" "content" "buttons";
24 | background-color: #fff;
25 | max-width: 1000px;
26 | margin: auto;
27 | }
28 |
29 | .buttons {
30 | grid-area: buttons;
31 | display: grid;
32 | color: #3f51b5;
33 | justify-content: flex-end;
34 | }
35 |
36 | .paper-header {
37 | grid-area: header;
38 | font-size: 24px;
39 | font-weight: 400;
40 | padding: 0 0 10px 0;
41 | }
42 |
43 | .paper-content {
44 | grid-area: content;
45 | display: grid;
46 | }
47 |
--------------------------------------------------------------------------------
/src/app/components/polymer/paper-checkbox/paper-checkbox.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: inline-block;
3 | white-space: nowrap;
4 | cursor: pointer;
5 |
6 | position: relative;
7 | }
8 |
9 | :host:focus {
10 | outline: none;
11 | }
12 |
13 | .pcheckbox {
14 | box-sizing: border-box;
15 | height: 18px;
16 | width: 18px;
17 | border: solid 2px;
18 | border-radius: 2px;
19 | pointer-events: none;
20 | -webkit-transition: background-color 140ms, border-color 140ms;
21 | transition: background-color 140ms, border-color 140ms;
22 | display: inline-block;
23 | position: relative;
24 | vertical-align: middle;
25 | }
26 |
27 | .pcheckmark {
28 | position: absolute;
29 | width: 36%;
30 | height: 70%;
31 | transform-origin: 97% 86%;
32 | -webkit-transform-origin: 97% 86%;
33 | transform: rotate(45deg);
34 | border: none white;
35 | border-right: calc(2 / 15 * 18px) solid;
36 | border-bottom: calc(2 / 15 * 18px) solid;
37 | margin-left: 1px;
38 | margin-top: 1px;
39 | color: white;
40 | }
41 |
42 | .plabel {
43 | position: relative;
44 | display: inline-block;
45 | vertical-align: middle;
46 | white-space: normal;
47 | pointer-events: none;
48 | padding-left: 8px;
49 | }
50 |
--------------------------------------------------------------------------------
/src/app/components/comparison/comparison.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | // Provider imports
3 | import { BrowserModule, Title } from '@angular/platform-browser';
4 | import { HttpClient, HttpClientModule } from '@angular/common/http';
5 | import { ComparisonDetailsComponent } from './details/comparison.details.component';
6 | import { ComparisonComponent } from './comparison.component';
7 | import { PipesModule } from '../pipes/pipes.module';
8 | import { InputModule } from '../input/input.module';
9 | import { OutputModule } from '../output/output.module';
10 | import { ConfigurationService } from './configuration/configuration.service';
11 | import { ComparisonSettingsComponent } from './settings/comparison.settings.component';
12 |
13 | @NgModule({
14 | imports: [
15 | BrowserModule,
16 | HttpClientModule,
17 | InputModule,
18 | OutputModule,
19 | PipesModule
20 | ],
21 | exports: [
22 | ComparisonComponent
23 | ],
24 | declarations: [
25 | ComparisonComponent,
26 | ComparisonDetailsComponent,
27 | ComparisonSettingsComponent
28 | ],
29 | providers: [
30 | ConfigurationService,
31 | Title,
32 | HttpClient
33 | ]
34 | })
35 | export class ComparisonModule {
36 | }
37 |
--------------------------------------------------------------------------------
/src/app/components/output/latex-table/latex-table.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, ElementRef, Input } from '@angular/core';
2 | import { CriteriaData, CriteriaTypes } from '../../../../../lib/gulp/model/model.module';
3 |
4 | @Component({
5 | selector: 'latextable',
6 | templateUrl: './latex-table.component.html',
7 | styleUrls: ['./latex-table.component.css'],
8 | changeDetection: ChangeDetectionStrategy.OnPush
9 | })
10 | export class LatexTableComponent {
11 | @Input() changeNum;
12 | @Input() showTableTooltips = true;
13 | @Input() tableTooltipsAsFootnotes = true;
14 |
15 | @Input() columns: Array = [];
16 | @Input() types: Array = [];
17 | @Input() items: Array> = [];
18 | @Input() index: Array = [];
19 |
20 | public footnotes: Map = new Map();
21 |
22 | constructor(public element: ElementRef) {
23 |
24 | }
25 |
26 | public getFootnotes() {
27 | let footnoteItems: Array<{ ref: string, count: number, text: string }> = [];
28 | this.footnotes.forEach((value, key) => {
29 | footnoteItems.push({ref: value.ref, count: value.count, text: key})
30 | });
31 | return footnoteItems;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2018 Christoph Kleine
4 | Copyright (c) 2016-2018 Oliver Kopp
5 | Copyright (c) 2016-2018 Michael Falkenthal
6 | Copyright (c) 2016-2018 Armin Hüneburg
7 | Copyright (c) 2016-2017 Andreas Bader
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
10 | and associated documentation files (the "Software"), to deal in the Software without restriction,
11 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
12 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial
16 | portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
19 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
20 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
21 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/lib/uc/uc:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | CWD=$(pwd)
4 | DIR="$(dirname "$(readlink -f "$0")")"
5 |
6 | setup () {
7 | cp -r ${DIR}/../../data ${CWD}/
8 | cp -r ${DIR}/../../configuration ${CWD}/
9 |
10 | cp ${DIR}/LICENSE ${CWD}/
11 | cp ${DIR}/.editorconfig ${CWD}/
12 | cp ${DIR}/.travis.yml ${CWD}/
13 | cp ${DIR}/gitignore.template ${CWD}/.gitignore
14 | cp ${DIR}/package.json ${CWD}/package.json
15 | cp ${DIR}/README.md ${CWD}/
16 |
17 | echo "What is the name of your comparison?"
18 | read -e NAME
19 | if [[ ${NAME} == "" ]]; then
20 | NAME="ultimate-comparison-project"
21 | fi
22 | echo "What is the version of your comparison?"
23 | read -e VERS
24 | if [[ ${VERS} == "" ]]; then
25 | VERS="0.0.0"
26 | fi
27 | echo "How would you describe your comparison?"
28 | read -e DESC
29 | sed -i "s/##name/${NAME}/" ${CWD}/package.json
30 | sed -i "s/##description/${DESC}/" ${CWD}/package.json
31 | sed -i "s/##version/${VERS}/" ${CWD}/package.json
32 | npm install
33 | npm i ultimate-comparison@next
34 | }
35 |
36 | start () {
37 | npm start
38 | }
39 |
40 | dev () {
41 | npm run dev
42 | }
43 |
44 | if [[ "$1" != "setup" ]] && [[ "$1" != "start" ]] && [[ "$1" != "dev" ]]; then
45 | echo "Invalid command, please use 'uc setup' or 'uc start' or 'uc dev"
46 | else
47 | eval ${1}
48 | fi
49 |
--------------------------------------------------------------------------------
/docs/adr/template.md:
--------------------------------------------------------------------------------
1 | # *[short title of solved problem and solution]*
2 |
3 | **User Story:** *[ticket/issue-number]*
4 |
5 | *[context and problem statement]*
6 | *[decision drivers | forces]*
7 |
8 | ## Considered Alternatives
9 |
10 | * *[alternative 1]*
11 | * *[alternative 2]*
12 | * *[alternative 3]*
13 | * *[...]*
14 |
15 | ## Decision Outcome
16 |
17 | * Chosen Alternative: *[alternative 1]*
18 | * *[justification. e.g., only alternative, which meets k.o. criterion decision driver | which resolves force force | ... | comes out best (see below)]*
19 | * *[consequences. e.g., negative impact on quality attribute, follow-up decisions required, ...]*
20 |
21 | ## Pros and Cons of the Alternatives
22 |
23 | ### *[alternative 1]*
24 |
25 | * `+` *[argument 1 pro]*
26 | * `+` *[argument 2 pro]*
27 | * `-` *[argument 1 con]*
28 | * *[...]*
29 |
30 | ### *[alternative 2]*
31 |
32 | * `+` *[argument 1 pro]*
33 | * `+` *[argument 2 pro]*
34 | * `-` *[argument 1 con]*
35 | * *[...]*
36 |
37 | ### *[alternative 3]*
38 |
39 | * `+` *[argument 1 pro]*
40 | * `+` *[argument 2 pro]*
41 | * `-` *[argument 1 con]*
42 | * *[...]*
43 |
--------------------------------------------------------------------------------
/lib/gulp/model/citation/citationFiles.js:
--------------------------------------------------------------------------------
1 | import { isNullOrUndefined, resolveDefault } from "../util";
2 |
3 | const defaultConfiguration = require("../default");
4 |
5 | class CitationFiles {
6 | constructor(csl, bib, useDefaults = true) {
7 | const ref = {
8 | csl: csl,
9 | bib: bib
10 | };
11 |
12 | const defaultConfig = this.constructor.defaultConfig || defaultConfiguration;
13 | const configuration = defaultConfig.citation;
14 |
15 | if (useDefaults) {
16 | if (isNullOrUndefined(csl)) {
17 | ref.csl = resolveDefault(configuration.csl, ref);
18 | }
19 |
20 | if (isNullOrUndefined(bib)) {
21 | ref.bib = resolveDefault(configuration.bib, ref);
22 | }
23 | }
24 |
25 | this.csl = ref.csl;
26 | this.bib = ref.bib;
27 | }
28 |
29 | static load(json, defaultConfig, useDefaults) {
30 | CitationFiles.defaultConfig = defaultConfig;
31 | if (isNullOrUndefined(json)) {
32 | return CitationFiles.empty(useDefaults);
33 | } else {
34 | return new CitationFiles(
35 | json.csl,
36 | json.bib,
37 | useDefaults
38 | );
39 | }
40 | }
41 |
42 | static empty(useDefaults) {
43 | return new CitationFiles(null, null, useDefaults);
44 | }
45 |
46 | json() {
47 | return {csl: this.csl, bib: this.bib};
48 | }
49 | }
50 |
51 | export { CitationFiles };
52 |
--------------------------------------------------------------------------------
/src/app/components/comparison/details/comparison.details.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: grid;
3 | padding: 0;
4 | }
5 |
6 | :host h2 ptooltip {
7 | font-family: Roboto, Noto, sans-serif;
8 | font-size: 14px;
9 | font-weight: 400;
10 | }
11 |
12 | .mylabel {
13 | margin: 2px;
14 | display: inline-block !important;
15 | cursor: pointer;
16 | font-size: 14px !important;
17 | white-space: inherit;
18 | }
19 |
20 | .card-content {
21 | position: relative;
22 | }
23 |
24 | .tooltip-text {
25 | display: inline-table;
26 | }
27 |
28 | .tooltip-text ::ng-deep ul {
29 | padding-left: 15px;
30 | }
31 |
32 | .pheader h2 {
33 | margin-top: 0;
34 | }
35 |
36 | .description {
37 | grid-column: span 1;
38 | }
39 |
40 | .grid-content {
41 | display: grid;
42 | grid-template-columns: auto;
43 | grid-column-gap: 10px;
44 | grid-row-gap: 10px;
45 | grid-auto-flow: row;
46 | }
47 |
48 | @media only screen and (min-width: 400px) {
49 | .description {
50 | grid-column: span 2;
51 | }
52 |
53 | .grid-content {
54 | grid-template-columns: 1fr 1fr;
55 | }
56 | }
57 |
58 | .tt-container {
59 | display: grid;
60 | grid-template-columns: auto 1fr;
61 | }
62 |
63 | .tt-label {
64 | grid-column: 1;
65 | margin: 1px 2px auto 2px;
66 | }
67 |
68 | tt-tooltip {
69 | grid-column: 2;
70 | }
71 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { AppComponent } from './app.component';
4 | import { ComparisonModule } from './components/comparison/comparison.module';
5 | import { StoreModule } from '@ngrx/store';
6 | import { masterReducer } from './redux/uc.reducers';
7 | import { RouterModule } from '@angular/router';
8 | import { ComparisonComponent } from './components/comparison/comparison.component';
9 | import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store';
10 | import { APP_BASE_HREF } from '@angular/common';
11 | import { CustomRouterStateSerializer } from './redux/custom-router-state-serializer';
12 |
13 | @NgModule({
14 | imports: [
15 | BrowserModule,
16 | ComparisonModule,
17 | StoreModule.forRoot({
18 | state: masterReducer
19 | }),
20 | RouterModule.forRoot([{
21 | path: '', component: ComparisonComponent
22 | }], {useHash: false}),
23 | StoreRouterConnectingModule
24 | ],
25 | declarations: [
26 | AppComponent,
27 | ],
28 | providers: [
29 | {provide: APP_BASE_HREF, useValue: window['_app_base'] || '/'},
30 | {provide: RouterStateSerializer, useClass: CustomRouterStateSerializer}
31 | ],
32 | bootstrap: [AppComponent]
33 | })
34 | export class AppModule {
35 | }
36 |
--------------------------------------------------------------------------------
/src/app/redux/custom-router-state-serializer.ts:
--------------------------------------------------------------------------------
1 | import { RouterStateSerializer } from '@ngrx/router-store';
2 | import { Params, RouterStateSnapshot } from '@angular/router';
3 |
4 | export interface RouterStateUrl {
5 | url: string;
6 | queryParams: Params;
7 | sectionLink: string
8 | }
9 |
10 | export class CustomRouterStateSerializer implements RouterStateSerializer {
11 | serialize(routerState: RouterStateSnapshot): RouterStateUrl {
12 | let { url } = routerState;
13 | const queryParams = {};
14 | let route = routerState.root;
15 |
16 | while (route.firstChild) {
17 | route = route.firstChild;
18 | }
19 | if (url.startsWith('/')) {
20 | url = url.substr(1);
21 | }
22 | if (url.startsWith('#')) {
23 | url = url.substr(1);
24 | }
25 | let sectionLink: string = null;
26 |
27 | for (const u of url.split('&')) {
28 | const regex = /\??(.+)=(.*)/.exec(u);
29 | if (regex === null) {
30 | continue;
31 | }
32 | const key = regex[1];
33 | let value = regex[2];
34 |
35 | if (value.indexOf('#') > -1) {
36 | [value, sectionLink] = value.split('#');
37 | }
38 |
39 | queryParams[key] = value;
40 | }
41 |
42 | return { url, queryParams, sectionLink };
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/lib/gulp/model/details/body.js:
--------------------------------------------------------------------------------
1 | import { deleteUndefinedKeys, isNullOrUndefined, resolveDefault } from "../util";
2 |
3 | const defaultConfiguration = require("../default");
4 |
5 | class Body {
6 | constructor(title, bodyRef, useDefaults = true) {
7 | const ref = {
8 | title: title,
9 | bodyRef: bodyRef
10 | };
11 |
12 | const defaultConfig = this.constructor.defaultConfig || defaultConfiguration;
13 | const configuration = defaultConfig.details.body;
14 |
15 | if (useDefaults) {
16 | if (isNullOrUndefined(title)) {
17 | ref.title = resolveDefault(configuration.title, ref);
18 | }
19 |
20 | if (isNullOrUndefined(bodyRef)) {
21 | ref.bodyRef = resolveDefault(configuration.bodyRef, ref);
22 | }
23 | }
24 |
25 | this.title = ref.title;
26 | this.bodyRef = ref.bodyRef;
27 | }
28 |
29 | static load(json, defaultConfig, useDefaults) {
30 | Body.defaultConfig = defaultConfig;
31 | if (isNullOrUndefined(json)) {
32 | return Body.empty(useDefaults);
33 | } else {
34 | return new Body(
35 | json.title,
36 | json.bodyRef,
37 | useDefaults
38 | );
39 | }
40 | }
41 |
42 | static empty(useDefaults) {
43 | return new Body(null, null, useDefaults);
44 | }
45 |
46 | json() {
47 | return deleteUndefinedKeys({
48 | title: this.title,
49 | bodyRef: this.bodyRef
50 | });
51 | }
52 | }
53 |
54 | export { Body };
55 |
--------------------------------------------------------------------------------
/src/app/components/output/generic-table/generic-table.component.css:
--------------------------------------------------------------------------------
1 | :host {
2 | display: block;
3 | }
4 |
5 | .grid-table {
6 | display: grid;
7 | grid-template-columns: auto;
8 | grid-column-gap: 10px;
9 | grid-row-gap: 10px;
10 | grid-auto-flow: column;
11 |
12 | }
13 |
14 | .mylabel {
15 | margin: 2px;
16 | display: inline-block !important;
17 | cursor: pointer;
18 | font-size: 14px !important;
19 | white-space: inherit;
20 | }
21 |
22 | .label-unknown {
23 | color: black;
24 | border: solid black 1px;
25 | }
26 |
27 | th {
28 | padding: 0 2px 2px 4px;
29 | vertical-align: bottom;
30 | }
31 |
32 | td {
33 | padding: 2px 2px 0 4px;
34 | vertical-align: top;
35 | border-top: 1px solid #ddd;
36 | }
37 |
38 | th > button {
39 | border: none;
40 | padding: 0;
41 | outline: none;
42 | background-color: white;
43 | position: sticky;
44 | position: -webkit-sticky;
45 | top: 0; /* required */
46 |
47 | }
48 |
49 | table th {
50 | position: sticky;
51 | top: 0px;
52 | background: white;
53 | z-index: 4998;
54 | }
55 |
56 | table tr {
57 | white-space: normal;
58 | line-height: 1em;
59 | }
60 |
61 | table {
62 | width: auto;
63 | }
64 |
65 | .anchored::before {
66 | content: '';
67 | display: block;
68 | height: 48px;
69 | margin: -48px 0 0;
70 | }
71 |
72 | .unknown {
73 | background-color: lightgray;
74 | color: white;
75 | }
76 |
--------------------------------------------------------------------------------
/src/app/components/polymer/polymer.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { PaperCardComponent } from './paper-card/paper-card.component';
4 | import { IronIconComponent } from './iron-icon/iron-icon.component';
5 | import { TooltipComponent } from './tooltip/tooltip.component';
6 | import { PaperIconButtonComponent } from './paper-icon-button/paper-icon-button.component';
7 | import { PaperButtonComponent } from './paper-button/paper-button.component';
8 | import { PaperDialogComponent } from './paper-dialog/paper-dialog.component';
9 | import { PaperItemComponent } from './paper-item/paper-item.component';
10 | import { PaperCheckboxComponent } from './paper-checkbox/paper-checkbox.component';
11 |
12 | @NgModule({
13 | imports: [
14 | BrowserModule
15 | ],
16 | exports: [
17 | PaperCardComponent,
18 | IronIconComponent,
19 | TooltipComponent,
20 | PaperIconButtonComponent,
21 | PaperButtonComponent,
22 | PaperDialogComponent,
23 | PaperItemComponent,
24 | PaperCheckboxComponent
25 | ],
26 | declarations: [
27 | PaperCardComponent,
28 | IronIconComponent,
29 | TooltipComponent,
30 | PaperIconButtonComponent,
31 | PaperButtonComponent,
32 | PaperDialogComponent,
33 | PaperItemComponent,
34 | PaperCheckboxComponent
35 | ]
36 | })
37 | export class PolymerModule {
38 | }
39 |
--------------------------------------------------------------------------------
/lib/gulp/model/configuration/configuration.d.ts:
--------------------------------------------------------------------------------
1 | import { CitationFiles } from '../citation/citationFiles';
2 | import { Criteria } from '../criteria/criteria';
3 | import { Details } from '../details/details';
4 | import { Citation } from '../citation/citation';
5 |
6 | export class Configuration {
7 | public title: string;
8 | public subtitle: string;
9 | public selectTitle: string;
10 | public tableTitle: string;
11 | public repository: string;
12 | public details: Details;
13 | public criteria: Array;
14 | public citation: Array;
15 | public citationFiles: CitationFiles;
16 |
17 | constructor(title?: string,
18 | subtitle?: string,
19 | selectTitle?: string,
20 | tableTitle?: string,
21 | repository?: string,
22 | details?: Details,
23 | criteria?: Array,
24 | citation?: CitationFiles,
25 | useDefaults?: boolean);
26 |
27 | public static load(json, defaultConfig?, useDefaults?): Configuration;
28 |
29 | public static empty(useDefaults?): Configuration;
30 |
31 | public json(): Object;
32 |
33 | public setCitation(csl: string, bibtex: string): Configuration;
34 |
35 | public hasCitation(key: string): boolean;
36 |
37 | public containsCriteria(name: string): boolean;
38 |
39 | public setCriteria(index: number, criteria: Criteria): Configuration;
40 |
41 | public getCriteria(name: string): Criteria;
42 |
43 | public combine(other: Configuration): Configuration;
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/configuration/comparison-auto-config.yml:
--------------------------------------------------------------------------------
1 | citations:
2 | - index: 0
3 | key: 'Adi:2004:ASM:988145.988150'
4 | text: >-
5 | Adi, A. and Etzion, O. 2004. Amit – the Situation Manager. The VLDB
6 | Journal 13, 2, 177–203.
7 | - index: 1
8 | key: Bry07towardsformal
9 | text: >-
10 | Bry, F. 2007. Towards formal foundations of event queries and rules. In
11 | Proc. Int. Workshop on Event-Driven Architecture, Processing and Systems.
12 | - index: 2
13 | key: 'Dayal:1988:ROT:60295.60304'
14 | text: >-
15 | Dayal, U., Buchmann, A.P., and McCarthy, D.R. 1988. Rules Are Objects Too:
16 | A Knowledge Model for an Active, Object-oriented Databasesystem. Lecture
17 | Notes in Computer Science on Advances in Object-oriented Database Systems,
18 | Springer-Verlag New York, Inc., 129–143.
19 | - index: 3
20 | key: eckertThesisCEP
21 | text: >-
22 | Eckert, M. 2008. Complex Event Processing with XChange EQ : Language
23 | Design, Formal Semantics, and Incremental Evaluation for Querying Events.
24 | - index: 5
25 | key: esper-reference
26 | text: >-
27 | Team, E. Esper Reference documentation.
28 | http://www.espertech.com/esper/release-5.1.0/esper-reference/pdf/esper_reference.pdf.
29 | criteria:
30 | - NumberColumn:
31 | type: LABEL
32 | values:
33 | '100':
34 | color: '#0d0d0d'
35 | backgroundColor: 'hsl(75, 100%, 70%)'
36 | '233':
37 | color: '#0d0d0d'
38 | backgroundColor: 'hsl(105, 100%, 70%)'
39 |
--------------------------------------------------------------------------------
/lib/gulp/model/util.js:
--------------------------------------------------------------------------------
1 | export function isNullOrUndefined(value) {
2 | return value === undefined || value === null;
3 | }
4 |
5 | export function resolveDefault(def, ref) {
6 | if (!isNullOrUndefined(def) && def.hasOwnProperty('template')) {
7 | let i = 0;
8 | return def.template.replace(/{}/g, (x) => ref[def.variables[i++]])
9 | } else {
10 | return def;
11 | }
12 | }
13 |
14 | export function resolveLock(id, ref) {
15 | if (ref.lock.hasOwnProperty(id)) {
16 | return ref.lock[id];
17 | } else {
18 | return {};
19 | }
20 | }
21 |
22 | export function deleteUndefinedKeys(obj) {
23 | Object.keys(obj).forEach(key => isNullOrUndefined(obj[key]) && delete obj[key]);
24 | return obj;
25 | }
26 |
27 | export function splitNameUrl(string) {
28 | const regex = /^((?:.*?)+?(?:-?.*?)+?)\s*-?\s*((?:(?:http|ftp|https)(?::\/\/)(?:[\w_-]+(?:(?:\.[\w_-]+)+))|(?:www.))(?:[\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?)$/gi
29 | .exec(string);
30 |
31 | const result = {
32 | name: (!isNullOrUndefined(regex) && regex.length > 1) ? regex[1] : "",
33 | url: (!isNullOrUndefined(regex) && regex.length > 2) ? regex[2] : ""
34 | }
35 |
36 | if (/^www/.test(result.url)) {
37 | result.url = 'http://'.concat(result.url);
38 | }
39 |
40 | return result;
41 | }
42 |
43 | export function getDefaultCriteria(criteria, type) {
44 | let key = "default-" + (type || "").toString().toLowerCase();
45 |
46 | const result = criteria.filter(value => value.hasOwnProperty(key));
47 | if (result.length > 0) {
48 | return result[0][key];
49 | }
50 | return {};
51 | }
52 |
--------------------------------------------------------------------------------
/lib/gulp/model/citation/citation.js:
--------------------------------------------------------------------------------
1 | import { isNullOrUndefined } from "../util";
2 |
3 | const Cite = require('citation-js');
4 |
5 | class Citation {
6 | constructor(index, key, text) {
7 | this.index = index;
8 | this.key = key;
9 | this.text = text;
10 | }
11 |
12 | static load(json) {
13 | const result = [];
14 | if (!isNullOrUndefined(json)) {
15 | json.forEach(obj => {
16 | result.push(new Citation(obj.index, obj.key, obj.text));
17 | })
18 | }
19 | return result;
20 | }
21 |
22 | static loadArray(csl, bibtex) {
23 | // Set Citation style (csl)
24 | if (!isNullOrUndefined(csl)) {
25 | Cite.CSL.register.addTemplate("defaultParameter", csl.toString());
26 | }
27 |
28 | // Use citation-js to convert
29 | const bibtexNormalized = (bibtex || "").toString().replace(/^%.*\n?/gm, '').trim();
30 | if (bibtexNormalized.length === 0) {
31 | return [];
32 | }
33 | const cite = new Cite(bibtexNormalized, {forceType: 'string/bibtex'});
34 | return (cite.data || []).map((item, index) => {
35 | let itemData = new Cite(item);
36 | const key = item.id;
37 | const text = (csl ?
38 | itemData.get({
39 | type: 'string',
40 | style: 'citation-defaultParameter'
41 | }) :
42 | item.get({type: 'string'})
43 | ).trim().replace(/\. \./gm, ".");
44 | return new Citation(index, key, text);
45 | });
46 | }
47 |
48 | json() {
49 | return {
50 | index: this.index,
51 | key: this.key,
52 | text: this.text
53 | };
54 | }
55 | }
56 |
57 | export {
58 | Citation
59 | };
60 |
--------------------------------------------------------------------------------
/lib/gulp/publish.js:
--------------------------------------------------------------------------------
1 | const spawn = require('child_process').spawn;
2 | const argv = require('minimist')(process.argv.slice(2));
3 |
4 | spawn(
5 | 'node',
6 | [
7 | './node_modules/gulp/bin/gulp.js',
8 | 'release',
9 | '--gulpfile=./lib/gulp/gulpfile.js',
10 | '--tag=' + argv.tag
11 | ],
12 | {
13 | stdio: 'inherit'
14 | }
15 | ).on('close', (code) => {
16 | if (code === 0) {
17 | spawn('node',
18 | [
19 | './node_modules/gulp/bin/gulp.js',
20 | 'default',
21 | '--gulpfile=./lib/gulp/gulpfile.js'
22 | ],
23 | {
24 | stdio: 'inherit'
25 | }
26 | ).on('close', (code1 => {
27 | if (code1 === 0) {
28 | spawn('webpack',
29 | [
30 | '--config', 'lib/webpack/webpack.prod.js',
31 | '--progress',
32 | '--profile',
33 | '--bail'
34 | ],
35 | {
36 | stdio: 'inherit'
37 | }
38 | ).on('close', (code2 => {
39 | if (code2 === 0) {
40 | spawn('git', ['add', 'src/assets/VersionInformation.ts'], {stdio: 'inherit'});
41 | spawn('git', ['commit', '-m "Update VersionInformation.ts"'], {stdio: 'inherit'});
42 | spawn('np', [argv.tag, '--tag=latest'], {stdio: 'inherit'});
43 | }
44 | }));
45 | }
46 | }));
47 | }
48 | });
49 |
50 |
--------------------------------------------------------------------------------
/lib/uc/README.md:
--------------------------------------------------------------------------------
1 | # Ultimate THING Comparison [](https://travis-ci.org/example.com/ultimate-THING-comparison)
2 |
3 | This is an ultimate comparison of THINGs.
4 |
5 | ## Start the comparison
6 |
7 | 1. Install dependencies `npm install`
8 | 2. Start web server `npm start`
9 | 3. Alternatively start development mode `npm run dev`
10 |
11 | ## Deploy comparison with github and travis
12 |
13 | 1. [Setup Git](https://help.github.com/articles/set-up-git/)
14 | 2. [Setup Travis](https://docs.travis-ci.com/user/getting-started/)
15 | - Changes to `.travis.yml` are not required
16 | 3. [Create a personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)
17 | 4. [Add the environment variable `GITHUB_TOKEN` to travis](https://docs.travis-ci.com/user/environment-variables#Defining-Variables-in-Repository-Settings)
18 |
19 | ## Ultimate-THING-Comparison Element Specification
20 |
21 | The code below shows a sample element.
22 |
23 | ```markdown
24 | # THING Element - http://example.com
25 | Element short description ...
26 |
27 | ## Description
28 | Element long __markdown__ description ...
29 |
30 | ## Property 1
31 | - Label 1
32 | - Tooltip for label 1
33 | - Label 2
34 | - Itemized tooltip for label 1
35 | - Second tooltip item
36 |
37 | ## Property 2
38 | - Label 3
39 | - Label 4
40 | - Label 5
41 |
42 | ## Rating
43 | - [1] Bad THING
44 | - [3] It is ok
45 | - [5] Good THING
46 | ```
47 |
48 | ## License
49 |
50 | The content is licensed under [CC0-1.0].
51 |
52 | [CC0-1.0]: https://creativecommons.org/publicdomain/zero/1.0/
53 |
--------------------------------------------------------------------------------
/lib/md-to-json/src/main/java/json/converter/JsonConverterExtension.java:
--------------------------------------------------------------------------------
1 | package json.converter;
2 |
3 | import com.vladsch.flexmark.Extension;
4 | import com.vladsch.flexmark.html.HtmlRenderer;
5 | import com.vladsch.flexmark.parser.Parser;
6 | import com.vladsch.flexmark.util.options.MutableDataHolder;
7 | import json.converter.internal.JsonConverterNodeRenderer;
8 |
9 | public class JsonConverterExtension implements Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension {
10 | private JsonConverterExtension() {
11 |
12 | }
13 |
14 | public static Extension create() {
15 | return new JsonConverterExtension();
16 | }
17 |
18 | @Override
19 | public void rendererOptions(MutableDataHolder options) {
20 | final String rendererType = HtmlRenderer.TYPE.getFrom(options);
21 | if (rendererType.equals("HTML")) {
22 | options.set(HtmlRenderer.TYPE, "JSON");
23 | } else if (!rendererType.equals("JSON")) {
24 | throw new IllegalStateException("Non HTML Renderer is already set to " + rendererType);
25 | }
26 | }
27 |
28 | @Override
29 | public void extend(HtmlRenderer.Builder rendererBuilder, String rendererType) {
30 | if (rendererType.equals("JSON")) {
31 | rendererBuilder.nodeRendererFactory(new JsonConverterNodeRenderer.Factory());
32 | } else {
33 | throw new IllegalStateException("JSON Converter Extension used with non JSON Renderer " + rendererType);
34 | }
35 | }
36 |
37 | @Override
38 | public void parserOptions(MutableDataHolder options) {
39 |
40 | }
41 |
42 | @Override
43 | public void extend(Parser.Builder parserBuilder) {
44 |
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/app/components/comparison/settings/comparison.settings.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, EventEmitter, Input, Output } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'comparison-settings',
5 | templateUrl: './comparison.settings.template.html',
6 | styleUrls: ['./comparison.settings.component.css']
7 | })
8 | export class ComparisonSettingsComponent {
9 | @Input() columnDisplayAll: boolean = false;
10 | @Input() columnNames: Array = [];
11 | @Input() columnsEnabled: Array = [];
12 |
13 | @Input() elementDisplayAll: boolean = true;
14 | @Input() elementNames: Array = [];
15 | @Input() elementsEnabled: Array = [];
16 |
17 | @Input() latexDisplayTable: boolean = false;
18 | @Input() latexEnableTooltips: boolean = false;
19 | @Input() latexTooltipsAsFootnotes: boolean = false;
20 |
21 | @Input() detailsDisplayTooltips: boolean = false;
22 |
23 | @Output() columnsDisplayAllChange: EventEmitter = new EventEmitter();
24 | @Output() columnChange: EventEmitter = new EventEmitter();
25 |
26 | @Output() elementsDisplayAllChange: EventEmitter = new EventEmitter();
27 | @Output() elementChange: EventEmitter = new EventEmitter();
28 |
29 | @Output() latexDisplayTableChange: EventEmitter = new EventEmitter();
30 | @Output() latexEnableTooltipsChange: EventEmitter = new EventEmitter();
31 | @Output() latexTooltipsAsFootnotesChange: EventEmitter = new EventEmitter();
32 | @Output() latexDownload: EventEmitter = new EventEmitter();
33 |
34 | @Output() detailsDisplayTooltipsChange: EventEmitter = new EventEmitter();
35 | }
36 |
--------------------------------------------------------------------------------
/lib/gulp/model/criteria/criteria.d.ts:
--------------------------------------------------------------------------------
1 | import { CriteriaValue } from './criteriaValue';
2 |
3 | export class Criteria {
4 | public id: string;
5 | public type: CriteriaTypes;
6 | public name: string;
7 | public search: boolean;
8 | public table: boolean;
9 | public detail: boolean;
10 | public description: string;
11 | public placeholder: string;
12 | public order: string;
13 | public andSearch: boolean;
14 | public rangeSearch: boolean;
15 | public values: Map;
16 | public lock: Map;
17 |
18 | constructor(id: string,
19 | type: CriteriaTypes,
20 | name?: string,
21 | search?: boolean,
22 | table?: boolean,
23 | details?: boolean,
24 | description?: string,
25 | placeholder?: string,
26 | order?: string,
27 | andSearch?: boolean,
28 | rangeSearch?: boolean,
29 | values?: Map,
30 | lock?: Map,
31 | useDefaults?: boolean);
32 |
33 | public static copy(id: string, name: string, criteria: Criteria);
34 |
35 | public static empty(key, type, useDefaults?, defaultConfiguration?): Criteria;
36 |
37 | public static load(key, type, json, defaultConfig?, useDefaults?): Criteria;
38 |
39 | public static loadArray(json, defaultConfig?, useDefaults?): Array;
40 |
41 | public getValue(name: string): CriteriaValue;
42 |
43 | public combine(other: Criteria): Criteria;
44 | }
45 |
46 | export enum CriteriaTypes {
47 | NAME_URL = 'NAME_URL',
48 | LABEL = 'LABEL',
49 | TEXT = 'TEXT',
50 | MARKDOWN = 'MARKDOWN',
51 | RATING = 'RATING',
52 | REPOSITORY = 'REPOSITORY'
53 | }
54 |
55 | export const CriteriaTypeKeys: string[];
56 |
--------------------------------------------------------------------------------
/lib/gulp/model/details/details.js:
--------------------------------------------------------------------------------
1 | import { Header } from "./header";
2 | import { Body } from "./body";
3 | import { deleteUndefinedKeys, isNullOrUndefined } from "../util";
4 |
5 | const defaultConfiguration = require("../default");
6 |
7 | class Details {
8 | constructor(header, body, tooltipAsText, useDefaults = true) {
9 | const ref = {
10 | header: header,
11 | body: body,
12 | tooltipAsText: tooltipAsText
13 | };
14 |
15 | if (isNullOrUndefined(header)) {
16 | ref.header = Header.empty(useDefaults);
17 | }
18 |
19 | if (isNullOrUndefined(body)) {
20 | ref.body = Body.empty(useDefaults);
21 | }
22 |
23 | if (useDefaults) {
24 | const defaultConfig = this.constructor.defaultConfig || defaultConfiguration;
25 | const def = defaultConfig.details;
26 |
27 | if (isNullOrUndefined(tooltipAsText)) {
28 | ref.tooltipAsText = def.tooltipAsText;
29 | }
30 | }
31 |
32 | this.header = ref.header;
33 | this.body = ref.body;
34 | this.tooltipAsText = ref.tooltipAsText;
35 | }
36 |
37 | static load(json, defaultConfig, useDefaults) {
38 | if (isNullOrUndefined(json)) {
39 | return Details.empty(useDefaults);
40 | } else {
41 | return new Details(
42 | Header.load(json.header, defaultConfig, useDefaults),
43 | Body.load(json.body, defaultConfig, useDefaults),
44 | json.tooltipAsText,
45 | useDefaults
46 | );
47 | }
48 | }
49 |
50 | static empty(useDefaults) {
51 | return new Details(null, null, null, useDefaults);
52 | }
53 |
54 | json() {
55 | return deleteUndefinedKeys({
56 | header: this.header.json(),
57 | body: this.body.json(),
58 | tooltipAsText: this.tooltipAsText
59 | });
60 | }
61 | }
62 |
63 | export { Details };
64 |
--------------------------------------------------------------------------------
/lib/md-to-json/src/test/java/json/converter/JsonConverterTest.java:
--------------------------------------------------------------------------------
1 | package json.converter;
2 |
3 | import com.vladsch.flexmark.ast.Node;
4 | import com.vladsch.flexmark.html.HtmlRenderer;
5 | import com.vladsch.flexmark.parser.Parser;
6 | import com.vladsch.flexmark.util.options.MutableDataSet;
7 | import json.converter.internal.JsonConverterNodeRenderer;
8 | import org.eclipse.collections.impl.factory.Maps;
9 | import org.junit.jupiter.api.Test;
10 | import org.skyscreamer.jsonassert.JSONAssert;
11 |
12 | import java.nio.file.Files;
13 | import java.nio.file.Path;
14 | import java.nio.file.Paths;
15 | import java.util.Collections;
16 | import java.util.Objects;
17 |
18 | public class JsonConverterTest {
19 |
20 | private String loadResource(String name) throws Exception {
21 | Path path = Paths.get(Objects.requireNonNull(this.getClass().getClassLoader().getResource(name)).toURI());
22 | return new String(Files.readAllBytes(path));
23 | }
24 |
25 | @Test
26 | public void test() throws Exception {
27 | MutableDataSet options = new MutableDataSet();
28 | options.set(Parser.EXTENSIONS, Collections.singletonList(JsonConverterExtension.create()));
29 | options.set(HtmlRenderer.INDENT_SIZE, 2);
30 | options.set(JsonConverterNodeRenderer.PLAIN_CHILDREN, Maps.mutable.with("item", Maps.mutable.with("1", true)));
31 | options.set(JsonConverterNodeRenderer.CHILDREN, Maps.mutable.with("item", Maps.mutable.with("1", false)));
32 |
33 | Parser parser = Parser.builder(options).build();
34 | HtmlRenderer renderer = HtmlRenderer.builder(options).build();
35 |
36 | Node document = parser.parse(loadResource("test.md"));
37 |
38 | String json = renderer.render(document);
39 |
40 | JSONAssert.assertEquals(loadResource("test.json"), json, false);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/gulp/model/details/header.js:
--------------------------------------------------------------------------------
1 | import { deleteUndefinedKeys, isNullOrUndefined, resolveDefault } from "../util";
2 |
3 | const defaultConfiguration = require("../default");
4 |
5 | class Header {
6 | constructor(nameRef, labelRef, urlRef, useDefaults = true) {
7 | const ref = {
8 | nameRef: nameRef,
9 | labelRef: labelRef,
10 | urlRef: urlRef
11 | };
12 |
13 | const defaultConfig = this.constructor.defaultConfig || defaultConfiguration;
14 |
15 | const configuration = defaultConfig.details.header;
16 |
17 | if (ref.urlRef === "inline") {
18 | ref.urlRef = "id";
19 | }
20 |
21 | if (useDefaults) {
22 | if (isNullOrUndefined(nameRef)) {
23 | ref.nameRef = resolveDefault(configuration.nameRef, ref);
24 | }
25 |
26 | if (isNullOrUndefined(labelRef)) {
27 | ref.labelRef = resolveDefault(configuration.labelRef, ref);
28 | }
29 |
30 | if (isNullOrUndefined(urlRef)) {
31 | ref.urlRef = resolveDefault(configuration.urlRef, ref);
32 | }
33 | }
34 |
35 |
36 | this.nameRef = ref.nameRef;
37 | this.labelRef = ref.labelRef;
38 | this.urlRef = ref.urlRef;
39 | }
40 |
41 | static load(json, defaultConfig, useDefaults) {
42 | Header.defaultConfig = defaultConfig;
43 | if (isNullOrUndefined(json)) {
44 | return Header.empty(useDefaults);
45 | } else {
46 | return new Header(
47 | json.nameRef,
48 | json.labelRef,
49 | json.urlRef,
50 | useDefaults
51 | );
52 | }
53 | }
54 |
55 | static empty(useDefaults) {
56 | return new Header(null, null, null, useDefaults);
57 | }
58 |
59 | json() {
60 | return deleteUndefinedKeys({
61 | nameRef: this.nameRef,
62 | labelRef: this.labelRef,
63 | urlRef: this.urlRef
64 | });
65 | }
66 | }
67 |
68 | export { Header };
69 |
--------------------------------------------------------------------------------
/src/app/components/output/generic-table/generic-table.component.ts:
--------------------------------------------------------------------------------
1 | import { AfterViewChecked, ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
2 | import * as AnchorJS from 'anchor-js';
3 | import { CriteriaData, Label } from '../../../../../lib/gulp/model/model.module';
4 |
5 | @Component({
6 | selector: 'generictable',
7 | templateUrl: './generic-table.component.html',
8 | styleUrls: ['./generic-table.component.css'],
9 | changeDetection: ChangeDetectionStrategy.OnPush
10 | })
11 | export class GenericTableComponent implements AfterViewChecked, OnChanges {
12 | @Input() changeNum = 0;
13 |
14 | @Output() settingsCallback: EventEmitter = new EventEmitter();
15 | @Output() showDetails: EventEmitter = new EventEmitter();
16 | @Output() searchFor: EventEmitter = new EventEmitter();
17 | @Output() orderChange: EventEmitter = new EventEmitter();
18 |
19 | @Input() columns: Array = [];
20 | @Input() types: Array = [];
21 | @Input() items: Array> = [];
22 | @Input() index: Array = [];
23 | @Input() order: Array = [];
24 |
25 | private table;
26 | private anchor;
27 |
28 | public labelClick(event: MouseEvent, key: Label, index: number) {
29 | this.searchFor.emit({event, key, index});
30 | }
31 |
32 | public orderClick(e: MouseEvent, value: number) {
33 | this.orderChange.emit({index: value, ctrl: e.ctrlKey});
34 | }
35 |
36 | ngAfterViewChecked(): void {
37 | this.anchor = new AnchorJS({placement: 'right'}).add('.anchored');
38 | }
39 |
40 | ngOnChanges(changes): void {
41 | this.update();
42 | }
43 |
44 | public update(): void {
45 | if (this.table != null) {
46 | this.table.trigger('reflow');
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/app/redux/uc.action.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 | import {
3 | CLICK_ACTION,
4 | NEW_STATE_ACTION,
5 | TOGGLE_DETAILS_ACTION,
6 | UPDATE_DATA,
7 | UPDATE_ORDER,
8 | UPDATE_SEARCH,
9 | UPDATE_SETTINGS
10 | } from './uc.reducers';
11 | import { IUCAppState } from './uc.app-state';
12 | import { Criteria, DataElement } from '../../../lib/gulp/model/model.module';
13 |
14 | export class UCAction implements Action {
15 | type: string;
16 | value: number;
17 | }
18 |
19 | export class UCRouterAction extends UCAction {
20 | payload: any;
21 | }
22 |
23 | export class UCDataUpdateAction extends UCAction {
24 | type = UPDATE_DATA;
25 |
26 | constructor(public criterias: Map) {
27 | super();
28 | }
29 | }
30 |
31 | export class UCSearchUpdateAction extends UCAction {
32 | type = UPDATE_SEARCH;
33 |
34 | constructor(public criterias: Map) {
35 | super();
36 | }
37 | }
38 |
39 | export class UCTableOrderAction extends UCAction {
40 | type = UPDATE_ORDER;
41 |
42 | constructor(public index: number, public ctrl: boolean) {
43 | super();
44 | }
45 | }
46 |
47 | export class UCSettingsUpdateAction extends UCAction {
48 | type = UPDATE_SETTINGS;
49 |
50 | constructor(public enable: boolean, public operation: string) {
51 | super();
52 | }
53 | }
54 |
55 | export class UCClickAction extends UCAction {
56 | type = CLICK_ACTION;
57 |
58 | constructor(public val: string, public index: number) {
59 | super();
60 | }
61 | }
62 |
63 | export class UCNewStateAction extends UCAction {
64 | type = NEW_STATE_ACTION;
65 |
66 | constructor(public newState: IUCAppState) {
67 | super();
68 | }
69 | }
70 |
71 | export class UCDetailsAction extends UCAction {
72 | type = TOGGLE_DETAILS_ACTION;
73 |
74 | constructor(public data: DataElement) {
75 | super();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/app/components/polymer/paper-checkbox/paper-checkbox.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, Output,
3 | Renderer
4 | } from "@angular/core";
5 |
6 | @Component({
7 | selector: 'pcheckbox',
8 | templateUrl: './paper-checkbox.component.html',
9 | styleUrls: ['./paper-checkbox.component.css'],
10 | changeDetection: ChangeDetectionStrategy.OnPush
11 | })
12 | export class PaperCheckboxComponent implements OnChanges {
13 | @Input() label: string;
14 | @Input() checked: boolean;
15 | @Output() checkedChange: EventEmitter = new EventEmitter();
16 |
17 | constructor(private el: ElementRef, private renderer: Renderer) {
18 | }
19 |
20 | ngOnChanges() {
21 | if (this.checked) {
22 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'background-color', '#3f51b5');
23 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'border-color', '#3f51b5');
24 | } else {
25 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'background-color', '#fff');
26 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'border-color', '#000');
27 | }
28 | this.el.nativeElement.checked = this.checked;
29 | }
30 |
31 | @HostListener('click', ['$event'])
32 | onChange(e) {
33 | this.checked = !this.checked;
34 | if (this.checked) {
35 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'background-color', '#3f51b5');
36 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'border-color', '#3f51b5');
37 | } else {
38 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'background-color', '#fff');
39 | this.renderer.setElementStyle(this.el.nativeElement.children[0], 'border-color', '#000');
40 | }
41 | this.el.nativeElement.checked = this.checked;
42 | this.checkedChange.emit(this.checked);
43 | }
44 |
45 | private toogleCheck() {
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/app/components/input/select2/select2.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ChangeDetectionStrategy,
3 | ChangeDetectorRef,
4 | Component,
5 | EventEmitter,
6 | Input,
7 | Output,
8 | ViewChild
9 | } from '@angular/core';
10 | import { isNullOrUndefined } from "util";
11 | import { InputInterface } from "../input-interface";
12 |
13 | @Component({
14 | selector: 'select2',
15 | templateUrl: 'select2.template.html',
16 | styleUrls: [
17 | 'select2.component.css'
18 | ],
19 | changeDetection: ChangeDetectionStrategy.OnPush
20 | })
21 | export class Select2Component implements InputInterface {
22 | public static components: Array = [];
23 | @Input() options: Array