├── app ├── assets │ ├── styles │ │ ├── _icon-buttons.scss │ │ ├── .DS_Store │ │ ├── _browse-happy.scss │ │ ├── mixins │ │ │ ├── _center-block.scss │ │ │ ├── _opacity.scss │ │ │ ├── _size.scss │ │ │ ├── _text-overflow.scss │ │ │ ├── _tab-focus.scss │ │ │ ├── _resize.scss │ │ │ ├── _labels.scss │ │ │ ├── _text-emphasis.scss │ │ │ ├── _progress-bar.scss │ │ │ ├── _background-variant.scss │ │ │ ├── _reset-filter.scss │ │ │ ├── _nav-divider.scss │ │ │ ├── _alerts.scss │ │ │ ├── _nav-vertical-align.scss │ │ │ ├── _pagination.scss │ │ │ ├── _border-radius.scss │ │ │ ├── _responsive-visibility.scss │ │ │ ├── _panels.scss │ │ │ ├── _hide-text.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _list-group.scss │ │ │ ├── _table-row.scss │ │ │ ├── _buttons.scss │ │ │ ├── _image.scss │ │ │ ├── _grid-framework.scss │ │ │ ├── _forms.scss │ │ │ ├── _grid.scss │ │ │ └── _gradients.scss │ │ ├── _wells.scss │ │ ├── _breadcrumbs.scss │ │ ├── _responsive-embed.scss │ │ ├── _close.scss │ │ ├── _component-animations.scss │ │ ├── _app.scss │ │ ├── _thumbnails.scss │ │ ├── _media.scss │ │ ├── _pager.scss │ │ ├── _utilities.scss │ │ ├── _mixins.scss │ │ ├── _flaticon.scss │ │ ├── _jumbotron.scss │ │ ├── _badges.scss │ │ ├── _labels.scss │ │ ├── styles.scss │ │ ├── _code.scss │ │ ├── _grid.scss │ │ ├── _alerts.scss │ │ ├── _print.scss │ │ ├── _pagination.scss │ │ ├── _progress-bars.scss │ │ ├── _leaflet-awesome-markers.scss │ │ ├── _tooltip.scss │ │ ├── _scaffolding.scss │ │ ├── _angular-animations.scss │ │ ├── _list-group.scss │ │ ├── _bootswatch.scss │ │ ├── _popovers.scss │ │ ├── _modals.scss │ │ ├── _buttons.scss │ │ ├── _flipping.scss │ │ ├── _input-groups.scss │ │ └── _responsive-utilities.scss │ ├── .DS_Store │ ├── fonts │ │ ├── .DS_Store │ │ ├── flaticon.eot │ │ ├── flaticon.ttf │ │ ├── flaticon.woff │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ └── images │ │ ├── address.png │ │ ├── crimes.png │ │ ├── layers.png │ │ ├── mailbox.png │ │ ├── trash.png │ │ ├── zoning.png │ │ ├── layers-2x.png │ │ ├── property.png │ │ ├── recycling.png │ │ ├── development.png │ │ ├── marker-icon.png │ │ ├── markers-soft.png │ │ ├── marker-icon-2x.png │ │ ├── marker-shadow.png │ │ ├── markers-matte.png │ │ ├── markers-plain.png │ │ ├── markers-shadow.png │ │ ├── citylogo-flatblue.png │ │ ├── markers-matte@2x.png │ │ ├── markers-shadow@2x.png │ │ ├── markers-soft@2x.png │ │ ├── street-maintenance.png │ │ ├── powered-by-google-on-white.png │ │ └── leaflet.awesome-markers.css ├── .DS_Store ├── favicon.ico ├── 404.html ├── citylogo-flatblue.png ├── components │ ├── topics │ │ ├── topic-components │ │ │ ├── trash-collection │ │ │ │ ├── trash.collection.simple.view.html │ │ │ │ └── trash.factory.js │ │ │ ├── owner │ │ │ │ ├── owner.view.html │ │ │ │ ├── owner.details.view.html │ │ │ │ └── owner.list.view.html │ │ │ ├── recycling-collection │ │ │ │ ├── recycling.collection.simple.view.html │ │ │ │ └── recycling.factory.js │ │ │ ├── address-list │ │ │ │ ├── address-list.view.html │ │ │ │ └── address.list.factory.js │ │ │ ├── crime │ │ │ │ ├── crime.summary.view.html │ │ │ │ └── crime.list.view.html │ │ │ ├── development │ │ │ │ ├── development.summary.view.html │ │ │ │ └── development.list.view.html │ │ │ ├── zoning │ │ │ │ ├── zoning.view.html │ │ │ │ └── zoning.factory.js │ │ │ └── street-maintenance │ │ │ │ └── street.maintenance.list.view.html │ │ ├── sanitation.card.html │ │ ├── topic-list │ │ │ ├── topic.list.controller.js │ │ │ └── topic.list.html │ │ ├── topic-headers │ │ │ ├── topic.header.along.html │ │ │ ├── topic.header.at.html │ │ │ ├── topic.header.in.html │ │ │ ├── topic.header.ownedby.html │ │ │ ├── topic.header.during.along.html │ │ │ ├── topic.header.during.in.html │ │ │ └── topic.header.during.within.of.html │ │ └── topics.factory.js │ ├── main │ │ ├── main.controller.js │ │ └── main.html │ ├── simplicity.controller.js │ ├── citizen-service-request │ │ └── request-form.html │ └── search │ │ ├── search.html │ │ └── search.controller.js ├── simplicity.js ├── adapters │ └── simplicity.google.places.api.adapter.js ├── simplicity.http.js └── index.html ├── test ├── .DS_Store ├── e2e │ ├── .DS_Store │ └── main.js ├── dependencies │ └── .DS_Store ├── unit │ ├── main.mocha.js │ └── app.factory.mocha.js ├── protractor.conf.js └── karma.conf.js ├── .jshintrc ├── .gitignore ├── unit-tests.js ├── e2e-tests.js ├── LICENSE.md ├── package.json └── README.md /app/assets/styles/_icon-buttons.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/.DS_Store -------------------------------------------------------------------------------- /test/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/test/.DS_Store -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /app/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/e2e/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/test/e2e/.DS_Store -------------------------------------------------------------------------------- /app/assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/.DS_Store -------------------------------------------------------------------------------- /app/assets/fonts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/.DS_Store -------------------------------------------------------------------------------- /app/citylogo-flatblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/citylogo-flatblue.png -------------------------------------------------------------------------------- /app/assets/fonts/flaticon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/flaticon.eot -------------------------------------------------------------------------------- /app/assets/fonts/flaticon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/flaticon.ttf -------------------------------------------------------------------------------- /app/assets/images/address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/address.png -------------------------------------------------------------------------------- /app/assets/images/crimes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/crimes.png -------------------------------------------------------------------------------- /app/assets/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/layers.png -------------------------------------------------------------------------------- /app/assets/images/mailbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/mailbox.png -------------------------------------------------------------------------------- /app/assets/images/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/trash.png -------------------------------------------------------------------------------- /app/assets/images/zoning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/zoning.png -------------------------------------------------------------------------------- /app/assets/styles/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/styles/.DS_Store -------------------------------------------------------------------------------- /test/dependencies/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/test/dependencies/.DS_Store -------------------------------------------------------------------------------- /app/assets/fonts/flaticon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/flaticon.woff -------------------------------------------------------------------------------- /app/assets/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/layers-2x.png -------------------------------------------------------------------------------- /app/assets/images/property.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/property.png -------------------------------------------------------------------------------- /app/assets/images/recycling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/recycling.png -------------------------------------------------------------------------------- /app/assets/images/development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/development.png -------------------------------------------------------------------------------- /app/assets/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/marker-icon.png -------------------------------------------------------------------------------- /app/assets/images/markers-soft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-soft.png -------------------------------------------------------------------------------- /app/assets/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/marker-icon-2x.png -------------------------------------------------------------------------------- /app/assets/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/marker-shadow.png -------------------------------------------------------------------------------- /app/assets/images/markers-matte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-matte.png -------------------------------------------------------------------------------- /app/assets/images/markers-plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-plain.png -------------------------------------------------------------------------------- /app/assets/images/markers-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-shadow.png -------------------------------------------------------------------------------- /app/assets/images/citylogo-flatblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/citylogo-flatblue.png -------------------------------------------------------------------------------- /app/assets/images/markers-matte@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-matte@2x.png -------------------------------------------------------------------------------- /app/assets/images/markers-shadow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-shadow@2x.png -------------------------------------------------------------------------------- /app/assets/images/markers-soft@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/markers-soft@2x.png -------------------------------------------------------------------------------- /app/assets/images/street-maintenance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/street-maintenance.png -------------------------------------------------------------------------------- /app/assets/styles/_browse-happy.scss: -------------------------------------------------------------------------------- 1 | .browsehappy { 2 | margin: 0.2em 0; 3 | background: #ccc; 4 | color: #000; 5 | padding: 0.2em 0; 6 | } 7 | -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/assets/images/powered-by-google-on-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/images/powered-by-google-on-white.png -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cityofasheville/simplicity-ui/HEAD/app/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/assets/styles/mixins/_center-block.scss: -------------------------------------------------------------------------------- 1 | // Center-align a block level element 2 | 3 | @mixin center-block() { 4 | display: block; 5 | margin-left: auto; 6 | margin-right: auto; 7 | } 8 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_opacity.scss: -------------------------------------------------------------------------------- 1 | // Opacity 2 | 3 | @mixin opacity($opacity) { 4 | opacity: $opacity; 5 | // IE8 filter 6 | $opacity-ie: ($opacity * 100); 7 | filter: #{alpha(opacity=$opacity-ie)}; 8 | } 9 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_size.scss: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | @mixin size($width, $height) { 4 | width: $width; 5 | height: $height; 6 | } 7 | 8 | @mixin square($size) { 9 | @include size($size, $size); 10 | } 11 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_text-overflow.scss: -------------------------------------------------------------------------------- 1 | // Text overflow 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-overflow() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_tab-focus.scss: -------------------------------------------------------------------------------- 1 | // WebKit-style focus 2 | 3 | @mixin tab-focus() { 4 | // Default 5 | outline: thin dotted; 6 | // WebKit 7 | outline: 5px auto -webkit-focus-ring-color; 8 | outline-offset: -2px; 9 | } 10 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | resize: $direction; // Options: horizontal, vertical, both 5 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 6 | } 7 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_labels.scss: -------------------------------------------------------------------------------- 1 | // Labels 2 | 3 | @mixin label-variant($color) { 4 | background-color: $color; 5 | 6 | &[href] { 7 | &:hover, 8 | &:focus { 9 | background-color: darken($color, 10%); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/trash-collection/trash.collection.simple.view.html: -------------------------------------------------------------------------------- 1 |
2 |

Your trash is collected every

3 |

{{topic.trash}}.

4 |
-------------------------------------------------------------------------------- /app/assets/styles/mixins/_text-emphasis.scss: -------------------------------------------------------------------------------- 1 | // Typography 2 | 3 | // [converter] $parent hack 4 | @mixin text-emphasis-variant($parent, $color) { 5 | #{$parent} { 6 | color: $color; 7 | } 8 | a#{$parent}:hover { 9 | color: darken($color, 10%); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_progress-bar.scss: -------------------------------------------------------------------------------- 1 | // Progress bars 2 | 3 | @mixin progress-bar-variant($color) { 4 | background-color: $color; 5 | 6 | // Deprecated parent class requirement as of v3.2.0 7 | .progress-striped & { 8 | @include gradient-striped(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_background-variant.scss: -------------------------------------------------------------------------------- 1 | // Contextual backgrounds 2 | 3 | // [converter] $parent hack 4 | @mixin bg-variant($parent, $color) { 5 | #{$parent} { 6 | background-color: $color; 7 | } 8 | a#{$parent}:hover { 9 | background-color: darken($color, 10%); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/owner/owner.view.html: -------------------------------------------------------------------------------- 1 |
2 |

Owner

3 | {{feature.properties.owner}} 4 |
{{feature.properties.owner_address}}
5 | {{feature.properties.owner_citystatezip}}
6 |
-------------------------------------------------------------------------------- /app/assets/styles/mixins/_reset-filter.scss: -------------------------------------------------------------------------------- 1 | // Reset filters for IE 2 | // 3 | // When you need to remove a gradient background, do not forget to use this to reset 4 | // the IE filter for IE9 and below. 5 | 6 | @mixin reset-filter() { 7 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 8 | } 9 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_nav-divider.scss: -------------------------------------------------------------------------------- 1 | // Horizontal dividers 2 | // 3 | // Dividers (basically an hr) within dropdowns and nav lists 4 | 5 | @mixin nav-divider($color: #e5e5e5) { 6 | height: 1px; 7 | margin: (($line-height-computed / 2) - 1) 0; 8 | overflow: hidden; 9 | background-color: $color; 10 | } 11 | -------------------------------------------------------------------------------- /app/components/main/main.controller.js: -------------------------------------------------------------------------------- 1 | simplicity.controller('MainCtrl', ['$scope', '$state', '$stateParams', '$location', '$http', '$timeout', 2 | function ($scope, $state, $stateParams, $location, $http, $timeout) { 3 | 4 | 5 | $scope.goHome = function(){ 6 | $location.path(''); 7 | }; 8 | 9 | 10 | 11 | }]); -------------------------------------------------------------------------------- /app/assets/styles/mixins/_alerts.scss: -------------------------------------------------------------------------------- 1 | // Alerts 2 | 3 | @mixin alert-variant($background, $border, $text-color) { 4 | background-color: $background; 5 | border-color: $border; 6 | color: $text-color; 7 | 8 | hr { 9 | border-top-color: darken($border, 5%); 10 | } 11 | .alert-link { 12 | color: darken($text-color, 10%); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/recycling-collection/recycling.collection.simple.view.html: -------------------------------------------------------------------------------- 1 |
2 |

Recycling is collected every other week.

3 |

Your recycling will be collected

4 |

{{topic.recyclingSchedule.when}} on {{topic.recyclingDay}}.

5 |
-------------------------------------------------------------------------------- /test/unit/main.mocha.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a test suite', function(){ 4 | var $scope; 5 | 6 | beforeEach(module('simplicity')); 7 | 8 | beforeEach(inject(function($rootScope) { 9 | $scope = $rootScope.$new(); 10 | })); 11 | 12 | it('should define more than 5 awesome things', function() { 13 | var somethingTrue = true; 14 | expect(somethingTrue).to.equal(true); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/e2e/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('The main view', function () { 4 | 5 | beforeEach(function () { 6 | browser.get('http://localhost:3000/index.html'); 7 | }); 8 | 9 | it('list more than 5 awesome things', function () { 10 | element.all(by.repeater('awesomeThing in awesomeThings')).count().then(function(count) { 11 | expect(count > 5).toBeTruthy(); 12 | }); 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /app/components/simplicity.controller.js: -------------------------------------------------------------------------------- 1 | //template is defined inline in app.config.js 2 | simplicity.controller('AppCtrl', ['$scope', '$location', function ($scope, $location) { 3 | 4 | $scope.$on('$stateChangeSuccess', function (event, toState) { 5 | if (toState.name === 'main') { 6 | 7 | $scope.back = true; 8 | } else { 9 | $scope.back = false; 10 | } 11 | }); 12 | }]); -------------------------------------------------------------------------------- /app/assets/styles/mixins/_nav-vertical-align.scss: -------------------------------------------------------------------------------- 1 | // Navbar vertical align 2 | // 3 | // Vertically center elements in the navbar. 4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. 5 | 6 | @mixin navbar-vertical-align($element-height) { 7 | margin-top: (($navbar-height - $element-height) / 2); 8 | margin-bottom: (($navbar-height - $element-height) / 2); 9 | } 10 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": false, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 4, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "undef": true, 15 | "unused": false, 16 | "strict": true, 17 | "trailing": true, 18 | "smarttabs": true, 19 | "multistr": true, 20 | "globals": { 21 | "app": true, 22 | "angular": false, 23 | "L" : true, 24 | "$" : true 25 | } 26 | } -------------------------------------------------------------------------------- /app/assets/styles/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | @mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) { 4 | > li { 5 | > a, 6 | > span { 7 | padding: $padding-vertical $padding-horizontal; 8 | font-size: $font-size; 9 | } 10 | &:first-child { 11 | > a, 12 | > span { 13 | @include border-left-radius($border-radius); 14 | } 15 | } 16 | &:last-child { 17 | > a, 18 | > span { 19 | @include border-right-radius($border-radius); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // Single side border-radius 2 | 3 | @mixin border-top-radius($radius) { 4 | border-top-right-radius: $radius; 5 | border-top-left-radius: $radius; 6 | } 7 | @mixin border-right-radius($radius) { 8 | border-bottom-right-radius: $radius; 9 | border-top-right-radius: $radius; 10 | } 11 | @mixin border-bottom-radius($radius) { 12 | border-bottom-right-radius: $radius; 13 | border-bottom-left-radius: $radius; 14 | } 15 | @mixin border-left-radius($radius) { 16 | border-bottom-left-radius: $radius; 17 | border-top-left-radius: $radius; 18 | } 19 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_responsive-visibility.scss: -------------------------------------------------------------------------------- 1 | // Responsive utilities 2 | 3 | // 4 | // More easily include all the states for responsive-utilities.less. 5 | // [converter] $parent hack 6 | @mixin responsive-visibility($parent) { 7 | #{$parent} { 8 | display: block !important; 9 | } 10 | table#{$parent} { display: table; } 11 | tr#{$parent} { display: table-row !important; } 12 | th#{$parent}, 13 | td#{$parent} { display: table-cell !important; } 14 | } 15 | 16 | // [converter] $parent hack 17 | @mixin responsive-invisibility($parent) { 18 | #{$parent} { 19 | display: none !important; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/address-list/address-list.view.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | {{feature.properties.street_number}} {{feature.properties.street_name}} {{feature.properties.street_type}} 4 | , 5 | UNIT {{feature.properties.unit_number}}, 6 | {{feature.properties.zip_code}} 7 |

8 |
-------------------------------------------------------------------------------- /app/assets/styles/mixins/_panels.scss: -------------------------------------------------------------------------------- 1 | // Panels 2 | 3 | @mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) { 4 | border-color: $border; 5 | 6 | & > .panel-heading { 7 | color: $heading-text-color; 8 | background-color: $heading-bg-color; 9 | border-color: $heading-border; 10 | 11 | + .panel-collapse > .panel-body { 12 | border-top-color: $border; 13 | } 14 | .badge { 15 | color: $heading-bg-color; 16 | background-color: $heading-text-color; 17 | } 18 | } 19 | & > .panel-footer { 20 | + .panel-collapse > .panel-body { 21 | border-bottom-color: $border; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | *.sql 27 | *.sqlite 28 | 29 | # OS generated files # 30 | ###################### 31 | 32 | .DS_Store 33 | 34 | .DS_Store? 35 | ._* 36 | .Spotlight-V100 37 | .Trashes 38 | ehthumbs.db 39 | Thumbs.db 40 | 41 | # 42 | /dist 43 | /dev 44 | /node_modules 45 | -------------------------------------------------------------------------------- /app/assets/styles/_wells.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Wells 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .well { 8 | min-height: 20px; 9 | padding: 19px; 10 | margin-bottom: 20px; 11 | background-color: $well-bg; 12 | border: 1px solid $well-border; 13 | border-radius: $border-radius-base; 14 | @include box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); 15 | blockquote { 16 | border-color: #ddd; 17 | border-color: rgba(0,0,0,.15); 18 | } 19 | } 20 | 21 | // Sizes 22 | .well-lg { 23 | padding: 24px; 24 | border-radius: $border-radius-large; 25 | } 26 | .well-sm { 27 | padding: 9px; 28 | border-radius: $border-radius-small; 29 | } 30 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/owner/owner.details.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

We couldn't find any results.

5 |
6 |
7 | 8 |

Owner

9 | {{feature.properties.owner}} 10 |
{{feature.properties.owner_address}}
11 | {{feature.properties.owner_citystatezip}}
12 | 13 |
14 |
15 | 16 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/owner/owner.list.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

We couldn't find any results.

5 |
6 |
7 | 8 |

Owner

9 | {{feature.properties.owner}} 10 |
{{feature.properties.owner_address}}
11 | {{feature.properties.owner_citystatezip}}
12 | 13 |
14 |
15 | 16 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_hide-text.scss: -------------------------------------------------------------------------------- 1 | // CSS image replacement 2 | // 3 | // Heads up! v3 launched with with only `.hide-text()`, but per our pattern for 4 | // mixins being reused as classes with the same name, this doesn't hold up. As 5 | // of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. 6 | // 7 | // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 8 | 9 | // Deprecated as of v3.0.1 (will be removed in v4) 10 | @mixin hide-text() { 11 | font: #{0/0} a; 12 | color: transparent; 13 | text-shadow: none; 14 | background-color: transparent; 15 | border: 0; 16 | } 17 | 18 | // New mixin to use as of v3.0.1 19 | @mixin text-hide() { 20 | @include hide-text(); 21 | } 22 | -------------------------------------------------------------------------------- /app/assets/styles/_breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal; 8 | margin-bottom: $line-height-computed; 9 | list-style: none; 10 | background-color: $breadcrumb-bg; 11 | border-radius: $border-radius-base; 12 | 13 | > li { 14 | display: inline-block; 15 | 16 | + li:before { 17 | content: "#{$breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space 18 | padding: 0 5px; 19 | color: $breadcrumb-color; 20 | } 21 | } 22 | 23 | > .active { 24 | color: $breadcrumb-active-color; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // Clearfix 2 | // 3 | // For modern browsers 4 | // 1. The space content is one way to avoid an Opera bug when the 5 | // contenteditable attribute is included anywhere else in the document. 6 | // Otherwise it causes space to appear at the top and bottom of elements 7 | // that are clearfixed. 8 | // 2. The use of `table` rather than `block` is only necessary if using 9 | // `:before` to contain the top-margins of child elements. 10 | // 11 | // Source: http://nicolasgallagher.com/micro-clearfix-hack/ 12 | 13 | @mixin clearfix() { 14 | &:before, 15 | &:after { 16 | content: " "; // 1 17 | display: table; // 2 18 | } 19 | &:after { 20 | clear: both; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/assets/styles/_responsive-embed.scss: -------------------------------------------------------------------------------- 1 | // Embeds responsive 2 | // 3 | // Credit: Nicolas Gallagher and SUIT CSS. 4 | 5 | .embed-responsive { 6 | position: relative; 7 | display: block; 8 | height: 0; 9 | padding: 0; 10 | overflow: hidden; 11 | 12 | .embed-responsive-item, 13 | iframe, 14 | embed, 15 | object { 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | bottom: 0; 20 | height: 100%; 21 | width: 100%; 22 | border: 0; 23 | } 24 | 25 | // Modifier class for 16:9 aspect ratio 26 | &.embed-responsive-16by9 { 27 | padding-bottom: 56.25%; 28 | } 29 | 30 | // Modifier class for 4:3 aspect ratio 31 | &.embed-responsive-4by3 { 32 | padding-bottom: 75%; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | @mixin list-group-item-variant($state, $background, $color) { 4 | .list-group-item-#{$state} { 5 | color: $color; 6 | background-color: $background; 7 | 8 | // [converter] extracted a& to a.list-group-item-#{$state} 9 | } 10 | 11 | a.list-group-item-#{$state} { 12 | color: $color; 13 | 14 | .list-group-item-heading { 15 | color: inherit; 16 | } 17 | 18 | &:hover, 19 | &:focus { 20 | color: $color; 21 | background-color: darken($background, 5%); 22 | } 23 | &.active, 24 | &.active:hover, 25 | &.active:focus { 26 | color: #fff; 27 | background-color: $color; 28 | border-color: $color; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // An example configuration file. 2 | exports.config = { 3 | // The address of a running selenium server. 4 | //seleniumAddress: 'http://localhost:4444/wd/hub', 5 | seleniumServerJar: '../node_modules/protractor/selenium/selenium-server-standalone-2.43.1.jar', // Make use you check the version in the folder 6 | 7 | // Capabilities to be passed to the webdriver instance. 8 | capabilities: { 9 | 'browserName': 'chrome' 10 | }, 11 | 12 | // Spec patterns are relative to the current working directly when 13 | // protractor is called. 14 | specs: ['test/e2e/**/*.js'], 15 | 16 | // Options to be passed to Jasmine-node. 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(config) { 4 | 5 | config.set({ 6 | basePath : '..', 7 | 8 | files : [ 9 | 'test/dependencies/angular.js', 10 | 'test/dependencies/jquery-2.1.1.js', 11 | 'test/dependencies/**/*.js', 12 | 'app/**/*.js', 13 | 'test/unit/**/*.js' 14 | ], 15 | 16 | reporters: ['spec'], 17 | 18 | autoWatch : false, 19 | 20 | frameworks: ['mocha', 'chai', 'chai-as-promised'], 21 | 22 | browsers : ['PhantomJS'], 23 | 24 | plugins : [ 25 | 'karma-phantomjs-launcher', 26 | 'karma-chrome-launcher', 27 | 'karma-mocha', 28 | 'karma-chai', 29 | 'karma-chai-plugins', 30 | 'karma-spec-reporter' 31 | ] 32 | }); 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /unit-tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | 5 | var $ = require('gulp-load-plugins')(); 6 | 7 | var wiredep = require('wiredep'); 8 | 9 | gulp.task('test', function() { 10 | var bowerDeps = wiredep({ 11 | directory: 'src/bower_components', 12 | exclude: ['bootstrap-sass-official'], 13 | dependencies: true, 14 | devDependencies: true 15 | }); 16 | 17 | var testFiles = bowerDeps.js.concat([ 18 | 'src/{app,components}/**/*.js', 19 | 'test/unit/**/*.js' 20 | ]); 21 | 22 | return gulp.src(testFiles) 23 | .pipe($.karma({ 24 | configFile: 'test/karma.conf.js', 25 | action: 'run' 26 | })) 27 | .on('error', function(err) { 28 | // Make sure failed tests cause gulp to exit non-zero 29 | throw err; 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_table-row.scss: -------------------------------------------------------------------------------- 1 | // Tables 2 | 3 | @mixin table-row-variant($state, $background) { 4 | // Exact selectors below required to override `.table-striped` and prevent 5 | // inheritance to nested tables. 6 | .table > thead > tr, 7 | .table > tbody > tr, 8 | .table > tfoot > tr { 9 | > td.#{$state}, 10 | > th.#{$state}, 11 | &.#{$state} > td, 12 | &.#{$state} > th { 13 | background-color: $background; 14 | } 15 | } 16 | 17 | // Hover states for `.table-hover` 18 | // Note: this is not available for cells or rows within `thead` or `tfoot`. 19 | .table-hover > tbody > tr { 20 | > td.#{$state}:hover, 21 | > th.#{$state}:hover, 22 | &.#{$state}:hover > td, 23 | &:hover > .#{$state}, 24 | &.#{$state}:hover > th { 25 | background-color: darken($background, 5%); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/assets/styles/_close.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: ($font-size-base * 1.5); 9 | font-weight: $close-font-weight; 10 | line-height: 1; 11 | color: $close-color; 12 | text-shadow: $close-text-shadow; 13 | @include opacity(.2); 14 | 15 | &:hover, 16 | &:focus { 17 | color: $close-color; 18 | text-decoration: none; 19 | cursor: pointer; 20 | @include opacity(.5); 21 | } 22 | 23 | // [converter] extracted button& to button.close 24 | } 25 | 26 | // Additional properties for button version 27 | // iOS requires the button element instead of an anchor tag. 28 | // If you want the anchor version, it requires `href="#"`. 29 | button.close { 30 | padding: 0; 31 | cursor: pointer; 32 | background: transparent; 33 | border: 0; 34 | -webkit-appearance: none; 35 | } 36 | -------------------------------------------------------------------------------- /app/assets/styles/_component-animations.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | // Heads up! 6 | // 7 | // We don't use the `.opacity()` mixin here since it causes a bug with text 8 | // fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. 9 | 10 | .fade { 11 | opacity: 0; 12 | @include transition(opacity .15s linear); 13 | &.in { 14 | opacity: 1; 15 | } 16 | } 17 | 18 | .collapse { 19 | display: none; 20 | 21 | &.in { display: block; } 22 | // [converter] extracted tr&.in to tr.collapse.in 23 | // [converter] extracted tbody&.in to tbody.collapse.in 24 | } 25 | 26 | tr.collapse.in { display: table-row; } 27 | 28 | tbody.collapse.in { display: table-row-group; } 29 | 30 | .collapsing { 31 | position: relative; 32 | height: 0; 33 | overflow: hidden; 34 | @include transition(height .35s ease); 35 | } 36 | -------------------------------------------------------------------------------- /app/assets/styles/_app.scss: -------------------------------------------------------------------------------- 1 | .list-item-panel{ 2 | 3 | margin : 2px; 4 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); 5 | } 6 | 7 | a{ 8 | cursor: pointer; 9 | } 10 | 11 | .modal .modal-body { 12 | max-height: 500px; 13 | overflow-y: auto; 14 | } 15 | 16 | .leaflet-control-expand-map-interior{ 17 | width: 26px; 18 | height: 26px; 19 | display: block; 20 | padding: 2px; 21 | border-radius: 4px; 22 | -webkit-border-radius: 4px; 23 | -moz-border-radius: 4px; 24 | box-shadow: 0 1px 7px rgba(0, 0, 0, 0.65); 25 | cursor: pointer; 26 | text-align: center; 27 | background-color: #FFFFFF; 28 | } 29 | .leaflet-control-expand:before{ 30 | font-family: "fontawesome"; 31 | content : "\f0b2"; 32 | font-size: 17px; 33 | } 34 | 35 | .leaflet-control-collapse:before{ 36 | font-family: "fontawesome"; 37 | content : "\f066"; 38 | font-size: 17px; 39 | } 40 | 41 | .leaflet-control-command-interior:hover{ 42 | 43 | background-color: #F4F4F4; 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/assets/styles/_thumbnails.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Mixin and adjust the regular image class 7 | .thumbnail { 8 | display: block; 9 | padding: $thumbnail-padding; 10 | margin-bottom: $line-height-computed; 11 | line-height: $line-height-base; 12 | background-color: $thumbnail-bg; 13 | border: 1px solid $thumbnail-border; 14 | border-radius: $thumbnail-border-radius; 15 | @include transition(all .2s ease-in-out); 16 | 17 | > img, 18 | a > img { 19 | @include img-responsive(); 20 | margin-left: auto; 21 | margin-right: auto; 22 | } 23 | 24 | // [converter] extracted a&:hover, a&:focus, a&.active to a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active 25 | 26 | // Image captions 27 | .caption { 28 | padding: $thumbnail-caption-padding; 29 | color: $thumbnail-caption-color; 30 | } 31 | } 32 | 33 | // Add a hover state for linked versions only 34 | a.thumbnail:hover, 35 | a.thumbnail:focus, 36 | a.thumbnail.active { 37 | border-color: $link-color; 38 | } 39 | -------------------------------------------------------------------------------- /app/components/main/main.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

SimpliCity

6 |
city data simplified
7 |
8 | 9 |
10 |
11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 22 |
23 |
24 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/crime/crime.summary.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

We couldn't find any results.

5 |

Try expanding the time frame or extent of your search.

6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 |
TypeCount
17 | {{key}} 18 |
19 |

{{value.description}}

20 |
{{value.count}}
25 |
26 | -------------------------------------------------------------------------------- /app/assets/styles/_media.scss: -------------------------------------------------------------------------------- 1 | // Media objects 2 | // Source: http://stubbornella.org/content/?p=497 3 | // -------------------------------------------------- 4 | 5 | 6 | // Common styles 7 | // ------------------------- 8 | 9 | // Clear the floats 10 | .media, 11 | .media-body { 12 | overflow: hidden; 13 | zoom: 1; 14 | } 15 | 16 | // Proper spacing between instances of .media 17 | .media, 18 | .media .media { 19 | margin-top: 15px; 20 | } 21 | .media:first-child { 22 | margin-top: 0; 23 | } 24 | 25 | // For images and videos, set to block 26 | .media-object { 27 | display: block; 28 | } 29 | 30 | // Reset margins on headings for tighter default spacing 31 | .media-heading { 32 | margin: 0 0 5px; 33 | } 34 | 35 | 36 | // Media image alignment 37 | // ------------------------- 38 | 39 | .media { 40 | > .pull-left { 41 | margin-right: 10px; 42 | } 43 | > .pull-right { 44 | margin-left: 10px; 45 | } 46 | } 47 | 48 | 49 | // Media list variation 50 | // ------------------------- 51 | 52 | // Undo default ul/ol styles 53 | .media-list { 54 | padding-left: 0; 55 | list-style: none; 56 | } 57 | -------------------------------------------------------------------------------- /app/assets/styles/_pager.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Pager pagination 3 | // -------------------------------------------------- 4 | 5 | 6 | .pager { 7 | padding-left: 0; 8 | margin: $line-height-computed 0; 9 | list-style: none; 10 | text-align: center; 11 | @include clearfix(); 12 | li { 13 | display: inline; 14 | > a, 15 | > span { 16 | display: inline-block; 17 | padding: 5px 14px; 18 | background-color: $pager-bg; 19 | border: 1px solid $pager-border; 20 | border-radius: $pager-border-radius; 21 | } 22 | 23 | > a:hover, 24 | > a:focus { 25 | text-decoration: none; 26 | background-color: $pager-hover-bg; 27 | } 28 | } 29 | 30 | .next { 31 | > a, 32 | > span { 33 | float: right; 34 | } 35 | } 36 | 37 | .previous { 38 | > a, 39 | > span { 40 | float: left; 41 | } 42 | } 43 | 44 | .disabled { 45 | > a, 46 | > a:hover, 47 | > a:focus, 48 | > span { 49 | color: $pager-disabled-color; 50 | background-color: $pager-bg; 51 | cursor: not-allowed; 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/assets/styles/_utilities.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // Floats 7 | // ------------------------- 8 | 9 | .clearfix { 10 | @include clearfix(); 11 | } 12 | .center-block { 13 | @include center-block(); 14 | } 15 | .pull-right { 16 | float: right !important; 17 | } 18 | .pull-left { 19 | float: left !important; 20 | } 21 | 22 | 23 | // Toggling content 24 | // ------------------------- 25 | 26 | // Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1 27 | .hide { 28 | display: none !important; 29 | } 30 | .show { 31 | display: block !important; 32 | } 33 | .invisible { 34 | visibility: hidden; 35 | } 36 | .text-hide { 37 | @include text-hide(); 38 | } 39 | 40 | 41 | // Hide from screenreaders and browsers 42 | // 43 | // Credit: HTML5 Boilerplate 44 | 45 | .hidden { 46 | display: none !important; 47 | visibility: hidden !important; 48 | } 49 | 50 | 51 | // For Affix plugin 52 | // ------------------------- 53 | 54 | .affix { 55 | position: fixed; 56 | @include translate3d(0, 0, 0); 57 | } 58 | -------------------------------------------------------------------------------- /e2e-tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | 5 | var $ = require('gulp-load-plugins')(); 6 | 7 | var browserSync = require('browser-sync'); 8 | 9 | // Downloads the selenium webdriver 10 | gulp.task('webdriver-update', $.protractor.webdriver_update); 11 | 12 | gulp.task('webdriver-standalone', $.protractor.webdriver_standalone); 13 | 14 | gulp.task('protractor-only', ['webdriver-update', 'wiredep'], function (done) { 15 | var testFiles = [ 16 | 'test/e2e/**/*.js' 17 | ]; 18 | 19 | gulp.src(testFiles) 20 | .pipe($.protractor.protractor({ 21 | configFile: 'test/protractor.conf.js', 22 | })) 23 | .on('error', function (err) { 24 | // Make sure failed tests cause gulp to exit non-zero 25 | throw err; 26 | }) 27 | .on('end', function () { 28 | // Close browser sync server 29 | browserSync.exit(); 30 | done(); 31 | }); 32 | }); 33 | 34 | gulp.task('protractor', ['serve:e2e', 'protractor-only']); 35 | gulp.task('protractor:src', ['serve:e2e', 'protractor-only']); 36 | gulp.task('protractor:dist', ['serve:e2e-dist', 'protractor-only']); 37 | -------------------------------------------------------------------------------- /app/components/topics/sanitation.card.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Trash

4 |

Your trash is collected every {{card.trash}}.

5 |
6 |

Recycling

7 |

Recycling is collected every other week.

8 |

Your recycling will be collected {{card.recyclingSchedule.when}} on {{card.recycling}}.

9 |
10 |

Brush and Leaf Collection

11 |

Brush and leaves are collected every other week, and should be placed at the curb by 7 a.m. on Monday of your pickup week.

12 |

Your brush will be collected {{card.brushSchedule.when}}.

13 |
14 |

Bulky Item Collection

15 |

Call to schedule pickup 16 | (828) 251-1122. 17 | More Info. 18 |

19 |
20 |
-------------------------------------------------------------------------------- /app/components/topics/topic-components/development/development.summary.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

We couldn't find any results.

5 |

Try expanding the time frame or extent of your search.

6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 |
TypeCount
17 | {{key}} 18 |
19 |

{{value.description}}

20 |
{{value.count}}
25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/assets/styles/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------------------------------- 3 | 4 | // Utilities 5 | @import "mixins/hide-text"; 6 | @import "mixins/opacity"; 7 | @import "mixins/image"; 8 | @import "mixins/labels"; 9 | @import "mixins/reset-filter"; 10 | @import "mixins/resize"; 11 | @import "mixins/responsive-visibility"; 12 | @import "mixins/size"; 13 | @import "mixins/tab-focus"; 14 | @import "mixins/text-emphasis"; 15 | @import "mixins/text-overflow"; 16 | @import "mixins/vendor-prefixes"; 17 | 18 | // Components 19 | @import "mixins/alerts"; 20 | @import "mixins/buttons"; 21 | @import "mixins/panels"; 22 | @import "mixins/pagination"; 23 | @import "mixins/list-group"; 24 | @import "mixins/nav-divider"; 25 | @import "mixins/forms"; 26 | @import "mixins/progress-bar"; 27 | @import "mixins/table-row"; 28 | 29 | // Skins 30 | @import "mixins/background-variant"; 31 | @import "mixins/border-radius"; 32 | @import "mixins/gradients"; 33 | 34 | // Layout 35 | @import "mixins/clearfix"; 36 | @import "mixins/center-block"; 37 | @import "mixins/nav-vertical-align"; 38 | @import "mixins/grid-framework"; 39 | @import "mixins/grid"; 40 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 City of Asheville, NC 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 | -------------------------------------------------------------------------------- /app/assets/styles/_flaticon.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Flaticon"; 3 | src: url("fonts/flaticon.eot"); 4 | src: url("fonts/flaticon.eot#iefix") format("embedded-opentype"), 5 | url("fonts/flaticon.woff") format("woff"), 6 | url("fonts/flaticon.ttf") format("truetype"), 7 | url("fonts/flaticon.svg") format("svg"); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | [class^="flaticon-"]:before, [class*=" flaticon-"]:before, 12 | [class^="flaticon-"]:after, [class*=" flaticon-"]:after { 13 | font-family: Flaticon; 14 | font-size: 3em; 15 | font-style: normal; 16 | margin-left: 20px; 17 | }.flaticon-building33:before { 18 | content: "\e000"; 19 | } 20 | .flaticon-email20:before { 21 | content: "\e001"; 22 | } 23 | .flaticon-garbage5:before { 24 | content: "\e002"; 25 | } 26 | .flaticon-house112:before { 27 | content: "\e003"; 28 | } 29 | .flaticon-map104:before { 30 | content: "\e004"; 31 | } 32 | .flaticon-police19:before { 33 | content: "\e005"; 34 | } 35 | .flaticon-purchase1:before { 36 | content: "\e006"; 37 | } 38 | .flaticon-shovel1:before { 39 | content: "\e007"; 40 | } 41 | .flaticon-trash42:before { 42 | content: "\e008"; 43 | } 44 | -------------------------------------------------------------------------------- /app/assets/styles/_jumbotron.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Jumbotron 3 | // -------------------------------------------------- 4 | 5 | 6 | .jumbotron { 7 | padding: $jumbotron-padding; 8 | margin-bottom: $jumbotron-padding; 9 | color: $jumbotron-color; 10 | background-color: $jumbotron-bg; 11 | 12 | h1, 13 | .h1 { 14 | color: $jumbotron-heading-color; 15 | } 16 | p { 17 | margin-bottom: ($jumbotron-padding / 2); 18 | font-size: $jumbotron-font-size; 19 | font-weight: 200; 20 | } 21 | 22 | > hr { 23 | border-top-color: darken($jumbotron-bg, 10%); 24 | } 25 | 26 | .container & { 27 | border-radius: $border-radius-large; // Only round corners at higher resolutions if contained in a container 28 | } 29 | 30 | .container { 31 | max-width: 100%; 32 | } 33 | 34 | @media screen and (min-width: $screen-sm-min) { 35 | padding-top: ($jumbotron-padding * 1.6); 36 | padding-bottom: ($jumbotron-padding * 1.6); 37 | 38 | .container & { 39 | padding-left: ($jumbotron-padding * 2); 40 | padding-right: ($jumbotron-padding * 2); 41 | } 42 | 43 | h1, 44 | .h1 { 45 | font-size: ($font-size-base * 4.5); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/zoning/zoning.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Zoning

4 |
5 | District 6 | : 7 | 8 | {{zoning.zoningDistrict}} 9 | {{zoning.zoningDistrict}}, 10 | 11 | No City of Asheville Zoning 12 |
13 | 14 |
15 | Zoning Overlay 16 | : 17 | {{feature.properties.zoningOverlays}} 18 |
19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_buttons.scss: -------------------------------------------------------------------------------- 1 | // Button variants 2 | // 3 | // Easily pump out default styles, as well as :hover, :focus, :active, 4 | // and disabled options for all buttons 5 | 6 | @mixin button-variant($color, $background, $border) { 7 | color: $color; 8 | background-color: $background; 9 | border-color: lighten($border, 2%); 10 | 11 | &:hover, 12 | &:focus, 13 | &:active, 14 | &.active, 15 | .open > &.dropdown-toggle { 16 | color: $color; 17 | 18 | background-color: darken($background, 10%); 19 | border-color: darken($border, 12%); 20 | } 21 | &:active, 22 | &.active, 23 | .open > &.dropdown-toggle { 24 | background-image: none; 25 | } 26 | &.disabled, 27 | &[disabled], 28 | fieldset[disabled] & { 29 | &, 30 | &:hover, 31 | &:focus, 32 | &:active, 33 | &.active { 34 | background-color: $background; 35 | border-color: $border; 36 | } 37 | } 38 | 39 | .badge { 40 | color: $background; 41 | background-color: $color; 42 | } 43 | } 44 | 45 | // Button sizes 46 | @mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) { 47 | padding: $padding-vertical $padding-horizontal; 48 | font-size: $font-size; 49 | line-height: $line-height; 50 | border-radius: $border-radius; 51 | } 52 | -------------------------------------------------------------------------------- /app/assets/styles/_badges.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .badge { 8 | display: inline-block; 9 | min-width: 10px; 10 | padding: 3px 7px; 11 | font-size: $font-size-small; 12 | font-weight: $badge-font-weight; 13 | color: $badge-color; 14 | line-height: $badge-line-height; 15 | vertical-align: baseline; 16 | white-space: nowrap; 17 | text-align: center; 18 | background-color: $badge-bg; 19 | border-radius: $badge-border-radius; 20 | 21 | // Empty badges collapse automatically (not available in IE8) 22 | &:empty { 23 | display: none; 24 | } 25 | 26 | // Quick fix for badges in buttons 27 | .btn & { 28 | position: relative; 29 | top: -1px; 30 | } 31 | .btn-xs & { 32 | top: 0; 33 | padding: 1px 5px; 34 | } 35 | 36 | // [converter] extracted a& to a.badge 37 | 38 | // Account for badges in navs 39 | a.list-group-item.active > &, 40 | .nav-pills > .active > a > & { 41 | color: $badge-active-color; 42 | background-color: $badge-active-bg; 43 | } 44 | .nav-pills > li > a > & { 45 | margin-left: 3px; 46 | } 47 | } 48 | 49 | // Hover state, but only for links 50 | a.badge { 51 | &:hover, 52 | &:focus { 53 | color: $badge-link-hover-color; 54 | text-decoration: none; 55 | cursor: pointer; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/components/topics/topic-list/topic.list.controller.js: -------------------------------------------------------------------------------- 1 | simplicity.controller('TopicListCtrl', ['$scope', '$stateParams', '$state', 'Topics', 'AddressCache', 2 | function ($scope, $stateParams, $state, Topics, AddressCache) { 3 | $("html, body").animate({'scrollTop' : "0px"}); 4 | $scope.$on('$stateChangeSuccess', function (event, toState) { 5 | if (toState.name === 'main.topics') { 6 | $scope.back = true; 7 | } else { 8 | $scope.back = false; 9 | } 10 | }); 11 | 12 | //you can't have more tha 13 | $scope.heading = 'Topics for '; 14 | $scope.inTheCity = null; 15 | $scope.loading = false; 16 | $scope.anAddress = false; 17 | 18 | if($stateParams.searchtext){ 19 | $scope.searchText = $stateParams.searchtext; 20 | }else{ 21 | $scope.heading = 'Topics'; 22 | $scope.searchText = ""; 23 | } 24 | 25 | 26 | $scope.topics = Topics.getTopics($stateParams); 27 | 28 | 29 | if($stateParams.searchby === 'address'){ 30 | $scope.anAddress = true; 31 | $scope.loading = true; 32 | AddressCache.query() 33 | .then(function(data){ 34 | $scope.loading = false; 35 | if(data.inTheCity === true){ 36 | $scope.inTheCity = true; 37 | }else{ 38 | $scope.inTheCity = false; 39 | } 40 | }); 41 | } 42 | 43 | 44 | }]); -------------------------------------------------------------------------------- /app/assets/styles/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | @mixin img-responsive($display: block) { 10 | display: $display; 11 | width: 100% \9; // Force IE10 and below to size SVG images correctly 12 | max-width: 100%; // Part 1: Set a maximum relative to the parent 13 | height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching 14 | } 15 | 16 | 17 | // Retina image 18 | // 19 | // Short retina mixin for setting background-image and -size. Note that the 20 | // spelling of `min--moz-device-pixel-ratio` is intentional. 21 | @mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) { 22 | background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-1x}"), "#{$file-1x}")); 23 | 24 | @media 25 | only screen and (-webkit-min-device-pixel-ratio: 2), 26 | only screen and ( min--moz-device-pixel-ratio: 2), 27 | only screen and ( -o-min-device-pixel-ratio: 2/1), 28 | only screen and ( min-device-pixel-ratio: 2), 29 | only screen and ( min-resolution: 192dpi), 30 | only screen and ( min-resolution: 2dppx) { 31 | background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-2x}"), "#{$file-2x}")); 32 | background-size: $width-1x $height-1x; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/assets/styles/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // -------------------------------------------------- 4 | 5 | .label { 6 | display: inline; 7 | padding: .2em .6em .3em; 8 | font-size: 75%; 9 | font-weight: bold; 10 | line-height: 1; 11 | color: $label-color; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | border-radius: .25em; 16 | 17 | // [converter] extracted a& to a.label 18 | 19 | // Empty labels collapse automatically (not available in IE8) 20 | &:empty { 21 | display: none; 22 | } 23 | 24 | // Quick fix for labels in buttons 25 | .btn & { 26 | position: relative; 27 | top: -1px; 28 | } 29 | } 30 | 31 | // Add hover effects, but only for links 32 | a.label { 33 | &:hover, 34 | &:focus { 35 | color: $label-link-hover-color; 36 | text-decoration: none; 37 | cursor: pointer; 38 | } 39 | } 40 | 41 | // Colors 42 | // Contextual variations (linked labels get darker on :hover) 43 | 44 | .label-default { 45 | @include label-variant($label-default-bg); 46 | } 47 | 48 | .label-primary { 49 | @include label-variant($label-primary-bg); 50 | } 51 | 52 | .label-success { 53 | @include label-variant($label-success-bg); 54 | } 55 | 56 | .label-info { 57 | @include label-variant($label-info-bg); 58 | } 59 | 60 | .label-warning { 61 | @include label-variant($label-warning-bg); 62 | } 63 | 64 | .label-danger { 65 | @include label-variant($label-danger-bg); 66 | } 67 | -------------------------------------------------------------------------------- /app/assets/styles/styles.scss: -------------------------------------------------------------------------------- 1 | // Bootswatch 2 | //@import "variables_bootstrap"; 3 | @import "variables_bootswatch"; 4 | 5 | 6 | // Core variables and mixins 7 | //@import "variables_bootstrap"; 8 | @import "mixins"; 9 | 10 | 11 | 12 | 13 | // Reset and dependencies 14 | @import "normalize"; 15 | @import "print"; 16 | //@import "glyphicons"; 17 | 18 | // Core CSS 19 | @import "scaffolding"; 20 | @import "type"; 21 | @import "code"; 22 | @import "grid"; 23 | @import "tables"; 24 | @import "forms"; 25 | @import "buttons"; 26 | 27 | // Components 28 | @import "component-animations"; 29 | @import "dropdowns"; 30 | @import "button-groups"; 31 | @import "input-groups"; 32 | @import "navs"; 33 | @import "navbar"; 34 | @import "breadcrumbs"; 35 | @import "pagination"; 36 | @import "pager"; 37 | @import "labels"; 38 | @import "badges"; 39 | @import "jumbotron"; 40 | @import "thumbnails"; 41 | @import "alerts"; 42 | @import "progress-bars"; 43 | @import "media"; 44 | @import "list-group"; 45 | @import "panels"; 46 | @import "responsive-embed"; 47 | @import "wells"; 48 | @import "close"; 49 | 50 | // Components w/ JavaScript 51 | @import "modals"; 52 | @import "tooltip"; 53 | @import "popovers"; 54 | @import "carousel"; 55 | 56 | // Utility classes 57 | @import "utilities"; 58 | @import "responsive-utilities"; 59 | 60 | @import "bootswatch"; 61 | @import "flipping"; 62 | @import "angular-animations"; 63 | 64 | @import "app"; 65 | @import "leaflet-awesome-markers"; 66 | @import "flaticon"; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simplicity", 3 | "version": "0.0.1", 4 | "description": "UI to simlify city data", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Cameron Carlyle ccarlyle@ashevillenc.gov", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "angular-mocks": "^1.3.0", 13 | "browser-sync": "^1.5.7", 14 | "chai": "^1.9.2", 15 | "chai-as-promised": "^4.1.1", 16 | "del": "^0.1.3", 17 | "event-stream": "^3.1.7", 18 | "gulp": "^3.8.8", 19 | "gulp-concat": "^2.4.1", 20 | "gulp-filter": "^1.0.2", 21 | "gulp-flatten": "0.0.3", 22 | "gulp-inject": "^1.0.2", 23 | "gulp-jshint": "^1.8.5", 24 | "gulp-minify-html": "^0.1.6", 25 | "gulp-ng-annotate": "^0.3.3", 26 | "gulp-ng-html2js": "^0.1.8", 27 | "gulp-rename": "^1.2.0", 28 | "gulp-rev": "^1.1.0", 29 | "gulp-sass": "^2.3.2", 30 | "gulp-size": "^1.1.0", 31 | "gulp-uglify": "^1.0.1", 32 | "jshint-stylish": "^1.0.0", 33 | "karma": "^0.12.24", 34 | "karma-chai": "^0.1.0", 35 | "karma-chai-plugins": "^0.2.3", 36 | "karma-chrome-launcher": "^0.1.5", 37 | "karma-jasmine": "^0.1.5", 38 | "karma-mocha": "^0.1.9", 39 | "karma-phantomjs-launcher": "^0.1.4", 40 | "karma-spec-reporter": "0.0.13", 41 | "mocha": "^2.0.1", 42 | "node-sass": "^3.13.0", 43 | "require-dir": "^0.1.0", 44 | "sinon": "^1.10.3", 45 | "sinon-chai": "^2.6.0" 46 | }, 47 | "dependencies": {} 48 | } 49 | -------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.along.html: -------------------------------------------------------------------------------- 1 |
2 |

{{topicProperties.title}}

3 |
4 |
Download
5 |
Email
6 |
7 |
8 |
Download
9 |
Email
10 |
11 | 12 |
13 |
14 | 15 |
16 |

{{stateParams.searchtext}}.

17 |
18 |
19 |
20 |
-------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.at.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

{{topicProperties.title}}

4 | 5 |
6 |
Download
7 |
Email
8 |
9 |
10 |
Download
11 |
Email
12 |
13 |
14 |
15 | 16 |
17 |

{{stateParams.searchtext}}.

18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.in.html: -------------------------------------------------------------------------------- 1 |
2 |

{{topicProperties.title}}

3 | 4 |
5 |
Download
6 |
Email
7 |
8 |
9 |
Download
10 |
Email
11 |
12 | 13 |
14 |
15 | 16 |
17 |

{{stateParams.searchtext}} Neighborhood

18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.ownedby.html: -------------------------------------------------------------------------------- 1 |
2 |

{{topicProperties.title}}

3 | 4 |
5 |
Download
6 |
Email
7 |
8 |
9 |
Download
10 |
Email
11 |
12 | 13 |
14 |
15 | 16 |
17 |

{{stateParams.searchtext}}.

18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /app/assets/styles/_code.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and block) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | kbd, 9 | pre, 10 | samp { 11 | font-family: $font-family-monospace; 12 | } 13 | 14 | // Inline code 15 | code { 16 | padding: 2px 4px; 17 | font-size: 90%; 18 | color: $code-color; 19 | background-color: $code-bg; 20 | border-radius: $border-radius-base; 21 | } 22 | 23 | // User input typically entered via keyboard 24 | kbd { 25 | padding: 2px 4px; 26 | font-size: 90%; 27 | color: $kbd-color; 28 | background-color: $kbd-bg; 29 | border-radius: $border-radius-small; 30 | box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); 31 | 32 | kbd { 33 | padding: 0; 34 | font-size: 100%; 35 | box-shadow: none; 36 | } 37 | } 38 | 39 | // Blocks of code 40 | pre { 41 | display: block; 42 | padding: (($line-height-computed - 1) / 2); 43 | margin: 0 0 ($line-height-computed / 2); 44 | font-size: ($font-size-base - 1); // 14px to 13px 45 | line-height: $line-height-base; 46 | word-break: break-all; 47 | word-wrap: break-word; 48 | color: $pre-color; 49 | background-color: $pre-bg; 50 | border: 1px solid $pre-border-color; 51 | border-radius: $border-radius-base; 52 | 53 | // Account for some code outputs that place code tags in pre tags 54 | code { 55 | padding: 0; 56 | font-size: inherit; 57 | color: inherit; 58 | white-space: pre-wrap; 59 | background-color: transparent; 60 | border-radius: 0; 61 | } 62 | } 63 | 64 | // Enable scrollable blocks of code 65 | .pre-scrollable { 66 | max-height: $pre-scrollable-max-height; 67 | overflow-y: scroll; 68 | } 69 | -------------------------------------------------------------------------------- /app/simplicity.js: -------------------------------------------------------------------------------- 1 | //instatiate an AngularJS module and inject an dependancy modules 2 | var simplicity = angular.module('simplicity', ['angulartics', 'angulartics.google.analytics', 'simplicity.frontend.config', 'simplicity.backend.config', 'ui.router', 'ngAnimate']); 3 | 4 | //Configure application states and routes 5 | simplicity.config(function ($stateProvider, $urlRouterProvider, $httpProvider, $compileProvider) { 6 | 7 | $urlRouterProvider.when('/topics', '/topics/list'); 8 | $urlRouterProvider.when('', '/search'); 9 | $urlRouterProvider.when('/', '/search'); 10 | $urlRouterProvider.when('/a-zA-Z0-9/', ''); 11 | $urlRouterProvider.otherwise('/search'); 12 | 13 | 14 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|data|mailto|chrome-extension):/); 15 | 16 | 17 | //define states 18 | $stateProvider 19 | .state('main', { 20 | url: '', 21 | templateUrl: 'main/main.html', 22 | controller: 'MainCtrl' 23 | }) 24 | .state('main.search', { 25 | url: '/search?topic', 26 | templateUrl: 'search/search.html', 27 | controller: 'SearchCtrl' 28 | }) 29 | .state('main.topics', { 30 | url: '/topics', 31 | abstract: true, 32 | template: "
" 33 | }) 34 | .state('main.topics.list', { 35 | url: '/list?searchtext&searchby&id', 36 | templateUrl: 'topics/topic-list/topic.list.html', 37 | controller : 'TopicListCtrl' 38 | }) 39 | .state('main.topics.topic', { 40 | url: '/:topic?searchtext&searchby&id&view&timeframe&extent&type&mapcenter', 41 | templateUrl: 'topics/topic-single/topic.single.html', 42 | controller: 'TopicSingleCtrl' 43 | }); 44 | });//END config 45 | -------------------------------------------------------------------------------- /app/assets/styles/_grid.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Grid system 3 | // -------------------------------------------------- 4 | 5 | 6 | // Container widths 7 | // 8 | // Set the container width, and override it for fixed navbars in media queries. 9 | 10 | .container { 11 | @include container-fixed(); 12 | 13 | @media (min-width: $screen-sm-min) { 14 | width: $container-sm; 15 | } 16 | @media (min-width: $screen-md-min) { 17 | width: $container-md; 18 | } 19 | @media (min-width: $screen-lg-min) { 20 | width: $container-lg; 21 | } 22 | } 23 | 24 | 25 | // Fluid container 26 | // 27 | // Utilizes the mixin meant for fixed width containers, but without any defined 28 | // width for fluid, full width layouts. 29 | 30 | .container-fluid { 31 | @include container-fixed(); 32 | } 33 | 34 | 35 | // Row 36 | // 37 | // Rows contain and clear the floats of your columns. 38 | 39 | .row { 40 | @include make-row(); 41 | } 42 | 43 | 44 | // Columns 45 | // 46 | // Common styles for small and large grid columns 47 | 48 | @include make-grid-columns(); 49 | 50 | 51 | // Extra small grid 52 | // 53 | // Columns, offsets, pushes, and pulls for extra small devices like 54 | // smartphones. 55 | 56 | @include make-grid(xs); 57 | 58 | 59 | // Small grid 60 | // 61 | // Columns, offsets, pushes, and pulls for the small device range, from phones 62 | // to tablets. 63 | 64 | @media (min-width: $screen-sm-min) { 65 | @include make-grid(sm); 66 | } 67 | 68 | 69 | // Medium grid 70 | // 71 | // Columns, offsets, pushes, and pulls for the desktop device range. 72 | 73 | @media (min-width: $screen-md-min) { 74 | @include make-grid(md); 75 | } 76 | 77 | 78 | // Large grid 79 | // 80 | // Columns, offsets, pushes, and pulls for the large desktop device range. 81 | 82 | @media (min-width: $screen-lg-min) { 83 | @include make-grid(lg); 84 | } 85 | -------------------------------------------------------------------------------- /app/assets/styles/_alerts.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Alerts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // ------------------------- 8 | 9 | .alert { 10 | padding: $alert-padding; 11 | margin-bottom: $line-height-computed; 12 | border: 1px solid transparent; 13 | border-radius: $alert-border-radius; 14 | 15 | // Headings for larger alerts 16 | h4 { 17 | margin-top: 0; 18 | // Specified for the h4 to prevent conflicts of changing $headings-color 19 | color: inherit; 20 | } 21 | // Provide class for links that match alerts 22 | .alert-link { 23 | font-weight: $alert-link-font-weight; 24 | } 25 | 26 | // Improve alignment and spacing of inner content 27 | > p, 28 | > ul { 29 | margin-bottom: 0; 30 | } 31 | > p + p { 32 | margin-top: 5px; 33 | } 34 | } 35 | 36 | // Dismissible alerts 37 | // 38 | // Expand the right padding and account for the close button's positioning. 39 | 40 | .alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. 41 | .alert-dismissible { 42 | padding-right: ($alert-padding + 20); 43 | 44 | // Adjust close link position 45 | .close { 46 | position: relative; 47 | top: -2px; 48 | right: -21px; 49 | color: inherit; 50 | } 51 | } 52 | 53 | // Alternate styles 54 | // 55 | // Generate contextual modifier classes for colorizing the alert. 56 | 57 | .alert-success { 58 | @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); 59 | } 60 | .alert-info { 61 | @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); 62 | } 63 | .alert-warning { 64 | @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); 65 | } 66 | .alert-danger { 67 | @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); 68 | } 69 | -------------------------------------------------------------------------------- /app/assets/styles/_print.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Basic print styles 3 | // -------------------------------------------------- 4 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css 5 | 6 | @media print { 7 | 8 | * { 9 | text-shadow: none !important; 10 | color: #000 !important; // Black prints faster: h5bp.com/s 11 | background: transparent !important; 12 | box-shadow: none !important; 13 | } 14 | 15 | a, 16 | a:visited { 17 | text-decoration: underline; 18 | } 19 | 20 | a[href]:after { 21 | content: " (" attr(href) ")"; 22 | } 23 | 24 | abbr[title]:after { 25 | content: " (" attr(title) ")"; 26 | } 27 | 28 | // Don't show links for images, or javascript/internal links 29 | a[href^="javascript:"]:after, 30 | a[href^="#"]:after { 31 | content: ""; 32 | } 33 | 34 | pre, 35 | blockquote { 36 | border: 1px solid #999; 37 | page-break-inside: avoid; 38 | } 39 | 40 | thead { 41 | display: table-header-group; // h5bp.com/t 42 | } 43 | 44 | tr, 45 | img { 46 | page-break-inside: avoid; 47 | } 48 | 49 | img { 50 | max-width: 100% !important; 51 | } 52 | 53 | p, 54 | h2, 55 | h3 { 56 | orphans: 3; 57 | widows: 3; 58 | } 59 | 60 | h2, 61 | h3 { 62 | page-break-after: avoid; 63 | } 64 | 65 | // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245 66 | // Once fixed, we can just straight up remove this. 67 | select { 68 | background: #fff !important; 69 | } 70 | 71 | // Bootstrap components 72 | .navbar { 73 | display: none; 74 | } 75 | .table { 76 | td, 77 | th { 78 | background-color: #fff !important; 79 | } 80 | } 81 | .btn, 82 | .dropup > .btn { 83 | > .caret { 84 | border-top-color: #000 !important; 85 | } 86 | } 87 | .label { 88 | border: 1px solid #000; 89 | } 90 | 91 | .table { 92 | border-collapse: collapse !important; 93 | } 94 | .table-bordered { 95 | th, 96 | td { 97 | border: 1px solid #ddd !important; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.during.along.html: -------------------------------------------------------------------------------- 1 |
2 |

