├── .bowerrc ├── .editorconfig ├── .gitattributes ├── .github ├── PULL_REQUEST_TEMPLATE └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .htmlhintrc ├── .npmignore ├── .openshift ├── README.md ├── action_hooks │ └── README.md ├── cron │ ├── README.cron │ ├── daily │ │ └── .gitignore │ ├── hourly │ │ └── .gitignore │ ├── minutely │ │ └── .gitignore │ ├── monthly │ │ └── .gitignore │ └── weekly │ │ ├── README │ │ ├── chronograph │ │ ├── jobs.allow │ │ └── jobs.deny └── markers │ ├── README.md │ └── hot_deploy ├── .travis.yml ├── Gruntfile.js ├── LICENSE.txt ├── README.md ├── bower.json ├── component-conversion.md ├── contributing.md ├── deploy_key.enc ├── eslint.yaml ├── grunt-uidocs-index.tmpl ├── index.js ├── misc ├── angular-bootstrap-prettify.js ├── canvas-dot-grid.png ├── examples.css ├── grid-sidebar.png ├── logo-alt.svg ├── ng-docs.css ├── patternfly-logo.svg ├── patternfly-orb.svg ├── patternfly-showcase.css └── test-lib │ └── helpers.js ├── package-lock.json ├── package.json ├── scripts └── publish-ghpages.sh ├── server.js ├── src ├── autofocus │ └── autofocus.js ├── canvas-view │ ├── canvas-editor │ │ ├── canvas-editor.component.js │ │ ├── canvas-editor.html │ │ ├── canvas-editor.less │ │ ├── toolbox-items.component.js │ │ └── toolbox-items.html │ ├── canvas.module.js │ ├── canvas │ │ ├── canvas-component.js │ │ ├── canvas-viewmodel.js │ │ ├── canvas.html │ │ ├── canvas.less │ │ ├── dragging-service.js │ │ ├── mouse-capture-service.js │ │ ├── node-toolbar.component.js │ │ └── node-toolbar.html │ └── examples │ │ ├── canvas.js │ │ └── canvasEditor.js ├── card │ ├── aggregate-status │ │ ├── aggregate-status-card.component.js │ │ └── aggregate-status-card.html │ ├── basic │ │ ├── card-filter.html │ │ ├── card.component.js │ │ └── card.html │ ├── card.less │ ├── card.module.js │ ├── examples │ │ ├── card-timeframe.js │ │ └── card-trend.js │ └── info-status │ │ ├── info-status-card.component.js │ │ └── info-status-card.html ├── charts │ ├── c3 │ │ ├── c3-chart-defaults.js │ │ └── c3-chart.component.js │ ├── charts.less │ ├── charts.module.js │ ├── donut │ │ ├── donut-chart-component.js │ │ ├── donut-chart.html │ │ ├── donut-pct-chart-component.js │ │ ├── donut-pct-chart.html │ │ └── examples │ │ │ ├── donut-chart.js │ │ │ └── donut-pct-chart.js │ ├── empty-chart.component.js │ ├── empty-chart.html │ ├── heatmap │ │ ├── heatmap-legend.component.js │ │ ├── heatmap-legend.html │ │ ├── heatmap.component.js │ │ └── heatmap.html │ ├── line │ │ ├── line-chart.component.js │ │ └── line-chart.html │ ├── sparkline │ │ ├── sparkline-chart.component.js │ │ └── sparkline-chart.html │ ├── topology-map │ │ ├── examples │ │ │ └── topology-map-view.js │ │ ├── topology-map.html │ │ └── topologyMap.component.js │ ├── topology │ │ ├── examples │ │ │ └── topology-view.js │ │ └── topology.component.js │ ├── trends │ │ ├── trends-chart.component.js │ │ └── trends-chart.html │ ├── utilization-bar │ │ ├── utilization-bar-chart.component.js │ │ └── utilization-bar-chart.html │ └── utilization-trend │ │ ├── utilization-trend-chart-component.js │ │ └── utilization-trend-chart.html ├── datepicker │ ├── bootstrap-datepicker.component.js │ ├── datepicker.html │ ├── datepicker.less │ ├── datepicker.module.js │ └── examples │ │ └── bootstrap.datepicker.js ├── filters │ ├── examples │ │ ├── filter-panel.js │ │ └── filter.js │ ├── filter-panel │ │ ├── filter-panel-component.js │ │ ├── filter-panel-results-component.js │ │ ├── filter-panel-results.html │ │ └── filter-panel.html │ ├── filters.less │ ├── filters.module.js │ └── simple-filter │ │ ├── filter-component.js │ │ ├── filter-fields-component.js │ │ ├── filter-fields.html │ │ ├── filter-results-component.js │ │ ├── filter-results.html │ │ └── filter.html ├── form │ ├── examples │ │ ├── form-buttons.js │ │ ├── form-group.js │ │ └── remaining-chars-count.directive.js │ ├── form-buttons │ │ ├── form-buttons.component.js │ │ └── form-buttons.html │ ├── form-group │ │ ├── form-group.component.js │ │ └── form-group.html │ ├── form.module.js │ └── remaining-chars-count │ │ └── remaining-chars-count.directive.js ├── modals │ ├── about-modal │ │ ├── about-modal.component.js │ │ └── about-modal.html │ ├── examples │ │ ├── about-modal.js │ │ └── modal-overlay.js │ ├── modal-overlay │ │ ├── modal-overlay.component.js │ │ ├── modal-overlay.html │ │ └── modal-overlay.less │ └── modals.module.js ├── navigation │ ├── application-launcher.component.js │ ├── application-launcher.html │ ├── examples │ │ ├── vertical-navigation-basic.js │ │ └── vertical-navigation-router.js │ ├── navigation.module.js │ ├── vertical-navigation.component.js │ ├── vertical-navigation.html │ └── vertical-navigation.less ├── notification │ ├── examples │ │ └── notification-drawer.js │ ├── inline-notification.component.js │ ├── inline-notification.html │ ├── notification-drawer.component.js │ ├── notification-drawer.html │ ├── notification-list.html │ ├── notification.js │ ├── notification.less │ ├── notification.module.js │ ├── toast-notification-list.component.js │ ├── toast-notification-list.html │ ├── toast-notification.component.js │ └── toast-notification.html ├── pagination │ ├── pagination.component.js │ ├── pagination.html │ ├── pagination.less │ └── pagination.module.js ├── patternfly.module.js ├── select │ ├── bootstrap-select.directive.js │ ├── examples │ │ ├── bootstrap.select.js │ │ └── select.js │ ├── select.component.js │ ├── select.html │ └── select.module.js ├── sort │ ├── examples │ │ └── sort.js │ ├── sort-component.js │ ├── sort.html │ ├── sort.less │ └── sort.module.js ├── table │ ├── table.less │ ├── table.module.js │ └── tableview │ │ ├── examples │ │ ├── table-view-basic.js │ │ └── table-view-with-toolbar.js │ │ ├── table-view.component.js │ │ └── table-view.html ├── toolbars │ ├── examples │ │ └── toolbar.js │ ├── toolbar-component.js │ ├── toolbar.html │ ├── toolbars.less │ └── toolbars.module.js ├── utils │ ├── fixed-accordion.directive.js │ ├── transclude-directive.js │ ├── utils.js │ └── utils.module.js ├── validation │ └── validation.js ├── views │ ├── cardview │ │ ├── card-view.component.js │ │ └── card-view.html │ ├── empty-state.component.js │ ├── empty-state.html │ ├── listview │ │ ├── examples │ │ │ ├── clusters-content.html │ │ │ ├── hosts-content.html │ │ │ ├── images-content.html │ │ │ ├── list-view.js │ │ │ └── nodes-content.html │ │ ├── list-view.component.js │ │ ├── list-view.html │ │ └── list-view.less │ ├── view-utils.js │ ├── views.less │ └── views.module.js └── wizard │ ├── examples │ └── wizard.js │ ├── wizard-buttons.js │ ├── wizard-review-page.component.js │ ├── wizard-review-page.html │ ├── wizard-step.component.js │ ├── wizard-step.html │ ├── wizard-substep.component.js │ ├── wizard-substep.html │ ├── wizard.component.js │ ├── wizard.html │ ├── wizard.less │ └── wizard.module.js ├── styles ├── _angular-patternfly.scss ├── angular-patternfly.less ├── build.scss └── misc.less ├── test ├── autofocus │ └── autofocus.spec.js ├── card │ ├── aggregate-status │ │ └── aggregate-status-card.component.spec.js │ ├── basic │ │ └── card.spec.js │ └── info-status │ │ └── info-status-card.component.spec.js ├── charts │ ├── c3 │ │ └── c3.spec.js │ ├── donut │ │ └── donut-pct.spec.js │ ├── heatmap │ │ ├── heatmap-legend.spec.js │ │ └── heatmap.spec.js │ ├── sparkline │ │ └── sparkline-chart.spec.js │ ├── topology-map │ │ └── topology-map.spec.js │ ├── topology │ │ └── topology.spec.js │ ├── trends │ │ └── trends-chart.spec.js │ ├── utilization-bar │ │ └── utilization-bar.spec.js │ └── utilization-trend │ │ └── utilization-trend-chart.spec.js ├── datepicker │ └── bootstrap-datepicker.spec.js ├── eslint.yaml ├── filters │ ├── filter-panel.spec.js │ └── filter.spec.js ├── form │ ├── form-buttons │ │ └── form-buttons.component.spec.js │ ├── form-group │ │ └── form-group.component.spec.js │ └── remaining-chars-count │ │ └── remaining-chars-count.directive.spec.js ├── karma.conf.js ├── modals │ ├── about-modal.spec.js │ └── modal-overlay.spec.js ├── navigation │ ├── application-launcher.spec.js │ └── vertical-navigation.spec.js ├── notification │ ├── heading.html │ ├── notification-body.html │ ├── notification-drawer.spec.js │ ├── notification-footer.html │ ├── notification.spec.js │ ├── subheading.html │ ├── title.html │ ├── toast-notification-list.spec.js │ └── toast-notification.spec.js ├── pagination │ └── pagination.spec.js ├── select │ ├── bootstrap-select.spec.js │ └── select.spec.js ├── sort │ └── sort.spec.js ├── table │ └── tableview │ │ └── table-view.spec.js ├── toolbars │ └── toolbar.spec.js ├── utils │ ├── fixed-accordion.spec.js │ ├── specUtils.js │ ├── transclude-directive.spec.js │ └── utils.spec.js ├── validation │ └── validation.spec.js ├── views │ ├── cardview │ │ └── card-view.spec.js │ ├── empty-state.spec.js │ └── listview │ │ └── list-view.spec.js └── wizard │ ├── deployment.html │ ├── detail-page.html │ ├── review-second-template.html │ ├── review-template.html │ ├── script.js │ ├── summary.html │ ├── wizard-container-hidden.html │ ├── wizard-container-hide-back.html │ ├── wizard-container-step-class.html │ ├── wizard-container-step-side-class.html │ ├── wizard-container.html │ ├── wizard-test-steps.html │ └── wizard.spec.js └── wiki └── Community_Meetings ├── Angular_PF_Community_Meeting_Aug17.md └── Angular_PF_Community_Meeting_NOV2017.md /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "lib" 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.h text 8 | 9 | # Declare files that will always have CRLF line endings on checkout. 10 | *.sln text eol=crlf 11 | 12 | # Denote all files that are truly binary and should not be modified. 13 | *.png binary 14 | *.jpg binary 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | ## Description 2 | State the overall goal of the pull request. Describe the list of changes the PR introduces and include any related PRs, Issues and/or Jira stories. 3 | 4 | ## PR Checklist 5 | 6 | - [ ] Unit tests are included 7 | - [ ] Screenshots are attached (if there are visual changes in the UI) 8 | - [ ] A Designer (@beanh66) is assigned as a reviewer (if there are visual changes in the UI) 9 | - [ ] A CSS rep (@cshinn) is assigned as a reviewer (if there are visual changes in the UI) 10 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | State the overall goal of the pull request. Describe the list of changes the PR introduces and include any related PRs, Issues and/or Jira stories. 3 | 4 | ## PR Checklist 5 | 6 | - [ ] Unit tests are included 7 | - [ ] Screenshots are attached (if there are visual changes in the UI) 8 | - [ ] A Designer (@beanh66) is assigned as a reviewer (if there are visual changes in the UI) 9 | - [ ] A CSS rep (@cshinn) is assigned as a reviewer (if there are visual changes in the UI) 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .tmp 4 | coverage 5 | docs 6 | dist 7 | test-results.xml 8 | npm-debug.log 9 | 10 | .idea/* 11 | *.iml 12 | .vscode 13 | -------------------------------------------------------------------------------- /.htmlhintrc: -------------------------------------------------------------------------------- 1 | { 2 | "tagname-lowercase": true, 3 | "attr-lowercase": true, 4 | "attr-value-doublequotes": true, 5 | "tag-pair": true, 6 | "tag-self-close": true, 7 | "id-unique": true, 8 | "src-not-empty": true, 9 | "style-disabled": true, 10 | "img-alt-require": true, 11 | "spec-char-escape": true 12 | } 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # generic (system) files/extensions we don't want 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | .idea/* 10 | *.iml 11 | *.DS_Store 12 | lib-cov 13 | pids 14 | logs 15 | results 16 | test-results.xml 17 | dist/docs/components 18 | dist/docs/font* 19 | dist/docs/grunt-styles 20 | dist/docs/img 21 | dist/docs/index.html 22 | 23 | 24 | docs 25 | node_modules 26 | npm-debug.log 27 | lib 28 | .bower 29 | 30 | 31 | .openshift 32 | /misc 33 | /scripts 34 | /src 35 | /styles 36 | test 37 | .bowerrc 38 | .editorconfig 39 | .gitattributes 40 | .htmlhintrc 41 | .travis.yml 42 | bower.json 43 | deploy_key.enc 44 | eslint.yaml 45 | grunt-ngdocs-index.tmpl 46 | Gruntfile.js 47 | /server.js 48 | -------------------------------------------------------------------------------- /.openshift/README.md: -------------------------------------------------------------------------------- 1 | For information about .openshift directory, consult the documentation: 2 | 3 | http://openshift.github.io/documentation/oo_user_guide.html#the-openshift-directory 4 | -------------------------------------------------------------------------------- /.openshift/action_hooks/README.md: -------------------------------------------------------------------------------- 1 | For information about action hooks, consult the documentation: 2 | 3 | http://openshift.github.io/documentation/oo_user_guide.html#action-hooks 4 | -------------------------------------------------------------------------------- /.openshift/cron/README.cron: -------------------------------------------------------------------------------- 1 | Run scripts or jobs on a periodic basis 2 | ======================================= 3 | Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly 4 | directories will be run on a scheduled basis (frequency is as indicated by the 5 | name of the directory) using run-parts. 6 | 7 | run-parts ignores any files that are hidden or dotfiles (.*) or backup 8 | files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} 9 | 10 | The presence of two specially named files jobs.deny and jobs.allow controls 11 | how run-parts executes your scripts/jobs. 12 | jobs.deny ===> Prevents specific scripts or jobs from being executed. 13 | jobs.allow ===> Only execute the named scripts or jobs (all other/non-named 14 | scripts that exist in this directory are ignored). 15 | 16 | The principles of jobs.deny and jobs.allow are the same as those of cron.deny 17 | and cron.allow and are described in detail at: 18 | http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access 19 | 20 | See: man crontab or above link for more details and see the the weekly/ 21 | directory for an example. 22 | 23 | PLEASE NOTE: The Cron cartridge must be installed in order to run the configured jobs. 24 | 25 | For more information about cron, consult the documentation: 26 | http://openshift.github.io/documentation/oo_cartridge_guide.html#cron 27 | http://openshift.github.io/documentation/oo_user_guide.html#cron 28 | -------------------------------------------------------------------------------- /.openshift/cron/daily/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/.openshift/cron/daily/.gitignore -------------------------------------------------------------------------------- /.openshift/cron/hourly/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/.openshift/cron/hourly/.gitignore -------------------------------------------------------------------------------- /.openshift/cron/minutely/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/.openshift/cron/minutely/.gitignore -------------------------------------------------------------------------------- /.openshift/cron/monthly/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/.openshift/cron/monthly/.gitignore -------------------------------------------------------------------------------- /.openshift/cron/weekly/README: -------------------------------------------------------------------------------- 1 | Run scripts or jobs on a weekly basis 2 | ===================================== 3 | Any scripts or jobs added to this directory will be run on a scheduled basis 4 | (weekly) using run-parts. 5 | 6 | run-parts ignores any files that are hidden or dotfiles (.*) or backup 7 | files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles 8 | the files named jobs.deny and jobs.allow specially. 9 | 10 | In this specific example, the chronograph script is the only script or job file 11 | executed on a weekly basis (due to white-listing it in jobs.allow). And the 12 | README and chrono.dat file are ignored either as a result of being black-listed 13 | in jobs.deny or because they are NOT white-listed in the jobs.allow file. 14 | 15 | For more details, please see ../README.cron file. 16 | 17 | -------------------------------------------------------------------------------- /.openshift/cron/weekly/chronograph: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "`date`: `cat $(dirname \"$0\")/chrono.dat`" 4 | -------------------------------------------------------------------------------- /.openshift/cron/weekly/jobs.allow: -------------------------------------------------------------------------------- 1 | # 2 | # Script or job files listed in here (one entry per line) will be 3 | # executed on a weekly-basis. 4 | # 5 | # Example: The chronograph script will be executed weekly but the README 6 | # and chrono.dat files in this directory will be ignored. 7 | # 8 | # The README file is actually ignored due to the entry in the 9 | # jobs.deny which is checked before jobs.allow (this file). 10 | # 11 | chronograph 12 | 13 | -------------------------------------------------------------------------------- /.openshift/cron/weekly/jobs.deny: -------------------------------------------------------------------------------- 1 | # 2 | # Any script or job files listed in here (one entry per line) will NOT be 3 | # executed (read as ignored by run-parts). 4 | # 5 | 6 | README 7 | 8 | -------------------------------------------------------------------------------- /.openshift/markers/README.md: -------------------------------------------------------------------------------- 1 | For information about markers, consult the documentation: 2 | 3 | http://openshift.github.io/documentation/oo_user_guide.html#markers 4 | 5 | NOTE: To enable hot deploy, simpy create a file named hot_deploy. 6 | -------------------------------------------------------------------------------- /.openshift/markers/hot_deploy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/.openshift/markers/hot_deploy -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | 5 | cache: 6 | directories: 7 | - node_modules 8 | 9 | notifications: 10 | email: false 11 | 12 | env: 13 | global: 14 | - ENCRYPTION_LABEL: "aa286ccd339e" 15 | - COMMIT_AUTHOR_EMAIL: "patternfly-build@redhat.com" 16 | - TRIGGER_REPO_SLUG: "patternfly/angular-patternfly" 17 | - TRIGGER_REPO_BRANCH: "master" 18 | 19 | before_install: 20 | - npm install -g npm@5.4.0 21 | - npm install -g bower grunt-cli 22 | - npm install patternfly-eng-release 23 | 24 | install: true 25 | 26 | script: 27 | - sh -x ./node_modules/patternfly-eng-release/scripts/_build.sh -a 28 | 29 | after_success: 30 | - 'if [[ "$TRAVIS_SECURE_ENV_VARS" = "true" && "$TRAVIS_BRANCH" = "master-dist" ]]; then 31 | npm prune; 32 | npm run semantic-release-pre; 33 | sh -x ./node_modules/patternfly-eng-release/scripts/semantic-release/_bump.sh -a; 34 | sh -x ./node_modules/patternfly-eng-release/scripts/semantic-release/_publish-npm.sh || travis_terminate 0; 35 | npm run semantic-release-post; 36 | - sh -x ./node_modules/patternfly-eng-release/scripts/semantic-release/_publish-webjar.sh -a; 37 | fi' 38 | - ./scripts/publish-ghpages.sh -t docs 39 | 40 | branches: 41 | except: 42 | - /^v\d+\.\d+\.\d+$/ 43 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Red Hat, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-patternfly", 3 | "version": "0.0.0-semantically-released", 4 | "authors": [ 5 | "Red Hat" 6 | ], 7 | "description": "Angular extension of the PatternFly project.", 8 | "keywords": [ 9 | "angular", 10 | "patternfly" 11 | ], 12 | "license": "MIT", 13 | "ignore": [ 14 | "**/.*", 15 | "docs", 16 | "lib", 17 | "misc", 18 | "node_modules", 19 | "scripts", 20 | "src", 21 | "/styles", 22 | "test", 23 | "deploy_key.enc", 24 | "eslint.yaml", 25 | "grunt-ngdocs-index.tmpl", 26 | "Gruntfile.js", 27 | "/index.js", 28 | "npm-shrinkwrap.json", 29 | "/server.js" 30 | ], 31 | "main": [ 32 | "dist/angular-patternfly.js", 33 | "dist/styles/angular-patternfly.css" 34 | ], 35 | "repository": { 36 | "type": "git", 37 | "url": "git://github.com/patternfly/angular-patternfly.git" 38 | }, 39 | "dependencies": { 40 | "angular": "^1.7.7", 41 | "angular-animate": "^1.7.7", 42 | "angular-sanitize": "^1.7.7", 43 | "angular-svg-base-fix": "2.0.0", 44 | "angular-ui-bootstrap": "2.3.x", 45 | "lodash": "4.x", 46 | "patternfly": "^3.37.1" 47 | }, 48 | "devDependencies": { 49 | "angular-mocks": "^1.7.7", 50 | "angular-ui-router": "^1.0.20" 51 | }, 52 | "overrides": { 53 | "datatables": { 54 | "main": [ 55 | "media/css/jquery.dataTables.css", 56 | "media/images/sort_asc.png", 57 | "media/images/sort_asc_disabled.png", 58 | "media/images/sort_both.png", 59 | "media/images/sort_desc.png", 60 | "media/images/sort_desc_disabled.png" 61 | ] 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /component-conversion.md: -------------------------------------------------------------------------------- 1 | # Converting Angular 1.4 style directives to Angular 1.5 2 | 3 | ## Directive Conversion 4 | 1. Rename file from name-directive.js to name.component.js 5 | 2. In the directive - modify the following: 6 | ``` 7 | angular.module('patternfly.notification').directive('pfNotificationDrawer', function ($window, $timeout) { 8 | 'use strict'; 9 | return { 10 | restrict: 'A', 11 | scope: { 12 | scrollSelector: '@', 13 | groupHeight: '@', 14 | groupClass: '@' 15 | }, 16 | controller: function($window, $timeout) { 17 | $scope.toggle = function () { 18 | 19 | 20 | 21 | angular.module('patternfly.notification').component('pfNotificationDrawer', { 22 | bindings: { 23 | scrollSelector: '@', 24 | groupHeight: '@', 25 | groupClass: '@' 26 | }, 27 | controller: function ($window, $timeout) { 28 | 'use strict'; 29 | var ctrl = this; 30 | 31 | ctrl.toggle = function () { 32 | ``` 33 | 3. Any initialization logic should be moved out of link functions and into $onInit functions 34 | 4. Any event listeners that are added for $window or $timeout events should be cleaned up in $onDestroy 35 | 5. $scope watchers should be moved to $onChanges for bound properties (defined in bindings object) 36 | 6. If DOM manipulation still must happen, there is a $postLink function. A bit more investigation will be necessary to see if these components can be upgraded to Angular 2. 37 | 38 | ## View Conversion 39 | In the template referenced by the templateUrl in the component, some changes have to be made. Anywhere a former $scope variable is referenced, you'll need to prepend $ctrl 40 | ``` 41 |
  • 42 |
    43 | ``` 44 | Becomes: 45 | ``` 46 | 47 |
  • 48 |
    49 | ``` 50 | 51 | ## Unit tests 52 | 1. Modify test to move attribute directives to component in any html code used in the $compile step. 53 | ``` 54 |
    55 | 56 | 57 | ``` 58 | 2. Make sure all unit tests pass 59 | 60 | ## NgDoc changes 61 | 1. Replace the word .directive. with .component. in the ngdoc @name 62 | 2. Add @restrict E under the @name 63 | 3. In example html, move any attribute directives to component.
    becomes 64 | 65 | ## Helpful Links 66 | - https://docs.angularjs.org/guide/component 67 | - https://gist.github.com/toddmotto/5b4de6c777d3e446e6410fdadb824522 68 | -------------------------------------------------------------------------------- /deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/deploy_key.enc -------------------------------------------------------------------------------- /eslint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | browser: true 4 | node: true 5 | 6 | globals: 7 | angular: true 8 | _: true 9 | $: true 10 | 11 | rules: 12 | strict: [2, "function"] 13 | quotes: 0 14 | camelcase: 1 15 | indent: [2, 2] 16 | new-cap: 17 | - 2 18 | - {"newIsCap": true, "capIsNew": false} 19 | no-mixed-spaces-and-tabs: 2 20 | no-multiple-empty-lines: 2 21 | no-trailing-spaces: 2 22 | keyword-spacing: 2 23 | space-before-blocks: 2 24 | space-before-function-paren: 0 25 | space-infix-ops: 2 26 | brace-style: 2 27 | semi: 2 28 | block-scoped-var: 2 29 | consistent-return: 2 30 | curly: 2 31 | eqeqeq: 2 32 | guard-for-in: 2 33 | no-else-return: 2 34 | no-loop-func: 2 35 | vars-on-top: 1 36 | no-debugger: 2 37 | no-cond-assign: 2 38 | no-console: 1 39 | no-extra-semi: 2 40 | no-irregular-whitespace: 2 41 | dot-notation: 42 | - 2 43 | - {"allowPattern": "^[a-z]+(_[a-z]+)+$"} 44 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('angular'); 2 | require('angular-animate'); 3 | require('angular-sanitize'); 4 | require('angular-ui-bootstrap'); 5 | require('lodash'); 6 | require('angular-drag-and-drop-lists'); 7 | require('patternfly/dist/js/patternfly-settings.min'); 8 | require('./dist/angular-patternfly'); 9 | module.exports = 'angular-patternfly'; 10 | -------------------------------------------------------------------------------- /misc/canvas-dot-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/misc/canvas-dot-grid.png -------------------------------------------------------------------------------- /misc/examples.css: -------------------------------------------------------------------------------- 1 | /* Demo CSS */ 2 | .pf-transclude-example div { 3 | border: 1px solid #337ab7; 4 | margin-bottom: 20px; 5 | margin-left: 20px; 6 | } 7 | 8 | .pf-transclude-example p { 9 | background-color: #337ab7; 10 | margin: 0; 11 | padding: 5px 10px; 12 | } 13 | 14 | .pf-transclude-example id { 15 | display: inline-block; 16 | background-color: #def3ff; 17 | color: #000; 18 | border-radius: 10px; 19 | width: 20px; 20 | height: 20px; 21 | text-align: center; 22 | line-height: 20px; 23 | margin-left: 5px; 24 | } 25 | 26 | .pf-transclude-example pre { 27 | padding: 5px; 28 | border-width: 0px; 29 | } 30 | 31 | hr { 32 | display: block; 33 | height: 10px; 34 | border: 0; 35 | border-top: 1px solid #525252; 36 | margin: 1em 0; 37 | padding: 0; 38 | } 39 | 40 | .example-container { 41 | display:inline-block; 42 | width: 100%; 43 | } 44 | 45 | .example-list-view { 46 | height: 100%; 47 | width: 100%; 48 | overflow-y: auto; 49 | background-color: #fff; 50 | } 51 | 52 | .list-view-container { 53 | border: 1px solid #000000; 54 | height: 460px; 55 | min-height: 25px; 56 | margin: 10px; 57 | padding: 0; 58 | } 59 | 60 | .list-view-container .list-row { 61 | padding-top: 2px; 62 | } 63 | 64 | .card-view-container { 65 | border: 1px solid #000000; 66 | margin: 10px; 67 | min-height: 25px; 68 | padding: 5px; 69 | } 70 | 71 | .card-view-container .card-view-pf .card { 72 | height: 110px; 73 | width: 300px; 74 | } 75 | 76 | .dropdown-menu > li > a:hover { 77 | background-image: none; 78 | } 79 | 80 | .pf-select-sm { 81 | height :25px; 82 | width :120px; 83 | } 84 | 85 | .actions-label { 86 | margin-top: 5px; 87 | } 88 | 89 | .pre-demo-text { 90 | margin-top: -20px; 91 | } 92 | 93 | .label-title { 94 | font-size: 16px; 95 | font-weight: 600; 96 | padding-bottom: 10px; 97 | } 98 | 99 | .example-heatmap-container { 100 | border: solid 1px #d1d1d1; 101 | margin: 0 10px; 102 | } 103 | 104 | .example-page-container.container-fluid { 105 | position: fixed; 106 | top: 37px; 107 | bottom: 0; 108 | left: 0; 109 | right: 0; 110 | background-color: #f5f5f5; 111 | padding-top: 15px; 112 | } 113 | .hide-vertical-nav { 114 | margin-top: 15px; 115 | margin-left: 30px; 116 | } 117 | .example-info-text { 118 | width: 100%; 119 | } 120 | .example-info-text:first-of-type { 121 | margin-top: 10px; 122 | } 123 | 124 | .example-error-background { 125 | background-color: #cc0000 !important; 126 | } 127 | .example-warning-background { 128 | background-color: #ec7a08 !important; 129 | } 130 | 131 | .dropdown-kebab-pf.red .btn-link { 132 | color: red; 133 | } 134 | 135 | .canvas-demo-container { 136 | height: 600px; 137 | margin-left: 15px; 138 | overflow: auto; 139 | width: 99%; 140 | } 141 | 142 | .example-wizard-sidebar { 143 | height: 500px; 144 | max-height: 500px; 145 | overflow-y: auto; 146 | } 147 | .example-wizard-step { 148 | height: 500px; 149 | max-height: 500px; 150 | overflow-y: auto; 151 | } 152 | -------------------------------------------------------------------------------- /misc/grid-sidebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patternfly/angular-patternfly/6d989914831096425788abbaa1be7a1c6cf14ce0/misc/grid-sidebar.png -------------------------------------------------------------------------------- /misc/logo-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | -------------------------------------------------------------------------------- /misc/patternfly-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /misc/patternfly-orb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /misc/test-lib/helpers.js: -------------------------------------------------------------------------------- 1 | // jasmine matcher for expecting an element to have a css class 2 | // https://github.com/angular/angular.js/blob/master/test/matchers.js 3 | beforeEach(function() { 4 | jasmine.addMatchers({ 5 | toHaveClass: function() { 6 | return { 7 | compare: function(actual, expected) { 8 | var message = 'Expected "' + actual + '"' + (this.isNot ? ' not ' : ' ') + 'to have class "' + expected + '".'; 9 | 10 | return { 11 | pass: actual.hasClass(expected), 12 | message: message 13 | } 14 | } 15 | }; 16 | }, 17 | 18 | toBeHidden: function() { 19 | return { 20 | compare: function(actual) { 21 | var element = angular.element(actual); 22 | 23 | var message = 'Expected "' + actual + '"' + (this.isNot ? ' not ' : ' ') + 'to be hidden.' 24 | 25 | return { 26 | pass: element.hasClass('ng-hide') || element.css('display') == 'none', 27 | message: message 28 | } 29 | } 30 | }; 31 | }, 32 | 33 | toEqualSelect: function() { 34 | return { 35 | compare: function (actual, expected) { 36 | var actualValues = [], 37 | expectedValues = [].slice.call(expected); 38 | 39 | angular.forEach(actual.find('option'), function(option){ 40 | actualValues.push(option.selected ? [option.text] : option.text); 41 | }); 42 | 43 | var message = 'Expected ' + angular.toJson(actualValues) + ' to equal ' + angular.toJson(expectedValues) + '.'; 44 | 45 | return { 46 | pass: angular.equals(expectedValues, actualValues), 47 | message: message 48 | }; 49 | 50 | } 51 | } 52 | } 53 | }) 54 | }); 55 | 56 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var http = require('http'); 5 | var ipaddress = process.env.OPENSHIFT_NODEJS_IP || 'localhost'; 6 | var port = process.env.OPENSHIFT_NODEJS_PORT || 8080; 7 | 8 | var app = express(); 9 | 10 | // A shutdown handler to log when we quit. 11 | process.on('exit', function() { 12 | console.log('%s: INFO - Node server is shutting down.', 13 | Date(Date.now())); 14 | }); 15 | 16 | try { 17 | app.use(express.static('./dist/docs')); 18 | console.log('%s: INFO - Node server started on %s:%d ...', 19 | Date(Date.now()), ipaddress, port); 20 | http.createServer(app).listen(port, ipaddress); 21 | } 22 | catch (err) { 23 | console.log('%s: ERROR - Problem starting node server%s', 24 | Date(Date.now()), err); 25 | } 26 | -------------------------------------------------------------------------------- /src/autofocus/autofocus.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name patternfly.autofocus:pfFocused 4 | * @restrict A 5 | * @element ANY 6 | * @param {expression=} pfFocused If the expression is true, the element is focused and selected (if possible). 7 | * 8 | * @description 9 | * The focus on element is evaluated from given expression. If the expression provided as an attribute to this directive 10 | * is evaluated as true, the element is selected (and focused). 11 | * 12 | * @example 13 | 14 | 15 | 16 |
    17 |
    18 | 19 |
    20 | 21 |
    22 | 23 |
    24 |
    25 | 26 |
    27 | 28 |
    29 | 30 |
    31 |
    32 | 33 |
    34 |
    35 |
    36 | 37 |
    38 | */ 39 | 40 | angular.module('patternfly.autofocus', []).directive('pfFocused', function ($timeout) { 41 | 'use strict'; 42 | 43 | return { 44 | restrict: 'A', 45 | link: function (scope, element, attrs) { 46 | scope.$watch(attrs.pfFocused, function (newValue) { 47 | $timeout(function () { 48 | if (newValue) { 49 | element[0].focus(); 50 | if (element[0].select) { 51 | element[0].select(); 52 | } 53 | } 54 | }); 55 | }); 56 | } 57 | }; 58 | }); 59 | -------------------------------------------------------------------------------- /src/canvas-view/canvas-editor/toolbox-items.component.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('patternfly.canvas') 5 | .component('toolboxItems', { 6 | templateUrl: 'canvas-view/canvas-editor/toolbox-items.html', 7 | bindings: { 8 | items: '=', 9 | startDragCallback: '<', 10 | clickCallback: '<', 11 | searchText: '=' 12 | }, 13 | controller: function toolboxItemsController () { 14 | var ctrl = this; 15 | 16 | ctrl.itemClicked = function (item) { 17 | if (angular.isFunction(ctrl.clickCallback) && !item.disableInToolbox) { 18 | ctrl.clickCallback(item); 19 | } 20 | }; 21 | 22 | ctrl.startItemDrag = function (event, ui, item) { 23 | if (angular.isFunction(ctrl.startDragCallback)) { 24 | ctrl.startDragCallback(event, ui, item); 25 | } 26 | }; 27 | } 28 | }); 29 | })(); 30 | -------------------------------------------------------------------------------- /src/canvas-view/canvas-editor/toolbox-items.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/canvas-view/canvas.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name patternfly canvas 3 | * 4 | * @description 5 | * Canvas module for patternfly. 6 | * 7 | */ 8 | angular.module('patternfly.canvas', ['dragging', 'ngDragDrop', 'ui.bootstrap']); 9 | -------------------------------------------------------------------------------- /src/canvas-view/canvas/dragging-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | // Service used to help with dragging and clicking on elements. 5 | angular.module('dragging', ['mouseCapture']) 6 | .factory('dragging', ['mouseCapture', Factory]); 7 | 8 | function Factory (mouseCapture) { 9 | // 10 | // Threshold for dragging. 11 | // When the mouse moves by at least this amount dragging starts. 12 | // 13 | var threshold = 5; 14 | 15 | return { 16 | 17 | // 18 | // Called by users of the service to register a mousedown event and start dragging. 19 | // Acquires the 'mouse capture' until the mouseup event. 20 | // 21 | startDrag: function (evt, config) { 22 | var dragging = false; 23 | var x = evt.pageX; 24 | var y = evt.pageY; 25 | 26 | // 27 | // Handler for mousemove events while the mouse is 'captured'. 28 | // 29 | var mouseMove = function (evt) { 30 | if (!dragging) { 31 | if (Math.abs(evt.pageX - x) > threshold 32 | || Math.abs(evt.pageY - y) > threshold) { 33 | dragging = true; 34 | 35 | if (config.dragStarted) { 36 | config.dragStarted(x, y, evt); 37 | } 38 | 39 | if (config.dragging) { 40 | // First 'dragging' call to take into account that we have 41 | // already moved the mouse by a 'threshold' amount. 42 | config.dragging(evt.pageX, evt.pageY, evt); 43 | } 44 | } 45 | } else { 46 | if (config.dragging) { 47 | config.dragging(evt.pageX, evt.pageY, evt); 48 | } 49 | 50 | x = evt.pageX; 51 | y = evt.pageY; 52 | } 53 | }; 54 | 55 | // 56 | // Handler for when mouse capture is released. 57 | // 58 | var released = function () { 59 | if (dragging) { 60 | if (config.dragEnded) { 61 | config.dragEnded(); 62 | } 63 | } else { 64 | if (config.clicked) { 65 | config.clicked(); 66 | } 67 | } 68 | }; 69 | 70 | // 71 | // Handler for mouseup event while the mouse is 'captured'. 72 | // Mouseup releases the mouse capture. 73 | // 74 | var mouseUp = function (evt) { 75 | mouseCapture.release(); 76 | 77 | evt.stopPropagation(); 78 | evt.preventDefault(); 79 | }; 80 | 81 | // 82 | // Acquire the mouse capture and start handling mouse events. 83 | // 84 | mouseCapture.acquire(evt, { 85 | mouseMove: mouseMove, 86 | mouseUp: mouseUp, 87 | released: released 88 | }); 89 | 90 | evt.stopPropagation(); 91 | evt.preventDefault(); 92 | } 93 | }; 94 | } 95 | })(); 96 | 97 | -------------------------------------------------------------------------------- /src/canvas-view/canvas/mouse-capture-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | 4 | // Service used to acquire 'mouse capture' then receive dragging events while the mouse is captured. 5 | angular.module('mouseCapture', []) 6 | .factory('mouseCapture', ['$rootScope', Factory]) 7 | .directive('mouseCapture', [ComponentDirective]); 8 | 9 | function Factory ($rootScope) { 10 | // 11 | // Element that the mouse capture applies to, defaults to 'document' 12 | // unless the 'mouse-capture' directive is used. 13 | // 14 | var $element = document; 15 | 16 | // 17 | // Set when mouse capture is acquired to an object that contains 18 | // handlers for 'mousemove' and 'mouseup' events. 19 | // 20 | var mouseCaptureConfig = null; 21 | 22 | // 23 | // Handler for mousemove events while the mouse is 'captured'. 24 | // 25 | var mouseMove = function (evt) { 26 | if (mouseCaptureConfig && mouseCaptureConfig.mouseMove) { 27 | mouseCaptureConfig.mouseMove(evt); 28 | 29 | $rootScope.$digest(); 30 | } 31 | }; 32 | 33 | // 34 | // Handler for mouseup event while the mouse is 'captured'. 35 | // 36 | var mouseUp = function (evt) { 37 | if (mouseCaptureConfig && mouseCaptureConfig.mouseUp) { 38 | mouseCaptureConfig.mouseUp(evt); 39 | 40 | $rootScope.$digest(); 41 | } 42 | }; 43 | 44 | return { 45 | 46 | // 47 | // Register an element to use as the mouse capture element instead of 48 | // the default which is the document. 49 | // 50 | registerElement: function (element) { 51 | $element = element; 52 | }, 53 | 54 | // 55 | // Acquire the 'mouse capture'. 56 | // After acquiring the mouse capture mousemove and mouseup events will be 57 | // forwarded to callbacks in 'config'. 58 | // 59 | acquire: function (evt, config) { 60 | // 61 | // Release any prior mouse capture. 62 | // 63 | this.release(); 64 | 65 | mouseCaptureConfig = config; 66 | 67 | // 68 | // In response to the mousedown event register handlers for mousemove and mouseup 69 | // during 'mouse capture'. 70 | // 71 | $element.mousemove(mouseMove); 72 | $element.mouseup(mouseUp); 73 | }, 74 | 75 | // 76 | // Release the 'mouse capture'. 77 | // 78 | release: function () { 79 | if (mouseCaptureConfig) { 80 | if (mouseCaptureConfig.released) { 81 | // 82 | // Let the client know that their 'mouse capture' has been released. 83 | // 84 | mouseCaptureConfig.released(); 85 | } 86 | 87 | mouseCaptureConfig = null; 88 | } 89 | 90 | $element.unbind("mousemove", mouseMove); 91 | $element.unbind("mouseup", mouseUp); 92 | } 93 | }; 94 | } 95 | 96 | function ComponentDirective () { 97 | return { 98 | restrict: 'A', 99 | controller: ['$scope', '$element', '$attrs', 'mouseCapture', 100 | function ($scope, $element, $attrs, mouseCapture) { 101 | // 102 | // Register the directives element as the mouse capture element. 103 | // 104 | mouseCapture.registerElement($element); 105 | }] 106 | 107 | }; 108 | } 109 | })(); 110 | 111 | -------------------------------------------------------------------------------- /src/canvas-view/canvas/node-toolbar.component.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('patternfly.canvas') 5 | .component('nodeToolbar', { 6 | templateUrl: 'canvas-view/canvas/node-toolbar.html', 7 | bindings: { 8 | node: '=', 9 | nodeActions: '=', 10 | nodeClickHandler: '<', 11 | nodeCloseHandler: '<' 12 | }, 13 | controller: function NodeToolbarController ($scope) { 14 | var ctrl = this; 15 | ctrl.selectedAction = 'none'; 16 | 17 | ctrl.actionIconClicked = function (action) { 18 | ctrl.selectedAction = action; 19 | $scope.$emit('nodeActionClicked', {'action': action, 'node': ctrl.node}); 20 | if (angular.isFunction(ctrl.nodeClickHandler)) { 21 | ctrl.nodeClickHandler(action, ctrl.node); 22 | } 23 | }; 24 | 25 | ctrl.close = function () { 26 | ctrl.selectedAction = 'none'; 27 | $scope.$emit('nodeActionClosed'); 28 | if (angular.isFunction(ctrl.nodeCloseHandler)) { 29 | ctrl.nodeCloseHandler(); 30 | } 31 | }; 32 | } 33 | }); 34 | })(); 35 | -------------------------------------------------------------------------------- /src/canvas-view/canvas/node-toolbar.html: -------------------------------------------------------------------------------- 1 |
    2 | 5 | 6 |
    7 | -------------------------------------------------------------------------------- /src/card/basic/card-filter.html: -------------------------------------------------------------------------------- 1 |
    2 | 6 | 13 |
    14 | -------------------------------------------------------------------------------- /src/card/basic/card.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |

    {{$ctrl.headTitle}}

    5 |
    6 | {{$ctrl.subTitle}} 7 | 8 |
    9 |
    10 |
    11 |
    12 | 13 | {{$ctrl.spinnerText}} 14 | 15 |
    16 |
    17 |
    18 | 35 |
    36 | -------------------------------------------------------------------------------- /src/card/card.less: -------------------------------------------------------------------------------- 1 | .card-pf-aggregate-status-alt { 2 | .card-pf-body { 3 | padding-bottom: 20px; 4 | } 5 | .card-pf-title { 6 | font-weight: 300; 7 | line-height: 22px; 8 | margin: 20px 0 10px 0; 9 | } 10 | .card-pf-aggregate-status-count { 11 | font-size: 24px; 12 | } 13 | .card-pf-aggregate-status-title { 14 | display: block; 15 | font-size: 12px; 16 | } 17 | .card-pf-aggregate-status-notifications { 18 | .card-pf-aggregate-status-notification { 19 | border-left: none; 20 | } 21 | .fa { 22 | position: relative; 23 | top: -1px; 24 | } 25 | .pficon { 26 | position: relative; 27 | top: -1px; 28 | } 29 | } 30 | } 31 | 32 | .card-pf.card-pf-aggregate-status .card-pf-body .spinner-container { 33 | position: static; 34 | } 35 | 36 | .card-pf { 37 | .hide-for-spinner { 38 | opacity: 0; 39 | } 40 | .card-pf-body { 41 | &.show-spinner { 42 | position: relative; 43 | } 44 | .spinner-container { 45 | display: flex; 46 | justify-content: center; 47 | left: 0; 48 | position: absolute; 49 | right: 0; 50 | top: -20px; 51 | bottom: 0; 52 | 53 | .loading-indicator { 54 | align-items: center; 55 | justify-content: center; 56 | display: flex; 57 | 58 | .loading-text { 59 | font-size: 16px; 60 | margin-left: 10px; 61 | } 62 | 63 | .spinner.spinner-lg { 64 | display: inline-block; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | .card-pf-info-status .card-pf-body .spinner-container{ 72 | top: 0px; 73 | height: 100%; 74 | &.with-title { 75 | top: 12px; 76 | } 77 | } 78 | 79 | .card-pf-aggregate-status-mini { 80 | .card-pf-body { 81 | &.show-spinner { 82 | height: 40px; 83 | } 84 | .spinner-container { 85 | top: -22px; 86 | } 87 | } 88 | } 89 | 90 | .card-pf-heading-no-bottom { 91 | margin: 0 -20px 0px; 92 | padding: 0 20px 0; 93 | } 94 | 95 | .card-pf-icon-image { 96 | height: 18px; 97 | margin: 0 5px 5px; 98 | } 99 | 100 | .trend-card-large-pf { 101 | .trend-header-pf { 102 | display: block; 103 | font-size: 16px; 104 | font-weight: 400; 105 | margin-left: 10px; 106 | } 107 | .trend-title-big-pf { 108 | font-size: 26px; 109 | font-weight: 300; 110 | margin-left: 10px; 111 | } 112 | .trend-title-small-pf { 113 | font-size: 12px; 114 | font-weight: 400; 115 | } 116 | } 117 | 118 | .trend-card-small-pf { 119 | .trend-header-pf { 120 | display: block; 121 | font-size: 12px; 122 | font-weight: 400; 123 | margin-left: 10px; 124 | } 125 | .trend-title-big-pf { 126 | font-size: 17px; 127 | font-weight: 400; 128 | margin-left: 10px; 129 | } 130 | .trend-title-small-pf { 131 | font-size: 10px; 132 | font-weight: 400; 133 | } 134 | } 135 | 136 | .card-pf-info-status { 137 | display: flex; 138 | .card-pf-info-image { 139 | display: flex; 140 | align-items: center; 141 | justify-content: center; 142 | flex-direction:column; 143 | margin-right: 15px; 144 | .info-icon { 145 | font-size: 50px; 146 | } 147 | .info-img { 148 | max-height: 50px; 149 | } 150 | } 151 | .card-pf-info-content { 152 | margin: 10px 0; 153 | .card-pf-title{ 154 | margin-top: 10px; 155 | margin-bottom: 15px; 156 | } 157 | } 158 | .show-spinner { 159 | width: 100%; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/card/card.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name patternfly card 3 | * 4 | * @description 5 | * Card module for patternfly. 6 | * 7 | */ 8 | angular.module('patternfly.card', ['ui.bootstrap']); 9 | -------------------------------------------------------------------------------- /src/card/info-status/info-status-card.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 5 | 6 |
    7 |
    8 |

    9 | 10 | {{$ctrl.status.title}} 11 | 12 | 13 | {{$ctrl.status.title}} 14 | 15 |

    16 |
    17 |
    18 | 19 | {{$ctrl.spinnerText}} 20 | 21 |
    22 |
    23 | 24 |
    26 |
    28 |
    29 |
    30 |
    31 | -------------------------------------------------------------------------------- /src/charts/c3/c3-chart-defaults.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var patternflyDefaults = patternfly.c3ChartDefaults(); 5 | 6 | angular.module('patternfly.charts').constant('c3ChartDefaults', { 7 | getDefaultColors: patternflyDefaults.getDefaultColors, 8 | getDefaultDonut: patternflyDefaults.getDefaultDonut, 9 | getDefaultDonutSize: patternflyDefaults.getDefaultDonutSize, 10 | getDefaultDonutColor: patternflyDefaults.getDefaultDonutColors, 11 | getDefaultDonutLegend: patternflyDefaults.getDefaultDonutLegend, 12 | getDefaultDonutConfig: patternflyDefaults.getDefaultDonutConfig, 13 | getDefaultSparklineArea: patternflyDefaults.getDefaultSparklineArea, 14 | getDefaultSparklineSize: patternflyDefaults.getDefaultSparklineSize, 15 | getDefaultSparklineAxis: patternflyDefaults.getDefaultSparklineAxis, 16 | getDefaultSparklineColor: patternflyDefaults.getDefaultColors, 17 | getDefaultSparklineLegend: patternflyDefaults.getDefaultSparklineLegend, 18 | getDefaultSparklinePoint: patternflyDefaults.getDefaultSparklinePoint, 19 | getDefaultSparklineTooltip: patternflyDefaults.getDefaultSparklineTooltip, 20 | getDefaultSparklineConfig: patternflyDefaults.getDefaultSparklineConfig, 21 | getDefaultLineConfig: patternflyDefaults.getDefaultLineConfig 22 | }); 23 | })(); 24 | -------------------------------------------------------------------------------- /src/charts/charts.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name patternfly 3 | * 4 | * @description 5 | * Charts module for patternfly. Must Include d3.js and c3.js to use 6 | * 7 | */ 8 | angular.module('patternfly.charts', ['patternfly.utils', 'ui.bootstrap', 'ngSanitize']); 9 | 10 | -------------------------------------------------------------------------------- /src/charts/donut/donut-chart-component.js: -------------------------------------------------------------------------------- 1 | angular.module('patternfly.charts').component('pfDonutChart', { 2 | bindings: { 3 | config: '<', 4 | data: '<', 5 | chartHeight: ' 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/charts/donut/donut-pct-chart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | {{$ctrl.config.labelConfig.title}} 10 | 11 | 12 | {{$ctrl.data.available}} {{$ctrl.config.labelConfig.units}} available 13 | {{$ctrl.data.percent}}% used 14 | {{$ctrl.data.used}} {{$ctrl.config.labelConfig.units}} of {{$ctrl.data.total}} {{$ctrl.config.labelConfig.units}} used 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/charts/donut/examples/donut-chart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name patternfly.charts.directive:pfDonutChart 4 | * @restrict E 5 | * 6 | * @description 7 | * Component for rendering a donut chart which shows the relationships of a set of values to a whole. When using a 8 | * Donut Chart to show the relationship of a set of values to a whole, there should be no more than six 9 | * categories. 10 | * 11 | *

    12 | * See http://c3js.org/reference.html for a full list of C3 chart options. 13 | * 14 | * @param {object} config configuration properties for the donut chart:
    15 | * 20 | * 21 | * @param {object} data an array of values for the donut chart.
    22 | * 26 | * 27 | * @param {number} chartHeight height of the donut chart 28 | 29 | * @example 30 | 31 | 32 |
    33 |
    34 |
    35 |
    36 | 37 |
    38 |
    39 | 40 |
    41 |
    42 |
    43 |
    44 |
    45 | 46 |
    47 |
    48 | 49 |
    50 |
    51 |
    52 |
    53 | 54 | 55 | 56 | angular.module( 'patternfly.charts' ).controller( 'ChartCtrl', function( $scope, $interval ) { 57 | $scope.config = { 58 | 'chartId': 'chartOne', 59 | 'legend': {"show":true}, 60 | 'colors' : { 61 | 'Cats': '#0088ce', // blue 62 | 'Hamsters': '#3f9c35', // green 63 | 'Fish': '#ec7a08', // orange 64 | 'Dogs': '#cc0000' // red 65 | }, 66 | donut: { 67 | title: "Animals" 68 | }, 69 | 'onClickFn': function (d, i) { 70 | alert("You clicked on donut arc: " + d.id); 71 | } 72 | }; 73 | 74 | $scope.custConfig = angular.copy($scope.config); 75 | $scope.custConfig.chartId = 'chartTwo'; 76 | $scope.custConfig.legend.position = 'right'; 77 | $scope.custConfig.centerLabelFn = function () { 78 | return "Pets"; 79 | }; 80 | $scope.chartHeight = 120; 81 | 82 | $scope.data = [ 83 | ['Cats', 2], 84 | ['Hamsters', 1], 85 | ['Fish', 3], 86 | ['Dogs', 2] 87 | ]; 88 | 89 | 90 | }); 91 | 92 | 93 | */ 94 | -------------------------------------------------------------------------------- /src/charts/empty-chart.component.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @description 4 | * Directive for rendering an empty chart. This is used by chart directives when the data 5 | * available flag is set to false. 6 | * 7 | * @param {string=} chartHeight height of the chart (no units) - default: 40 8 | */ 9 | angular.module('patternfly.charts').component('pfEmptyChart', { 10 | bindings: { 11 | chartHeight: ' 2 | 3 | No data available 4 | 5 | -------------------------------------------------------------------------------- /src/charts/heatmap/heatmap-legend.component.js: -------------------------------------------------------------------------------- 1 | angular.module('patternfly.charts').component('pfHeatmapLegend', { 2 | bindings: { 3 | legend: ' 90%']; 13 | 14 | ctrl.$onInit = function () { 15 | ctrl.updateAll(); 16 | }; 17 | 18 | ctrl.updateAll = function () { 19 | var items = []; 20 | var index; 21 | 22 | //Allow overriding of defaults 23 | if (!ctrl.legendColors) { 24 | ctrl.legendColors = heatmapColorPatternDefaults; 25 | } 26 | if (!ctrl.legend) { 27 | ctrl.legend = legendLabelDefaults; 28 | } 29 | for (index = ctrl.legend.length - 1; index >= 0; index--) { 30 | items.push({ 31 | text: ctrl.legend[index], 32 | color: ctrl.legendColors[index] 33 | }); 34 | } 35 | ctrl.legendItems = items; 36 | }; 37 | 38 | ctrl.$onChanges = function (changesObj) { 39 | if (changesObj.legend && !changesObj.legend.isFirstChange()) { 40 | ctrl.updateAll(); 41 | } 42 | if (changesObj.legendColors && !changesObj.legendColors.isFirstChange()) { 43 | ctrl.updateAll(); 44 | } 45 | }; 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /src/charts/heatmap/heatmap-legend.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /src/charts/heatmap/heatmap.html: -------------------------------------------------------------------------------- 1 |
    2 |

    {{$ctrl.chartTitle}}

    3 |
    4 | 5 |
    6 | 7 |
    8 | 9 |
    10 | -------------------------------------------------------------------------------- /src/charts/line/line-chart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/charts/sparkline/sparkline-chart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/charts/topology-map/topology-map.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | -------------------------------------------------------------------------------- /src/charts/utilization-bar/utilization-bar-chart.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    {{$ctrl.chartTitle}}
    4 |
    5 |
    8 | 9 | {{$ctrl.chartData.used}} of {{$ctrl.chartData.total}} {{$ctrl.units}} Used 10 | {{$ctrl.chartData.percentageUsed}}% Used 11 |
    12 |
    14 |
    15 |
    16 |
    17 | 18 |
    20 |
    {{$ctrl.chartTitle}}
    21 |
    22 |
    25 | 26 | {{$ctrl.chartData.used}} {{$ctrl.units}} Used 27 | {{$ctrl.chartData.percentageUsed}}% Used 28 |
    29 |
    31 |
    32 |
    33 |
    34 |
    35 | 36 |
    37 | -------------------------------------------------------------------------------- /src/charts/utilization-trend/utilization-trend-chart.html: -------------------------------------------------------------------------------- 1 |
    2 |

    {{$ctrl.config.title}}

    3 |
    4 |

    {{$ctrl.currentValue}}

    5 |
    6 |
    7 | {{$ctrl.currentText}} 8 |
    9 |
    10 | of {{$ctrl.chartData.total}} {{$ctrl.config.units}} 11 |
    12 |
    13 |
    14 |
    15 | 16 | 17 |
    18 |
    19 | 20 |
    21 | {{$ctrl.legendLeftText}} 22 | {{$ctrl.legendRightText}} 23 |
    24 | -------------------------------------------------------------------------------- /src/datepicker/bootstrap-datepicker.component.js: -------------------------------------------------------------------------------- 1 | angular.module('patternfly.datepicker').component('pfBootstrapDatepicker', { 2 | bindings: { 3 | date: '<', 4 | format: '@?', 5 | dateOptions: ' 2 | 11 | 12 | 13 | 14 |

    15 | -------------------------------------------------------------------------------- /src/datepicker/datepicker.less: -------------------------------------------------------------------------------- 1 | .uib-datepicker-popup { 2 | padding: 4px; 3 | 4 | *:focus { 5 | outline: none; 6 | } 7 | 8 | button { 9 | background: @color-pf-white; 10 | border: none; 11 | box-shadow: none; 12 | } 13 | 14 | th { 15 | height: 30px; 16 | } 17 | 18 | .uib-title { 19 | font-size: 14px; 20 | font-weight: 500; 21 | padding: 5px; 22 | 23 | strong { 24 | font-weight: normal; 25 | } 26 | } 27 | 28 | .uib-left { 29 | height: 30px; 30 | 31 | .glyphicon { 32 | display: none; 33 | } 34 | 35 | &::before { 36 | content: "\00AB"; 37 | } 38 | } 39 | 40 | .uib-right { 41 | height: 30px; 42 | 43 | .glyphicon { 44 | display: none; 45 | } 46 | 47 | &::before { 48 | content: "\00BB"; 49 | } 50 | } 51 | 52 | .uib-day { 53 | 54 | button.btn.btn-default { 55 | height: 30px; 56 | width: 30px; 57 | 58 | &:hover { 59 | background: @color-pf-blue-50; 60 | } 61 | 62 | &.active { 63 | background: @color-pf-blue-400; 64 | border-color: @color-pf-blue-600; 65 | color: @color-pf-white; 66 | box-shadow: none; 67 | padding: 0; 68 | 69 | .text-info { // this is today's date 70 | color: @color-pf-white; 71 | } 72 | } 73 | 74 | &:not(.active){ 75 | .text-info { // this is today's date 76 | color: @color-pf-black-800; 77 | background: @color-pf-gold-200; 78 | height: 30px; 79 | width: 30px; 80 | padding: 7px; 81 | display: inline-block; 82 | margin: -1px -7px -2px -7px; 83 | 84 | &:hover { 85 | background: @color-pf-blue-50; 86 | } 87 | } 88 | } 89 | } 90 | 91 | } 92 | 93 | .uib-button-bar { 94 | padding: 0; 95 | 96 | .btn-group { 97 | width: 100%; 98 | 99 | .uib-clear { 100 | display: none; 101 | } 102 | 103 | .uib-datepicker-current { 104 | color: @color-pf-black; 105 | width: 100%; 106 | font-size: 14px; 107 | font-weight: 500; 108 | height: 30px; 109 | 110 | &:hover { 111 | background: @color-pf-blue-50; 112 | } 113 | } 114 | } 115 | 116 | .uib-close { 117 | display: none; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/datepicker/datepicker.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name patternfly datepicker 3 | * 4 | * @description 5 | * Datepicker module for patternfly. 6 | * 7 | */ 8 | angular.module('patternfly.datepicker', ['ui.bootstrap']); 9 | 10 | -------------------------------------------------------------------------------- /src/datepicker/examples/bootstrap.datepicker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name patternfly.datepicker.componenet:pfBootstrapDatepicker 4 | * @element pf-bootstrap-datepicker 5 | * 6 | * @param {date} date Must be a Javascript Date - to be displayed in the input. Can be left empty. 7 | * @param {string} format Optional date format for displayed dates ('MM/dd/yyyy' by default). 8 | * @param {function} on-date-change Optional user defined function which is called when the date is changed by the picker.
    9 | * @param {boolean} isOpen Optional boolean for determining whether or not to have the datepicker default to open (false by default). 10 | * @param {string} popupPlacement Optional configuration string used to position the popup datepicker relative to the input element. See {@link https://angular-ui.github.io/bootstrap/#datepickerPopup Angular UI Datepicker Popup}. 11 | * @param {object} dateOptions Optional uib-datepicker configuration object. See {@link https://angular-ui.github.io/bootstrap/#datepicker Angular UI Datepicker}. 12 | * 13 | * @description 14 | * A wrapper for the Angular UI {@link http://angular-ui.github.io/bootstrap/#!#datepickerPopup datepicker}. 15 | * 16 | * @example 17 | 18 | 19 | 20 |
    21 |
    22 | 23 | 27 | 28 | 29 | 37 | 38 |
    39 |
    40 | 41 |
    42 |
    43 | 44 |
    45 |
    46 |
    47 | 48 | 49 | angular.module('patternfly.datepicker').controller('DemoBootstrapDatepicker', function( $scope ) { 50 | $scope.eventText = ''; 51 | 52 | // first datepicker 53 | $scope.dateOne = new Date("Jan 1, 2000"); 54 | $scope.firstDateChanged = function(date) { 55 | $scope.eventText = 'Date One Updated to: ' + date + '\r\n' + $scope.eventText; 56 | }; 57 | 58 | // second datepicker 59 | $scope.dateTwo = new Date("Feb 1, 2000"); 60 | $scope.format1 = "MM/dd/yy"; 61 | $scope.dateOptions = { 62 | showWeeks : true 63 | }; 64 | $scope.isOpen = true; 65 | $scope.popupPlacement = "bottom-left"; 66 | 67 | $scope.secondDateChanged = function(date) { 68 | $scope.eventText = 'Date Two Updated to: ' + date + '\r\n' + $scope.eventText; 69 | }; 70 | }); 71 | 72 | 73 |
    74 | */ 75 | -------------------------------------------------------------------------------- /src/filters/filter-panel/filter-panel-component.js: -------------------------------------------------------------------------------- 1 | angular.module('patternfly.filters').component('pfFilterPanel', { 2 | bindings: { 3 | config: '=' 4 | }, 5 | transclude: true, 6 | templateUrl: 'filters/filter-panel/filter-panel.html', 7 | controller: function () { 8 | 'use strict'; 9 | 10 | var ctrl = this; 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /src/filters/filter-panel/filter-panel-results-component.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name patternfly.filters.directive:pfFilterPanelResults 4 | * @restrict E 5 | * 6 | * @description 7 | * Component for the filter panel results 8 | *

    9 | * 10 | * @param {object} config configuration settings for the filter panel results:
    11 | * 28 | * 29 | */ 30 | angular.module('patternfly.filters').component('pfFilterPanelResults', { 31 | bindings: { 32 | config: '=' 33 | }, 34 | templateUrl: 'filters/filter-panel/filter-panel-results.html', 35 | controller: function () { 36 | 'use strict'; 37 | 38 | var ctrl = this; 39 | 40 | ctrl.$onInit = function () { 41 | angular.extend(ctrl, { 42 | clearFilter: clearFilter, 43 | clearAllFilters: clearAllFilters 44 | }); 45 | }; 46 | 47 | ctrl.$onChanges = function () { 48 | setupConfig (); 49 | }; 50 | 51 | function setupConfig () { 52 | if (!ctrl.config.appliedFilters) { 53 | ctrl.config.appliedFilters = []; 54 | } 55 | if (ctrl.config.resultsCount === undefined) { 56 | ctrl.config.resultsCount = 0; 57 | } 58 | } 59 | 60 | function clearFilter (evt, filter, value) { 61 | var changedFilterId = filter.id; 62 | evt.preventDefault(); 63 | 64 | _.pull(filter.values, value); 65 | 66 | if (filter.values.length === 0) { 67 | _.pull(ctrl.config.appliedFilters, filter); 68 | } 69 | 70 | if (ctrl.config.onFilterChange) { 71 | ctrl.config.onFilterChange(ctrl.config.appliedFilters, changedFilterId, value); 72 | } 73 | } 74 | 75 | function clearAllFilters (evt) { 76 | evt.preventDefault(); 77 | 78 | ctrl.config.appliedFilters = []; 79 | 80 | if (ctrl.config.onFilterChange) { 81 | ctrl.config.onFilterChange(ctrl.config.appliedFilters); 82 | } 83 | } 84 | } 85 | }); 86 | -------------------------------------------------------------------------------- /src/filters/filter-panel/filter-panel-results.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | {{$ctrl.config.resultsCount}} 5 | of {{$ctrl.config.totalCount}} 6 | {{$ctrl.config.resultsLabel === undefined ? "Results" : $ctrl.config.resultsLabel}} 7 |
    8 |

    Active filters:

    9 |
      10 |
    • 11 | 12 | {{filter.title}}: 13 |
        14 |
      • 15 | {{value}} 16 | 17 | 18 |
      • 19 |
      20 |
      21 |
    • 22 |
    23 |

    Clear All Filters

    24 |
    25 |
    26 | -------------------------------------------------------------------------------- /src/filters/filter-panel/filter-panel.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 7 | 8 | 9 | 10 |
    11 | -------------------------------------------------------------------------------- /src/filters/filters.less: -------------------------------------------------------------------------------- 1 | .filter-pf { 2 | .category-select { 3 | display: flex; 4 | } 5 | .category-select-value { 6 | border-left-width: 0 !important; 7 | } 8 | } 9 | .filter-pf.filter-fields { 10 | .form-group { 11 | width: 275px; 12 | } 13 | } 14 | .filter-select { 15 | .btn-default { 16 | background-color: @color-pf-white; 17 | background-image: none; 18 | color: @color-pf-black-500; 19 | font-size: 12px; 20 | font-style: italic; 21 | font-weight: 400; 22 | } 23 | } 24 | 25 | pf-filter-panel { 26 | .dropdown > .dropdown-menu, .input-group-btn > .dropdown-menu { 27 | margin-top: 5px; 28 | opacity: .95; 29 | } 30 | input { 31 | &:-moz-placeholder { font-style: italic; padding-left: 10px; } // Firefox 4-18 32 | &::-moz-placeholder { font-style: italic; padding-left: 10px; } // Firefox 19+ 33 | &:-ms-input-placeholder { font-style: italic; padding-left: 10px; } // Internet Explorer 10+ 34 | &::-webkit-input-placeholder { font-style: italic; padding-left: 10px;} // Safari and Chrome 35 | } 36 | .inline-filter-pf > .dropdown { 37 | margin-right: 10px; 38 | } 39 | .filter-panel-container { 40 | padding: 10px; 41 | .keyword-filter { 42 | margin-bottom: 10px; 43 | } 44 | ul { 45 | list-style-type: none; 46 | padding-left: 16px; 47 | } 48 | .category { 49 | font-size: 15px; 50 | font-weight: 400; 51 | 52 | .category-option-label { 53 | font-size: 12px; 54 | vertical-align: text-bottom; 55 | } 56 | } 57 | } 58 | } 59 | 60 | .filter-pf-active-label { 61 | margin-right: 5px; 62 | } 63 | 64 | .filter-pf-category-item { 65 | margin-bottom: 5px; 66 | } 67 | 68 | .pf-filter-category-label { 69 | font-weight: 700; 70 | padding: 5px 0 6px 5px; 71 | margin-right: 5px; 72 | 73 | &.multiples { 74 | background-color: @color-pf-blue-300; 75 | padding-right: 5px; 76 | } 77 | } 78 | 79 | .filter-pf-category-values.list-inline { 80 | margin-left: 0; 81 | > li { 82 | margin-left: 5px; 83 | padding: 0; 84 | } 85 | } 86 | 87 | 88 | .filter-pf { 89 | &.inline-filter-pf { 90 | pf-filter-fields, 91 | pf-filter-results, 92 | pf-filter-panel-results { 93 | display: inline-block; 94 | } 95 | pf-filter-fields { 96 | vertical-align: middle; 97 | } 98 | 99 | .filter-fields { 100 | > .form-group { 101 | margin-bottom: 3px; 102 | margin-right: 15px; 103 | } 104 | } 105 | .toolbar-pf-results { 106 | border-top: none; 107 | margin-top: 0; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/filters/filters.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name patternfly card 3 | * 4 | * @description 5 | * Filters module for patternfly. 6 | * 7 | */ 8 | angular.module('patternfly.filters', ['ui.bootstrap']); 9 | -------------------------------------------------------------------------------- /src/filters/simple-filter/filter-component.js: -------------------------------------------------------------------------------- 1 | angular.module('patternfly.filters').component('pfFilter', { 2 | bindings: { 3 | config: '=' 4 | }, 5 | templateUrl: 'filters/simple-filter/filter.html', 6 | controller: function () { 7 | 'use strict'; 8 | 9 | var ctrl = this; 10 | 11 | ctrl.$onInit = function () { 12 | 13 | angular.extend(ctrl, 14 | { 15 | addFilter: addFilter 16 | } 17 | ); 18 | }; 19 | 20 | function filterExists (filter) { 21 | return angular.isDefined(_.find(ctrl.config.appliedFilters, {title: filter.title, value: filter.value})); 22 | } 23 | 24 | function findDuplicateComplexSelect (item) { 25 | return item.value.filterCategory; 26 | } 27 | 28 | function enforceSingleSelect (filter) { 29 | _.remove(ctrl.config.appliedFilters, {title: filter.title}); 30 | } 31 | 32 | function addFilter (field, value) { 33 | var newFilter = { 34 | id: field.id, 35 | title: field.title, 36 | type: field.filterType, 37 | value: value 38 | }; 39 | 40 | if (!filterExists(newFilter)) { 41 | 42 | if (newFilter.type === 'select') { 43 | enforceSingleSelect(newFilter); 44 | } 45 | 46 | if (field.filterType === 'complex-select' && !field.filterMultiselect) { 47 | _.remove(ctrl.config.appliedFilters, findDuplicateComplexSelect); 48 | } 49 | 50 | ctrl.config.appliedFilters.push(newFilter); 51 | 52 | if (ctrl.config.onFilterChange) { 53 | ctrl.config.onFilterChange(ctrl.config.appliedFilters); 54 | } 55 | } 56 | } 57 | } 58 | }); 59 | -------------------------------------------------------------------------------- /src/filters/simple-filter/filter-results.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    {{$ctrl.config.resultsCount}} {{$ctrl.config.itemsLabel}}
    5 |
    {{$ctrl.config.resultsCount}} {{$ctrl.config.itemsLabelPlural}}
    6 |
    7 | 8 |
    {{$ctrl.config.resultsCount}} of {{$ctrl.config.totalCount}} {{$ctrl.config.itemsLabel}}
    9 |
    {{$ctrl.config.resultsCount}} of {{$ctrl.config.totalCount}} {{$ctrl.config.itemsLabelPlural}}
    10 |
    11 |

    Active Filters:

    12 |
      13 |
    • 14 | 15 | {{filter.title}}: {{((filter.value.filterCategory.title || filter.value.filterCategory) + filter.value.filterDelimiter + (filter.value.filterValue.title || filter.value.filterValue)) || filter.value.title || filter.value}} 16 | 17 | 18 |
    • 19 |
    20 |

    Clear All Filters

    21 |
    22 | {{$ctrl.config.selectedCount}} of {{$ctrl.config.totalCount}} selected 23 |
    24 |
    25 |
    26 | -------------------------------------------------------------------------------- /src/filters/simple-filter/filter.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 |
    5 | -------------------------------------------------------------------------------- /src/form/examples/form-buttons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name patternfly.form.directive:pfFormButtons 4 | * @restrict E 5 | * 6 | * @description 7 | * Encapsulates the standard structure and styling for create and cancel buttons 8 | * when used with a form. 9 | * 10 | * This directive creates new scope. 11 | * 12 | * @param {function} pfHandleCancel function to call when the user clicks cancel. 13 | * @param {function} pfHandleSave function to call when the user clicks save. 14 | * @param {expression} pfWorking the model to store the working status in. 15 | * @param {string} pfButtonClass the class of the button container. 16 | * 17 | * @example 18 | 19 | 20 | 21 |
    22 |

    Saved?

    23 |

    {{ status }}

    24 |
    25 |
    Input 27 | 28 |
    29 | 30 |
    31 |
    32 |
    33 | 34 | 35 | angular.module( 'patternfly.form' ).controller( 'FormButtonCtrl', function( $scope, $timeout, $element ) { 36 | $scope.status = 'Not yet Saved'; 37 | $scope.working = false; 38 | 39 | $scope.save = function (item) { 40 | $scope.status = 'saved'; 41 | $scope.working = true; 42 | 43 | $timeout(function () { 44 | $scope.working = false; 45 | }, 1000); 46 | }; 47 | 48 | $scope.cancel = function () { 49 | $scope.status = 'cancelled'; 50 | $scope.input = null; 51 | }; 52 | }); 53 | 54 |
    55 | */ 56 | -------------------------------------------------------------------------------- /src/form/examples/form-group.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc directive 3 | * @name patternfly.form.directive:pfFormGroup 4 | * @restrict E 5 | * 6 | * @description 7 | * Encapsulates the structure and styling for a label + input used within a 8 | * Bootstrap3 based form. 9 | * 10 | * This directive creates new scope. 11 | * 12 | * @param {string} pfLabel the text for the