├── .dockerignore
├── .editorconfig
├── .eslintrc.json
├── .github
├── CODEOWNERS
└── workflows
│ └── ci.yaml
├── .gitignore
├── .npmignore
├── .whitesource
├── Dockerfile
├── LICENSE
├── MiQ-UI-Architecture.jpg
├── README.md
├── application-settings.js
├── bin
├── before_install
├── build
├── ci
└── setup
├── demo
├── assets
│ ├── 100
│ │ └── vendor-hawkular.png
│ ├── manageiq.svg
│ ├── protected.svg
│ ├── vendor-centos.svg
│ ├── vendor-chrome.svg
│ ├── vendor-openshift.svg
│ ├── vendor-redhat.svg
│ ├── vendor-ubuntu.svg
│ └── vendor-vmware.svg
├── controllers
│ ├── availableComponentsController.ts
│ ├── dialogEditorController.ts
│ ├── dialogUserController.ts
│ ├── fonticonPickerController.ts
│ ├── index.ts
│ ├── treeSelectorController.ts
│ └── treeViewController.ts
├── data
│ ├── data-table.json
│ ├── dialog-data-refresh.json
│ ├── dialog-data.json
│ ├── dialog_editor.json
│ ├── lazyTree.json
│ └── tree.json
├── index.ts
├── services
│ ├── DialogEditorHttpService.ts
│ ├── availableComponentBuilder.ts
│ ├── availableComponentsService.ts
│ └── translateFilter.ts
├── styles
│ └── demo-app.scss
├── template-index.ejs
└── views
│ ├── dialog
│ ├── editor.html
│ └── user.html
│ ├── fonticon-picker
│ └── basic.html
│ ├── index.ts
│ ├── main.html
│ └── tree-view
│ ├── basic.html
│ └── tree-selector.html
├── jsdoc-conf.json
├── karma.conf.js
├── locale
├── en
│ └── ui-components.po
├── es
│ └── ui-components.po
├── fr
│ └── ui-components.po
├── ja
│ └── ui-components.po
├── pt_BR
│ └── ui-components.po
├── ui-components.pot
├── zanata.xml
└── zh_CN
│ └── ui-components.po
├── package.json
├── pkg
└── .gitkeep
├── renovate.json
├── scripts
├── .coverage.sh
└── validate-gettext-catalog.js
├── src
├── common
│ ├── components
│ │ ├── index.ts
│ │ ├── miqPfSort.html
│ │ ├── miqPfSort.js
│ │ ├── sortItemsComponent.spec.ts
│ │ └── sortItemsComponent.ts
│ ├── filters
│ │ ├── abbrNumberFilter.spec.ts
│ │ ├── abbrNumberFilter.ts
│ │ ├── adjustColorFilter.spec.ts
│ │ ├── adjustColorFilter.ts
│ │ └── index.ts
│ ├── index.ts
│ ├── interfaces
│ │ └── endpoints.ts
│ ├── services
│ │ ├── endpointsService.ts
│ │ ├── enpointsService.spec.ts
│ │ ├── index.ts
│ │ └── translateService.ts
│ └── translateFunction.ts
├── dialog-editor
│ ├── README.md
│ ├── components
│ │ ├── abstractModal.ts
│ │ ├── box
│ │ │ ├── box.html
│ │ │ ├── boxComponent.ts
│ │ │ └── index.ts
│ │ ├── dialog-editor
│ │ │ ├── dialog-editor.html
│ │ │ ├── dialogEditorComponent.ts
│ │ │ └── index.ts
│ │ ├── field
│ │ │ ├── field.html
│ │ │ ├── fieldComponent.ts
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── modal-box
│ │ │ ├── box.html
│ │ │ ├── index.ts
│ │ │ └── modalBoxComponent.ts
│ │ ├── modal-field-template
│ │ │ ├── check-box.html
│ │ │ ├── date-control.html
│ │ │ ├── date-time-control.html
│ │ │ ├── drop-down-list.html
│ │ │ ├── dynamic-values.html
│ │ │ ├── fields-to-refresh.html
│ │ │ ├── index.ts
│ │ │ ├── modalFieldTemplateComponent.spec.ts
│ │ │ ├── modalFieldTemplateComponent.ts
│ │ │ ├── radio-button.html
│ │ │ ├── tag-control.html
│ │ │ ├── text-area-box.html
│ │ │ └── text-box.html
│ │ ├── modal-field
│ │ │ ├── field.html
│ │ │ ├── index.ts
│ │ │ └── modalFieldComponent.ts
│ │ ├── modal-tab
│ │ │ ├── index.ts
│ │ │ ├── modalTabComponent.ts
│ │ │ └── tab.html
│ │ ├── modal
│ │ │ ├── index.ts
│ │ │ ├── modalComponent.spec.ts
│ │ │ └── modalComponent.ts
│ │ ├── tab-list
│ │ │ ├── index.ts
│ │ │ ├── tab-list.html
│ │ │ └── tabListComponent.ts
│ │ ├── toolbox
│ │ │ ├── index.ts
│ │ │ ├── toolbox.html
│ │ │ └── toolboxComponent.ts
│ │ ├── tree-selector
│ │ │ ├── index.ts
│ │ │ ├── tree-selector.html
│ │ │ └── treeSelector.ts
│ │ └── validation
│ │ │ ├── index.ts
│ │ │ ├── validation.html
│ │ │ └── validation.ts
│ ├── index.ts
│ └── services
│ │ ├── dialogEditorService.spec.ts
│ │ ├── dialogEditorService.ts
│ │ ├── dialogValidationService.spec.ts
│ │ ├── dialogValidationService.ts
│ │ └── index.ts
├── dialog-user
│ ├── components
│ │ ├── dialog-user
│ │ │ ├── dialog.html
│ │ │ ├── dialogField.html
│ │ │ ├── dialogField.spec.ts
│ │ │ ├── dialogField.ts
│ │ │ ├── dialogUser.spec.ts
│ │ │ ├── dialogUser.ts
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── index.ts
│ ├── interfaces
│ │ ├── abstractDialogClass.ts
│ │ └── dialog.ts
│ └── services
│ │ ├── dialogData.spec.ts
│ │ ├── dialogData.ts
│ │ └── index.ts
├── fonticon-picker
│ ├── components
│ │ ├── fonticon-family
│ │ │ ├── fonticonFamilyComponent.ts
│ │ │ └── index.ts
│ │ ├── fonticon-picker
│ │ │ ├── fonticon-modal.html
│ │ │ ├── fonticon-picker.html
│ │ │ ├── fonticonPickerComponent.ts
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── index.ts
│ └── services
│ │ ├── fonticonService.ts
│ │ └── index.ts
├── index.ts
├── miq-select
│ ├── index.ts
│ ├── miqOptions.js
│ ├── miqSelect.js
│ └── miqSelect.spec.js
├── styles
│ ├── colors.scss
│ ├── dialog-editor-boxes.scss
│ ├── dialog-editor-toolbox.scss
│ ├── dialog-editor.scss
│ ├── ui-components.scss
│ └── vendor.scss
├── tree-selector
│ ├── index.ts
│ ├── treeSelector.html
│ └── treeSelectorComponent.ts
├── tree-view
│ ├── index.ts
│ ├── treeViewComponent.spec.ts
│ └── treeViewComponent.ts
└── vendor.ts
├── tsconfig.json
├── tslint.json
├── webpack.config.js
├── webpack.vendor.config.js
└── yarn.lock
/.dockerignore:
--------------------------------------------------------------------------------
1 | /node_modules/
2 | /pkg/*.tgz
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root= true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.{js,ts,html,less,css,json}]
13 | indent_style = space
14 | indent_size = 2
15 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "env": {
4 | "browser": true,
5 | "jquery": true
6 | },
7 | "parser": "babel-eslint",
8 | "parserOptions": {
9 | "ecmaVersion": 5,
10 | "sourceType": "module",
11 | "ecmaFeatures": {
12 | "globalReturn": false,
13 | "impliedStrict": false
14 | }
15 | },
16 |
17 | "plugins": [],
18 | "extends": [],
19 |
20 | "globals": {
21 | "Promise": false,
22 | "_": false,
23 | "__": false,
24 | "angular": false
25 | },
26 |
27 | "rules": {
28 | // {{{ this section comes from eslint-config-airbnb-es5 1.0.9
29 | "strict": 0,
30 | "no-shadow": 2,
31 | "no-shadow-restricted-names": 2,
32 | "no-cond-assign": [2, "always"],
33 | "no-console": 1,
34 | "no-constant-condition": 1,
35 | "no-dupe-keys": 2,
36 | "no-duplicate-case": 2,
37 | "no-empty": 2,
38 | "no-empty-character-class": 2,
39 | "no-ex-assign": 2,
40 | "no-extra-semi": 2,
41 | "no-func-assign": 2,
42 | "no-inner-declarations": 2,
43 | "no-invalid-regexp": 2,
44 | "no-irregular-whitespace": 2,
45 | "no-negated-in-lhs": 2,
46 | "no-new-require": 2,
47 | "no-obj-calls": 2,
48 | "no-path-concat": 2,
49 | "no-regex-spaces": 2,
50 | "no-sparse-arrays": 2,
51 | "no-unreachable": 2,
52 | "use-isnan": 2,
53 | "valid-jsdoc": 2,
54 | "valid-typeof": 2,
55 | "dot-notation": [2, {
56 | "allowKeywords": true
57 | }],
58 | "guard-for-in": 2,
59 | "no-caller": 2,
60 | "no-div-regex": 2,
61 | "no-labels": 2,
62 | "no-eval": 2,
63 | "no-extend-native": 2,
64 | "no-extra-bind": 2,
65 | "no-floating-decimal": 2,
66 | "no-implied-eval": 2,
67 | "no-lone-blocks": 2,
68 | "no-loop-func": 2,
69 | "no-multi-str": 2,
70 | "no-native-reassign": 2,
71 | "no-new": 2,
72 | "no-new-func": 2,
73 | "no-new-wrappers": 2,
74 | "no-octal": 2,
75 | "no-octal-escape": 2,
76 | "no-process-exit": 2,
77 | "no-proto": 2,
78 | "no-redeclare": 2,
79 | "no-return-assign": 2,
80 | "no-script-url": 2,
81 | "no-self-compare": 2,
82 | "no-sequences": 2,
83 | "no-throw-literal": 2,
84 | "no-undef-init": 2,
85 | "no-undefined": 1,
86 | "no-with": 2,
87 | "handle-callback-err": 1,
88 | "radix": 2,
89 | "wrap-iife": [2, "any"],
90 | "yoda": 2,
91 | "brace-style": [2,
92 | "1tbs", {
93 | "allowSingleLine": true
94 | }],
95 | "camelcase": [2, {
96 | "properties": "never"
97 | }],
98 | "comma-spacing": [2, {
99 | "before": false,
100 | "after": true
101 | }],
102 | "comma-style": [2, "last"],
103 | "eol-last": 2,
104 | "key-spacing": [2, {
105 | "beforeColon": false,
106 | "afterColon": true
107 | }],
108 | "new-cap": [2, {
109 | "newIsCap": true
110 | }],
111 | "new-parens": 2,
112 | "no-array-constructor": 2,
113 | "no-lonely-if": 1,
114 | "no-multiple-empty-lines": [2, {
115 | "max": 2
116 | }],
117 | "no-nested-ternary": 2,
118 | "no-new-object": 2,
119 | "no-spaced-func": 2,
120 | "no-trailing-spaces": 2,
121 | "no-extra-parens": [2, "functions"],
122 | "one-var": [2, "never"],
123 | "padded-blocks": [2, "never"],
124 | "semi": [2, "always"],
125 | "semi-spacing": [2, {
126 | "before": false,
127 | "after": true
128 | }],
129 | "keyword-spacing": 2,
130 | "space-before-blocks": 2,
131 | "space-before-function-paren": [2, "never"],
132 | "space-infix-ops": 2,
133 | "spaced-comment": [2, "always", {
134 | "exceptions": ["-", "+"],
135 | "markers": ["=", "!"] // space here to support sprockets directives
136 | }],
137 | // }}} (except for removing the JSX rules, and anything we override)
138 |
139 | "indent": [ "error", 2, {
140 | "SwitchCase": 1,
141 | "VariableDeclarator": 1
142 | }],
143 | "consistent-return": 1,
144 | "default-case": 1,
145 | "vars-on-top": 0,
146 | "no-var": 0,
147 | "linebreak-style": [ "error", "unix" ],
148 | "comma-dangle": [ "warn", "always-multiline" ],
149 | "space-unary-ops": [ "error", {
150 | "words": true,
151 | "nonwords": false,
152 | "overrides": {
153 | "!": true
154 | }
155 | }],
156 | "no-unused-vars": [ "error", {
157 | "args": "all",
158 | "argsIgnorePattern": "^_",
159 | "vars": "local",
160 | "caughtErrors": "all",
161 | "caughtErrorsIgnorePattern": "^_"
162 | }],
163 | "no-alert": 2,
164 | "no-debugger": 2,
165 | "no-else-return": 1,
166 | "no-undef": [ "warn", {
167 | "typeof": true
168 | }],
169 | "eqeqeq": [ "error", "smart" ],
170 | "quotes": [ "warn", "single", {
171 | "avoidEscape": true,
172 | "allowTemplateLiterals": true
173 | }],
174 | "func-names": 0,
175 | "no-mixed-spaces-and-tabs": 2,
176 | "camelcase": [ "warn", {
177 | "properties": "never"
178 | }],
179 |
180 | "curly": [ "warn", "all" ],
181 | "no-eq-null": 0,
182 | "no-param-reassign": 1,
183 | "no-fallthrough": [ "error", {
184 | "commentPattern": "fall.*through|pass"
185 | }],
186 | "no-use-before-define": [ "error", {
187 | "functions": false,
188 | "classes": true
189 | }]
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # dialog editor
2 | src/dialog-editor @romanblanco
3 | src/dialog-user @chalettu
4 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | pull_request:
6 | workflow_dispatch:
7 | schedule:
8 | - cron: '0 0 * * *'
9 |
10 | jobs:
11 | ci:
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | node-version:
16 | - '14'
17 | steps:
18 | - uses: actions/checkout@v4
19 | - name: Set up system
20 | run: bin/before_install
21 | - name: Set up Node
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: ${{ matrix.node-version }}
25 | # TODO: Uncomment this for yarn 3
26 | # cache: yarn
27 | # registry-url: https://npm.manageiq.org/
28 | - name: Prepare tests
29 | run: bin/setup
30 | - name: Run tests
31 | run: bin/ci
32 | - name: Report code coverage
33 | if: ${{ github.ref == 'refs/heads/master' && matrix.node-version == '14' }}
34 | continue-on-error: true
35 | run: scripts/.coverage.sh
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs/
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Users Environment Variables
11 | .lock-wscript
12 |
13 | dist/assets/
14 | dist/css
15 | dist/data/
16 | dist/docs/
17 | dist/js
18 | dist/**/demo-app.*
19 | dist/*.ttf
20 | dist/*.eot
21 | dist/*.svg
22 | dist/*.woff
23 | dist/*.woff2
24 | .tmp/
25 | libs/
26 | node_modules/
27 | dist/index.html
28 | tsd/
29 | typings/
30 | vendor.js
31 | vendor.css
32 | *.css.map
33 | *.js.map
34 |
35 | ._*
36 | .DS_Store
37 |
38 | # idea files
39 | .idea/
40 | *.ipr
41 | *.iws
42 | *.iml
43 |
44 | coverage
45 | yarn.lock
46 | package-lock.json
47 | pkg/
48 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs/
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Users Environment Variables
11 | .lock-wscript
12 |
13 | dist/assets/
14 | dist/data/
15 | dist/docs/
16 | dist/**/demo-app.*
17 | .tmp/
18 | libs/
19 | node_modules/
20 | dist/index.html
21 | tsd/
22 | typings/
23 | vendor.js
24 | vendor.css
25 |
26 | ._*
27 | .DS_Store
28 |
29 | # idea files
30 | .idea/
31 | *.ipr
32 | *.iws
33 | *.iml
34 |
35 | coverage
36 |
--------------------------------------------------------------------------------
/.whitesource:
--------------------------------------------------------------------------------
1 | {
2 | "settingsInheritedFrom": "ManageIQ/whitesource-config@master"
3 | }
4 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:2.7-buster
2 |
3 | SHELL ["/bin/bash", "--login", "-c"]
4 |
5 | RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
6 | RUN nvm install 14
7 | RUN npm install --global yarn
8 |
9 | WORKDIR /ui-components
10 | COPY . /ui-components
11 | RUN git clean -fdx
12 | RUN yarn install
13 | RUN yarn pack
14 |
--------------------------------------------------------------------------------
/MiQ-UI-Architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ManageIQ/ui-components/297eaf92aa8e19056ace8e704a7477073f4f1d4e/MiQ-UI-Architecture.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular UI Components for ManageIQ
2 |
3 | [](https://github.com/ManageIQ/ui-components/actions/workflows/ci.yaml)
4 | [](https://coveralls.io/github/ManageIQ/ui-components)
5 | [](https://gitter.im/ManageIQ/manageiq/ui?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6 |
7 | [](https://www.bithound.io/github/ManageIQ/ui-components)
8 | [](https://www.bithound.io/github/ManageIQ/ui-components/master/dependencies/npm)
9 | [](https://www.bithound.io/github/ManageIQ/ui-components/master/dependencies/npm)
10 | [](https://snyk.io/test/github/mtho11/ui-components)
11 |
12 | ## Purpose
13 |
14 | The purpose of this repository is to provide reusable components for the [ManageIQ](http:github.com/manageiq/manageiq)
15 | project. These are not general purpose components, but specific to ManageIQ, however, reusable across all of
16 | ManageIQ (providers). The intention is to provide components that are reusable in various ways. Many of these components
17 | are 'Smart Components' that know how to communicate to backend endpoints(data-driven by provider) and retrieve relevant data for
18 | the component's configuration.
19 |
20 | As we achieve greater reuse, the idea is to move more and more components to this repository. Creating a repository for
21 | *smart* reusable components (specific to a domain) across providers.
22 |
23 | ## Architectural Goals
24 |
25 | * Separate git repository from ManageIQ
26 | * Components communicate via REST with ManageIQ API
27 | * Maintain routing inside ManageIQ (routes.rb)
28 |
29 | ## Technologies
30 |
31 | * Angular 1.5+ (soon to be Angular 2.x)
32 | * Typescript
33 | * Webpack
34 | * Yarn
35 |
36 | ## Architecture
37 |
38 | 
39 |
40 | ## Angular 1.5 Components
41 |
42 | We are recommending [Angular 1.5 Components](https://docs.angularjs.org/guide/component) instead of Angular Directives
43 | for better compatibility and easier upgrade to Angular 2.0.
44 |
45 | For a great overview of using Angular 1.5.x Components please see: [NG-Conf 2016: Components, Components, Components!...and Angular 1.5 - Pete Bacon Darwin](https://www.youtube.com/watch?list=PLOETEcp3DkCq788xapkP_OU-78jhTf68j&v=AMwjDibFxno&ab_channel=ng-conf)
46 |
47 |
48 | ## Development Environment
49 |
50 | You need to have installed [Node.js >= 14 and npm >= 6](https://docs.npmjs.com/getting-started/installing-node) on your system.
51 | It is recommended to use a node version manager such as [n](https://www.npmjs.com/package/n). If you have node installed then it is
52 | just `yarn global add n` and then `n lts` to use the latest LTS version of node (see the docs for switching versions).
53 |
54 | Install these node packages globally in the system
55 | ```
56 | npm install -g yarn
57 | yarn global add webpack wiredep-cli typescript typescript-formatter
58 | ```
59 |
60 | After [yarn](http://yarn.io) is installed, it is pretty much a replacement for npm, with faster, more dependable builds
61 | but still utilizing the npm packages.
62 |
63 | See comparison: [npm vs. yarn commands](https://yarnpkg.com/en/docs/migrating-from-npm)
64 |
65 | Install local node dependencies
66 | ```
67 | yarn
68 | ```
69 |
70 | Create library dependencies (run this every time you make any changes to `vendor.ts`) - no need to worry about any TS
71 | errors. Also, if you are pushing some changes please run this command so you will push minifed version of JS and CSS.
72 | ```
73 | yarn run build
74 | ```
75 |
76 | To run:
77 | ```
78 | yarn start
79 | ```
80 |
81 | To run tests:
82 | ```
83 | yarn
84 | yarn run build-dev
85 | yarn run test
86 | ```
87 |
88 | Before submitting code, run the following command to format the code according to the tslint rules:
89 | ```
90 | tsmft -r
91 | ```
92 |
93 | This formats the code according to the tslint rules.
94 |
95 | #### Documentation
96 |
97 | If you want to see documentation for each component, controller, filter, etc. run
98 | ```
99 | yarn run-script build-docs
100 | ```
101 | This will generate docs from JS docs and after running `yarn start` this documentation will be available on `localhost:4000/docs`
102 |
103 | If you want to release ui-components look at documentation in Wiki of this repository.
104 |
105 | #### ManageIQ version mapping
106 |
107 | 1.6 - master, radjabov
108 | 1.5 - petrosian, quinteros
109 | 1.4 - kasparov, lasker, morphy, najdorf, oparin
110 | 1.3 - jansa
111 | 1.2 - ivanchuk
112 | 1.1 - hammer
113 | 1.0 - gaprindashvili
114 |
--------------------------------------------------------------------------------
/application-settings.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = {
3 | stylesFolder: '/styles',
4 | sourceFolder: '/src',
5 | distFolder: '/dist',
6 | javascriptFolder: 'js',
7 | stylesheetFolder: 'css',
8 | appName: 'ui-components',
9 | modules: {
10 | common: '/common',
11 | dialogEditor: '/dialog-editor',
12 | fonticonPicker: '/fonticon-picker',
13 | dialogs: '/dialog-user',
14 | treeView: '/tree-view',
15 | treeSelector: '/tree-selector',
16 | miqSelect: '/miq-select',
17 | },
18 | nodePackages: 'node_modules/',
19 | get stylesheetPath() {
20 | return this.stylesheetFolder + '/[name]' + '.css';
21 | },
22 | get indexLocation() {
23 | return __dirname + '/demo/index.html';
24 | },
25 | isMinified: function (production) {
26 | return (!production ? '.js' : '.min.js');
27 | },
28 | get sassRootFolder() {
29 | return '.' + this.sourceFolder + this.stylesFolder;
30 | },
31 | get sassEntryPoint() {
32 | return this.sassRootFolder + '/' + this.appName + '.scss'
33 | },
34 | get tsEntryPoint() {
35 | return '.' + this.sourceFolder + '/index.ts'
36 | },
37 | get tsModules() {
38 | let availableObjects = [];
39 | Object.keys(this.modules).forEach(key => {
40 | availableObjects.push('.' + this.sourceFolder + this.modules[key]);
41 | });
42 | return availableObjects;
43 | },
44 | get outputFolder() {
45 | return __dirname + this.distFolder
46 | }
47 | };
48 |
--------------------------------------------------------------------------------
/bin/before_install:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | if [ -n "$CI" ]; then
6 | npm install --global yarn
7 | fi
8 |
--------------------------------------------------------------------------------
/bin/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | image="docker.io/manageiq/ui-components:latest"
6 |
7 | # Build the image, which will build the package
8 | docker build . -t $image --no-cache
9 |
10 | # Extract the package from the image
11 | container_id=$(docker create $image)
12 | package=$(docker run --rm -it --entrypoint /bin/bash $image -c "ls -1 manageiq-ui-components-*.tgz" | tr -d '\r')
13 | docker cp "$container_id:/ui-components/$package" pkg
14 | docker rm "$container_id"
15 |
16 | echo
17 | echo "Package 'pkg/$package' has been built."
18 | echo
19 |
20 | # Optionally publish the image
21 | read -r -p "Publish the package now? (y/N) " -n 1
22 | echo
23 | echo
24 | if [[ "$REPLY" =~ ^[Yy]$ ]]; then
25 | pushd pkg >/dev/null
26 | npm login
27 | npm publish --access public $package
28 | popd >/dev/null
29 | else
30 | echo "You can manually publish the package with:"
31 | echo " cd pkg"
32 | echo " npm login"
33 | echo " npm publish --access public $package"
34 | fi
35 |
--------------------------------------------------------------------------------
/bin/ci:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | yarn run build-dev
6 | yarn run test
7 | yarn run gettext:extract
8 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | if [ -n "$CI" ]; then
6 | yarn global add typings webpack karma typescript
7 | fi
8 |
9 | yarn install
10 |
--------------------------------------------------------------------------------
/demo/assets/100/vendor-hawkular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ManageIQ/ui-components/297eaf92aa8e19056ace8e704a7477073f4f1d4e/demo/assets/100/vendor-hawkular.png
--------------------------------------------------------------------------------
/demo/assets/manageiq.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 | miq-logo
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/demo/assets/vendor-centos.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/demo/assets/vendor-chrome.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/demo/assets/vendor-openshift.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
10 |
11 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/demo/assets/vendor-redhat.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
10 |
19 |
20 |
27 |
29 |
31 |
32 |
--------------------------------------------------------------------------------
/demo/assets/vendor-ubuntu.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | ]>
6 |
10 |
11 |
12 |
14 |
27 |
28 |
--------------------------------------------------------------------------------
/demo/assets/vendor-vmware.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demo/controllers/availableComponentsController.ts:
--------------------------------------------------------------------------------
1 | import AvailableComponentsService from './../services/availableComponentsService';
2 | import {IAvailableGroup} from '../services/availableComponentsService';
3 |
4 | export default class AvailableComponentsController {
5 | public availableComponents: IAvailableGroup[];
6 |
7 | /* @ngInject */
8 | public constructor() {
9 | this.availableComponents = (new AvailableComponentsService()).availableComponents;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/demo/controllers/dialogEditorController.ts:
--------------------------------------------------------------------------------
1 | import DialogEditorService from '../../src/dialog-editor/services/dialogEditorService';
2 | import {ComponentDemo} from '../services/availableComponentBuilder';
3 | @ComponentDemo({
4 | name: 'editor',
5 | title: 'Dialog editor',
6 | template: require('./../views/dialog/editor.html'),
7 | group: 'dialog',
8 | controller: 'demoDialogEditor as vm'
9 | })
10 | export default class DialogEditorController {
11 | public dialog: any;
12 | public modalOptions: any;
13 | public elementInfo: any;
14 |
15 | /* @ngInject */
16 | constructor(private DialogEditor: DialogEditorService) {
17 | this.init({
18 | 'content': [{
19 | 'dialog_tabs': [{
20 | 'label': 'New Tab',
21 | 'position': 0,
22 | 'dialog_groups': [{
23 | 'label': 'New Section',
24 | 'position': 0,
25 | 'dialog_fields': []
26 | }],
27 | }],
28 | }],
29 | });
30 | }
31 |
32 | public init(dialog) {
33 | this.DialogEditor.setData(dialog);
34 | this.dialog = dialog;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/demo/controllers/dialogUserController.ts:
--------------------------------------------------------------------------------
1 | import {ComponentDemo} from '../services/availableComponentBuilder';
2 | @ComponentDemo({
3 | name: 'user',
4 | title: 'Dialog user',
5 | template: require('./../views/dialog/user.html'),
6 | group: 'dialog',
7 | controller: 'demoDialogUser as vm'
8 | })
9 | export default class DialogUserController {
10 | public dialog: any;
11 | public showDialogData: boolean;
12 | public dialogDataResults: any;
13 |
14 | /* @ngInject */
15 | constructor() {
16 | const dialogFile = require('../data/dialog-data.json');
17 | this.dialog = dialogFile.resources[0].content[0];
18 | this.showDialogData = false;
19 | }
20 | public refreshField(field) {
21 | let Promise: any;
22 | return new Promise((resolve, reject) => {
23 | resolve({ 'status': 'success' });
24 | });
25 | }
26 | public dialogData(data) {
27 | this.dialogDataResults = data;
28 | }
29 | public showDialogDataResults() {
30 | this.showDialogData = true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/demo/controllers/fonticonPickerController.ts:
--------------------------------------------------------------------------------
1 | import {ComponentDemo} from '../services/availableComponentBuilder';
2 | @ComponentDemo({
3 | name: 'basic',
4 | title: 'Fonticon picker',
5 | template: require('./../views/fonticon-picker/basic.html'),
6 | group: 'fonticon-picker',
7 | controller: 'demoFonticonPicker as vm'
8 | })
9 | export default class FonticonPickerController {
10 | }
11 |
--------------------------------------------------------------------------------
/demo/controllers/index.ts:
--------------------------------------------------------------------------------
1 | import AvailableComponentsController from './availableComponentsController';
2 | import FonticonPickerController from './fonticonPickerController';
3 | import DialogUserController from './dialogUserController';
4 | import DialogEditorController from './dialogEditorController';
5 | import TreeViewController from './treeViewController';
6 | import TreeSelectorController from './treeSelectorController';
7 | import * as ng from 'angular';
8 |
9 | export default (module: ng.IModule) => {
10 | module.controller('demoAvailableComponents', AvailableComponentsController);
11 | module.controller('demoFonticonPicker', FonticonPickerController);
12 | module.controller('demoDialogUser', DialogUserController);
13 | module.controller('demoDialogEditor', DialogEditorController);
14 | module.controller('demoTreeView', TreeViewController);
15 | module.controller('demoTreeSelector', TreeSelectorController);
16 | };
17 |
--------------------------------------------------------------------------------
/demo/controllers/treeSelectorController.ts:
--------------------------------------------------------------------------------
1 | import * as ng from 'angular';
2 | import {ComponentDemo} from '../services/availableComponentBuilder';
3 |
4 | @ComponentDemo({
5 | name: 'tree-selector',
6 | title: 'TreeSelector',
7 | template: require('./../views/tree-view/tree-selector.html'),
8 | group: 'tree-view',
9 | controller: 'demoTreeSelector as vm'
10 | })
11 | export default class TreeSelectorController {
12 | public display = false;
13 | public node;
14 | public data = require('../data/tree.json');
15 |
16 | /*@ngInject*/
17 | constructor(private $timeout : ng.ITimeoutService) {}
18 |
19 | public toggleTree() {
20 | this.display = !this.display;
21 | };
22 |
23 | public nodeSelect(node) {
24 | this.node = node;
25 | this.display = false;
26 | }
27 |
28 | public lazyLoad(node) {
29 | let data = require('../data/lazyTree.json');
30 | // Wait to simulate HTTP delay
31 | return new Promise(resolve => this.$timeout(() => resolve(data), 1500));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/demo/controllers/treeViewController.ts:
--------------------------------------------------------------------------------
1 | import * as ng from 'angular';
2 | import {ComponentDemo} from '../services/availableComponentBuilder';
3 | @ComponentDemo({
4 | name: 'tree-view',
5 | title: 'TreView',
6 | template: require('./../views/tree-view/basic.html'),
7 | group: 'tree-view',
8 | controller: 'demoTreeView as vm'
9 | })
10 | export default class TreeViewController {
11 | public node;
12 | public data = require('../data/tree.json');
13 | public selectNode;
14 |
15 | /*@ngInject*/
16 | constructor(private $scope : ng.IScope, private $timeout : ng.ITimeoutService, private $window : ng.IWindowService) {
17 | };
18 |
19 | public resetState() {
20 | sessionStorage.clear();
21 | this.$window.location.reload();
22 | }
23 |
24 | public selectRandom() {
25 | let keys = JSON.stringify(this.data)
26 | .match(/\"key\":\"[^\"]+\"/g)
27 | .map((item) => item.replace(/\"key\":\"([^\"]+)\"/, '$1'));
28 | let key = keys[Math.floor(Math.random() * keys.length)];
29 |
30 | this.selectNode = { key: key };
31 | }
32 |
33 | public selectLazy() {
34 | this.selectNode = [{key: 'lp-1'}, {key: 'lc-2'}, {key: 'lgc-1'}];
35 | }
36 |
37 | public lazyLoad(node) {
38 | let data = require('../data/lazyTree.json');
39 | // Wait to simulate HTTP delay
40 | return new Promise(resolve => this.$timeout(() => resolve(data), 1500));
41 | }
42 |
43 | public reloadData() {
44 | this.data = require('../data/lazyTree.json');
45 | }
46 |
47 | public nodeSelect(node) {
48 | // Drop some attributes to keep the output short
49 | delete node.$el;
50 | delete node.nodes;
51 | delete node.searchResult;
52 |
53 | this.node = node;
54 | this.$scope.$apply();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/demo/data/data-table.json:
--------------------------------------------------------------------------------
1 | {
2 | "settings": {
3 | "perpage": 20,
4 | "current": 1,
5 | "items": 6,
6 | "total": 1
7 | },
8 | "data": {
9 | "head": [
10 | {
11 | "is_narrow": true
12 | },
13 | {
14 | "is_narrow": true
15 | },
16 | {
17 | "header_text": "Messaging Name",
18 | "sort": "str",
19 | "col_idx": 0,
20 | "align": "left"
21 | },
22 | {
23 | "header_text": "Messaging Type",
24 | "sort": "str",
25 | "col_idx": 1,
26 | "align": "left"
27 | },
28 | {
29 | "header_text": "Server",
30 | "sort": "str",
31 | "col_idx": 2,
32 | "align": "left"
33 | }
34 | ],
35 | "rows": [
36 | {
37 | "id": "16",
38 | "cells": [
39 | {
40 | "is_checkbox": true
41 | },
42 | {
43 | "title": "View this item",
44 | "image": "assets/100/vendor-hawkular.png",
45 | "icon": "fa fa-exchange"
46 | },
47 | {
48 | "text": "JMS Queue [DLQ]"
49 | },
50 | {
51 | "text": "JMS Queue"
52 | },
53 | {
54 | "text": "server-one"
55 | }
56 | ],
57 | "quad": {
58 | "topLeft": {
59 | "fileicon": "/assets/vendor-centos.svg",
60 | "tooltip": "Hello, I am a very useful tooltip in the first quadrant!"
61 | },
62 | "topRight": {
63 | "text": "T",
64 | "background": "#336699",
65 | "tooltip": "Hello, I am a very useful tooltip in the second quadrant!"
66 | },
67 | "bottomLeft": {
68 | "fileicon": "/assets/vendor-vmware.svg",
69 | "tooltip": "Hello, I am a very useful tooltip in the third quadrant!"
70 | },
71 | "bottomRight": {
72 | "text": "0",
73 | "tooltip": "Hello, I am a very useful tooltip in the fourth quadrant!"
74 | }
75 | }
76 | },
77 | {
78 | "id": "14",
79 | "cells": [
80 | {
81 | "is_checkbox": true
82 | },
83 | {
84 | "title": "View this item",
85 | "image": "assets/100/vendor-hawkular.png"
86 | },
87 | {
88 | "text": "JMS Queue [DLQ]"
89 | },
90 | {
91 | "text": "JMS Queue"
92 | },
93 | {
94 | "text": "Local"
95 | }
96 | ],
97 | "quad": {
98 | "fonticon": "pficon pficon-server",
99 | "color": "#0099cc",
100 | "tooltip": "Hello, I am a very useful tooltip!"
101 | }
102 | },
103 | {
104 | "id": "10",
105 | "cells": [
106 | {
107 | "is_checkbox": true
108 | },
109 | {
110 | "title": "View this item",
111 | "picture": "assets/100/vendor-hawkular.png",
112 | "icon": "fa fa-exchange"
113 | },
114 | {
115 | "text": "JMS Queue [ExpiryQueue]"
116 | },
117 | {
118 | "text": "JMS Queue"
119 | },
120 | {
121 | "text": "Local"
122 | }
123 | ]
124 | },
125 | {
126 | "id": "17",
127 | "cells": [
128 | {
129 | "is_checkbox": true
130 | },
131 | {
132 | "title": "View this item",
133 | "image": "assets/100/vendor-hawkular.png",
134 | "icon": "fa fa-exchange"
135 | },
136 | {
137 | "text": "JMS Queue [ExpiryQueue]"
138 | },
139 | {
140 | "text": "JMS Queue"
141 | },
142 | {
143 | "text": "server-one"
144 | }
145 | ]
146 | },
147 | {
148 | "id": "12",
149 | "cells": [
150 | {
151 | "is_checkbox": true
152 | },
153 | {
154 | "title": "View this item",
155 | "image": "assets/100/vendor-hawkular.png",
156 | "icon": "fa fa-exchange"
157 | },
158 | {
159 | "text": "JMS Queue [HawkularAlertsActionsResponseQueue]"
160 | },
161 | {
162 | "text": "JMS Queue"
163 | },
164 | {
165 | "text": "Local"
166 | }
167 | ]
168 | },
169 | {
170 | "id": "13",
171 | "cells": [
172 | {
173 | "is_checkbox": true
174 | },
175 | {
176 | "title": "View this item",
177 | "image": "assets/100/vendor-hawkular.png",
178 | "icon": "fa fa-exchange"
179 | },
180 | {
181 | "text": "JMS Queue [HawkularAlertsPluginsQueue]"
182 | },
183 | {
184 | "text": "JMS Queue"
185 | },
186 | {
187 | "text": "Local"
188 | }
189 | ]
190 | }
191 | ]
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/demo/data/dialog_editor.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 10000000000001,
3 | "description": "Dialog for testing",
4 | "buttons": "submit,cancel",
5 | "created_at": "2012-06-13T22:17:08Z",
6 | "updated_at": "2012-06-19T19:14:09Z",
7 | "label": "Dialog",
8 | "content": [{
9 | "description": "Dialog for testing",
10 | "buttons": "submit,cancel",
11 | "label": "Dialog",
12 | "dialog_tabs": [{
13 | "description": "First testing tab",
14 | "display": "edit",
15 | "label": "Tab 1",
16 | "position": 0,
17 | "dialog_groups": [{
18 | "description": "First box in first tab",
19 | "display": "edit",
20 | "label": "Tab 1 - Box 1",
21 | "position": 0,
22 | "dialog_fields": [{
23 | "name": "textbox1",
24 | "type": "DialogFieldTextBox",
25 | "display": "edit",
26 | "display_method_options": {},
27 | "required": false,
28 | "required_method_options": {},
29 | "values_method_options": {},
30 | "options": {},
31 | "label": "Tab 1 - Box 1 - Element 1",
32 | "position": 0,
33 | "resource_action": {
34 | "resource_type": "DialogField",
35 | "ae_attributes": {}
36 | }
37 | }, {
38 | "name": "textbox2",
39 | "type": "DialogFieldTextBox",
40 | "display": "edit",
41 | "display_method_options": {},
42 | "required": false,
43 | "required_method_options": {},
44 | "values_method_options": {},
45 | "options": {},
46 | "label": "Tab 1 - Box 1 - Element 2",
47 | "position": 1,
48 | "resource_action": {
49 | "resource_type": "DialogField",
50 | "ae_attributes": {}
51 | }
52 | }, {
53 | "name": "textareabox1",
54 | "type": "DialogFieldTextAreaBox",
55 | "display": "edit",
56 | "display_method_options": {},
57 | "required": false,
58 | "required_method_options": {},
59 | "values_method_options": {},
60 | "options": {},
61 | "label": "Tab 1 - Box 1 - Element 3",
62 | "position": 2,
63 | "resource_action": {
64 | "resource_type": "DialogField",
65 | "ae_attributes": {}
66 | }
67 | }]
68 | }]
69 | }, {
70 | "description": "Second testing tab",
71 | "display": "edit",
72 | "label": "Tab 2",
73 | "position": 1,
74 | "dialog_groups": [{
75 | "description": "First box in second tab",
76 | "display": "edit",
77 | "label": "Tab 2 - Box 1",
78 | "position": 0,
79 | "dialog_fields": [{
80 | "name": "dropdownlist1",
81 | "description": "First drop down list",
82 | "type": "DialogFieldDropDownList",
83 | "data_type": "string",
84 | "display": "edit",
85 | "display_method_options": {},
86 | "required": true,
87 | "required_method_options": {},
88 | "values": [["Yes", "yes"], ["No", "no"], ["Maybe", "maybe"]],
89 | "values_method_options": {},
90 | "options": {
91 | "sort_by": "description",
92 | "sort_order": "descending"
93 | },
94 | "label": "Tab 2 - Box 1 - Element 1",
95 | "position": 0,
96 | "resource_action": {
97 | "resource_type": "DialogField",
98 | "ae_attributes": {}
99 | }
100 | }]
101 | }]
102 | }]
103 | }]
104 | }
105 |
--------------------------------------------------------------------------------
/demo/data/lazyTree.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "lc-1",
4 | "icon": "ff ff-diamond",
5 | "text": "Lazy Child 1"
6 | },
7 | {
8 | "key": "lc-2",
9 | "icon": "ff ff-diamond",
10 | "text": "Lazy Child 2",
11 | "nodes": [
12 | {
13 | "key": "lgc-1",
14 | "icon": "ff ff-diamond",
15 | "text": "Lazy grandchild 1"
16 | }
17 | ]
18 | }
19 | ]
20 |
--------------------------------------------------------------------------------
/demo/data/tree.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "p-1",
4 | "icon": "ff ff-diamond",
5 | "text": "Parent",
6 | "nodes": [
7 | {
8 | "key": "c-1",
9 | "icon": "ff ff-diamond",
10 | "text": "Child 1",
11 | "nodes": [
12 | {
13 | "key": "gc-1",
14 | "icon": "ff ff-diamond",
15 | "text": "Grandchild 1"
16 | },
17 | {
18 | "key": "gc-2",
19 | "icon": "ff ff-diamond",
20 | "text": "Grandchild 2"
21 | }
22 | ]
23 | },
24 | {
25 | "key": "c-2",
26 | "icon": "ff ff-diamond",
27 | "text": "Child 2"
28 | }
29 | ]
30 | },
31 | {
32 | "key": "lp-1",
33 | "icon": "ff ff-diamond",
34 | "text": "Lazy Parent",
35 | "lazyLoad": true
36 | }
37 | ]
38 |
--------------------------------------------------------------------------------
/demo/index.ts:
--------------------------------------------------------------------------------
1 | import views from './views';
2 | import controllers from './controllers';
3 | import * as angular from 'angular';
4 | import TranslateFilter from './services/translateFilter';
5 | import DialogEditorHttpService from './services/DialogEditorHttpService';
6 |
7 | export const app = angular.module('demoApp', [
8 | 'ui.sortable', 'ngDragDrop', 'frapontillo.bootstrap-switch', 'miqStaticAssets', 'ui.bootstrap', 'ui.router',
9 | 'patternfly.form', 'patternfly.select', 'ui.bootstrap.tabs', 'patternfly.views', 'ngAnimate'
10 | ]);
11 | controllers(app);
12 | views(app);
13 | app.filter('translate', TranslateFilter.filter);
14 | app.service('DialogEditorHttp', DialogEditorHttpService);
15 |
--------------------------------------------------------------------------------
/demo/services/DialogEditorHttpService.ts:
--------------------------------------------------------------------------------
1 | export default class DialogEditorHttpService {
2 | public loadCategories(): Promise {
3 | return new Promise(resolve => resolve([]));
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/demo/services/availableComponentBuilder.ts:
--------------------------------------------------------------------------------
1 | import {AvailableComponent, default as AvailableComponentsService} from './availableComponentsService';
2 |
3 | function checkProperties(settings, fields, target?) {
4 | for (let field of fields) {
5 | if (!settings.hasOwnProperty(field)) {
6 | let suffix = target ? `Called on class ${target['name']}.` : '';
7 | throw new Error(`Available component has to have ${field} set up! ${suffix}`);
8 | }
9 | }
10 | }
11 |
12 | export function ComponentDemo(settings: any) {
13 | function componentFactory() {
14 | return new AvailableComponent(
15 | settings.name,
16 | settings.title || settings.name,
17 | settings.location || `/${settings.name}`,
18 | settings.template,
19 | settings.controller
20 | );
21 | }
22 |
23 | return function(target: Function) {
24 | checkProperties(settings, ['controller', 'name', 'template', 'group'], target);
25 | let availCmps = new AvailableComponentsService();
26 | const currentGroup = availCmps.availableComponents.filter(group => group.name === settings.group);
27 | if (!currentGroup) {
28 | throw new Error(`Selected group '${settings.group}' does not exists!`);
29 | }
30 | currentGroup.forEach(oneGroup => oneGroup.components.push(componentFactory()));
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/demo/services/availableComponentsService.ts:
--------------------------------------------------------------------------------
1 | export interface IAvailComponent {
2 | name: string;
3 | title: string;
4 | location: string;
5 | template: string;
6 | controller: string;
7 | }
8 |
9 | export interface IAvailableGroup {
10 | name: string;
11 | title: string;
12 | location: string;
13 | components: IAvailComponent[];
14 | }
15 |
16 | export class AvailableGroup implements IAvailableGroup {
17 | public constructor(public name: string,
18 | public title: string,
19 | public location: string,
20 | public components: IAvailComponent[]) { }
21 | }
22 |
23 | export class AvailableComponent implements IAvailComponent {
24 | public constructor(public name: string,
25 | public title: string,
26 | public location: string,
27 | public template: string,
28 | public controller: string) { }
29 | }
30 |
31 | export default class AvailableComponentsService {
32 | public static instance: AvailableComponentsService;
33 | public availableComponents: IAvailableGroup[];
34 |
35 | public constructor() {
36 | if (AvailableComponentsService.instance) {
37 | return AvailableComponentsService.instance;
38 | }
39 | this.initComponents();
40 | AvailableComponentsService.instance = this;
41 | }
42 |
43 | public initComponents() {
44 | this.availableComponents = [
45 | new AvailableGroup('fonticon-picker', 'Fonticon Picker Components', '/fonticon-picker', []),
46 | new AvailableGroup('dialog', 'Dialog Components', '/dialog', []),
47 | new AvailableGroup('tree-view', 'Tree Components', '/tree', [])
48 | ];
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/demo/services/translateFilter.ts:
--------------------------------------------------------------------------------
1 | export default class TranslateFilter {
2 | public static filter() {
3 | return (value) => {
4 | return value;
5 | };
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/demo/styles/demo-app.scss:
--------------------------------------------------------------------------------
1 | ul.nav.nav-list.well {
2 | padding: 0;
3 |
4 | li.nav-header {
5 | background: #d3d3d3;
6 |
7 | a {
8 | color: black;
9 | font-size: larger;
10 | margin: 0;
11 | }
12 | }
13 | }
14 |
15 | table.table tbody td img {
16 | height: 20px;
17 | width: 20px;
18 | }
19 |
20 | table .narrow {
21 | width: 1%;
22 | white-space: nowrap;
23 | }
24 |
25 | .clear-navbar {
26 | margin-top: 60px;
27 | }
28 |
29 | .dl-horizontal.tile dt {
30 | float: left;
31 | width: 100px;
32 | clear: left;
33 | text-align: right;
34 | overflow: hidden;
35 | text-overflow: ellipsis;
36 | white-space: nowrap;
37 | }
38 |
39 | .demo-dialog-container {
40 | height: 550px;
41 | }
42 | .demo-dialog {
43 | display:block;
44 | width: 80%;
45 | padding-bottom: 90px;
46 | }
47 | .demo-dialog-results {
48 | padding-top: 10px;
49 | }
50 | .demo-dialog-submit-button {
51 | margin-left: 147px;
52 | margin-top: 25px;
53 | }
54 |
55 | .piechart {
56 | $chart-empty: yellowgreen !default;
57 | $chart-fill: blue !default;
58 |
59 | border-radius: 50%;
60 | background: $chart-empty;
61 | background-image: linear-gradient(to right, transparent 50%, $chart-fill 0);
62 |
63 | &::before {
64 | content: '';
65 | display: block;
66 | margin-left: 50%;
67 | height: 100%;
68 | border-radius: 0 100% 100% 0 / 50%;
69 | background-color: inherit;
70 | transform-origin: left;
71 | }
72 |
73 | @for $i from 0 through 10 {
74 | &.fill-#{$i}::before {
75 | transform: rotate(#{$i / 20}turn);
76 | }
77 | }
78 |
79 | @for $i from 11 through 20 {
80 | &.fill-#{$i}::before {
81 | background: $chart-fill;
82 | transform: rotate(#{($i - 10) / 20}turn);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/demo/template-index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | <%= htmlWebpackPlugin.options.title %>
15 |
16 |
17 |