{{topicProperties.title}}

3 |
4 |
Download
5 |
Email
6 |
7 |
8 |
Download
9 |
Email
10 |
11 | 12 |
13 | 14 |
15 | 16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |

{{stateParams.searchtext}}.

24 |
25 |
26 |
27 |
-------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.during.in.html: -------------------------------------------------------------------------------- 1 |
2 |

{{topicProperties.title}}

3 |
4 |
Download
5 |
Email
6 |
7 |
8 |
Download
9 |
Email
10 |
11 | 12 |
13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 |

{{stateParams.searchtext}} Neighborhood

23 |
24 |
25 |
26 |
-------------------------------------------------------------------------------- /app/components/topics/topic-components/street-maintenance/street.maintenance.list.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Zoom to this centerline on the map 4 |
5 |
6 |
Name
7 |

8 | {{feature.properties.full_street_name}} 9 |

10 |
11 | 12 |
13 |
Centerline ID
14 |

15 | {{feature.properties.centerline_id}} 16 |

17 |
18 | 19 | 20 | 21 |
22 |
Responsibility
23 |

24 | {{feature.properties.street_responsibility}} 25 |

26 | 27 |

28 | {{feature.properties.street_responsibility}} 29 |

30 |
31 | 32 |

33 | Click here to contact the maintenance authority 34 |

