diff --git a/.gitignore b/.gitignore index 649ea31e2e..de636050f9 100644 --- a/.gitignore +++ b/.gitignore @@ -90,4 +90,6 @@ out/ .idea/ *.iml rake.log -lein.log \ No newline at end of file +lein.log + +tmp/ diff --git a/.travis.yml b/.travis.yml index 55cdef7192..15b3564693 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,3 +13,6 @@ script: before_cache: - find $HOME/.m2 -name resolver-status.properties -exec rm {} \; + +notifications: + slack: akvo:ZLetmotGiT22QryK6pR5bnFS \ No newline at end of file diff --git a/Dashboard/.babelrc b/Dashboard/.babelrc new file mode 100644 index 0000000000..d90261d312 --- /dev/null +++ b/Dashboard/.babelrc @@ -0,0 +1,42 @@ + { + "plugins": [ + "transform-class-properties", + "transform-es2015-for-of" + ], + "env": { + "development": { + "presets": [ + "env", + "react", + "react-hmre", + "stage-2" + ] + }, + "production": { + "presets": [ + [ + "env", + { + "targets": { + "ie": 9, + "uglify": true + } + } + ], + "react", + "stage-2" + ], + "plugins": [ + "transform-react-constant-elements", + "transform-react-remove-prop-types" + ] + }, + "test": { + "presets": [ + "env", + "react", + "stage-2" + ] + } + } + } \ No newline at end of file diff --git a/Dashboard/.eslintrc b/Dashboard/.eslintrc new file mode 100644 index 0000000000..b47669501f --- /dev/null +++ b/Dashboard/.eslintrc @@ -0,0 +1,83 @@ +{ + "extends": "airbnb", + "parser": "babel-eslint", + "env": { + "browser": true, + "node": true + }, + "plugins": [ + "react", + "babel" + ], + "parserOptions": { + "ecmaFeatures": { + "jsx": true + } + }, + "rules": { + "camelcase": 1, + "class-methods-use-this": 1, + "comma-dangle": ["error", { + "arrays": "always-multiline", + "objects": "always-multiline", + "imports": "always-multiline", + "exports": "never", + "functions": "never" + }], + "func-names": 0, + "global-require": 1, + "jsx-a11y/no-static-element-interactions": 0, + "no-plusplus": 0, + "no-underscore-dangle": 0, + "prefer-const": 1, + "prefer-destructuring": 1, + "radix": 1, + "react/forbid-prop-types": 0, + "react/no-unused-prop-types": 0, + "react/no-multi-comp": 0, + + "no-mixed-operators": 1, + "no-bitwise": 0, + "prefer-spread": 1, + "prefer-rest-params": 1, + "no-throw-literal": 1, + "import/no-extraneous-dependencies": 1, + "no-unused-vars": 1, + "eqeqeq": 1, + "max-len": 1, + "no-continue": 1, + "no-mixed-spaces-and-tabs": 1, + "no-tabs": 1, + "no-extend-native": 1, + "no-use-before-define": 1, + "no-param-reassign": 1, + "consistent-return": 1, + "no-restricted-globals": 1, + "import/no-unresolved": 1, + "function-paren-newline": 1, + "no-var": 1, + "no-lonely-if": 1, + "no-useless-escape": 1, + "no-useless-concat": 1, + "no-irregular-whitespace": 1, + "vars-on-top": 1, + "new-cap": 1, + "no-array-constructor": 1, + "no-restricted-syntax": 1, + "guard-for-in": 1, + "no-empty": 1, + "for-direction": 1, + "no-shadow": 1, + "no-unused-expressions": 1, + "no-loop-func": 1 + }, + "globals": { + "window": true, + "document": true, + "FLOW": true, + "Ember": true, + "$": true, + "jQuery": true, + "DS": true + } +} diff --git a/Dashboard/Assetfile b/Dashboard/Assetfile index 6a41bbe52a..5597e3f928 100644 --- a/Dashboard/Assetfile +++ b/Dashboard/Assetfile @@ -17,115 +17,6 @@ class LoaderFilter < WebFilters::MinispadeFilter end end -class EmberAssertFilter < Filter - def generate_output(inputs, output) - inputs.each do |input| - result = input.read - result.gsub!(/ember_assert\((.*)\);/, '') - output.write(result) - end - end -end - -class HandlebarsFilter < Filter - def generate_output(inputs, output) - inputs.each do |input| - code = input.read.to_json - name = File.basename(input.path, '.handlebars') - output.write "\nreturn Ember.Handlebars.compile(#{code});\n" - end - end -end - -class CSSMinFilter < Filter - def generate_output(inputs, output) - inputs.each do |input| - result = input.read - result.gsub!(/href="css\/(.*)\.css"/, 'href="css/\1.min.css"') # index.html - result.gsub!(/url\("(.*?).css"\)/, 'url("\1.min.css")') # screen.css - output.write(result) - end - end -end - -output '../GAE/target/akvo-flow/admin' -input 'app' do - - match 'css/main.scss' do - scss - end - - match 'css/users.scss' do - scss - end - - match 'dashboard.html' do - if ENV['RAKEP_MODE'] == 'production' - filter CSSMinFilter - end - copy 'index.html' - end - - match 'js/lib/**/*.js' do - filter LoaderFilter, - :module_id_generator => proc { |input| - input.path.sub(/^js\/lib\//, "#{APPNAME}/").sub(/\.js$/, '') - } - - if ENV['RAKEP_MODE'] == 'production' - filter EmberAssertFilter - uglify {|input| input} - end - concat 'js/app.js' - end - - match 'js/plugins/**/*.js' do - if ENV['RAKEP_MODE'] == 'production' - uglify {|input| input} - end - concat do |input| - input.sub(/plugins\//, '') - end - end - - match 'js/templates/**/*.handlebars' do - filter HandlebarsFilter - filter LoaderFilter, - :module_id_generator => proc { |input| - input.path.sub(/^js\/templates\//, "#{APPNAME}/templates/").sub(/\.handlebars$/, '') - } - if ENV['RAKEP_MODE'] == 'production' - uglify {|input| input} - end - concat 'js/app.js' - end - - - match "static/**/*" do - concat do |input| - input.sub(/static\//, '') - end - end - - match "css/custom-theme/images/*" do - concat do |input| - input.sub(/static\//, '') - end - end - - match "css/**/*.css" do - if ENV['RAKEP_MODE'] == 'production' - yui_css - filter CSSMinFilter - else - concat do |input| - input - end - end - end - -end - output '../GAE/target/akvo-flow/vendorjs' input 'app' do match "js/vendor/**/*.js" do diff --git a/Dashboard/AssetfilePublic b/Dashboard/AssetfilePublic deleted file mode 100755 index e1b795e489..0000000000 --- a/Dashboard/AssetfilePublic +++ /dev/null @@ -1,155 +0,0 @@ -APPNAME = 'akvo-flow' - -require 'json' -require 'rake-pipeline-web-filters' - -WebFilters = Rake::Pipeline::Web::Filters - -class LoaderFilter < WebFilters::MinispadeFilter - def generate_output(inputs, output) - inputs.each do |input| - code = input.read - module_id = @module_id_generator.call(input) - contents = "function(require) {\n#{code}\n}" - ret = "\nloader.register('#{module_id}', #{contents});\n" - output.write ret - end - end -end - -class EmberAssertFilter < Filter - def generate_output(inputs, output) - inputs.each do |input| - result = input.read - result.gsub!(/ember_assert\((.*)\);/, '') - output.write(result) - end - end -end - -class HandlebarsFilter < Filter - def generate_output(inputs, output) - inputs.each do |input| - code = input.read.to_json - name = File.basename(input.path, '.handlebars') - output.write "\nreturn Ember.Handlebars.compile(#{code});\n" - end - end -end - -class CSSMinFilter < Filter - def generate_output(inputs, output) - inputs.each do |input| - result = input.read - result.gsub!(/href="\/publicmap\/css\/(.*)\.css"/, 'href="/publicmap/css/\1.min.css"') # index.html - result.gsub!(/url\("(.*?).css"\)/, 'url("\1.min.css")') # screen.css - output.write(result) - end - end -end - -output '../GAE/target/akvo-flow/publicmap' -input 'app' do - - match 'css/main.scss' do - scss - end - - match 'public.html' do - if ENV['RAKEP_MODE'] == 'production' - filter CSSMinFilter - end - copy '../index.html' - end - - match 'js/lib/**/*public.js' do - filter LoaderFilter, - :module_id_generator => proc { |input| - input.path.sub(/^js\/lib\//, "#{APPNAME}/").sub(/\.js$/, '') - } - - if ENV['RAKEP_MODE'] == 'production' - filter EmberAssertFilter - uglify {|input| input} - end - concat 'js/app.js' - end - - match 'js/lib/**/*common.js' do - filter LoaderFilter, - :module_id_generator => proc { |input| - input.path.sub(/^js\/lib\//, "#{APPNAME}/").sub(/\.js$/, '') - } - - if ENV['RAKEP_MODE'] == 'production' - filter EmberAssertFilter - uglify {|input| input} - end - concat 'js/app.js' - end - - match 'js/plugins/**/*.js' do - if ENV['RAKEP_MODE'] == 'production' - uglify {|input| input} - end - concat do |input| - input.sub(/plugins\//, '') - end - end - - match 'js/templates/**/*-common.handlebars' do - filter HandlebarsFilter - filter LoaderFilter, - :module_id_generator => proc { |input| - input.path.sub(/^js\/templates\//, "#{APPNAME}/templates/").sub(/\.handlebars$/, '') - } - if ENV['RAKEP_MODE'] == 'production' - uglify {|input| input} - end - concat 'js/app.js' - end - - match 'js/templates/**/*-public.handlebars' do - filter HandlebarsFilter - filter LoaderFilter, - :module_id_generator => proc { |input| - input.path.sub(/^js\/templates\//, "#{APPNAME}/templates/").sub(/\.handlebars$/, '') - } - if ENV['RAKEP_MODE'] == 'production' - uglify {|input| input} - end - concat 'js/app.js' - end - - match "static/**/*" do - concat do |input| - input.sub(/static\//, '') - end - end - - match "css/custom-theme/images/*" do - concat do |input| - input.sub(/static\//, '') - end - end - - match "css/**/*.css" do - if ENV['RAKEP_MODE'] == 'production' - yui_css - filter CSSMinFilter - else - concat do |input| - input - end - end - end - - # match "js/vendor/**/*.js" do - # concat do |input| - # input - # end - # end - -end - -# vim: filetype=ruby diff --git a/Dashboard/Rakefile b/Dashboard/Rakefile index c3ad15a904..fad31a1e39 100755 --- a/Dashboard/Rakefile +++ b/Dashboard/Rakefile @@ -9,10 +9,6 @@ def pipeline Rake::Pipeline::Project.new('Assetfile') end -def pipeline_public - Rake::Pipeline::Project.new('AssetfilePublic') -end - desc "Clean #{APPNAME}" task :clean do pipeline.clean @@ -22,7 +18,6 @@ end desc "Build #{APPNAME}" task :build => :clean do pipeline.invoke - pipeline_public.invoke end desc "Watch for changes" diff --git a/Dashboard/app/css/form.scss b/Dashboard/app/css/form.scss index bb06cd1506..63b3b324b5 100644 --- a/Dashboard/app/css/form.scss +++ b/Dashboard/app/css/form.scss @@ -122,14 +122,14 @@ input[type="search"] { box-sizing: content-box; padding: 5px 25px 3px 4px; border: 1px solid rgb(218, 218, 218); - background: rgb(255, 255, 255) url(../images/search-icon.png) no-repeat 3px right; + background: rgb(255, 255, 255) url(/admin/images/search-icon.png) no-repeat 3px right; &:hover { border: 1px solid rgb(114, 205, 255); - background: rgb(224, 224, 224) url(../images/search-icon.png) no-repeat top right; + background: rgb(224, 224, 224) url(/admin/images/search-icon.png) no-repeat top right; } &:focus { border: 1px solid rgb(123, 123, 123); - background: rgb(244, 244, 244) url(../images/search-icon.png) no-repeat top right; + background: rgb(244, 244, 244) url(/admin/images/search-icon.png) no-repeat top right; } } diff --git a/Dashboard/app/css/main.scss b/Dashboard/app/css/main.scss index 8c4f4f3ad3..aebb5ca7e2 100644 --- a/Dashboard/app/css/main.scss +++ b/Dashboard/app/css/main.scss @@ -155,7 +155,7 @@ pre { border-radius: 3px; box-shadow: 0 5px 8px rgba(212, 212, 212, 0.5); padding: 5px 3px 5px 25px; - background: rgb(248, 248, 248) url(../images/loader.gif) 5px center no-repeat; + background: rgb(248, 248, 248) url(/admin/images/loader.gif) 5px center no-repeat; color: rgb(252, 159, 0); } } @@ -267,7 +267,7 @@ a, a:link, a:visited { &.AddBtn { display: inline-block !important; padding: 1em 1% 0.8em 1.5em; - background: url(../images/addbtn.png) left center no-repeat; + background: url(/admin/images/addbtn.png) left center no-repeat; color: rgb(0, 123, 182); text-align: left; font-size: 1.1em; @@ -281,11 +281,11 @@ a, a:link, a:visited { width: 20px; height: 16px; border-radius: 6px; - background: url(../images/closeDialog.png) center top no-repeat; + background: url(/admin/images/closeDialog.png) center top no-repeat; text-indent: -9999px; -o-border-radius: 6px; &:hover { - background: url(../images/closeDialog.png) center bottom no-repeat; + background: url(/admin/images/closeDialog.png) center bottom no-repeat; } } } @@ -551,7 +551,7 @@ header.top { left: 0px; height: 40px; width: 145px; - background: url(../images/akvoFlowLogo.svg) no-repeat 5px top; + background: url(/admin/images/akvoFlowLogo.svg) no-repeat 5px top; text-indent: -9999px; background-size: 90% auto; } @@ -786,7 +786,7 @@ table.dataTable { position: relative; padding: 9px 1em 9px 1em; border-right: thin solid white; - background: url(../images/sortTableArrows.png) right center no-repeat; + background: url(/admin/images/sortTableArrows.png) right center no-repeat; text-align: center; font-weight: normal; color: $linkColor; @@ -847,11 +847,11 @@ table.dataTable thead tr th a.helpIcon { } table.dataTable thead tr th.sorting_desc { - background: url(../images/sortTableDown.png) right center no-repeat; + background: url(/admin/images/sortTableDown.png) right center no-repeat; } table.dataTable thead tr th.sorting_asc { - background: url(../images/sortTableUp.png) right center no-repeat; + background: url(/admin/images/sortTableUp.png) right center no-repeat; } table.dataTable thead tr th:last-child { @@ -912,7 +912,7 @@ tfoot tr { } .greyBg a.standardBtn { - background-image: url("../images/addPlus.png") left center no-repeat; + background-image: url("/admin/images/addPlus.png") left center no-repeat; } @mixin disabledMix { @@ -1139,11 +1139,11 @@ input.hasDatepicker { margin: 3px auto; padding: 0; width: 99%; - background: rgb(242, 242, 242) url(../images/FieldSetSep.png) center center no-repeat; + background: rgb(242, 242, 242) url(/admin/images/FieldSetSep.png) center center no-repeat; } .fieldSetWrap.makeWhite { - background: white url(../images/FieldSetSep.png) center center no-repeat; + background: white url(/admin/images/FieldSetSep.png) center center no-repeat; } #assignSurveys .fieldSetWrap fieldset table { @@ -1384,11 +1384,11 @@ nav.menuGroupWrap { width: calc(98%-30px); border-bottom: thin solid rgb(55, 55, 55); background: rgb(70, 70, 70); - background: rgba(255, 255, 255, 0.05) url(../images/selectFolder.svg) 2px center no-repeat; + background: rgba(255, 255, 255, 0.05) url(/admin/images/selectFolder.svg) 2px center no-repeat; background-size: 20px 20px; div.edit { position: absolute; - background: url(../images/IconEditGrey.svg) center center no-repeat; + background: url(/admin/images/IconEditGrey.svg) center center no-repeat; background-size: 20px 20px; width: 25px; height: 25px; @@ -1399,7 +1399,7 @@ nav.menuGroupWrap { } div.trashFolder { position: absolute; - background: url(../images/IconTrashGrey.svg) center center no-repeat; + background: url(/admin/images/IconTrashGrey.svg) center center no-repeat; background-size: 20px 20px; width: 25px; height: 25px; @@ -1410,7 +1410,7 @@ nav.menuGroupWrap { } div.copyFolder { position: absolute; - background: url(../images/IconCopyGrey.svg) center center no-repeat; + background: url(/admin/images/IconCopyGrey.svg) center center no-repeat; background-size: 20px 20px; width: 25px; height: 25px; @@ -1421,11 +1421,11 @@ nav.menuGroupWrap { } &.folderUp { background: rgb(70, 70, 70); - background: url(../images/folderUp.svg) 2px center no-repeat; + background: url(/admin/images/folderUp.svg) 2px center no-repeat; background-size: 35px 35px; &:hover { background: rgb(70, 70, 70); - background: rgba(255, 255, 255, 0.05) url(../images/folderUpHover.svg) 2px center no-repeat; + background: rgba(255, 255, 255, 0.05) url(/admin/images/folderUpHover.svg) 2px center no-repeat; background-size: 35px 35px; } a { @@ -1441,11 +1441,11 @@ nav.menuGroupWrap { } &.current { border-bottom: thin solid rgb(55, 55, 55); - background: rgb(90, 90, 90) url(../images/selectFolder.svg) left center no-repeat; - background: rgba(255, 255, 255, 0.15) url(../images/selectFolder.svg) 2px center no-repeat; + background: rgb(90, 90, 90) url(/admin/images/selectFolder.svg) left center no-repeat; + background: rgba(255, 255, 255, 0.15) url(/admin/images/selectFolder.svg) 2px center no-repeat; background-size: 20px 20px; a, a:hover { - background: url(../images/carretFolderSelected.svg) right center no-repeat; + background: url(/admin/images/carretFolderSelected.svg) right center no-repeat; color: $flowAnchorLinkHover; background-size: 15px 25px; } @@ -1455,15 +1455,15 @@ nav.menuGroupWrap { padding: 10px 10% 10px 2%; width: 93%; height: 23px; - background: url(../images/carretFolder.svg) right center no-repeat; + background: url(/admin/images/carretFolder.svg) right center no-repeat; background-size: 15px 25px; color: rgb(153, 153, 153); color: rgba(255, 255, 255, 0.6); @include noWrapTxt; cursor: pointer; &:hover { - background: rgb(80, 80, 80) url(../images/carretFolder.svg) right center no-repeat; - background: rgba(255, 255, 255, 0.05) url(../images/carretFolder.svg) right center no-repeat; + background: rgb(80, 80, 80) url(/admin/images/carretFolder.svg) right center no-repeat; + background: rgba(255, 255, 255, 0.05) url(/admin/images/carretFolder.svg) right center no-repeat; color: rgb(114, 205, 255); background-size: 15px 25px; } @@ -1499,16 +1499,16 @@ nav.menuGroupWrap { transition: background 0.4s ease-in; &.scrollUp { border-radius: 5px 5px 0 0; - background: rgb(31, 31, 31) url(../images/scrollUp.png) center center no-repeat; + background: rgb(31, 31, 31) url(/admin/images/scrollUp.png) center center no-repeat; &:hover { - background: rgb(107, 134, 141) url(../images/scrollUp.png) center center no-repeat; + background: rgb(107, 134, 141) url(/admin/images/scrollUp.png) center center no-repeat; } } &.scrollDown { border-radius: 0 0 5px 5px; - background: rgb(31, 31, 31) url(../images/scrollDown.png) center center no-repeat; + background: rgb(31, 31, 31) url(/admin/images/scrollDown.png) center center no-repeat; &:hover { - background: rgb(107, 134, 141) url(../images/scrollDown.png) center center no-repeat; + background: rgb(107, 134, 141) url(/admin/images/scrollDown.png) center center no-repeat; } } } @@ -1748,13 +1748,13 @@ section.topBar { &.homeRoot { border-radius: 3px 0 0 3px; width: 40px; - background: url(../images/breadCrumb-Root.png) center center no-repeat $akvoLightBlue; + background: url(/admin/images/breadCrumb-Root.png) center center no-repeat $akvoLightBlue; background-size: 60%; text-indent: -9999px; z-index: 9999; margin-left: 0; &:hover { - background: url(../images/breadCrumb-Root.png) center center no-repeat $flowAnchorLinkHover; + background: url(/admin/images/breadCrumb-Root.png) center center no-repeat $flowAnchorLinkHover; background-size: 60%; } } @@ -1772,7 +1772,7 @@ section.topBar { padding-right: 0; border-radius: 3px 0 0 3px; width: 40px; - background: url(../images/breadCrumb-Root.png) center center no-repeat $akvoLightBlue; + background: url(/admin/images/breadCrumb-Root.png) center center no-repeat $akvoLightBlue; text-indent: -9999px; z-index: 9999; margin-left: 0; @@ -1792,7 +1792,7 @@ section.topBar { z-index: 10; } &:hover { - background: url(../images/breadCrumb-Root.png) center center no-repeat $akvoLightBlue; + background: url(/admin/images/breadCrumb-Root.png) center center no-repeat $akvoLightBlue; } } &:after { @@ -1815,7 +1815,7 @@ section.topBar { padding: 0; &.actionTitleEdit { padding: 5px 5px 5px 15px; - background: url(../images/IconEditGreyLight.svg) left center no-repeat; + background: url(/admin/images/IconEditGreyLight.svg) left center no-repeat; background-size: 15px; } } @@ -2044,22 +2044,22 @@ li.aFolder { a.editFolderName { display: inline-block; width: 30px; - background: url(../images/IconEditGreyLight.svg) center center no-repeat; + background: url(/admin/images/IconEditGreyLight.svg) center center no-repeat; background-size: 25px; text-indent: -9999px; opacity: 0.5; &:hover { - background: url(../images/IconEditOrange.svg) center center no-repeat; + background: url(/admin/images/IconEditOrange.svg) center center no-repeat; background-size: 25px; opacity: 1; } } a.editingFolderName { @extend .editFolderName; - background: url(../images/IconSave.svg) center center no-repeat; + background: url(/admin/images/IconSave.svg) center center no-repeat; background-size: 70px 70px; &:hover { - background: url(../images/IconSaveOrange.svg) center center no-repeat; + background: url(/admin/images/IconSaveOrange.svg) center center no-repeat; background-size: 70px 70px; opacity: 1; } @@ -2071,7 +2071,7 @@ li.aFolder { padding-bottom: 10px; h2 { color: rgba($akvoBlack, 0.7); - background: url(../images/folderIcn.svg) right center no-repeat; + background: url(/admin/images/folderIcn.svg) right center no-repeat; display: inline; width: initial; padding-right: 45px; @@ -2086,7 +2086,7 @@ li.aFolder { } &.folderEmpty { h2 { - background: url(../images/folderIcnEmpty.svg) right center no-repeat; + background: url(/admin/images/folderIcnEmpty.svg) right center no-repeat; } } } @@ -2223,7 +2223,7 @@ ul.surveyInfo li.responseNumber { -moz-animation: appearFx 2s linear 1 normal forwards; -o-animation: appearFx 2s linear 1 normal forwards; animation: appearFx 2s linear 1 normal forwards; - background-image: url(../images/carret.svg); + background-image: url(/admin/images/carret.svg); background-position: right center; background-repeat: no-repeat; } @@ -2473,24 +2473,24 @@ div.published { } a.publishProjectBtn { - background: $flowAnchorLink url(../images/IconPublishWhite.svg) left center no-repeat; + background: $flowAnchorLink url(/admin/images/IconPublishWhite.svg) left center no-repeat; background-size: 55px 55px; padding: 10px 15px 10px 45px; color: white; border-radius: 3px; &.noChanges { - background: rgba(32, 32, 36, 0.1) url(../images/IconPublishWhite.svg) left center no-repeat; + background: rgba(32, 32, 36, 0.1) url(/admin/images/IconPublishWhite.svg) left center no-repeat; background-size: 55px 55px; padding: 10px 15px 10px 45px; color: white; cursor: text; &:hover { - background: rgba(32, 32, 36, 0.1) url(../images/IconPublishWhite.svg) left center no-repeat; + background: rgba(32, 32, 36, 0.1) url(/admin/images/IconPublishWhite.svg) left center no-repeat; background-size: 55px 55px; } } &:hover { - background: $flowAnchorLinkHover url(../images/IconPublishWhite.svg) left center no-repeat; + background: $flowAnchorLinkHover url(/admin/images/IconPublishWhite.svg) left center no-repeat; background-size: 55px 55px; color: white; } @@ -2619,7 +2619,7 @@ span.qtnGroupHead { display: inline-block; margin: 0 0 0 10px; padding: 0.75em 0.5em 0.25em 17px; - background: url(../images/editTinyIcon.png) left center no-repeat; + background: url(/admin/images/editTinyIcon.png) left center no-repeat; } .aQuestionSet header input { @@ -2650,13 +2650,13 @@ span.qtnGroupHead { padding: 0.50em 0.5em 0.35em 25px; width: 7%; border-radius: 3px; - background: rgb(235, 235, 235) url(../images/addSet.png) left center no-repeat; + background: rgb(235, 235, 235) url(/admin/images/addSet.png) left center no-repeat; color: rgb(227, 27, 35); @include noWrapTxt; } .aQuestionSet footer a.addSet:hover { - background: rgb(214, 214, 214) url(../images/addSet.png) left center no-repeat; + background: rgb(214, 214, 214) url(/admin/images/addSet.png) left center no-repeat; color: rgb(227, 27, 35); } @@ -2774,7 +2774,7 @@ nav.questionActionMenu a:hover { } .aQuestionSet header nav.qtnGroupMenu ul li a.showQuestionGroup { - background: url(../images/IconShow.svg) left center no-repeat; + background: url(/admin/images/IconShow.svg) left center no-repeat; text-align: left; padding-left: 25px; background-size: 14%; @@ -2784,7 +2784,7 @@ nav.questionActionMenu a:hover { } .aQuestionSet header nav.qtnGroupMenu ul li a.showQuestionGroup:hover { - background: url(../images/IconShowHover.svg) left center no-repeat; + background: url(/admin/images/IconShowHover.svg) left center no-repeat; text-align: left; padding-left: 25px; background-size: 14%; @@ -2792,7 +2792,7 @@ nav.questionActionMenu a:hover { .aQuestionSet header nav.qtnGroupMenu ul li a.showQuestionGroup.shown { color: $flowAnchorLinkHover; - background: url(../images/IconShowOrange.svg) left center no-repeat; + background: url(/admin/images/IconShowOrange.svg) left center no-repeat; padding-left: 25px; background-size: 14%; } @@ -2890,43 +2890,43 @@ nav.questionActionMenu a:hover { } // nav.smallMenu ul li a.editQuestion { -// background: url(../images/IconEdit.svg) left center no-repeat; +// background: url(/admin/images/IconEdit.svg) left center no-repeat; // } // nav.smallMenu ul li a.deleteQuestion { -// background: url(../images/IconDelete.svg) left center no-repeat; +// background: url(/admin/images/IconDelete.svg) left center no-repeat; // } // nav.smallMenu ul li a.moveQuestion { -// background: url(../images/IconMove.svg) left center no-repeat; +// background: url(/admin/images/IconMove.svg) left center no-repeat; // } // nav.smallMenu ul li a.copyQuestion { -// background: url(../images/IconCopy.svg) left center no-repeat; +// background: url(/admin/images/IconCopy.svg) left center no-repeat; // } // nav.smallMenu ul li a.showQuestion { -// background: url(../images/IconShow.svg) left center no-repeat; +// background: url(/admin/images/IconShow.svg) left center no-repeat; // } // nav.smallMenu ul li a.editQuestion:hover { -// background: url(../images/IconEditOrange.svg) left center no-repeat; +// background: url(/admin/images/IconEditOrange.svg) left center no-repeat; // } // nav.smallMenu ul li a.deleteQuestion:hover { -// background: url(../images/IconDeleteOrange.svg) left center no-repeat; +// background: url(/admin/images/IconDeleteOrange.svg) left center no-repeat; // } // nav.smallMenu ul li a.moveQuestion:hover { -// background: url(../images/IconMoveOrange.svg) left center no-repeat; +// background: url(/admin/images/IconMoveOrange.svg) left center no-repeat; // } // nav.smallMenu ul li a.copyQuestion:hover { -// background: url(../images/IconCopyOrange.svg) left center no-repeat; +// background: url(/admin/images/IconCopyOrange.svg) left center no-repeat; // } // nav.smallMenu ul li a.showQuestion:hover { -// background: url(../images/IconShowOrange.svg) left center no-repeat; +// background: url(/admin/images/IconShowOrange.svg) left center no-repeat; // } /*------------------------------------------------------------------------------------------------------------------------------- @@ -3703,7 +3703,7 @@ div.drawHandle { .placeMarkBasicInfo { padding: 1em 2%; width: 96%; - background: url(../images/mapPointDetailSep.png) center bottom no-repeat; + background: url(/admin/images/mapPointDetailSep.png) center bottom no-repeat; } .placeMarkBasicInfo li { @@ -3830,7 +3830,7 @@ footer.bottomPage nav ul li a { footer.bottomPage nav ul li a.akvoDotOrg { margin: 0 10px 0 0; width: 42px; - background: url(../images/akvo.orgLogo.svg) center center no-repeat; + background: url(/admin/images/akvo.orgLogo.svg) center center no-repeat; text-indent: -9999px; } @@ -4254,7 +4254,7 @@ table#languageOption td.formTitle { table.surveyTranslate { -o-border-radius: 0.25em; border-radius: 0.25em; - background: white url(../images/borderMiddle.png) center top repeat-y; + background: white url(/admin/images/borderMiddle.png) center top repeat-y; } table.surveyTranslate td { @@ -4689,7 +4689,7 @@ table.surveyDetails { } .tabNav { .aFormTab { - background: rgb(32, 32, 36) url(../images/IconForms.png) no-repeat left center; + background: rgb(32, 32, 36) url(/admin/images/IconForms.png) no-repeat left center; } } } @@ -4892,10 +4892,10 @@ table.surveyDetails { width: 20px; text-indent: -9999px; &.editSurvey { - background: url(../images/IconEdit.svg) center center no-repeat; + background: url(/admin/images/IconEdit.svg) center center no-repeat; background-size: 18px 18px; &:hover { - background: url(../images/IconEditOrange.svg) center center no-repeat; + background: url(/admin/images/IconEditOrange.svg) center center no-repeat; background-size: 18px 18px; } } @@ -5073,19 +5073,19 @@ nav.cascadeBreadCrumb { color: white; padding: 0 2%; width: 96%; - background: url(../images/carret.svg) right center no-repeat; + background: url(/admin/images/carret.svg) right center no-repeat; margin: 5px auto; background-size: 15px 15px; border-top: 1px solid rgba(32, 32, 36, 0.1); &:first-of-type {} &:hover { - background: rgba(255, 255, 255, 0.2) url(../images/carret.svg) right center no-repeat; + background: rgba(255, 255, 255, 0.2) url(/admin/images/carret.svg) right center no-repeat; background-size: 15px 15px; cursor: pointer; box-shadow: 1px 1px 1px rgba(32, 32, 36, 0.2); } &.selected { - background: rgba(41, 119, 152, 0.1) url(../images/carret.svg) right center no-repeat; + background: rgba(41, 119, 152, 0.1) url(/admin/images/carret.svg) right center no-repeat; background-size: 15px 15px; cursor: text; box-shadow: 1px 1px 1px rgba(32, 32, 36, 0.2); @@ -5146,13 +5146,13 @@ a.levelUp { display: table; margin: 20px auto 0; padding: 15px 35px 15px 15px; - background: rgba($flowAnchorLink, 0) url(../images/IconRightBlue.svg) right center no-repeat; + background: rgba($flowAnchorLink, 0) url(/admin/images/IconRightBlue.svg) right center no-repeat; -webkit-transition: color 0.2s ease-in, background-color 0.2s ease-in; transition: color 0.2s ease-in, background-color 0.2s ease-in; -webkit-background-size: 25px 25px; background-size: 25px 25px; &:hover { - background: rgba($flowAnchorLink, 0.1) url(../images/IconRightOrange.svg) right center no-repeat; + background: rgba($flowAnchorLink, 0.1) url(/admin/images/IconRightOrange.svg) right center no-repeat; -webkit-background-size: 25px 25px; background-size: 25px 25px; } @@ -5162,13 +5162,13 @@ a.levelDown { display: table; margin: 20px auto 0; padding: 15px 15px 15px 35px; - background: rgba($flowAnchorLink, 0) url(../images/IconLeftBlue.svg) left center no-repeat; + background: rgba($flowAnchorLink, 0) url(/admin/images/IconLeftBlue.svg) left center no-repeat; -webkit-transition: color 0.2s ease-in, background-color 0.2s ease-in; transition: color 0.2s ease-in, background-color 0.2s ease-in; -webkit-background-size: 25px 25px; background-size: 25px 25px; &:hover { - background: rgba($flowAnchorLink, 0.1) url(../images/IconLeftOrange.svg) left center no-repeat; + background: rgba($flowAnchorLink, 0.1) url(/admin/images/IconLeftOrange.svg) left center no-repeat; -webkit-background-size: 25px 25px; background-size: 25px 25px; } @@ -5181,13 +5181,13 @@ li.disable { @include opacity(0.2); color: white; padding: 15px 35px 15px 15px; - background: rgba($flowAnchorLink, 0) url(../images/IconRightWhite.svg) right center no-repeat; + background: rgba($flowAnchorLink, 0) url(/admin/images/IconRightWhite.svg) right center no-repeat; -webkit-background-size: 25px 25px; background-size: 25px 25px; &:hover { -webkit-background-size: 25px 25px; background-size: 25px 25px; - background: rgba($flowAnchorLink, 0) url(../images/IconRightWhite.svg) right center no-repeat; + background: rgba($flowAnchorLink, 0) url(/admin/images/IconRightWhite.svg) right center no-repeat; } } a.levelDown { @@ -5196,11 +5196,11 @@ li.disable { @include opacity(0.2); color: white; padding: 15px 15px 15px 35px; - background: rgba($flowAnchorLink, 0) url(../images/IconLeftWhite.svg) left center no-repeat; + background: rgba($flowAnchorLink, 0) url(/admin/images/IconLeftWhite.svg) left center no-repeat; -webkit-background-size: 25px 25px; background-size: 25px 25px; &:hover { - background: rgba($flowAnchorLink, 0) url(../images/IconLeftWhite.svg) left center no-repeat; + background: rgba($flowAnchorLink, 0) url(/admin/images/IconLeftWhite.svg) left center no-repeat; -webkit-background-size: 25px 25px; background-size: 25px 25px; } @@ -5282,7 +5282,7 @@ li.disable { border-radius: 3px; box-shadow: 0 5px 8px rgba(212, 212, 212, 0.5); padding: 5px 3px 5px 25px; - background: rgb(248, 248, 248) url(../images/loader.gif) 5px center no-repeat; + background: rgb(248, 248, 248) url(/admin/images/loader.gif) 5px center no-repeat; color: rgb(252, 159, 0); font-weight: bold; } @@ -5481,9 +5481,9 @@ html.navMaps, .public { padding: 5px 0 10px 25px; -webkit-background-size: 15px auto; background-size: 15px auto; - background: url(../images/topnavUsers.svg) left center no-repeat; + background: url(/admin/images/topnavUsers.svg) left center no-repeat; &:hover { - background: url(../images/topnavUsersOrange.svg) left center no-repeat; + background: url(/admin/images/topnavUsersOrange.svg) left center no-repeat; } } } @@ -5587,13 +5587,13 @@ svg { &.homeRoot { border-radius: 3px 0 0 3px; width: 40px; - background: url(../images/breadCrumb-Root.png) center center no-repeat $akvoBlack; + background: url(/admin/images/breadCrumb-Root.png) center center no-repeat $akvoBlack; background-size: 40%; text-indent: -9999px; z-index: 9999; margin-left: 0; &:hover { - background: url(../images/breadCrumb-Root.png) center center no-repeat $akvoBlack; + background: url(/admin/images/breadCrumb-Root.png) center center no-repeat $akvoBlack; background-size: 40%; } } @@ -5632,31 +5632,31 @@ svg { } &.dataCleanExp { h2 { - background: url(../images/Export01.svg) center top no-repeat; + background: url(/admin/images/Export01.svg) center top no-repeat; background-size: 60px; } } &.dataAnalyseExp { h2 { - background: url(../images/Export02.svg) center top no-repeat; + background: url(/admin/images/Export02.svg) center top no-repeat; background-size: 60px; } } &.compReportExp { h2 { - background: url(../images/Export03.svg) center top no-repeat; + background: url(/admin/images/Export03.svg) center top no-repeat; background-size: 60px; } } &.geoShapeDataExp { h2 { - background: url(../images/Export04.svg) center top no-repeat; + background: url(/admin/images/Export04.svg) center top no-repeat; background-size: 60px; } } &.surveyFormExp { h2 { - background: url(../images/Export05.svg) center top no-repeat; + background: url(/admin/images/Export05.svg) center top no-repeat; background-size: 60px; } } @@ -5851,7 +5851,7 @@ svg { text-align: center; .zipIcn { height: 80px; - background: url(../images/zipIcn.svg) center top no-repeat; + background: url(/admin/images/zipIcn.svg) center top no-repeat; background-size: 60px; } p { @@ -6267,7 +6267,7 @@ svg { display: inline-block; width: 100%; height: 23px; - background: url(../images/loading.svg) left center no-repeat; + background: url(/admin/images/loading.svg) left center no-repeat; background-size: contain; font-size: 0.8em; } @@ -6300,45 +6300,52 @@ svg { } } &.dataCleanExp { - background: url(../images/Export01.svg) 15px center no-repeat; + background: url(/admin/images/Export01.svg) 15px center no-repeat; background-size: 30px; &.exportGenerating { - background: rgba(128, 128, 128, 0.1) url(../images/Export01.svg) 15px center no-repeat; + background: rgba(128, 128, 128, 0.1) url(/admin/images/Export01.svg) 15px center no-repeat; background-size: 30px; } } &.dataAnalyseExp { - background: url(../images/Export02.svg) 15px center no-repeat; + background: url(/admin/images/Export02.svg) 15px center no-repeat; background-size: 30px; &.exportGenerating { - background: rgba(128, 128, 128, 0.1) url(../images/Export02.svg) 15px center no-repeat; + background: rgba(128, 128, 128, 0.1) url(/admin/images/Export02.svg) 15px center no-repeat; background-size: 30px; } } &.compReportExp { - background: url(../images/Export03.svg) 15px center no-repeat; + background: url(/admin/images/Export03.svg) 15px center no-repeat; background-size: 30px; &.exportGenerating { - background: rgba(128, 128, 128, 0.1) url(../images/Export03.svg) 15px center no-repeat; + background: rgba(128, 128, 128, 0.1) url(/admin/images/Export03.svg) 15px center no-repeat; background-size: 30px; } } &.geoShapeDataExp { - background: url(../images/Export04.svg) 15px center no-repeat; + background: url(/admin/images/Export04.svg) 15px center no-repeat; background-size: 30px; &.exportGenerating { - background: rgba(128, 128, 128, 0.1) url(../images/Export04.svg) 15px center no-repeat; + background: rgba(128, 128, 128, 0.1) url(/admin/images/Export04.svg) 15px center no-repeat; background-size: 30px; } } &.surveyFormExp { - background: url(../images/Export05.svg) 15px center no-repeat; + background: url(/admin/images/Export05.svg) 15px center no-repeat; background-size: 30px; &.exportGenerating { - background: rgba(128, 128, 128, 0.1) url(../images/Export05.svg) 15px center no-repeat; + background: rgba(128, 128, 128, 0.1) url(/admin/images/Export05.svg) 15px center no-repeat; background-size: 30px; } } } } -} \ No newline at end of file +} + +.not-active { + pointer-events: none; + cursor: default; + text-decoration: none; + color: black; +} diff --git a/Dashboard/app/css/screen.css b/Dashboard/app/css/screen.css deleted file mode 100644 index ba87fcaf05..0000000000 --- a/Dashboard/app/css/screen.css +++ /dev/null @@ -1,3 +0,0 @@ -@import url("main.css"); - -@import url("custom-theme/jquery-ui-1.8.21.custom.css"); \ No newline at end of file diff --git a/Dashboard/app/css/screen.scss b/Dashboard/app/css/screen.scss new file mode 100644 index 0000000000..768d26ece0 --- /dev/null +++ b/Dashboard/app/css/screen.scss @@ -0,0 +1,3 @@ +@import "main.scss"; + +@import "custom-theme/jquery-ui-1.8.21.custom.css"; \ No newline at end of file diff --git a/Dashboard/app/dashboard.html b/Dashboard/app/dashboard.ejs similarity index 65% rename from Dashboard/app/dashboard.html rename to Dashboard/app/dashboard.ejs index 026d691d44..8ba68a250c 100644 --- a/Dashboard/app/dashboard.html +++ b/Dashboard/app/dashboard.ejs @@ -13,15 +13,14 @@ - - - - -
+ + - + @@ -29,14 +28,10 @@ + - - - - - - - + diff --git a/Dashboard/app/js/lib/analytics.js b/Dashboard/app/js/lib/analytics.js new file mode 100644 index 0000000000..49a16ce53c --- /dev/null +++ b/Dashboard/app/js/lib/analytics.js @@ -0,0 +1,20 @@ +var _paq = _paq || []; +_paq.push(['setDocumentTitle', `${document.domain}/${document.title}`]); +_paq.push(['setCookieDomain', '*.akvoflow.org']); +_paq.push(['setDomains', ['*.akvoflow.org']]); +_paq.push(['trackPageView']); +_paq.push(['enableLinkTracking']); + +(function () { + const u = `${(document.location.protocol == 'https:') ? 'https' : 'http'}://analytics.akvo.org/`; + _paq.push(['setTrackerUrl', `${u}piwik.php`]); + _paq.push(['setSiteId', '10']); + const d = document; + const g = d.createElement('script'); + const s = d.getElementsByTagName('script')[0]; + g.type = 'text/javascript'; + g.defer = true; + g.async = true; + g.src = `${u}piwik.js`; + s.parentNode.insertBefore(g, s); +}()); diff --git a/Dashboard/app/js/lib/controllers/controllers-public.js b/Dashboard/app/js/lib/controllers/controllers-public.js index 0004a33f80..977b5601cf 100644 --- a/Dashboard/app/js/lib/controllers/controllers-public.js +++ b/Dashboard/app/js/lib/controllers/controllers-public.js @@ -3,8 +3,8 @@ // ***********************************************// // Define the main application controller. This is automatically picked up by // the application and initialized. +loader.require('akvo-flow/flowenv'); require('akvo-flow/core-common'); -require('akvo-flow/flowenv'); require('akvo-flow/controllers/general-controllers-common'); require('akvo-flow/controllers/maps-controllers-common'); diff --git a/Dashboard/app/js/lib/controllers/controllers.js b/Dashboard/app/js/lib/controllers/controllers.js index 66fe8e7164..96bb6632b4 100644 --- a/Dashboard/app/js/lib/controllers/controllers.js +++ b/Dashboard/app/js/lib/controllers/controllers.js @@ -3,10 +3,10 @@ // ***********************************************// // Define the main application controller. This is automatically picked up by // the application and initialized. +loader.require('akvo-flow/flowenv'); +loader.require('akvo-flow/currentuser'); require('akvo-flow/core-common'); -require('akvo-flow/flowenv'); require('akvo-flow/controllers/languages'); -require('akvo-flow/currentuser'); require('akvo-flow/controllers/permissions'); require('akvo-flow/controllers/general-controllers-common'); require('akvo-flow/controllers/survey-controllers'); @@ -21,21 +21,19 @@ require('akvo-flow/controllers/survey-selection'); FLOW.ApplicationController = Ember.Controller.extend({}); FLOW.role = Ember.Object.create({ - SUPER_ADMIN: function () { + SUPER_ADMIN: Ember.computed(function () { return FLOW.currentUser && FLOW.currentUser.permissionList === 0; - }.property(), + }).property(), - ADMIN: function () { + ADMIN: Ember.computed(function () { return FLOW.currentUser && FLOW.currentUser.permissionList <= 10; - }.property(), + }).property(), - USER: function () { + USER: Ember.computed(function () { return FLOW.currentUser && FLOW.currentUser.permissionList <= 20; - }.property() + }).property() }); -//require('akvo-flow/currentuser'); - // Navigation controllers FLOW.NavigationController = Em.Controller.extend({ selected: null diff --git a/Dashboard/app/js/lib/controllers/data-controllers.js b/Dashboard/app/js/lib/controllers/data-controllers.js index f128df9bfb..da7870fa50 100644 --- a/Dashboard/app/js/lib/controllers/data-controllers.js +++ b/Dashboard/app/js/lib/controllers/data-controllers.js @@ -1,10 +1,13 @@ +import observe from '../mixins/observe'; function capitaliseFirstLetter(string) { if (Ember.empty(string)) return ""; return string.charAt(0).toUpperCase() + string.slice(1); } -FLOW.cascadeResourceControl = Ember.ArrayController.create({ +FLOW.cascadeResourceControl = Ember.ArrayController.create(observe({ + 'FLOW.selectedControl.selectedCascadeResource': 'hasQuestions', +}), { content:null, published:null, statusUpdateTrigger:false, @@ -74,13 +77,13 @@ FLOW.cascadeResourceControl = Ember.ArrayController.create({ return; } FLOW.store.findQuery(FLOW.Question, {cascadeResourceId: FLOW.selectedControl.selectedCascadeResource.get('keyId')}); - }.observes('FLOW.selectedControl.selectedCascadeResource'), + }, triggerStatusUpdate: function(){ this.toggleProperty('statusUpdateTrigger'); }, - currentStatus: function () { + currentStatus: Ember.computed(function () { // hack to get translation keys, don't delete them // {{t _not_published}} // {{t _publishing}} @@ -91,14 +94,14 @@ FLOW.cascadeResourceControl = Ember.ArrayController.create({ } status = ('_' + FLOW.selectedControl.selectedCascadeResource.get('status')).toLowerCase(); return Ember.String.loc(status); - }.property('FLOW.selectedControl.selectedCascadeResource','this.statusUpdateTrigger'), + }).property('FLOW.selectedControl.selectedCascadeResource','this.statusUpdateTrigger'), - isPublished: function () { + isPublished: Ember.computed(function () { if (!FLOW.selectedControl.selectedCascadeResource) { return false; } return FLOW.selectedControl.selectedCascadeResource.get('status') === 'PUBLISHED'; - }.property('FLOW.selectedControl.selectedCascadeResource','this.statusUpdateTrigger') + }).property('FLOW.selectedControl.selectedCascadeResource','this.statusUpdateTrigger') }); FLOW.cascadeNodeControl = Ember.ArrayController.create({ @@ -167,7 +170,10 @@ FLOW.cascadeNodeControl = Ember.ArrayController.create({ }); -FLOW.surveyInstanceControl = Ember.ArrayController.create({ +FLOW.surveyInstanceControl = Ember.ArrayController.create(observe({ + content: 'contentChanged', + 'content.isLoaded': 'contentChanged', +}), { sortProperties: ['collectionDate'], sortAscending: false, selectedSurvey: null, @@ -202,7 +208,7 @@ FLOW.surveyInstanceControl = Ember.ArrayController.create({ }); this.set('currentContents', mutableContents); - }.observes('content', 'content.isLoaded'), + }, removeInstance: function(instance) { this.get('currentContents').forEach(function(item, i, currentContents) { @@ -212,18 +218,18 @@ FLOW.surveyInstanceControl = Ember.ArrayController.create({ }); }, - allAreSelected: function (key, value) { + allAreSelected: Ember.computed(function (key, value) { if (arguments.length === 2) { this.setEach('isSelected', value); return value; } else { return !this.get('isEmpty') && this.everyProperty('isSelected', true); } - }.property('@each.isSelected'), + }).property('@each.isSelected'), - atLeastOneSelected: function () { + atLeastOneSelected: Ember.computed(function () { return this.filterProperty('isSelected', true).get('length'); - }.property('@each.isSelected'), + }).property('@each.isSelected'), // fired from tableColumnView.sort getSortInfo: function () { @@ -232,7 +238,10 @@ FLOW.surveyInstanceControl = Ember.ArrayController.create({ } }); -FLOW.SurveyedLocaleController = Ember.ArrayController.extend({ +FLOW.SurveyedLocaleController = Ember.ArrayController.extend(observe({ + content: 'contentChanged', + 'content.isLoaded': 'contentChanged', +}), { sortProperties: ['collectionDate'], sortAscending: false, selectedSurvey: null, @@ -251,7 +260,7 @@ FLOW.SurveyedLocaleController = Ember.ArrayController.extend({ }); this.set('currentContents', mutableContents); - }.observes('content', 'content.isLoaded'), + }, removeLocale: function(locale) { this.get('currentContents').forEach(function(item, i, currentContents) { @@ -263,7 +272,7 @@ FLOW.SurveyedLocaleController = Ember.ArrayController.extend({ /* the current user is able to delete surveyed locales stored in the 'content' property of this controller */ - userCanDelete: function() { + userCanDelete: Ember.computed(function() { if(this.get('content') === null) { return false; } @@ -272,7 +281,7 @@ FLOW.SurveyedLocaleController = Ember.ArrayController.extend({ return FLOW.surveyGroupControl.userCanDeleteData(surveyedLocale.get('surveyGroupId')); } return false; // prevents deletion incase no surveyId found - }.property('content'), + }).property('content'), }); FLOW.questionAnswerControl = Ember.ArrayController.create({ @@ -367,7 +376,10 @@ FLOW.questionAnswerControl = Ember.ArrayController.create({ }, }); -FLOW.locationControl = Ember.ArrayController.create({ +FLOW.locationControl = Ember.ArrayController.create(observe({ + 'this.selectedCountry': 'populateLevel1', + 'this.selectedLevel1': 'populateLevel2', +}), { selectedCountry: null, content:null, level1Content:null, @@ -383,7 +395,7 @@ FLOW.locationControl = Ember.ArrayController.create({ parentId:null })); } - }.observes('this.selectedCountry'), + }, populateLevel2: function(){ if (!Ember.none(this.get('selectedLevel1')) && this.selectedLevel1.get('name').length > 0){ @@ -393,7 +405,7 @@ FLOW.locationControl = Ember.ArrayController.create({ parentId:this.selectedLevel1.get('keyId') })); } - }.observes('this.selectedLevel1') + }, }); @@ -451,7 +463,7 @@ FLOW.ApprovalGroupController = Ember.ObjectController.extend({ * to a string representation in order to bind successfully to * value attribute of the generated