35 |
36 |
37 | 38 | 39 |
40 |
41 | 42 | 43 | 44 |
-------------------------------------------------------------------------------- /app/assets/styles/_pagination.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Pagination (multiple pages) 3 | // -------------------------------------------------- 4 | .pagination { 5 | display: inline-block; 6 | padding-left: 0; 7 | margin: $line-height-computed 0; 8 | border-radius: $border-radius-base; 9 | 10 | > li { 11 | display: inline; // Remove list-style and block-level defaults 12 | > a, 13 | > span { 14 | position: relative; 15 | float: left; // Collapse white-space 16 | padding: $padding-base-vertical $padding-base-horizontal; 17 | line-height: $line-height-base; 18 | text-decoration: none; 19 | color: $pagination-color; 20 | background-color: $pagination-bg; 21 | border: 1px solid $pagination-border; 22 | margin-left: -1px; 23 | } 24 | &:first-child { 25 | > a, 26 | > span { 27 | margin-left: 0; 28 | @include border-left-radius($border-radius-base); 29 | } 30 | } 31 | &:last-child { 32 | > a, 33 | > span { 34 | @include border-right-radius($border-radius-base); 35 | } 36 | } 37 | } 38 | 39 | > li > a, 40 | > li > span { 41 | &:hover, 42 | &:focus { 43 | color: $pagination-hover-color; 44 | background-color: $pagination-hover-bg; 45 | border-color: $pagination-hover-border; 46 | } 47 | } 48 | 49 | > .active > a, 50 | > .active > span { 51 | &, 52 | &:hover, 53 | &:focus { 54 | z-index: 2; 55 | color: $pagination-active-color; 56 | background-color: $pagination-active-bg; 57 | border-color: $pagination-active-border; 58 | cursor: default; 59 | } 60 | } 61 | 62 | > .disabled { 63 | > span, 64 | > span:hover, 65 | > span:focus, 66 | > a, 67 | > a:hover, 68 | > a:focus { 69 | color: $pagination-disabled-color; 70 | background-color: $pagination-disabled-bg; 71 | border-color: $pagination-disabled-border; 72 | cursor: not-allowed; 73 | } 74 | } 75 | } 76 | 77 | // Sizing 78 | // -------------------------------------------------- 79 | 80 | // Large 81 | .pagination-lg { 82 | @include pagination-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $border-radius-large); 83 | } 84 | 85 | // Small 86 | .pagination-sm { 87 | @include pagination-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $border-radius-small); 88 | } 89 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/trash-collection/trash.factory.js: -------------------------------------------------------------------------------- 1 | simplicity.factory('Trash', ['$q', '$stateParams', 'AddressCache', 2 | function($q, $stateParams, AddressCache){ 3 | 4 | var Trash = {}; 5 | 6 | var topicProperties = { 7 | 'name' : 'trash', 8 | 'title' : 'Trash Collection', 9 | 'plural' : 'trash collection', 10 | 'searchForText' : 'an address', 11 | 'position' : 4, 12 | 'downloadable' : false, 13 | 'inTheCityOnly' : true, 14 | 'searchby' : { 15 | 'address' : { 16 | 'params' : { 17 | 'type' : null, 18 | 'timeframe' : null, 19 | 'extent' : null, 20 | 'view' : 'simple', 21 | 'validViews' : ['simple'] 22 | }, 23 | 'prepositions' : { 24 | 'searchby' : 'at', 25 | }, 26 | 'requiredParams' : [], 27 | 'headerTemplate' : 'topics/topic-headers/topic.header.at.html', 28 | }, 29 | 'google_places' : { 30 | 'params' : { 31 | 'type' : null, 32 | 'timeframe' : null, 33 | 'extent' : null, 34 | 'view' : 'simple', 35 | 'validViews' : ['simple'] 36 | }, 37 | 'prepositions' : { 38 | 'searchby' : 'at', 39 | }, 40 | 'requiredParams' : [], 41 | 'headerTemplate' : 'topics/topic-headers/topic.header.at.html', 42 | } 43 | }, 44 | 'views' : { 45 | 'simple' : {'label' : 'Simple View', 'template' : 'topics/topic-components/trash-collection/trash.collection.simple.view.html'} 46 | }, 47 | 'simpleViewTemplate' : 'topics/topic-components/trash-collection/trash-collection.view.html', 48 | 'iconClass' : 'flaticon-garbage5', 49 | 'linkTopics' : ['recycling', 'property'], 50 | 'questions' : { 51 | 'topic' : 'Do you want to know when trash is collected?', 52 | 'address' : 'Do you want to know when trash is collected at this address?' 53 | } 54 | }; 55 | 56 | Trash.build = function(){ 57 | var addressCache = AddressCache.get(); 58 | var q = $q.defer(); 59 | var trash = { 60 | 'trash' : addressCache.trash, 61 | 'searchGeojson' : addressCache.searchGeojson 62 | }; 63 | 64 | q.resolve(trash); 65 | return q.promise; 66 | }; 67 | 68 | Trash.getTopicProperties = function(){ 69 | return topicProperties; 70 | }; 71 | 72 | //****Return the factory object****// 73 | return Trash; 74 | 75 | 76 | 77 | 78 | }]); //END Trash factory function 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_grid-framework.scss: -------------------------------------------------------------------------------- 1 | // Framework grid generation 2 | // 3 | // Used only by Bootstrap to generate the correct number of grid classes given 4 | // any value of `$grid-columns`. 5 | 6 | // [converter] This is defined recursively in LESS, but Sass supports real loops 7 | @mixin make-grid-columns($i: 1, $list: ".col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}") { 8 | @for $i from (1 + 1) through $grid-columns { 9 | $list: "#{$list}, .col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}"; 10 | } 11 | #{$list} { 12 | position: relative; 13 | // Prevent columns from collapsing when empty 14 | min-height: 1px; 15 | // Inner gutter via padding 16 | padding-left: ($grid-gutter-width / 2); 17 | padding-right: ($grid-gutter-width / 2); 18 | } 19 | } 20 | 21 | 22 | // [converter] This is defined recursively in LESS, but Sass supports real loops 23 | @mixin float-grid-columns($class, $i: 1, $list: ".col-#{$class}-#{$i}") { 24 | @for $i from (1 + 1) through $grid-columns { 25 | $list: "#{$list}, .col-#{$class}-#{$i}"; 26 | } 27 | #{$list} { 28 | float: left; 29 | } 30 | } 31 | 32 | 33 | @mixin calc-grid-column($index, $class, $type) { 34 | @if ($type == width) and ($index > 0) { 35 | .col-#{$class}-#{$index} { 36 | width: percentage(($index / $grid-columns)); 37 | } 38 | } 39 | @if ($type == push) and ($index > 0) { 40 | .col-#{$class}-push-#{$index} { 41 | left: percentage(($index / $grid-columns)); 42 | } 43 | } 44 | @if ($type == push) and ($index == 0) { 45 | .col-#{$class}-push-0 { 46 | left: auto; 47 | } 48 | } 49 | @if ($type == pull) and ($index > 0) { 50 | .col-#{$class}-pull-#{$index} { 51 | right: percentage(($index / $grid-columns)); 52 | } 53 | } 54 | @if ($type == pull) and ($index == 0) { 55 | .col-#{$class}-pull-0 { 56 | right: auto; 57 | } 58 | } 59 | @if ($type == offset) { 60 | .col-#{$class}-offset-#{$index} { 61 | margin-left: percentage(($index / $grid-columns)); 62 | } 63 | } 64 | } 65 | 66 | // [converter] This is defined recursively in LESS, but Sass supports real loops 67 | @mixin loop-grid-columns($columns, $class, $type) { 68 | @for $i from 0 through $columns { 69 | @include calc-grid-column($i, $class, $type); 70 | } 71 | } 72 | 73 | 74 | // Create grid for specific class 75 | @mixin make-grid($class) { 76 | @include float-grid-columns($class); 77 | @include loop-grid-columns($grid-columns, $class, width); 78 | @include loop-grid-columns($grid-columns, $class, pull); 79 | @include loop-grid-columns($grid-columns, $class, push); 80 | @include loop-grid-columns($grid-columns, $class, offset); 81 | } 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | simplicity-ui 2 | ============= 3 | 4 | View the site here: 5 | http://cityofasheville.github.io/simplicity-ui 6 | 7 | A webapp to provide simple access to city data. Built on an AngularJS frontend with an ArcGIS REST API on the back. 8 | 9 | 10 | ##GETTING STARTED 11 | 12 | ###Installation 13 | 14 | You'll need Node.js to work on SimpliCity. 15 | 16 | 1. Clone the repo, and cd into that directory 17 | 2. Install dependencies with npm 18 | 19 | npm install 20 | 3. You can serve it locally with gulp, and it'll watch for changes 21 | 22 | gulp serve 23 | 24 | ###Configuration 25 | ####There are 2 main configuration files: 26 | 27 | #####app/simplicity.frontend.config.js 28 | 29 | An assortment of frontend configuration stuff like colors, links, and drop-down values that probably can be abstracted and cleaned up. 30 | 31 | #####app/simplicity.backend.config.js 32 | 33 | Defines all the URIs to the ArcGIS feature services used by the app. It includes the simplicityBackend factory also exposes two methods in particular: 34 | 35 | ######simplicityBackend.simplicitySearch 36 | All search functionality is routed through this method. 37 | ######simplicityBackend.simplicityQuery 38 | All queries are routed through this method. 39 | 40 | An adapter, like app/adapters/simplicity.arcgis.rest.api.adapter.js, that contains set of queries defined as angular constants, and factory that exposes methods for querying an API, in this case the ArcGIS REST API, must be injected into the simplicityBackend factory. 41 | 42 | Additionally, each topic contains a set of views and a factory that is used to build that topic. 43 | 44 | 45 | #License 46 | The MIT License (MIT) 47 | 48 | Copyright (c) 2015 City of Asheville, NC 49 | 50 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 51 | 52 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 53 | 54 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 55 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/crime/crime.list.view.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

We couldn't find any results.

5 |

Try expanding the time frame or extent of your search.

6 |
7 |
8 |
9 | 10 |

{{feature.properties.offense}}

11 |

{{feature.properties.description}}

12 | Zoom to this crime on the map 13 |
14 |
15 | 16 |

{{feature.properties.address}}

17 |
18 |
19 | 20 |

{{feature.properties.thedate|date}}

21 |
22 |
23 | 24 | 38 |
39 |
40 |

Case Number: {{feature.properties.casenumber}}

41 |
42 |
43 |

Law Beat: {{feature.properties.law_beat}}

44 |

45 |
46 |
47 |

Severity: {{feature.properties.severity}}

48 |
49 |
50 | 51 |

Show More

52 |

Show Less

53 |
54 |
55 |
-------------------------------------------------------------------------------- /app/assets/styles/_progress-bars.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Progress bars 3 | // -------------------------------------------------- 4 | 5 | 6 | // Bar animations 7 | // ------------------------- 8 | 9 | // WebKit 10 | @-webkit-keyframes progress-bar-stripes { 11 | from { background-position: 40px 0; } 12 | to { background-position: 0 0; } 13 | } 14 | 15 | // Spec and IE10+ 16 | @keyframes progress-bar-stripes { 17 | from { background-position: 40px 0; } 18 | to { background-position: 0 0; } 19 | } 20 | 21 | 22 | 23 | // Bar itself 24 | // ------------------------- 25 | 26 | // Outer container 27 | .progress { 28 | overflow: hidden; 29 | height: $line-height-computed; 30 | margin-bottom: $line-height-computed; 31 | background-color: $progress-bg; 32 | border-radius: $border-radius-base; 33 | @include box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); 34 | } 35 | 36 | // Bar of progress 37 | .progress-bar { 38 | float: left; 39 | width: 0%; 40 | height: 100%; 41 | font-size: $font-size-small; 42 | line-height: $line-height-computed; 43 | color: $progress-bar-color; 44 | text-align: center; 45 | background-color: $progress-bar-bg; 46 | @include box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); 47 | @include transition(width .6s ease); 48 | } 49 | 50 | // Striped bars 51 | // 52 | // `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the 53 | // `.progress-bar-striped` class, which you just add to an existing 54 | // `.progress-bar`. 55 | .progress-striped .progress-bar, 56 | .progress-bar-striped { 57 | @include gradient-striped(); 58 | background-size: 40px 40px; 59 | } 60 | 61 | // Call animation for the active one 62 | // 63 | // `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the 64 | // `.progress-bar.active` approach. 65 | .progress.active .progress-bar, 66 | .progress-bar.active { 67 | @include animation(progress-bar-stripes 2s linear infinite); 68 | } 69 | 70 | // Account for lower percentages 71 | .progress-bar { 72 | &[aria-valuenow="1"], 73 | &[aria-valuenow="2"] { 74 | min-width: 30px; 75 | } 76 | 77 | &[aria-valuenow="0"] { 78 | color: $gray-light; 79 | min-width: 30px; 80 | background-color: transparent; 81 | background-image: none; 82 | box-shadow: none; 83 | } 84 | } 85 | 86 | 87 | 88 | // Variations 89 | // ------------------------- 90 | 91 | .progress-bar-success { 92 | @include progress-bar-variant($progress-bar-success-bg); 93 | } 94 | 95 | .progress-bar-info { 96 | @include progress-bar-variant($progress-bar-info-bg); 97 | } 98 | 99 | .progress-bar-warning { 100 | @include progress-bar-variant($progress-bar-warning-bg); 101 | } 102 | 103 | .progress-bar-danger { 104 | @include progress-bar-variant($progress-bar-danger-bg); 105 | } 106 | -------------------------------------------------------------------------------- /app/assets/styles/_leaflet-awesome-markers.scss: -------------------------------------------------------------------------------- 1 | /* 2 | Author: L. Voogdt 3 | License: MIT 4 | Version: 1.0 5 | */ 6 | 7 | /* Marker setup */ 8 | .awesome-marker { 9 | background: url('images/markers-soft.png') no-repeat 0 0; 10 | width: 35px; 11 | height: 46px; 12 | position:absolute; 13 | left:0; 14 | top:0; 15 | display: block; 16 | text-align: center; 17 | } 18 | 19 | .awesome-marker-shadow { 20 | background: url('images/markers-shadow.png') no-repeat 0 0; 21 | width: 36px; 22 | height: 16px; 23 | } 24 | 25 | /* Retina displays */ 26 | @media (min--moz-device-pixel-ratio: 1.5),(-o-min-device-pixel-ratio: 3/2), 27 | (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5),(min-resolution: 1.5dppx) { 28 | .awesome-marker { 29 | background-image: url('images/markers-soft@2x.png'); 30 | background-size: 720px 46px; 31 | } 32 | .awesome-marker-shadow { 33 | background-image: url('images/markers-shadow@2x.png'); 34 | background-size: 35px 16px; 35 | } 36 | } 37 | 38 | .awesome-marker i { 39 | color: #333; 40 | margin-top: 10px; 41 | display: inline-block; 42 | font-size: 14px; 43 | } 44 | 45 | .awesome-marker .icon-white { 46 | color: #fff; 47 | } 48 | 49 | /* Colors */ 50 | .awesome-marker-icon-red { 51 | background-position: 0 0; 52 | } 53 | 54 | .awesome-marker-icon-darkred { 55 | background-position: -180px 0; 56 | } 57 | 58 | .awesome-marker-icon-lightred { 59 | background-position: -360px 0; 60 | } 61 | 62 | .awesome-marker-icon-orange { 63 | background-position: -36px 0; 64 | } 65 | 66 | .awesome-marker-icon-beige { 67 | background-position: -396px 0; 68 | } 69 | 70 | .awesome-marker-icon-green { 71 | background-position: -72px 0; 72 | } 73 | 74 | .awesome-marker-icon-darkgreen { 75 | background-position: -252px 0; 76 | } 77 | 78 | .awesome-marker-icon-lightgreen { 79 | background-position: -432px 0; 80 | } 81 | 82 | .awesome-marker-icon-blue { 83 | background-position: -108px 0; 84 | } 85 | 86 | .awesome-marker-icon-darkblue { 87 | background-position: -216px 0; 88 | } 89 | 90 | .awesome-marker-icon-lightblue { 91 | background-position: -468px 0; 92 | } 93 | 94 | .awesome-marker-icon-purple { 95 | background-position: -144px 0; 96 | } 97 | 98 | .awesome-marker-icon-darkpurple { 99 | background-position: -288px 0; 100 | } 101 | 102 | .awesome-marker-icon-pink { 103 | background-position: -504px 0; 104 | } 105 | 106 | .awesome-marker-icon-cadetblue { 107 | background-position: -324px 0; 108 | } 109 | 110 | .awesome-marker-icon-white { 111 | background-position: -574px 0; 112 | } 113 | 114 | .awesome-marker-icon-gray { 115 | background-position: -648px 0; 116 | } 117 | 118 | .awesome-marker-icon-lightgray { 119 | background-position: -612px 0; 120 | } 121 | 122 | .awesome-marker-icon-black { 123 | background-position: -682px 0; 124 | } -------------------------------------------------------------------------------- /app/assets/images/leaflet.awesome-markers.css: -------------------------------------------------------------------------------- 1 | /* 2 | Author: L. Voogdt 3 | License: MIT 4 | Version: 1.0 5 | */ 6 | 7 | /* Marker setup */ 8 | .awesome-marker { 9 | background: url('images/markers-soft.png') no-repeat 0 0; 10 | width: 35px; 11 | height: 46px; 12 | position:absolute; 13 | left:0; 14 | top:0; 15 | display: block; 16 | text-align: center; 17 | } 18 | 19 | .awesome-marker-shadow { 20 | background: url('images/markers-shadow.png') no-repeat 0 0; 21 | width: 36px; 22 | height: 16px; 23 | } 24 | 25 | /* Retina displays */ 26 | @media (min--moz-device-pixel-ratio: 1.5),(-o-min-device-pixel-ratio: 3/2), 27 | (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5),(min-resolution: 1.5dppx) { 28 | .awesome-marker { 29 | background-image: url('images/markers-soft@2x.png'); 30 | background-size: 720px 46px; 31 | } 32 | .awesome-marker-shadow { 33 | background-image: url('images/markers-shadow@2x.png'); 34 | background-size: 35px 16px; 35 | } 36 | } 37 | 38 | .awesome-marker i { 39 | color: #333; 40 | margin-top: 10px; 41 | display: inline-block; 42 | font-size: 14px; 43 | } 44 | 45 | .awesome-marker .icon-white { 46 | color: #fff; 47 | } 48 | 49 | /* Colors */ 50 | .awesome-marker-icon-red { 51 | background-position: 0 0; 52 | } 53 | 54 | .awesome-marker-icon-darkred { 55 | background-position: -180px 0; 56 | } 57 | 58 | .awesome-marker-icon-lightred { 59 | background-position: -360px 0; 60 | } 61 | 62 | .awesome-marker-icon-orange { 63 | background-position: -36px 0; 64 | } 65 | 66 | .awesome-marker-icon-beige { 67 | background-position: -396px 0; 68 | } 69 | 70 | .awesome-marker-icon-green { 71 | background-position: -72px 0; 72 | } 73 | 74 | .awesome-marker-icon-darkgreen { 75 | background-position: -252px 0; 76 | } 77 | 78 | .awesome-marker-icon-lightgreen { 79 | background-position: -432px 0; 80 | } 81 | 82 | .awesome-marker-icon-blue { 83 | background-position: -108px 0; 84 | } 85 | 86 | .awesome-marker-icon-darkblue { 87 | background-position: -216px 0; 88 | } 89 | 90 | .awesome-marker-icon-lightblue { 91 | background-position: -468px 0; 92 | } 93 | 94 | .awesome-marker-icon-purple { 95 | background-position: -144px 0; 96 | } 97 | 98 | .awesome-marker-icon-darkpurple { 99 | background-position: -288px 0; 100 | } 101 | 102 | .awesome-marker-icon-pink { 103 | background-position: -504px 0; 104 | } 105 | 106 | .awesome-marker-icon-cadetblue { 107 | background-position: -324px 0; 108 | } 109 | 110 | .awesome-marker-icon-white { 111 | background-position: -574px 0; 112 | } 113 | 114 | .awesome-marker-icon-gray { 115 | background-position: -648px 0; 116 | } 117 | 118 | .awesome-marker-icon-lightgray { 119 | background-position: -612px 0; 120 | } 121 | 122 | .awesome-marker-icon-black { 123 | background-position: -682px 0; 124 | } 125 | -------------------------------------------------------------------------------- /app/components/topics/topic-headers/topic.header.during.within.of.html: -------------------------------------------------------------------------------- 1 |
2 |

{{topicProperties.title}}

3 | 4 |
5 |
Download
6 |
Email
7 |
8 |
9 |
Download
10 |
Email
11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 | 29 |
30 |

{{stateParams.searchtext}}.

31 |
32 |
33 |
34 | 35 |
-------------------------------------------------------------------------------- /app/assets/styles/_tooltip.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Tooltips 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .tooltip { 8 | position: absolute; 9 | z-index: $zindex-tooltip; 10 | display: block; 11 | visibility: visible; 12 | font-size: $font-size-small; 13 | line-height: 1.4; 14 | @include opacity(0); 15 | 16 | &.in { @include opacity($tooltip-opacity); } 17 | &.top { margin-top: -3px; padding: $tooltip-arrow-width 0; } 18 | &.right { margin-left: 3px; padding: 0 $tooltip-arrow-width; } 19 | &.bottom { margin-top: 3px; padding: $tooltip-arrow-width 0; } 20 | &.left { margin-left: -3px; padding: 0 $tooltip-arrow-width; } 21 | } 22 | 23 | // Wrapper for the tooltip content 24 | .tooltip-inner { 25 | max-width: $tooltip-max-width; 26 | padding: 3px 8px; 27 | color: $tooltip-color; 28 | text-align: center; 29 | text-decoration: none; 30 | background-color: $tooltip-bg; 31 | border-radius: $border-radius-base; 32 | } 33 | 34 | // Arrows 35 | .tooltip-arrow { 36 | position: absolute; 37 | width: 0; 38 | height: 0; 39 | border-color: transparent; 40 | border-style: solid; 41 | } 42 | .tooltip { 43 | &.top .tooltip-arrow { 44 | bottom: 0; 45 | left: 50%; 46 | margin-left: -$tooltip-arrow-width; 47 | border-width: $tooltip-arrow-width $tooltip-arrow-width 0; 48 | border-top-color: $tooltip-arrow-color; 49 | } 50 | &.top-left .tooltip-arrow { 51 | bottom: 0; 52 | left: $tooltip-arrow-width; 53 | border-width: $tooltip-arrow-width $tooltip-arrow-width 0; 54 | border-top-color: $tooltip-arrow-color; 55 | } 56 | &.top-right .tooltip-arrow { 57 | bottom: 0; 58 | right: $tooltip-arrow-width; 59 | border-width: $tooltip-arrow-width $tooltip-arrow-width 0; 60 | border-top-color: $tooltip-arrow-color; 61 | } 62 | &.right .tooltip-arrow { 63 | top: 50%; 64 | left: 0; 65 | margin-top: -$tooltip-arrow-width; 66 | border-width: $tooltip-arrow-width $tooltip-arrow-width $tooltip-arrow-width 0; 67 | border-right-color: $tooltip-arrow-color; 68 | } 69 | &.left .tooltip-arrow { 70 | top: 50%; 71 | right: 0; 72 | margin-top: -$tooltip-arrow-width; 73 | border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-width; 74 | border-left-color: $tooltip-arrow-color; 75 | } 76 | &.bottom .tooltip-arrow { 77 | top: 0; 78 | left: 50%; 79 | margin-left: -$tooltip-arrow-width; 80 | border-width: 0 $tooltip-arrow-width $tooltip-arrow-width; 81 | border-bottom-color: $tooltip-arrow-color; 82 | } 83 | &.bottom-left .tooltip-arrow { 84 | top: 0; 85 | left: $tooltip-arrow-width; 86 | border-width: 0 $tooltip-arrow-width $tooltip-arrow-width; 87 | border-bottom-color: $tooltip-arrow-color; 88 | } 89 | &.bottom-right .tooltip-arrow { 90 | top: 0; 91 | right: $tooltip-arrow-width; 92 | border-width: 0 $tooltip-arrow-width $tooltip-arrow-width; 93 | border-bottom-color: $tooltip-arrow-color; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/assets/styles/mixins/_forms.scss: -------------------------------------------------------------------------------- 1 | // Form validation states 2 | // 3 | // Used in forms.less to generate the form validation CSS for warnings, errors, 4 | // and successes. 5 | 6 | @mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) { 7 | // Color the label and help text 8 | .help-block, 9 | .control-label, 10 | .radio, 11 | .checkbox, 12 | .radio-inline, 13 | .checkbox-inline { 14 | color: $text-color; 15 | } 16 | // Set the border and box shadow on specific inputs to match 17 | .form-control { 18 | border-color: $border-color; 19 | @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work 20 | &:focus { 21 | border-color: darken($border-color, 10%); 22 | $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%); 23 | @include box-shadow($shadow); 24 | } 25 | } 26 | // Set validation states also for addons 27 | .input-group-addon { 28 | color: $text-color; 29 | border-color: $border-color; 30 | background-color: $background-color; 31 | } 32 | // Optional feedback icon 33 | .form-control-feedback { 34 | color: $text-color; 35 | } 36 | } 37 | 38 | 39 | // Form control focus state 40 | // 41 | // Generate a customized focus state and for any input with the specified color, 42 | // which defaults to the `$input-border-focus` variable. 43 | // 44 | // We highly encourage you to not customize the default value, but instead use 45 | // this to tweak colors on an as-needed basis. This aesthetic change is based on 46 | // WebKit's default styles, but applicable to a wider range of browsers. Its 47 | // usability and accessibility should be taken into account with any change. 48 | // 49 | // Example usage: change the default blue border and shadow to white for better 50 | // contrast against a dark gray background. 51 | @mixin form-control-focus($color: $input-border-focus) { 52 | $color-rgba: rgba(red($color), green($color), blue($color), .6); 53 | &:focus { 54 | border-color: $color; 55 | outline: 0; 56 | @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba); 57 | } 58 | } 59 | 60 | // Form control sizing 61 | // 62 | // Relative text size, padding, and border-radii changes for form controls. For 63 | // horizontal sizing, wrap controls in the predefined grid classes. ` 6 | 7 |
8 |
9 | 13 |

{{requestTypeField.description}}

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |

* idicates a required field

27 |
28 |

Your request has been submitted!

29 |

Your request ID number is {{requestedId}}.

30 |

You can track your request here.

31 |
32 |

Something went wrong. Please try again.

33 |

34 | 35 | 36 | -------------------------------------------------------------------------------- /app/simplicity.http.js: -------------------------------------------------------------------------------- 1 | //All HTTP requests are routed this this module 2 | angular.module('simplicity.http', []) 3 | .factory('simplicityHttp', ['$http', '$q', 4 | function($http, $q){ 5 | 6 | var simplicityHttp = {}; 7 | 8 | //Makes a GET request to a url query params defined as key-value pairs in the options object 9 | simplicityHttp.get = function(url, options){ 10 | //use $q promises to handle the http request asynchronously 11 | var q = $q.defer(); 12 | 13 | //options.callback = 'JSON_CALLBACK'; 14 | //make http request 15 | $http({method : 'GET', url : url, params : options, cache : true}) 16 | //callbacks 17 | .success(function(data, status, headers, config){ 18 | if(data.error){ 19 | console.log(data.error.code + ' queryBackend on url ' + url + '. ' + data.error.message); 20 | }else{ 21 | q.resolve(data); 22 | } 23 | }) 24 | .error(function(error){ 25 | console.log('Error querying feature service.'); 26 | console.log(error); 27 | }); 28 | 29 | //return the promise using q 30 | return q.promise; 31 | };//END queryBackend function 32 | 33 | 34 | //builds query params from a queryTemplate defined in a adapter file (eg. simplicity.arcgis.rest.api.adapter.js) 35 | //and an object of queryValues to inject into the queryTemplate 36 | simplicityHttp.buildQueryParams = function(queryTemplate, queryValues){ 37 | var q = $q.defer(); 38 | var sqlArray = []; 39 | 40 | for (var i = 0; i < queryTemplate.sqlArray.length; i++) { 41 | 42 | if(queryValues[queryTemplate.sqlArray[i]] !== undefined){ 43 | sqlArray.push(queryValues[queryTemplate.sqlArray[i]]); 44 | }else{ 45 | sqlArray.push(queryTemplate.sqlArray[i]); 46 | } 47 | } 48 | 49 | var sqlExpression = sqlArray.join(''); 50 | 51 | var queryParams = queryTemplate.queryParams; 52 | 53 | queryParams[queryTemplate.sqlParamName] = sqlExpression; 54 | 55 | q.resolve(queryParams); 56 | return q.promise; 57 | }; 58 | 59 | simplicityHttp.buildQueryParamsAndMakeGetRequest = function(queryTemplate, queryValues){ 60 | var q = $q.defer(); 61 | var sqlArray = []; 62 | 63 | for (var i = 0; i < queryTemplate.sqlArray.length; i++) { 64 | 65 | if(queryValues[queryTemplate.sqlArray[i]] !== undefined){ 66 | sqlArray.push(queryValues[queryTemplate.sqlArray[i]]); 67 | }else{ 68 | sqlArray.push(queryTemplate.sqlArray[i]); 69 | } 70 | } 71 | 72 | var sqlExpression = sqlArray.join(''); 73 | 74 | var queryParams = queryTemplate.queryParams; 75 | 76 | queryParams[queryTemplate.sqlParamName] = sqlExpression; 77 | 78 | var url = 'http://arcgis-arcgisserver1-1222684815.us-east-1.elb.amazonaws.com/arcgis/rest/services/opendata/FeatureServer/0/query'; 79 | $http({method : 'GET', url : url, params : queryParams, cache : true}) 80 | //callbacks 81 | .success(function(data, status, headers, config){ 82 | if(data.error){ 83 | console.log(data.error.code + ' queryBackend on url ' + url + '. ' + data.error.message); 84 | }else{ 85 | 86 | q.resolve(data); 87 | } 88 | }) 89 | .error(function(error){ 90 | console.log('Error querying feature service.'); 91 | console.log(error); 92 | }); 93 | return q.promise; 94 | }; 95 | 96 | 97 | //****Return the factory object****// 98 | return simplicityHttp; 99 | 100 | 101 | }]); //END simplicityHttp factory function -------------------------------------------------------------------------------- /app/components/topics/topic-components/zoning/zoning.factory.js: -------------------------------------------------------------------------------- 1 | simplicity.factory('Zoning', ['$q', '$stateParams', 'AddressCache', 'simplicityBackend', 'CODELINKS', 2 | function($q, $stateParams, AddressCache, simplicityBackend, CODELINKS){ 3 | 4 | var Zoning = {}; 5 | 6 | var topicProperties = { 7 | 'name' : 'zoning', 8 | 'title' : 'Zoning', 9 | 'plural' : 'zoning', 10 | 'searchForText' : 'an address', 11 | 'position' : 6, 12 | 'downloadable' : false, 13 | 'inTheCityOnly' : true, 14 | 'searchby' : { 15 | 'address' : { 16 | 'params' : { 17 | 'type' : null, 18 | 'timeframe' : null, 19 | 'extent' : null, 20 | 'view' : 'simple', 21 | 'validViews' : ['simple'] 22 | }, 23 | 'requiredParams' : [], 24 | 'headerTemplate' : 'topics/topic-headers/topic.header.at.html', 25 | } 26 | }, 27 | 'views' : { 28 | 'simple' : {'label' : 'Simple View', 'template' : 'topics/topic-components/zoning/zoning.view.html'} 29 | }, 30 | 'iconClass' : 'flaticon-map104', 31 | 'linkTopics' : ['property', 'crime', 'development'], 32 | 'questions' : { 33 | 'topic' : 'Do you want to know about a zoning?', 34 | 'address' : 'Do you want to know about the zoning at this address?' 35 | } 36 | }; 37 | 38 | var formatZoningPropertyForAnAddress = function(){ 39 | var addressCache = AddressCache.get(); 40 | var pinnum2civicaddressid = AddressCache.pinnum2civicaddressid(); 41 | var formattedZoningArray = []; 42 | if(addressCache.zoning){ 43 | for (var z = 0; z < addressCache.zoning.length; z++) { 44 | var zoningDistrict = addressCache.zoning[z]; 45 | if(CODELINKS[zoningDistrict] === undefined){ 46 | formattedZoningArray.push({'zoningDistrict' : zoningDistrict, 'codelink' : 'disable'}); 47 | }else{ 48 | formattedZoningArray.push({'zoningDistrict' : zoningDistrict, 'codelink' : CODELINKS[zoningDistrict]}); 49 | } 50 | } 51 | } 52 | return formattedZoningArray; 53 | }; 54 | 55 | Zoning.build = function(){ 56 | var q = $q.defer(); 57 | var addressCache = AddressCache.get(); 58 | var codelink; 59 | if(CODELINKS[addressCache.zoning] === undefined){ 60 | codelink = 'disable'; 61 | }else{ 62 | codelink = CODELINKS[addressCache.zoning]; 63 | } 64 | var geojson = { 65 | 'type' : 'FeatureCollection', 66 | 'summary' : {}, 67 | 'searchGeojson' : addressCache.searchGeojson, 68 | 'features' : [{ 69 | 'type' : 'Feature', 70 | 'properties' : { 71 | 'zoning' : formatZoningPropertyForAnAddress(), 72 | 'zoningOverlays' : addressCache.zoningOverlays, 73 | }, 74 | 'geometry' : { 75 | 'type' : 'Point', 76 | 'coordinates' : [addressCache.searchGeojson.features[0].geometry.coordinates[0], addressCache.searchGeojson.features[0].geometry.coordinates[1]] 77 | } 78 | }] 79 | }; 80 | if(addressCache.zoningOverlays){ 81 | var zoningOverlaysSplit = addressCache.zoningOverlays.split('-'); 82 | simplicityBackend.simplicityQuery('zoningOverlays', {'zoningOverlayName' : zoningOverlaysSplit[0]}) 83 | .then(function(zoningOverlayLayer){ 84 | geojson.overlays = zoningOverlayLayer; 85 | q.resolve(geojson); 86 | }); 87 | }else{ 88 | q.resolve(geojson); 89 | } 90 | 91 | return q.promise; 92 | }; 93 | 94 | Zoning.getTopicProperties = function(){ 95 | return topicProperties; 96 | }; 97 | 98 | //****Return the factory object****// 99 | return Zoning; 100 | 101 | 102 | }]); //END Zoning factory function 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /app/assets/styles/_popovers.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Popovers 3 | // -------------------------------------------------- 4 | 5 | 6 | .popover { 7 | position: absolute; 8 | top: 0; 9 | left: 0; 10 | z-index: $zindex-popover; 11 | display: none; 12 | max-width: $popover-max-width; 13 | padding: 1px; 14 | text-align: left; // Reset given new insertion method 15 | background-color: $popover-bg; 16 | background-clip: padding-box; 17 | border: 1px solid $popover-fallback-border-color; 18 | border: 1px solid $popover-border-color; 19 | border-radius: $border-radius-large; 20 | @include box-shadow(0 5px 10px rgba(0,0,0,.2)); 21 | 22 | // Overrides for proper insertion 23 | white-space: normal; 24 | 25 | // Offset the popover to account for the popover arrow 26 | &.top { margin-top: -$popover-arrow-width; } 27 | &.right { margin-left: $popover-arrow-width; } 28 | &.bottom { margin-top: $popover-arrow-width; } 29 | &.left { margin-left: -$popover-arrow-width; } 30 | } 31 | 32 | .popover-title { 33 | margin: 0; // reset heading margin 34 | padding: 8px 14px; 35 | font-size: $font-size-base; 36 | font-weight: normal; 37 | line-height: 18px; 38 | background-color: $popover-title-bg; 39 | border-bottom: 1px solid darken($popover-title-bg, 5%); 40 | border-radius: ($border-radius-large - 1) ($border-radius-large - 1) 0 0; 41 | } 42 | 43 | .popover-content { 44 | padding: 9px 14px; 45 | } 46 | 47 | // Arrows 48 | // 49 | // .arrow is outer, .arrow:after is inner 50 | 51 | .popover > .arrow { 52 | &, 53 | &:after { 54 | position: absolute; 55 | display: block; 56 | width: 0; 57 | height: 0; 58 | border-color: transparent; 59 | border-style: solid; 60 | } 61 | } 62 | .popover > .arrow { 63 | border-width: $popover-arrow-outer-width; 64 | } 65 | .popover > .arrow:after { 66 | border-width: $popover-arrow-width; 67 | content: ""; 68 | } 69 | 70 | .popover { 71 | &.top > .arrow { 72 | left: 50%; 73 | margin-left: -$popover-arrow-outer-width; 74 | border-bottom-width: 0; 75 | border-top-color: $popover-arrow-outer-fallback-color; // IE8 fallback 76 | border-top-color: $popover-arrow-outer-color; 77 | bottom: -$popover-arrow-outer-width; 78 | &:after { 79 | content: " "; 80 | bottom: 1px; 81 | margin-left: -$popover-arrow-width; 82 | border-bottom-width: 0; 83 | border-top-color: $popover-arrow-color; 84 | } 85 | } 86 | &.right > .arrow { 87 | top: 50%; 88 | left: -$popover-arrow-outer-width; 89 | margin-top: -$popover-arrow-outer-width; 90 | border-left-width: 0; 91 | border-right-color: $popover-arrow-outer-fallback-color; // IE8 fallback 92 | border-right-color: $popover-arrow-outer-color; 93 | &:after { 94 | content: " "; 95 | left: 1px; 96 | bottom: -$popover-arrow-width; 97 | border-left-width: 0; 98 | border-right-color: $popover-arrow-color; 99 | } 100 | } 101 | &.bottom > .arrow { 102 | left: 50%; 103 | margin-left: -$popover-arrow-outer-width; 104 | border-top-width: 0; 105 | border-bottom-color: $popover-arrow-outer-fallback-color; // IE8 fallback 106 | border-bottom-color: $popover-arrow-outer-color; 107 | top: -$popover-arrow-outer-width; 108 | &:after { 109 | content: " "; 110 | top: 1px; 111 | margin-left: -$popover-arrow-width; 112 | border-top-width: 0; 113 | border-bottom-color: $popover-arrow-color; 114 | } 115 | } 116 | 117 | &.left > .arrow { 118 | top: 50%; 119 | right: -$popover-arrow-outer-width; 120 | margin-top: -$popover-arrow-outer-width; 121 | border-right-width: 0; 122 | border-left-color: $popover-arrow-outer-fallback-color; // IE8 fallback 123 | border-left-color: $popover-arrow-outer-color; 124 | &:after { 125 | content: " "; 126 | right: 1px; 127 | border-right-width: 0; 128 | border-left-color: $popover-arrow-color; 129 | bottom: -$popover-arrow-width; 130 | } 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /app/assets/styles/_modals.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Modals 3 | // -------------------------------------------------- 4 | 5 | // .modal-open - body class for killing the scroll 6 | // .modal - container to scroll within 7 | // .modal-dialog - positioning shell for the actual modal 8 | // .modal-content - actual modal w/ bg and corners and shit 9 | 10 | // Kill the scroll on the body 11 | .modal-open { 12 | overflow: hidden; 13 | } 14 | 15 | // Container that the modal scrolls within 16 | .modal { 17 | display: none; 18 | overflow: hidden; 19 | position: fixed; 20 | top: 0; 21 | right: 0; 22 | bottom: 0; 23 | left: 0; 24 | z-index: $zindex-modal; 25 | -webkit-overflow-scrolling: touch; 26 | 27 | // Prevent Chrome on Windows from adding a focus outline. For details, see 28 | // https://github.com/twbs/bootstrap/pull/10951. 29 | outline: 0; 30 | 31 | // When fading in the modal, animate it to slide down 32 | &.fade .modal-dialog { 33 | @include translate3d(0, -25%, 0); 34 | @include transition-transform(0.3s ease-out); 35 | } 36 | &.in .modal-dialog { @include translate3d(0, 0, 0) } 37 | } 38 | .modal-open .modal { 39 | overflow-x: hidden; 40 | overflow-y: auto; 41 | } 42 | 43 | // Shell div to position the modal with bottom padding 44 | .modal-dialog { 45 | position: relative; 46 | width: auto; 47 | margin: 10px; 48 | } 49 | 50 | // Actual modal 51 | .modal-content { 52 | position: relative; 53 | background-color: $modal-content-bg; 54 | border: 1px solid $modal-content-fallback-border-color; //old browsers fallback (ie8 etc) 55 | border: 1px solid $modal-content-border-color; 56 | border-radius: $border-radius-large; 57 | @include box-shadow(0 3px 9px rgba(0,0,0,.5)); 58 | background-clip: padding-box; 59 | // Remove focus outline from opened modal 60 | outline: 0; 61 | } 62 | 63 | // Modal background 64 | .modal-backdrop { 65 | position: fixed; 66 | top: 0; 67 | right: 0; 68 | bottom: 0; 69 | left: 0; 70 | z-index: $zindex-modal-background; 71 | background-color: $modal-backdrop-bg; 72 | // Fade for backdrop 73 | &.fade { @include opacity(0); } 74 | &.in { @include opacity($modal-backdrop-opacity); } 75 | } 76 | 77 | // Modal header 78 | // Top section of the modal w/ title and dismiss 79 | .modal-header { 80 | padding: $modal-title-padding; 81 | border-bottom: 1px solid $modal-header-border-color; 82 | min-height: ($modal-title-padding + $modal-title-line-height); 83 | } 84 | // Close icon 85 | .modal-header .close { 86 | margin-top: -2px; 87 | } 88 | 89 | // Title text within header 90 | .modal-title { 91 | margin: 0; 92 | line-height: $modal-title-line-height; 93 | } 94 | 95 | // Modal body 96 | // Where all modal content resides (sibling of .modal-header and .modal-footer) 97 | .modal-body { 98 | position: relative; 99 | padding: $modal-inner-padding; 100 | } 101 | 102 | // Footer (for actions) 103 | .modal-footer { 104 | padding: $modal-inner-padding; 105 | text-align: right; // right align buttons 106 | border-top: 1px solid $modal-footer-border-color; 107 | @include clearfix(); // clear it in case folks use .pull-* classes on buttons 108 | 109 | // Properly space out buttons 110 | .btn + .btn { 111 | margin-left: 5px; 112 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs 113 | } 114 | // but override that for button groups 115 | .btn-group .btn + .btn { 116 | margin-left: -1px; 117 | } 118 | // and override it for block buttons as well 119 | .btn-block + .btn-block { 120 | margin-left: 0; 121 | } 122 | } 123 | 124 | // Measure scrollbar width for padding body during modal show/hide 125 | .modal-scrollbar-measure { 126 | position: absolute; 127 | top: -9999px; 128 | width: 50px; 129 | height: 50px; 130 | overflow: scroll; 131 | } 132 | 133 | // Scale up the modal 134 | @media (min-width: $screen-sm-min) { 135 | // Automatically set modal's width for larger viewports 136 | .modal-dialog { 137 | width: $modal-md; 138 | margin: 30px auto; 139 | } 140 | .modal-content { 141 | @include box-shadow(0 5px 15px rgba(0,0,0,.5)); 142 | } 143 | 144 | // Modal sizes 145 | .modal-sm { width: $modal-sm; } 146 | } 147 | 148 | @media (min-width: $screen-md-min) { 149 | .modal-lg { width: $modal-lg; } 150 | } 151 | -------------------------------------------------------------------------------- /app/assets/styles/_buttons.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Buttons 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // -------------------------------------------------- 8 | 9 | .btn { 10 | display: inline-block; 11 | margin-bottom: 0; // For input.btn 12 | font-weight: $btn-font-weight; 13 | text-align: center; 14 | vertical-align: middle; 15 | cursor: pointer; 16 | background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 17 | border: 1px solid transparent; 18 | white-space: nowrap; 19 | @include box-shadow(2px 2px 2px rgba(0,0,0,.3)); 20 | @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $border-radius-base); 21 | @include user-select(none); 22 | 23 | &, 24 | &:active, 25 | &.active { 26 | &:focus { 27 | @include tab-focus(); 28 | } 29 | } 30 | 31 | &:hover, 32 | &:focus { 33 | color: $btn-default-color; 34 | text-decoration: none; 35 | } 36 | 37 | &:active, 38 | &.active { 39 | outline: 0; 40 | background-image: none; 41 | @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); 42 | } 43 | 44 | &.disabled, 45 | &[disabled], 46 | fieldset[disabled] & { 47 | cursor: not-allowed; 48 | pointer-events: none; // Future-proof disabling of clicks 49 | @include opacity(.65); 50 | @include box-shadow(none); 51 | } 52 | } 53 | 54 | // Alternate buttons 55 | // -------------------------------------------------- 56 | 57 | .btn-default { 58 | @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border); 59 | } 60 | .btn-primary { 61 | @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); 62 | } 63 | // Success appears as green 64 | .btn-success { 65 | @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); 66 | } 67 | // Info appears as blue-green 68 | .btn-info { 69 | @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); 70 | } 71 | // Warning appears as orange 72 | .btn-warning { 73 | @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); 74 | } 75 | // Danger and error appear as red 76 | .btn-danger { 77 | @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); 78 | } 79 | 80 | 81 | // Link buttons 82 | // ------------------------- 83 | 84 | // Make a button look and behave like a link 85 | .btn-link { 86 | color: $link-color; 87 | font-weight: normal; 88 | cursor: pointer; 89 | border-radius: 0; 90 | 91 | &, 92 | &:active, 93 | &[disabled], 94 | fieldset[disabled] & { 95 | background-color: transparent; 96 | @include box-shadow(none); 97 | } 98 | &, 99 | &:hover, 100 | &:focus, 101 | &:active { 102 | border-color: transparent; 103 | } 104 | &:hover, 105 | &:focus { 106 | color: $link-hover-color; 107 | text-decoration: underline; 108 | background-color: transparent; 109 | } 110 | &[disabled], 111 | fieldset[disabled] & { 112 | &:hover, 113 | &:focus { 114 | color: $btn-link-disabled-color; 115 | text-decoration: none; 116 | } 117 | } 118 | } 119 | 120 | 121 | // Button Sizes 122 | // -------------------------------------------------- 123 | 124 | .btn-lg { 125 | // line-height: ensure even-numbered height of button next to large input 126 | @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $border-radius-large); 127 | } 128 | .btn-sm { 129 | // line-height: ensure proper height of button next to small input 130 | @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $border-radius-small); 131 | } 132 | .btn-xs { 133 | @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $border-radius-small); 134 | } 135 | 136 | 137 | // Block button 138 | // -------------------------------------------------- 139 | 140 | .btn-block { 141 | display: block; 142 | width: 100%; 143 | } 144 | 145 | // Vertically space out multiple block buttons 146 | .btn-block + .btn-block { 147 | margin-top: 5px; 148 | } 149 | 150 | // Specificity overrides 151 | input[type="submit"], 152 | input[type="reset"], 153 | input[type="button"] { 154 | &.btn-block { 155 | width: 100%; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SimpliCity 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 44 | 45 |
46 | 47 |
48 | 49 | 50 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/assets/styles/_flipping.scss: -------------------------------------------------------------------------------- 1 | #folder { 2 | padding: 10px; 3 | 4 | height: inherit; 5 | } 6 | .shadow{ 7 | border-color: #dddddd; 8 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); 9 | } 10 | 11 | 12 | .fold { 13 | padding: 10px; 14 | height: 80px; 15 | cursor: pointer; 16 | -webkit-transition: all .3s linear; 17 | -moz-transition: all .3s linear; 18 | -ms-transition: all .3s linear; 19 | transition: all .3s linear; 20 | } 21 | 22 | #toggle { display: none; } 23 | 24 | 25 | #toggle:checked ~ .fold:nth-child(odd) { 26 | margin-top: -85px; 27 | -webkit-transform: perspective(1000px) rotateX(-90deg); 28 | -moz-transform: perspective(1000px) rotateX(-90deg); 29 | -ms-transform: perspective(1000px) rotateX(-90deg); 30 | transform: perspective(1000px) rotateX(-90deg); 31 | } 32 | 33 | #toggle:checked ~ .fold:nth-child(even) { 34 | margin-top: -85px; 35 | -webkit-transform: perspective(1000px) rotateX(90deg); 36 | -moz-transform: perspective(1000px) rotateX(90deg); 37 | -ms-transform: perspective(1000px) rotateX(90deg); 38 | transform: perspective(1000px) rotateX(90deg); 39 | } 40 | .panel{ 41 | margin-bottom: 0px 42 | } 43 | 44 | /*.card-container { 45 | height : 400px; 46 | position: relative; 47 | -webkit-perspective: 1000px; 48 | -moz-perspective: 1000px; 49 | -o-perspective: 1000px; 50 | perspective: 1000px; 51 | } 52 | 53 | #card { 54 | width: 100%; 55 | height: 100%; 56 | position: absolute; 57 | -webkit-transition: -webkit-transform 1s; 58 | -moz-transition: -moz-transform 1s; 59 | -o-transition: -o-transform 1s; 60 | transition: transform 1s; 61 | -webkit-transform-style: preserve-3d; 62 | -moz-transform-style: preserve-3d; 63 | -o-transform-style: preserve-3d; 64 | transform-style: preserve-3d; 65 | } 66 | 67 | .face { 68 | background: white; 69 | display: block; 70 | height: 100%; 71 | width: 100%; 72 | position: absolute; 73 | -webkit-backface-visibility: visible; 74 | -webkit-backface-visibility: hidden; 75 | -moz-backface-visibility: hidden; 76 | -o-backface-visibility: hidden; 77 | backface-visibility: hidden; 78 | } 79 | 80 | #card .back { 81 | height: 400px; 82 | background: white; 83 | -webkit-transform: rotateY( 180deg ); 84 | -moz-transform: rotateY( 180deg ); 85 | -o-transform: rotateY( 180deg ); 86 | transform: rotateY( 180deg ); 87 | } 88 | 89 | #card.flipped { 90 | -webkit-transform: rotateY( 180deg ); 91 | -moz-transform: rotateY( 180deg ); 92 | -o-transform: rotateY( 180deg ); 93 | transform: rotateY( 180deg ); 94 | }*/ 95 | 96 | .flip { 97 | -webkit-perspective: 1000; 98 | -ms-perspective: 1000; 99 | -moz-perspective: 1000; 100 | -o-perspective: 1000; 101 | width: 100%; 102 | 103 | position: relative; 104 | } 105 | .flip .card.flipped { 106 | transform:rotatey(180deg); 107 | -ms-transform:rotatey(180deg); /* IE 9 */ 108 | -moz-transform:rotatey(180deg); /* Firefox */ 109 | -webkit-transform:rotatey(180deg); /* Safari and Chrome */ 110 | -o-transform:rotatey(180deg); /* Opera */ 111 | } 112 | .flip .card { 113 | width: 100%; 114 | height: 100%; 115 | -webkit-transform-style: preserve-3d; 116 | -webkit-transition: 0.5s; 117 | -moz-transform-style: preserve-3d; 118 | -moz-transition: 0.5s; 119 | -ms-transform-style: preserve-3d; 120 | -ms-transition: 0.5s; 121 | -o-transform-style: preserve-3d; 122 | -o-transition: 0.5s; 123 | transform-style: preserve-3d; 124 | transition: 0.5s; 125 | } 126 | .flip .card .face { 127 | width: 100%; 128 | height: 100%; 129 | backface-visibility: hidden; /* W3C */ 130 | -webkit-backface-visibility: hidden; /* Safari & Chrome */ 131 | -moz-backface-visibility: hidden; /* Firefox */ 132 | -ms-backface-visibility: hidden; /* Internet Explorer */ 133 | -o-backface-visibility: hidden; /* Opera */ 134 | 135 | } 136 | .flip .card .front { 137 | position: absolute; 138 | z-index: 1; 139 | background: white; 140 | } 141 | .flip .card .back { 142 | 143 | z-index: 1; 144 | background: white; 145 | position: absolute; 146 | 147 | transform:rotatey(180deg); 148 | -ms-transform:rotatey(180deg); /* IE 9 */ 149 | -moz-transform:rotatey(180deg); /* Firefox */ 150 | -webkit-transform:rotatey(180deg); /* Safari and Chrome */ 151 | -o-transform:rotatey(180deg); /* Opera */ 152 | 153 | } -------------------------------------------------------------------------------- /app/assets/styles/mixins/_gradients.scss: -------------------------------------------------------------------------------- 1 | // Gradients 2 | 3 | 4 | 5 | // Horizontal gradient, from left to right 6 | // 7 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 8 | // Color stops are not available in IE9 and below. 9 | @mixin gradient-horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { 10 | background-image: -webkit-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+ 11 | background-image: -o-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // Opera 12 12 | background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ 13 | background-repeat: repeat-x; 14 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down 15 | } 16 | 17 | // Vertical gradient, from top to bottom 18 | // 19 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 20 | // Color stops are not available in IE9 and below. 21 | @mixin gradient-vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { 22 | background-image: -webkit-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+ 23 | background-image: -o-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Opera 12 24 | background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ 25 | background-repeat: repeat-x; 26 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down 27 | } 28 | 29 | @mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) { 30 | background-repeat: repeat-x; 31 | background-image: -webkit-linear-gradient($deg, $start-color, $end-color); // Safari 5.1-6, Chrome 10+ 32 | background-image: -o-linear-gradient($deg, $start-color, $end-color); // Opera 12 33 | background-image: linear-gradient($deg, $start-color, $end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ 34 | } 35 | @mixin gradient-horizontal-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { 36 | background-image: -webkit-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color); 37 | background-image: -o-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color); 38 | background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); 39 | background-repeat: no-repeat; 40 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down, gets no color-stop at all for proper fallback 41 | } 42 | @mixin gradient-vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { 43 | background-image: -webkit-linear-gradient($start-color, $mid-color $color-stop, $end-color); 44 | background-image: -o-linear-gradient($start-color, $mid-color $color-stop, $end-color); 45 | background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); 46 | background-repeat: no-repeat; 47 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback 48 | } 49 | @mixin gradient-radial($inner-color: #555, $outer-color: #333) { 50 | background-image: -webkit-radial-gradient(circle, $inner-color, $outer-color); 51 | background-image: radial-gradient(circle, $inner-color, $outer-color); 52 | background-repeat: no-repeat; 53 | } 54 | @mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) { 55 | background-image: -webkit-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); 56 | background-image: -o-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); 57 | background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); 58 | } 59 | -------------------------------------------------------------------------------- /test/unit/app.factory.mocha.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('app.factory.js', function(){ 4 | var $scope; 5 | var AppFact; 6 | 7 | beforeEach(function(){ 8 | module('simplicity'); 9 | 10 | inject(function($rootScope, $injector) { 11 | $scope = $rootScope.$new(); 12 | AppFact = $injector.get('AppFact'); 13 | }); 14 | 15 | }); 16 | 17 | var locationProperties = { 18 | locationName : '123456', 19 | locationType : 'cai', 20 | inTheCity : true, 21 | address : '25 Howland Rd', 22 | city : 'Asheville', 23 | state : 'NC', 24 | zip : 28804 25 | }; 26 | var caiQuestions = [ 27 | {'question' : 'Do you want to know about crime?', 'category' : 'crime', 'detail' : 'within-quarter-mile'}, 28 | {'question' : 'Do you want to know about this property?', 'category' : 'property', 'detail' : 'summary'}, 29 | {'question' : 'Do you want to know about development?', 'category' : 'development', 'detail' : 'summary'}, 30 | {'question' : 'Do you want to know about the owner?', 'category' : 'property', 'detail' : 'owner'}, 31 | {'question' : 'Do you want to know about the zoning?', 'category' : 'property', 'detail' : 'zoning'}, 32 | {'question' : 'Do you want to know about the trash collection?', 'category' : 'property', 'detail' : 'trash'} 33 | ]; 34 | 35 | var timeOptions = [ 36 | {'value' : 'last-6-months', 'label' : 'During the last 6 months'}, 37 | {'value' : 'last-year', 'label' : 'During the last year'}, 38 | {'value' : '2014', 'label' : 'During the year 2014'}, 39 | {'value' : '2013', 'label' : 'During the year 2013'}, 40 | {'value' : '2012', 'label' : 'During the year 2012'} 41 | ]; 42 | 43 | var extentOptions = [ 44 | {'value' : 'within-a-quarter-mile', 'label' : 'Within a quarter mile'}, 45 | {'value' : 'within-a-half-mile', 'label' : 'Within a half mile'}, 46 | {'value' : 'within-a-mile', 'label' : 'Within a mile'}, 47 | {'value' : 'within-5-miles', 'label' : 'Within 5 miles'} 48 | ]; 49 | 50 | var propertyFilterOptions = [ 51 | {'value' : 'summary', 'label' : 'Property Summary'}, 52 | {'value' : 'zoning', 'label' : 'Zoning'}, 53 | {'value' : 'owner', 'label' : 'Owner'}, 54 | {'value' : 'deed', 'label' : 'Deed'}, 55 | {'value' : 'garbage', 'label' : 'Garbage Collection'}, 56 | {'value' : 'recycling', 'label' : 'Recycling'}, 57 | {'value' : 'leaf', 'label' : 'Leaf & Brush Collection'} 58 | ]; 59 | 60 | var crimeFilterOptions = [ 61 | {'value' : 'summary', 'label' : 'Crime Summary'}, 62 | {'value' : 'aggravated-assault', 'label' : 'Aggravated Assaults'}, 63 | {'value' : 'rape', 'label' : 'Rapes'}, 64 | {'value' : 'vandalism', 'label' : 'Vandalism'}, 65 | {'value' : 'larceny', 'label' : 'Larcenies'}, 66 | {'value' : 'larceny-auto', 'label' : 'Larcenies (Auto)'}, 67 | ]; 68 | 69 | it('should set location properties', function(){ 70 | AppFact.locationProperties(locationProperties); 71 | var theLocationPropertiesThatWereSet = AppFact.locationProperties(); 72 | expect(theLocationPropertiesThatWereSet).to.eventually.equal(locationProperties); 73 | expect(theLocationPropertiesThatWereSet).to.eventually.have.property('locationName'); 74 | }); 75 | 76 | 77 | it('should get location properties', function() { 78 | var theLocationPropertiesFromAppFact= AppFact.locationProperties(); 79 | expect(theLocationPropertiesFromAppFact).to.eventually.equal(locationProperties); 80 | expect(theLocationPropertiesFromAppFact).to.eventually.have.property('locationName'); 81 | }); 82 | 83 | it('should get questions for a civic address ID', function(){ 84 | AppFact.locationProperties(locationProperties); 85 | var ciaQuestionsFromAppFact = AppFact.questions(); 86 | expect(ciaQuestionsFromAppFact[0].question).to.equal(caiQuestions[0].question); 87 | }); 88 | 89 | it('should set and get time options', function(){ 90 | AppFact.timeOptions(timeOptions); 91 | var timeOptionsFromAppFact = AppFact.timeOptions(); 92 | expect(timeOptionsFromAppFact[0].value).to.equal(timeOptions[0].value); 93 | }); 94 | 95 | it('should set and get extent options', function(){ 96 | AppFact.extentOptions(extentOptions); 97 | var extentOptionsFromAppFact = AppFact.extentOptions(); 98 | expect(extentOptionsFromAppFact[0].value).to.equal(extentOptions[0].value); 99 | }); 100 | 101 | it('should set and get propertyFilter options', function(){ 102 | AppFact.propertyFilterOptions(propertyFilterOptions); 103 | var propertyFilterOptionsFromAppFact = AppFact.propertyFilterOptions(); 104 | expect(propertyFilterOptionsFromAppFact[0].value).to.equal(propertyFilterOptions[0].value); 105 | }); 106 | 107 | it('should set and get crimeFilter options', function(){ 108 | AppFact.filterOptions(crimeFilterOptions); 109 | var crimeFilterOptionsFromAppFact = AppFact.filterOptions(); 110 | expect(crimeFilterOptionsFromAppFact[0].value).to.equal(crimeFilterOptions[0].value); 111 | }); 112 | 113 | 114 | 115 | }); -------------------------------------------------------------------------------- /app/assets/styles/_input-groups.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Input groups 3 | // -------------------------------------------------- 4 | 5 | // Base styles 6 | // ------------------------- 7 | .input-group { 8 | position: relative; // For dropdowns 9 | display: table; 10 | border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table 11 | 12 | // Undo padding and float of grid classes 13 | &[class*="col-"] { 14 | float: none; 15 | padding-left: 0; 16 | padding-right: 0; 17 | } 18 | 19 | .form-control { 20 | // Ensure that the input is always above the *appended* addon button for 21 | // proper border colors. 22 | position: relative; 23 | z-index: 2; 24 | 25 | // IE9 fubars the placeholder attribute in text inputs and the arrows on 26 | // select elements in input groups. To fix it, we float the input. Details: 27 | // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855 28 | float: left; 29 | 30 | width: 100%; 31 | margin-bottom: 0; 32 | } 33 | } 34 | 35 | // Sizing options 36 | // 37 | // Remix the default form control sizing classes into new ones for easier 38 | // manipulation. 39 | 40 | .input-group-lg > .form-control, 41 | .input-group-lg > .input-group-addon, 42 | .input-group-lg > .input-group-btn > .btn { 43 | @extend .input-lg; 44 | } 45 | .input-group-sm > .form-control, 46 | .input-group-sm > .input-group-addon, 47 | .input-group-sm > .input-group-btn > .btn { 48 | @extend .input-sm; 49 | } 50 | 51 | 52 | // Display as table-cell 53 | // ------------------------- 54 | .input-group-addon, 55 | .input-group-btn, 56 | .input-group .form-control { 57 | display: table-cell; 58 | 59 | &:not(:first-child):not(:last-child) { 60 | border-radius: 0; 61 | } 62 | } 63 | // Addon and addon wrapper for buttons 64 | .input-group-addon, 65 | .input-group-btn { 66 | width: 1%; 67 | white-space: nowrap; 68 | vertical-align: middle; // Match the inputs 69 | } 70 | 71 | // Text input groups 72 | // ------------------------- 73 | .input-group-addon { 74 | padding: $padding-base-vertical $padding-base-horizontal; 75 | font-size: $font-size-base; 76 | font-weight: normal; 77 | line-height: 1; 78 | color: $input-color; 79 | text-align: center; 80 | background-color: $input-group-addon-bg; 81 | border: 1px solid $input-group-addon-border-color; 82 | border-radius: $border-radius-base; 83 | 84 | // Sizing 85 | &.input-sm { 86 | padding: $padding-small-vertical $padding-small-horizontal; 87 | font-size: $font-size-small; 88 | border-radius: $border-radius-small; 89 | } 90 | &.input-lg { 91 | padding: $padding-large-vertical $padding-large-horizontal; 92 | font-size: $font-size-large; 93 | border-radius: $border-radius-large; 94 | } 95 | 96 | // Nuke default margins from checkboxes and radios to vertically center within. 97 | input[type="radio"], 98 | input[type="checkbox"] { 99 | margin-top: 0; 100 | } 101 | } 102 | 103 | // Reset rounded corners 104 | .input-group .form-control:first-child, 105 | .input-group-addon:first-child, 106 | .input-group-btn:first-child > .btn, 107 | .input-group-btn:first-child > .btn-group > .btn, 108 | .input-group-btn:first-child > .dropdown-toggle, 109 | .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), 110 | .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { 111 | @include border-right-radius(0); 112 | } 113 | .input-group-addon:first-child { 114 | border-right: 0; 115 | } 116 | .input-group .form-control:last-child, 117 | .input-group-addon:last-child, 118 | .input-group-btn:last-child > .btn, 119 | .input-group-btn:last-child > .btn-group > .btn, 120 | .input-group-btn:last-child > .dropdown-toggle, 121 | .input-group-btn:first-child > .btn:not(:first-child), 122 | .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { 123 | @include border-left-radius(0); 124 | } 125 | .input-group-addon:last-child { 126 | border-left: 0; 127 | } 128 | 129 | // Button input groups 130 | // ------------------------- 131 | .input-group-btn { 132 | position: relative; 133 | // Jankily prevent input button groups from wrapping with `white-space` and 134 | // `font-size` in combination with `inline-block` on buttons. 135 | font-size: 0; 136 | white-space: nowrap; 137 | 138 | // Negative margin for spacing, position for bringing hovered/focused/actived 139 | // element above the siblings. 140 | > .btn { 141 | position: relative; 142 | + .btn { 143 | margin-left: -1px; 144 | } 145 | // Bring the "active" button to the front 146 | &:hover, 147 | &:focus, 148 | &:active { 149 | z-index: 2; 150 | } 151 | } 152 | 153 | // Negative margin to only have a 1px border between the two 154 | &:first-child { 155 | > .btn, 156 | > .btn-group { 157 | margin-right: -1px; 158 | } 159 | } 160 | &:last-child { 161 | > .btn, 162 | > .btn-group { 163 | margin-left: -1px; 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /app/components/search/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Discover city data about {{discoverText}} in your community.

5 |

Search for {{searchFor}} to get started!

6 |
7 |
8 |
9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | 18 |
19 | 20 |

{{errorMessage.message}}

21 |

{{helperMessage.message}}

22 | 23 | 24 | 25 |
26 |
27 |

28 | 29 | 30 | 31 | 32 | {{group.label}} 33 | {{group.results.length}} 34 | 35 |

36 | 50 | 60 |
61 |
62 |

{{errorMessage.message}}

63 |
64 |
65 |
Check out SimpliCity in action below...
66 |
67 | 68 | 69 |
70 | 71 |
72 |
73 | Not sure what you are looking for? Click here to view topics 74 |
75 |
76 |

77 | Developed by the 78 | City of Asheville 79 | 80 |

81 |
It's Open Source! Fork it on GitHub
82 |

Questions, concerns, comments? Contact us at Help@ashevillenc.gov

83 |
84 | 85 | 86 | 87 |
88 | -------------------------------------------------------------------------------- /app/components/topics/topic-components/address-list/address.list.factory.js: -------------------------------------------------------------------------------- 1 | simplicity.factory('AddressList', ['$q', '$stateParams', 'AddressCache', 'simplicityBackend', 'COLORS', 2 | function($q, $stateParams, AddressCache, simplicityBackend, COLORS){ 3 | 4 | var AddressList = {}; 5 | 6 | var topicProperties = { 7 | 'name' : 'addresslist', 8 | 'title' : 'Address List', 9 | 'plural' : 'address lists', 10 | 'searchForText' : 'a street or a neighborhood', 11 | 'position' : 8, 12 | 'downloadable' : true, 13 | 'inTheCityOnly' : false, 14 | 'searchby' : { 15 | 'street_name' : { 16 | 'params' : { 17 | 'type' : null, 18 | 'timeframe' : null, 19 | 'extent' : 82.5, 20 | 'view' : 'list', 21 | 'validViews' : ['list', 'map'] 22 | }, 23 | 'prepositions' : { 24 | 'searchby' : 'along', 25 | }, 26 | 'requiredParams' : [], 27 | 'headerTemplate' : 'topics/topic-headers/topic.header.along.html', 28 | }, 29 | 'neighborhood' : { 30 | 'params' : { 31 | 'type' : null, 32 | 'timeframe' : null, 33 | 'extent' : null, 34 | 'view' : 'list', 35 | 'validViews' : ['list', 'map'] 36 | }, 37 | 'prepositions' : { 38 | 'searchby' : 'in', 39 | }, 40 | 'requiredParams' : [], 41 | 'headerTemplate' : 'topics/topic-headers/topic.header.in.html', 42 | } 43 | }, 44 | 'views' : { 45 | 'map' : {'label' : 'Map View', 'template' : null}, 46 | 'list' : {'label' : 'List View', 'template' : 'topics/topic-components/address-list/address-list.view.html'}, 47 | }, 48 | 'simpleViewTemplate' : null, 49 | 'detailsViewTemplate' : null, 50 | 'tableViewTemplate' : 'topics/topic-components/address-list/address-list.table.view.html', 51 | 'listViewTemplate' : 'topics/topic-components/address-list/address-list.view.html', 52 | 'defaultView' : 'simple', 53 | 'iconClass' : 'flaticon-purchase1', 54 | 'linkTopics' : ['property'], 55 | 'questions' : { 56 | 'topic' : 'Do you want a list of addresses?', 57 | 'street_name' : 'Do you want a list of addresses along this street?', 58 | 'neighborhood' : 'Do you want a list of addresses in this neighborhood?' 59 | } 60 | }; 61 | 62 | AddressList.build = function(){ 63 | var q = $q.defer(); 64 | 65 | var addressCache = AddressCache.get(); 66 | var civicaddressIdArray = AddressCache.civicaddressIdArray(); 67 | 68 | if($stateParams.searchby === "street_name"){ 69 | simplicityBackend.simplicityQuery('addresses', {'civicaddressIds' : civicaddressIdArray.join(',')}) 70 | .then(function(addressResults){ 71 | var addressFeaturesArray = []; 72 | for (var i = 0; i < addressResults.features.length; i++) { 73 | if(addressCache.inTheCity[addressResults.features[i].properties.civicaddress_id]){ 74 | addressResults.features[i].properties.isincity = addressCache.inTheCity[addressResults.features[i].properties.civicaddress_id]; 75 | }else{ 76 | addressResults.features[i].properties.isincity = false; 77 | } 78 | 79 | addressResults.features[i].properties.color = '035096'; 80 | 81 | addressFeaturesArray.push(addressResults.features[i]); 82 | } 83 | var geojson = { 84 | 'type' : 'FeatureCollection', 85 | 'summary' : {}, 86 | 'searchGeojson' : addressCache.searchGeojson, 87 | 'features' : addressFeaturesArray 88 | }; 89 | q.resolve(geojson); 90 | }); 91 | }else if($stateParams.searchby === "neighborhood"){ 92 | simplicityBackend.simplicityQuery('addresses', {'neighborhoodName' : $stateParams.id }) 93 | .then(function(addressResults){ 94 | var addressFeaturesArray = []; 95 | for (var i = 0; i < addressResults.features.length; i++) { 96 | addressResults.features[i].properties.color = '035096'; 97 | addressFeaturesArray.push(addressResults.features[i]); 98 | } 99 | var geojson = { 100 | 'type' : 'FeatureCollection', 101 | 'summary' : {}, 102 | 'searchGeojson' : addressCache.searchGeojson, 103 | 'features' : addressFeaturesArray 104 | }; 105 | q.resolve(geojson); 106 | }); 107 | } 108 | 109 | return q.promise; 110 | }; 111 | 112 | AddressList.getTopicProperties = function(){ 113 | return topicProperties; 114 | }; 115 | 116 | //****Return the factory object****// 117 | return AddressList; 118 | 119 | 120 | }]); //END AddressList factory function 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /app/assets/styles/_responsive-utilities.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Responsive: Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // IE10 in Windows (Phone) 8 7 | // 8 | // Support for responsive views via media queries is kind of borked in IE10, for 9 | // Surface/desktop in split view and for Windows Phone 8. This particular fix 10 | // must be accompanied by a snippet of JavaScript to sniff the user agent and 11 | // apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at 12 | // our Getting Started page for more information on this bug. 13 | // 14 | // For more information, see the following: 15 | // 16 | // Issue: https://github.com/twbs/bootstrap/issues/10497 17 | // Docs: http://getbootstrap.com/getting-started/#support-ie10-width 18 | // Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/ 19 | // Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/ 20 | 21 | @-ms-viewport { 22 | width: device-width; 23 | } 24 | 25 | 26 | // Visibility utilities 27 | // Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0 28 | 29 | @include responsive-invisibility('.visible-xs, .visible-sm, .visible-md, .visible-lg'); 30 | 31 | .visible-xs-block, 32 | .visible-xs-inline, 33 | .visible-xs-inline-block, 34 | .visible-sm-block, 35 | .visible-sm-inline, 36 | .visible-sm-inline-block, 37 | .visible-md-block, 38 | .visible-md-inline, 39 | .visible-md-inline-block, 40 | .visible-lg-block, 41 | .visible-lg-inline, 42 | .visible-lg-inline-block { 43 | display: none !important; 44 | } 45 | 46 | @media (max-width: $screen-xs-max) { 47 | @include responsive-visibility('.visible-xs'); 48 | } 49 | .visible-xs-block { 50 | @media (max-width: $screen-xs-max) { 51 | display: block !important; 52 | } 53 | } 54 | .visible-xs-inline { 55 | @media (max-width: $screen-xs-max) { 56 | display: inline !important; 57 | } 58 | } 59 | .visible-xs-inline-block { 60 | @media (max-width: $screen-xs-max) { 61 | display: inline-block !important; 62 | } 63 | } 64 | 65 | @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { 66 | @include responsive-visibility('.visible-sm'); 67 | } 68 | .visible-sm-block { 69 | @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { 70 | display: block !important; 71 | } 72 | } 73 | .visible-sm-inline { 74 | @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { 75 | display: inline !important; 76 | } 77 | } 78 | .visible-sm-inline-block { 79 | @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { 80 | display: inline-block !important; 81 | } 82 | } 83 | 84 | @media (min-width: $screen-md-min) and (max-width: $screen-md-max) { 85 | @include responsive-visibility('.visible-md'); 86 | } 87 | .visible-md-block { 88 | @media (min-width: $screen-md-min) and (max-width: $screen-md-max) { 89 | display: block !important; 90 | } 91 | } 92 | .visible-md-inline { 93 | @media (min-width: $screen-md-min) and (max-width: $screen-md-max) { 94 | display: inline !important; 95 | } 96 | } 97 | .visible-md-inline-block { 98 | @media (min-width: $screen-md-min) and (max-width: $screen-md-max) { 99 | display: inline-block !important; 100 | } 101 | } 102 | 103 | @media (min-width: $screen-lg-min) { 104 | @include responsive-visibility('.visible-lg'); 105 | } 106 | .visible-lg-block { 107 | @media (min-width: $screen-lg-min) { 108 | display: block !important; 109 | } 110 | } 111 | .visible-lg-inline { 112 | @media (min-width: $screen-lg-min) { 113 | display: inline !important; 114 | } 115 | } 116 | .visible-lg-inline-block { 117 | @media (min-width: $screen-lg-min) { 118 | display: inline-block !important; 119 | } 120 | } 121 | 122 | @media (max-width: $screen-xs-max) { 123 | @include responsive-invisibility('.hidden-xs'); 124 | } 125 | 126 | @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { 127 | @include responsive-invisibility('.hidden-sm'); 128 | } 129 | 130 | @media (min-width: $screen-md-min) and (max-width: $screen-md-max) { 131 | @include responsive-invisibility('.hidden-md'); 132 | } 133 | 134 | @media (min-width: $screen-lg-min) { 135 | @include responsive-invisibility('.hidden-lg'); 136 | } 137 | 138 | 139 | // Print utilities 140 | // 141 | // Media queries are placed on the inside to be mixin-friendly. 142 | 143 | // Note: Deprecated .visible-print as of v3.2.0 144 | 145 | @include responsive-invisibility('.visible-print'); 146 | 147 | @media print { 148 | @include responsive-visibility('.visible-print'); 149 | } 150 | .visible-print-block { 151 | display: none !important; 152 | 153 | @media print { 154 | display: block !important; 155 | } 156 | } 157 | .visible-print-inline { 158 | display: none !important; 159 | 160 | @media print { 161 | display: inline !important; 162 | } 163 | } 164 | .visible-print-inline-block { 165 | display: none !important; 166 | 167 | @media print { 168 | display: inline-block !important; 169 | } 170 | } 171 | 172 | @media print { 173 | @include responsive-invisibility('.hidden-print'); 174 | } 175 | -------------------------------------------------------------------------------- /app/components/search/search.controller.js: -------------------------------------------------------------------------------- 1 | simplicity.controller('SearchCtrl', ['$scope', '$stateParams', '$state', '$timeout', 'simplicityBackend', 'Topics', 2 | function ($scope, $stateParams, $state, $timeout, simplicityBackend, Topics) { 3 | var getType = function(unformattedType){ 4 | var nameKey = { 5 | 'street_name' : 'street', 6 | 'address' : 'address', 7 | 'neighborhood' : 'neighborhood', 8 | 'owner_name' : 'owner', 9 | 'civicaddressid' : 'address', 10 | 'pinnum' : 'pin' 11 | }; 12 | return nameKey[unformattedType]; 13 | }; 14 | 15 | $('#searchContent').css({'minHeight' : $(window).height()}); 16 | 17 | $("#addressSearch").focus(); 18 | $scope.searchText = ''; 19 | 20 | $scope.errorMessage = { 21 | show : false, 22 | message : 'We had trouble locating that location. Please try to enter a location again.' 23 | }; 24 | $scope.helperMessage = { 25 | show : false, 26 | message : 'Please choose one of the options below.' 27 | }; 28 | 29 | $scope.discoverText = "places"; 30 | $scope.searchFor = "an address, street, neighborhood, or property"; 31 | 32 | var topicProperties = {}; 33 | 34 | $scope.showTopicsLink = true; 35 | 36 | //if a topic is defined we want to show topic specific text 37 | if($stateParams.topic !== null){ 38 | topicProperties = Topics.topicProperties(); 39 | $scope.showTopicsLink = false; 40 | $scope.discoverText = topicProperties.plural; 41 | $scope.searchFor = topicProperties.searchForText; 42 | } 43 | 44 | 45 | 46 | //Geocodes the search results 47 | $scope.doSearch = function(searchText, event){ 48 | var offset = $('#inputSearch').offset().top - 20; 49 | $("html, body").animate({'scrollTop' : offset + "px"}); 50 | //we don't want to start search until the user has input 3 characters 51 | if(searchText.length < 3){ 52 | $scope.searchGroups = []; 53 | return; 54 | } 55 | 56 | //if the user hits enter while after text search text 57 | //show a message that tells them to click on one of the results below 58 | if(event.keyCode === 13 && searchText !== ''){ 59 | $scope.helperMessage.show = true; 60 | $timeout(function() { 61 | $scope.helperMessage.show = false; 62 | }, 2000); 63 | } 64 | 65 | 66 | 67 | //Search usign searchText 68 | simplicityBackend.simplicitySearch(searchText) 69 | .then(function(searchResults){ 70 | if(searchText === ""){ 71 | $scope.searchGroups = []; 72 | }else{ 73 | if(searchResults.length !== 0){ 74 | if($stateParams.topic !== null){ 75 | for (var i = searchResults.length - 1; i >= 0; i--) { 76 | 77 | if(topicProperties.searchby[searchResults[i].name] === undefined){ 78 | searchResults.splice(i, 1); 79 | } 80 | } 81 | $scope.searchGroups = searchResults; 82 | }else{ 83 | $scope.searchGroups = searchResults; 84 | } 85 | 86 | } 87 | } 88 | }); 89 | }; 90 | 91 | $scope.unFocus = function(){ 92 | $timeout(function() { 93 | $scope.searchGroups = []; 94 | }, 100); 95 | }; 96 | 97 | 98 | 99 | 100 | 101 | $scope.detailedSelection = []; 102 | 103 | //groupOrderArray.splice(groupOrderPosition, 0, data.candidates[i].attributes.Loc_name); 104 | 105 | $scope.goToTopics = function(candidate, event){ 106 | var label = ""; 107 | for (var i = 0; i < candidate.label.length; i++) { 108 | if(candidate.label.charAt(i) === '&'){ 109 | label = label + 'AND'; 110 | }else{ 111 | label = label + candidate.label.charAt(i); 112 | } 113 | } 114 | if(candidate.type === 'civicaddressid'){ 115 | candidate.type = "address"; 116 | } 117 | if($stateParams.topic !== null){ 118 | if(candidate.googleResult === true){ 119 | simplicityBackend.simplicityFindGoogleAddress(candidate) 120 | .then(function(addressResults){ 121 | $state.go('main.topics.topic', {'topic' : $stateParams.topic, 'searchtext' : addressResults.label, 'searchby' : addressResults.type, 'id' : addressResults.id}); 122 | }); 123 | }else{ 124 | $state.go('main.topics.topic', {'topic' : $stateParams.topic, 'searchtext' : label, 'searchby' : candidate.type, 'id' : candidate.id}); 125 | } 126 | }else{ 127 | if(candidate.googleResult === true){ 128 | simplicityBackend.simplicityFindGoogleAddress(candidate) 129 | .then(function(addressResults){ 130 | $state.go('main.topics.list', {'searchtext' : addressResults.label, 'searchby' : addressResults.type, 'id' : addressResults.id}); 131 | }); 132 | 133 | }else{ 134 | $state.go('main.topics.list', {'searchtext' : label, 'searchby' : candidate.type, 'id' : candidate.id}); 135 | } 136 | } 137 | 138 | }; 139 | 140 | 141 | 142 | 143 | }]); --------------------------------------------------------------------------------