diff --git a/.cloud66/manifest.yml b/.cloud66/manifest.yml index 48edce71c..ba6a15581 100644 --- a/.cloud66/manifest.yml +++ b/.cloud66/manifest.yml @@ -11,8 +11,6 @@ development: region: us-east-1 size: m3.medium root_disk_size: 50 - extra_packages: - - jpegoptim postgresql: configuration: version: 9.6.3 @@ -48,8 +46,6 @@ staging: region: us-east-1 size: m3.medium root_disk_size: 50 - extra_packages: - - jpegoptim postgresql: configuration: version: 9.6.3 @@ -85,8 +81,6 @@ production: region: us-east-1 size: c4.xlarge root_disk_size: 50 - extra_packages: - - jpegoptim postgresql: configuration: version: 9.6.3 diff --git a/.cloud66/scripts/db_seed.sh b/.cloud66/scripts/db_seed.sh index fa75ee304..869d9a2f9 100644 --- a/.cloud66/scripts/db_seed.sh +++ b/.cloud66/scripts/db_seed.sh @@ -1,4 +1,4 @@ #!/bin/bash cd $STACK_PATH -bundle exec rake db:seed cortex:create_categories cortex:onet:fetch_and_provision +bundle exec rake db:seed diff --git a/.codeclimate.yml b/.codeclimate.yml index c36550f2e..6c609bf38 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -41,34 +41,8 @@ exclude_paths: - vendor/ - app/interactors/ - app/api/ -- app/assets/javascripts/legacy/ -- app/assets/javascripts/legacy_application.js -- app/assets/legacy_templates/ -- app/assets/stylesheets/legacy/ -- app/assets/stylesheets/legacy_application.scss -- app/controllers/legacy_controller.rb -- app/views/legacy/ - app/models/abilities/ -- app/models/observers/ -- app/models/media_types/ -- app/models/post_types/ -- app/models/onet/ -- app/models/concerns/searchable* - app/models/application.rb -- app/models/author.rb -- app/models/bulk_job.rb -- app/models/category.rb -- app/models/document.rb - app/models/locale.rb - app/models/localization.rb -- app/models/media.rb -- app/models/onet.rb -- app/models/post.rb -- app/models/snippet.rb -- app/models/webpage.rb -- app/jobs/bulk_create_media_job.rb -- app/jobs/bulk_create_users_job.rb -- app/jobs/cache_bust_webpage_job.rb -- app/jobs/youtube_media_job.rb -- app/jobs/youtube_media_job.rb - lib/tasks/cortex.rake diff --git a/.env.example b/.env.example index 80c02d03b..76e14a973 100644 --- a/.env.example +++ b/.env.example @@ -5,14 +5,12 @@ DEVISE_SECRET= # # Asset Host Configuration # -FOG_HOST=http://localhost:3000 HOST_ALIAS= # S3 S3_ACCESS_KEY_ID= S3_SECRET_ACCESS_KEY= S3_BUCKET_NAME= -S3_PROTOCOL= S3_REGION= # @@ -32,16 +30,6 @@ SMTP_USERNAME= SMTP_PASSWORD= SMTP_STARTTLS=true -# -# ONET version to use for `rake cortex:onet:fetch_and_provision` -# -ONET_VERSION=18.1 - -# -# Maximum media filesize -# -MEDIA_MAX_SIZE_MB=100 - # # CORS Configuration # @@ -56,9 +44,6 @@ CORS_ALLOWED_ORIGINS_REGEX= # External Services # -# APIs -YOUTUBE_API_KEY= - # Vendor/3rd Party Script Configuration GOOGLE_ANALYTICS_ID= QUALTRICS_ID= diff --git a/.gitignore b/.gitignore index c19fd93b4..5b872a734 100644 --- a/.gitignore +++ b/.gitignore @@ -9,12 +9,7 @@ /vendor/bundle /vendor/assets -/public/asset_field_types/ /public/assets/ -/public/media/ -/public/youtubes/ -/public/bulk_jobs/ -/public/content-snippets-edit /public/uploads/ # Ignore the default SQLite database. @@ -53,9 +48,6 @@ pickle-email-*.html .env /.cloud66/stack.json -# Test Artifacts -/media - # these should all be checked in to normalise the environment: # Gemfile.lock, .ruby-version, .ruby-gemset diff --git a/Brewfile b/Brewfile index 0d1195a3e..424822a5f 100644 --- a/Brewfile +++ b/Brewfile @@ -5,5 +5,4 @@ Caskroom/cask/java elasticsearch phantomjs imagemagick -jpegoptim ghostscript diff --git a/Gemfile b/Gemfile index 19c345602..115164d0c 100644 --- a/Gemfile +++ b/Gemfile @@ -28,11 +28,7 @@ gem 'rolify', '~> 5.1' gem 'pundit', '~> 1.1' # Data -gem 'rails-observers', git: 'https://github.com/triloch/rails-observers.git' -gem 'awesome_nested_set', git: 'https://github.com/cortex-cms/awesome_nested_set.git' -gem 'paperclip', '~> 5.1.0' -gem 'paperclip-optimizer', '~> 2.0' -gem 'image_optim_pack', '~> 0.4.0' +gem 'awesome_nested_set', '~> 3.1.3' gem 'acts-as-taggable-on', '~> 4.0' gem 'bcrypt', '~> 3.1.11' gem 'kaminari', '~> 0.17.0' @@ -51,23 +47,20 @@ gem 'deep_cloneable', '~> 2.2.2' gem 'rack-cors', '~> 0.4.1', require: 'rack/cors' # Utility -gem 'excon', '~> 0.55.0' gem 'hashie', '~> 3.5.5' gem 'hashr', '~> 2.0.1' -gem 'mime-types', '~> 3.1.0' -gem 'interactor-rails', '~> 2.0' +gem 'mimemagic', '~> 0.3.2' gem 'virtus', '~> 1.0.5' -gem 'rubyzip', '~> 1.2.1' +gem 'interactor-rails', '~> 2.1' gem 'addressable', '~> 2.5.1' gem 'json' # External Services -gem 'yt', '~> 0.30.1' gem 'aws-sdk', '~> 2.9' # Jobs gem 'sidekiq', '~> 5.0.0' -#gem 'sidekiq-failures', '~> 0.4.5' # Disabled until it supports sidekiq 5.x +gem 'sidekiq-failures', '~> 1.0.0' gem 'sinatra', '~> 2.0.0.rc', require: false # Pipeline @@ -75,8 +68,6 @@ gem 'sprockets-rails', '3.2.0', require: 'sprockets/railtie' gem 'sprockets', '3.7.1' gem 'uglifier', '~> 3.2.0' gem 'non-stupid-digest-assets', '~> 1.0.9' -gem 'angular-rails-templates', '~> 1.0.2' -gem 'ngannotate-rails', '~> 1.2.2' # View gem 'haml', '~> 5.0' @@ -99,7 +90,6 @@ gem 'turbolinks', '~> 5.0.1' gem 'jquery-rails', '~> 4.3.1' gem 'jquery-turbolinks', '~> 2.1' gem 'jquery-ui-rails', '~> 6.0.1' -gem 'ng-rails-csrf', '~> 0.1.0' gem 'bootstrap-tagsinput-rails', '~> 0.4.2' gem 'dialog-polyfill-rails', '~> 0.4.5' @@ -169,7 +159,6 @@ end group :test, :development do gem 'factory_girl_rails', '~> 4.8' gem 'faker', '~> 1.7' - gem 'fog-local', '~> 0.3.1' gem 'phantomjs', '~> 2.1.1' gem 'jasmine-rails', '~> 0.14' end diff --git a/Gemfile.lock b/Gemfile.lock index 402ebf964..4d128d29d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,53 +1,39 @@ -GIT - remote: https://github.com/cortex-cms/awesome_nested_set.git - revision: d3bad27fa959788e403becc411f6db9d1aac1dfb - specs: - awesome_nested_set (3.1.2) - activerecord (>= 4.0.0, < 5.1) - -GIT - remote: https://github.com/triloch/rails-observers.git - revision: ea30390cb07b4a37dd2f9d03966c89c1372f9dbe - specs: - rails-observers (0.1.3.alpha) - activemodel (>= 4.0, < 5.1) - GEM remote: https://rubygems.org/ specs: - actioncable (5.0.2) - actionpack (= 5.0.2) + actioncable (5.0.4) + actionpack (= 5.0.4) nio4r (>= 1.2, < 3.0) websocket-driver (~> 0.6.1) - actionmailer (5.0.2) - actionpack (= 5.0.2) - actionview (= 5.0.2) - activejob (= 5.0.2) + actionmailer (5.0.4) + actionpack (= 5.0.4) + actionview (= 5.0.4) + activejob (= 5.0.4) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.0.2) - actionview (= 5.0.2) - activesupport (= 5.0.2) + actionpack (5.0.4) + actionview (= 5.0.4) + activesupport (= 5.0.4) rack (~> 2.0) rack-test (~> 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.0.2) - activesupport (= 5.0.2) + actionview (5.0.4) + activesupport (= 5.0.4) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.0.2) - activesupport (= 5.0.2) + activejob (5.0.4) + activesupport (= 5.0.4) globalid (>= 0.3.6) - activemodel (5.0.2) - activesupport (= 5.0.2) - activerecord (5.0.2) - activemodel (= 5.0.2) - activesupport (= 5.0.2) + activemodel (5.0.4) + activesupport (= 5.0.4) + activerecord (5.0.4) + activemodel (= 5.0.4) + activesupport (= 5.0.4) arel (~> 7.0) - activesupport (5.0.2) + activesupport (5.0.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) @@ -56,22 +42,20 @@ GEM activerecord (>= 4.0) addressable (2.5.1) public_suffix (~> 2.0, >= 2.0.2) - angular-rails-templates (1.0.2) - railties (>= 4.2, < 6) - sprockets (>= 3.0, < 5) - tilt ansi (1.5.0) arel (7.1.4) attr_required (1.0.1) - autoprefixer-rails (6.7.7.2) + autoprefixer-rails (7.1.2.1) execjs - aws-sdk (2.9.14) - aws-sdk-resources (= 2.9.14) - aws-sdk-core (2.9.14) + awesome_nested_set (3.1.3) + activerecord (>= 4.0.0, < 5.2) + aws-sdk (2.10.9) + aws-sdk-resources (= 2.10.9) + aws-sdk-core (2.10.9) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-resources (2.9.14) - aws-sdk-core (= 2.9.14) + aws-sdk-resources (2.10.9) + aws-sdk-core (= 2.10.9) aws-sigv4 (1.0.0) axiom-types (0.1.1) descendants_tracker (~> 0.0.4) @@ -94,14 +78,14 @@ GEM breadcrumbs_on_rails (3.0.1) builder (3.2.3) byebug (9.0.6) - capybara (2.13.0) + capybara (2.14.4) addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - cells (4.1.6) + cells (4.1.7) declarative-builder (< 0.2.0) declarative-option (< 0.2.0) tilt (>= 1.4, < 3) @@ -109,16 +93,13 @@ GEM cells-haml (0.0.10) cells (>= 4.0.1, <= 6.0.0) haml (>= 4.1.0.beta.1) - cells-rails (0.0.7) + cells-rails (0.0.8) actionpack (>= 3.0) cells (>= 4.1.6, < 5.0.0) - childprocess (0.6.3) + childprocess (0.7.1) ffi (~> 1.0, >= 1.0.11) choice (0.2.0) - climate_control (0.1.0) cliver (0.3.2) - cocaine (0.5.8) - climate_control (>= 0.0.3, < 1.0) codeclimate-test-reporter (0.6.0) simplecov (>= 0.7.1, < 1.0.0) coderay (1.1.1) @@ -139,8 +120,8 @@ GEM rails (>= 4) react_on_rails (~> 6) shrine (~> 2.6) - database_cleaner (1.5.3) - debug_inspector (0.0.2) + database_cleaner (1.6.1) + debug_inspector (0.0.3) declarative-builder (0.1.0) declarative-option (< 0.2.0) declarative-option (0.1.0) @@ -157,13 +138,13 @@ GEM dialog-polyfill-rails (0.4.5.1) diff-lcs (1.3) docile (1.1.5) - doorkeeper (4.2.5) + doorkeeper (4.2.6) railties (>= 4.2) dotenv (2.2.1) dotenv-rails (2.2.1) dotenv (= 2.2.1) railties (>= 3.2, < 5.2) - down (2.5.1) + down (4.0.1) elasticsearch (5.0.4) elasticsearch-api (= 5.0.4) elasticsearch-transport (= 5.0.4) @@ -181,21 +162,19 @@ GEM elasticsearch-transport (5.0.4) faraday multi_json - email_spec (2.1.0) + email_spec (2.1.1) htmlentities (~> 4.3.3) launchy (~> 2.1) - mail (~> 2.6.3) + mail (~> 2.6) equalizer (0.0.11) erubis (2.7.0) - excon (0.55.0) execjs (2.7.0) - exifr (1.2.5) factory_girl (4.8.0) activesupport (>= 3.0.0) factory_girl_rails (4.8.0) factory_girl (~> 4.8.0) railties (>= 3.0.0) - faker (1.7.3) + faker (1.8.2) i18n (~> 0.5) faraday (0.12.1) multipart-post (>= 1.2, < 3) @@ -210,18 +189,11 @@ GEM flipper (~> 0.10.2) rack (>= 1.4, < 3) rack-protection (>= 1.5.3, < 2.1.0) - fog-core (1.44.1) - builder - excon (~> 0.49) - formatador (~> 0.2) - fog-local (0.3.1) - fog-core (~> 1.27) font-awesome-sass (4.7.0) sass (>= 3.2) foreman (0.84.0) thor (~> 0.19.1) formatador (0.2.5) - fspath (3.1.0) globalid (0.4.0) activesupport (>= 4.2.0) gon (6.1.0) @@ -269,7 +241,7 @@ GEM guard (~> 2.1) guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) - haml (5.0.0) + haml (5.0.1) temple (>= 0.8.0) tilt hashie (3.5.5) @@ -278,30 +250,19 @@ GEM hashr (2.0.1) htmlentities (4.3.4) httpclient (2.8.3) - i18n (0.8.1) + i18n (0.8.6) ice_nine (0.11.2) - image_optim (0.24.2) - exifr (~> 1.2, >= 1.2.2) - fspath (~> 3.0) - image_size (~> 1.5) - in_threads (~> 1.3) - progress (~> 3.0, >= 3.0.1) - image_optim_pack (0.4.0) - fspath (>= 2.1, < 4) - image_optim (~> 0.19) - image_processing (0.4.1) - image_size (1.5.0) - in_threads (1.4.0) + image_processing (0.4.4) interactor (3.1.0) - interactor-rails (2.0.2) + interactor-rails (2.1.1) interactor (~> 3.0) - rails (>= 3, < 5.1) + rails (>= 4.2, < 5.2) jasmine (2.6.0) jasmine-core (>= 2.6.0, < 3.0.0) phantomjs rack (>= 1.2.1) rake - jasmine-core (2.6.1) + jasmine-core (2.6.4) jasmine-rails (0.14.1) jasmine-core (>= 1.3, < 3.0) phantomjs (>= 1.9) @@ -318,7 +279,7 @@ GEM jquery-ui-rails (6.0.1) railties (>= 3.2.16) json (2.1.0) - json_spec (1.1.4) + json_spec (1.1.5) multi_json (~> 1.0) rspec (>= 2.0, < 4.0) jsonb_accessor (1.0.0.beta.6) @@ -337,23 +298,23 @@ GEM ruby_dep (~> 1.2) loofah (2.0.3) nokogiri (>= 1.5.9) - lumberjack (1.0.11) - mail (2.6.5) + lumberjack (1.0.12) + mail (2.6.6) mime-types (>= 1.16, < 4) - material_design_lite-sass (1.3.0) - autoprefixer-rails (~> 6.0) - sass (~> 3.3) + material_design_lite-sass (1.3.0.1) + autoprefixer-rails (>= 6.5) + sass (>= 3.3) metaclass (0.0.4) method_source (0.8.2) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mimemagic (0.3.2) - mini_magick (4.7.0) - mini_portile2 (2.1.0) + mini_magick (4.8.0) + mini_portile2 (2.2.0) mini_racer (0.1.9) libv8 (~> 5.3) - minitest (5.10.1) + minitest (5.10.2) mocha (1.2.1) metaclass (~> 0.0.1) multi_json (1.12.1) @@ -363,39 +324,25 @@ GEM mustermann-grape (1.0.0) mustermann (~> 1.0.0) nenv (0.3.0) - newrelic_rpm (4.1.0.333) - ng-rails-csrf (0.1.0) - ngannotate-rails (1.2.2) - execjs - rails (>= 3.1) - nio4r (2.0.0) - nokogiri (1.7.1) - mini_portile2 (~> 2.1.0) + newrelic_rpm (4.2.0.334) + nio4r (2.1.0) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) non-stupid-digest-assets (1.0.9) sprockets (>= 2.0) notiffany (0.1.1) nenv (~> 0.1) shellany (~> 0.0) orm_adapter (0.5.0) - paperclip (5.1.0) - activemodel (>= 4.2.0) - activesupport (>= 4.2.0) - cocaine (~> 0.5.5) - mime-types - mimemagic (~> 0.3.0) - paperclip-optimizer (2.0.0) - image_optim (~> 0.19) - paperclip (>= 3.4) paranoia (2.3.1) activerecord (>= 4.0, < 5.2) pg (0.20.0) phantomjs (2.1.1.0) - poltergeist (1.14.0) + poltergeist (1.15.0) capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) pomona (0.7.0) - progress (3.3.1) pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -414,7 +361,7 @@ GEM puma (3.8.2) pundit (1.1.0) activesupport (>= 3.0.0) - rack (2.0.1) + rack (2.0.3) rack-accept (0.4.5) rack (>= 0.4) rack-cors (0.4.1) @@ -424,44 +371,44 @@ GEM httpclient (>= 2.4) multi_json (>= 1.3.6) rack (>= 1.1) - rack-protection (2.0.0.rc2) + rack-protection (2.0.0) rack rack-test (0.6.3) rack (>= 1.0) - rails (5.0.2) - actioncable (= 5.0.2) - actionmailer (= 5.0.2) - actionpack (= 5.0.2) - actionview (= 5.0.2) - activejob (= 5.0.2) - activemodel (= 5.0.2) - activerecord (= 5.0.2) - activesupport (= 5.0.2) + rails (5.0.4) + actioncable (= 5.0.4) + actionmailer (= 5.0.4) + actionpack (= 5.0.4) + actionview (= 5.0.4) + activejob (= 5.0.4) + activemodel (= 5.0.4) + activerecord (= 5.0.4) + activesupport (= 5.0.4) bundler (>= 1.3.0, < 2.0) - railties (= 5.0.2) + railties (= 5.0.4) sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.2) - activesupport (>= 4.2.0, < 6.0) - nokogiri (~> 1.6) - rails-erd (1.5.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-erd (1.5.2) activerecord (>= 3.2) activesupport (>= 3.2) choice (~> 0.2.0) ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (5.0.2) - actionpack (= 5.0.2) - activesupport (= 5.0.2) + railties (5.0.4) + actionpack (= 5.0.4) + activesupport (= 5.0.4) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.2.2) rake rake (12.0.0) - rb-fsevent (0.9.8) - rb-inotify (0.9.8) - ffi (>= 0.5.0) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) react_on_rails (6.5.1) addressable connection_pool @@ -473,7 +420,7 @@ GEM actionpack (>= 4.0, < 6) redis-rack (>= 1, < 3) redis-store (>= 1.1.0, < 1.4.0) - redis-activesupport (5.0.2) + redis-activesupport (5.0.3) activesupport (>= 3, < 6) redis-store (~> 1.3.0) redis-namespace (1.5.3) @@ -492,62 +439,63 @@ GEM actionpack (>= 4.2.0, < 5.3) railties (>= 4.2.0, < 5.3) rolify (5.1.0) - rspec (3.5.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-core (3.5.4) - rspec-support (~> 3.5.0) - rspec-expectations (3.5.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-mocks (3.5.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-rails (3.5.2) + rspec-support (~> 3.6.0) + rspec-rails (3.6.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-support (~> 3.5.0) - rspec-sidekiq (3.0.1) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-support (~> 3.6.0) + rspec-sidekiq (3.0.3) rspec-core (~> 3.0, >= 3.0.0) sidekiq (>= 2.4.0) - rspec-support (3.5.0) + rspec-support (3.6.0) ruby-graphviz (1.2.3) ruby-prof (0.16.2) ruby_dep (1.5.0) - rubyzip (1.2.1) - sass (3.4.23) + sass (3.4.25) sass-rails (5.0.6) railties (>= 4.0.0, < 6) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sentry-raven (2.4.0) + sentry-raven (2.5.3) faraday (>= 0.7.6, < 1.0) shellany (0.0.1) shoulda-matchers (3.1.1) activesupport (>= 4.0.0) shrine (2.6.1) down (>= 2.3.6) - sidekiq (5.0.0) + sidekiq (5.0.4) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) redis (~> 3.3, >= 3.3.3) + sidekiq-failures (1.0.0) + sidekiq (>= 4.0.0) simplecov (0.14.1) docile (~> 1.1.0) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) - simplecov-html (0.10.0) - sinatra (2.0.0.rc2) - mustermann (= 1.0.0) + simplecov-html (0.10.1) + sinatra (2.0.0) + mustermann (~> 1.0) rack (~> 2.0) - rack-protection (= 2.0.0.rc2) + rack-protection (= 2.0.0) tilt (~> 2.0) six (0.2.0) slop (3.6.0) @@ -562,11 +510,11 @@ GEM thor (0.19.4) thread_safe (0.3.6) tilt (2.0.7) - timecop (0.8.1) + timecop (0.9.1) transitions (1.2.1) turbolinks (5.0.1) turbolinks-source (~> 5) - turbolinks-source (5.0.0) + turbolinks-source (5.0.3) tzinfo (1.2.3) thread_safe (~> 0.1) uber (0.1.0) @@ -582,12 +530,8 @@ GEM websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) - xpath (2.0.0) + xpath (2.1.0) nokogiri (~> 1.3) - yt (0.30.1) - activesupport - yt-support (>= 0.1) - yt-support (0.1.2) PLATFORMS ruby @@ -595,8 +539,7 @@ PLATFORMS DEPENDENCIES acts-as-taggable-on (~> 4.0) addressable (~> 2.5.1) - angular-rails-templates (~> 1.0.2) - awesome_nested_set! + awesome_nested_set (~> 3.1.3) aws-sdk (~> 2.9) bcrypt (~> 3.1.11) better_errors @@ -624,13 +567,11 @@ DEPENDENCIES elasticsearch-model (~> 5.0) elasticsearch-rails (~> 5.0) email_spec - excon (~> 0.55.0) factory_girl_rails (~> 4.8) faker (~> 1.7) flipper (~> 0.10) flipper-active_record (~> 0.10) flipper-ui (~> 0.10) - fog-local (~> 0.3.1) font-awesome-sass (~> 4.7.0) foreman gon (~> 6.1.0) @@ -644,8 +585,7 @@ DEPENDENCIES hashie (~> 3.5.5) hashie-forbidden_attributes (~> 0.1.1) hashr (~> 2.0.1) - image_optim_pack (~> 0.4.0) - interactor-rails (~> 2.0) + interactor-rails (~> 2.1) jasmine-core (~> 2.5) jasmine-rails (~> 0.14) jquery-rails (~> 4.3.1) @@ -655,16 +595,12 @@ DEPENDENCIES json_spec (~> 1.1) kaminari (~> 0.17.0) material_design_lite-sass (~> 1.3.0) - mime-types (~> 3.1.0) + mimemagic (~> 0.3.2) mini_racer mocha (~> 1.2) newrelic_rpm - ng-rails-csrf (~> 0.1.0) - ngannotate-rails (~> 1.2.2) nokogiri non-stupid-digest-assets (~> 1.0.9) - paperclip (~> 5.1.0) - paperclip-optimizer (~> 2.0) paranoia (~> 2.3) pg (~> 0.20.0) phantomjs (~> 2.1.1) @@ -680,18 +616,17 @@ DEPENDENCIES rack-oauth2 (~> 1.6.1) rails (~> 5.0.2) rails-erd - rails-observers! react_on_rails (< 6.6) redis-namespace redis-rails (~> 5.0) rolify (~> 5.1) rspec-rails (~> 3.5) rspec-sidekiq (~> 3.0) - rubyzip (~> 1.2.1) sass-rails (~> 5.0) sentry-raven shoulda-matchers (~> 3.1) sidekiq (~> 5.0.0) + sidekiq-failures (~> 1.0.0) simplecov (~> 0.14) sinatra (~> 2.0.0.rc) six (~> 0.2.0) @@ -702,7 +637,6 @@ DEPENDENCIES turbolinks (~> 5.0.1) uglifier (~> 3.2.0) virtus (~> 1.0.5) - yt (~> 0.30.1) RUBY VERSION ruby 2.4.1p111 diff --git a/Guardfile b/Guardfile index 4b37cdbf3..40991e35b 100644 --- a/Guardfile +++ b/Guardfile @@ -13,8 +13,7 @@ guard :rspec, cmd: "bundle exec rspec" do watch(%r{^app/interactors/(.+)\.rb$}) { |m| "spec/interactors/#{m[1]}_Spec.rb" } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch(%r{^spec/factories/(.+)\.rb$}) { "spec" } - watch('app/controllers/application_controller.rb') { ["spec/controllers", "spec/api"] } - watch('app/controllers/api_controller.rb') { "spec/api" } + watch('app/controllers/application_controller.rb') { ["spec/controllers"] } end guard 'jasmine', :server_mount => '/specs', :server_env => :test, :server => :webrick do diff --git a/README.md b/README.md index ba87c0e9b..9f3c40191 100644 --- a/README.md +++ b/README.md @@ -23,24 +23,10 @@ Cortex follows a decentralized, API-only architecture - it is *not* built like W - [Running Test Suite](#running-test-suite) - [API](#api) - [Documentation](#documentation) - - [Resources](#resources) - - [Tenants](#tenants) - - [Users](#users) - - [Media](#media) - - [Posts](#posts) - - [Categories](#categories) - - [Occupations](#occupations) - - [Localizations](#localizations) - - [Applications](#applications) - - [Bulk Jobs](#bulk_jobs) - - [Documents](#documents) - - [Snippets](#snippets) - - [Webpages](#webpages) - [Consuming Cortex](#consuming-cortex) - [Authorization](#authorization) - [Content](#content) - [Localizations](#localizations) - - [Webpages and Snippets](#webpages-and-snippets) - [Exceptions](#exceptions) - [Applications Using Cortex](#applications-using-cortex) - [Troubleshooting](#troubleshooting) @@ -58,7 +44,6 @@ For a rudimentary setup, these variables should be configured: * Execute `$ bundle exec rails secret` twice to generate both an `APP_SECRET` and `DEVISE_SECRET` * If the superuser isn't used for the app databases, the `DATABASE_USERNAME` and `DATABASE_PASSWORD` should be set accordingly. -* Set `HOST` to the local Web server's root URL to properly configure Fog (local asset storage) ### Dependencies @@ -153,12 +138,10 @@ $ bundle exec rake db:create $ bundle exec rake db:schema:load ``` -* Seed database with a top-level tenant, the superuser, Advice & Resources categories, ONET occupation/industry codes, and Custom Content data, then rebuild the ElasticSearch index: +* Seed database with a top-level tenant, the superuser and Custom Content data, then rebuild the ElasticSearch index: ```sh $ bundle exec rake db:seed -$ bundle exec rake cortex:create_categories -$ bundle exec rake cortex:onet:fetch_and_provision $ bundle exec rake cortex:core:db:reseed $ bundle exec rake cortex:rebuild_indexes ``` @@ -196,7 +179,7 @@ This will configure various things, such as [dotenv](https://github.com/bkeepers Initialize the test database: ```sh -$ RAILS_ENV=test bundle exec rake db:schema:load db:seed cortex:create_categories cortex:onet:fetch_and_provision cortex:core:db:reseed +$ RAILS_ENV=test bundle exec rake db:schema:load db:seed cortex:core:db:reseed $ RAILS_ENV=test bundle exec rake cortex:rebuild_indexes ``` @@ -217,69 +200,6 @@ SwaggerUI is provided at [http://docs.api.cbcortex.com/](http://docs.api.cbcorte Swagger Endpoints are available at [http://api.cbcortex.com/api/v1/swagger_doc.json](http://api.cbcortex.com/api/v1/swagger_doc.json). -### Resources - -Note: most resources are treated as 'paranoid' - that is, data is never truly deleted in the system - only archived. - -#### [Tenants](http://docs.api.cbcortex.com/#!/tenants) - -Tenants act as a nested set and are the foundation of the channel-focused content distribution mechanism of Cortex, and allow data to be segregated throughout the system. Tenancy is currently very limited in scope. For example, users are directly tied to a tenant, and content can only be associated with a tenant via an inflexible `content -> user -> tenant` relationship. This will be expanded soon. - -#### [Users](http://docs.api.cbcortex.com/#!/users) - -Users are for authorization and authentication. They currently lack roles, except for the ability to enable/disable admin access. - -#### [Media](http://docs.api.cbcortex.com/#!/media) - -Media covers any potential file-type to be stored in or linked to by the Cortex. This includes: - -* Images -* Audio -* Video -* Youtube Links -* Documents -* Text - -When Media is consumed anywhere within the system, the two pieces of content become tied, and the Media cannot be deleted without the reference removed in the consuming piece of content. - -#### [Posts](http://docs.api.cbcortex.com/#!/posts) - -Posts serve as a packaged distribution medium consisting of other content. They can be categorized, assigned to an occupation, and contain media of any format. - -The posts endpoint also includes other posts-specific functionality, such as post filters and post tags. - -#### [Categories](http://docs.api.cbcortex.com/#!/categories) - -Categories act as a nested set, living in a tree-like structure with parents and children. Cortex's API provides both this hierarchy and a flat list of categories, with a minimum depth as an optional parameter. These are currently unable to be manipulated via the admin interface, only directly within the database. - -#### [Occupations](http://docs.api.cbcortex.com/#!/occupations) - -Occupations act as a nested set of Industries with specific Occupations (with SOC codes) beneath them. They utilize the ONET database, and are intended to eventually power intelligent content recommendations. See the `cortex:onet` rake task for specifics. - -#### [Localizations](http://docs.api.cbcortex.com/#!/localizations) - -Localizations/locales provide YAML/JSON-formatted translations for consuming applications. - -#### [Applications](http://docs.api.cbcortex.com/#!/applications) - -Applications contain credentials for OAuth applications that consume Cortex. - -#### [Bulk Jobs](http://docs.api.cbcortex.com/#!/bulk_jobs) - -Bulk Jobs is the generic interface for uploads processed in bulk for any compatible resource, i.e. `users`, `posts` and `media`. - -#### [Documents](http://docs.api.cbcortex.com/#!/documents) - -Documents are an incredibly generic piece of content, consisting only of raw text. They are intended to be made more specific by other resources, i.e. `snippets` and `webpages`. - -#### [Snippets](http://docs.api.cbcortex.com/#!/snippets) - -Snippets build ontop of a generic Document, and are intended to be HTML sections on a webpage. - -#### [Webpages](http://docs.api.cbcortex.com/#!/webpages) - -Webpages group together `snippets`, and correspond to a destination URL, and contain various additional metadata to power a dynamic, editable webpage. - ## Consuming Cortex ### Authorization @@ -298,10 +218,6 @@ Content can be consumed from a feed or via the resource's endpoint directly. Use Localizations can be consumed via the client or via [i18n-backend-cortex](https://github.com/cortex-cms/i18n-backend-cortex), which allows easy localization for Rails applications. -### Webpages and Snippets - -Webpages/Snippets can be consumed via the client or via the [content-snippets-view](https://github.com/cortex-cms/content-snippets-view) and [content-snippets](https://github.com/cortex-cms/content-snippets) libraries, which need to be configured and hosted in order to be consumed. - ### Exceptions If a consuming or companion application would like to produce Cortex-equivalent exceptions, use the [cortex-exceptions](https://github.com/cb-talent-development/cortex-exceptions) gem. @@ -328,6 +244,6 @@ Cortex utilizes the Apache 2.0 License. See [LICENSE](LICENSE.md) for details. ## Copyright -Copyright (c) 2016 CareerBuilder, LLC. +Copyright (c) 2017 CareerBuilder, LLC. [cb-ce-github]: https://github.com/cb-talent-development "Content Enablement on GitHub" diff --git a/app/api/v1/api.rb b/app/api/v1/api.rb index 00cbfa3be..83bc043c1 100644 --- a/app/api/v1/api.rb +++ b/app/api/v1/api.rb @@ -6,29 +6,16 @@ class API < Grape::API content_type :json, 'application/json' version 'v1', using: :path - mount ::V1::Resources::Categories - mount ::V1::Resources::Posts - mount ::V1::Resources::Media - mount ::V1::Resources::Tenants - mount ::V1::Resources::Users - mount ::V1::Resources::Occupations mount ::V1::Resources::Localizations mount ::V1::Resources::Locales mount ::V1::Resources::Applications mount ::V1::Resources::Credentials - mount ::V1::Resources::BulkJobs - mount ::V1::Resources::Documents - mount ::V1::Resources::Snippets - mount ::V1::Resources::Webpages mount ::V1::Resources::ContentTypes mount ::V1::Resources::ContentItems add_swagger_documentation(base_path: '/api', hide_format: true, api_version: 'v1', - models: [::V1::Entities::Post, ::V1::Entities::Category, ::V1::Entities::Media, - ::V1::Entities::Tenant, ::V1::Entities::Occupation, ::V1::Entities::User, - ::V1::Entities::Localization, ::V1::Entities::Locale, + models: [::V1::Entities::Localization, ::V1::Entities::Locale, ::V1::Entities::Application, ::V1::Entities::Credential, - ::V1::Entities::BulkJob, ::V1::Entities::Document, ::V1::Entities::Snippet, - ::V1::Entities::Webpage, ::V1::Entities::ContentType, ::V1::Entities::ContentItem]) + ::V1::Entities::ContentType, ::V1::Entities::ContentItem]) end end diff --git a/app/api/v1/entities/author.rb b/app/api/v1/entities/author.rb deleted file mode 100644 index 971dc4d9c..000000000 --- a/app/api/v1/entities/author.rb +++ /dev/null @@ -1,18 +0,0 @@ -module V1 - module Entities - class Author < Grape::Entity - expose :firstname, documentation: { type: "String", desc: "First Name" } - expose :lastname, documentation: { type: "String", desc: "Last Name" } - expose :email, documentation: { type: "String", desc: "Email" } - expose :title, documentation: { type: "String", desc: "Title" } - expose :bio, documentation: { type: "String", desc: "Bio" } - expose :personal, documentation: { type: "String", desc: "Personal Website" } - expose :twitter, documentation: { type: "String", desc: "Twitter Profile" } - expose :facebook, documentation: { type: "String", desc: "Facebook Profile" } - expose :google, documentation: { type: "String", desc: "Google Profile" } - expose :avatars, documentation: { type: "String", desc: "Avatar" } - expose :fullname, documentation: { type: "String", desc: "Full Name" } - expose :id, documentation: { type: "Integer", desc: "Author ID" } - end - end -end diff --git a/app/api/v1/entities/bulk_job.rb b/app/api/v1/entities/bulk_job.rb deleted file mode 100644 index 290095912..000000000 --- a/app/api/v1/entities/bulk_job.rb +++ /dev/null @@ -1,15 +0,0 @@ -module V1 - module Entities - class BulkJob < Grape::Entity - expose :id, documentation: { type: 'UUID', desc: 'Bulk upload job UUID', required: true } - expose :content_type, documentation: { type: 'String', desc: 'Type of content being processed. Types supported: Media (/media/bulk_job), Users (/users/bulk_job)' } - expose :status, documentation: { type: 'String', desc: 'Bulk upload job status' } - expose :log, documentation: { type: 'Text', is_array: true, desc: 'Full log as Array for bulk upload job' } - expose :created_at, documentation: { type: 'dateTime', desc: 'Created date'} - expose :updated_at, documentation: { type: 'dateTime', desc: 'Updated date'} - expose :user, with: '::V1::Entities::User', as: :creator, documentation: { type: 'User', desc: 'Owner' } - expose :metadata, documentation: { type: 'String', desc: 'Bulk metadata (CSV) URL', required: true } - expose :assets, documentation: { type: 'String', desc: 'Assets to be uploaded (ZIP) URL' }, if: lambda { |bulkJob, _| bulkJob.assets_file_name.present? } - end - end -end diff --git a/app/api/v1/entities/category.rb b/app/api/v1/entities/category.rb deleted file mode 100644 index 2b514f102..000000000 --- a/app/api/v1/entities/category.rb +++ /dev/null @@ -1,9 +0,0 @@ -module V1 - module Entities - class Category < Grape::Entity - expose :id, documentation: { type: "Integer", desc: "Category ID" } - expose :name, documentation: { type: "String", desc: "Category Name"} - expose :children, if: lambda { |instance, options| options[:children] }, documentation: { type: "Category", is_array: true, desc: "Child Categories" } - end - end -end diff --git a/app/api/v1/entities/document.rb b/app/api/v1/entities/document.rb deleted file mode 100644 index e40f5830b..000000000 --- a/app/api/v1/entities/document.rb +++ /dev/null @@ -1,11 +0,0 @@ -module V1 - module Entities - class Document < Grape::Entity - expose :id, documentation: { type: 'Integer', desc: 'Document ID', required: true } - expose :name, documentation: { type: 'String', desc: 'Document Name', required: true } - expose :body, documentation: { type: 'String', desc: 'Body Text', required: true } - expose :created_at, documentation: { type: 'dateTime', desc: 'Created Date'} - expose :updated_at, documentation: { type: 'dateTime', desc: 'Updated Date'} - end - end -end diff --git a/app/api/v1/entities/media.rb b/app/api/v1/entities/media.rb deleted file mode 100644 index e0a9fc0fc..000000000 --- a/app/api/v1/entities/media.rb +++ /dev/null @@ -1,45 +0,0 @@ -module V1 - module Entities - class Media < Grape::Entity - expose :id, documentation: { type: "Integer", desc: "Media ID", required: true } - expose :name, documentation: { type: "String", desc: "Media Name", required: true } - expose :alt, documentation: { type: "String", desc: "Alt-text for Media" } - expose :taxon, documentation: { type: "String", desc: "Taxon string" } - expose :dimensions, documentation: { type: "Integer", is_array: true, desc: "Array of [Width, Height]" } - expose :url, documentation: { type: "String", desc: "URL of Media" } - expose :type, documentation: { type: "String", desc: "Media Type" } - expose :created_at, documentation: { type: 'dateTime', desc: "Created Date"} - expose :updated_at, documentation: { type: 'dateTime', desc: "Updated Date"} - expose :attachment_file_name, documentation: { type: "String", desc: "Filename" } - expose :content_type, documentation: { type: "String", desc: "Media type" } - expose :description, documentation: { type: "String", desc: "Description of the media" } - expose :active, documentation: { type: "Boolean", desc: "Media active" } - expose :tag_list, documentation: {type: "String", is_array: true, desc: "Tags"} - - expose :user, with: '::V1::Entities::User', as: :creator, documentation: { type: "User", desc: "Owner" } - - ## Thumbnails - expose :attachment, using: '::V1::Entities::MediaThumbnails', as: :thumbs, if: lambda { |media, _| media.can_thumb? }, documentation: { type: "MediaThumbnails", desc: "Thumbnails of the media"} - - ## Youtube Specific - with_options if: lambda { |media, _| media.content_type == 'youtube' } do - expose :duration, documentation: { type: "Integer", desc: "Video duration in seconds"} - expose :title, documentation: { type: "String", desc: "Video Title"} - expose :authors, documentation: { type: "String", desc: "String representing array of video's Youtube authors"} - expose :video_description, documentation: { type: "String", desc: "Youtube video description"} - expose :video_id, documentation: { type: "String", desc: "Youtube video ID"} - end - - # Full Only - with_options if: { full: true } do - expose :deactive_at, documentation: { type: 'dateTime', desc: "Deactivate Date"} - expose :deleted_at, documentation: { type: 'dateTime', desc: "Deleted Date"} - - ## Aliases - expose :attachment_file_size, documentation: { type: "Integer", desc: "Filesize in bytes" } - expose :attachment_content_type, documentation: { type: "String", desc: "Attachment Mime Type" } - expose :consumed?, as: :consumed, documentation: { type: "Boolean", desc: "Is the media consumed?" } - end - end - end -end diff --git a/app/api/v1/entities/media_thumbnails.rb b/app/api/v1/entities/media_thumbnails.rb deleted file mode 100644 index 247f15527..000000000 --- a/app/api/v1/entities/media_thumbnails.rb +++ /dev/null @@ -1,12 +0,0 @@ -module V1 - module Entities - class MediaThumbnails < Grape::Entity - expose :large, documentation: {desc: "Large thumbnail"} do |attachment| attachment.url(:large) end - expose :medium, documentation: {desc: "Medium thumbnail"} do |attachment| attachment.url(:medium) end - expose :default, documentation: {desc: "Default thumbnail"} do |attachment| attachment.url(:default) end - expose :mini, documentation: {desc: "Mini thumbnail"} do |attachment| attachment.url(:mini) end - expose :micro, documentation: {desc: "Micro thumbnail"} do |attachment| attachment.url(:micro) end - expose :ar_post, documentation: {desc: "Media resized for A&R post page"} do |attachment| attachment.url(:ar_post) end - end - end -end diff --git a/app/api/v1/entities/occupation.rb b/app/api/v1/entities/occupation.rb deleted file mode 100644 index 99bab15da..000000000 --- a/app/api/v1/entities/occupation.rb +++ /dev/null @@ -1,10 +0,0 @@ -module V1 - module Entities - class Occupation < Grape::Entity - expose :id, documentation: { type: "Integer", desc: "Occupation ID" } - expose :soc, documentation: { type: "String", desc: "SOC code" } - expose :title, documentation: { type: "String", desc: "Occupation Title" } - expose :description, documentation: { type: "String", desc: "Occupation Description" } - end - end -end diff --git a/app/api/v1/entities/post.rb b/app/api/v1/entities/post.rb deleted file mode 100644 index 7f55ca809..000000000 --- a/app/api/v1/entities/post.rb +++ /dev/null @@ -1,71 +0,0 @@ -module V1 - module Entities - class Post < Grape::Entity - expose :id, documentation: {type: "Integer", desc: "Post ID", required: true} - expose :title, documentation: {desc: "Post Title", type: "String" , required: true} - expose :type, documentation: {desc: "Post Type", type: "String", enum: ["ArticlePost", "VideoPost", "InfographicPost", "PromoPost"], required: true} - expose :draft, documentation: {desc: "Draft status", type: "Boolean"} - expose :is_wysiwyg, documentation: {desc: "Post needs a WYSIWYG editor", type: "Boolean"} - expose :comment_count, documentation: {desc: "Number of comments", type: "Integer"} - expose :short_description, documentation: {desc: "Short description of the post", type: "String", required: true} - expose :job_phase, documentation: {desc: "Job Phase", type: "String", enum: ["discovery", "find_the_job", "get_the_job", "on_the_job"], required: true} - expose :slug, documentation: {desc: "Slug", type: "String", required: true} - expose :created_at, documentation: { type: 'dateTime', desc: "Created Date"} - expose :updated_at, documentation: { type: 'dateTime', desc: "Last Updated Date"} - expose :published_at, documentation: { type: 'dateTime', desc: "Publish Date"} - expose :expired_at, documentation: { type: 'dateTime', desc: "Expiration Date"} - expose :copyright_owner, documentation: { type: "String", desc: "Copyright Owner"} - expose :notes, documentation: {type: "String", desc: "Notes about this post"} - expose :seo_title, documentation: {type: "String", desc: "SEO-specific title for this post"} - expose :seo_description, documentation: {type: "String", desc: "SEO-specific description for this post"} - expose :seo_keyword_list, documentation: {type: "String", is_array: true, desc: "SEO-specific keywords for this post"} - expose :primary_category_id, documentation: {type: "Integer", desc: "Primary Category ID"} - expose :primary_industry_id, documentation: {type: "Integer", desc: "Primary Industry ID"} - expose :tag_list, documentation: {type: "String", is_array: true, desc: "Tags"} - expose :body, documentation: {desc: "Body of the post", type: "String"} - - expose :categories, using: '::V1::Entities::Category', documentation: {type: 'Category', is_array: true, desc: "Categories"} - expose :featured_media, using: '::V1::Entities::Media', documentation: {type: 'Media', is_array: false, desc: "Featured Media for this post"} - expose :tile_media, using: '::V1::Entities::Media', documentation: {type: 'Media', is_array: false, desc: "Tile Media for this post"} - expose :industries, using: '::V1::Entities::Occupation', documentation: {type: 'Industry', is_array: true, desc: "Industries"} - - # This runtime exposure is necessary to correctly resolve the enum value - expose :display, {documentation: { type: "String", desc: "Post Display Size"}} do |post| - post.display - end - - expose :is_published, documentation: { type: "Boolean", desc: "If this post if active and published"} do |post| - post.published? - end - - expose :custom_author, documentation: {desc: "Author's name", type: "String", required: true} do |post, options| - if post.author - post.author.fullname - elsif options[:type] == true - nil - else - post[:custom_author] - end - end - - with_options if: lambda { |post, _| post.type == 'PromoPost' } do - expose :destination_url, { documentation: { type: "String", desc: "Destination URL for a Promo Post"} } - expose :call_to_action, { documentation: { type: "String", desc: "Call to Action for a Promo Post"} } - end - - with_options if: { full: true } do - represent :media, with: '::V1::Entities::Media', full: true, documentation: {type: "Media", is_array: true, desc: "All Media for this post"} - expose :user, with: '::V1::Entities::User' - expose :author, using: '::V1::Entities::Author' - end - - expose :noindex, documentation: { type: 'Boolean', desc: "SEO No Index Robots Setting" } - expose :nofollow, documentation: { type: 'Boolean', desc: "SEO No Follow Robots Setting" } - expose :noodp, documentation: { type: 'Boolean', desc: "SEO No ODP Setting" } - expose :nosnippet, documentation: { type: 'Boolean', desc: "SEO No Snippet Robots Setting" } - expose :noarchive, documentation: { type: 'Boolean', desc: "SEO No Archive Setting" } - expose :noimageindex, documentation: { type: 'Boolean', desc: "SEO No Image Index Robots Setting" } - expose :is_sticky, documentation: { type: 'Boolean', desc: "Is this Post Sticky?" } - end - end -end diff --git a/app/api/v1/entities/snippet.rb b/app/api/v1/entities/snippet.rb deleted file mode 100644 index 7ca4b07da..000000000 --- a/app/api/v1/entities/snippet.rb +++ /dev/null @@ -1,10 +0,0 @@ -module V1 - module Entities - class Snippet < Grape::Entity - expose :id, documentation: { type: 'Integer', desc: 'Snippet ID', required: true } - expose :created_at, documentation: { type: 'dateTime', desc: 'Created Date'} - expose :updated_at, documentation: { type: 'dateTime', desc: 'Updated Date'} - expose :document, with: '::V1::Entities::Document', documentation: {type: 'Document', desc: 'Associated Document'} - end - end -end diff --git a/app/api/v1/entities/tag.rb b/app/api/v1/entities/tag.rb deleted file mode 100644 index f9fdd59b4..000000000 --- a/app/api/v1/entities/tag.rb +++ /dev/null @@ -1,9 +0,0 @@ -module V1 - module Entities - class Tag < Grape::Entity - expose :id, documentation: { type: "Integer", desc: "Tag ID" } - expose :name, documentation: { type: "String", desc: "Tag Name" } - expose :count, documentation: { type: "Integer", desc: "Tag Count" } - end - end -end diff --git a/app/api/v1/entities/webpage.rb b/app/api/v1/entities/webpage.rb deleted file mode 100644 index 04466ae8f..000000000 --- a/app/api/v1/entities/webpage.rb +++ /dev/null @@ -1,37 +0,0 @@ -module V1 - module Entities - class Webpage < Grape::Entity - expose :id, documentation: { type: 'Integer', desc: 'Webpage ID', required: true } - expose :name, documentation: { type: 'String', desc: 'Webpage Name', required: true } - expose :created_at, documentation: { type: 'dateTime', desc: 'Created Date'} - expose :updated_at, documentation: { type: 'dateTime', desc: 'Updated Date'} - expose :snippets, with: '::V1::Entities::Snippet', documentation: {type: 'Snippet', is_array: true, desc: 'All associated Snippets for this Webpage'} - - expose :seo_title, documentation: { type: 'String', desc: "SEO Meta Tag Title" } - expose :seo_description, documentation: { type: 'String', desc: "SEO Meta Tag Description" } - expose :seo_keyword_list, documentation: {type: "String", is_array: true, desc: "SEO-specific keywords"} - expose :noindex, documentation: { type: 'Boolean', desc: "SEO No Index Robots Setting" } - expose :nofollow, documentation: { type: 'Boolean', desc: "SEO No Follow Robots Setting" } - expose :noodp, documentation: { type: 'Boolean', desc: "SEO No ODP Setting" } - expose :nosnippet, documentation: { type: 'Boolean', desc: "SEO No Snippet Robots Setting" } - expose :noarchive, documentation: { type: 'Boolean', desc: "SEO No Archive Setting" } - expose :noimageindex, documentation: { type: 'Boolean', desc: "SEO No Image Index Robots Setting" } - - expose :dynamic_yield_sku, documentation: { type: 'String', desc: "Dynamic Yield Webpage SKU/ID" } - expose :dynamic_yield_category, documentation: { type: 'String', desc: "Dynamic Yield Webpage Category" } - - expose :tables_widget_json, documentation: {type: 'Hash', is_array: true, desc: 'Tables Widget Data as JSON'} - expose :charts_widget_json, documentation: {type: 'Hash', is_array: true, desc: 'Charts Widget Data as JSON'} - expose :accordion_group_widget_json, documentation: {type: 'Hash', is_array: true, desc: 'Accordion Group Widget Data as JSON'} - - with_options if: { full: true } do - expose :user, with: '::V1::Entities::User', documentation: {type: 'User', desc: 'Owner'} - expose :url, documentation: { type: 'String', desc: 'URL of Webpage' } - - expose :tables_widget_yaml, documentation: {type: 'Hash', is_array: true, desc: 'Tables Widget Data as YAML'} - expose :accordion_group_widget_yaml, documentation: {type: 'Hash', is_array: true, desc: 'Accordion Group Widget Data as YAML'} - expose :charts_widget_yaml, documentation: {type: 'Hash', is_array: true, desc: 'Charts Widget Data as YAML'} - end - end - end -end diff --git a/app/api/v1/helpers/bulk_jobs_helper.rb b/app/api/v1/helpers/bulk_jobs_helper.rb deleted file mode 100644 index f49282851..000000000 --- a/app/api/v1/helpers/bulk_jobs_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module BulkJobsHelper - def bulk_job - @bulk_job ||= ::BulkJob.find_by_id(params[:id]) - end - - def bulk_job! - bulk_job || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/documents_helper.rb b/app/api/v1/helpers/documents_helper.rb deleted file mode 100644 index 0741c7f90..000000000 --- a/app/api/v1/helpers/documents_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module DocumentsHelper - def document - @document ||= Document.find_by_id(params[:id]) - end - - def document! - document || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/media_helper.rb b/app/api/v1/helpers/media_helper.rb deleted file mode 100644 index 8d9b12b08..000000000 --- a/app/api/v1/helpers/media_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module MediaHelper - def media - @media ||= ::GetSingleMedia.call(id: params[:id], tenant: current_tenant.id).media - end - - def media! - media || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/posts_helper.rb b/app/api/v1/helpers/posts_helper.rb deleted file mode 100644 index 0e9f68e76..000000000 --- a/app/api/v1/helpers/posts_helper.rb +++ /dev/null @@ -1,27 +0,0 @@ -module V1 - module Helpers - module PostsHelper - include ActsAsTaggableOn::TagsHelper - - def post - @post ||= ::GetPost.call(id: params[:id], tenant: current_tenant.id).post - end - - def reload_post - @post = ::GetPost.call(id: params[:id], tenant: current_tenant.id).post - end - - def published_post - @post = ::GetPost.call(id: params[:id], tenant: current_tenant.id, published: true).post - end - - def post! - post || not_found! - end - - def published_post! - published_post || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/shared_params_helper.rb b/app/api/v1/helpers/shared_params_helper.rb index dda441245..ef7edab3a 100644 --- a/app/api/v1/helpers/shared_params_helper.rb +++ b/app/api/v1/helpers/shared_params_helper.rb @@ -11,21 +11,6 @@ module SharedParamsHelper params :search do optional :q, type: String, desc: 'Query string' end - - params :post_metadata do - optional :categories, type: String, desc: 'Categories' - optional :industries, type: String, desc: 'Industries' - optional :job_phase, type: String, desc: 'Job Phase' - optional :post_type, type: String, desc: 'Post Type' - optional :author, type: String, desc: 'Post Author' - optional :tags, type: String, desc: 'Tags' - end - - params :post_associations do - optional :featured_media_id, type: Integer, desc: 'Featured Media ID' - optional :tile_media_id, type: Integer, desc: 'Tile Media ID' - optional :author_id, type: Integer, desc: 'Author ID' - end end end end diff --git a/app/api/v1/helpers/snippets_helper.rb b/app/api/v1/helpers/snippets_helper.rb deleted file mode 100644 index 593f22196..000000000 --- a/app/api/v1/helpers/snippets_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module SnippetsHelper - def snippet - @snippet ||= Snippet.find_by_id(params[:id]) - end - - def snippet! - snippet || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/tenants_helper.rb b/app/api/v1/helpers/tenants_helper.rb deleted file mode 100644 index 654531856..000000000 --- a/app/api/v1/helpers/tenants_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module TenantsHelper - def tenant - @tenant ||= Tenant.find_by_id(params[:id]) - end - - def tenant! - tenant || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/users_helper.rb b/app/api/v1/helpers/users_helper.rb deleted file mode 100644 index faadb3ed3..000000000 --- a/app/api/v1/helpers/users_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module UsersHelper - def user - @user ||= User.find(params[:user_id]) - end - - def user! - user || not_found! - end - end - end -end diff --git a/app/api/v1/helpers/webpages_helper.rb b/app/api/v1/helpers/webpages_helper.rb deleted file mode 100644 index 73a4c14af..000000000 --- a/app/api/v1/helpers/webpages_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module V1 - module Helpers - module WebpagesHelper - def webpage - @webpage ||= Webpage.find_by_id(params[:id]) - end - - def webpage! - webpage || not_found! - end - end - end -end diff --git a/app/api/v1/resources/bulk_jobs.rb b/app/api/v1/resources/bulk_jobs.rb deleted file mode 100644 index 8d4d4a7e2..000000000 --- a/app/api/v1/resources/bulk_jobs.rb +++ /dev/null @@ -1,30 +0,0 @@ -module V1 - module Resources - class BulkJobs < Grape::API - resource :bulk_jobs do - include Grape::Kaminari - helpers ::V1::Helpers::BulkJobsHelper - - paginate per_page: 25 - - desc 'Show all bulk jobs', { entity: ::V1::Entities::BulkJob, nickname: 'showAllBulkJobs' } - get do - authorize! :view, ::BulkJob - require_scope! 'view:bulk_jobs' - - @bulk_job = ::BulkJob.order(created_at: :desc) - - ::V1::Entities::BulkJob.represent paginate(@bulk_job) - end - - desc 'Get bulk job', { entity: ::V1::Entities::BulkJob, nickname: 'showBulkJob' } - get ':id' do - require_scope! 'view:bulk_jobs' - authorize! :view, bulk_job! - - present bulk_job, with: ::V1::Entities::BulkJob - end - end - end - end -end diff --git a/app/api/v1/resources/categories.rb b/app/api/v1/resources/categories.rb deleted file mode 100644 index 85696740f..000000000 --- a/app/api/v1/resources/categories.rb +++ /dev/null @@ -1,26 +0,0 @@ -module V1 - module Resources - class Categories < Grape::API - resource :categories do - desc 'Show all categories', { entity: ::V1::Entities::Category, nickname: "showAllCategories" } - params do - optional :depth, default: 1, type: Integer, desc: "Minimum category depth" - end - get do - authorize! :view, Category - present Category.where("depth >= ?", params[:depth]), with: ::V1::Entities::Category - end - - desc 'Show category hierarchy', { entity: ::V1::Entities::Category, nickname: "showCategoryHierarchy" } - get :hierarchy do - authorize! :view, Category - if params[:roots_only] == 'false' - present Category.all, with: ::V1::Entities::Category - else - present Category.roots, with: ::V1::Entities::Category, children: true - end - end - end - end - end -end diff --git a/app/api/v1/resources/documents.rb b/app/api/v1/resources/documents.rb deleted file mode 100644 index 9bca9fa1c..000000000 --- a/app/api/v1/resources/documents.rb +++ /dev/null @@ -1,72 +0,0 @@ -module V1 - module Resources - class Documents < Grape::API - resource :documents do - include Grape::Kaminari - helpers ::V1::Helpers::DocumentsHelper - - paginate per_page: 25 - - desc 'Show all documents', { entity: ::V1::Entities::Document, nickname: 'showAllDocument' } - get do - authorize! :view, ::Document - require_scope! 'view:documents' - - @document = ::Document.order(created_at: :desc) - ::V1::Entities::Document.represent paginate(@document) - end - - desc 'Get document', { entity: ::V1::Entities::Document, nickname: 'showDocument' } - get ':id' do - require_scope! 'view:documents' - authorize! :view, document! - - present document, with: ::V1::Entities::Document - end - - desc 'Create document', { entity: ::V1::Entities::Document, params: ::V1::Entities::Document.documentation, nickname: 'createDocument' } - post do - require_scope! 'modify:documents' - authorize! :create, ::Document - - document_params = params[:document] || params - - @document = ::Document.new(declared(document_params, { include_missing: false }, ::V1::Entities::Document.documentation.keys)) - document.user = current_user! - document.save! - - present document, with: ::V1::Entities::Document - end - - desc 'Update document', { entity: ::V1::Entities::Document, params: ::V1::Entities::Document.documentation, nickname: 'updateDocument' } - put ':id' do - require_scope! 'modify:documents' - authorize! :update, document! - - document_params = params[:document] || params - - document.update!(declared(document_params, { include_missing: false }, ::V1::Entities::Document.documentation.keys)) - - present document, with: ::V1::Entities::Document - end - - desc 'Delete document', { nickname: 'deleteDocument' } - delete ':id' do - require_scope! 'modify:documents' - authorize! :delete, document! - - begin - document.destroy - rescue Cortex::Exceptions::ResourceConsumed => e - error = error!({ - error: 'Conflict', - message: e.message, - status: 409 - }, 409) - error - end - end - end - end - end -end diff --git a/app/api/v1/resources/media.rb b/app/api/v1/resources/media.rb deleted file mode 100644 index 139bcc780..000000000 --- a/app/api/v1/resources/media.rb +++ /dev/null @@ -1,136 +0,0 @@ -module V1 - module Resources - class Media < Grape::API - helpers ::V1::Helpers::SharedParamsHelper - helpers ::V1::Helpers::ParamsHelper - - resource :media do - include Grape::Kaminari - helpers ::V1::Helpers::MediaHelper - helpers ::V1::Helpers::BulkJobsHelper - - paginate per_page: 25 - - desc 'Show all media', { entity: ::V1::Entities::Media, nickname: 'showAllMedia' } - params do - use :search - end - get do - authorize! :view, ::Media - require_scope! 'view:media' - - @media = ::GetMultipleMedia.call(params: declared(clean_params(params), include_missing: false), tenant: current_tenant).media - ::V1::Entities::Media.represent paginate(@media).records - end - - desc 'Show media tags' - params do - optional :s - end - get 'tags' do - require_scope! 'view:media' - authorize! :view, ::Media - - tags = params[:s] \ - ? ::Media.tag_counts_on(:tags).where('name ILIKE ?', "%#{params[:s]}%") \ - : ::Media.tag_counts_on(:tags) - - if params[:popular] - tags = tags.order('count DESC').limit(20) - end - - present tags, with: ::V1::Entities::Tag - end - - desc 'Get media', { entity: ::V1::Entities::Media, nickname: 'showMedia' } - get ':id' do - require_scope! 'view:media' - authorize! :view, media! - - present media, with: ::V1::Entities::Media, full: true - end - - desc 'Create media', { entity: ::V1::Entities::Media, params: ::V1::Entities::Media.documentation, nickname: 'createMedia' } - params do - optional :attachment - end - post do - require_scope! 'modify:media' - authorize! :create, ::Media - - media_params = params[:media] || params - - @media = ::Media.new(declared(media_params, { include_missing: false }, ::V1::Entities::Media.documentation.keys)) - media.user = current_user! - if params[:tag_list] - media.tag_list = params[:tag_list] - end - media.save! - - present media, with: ::V1::Entities::Media, full: true - end - - desc 'Update media', { entity: ::V1::Entities::Media, params: ::V1::Entities::Media.documentation, nickname: 'updateMedia' } - params do - optional :attachment - end - put ':id' do - require_scope! 'modify:media' - authorize! :update, media! - - media_params = params[:media] || params - - allowed_params = [:name, :alt, :description, :tag_list, :status, :deactive_at, :attachment] - - if params[:tag_list] - media.tag_list = params[:tag_list] - end - media.update!(declared(media_params, { include_missing: false }, allowed_params)) - - present media, with: ::V1::Entities::Media, full: true - end - - desc 'Delete media', { nickname: 'deleteMedia' } - delete ':id' do - require_scope! 'modify:media' - authorize! :delete, media! - - begin - media.destroy - rescue Cortex::Exceptions::ResourceConsumed => e - error = error!({ - error: 'Conflict', - message: e.message, - status: 409 - }, 409) - error - end - end - - desc 'Bulk create media', { entity: ::V1::Entities::BulkJob, nickname: 'bulkCreateMedia' } - params do - group :bulkJob, type: Hash do - requires :assets - end - end - post :bulk_job do - require_scope! 'modify:media' - require_scope! 'modify:bulk_jobs' - authorize! :create, ::Media - authorize! :create, ::BulkJob - - bulk_job_params = params[:bulkJob] || params - - @bulk_job = ::BulkJob.new(declared(bulk_job_params, { include_missing: false }, ::V1::Entities::BulkJob.documentation.keys)) - bulk_job.content_type = 'Media' - bulk_job.user = current_user! - bulk_job.save! - - BulkCreateMediaJob.perform_later(bulk_job, current_user!) - - present bulk_job, with: ::V1::Entities::BulkJob - end - end - end - end -end diff --git a/app/api/v1/resources/occupations.rb b/app/api/v1/resources/occupations.rb deleted file mode 100644 index bd20735ce..000000000 --- a/app/api/v1/resources/occupations.rb +++ /dev/null @@ -1,17 +0,0 @@ -module V1 - module Resources - class Occupations < Grape::API - resource :occupations do - desc 'Show all occupations', { entity: ::V1::Entities::Occupation, nickname: "showAllOccupations" } - get do - present ::Onet::Occupation.all, with: ::V1::Entities::Occupation - end - - desc 'Show all industries', { entity: ::V1::Entities::Occupation, nickname: "showAllIndustries" } - get :industries do - present ::Onet::Occupation.industries, with: ::V1::Entities::Occupation - end - end - end - end -end diff --git a/app/api/v1/resources/posts.rb b/app/api/v1/resources/posts.rb deleted file mode 100644 index c2f9ef86a..000000000 --- a/app/api/v1/resources/posts.rb +++ /dev/null @@ -1,175 +0,0 @@ -module V1 - module Resources - class Posts < Grape::API - helpers ::V1::Helpers::SharedParamsHelper - helpers ::V1::Helpers::ParamsHelper - - resource :posts do - include Grape::Kaminari - helpers ::V1::Helpers::PostsHelper - - paginate per_page: 25 - - desc 'Show all posts', { entity: ::V1::Entities::Post, nickname: "showAllPosts" } - params do - use :search - use :post_metadata - use :pagination - end - get do - require_scope! 'view:posts' - authorize! :view, ::Post - @posts = ::GetPosts.call(params: declared(clean_params(params), include_missing: false), tenant: current_tenant).posts - ::V1::Entities::Post.represent paginate(@posts).records - end - - desc 'Show published posts', { entity: ::V1::Entities::Post, nickname: "postFeed" } - params do - use :search - use :post_metadata - use :pagination - end - get 'feed' do - require_scope! 'view:posts' - authorize! :view, ::Post - last_updated_at = Post.last_updated_at - params_hash = Digest::MD5.hexdigest(declared(params).to_s) - cache_key = "feed-#{last_updated_at}-#{current_tenant.id}-#{params_hash}" - - posts = ::Rails.cache.fetch(cache_key, expires_in: 30.minutes, race_condition_ttl: 10) do - posts = ::GetPosts.call(params: declared(clean_params(params), include_missing: false), tenant: current_tenant, published: true).posts - paginated_posts = paginate(posts).records.to_a - {records: paginated_posts, headers: header} - end - - header.merge!(posts[:headers]) - ::V1::Entities::Post.represent posts[:records] - end - - desc 'Show all published posts', { entity: ::V1::Entities::Post, nickname: "allPostFeed" } - paginate per_page: 10000 - get 'feed/all_posts' do - require_scope! 'view:posts' - authorize! :view, ::Post - - posts = ::GetPosts.call(params: declared(clean_params(params), include_missing: false), tenant: current_tenant, published: true).posts - ::V1::Entities::Post.represent paginate(posts).records - end - - desc 'Show published post authors' - get 'feed/authors' do - present Author.published.distinct, with: ::V1::Entities::Author - end - - desc 'Show related published posts', { entity: ::V1::Entities::Post, nickname: "relatedPosts" } - paginate per_page: 5 - get 'feed/:id/related' do - require_scope! 'view:posts' - post = GetPost.call(id: params[:id], published: true).post - not_found! unless post - authorize! :view, post - - @posts = ::GetRelatedPosts.call(post: post, params: declared(clean_params(params), include_missing: false), tenant: current_tenant, published: true).posts - ::V1::Entities::Post.represent paginate(@posts).records - end - - desc 'Show a published post', { entity: ::V1::Entities::Post, nickname: "showFeedPost" } - get 'feed/*id' do - @post = ::GetPost.call(id: params[:id], published: true, tenant: current_tenant.id).post - not_found! unless @post - authorize! :view, @post - present @post, with: ::V1::Entities::Post, full: true - end - - desc 'Show post tags' - params do - optional :s - end - get 'tags' do - require_scope! 'view:posts' - authorize! :view, Post - - tags = params[:s] \ - ? ::Post.tag_counts_on(:tags).where('name ILIKE ?', "%#{params[:s]}%") \ - : ::Post.tag_counts_on(:tags) - - if params[:popular] - tags = tags.order('count DESC').limit(20) - end - - present tags, with: ::V1::Entities::Tag - end - - desc 'Show all filters/facets for posts', { nickname: "showFilters" } - params do - optional :depth, default: 1, desc: "Minimum depth of filters" - end - get 'filters' do - require_scope! 'view:posts' - authorize! :view, Post - present :industries, ::Onet::Occupation.industries, with: ::V1::Entities::Occupation - present :categories, ::Category.where('depth >= ?', params[:depth]), with: ::V1::Entities::Category - present :job_phases, ::Category.roots, with: ::V1::Entities::Category, children: true - end - - desc 'Show a post', { entity: ::V1::Entities::Post, nickname: "showPost" } - get ':id' do - require_scope! 'view:posts' - @post = ::GetPost.call(id: params[:id], tenant: current_tenant.id).post - not_found! unless @post - authorize! :view, @post - present @post, with: ::V1::Entities::Post, full: true - end - - desc 'Create a post', { entity: ::V1::Entities::Post, params: ::V1::Entities::Post.documentation, nickname: "createPost" } - params do - use :post_associations - end - post do - require_scope! 'modify:posts' - authorize! :create, Post - - allowed_params = remove_params(::V1::Entities::Post.documentation.keys, :featured_media, :tile_media, :media, :industries, :categories, :is_published) + [:category_ids, :industry_ids, :author_id] - - @post = ::Post.new(declared(params, {include_missing: false}, allowed_params)) - post.user = params[:user] ? User.find(params[:user]) : current_user - post.save! - present post, with: ::V1::Entities::Post, full: true - end - - desc 'Update a post', { entity: ::V1::Entities::Post, params: ::V1::Entities::Post.documentation, nickname: "updatePost" } - params do - use :post_associations - end - put ':id' do - require_scope! 'modify:posts' - authorize! :update, post! - - allowed_params = remove_params(::V1::Entities::Post.documentation.keys, :featured_media, :tile_media, :media, :industries, :categories, :is_published) + [:category_ids, :industry_ids, :author_id] - - if params[:type] - post.update!({type: params[:type]}) if params[:type] - reload_post - end - if params[:tag_list] - post.tag_list = params[:tag_list] - end - if params[:seo_keyword_list] - post.seo_keyword_list = params[:seo_keyword_list] - end - post.update!(declared(params, {include_missing: false}, allowed_params)) - - present post, with: ::V1::Entities::Post, full: true - end - - desc 'Delete a post', { nickname: "deletePost" } - delete ':id' do - require_scope! 'modify:posts' - authorize! :delete, post! - - post.destroy - end - end - end - end -end diff --git a/app/api/v1/resources/snippets.rb b/app/api/v1/resources/snippets.rb deleted file mode 100644 index 32443dbc9..000000000 --- a/app/api/v1/resources/snippets.rb +++ /dev/null @@ -1,72 +0,0 @@ -module V1 - module Resources - class Snippets < Grape::API - resource :snippets do - include Grape::Kaminari - helpers ::V1::Helpers::SnippetsHelper - - paginate per_page: 25 - - desc 'Show all snippets', { entity: ::V1::Entities::Snippet, nickname: 'showAllSnippet' } - get do - authorize! :view, ::Snippet - require_scope! 'view:snippets' - - @snippet = ::Snippet.order(created_at: :desc) - ::V1::Entities::Snippet.represent paginate(@snippet) - end - - desc 'Get snippet', { entity: ::V1::Entities::Snippet, nickname: 'showSnippet' } - get ':id' do - require_scope! 'view:snippets' - authorize! :view, snippet! - - present snippet, with: ::V1::Entities::Snippet - end - - desc 'Create snippet', { entity: ::V1::Entities::Snippet, params: ::V1::Entities::Snippet.documentation, nickname: 'createSnippet' } - post do - require_scope! 'modify:snippets' - authorize! :create, ::Snippet - - snippet_params = params[:snippet] || params - - @snippet = ::Snippet.new(declared(snippet_params, { include_missing: false }, ::V1::Entities::Snippet.documentation.keys)) - snippet.user = current_user! - snippet.save! - - present snippet, with: ::V1::Entities::Snippet - end - - desc 'Update snippet', { entity: ::V1::Entities::Snippet, params: ::V1::Entities::Snippet.documentation, nickname: 'updateSnippet' } - put ':id' do - require_scope! 'modify:snippets' - authorize! :update, snippet! - - snippet_params = params[:snippet] || params - - snippet.update!(declared(snippet_params, { include_missing: false }, ::V1::Entities::Snippet.documentation.keys)) - - present snippet, with: ::V1::Entities::Snippet - end - - desc 'Delete snippet', { nickname: 'deleteSnippet' } - delete ':id' do - require_scope! 'modify:snippets' - authorize! :delete, snippet! - - begin - snippet.destroy - rescue Cortex::Exceptions::ResourceConsumed => e - error = error!({ - error: 'Conflict', - message: e.message, - status: 409 - }, 409) - error - end - end - end - end - end -end diff --git a/app/api/v1/resources/tenants.rb b/app/api/v1/resources/tenants.rb deleted file mode 100644 index ed8df6699..000000000 --- a/app/api/v1/resources/tenants.rb +++ /dev/null @@ -1,92 +0,0 @@ -module V1 - module Resources - class Tenants < Grape::API - helpers ::V1::Helpers::SharedParamsHelper - helpers ::V1::Helpers::ParamsHelper - - resource :tenants do - include Grape::Kaminari - helpers ::V1::Helpers::TenantsHelper - - paginate per_page: 25 - - desc 'Show all tenants', { entity: ::V1::Entities::Tenant, nickname: "showAllTenants" } - get do - require_scope! 'view:tenants' - authorize! :view, Tenant - - ::V1::Entities::Tenant.represent paginate(Tenant.all), children: params[:include_children] - end - - desc 'Show tenant hierarchy', { entity: ::V1::Entities::Tenant, nickname: "showTenantHierarchy" } - get :hierarchy do - require_scope! 'view:tenants' - authorize! :view, Tenant - - present Tenant.roots, using: ::V1::Entities::Tenant, children: true - end - - desc 'Show a tenant', { entity: ::V1::Entities::Tenant, nickname: "showTenant" } - get ':id' do - present tenant!, with: ::V1::Entities::Tenant, children: false - end - - desc 'Create a tenant', { entity: ::V1::Entities::Tenant, params: ::V1::Entities::Tenant.documentation, nickname: "createTenant" } - params do - optional :name, type: String, desc: "Tenant Name" - end - post do - require_scope! 'modify:tenants' - authorize! :create, Tenant - - allowed_params = remove_params(::V1::Entities::Tenant.documentation.keys, :children) - - @tenant = ::Tenant.new(declared(params, { include_missing: true }, allowed_params)) - tenant.owner = current_user - tenant.save! - present tenant, with: ::V1::Entities::Tenant - end - - desc 'Update a tenant', { entity: ::V1::Entities::Tenant, params: ::V1::Entities::Tenant.documentation, nickname: "updateTenant" } - put ':id' do - require_scope! 'modify:tenants' - authorize! :update, tenant! - - allowed_params = remove_params(::V1::Entities::Tenant.documentation.keys, :children) - - tenant.update!(declared(params, { include_missing: false }, allowed_params)) - present tenant, with: ::V1::Entities::Tenant - end - - desc 'Delete a tenant', { nickname: "deleteTenant" } - delete ':id' do - require_scope! 'modify:tenants' - authorize! :delete, tenant! - - tenant.destroy - end - - segment '/:id' do - resource :users do - include Grape::Kaminari - helpers ::V1::Helpers::UsersHelper - - paginate per_page: 25 - - desc 'Show all users belonging to a tenant', { entity: ::V1::Entities::User, nickname: "showAllTenantUsers" } - params do - use :search - end - get do - authorize! :view, User - require_scope! 'view:users' - - @users = ::GetUsers.call(params: declared(clean_params(params), include_missing: false), tenant_id: params[:id]).users - ::V1::Entities::User.represent paginate(@users).records, full: true - end - end - end - end - end - end -end diff --git a/app/api/v1/resources/users.rb b/app/api/v1/resources/users.rb deleted file mode 100644 index 31f424fad..000000000 --- a/app/api/v1/resources/users.rb +++ /dev/null @@ -1,141 +0,0 @@ -module V1 - module Resources - class Users < Grape::API - resource :users do - helpers ::V1::Helpers::UsersHelper - helpers ::V1::Helpers::BulkJobsHelper - - desc 'Get the current user', { entity: ::V1::Entities::User, nickname: 'currentUser' } - get :me do - authorize! :view, current_user! - present current_user, with: ::V1::Entities::User, full: true - end - - desc "Fetch a user's author info" - get ':user_id/author' do - require_scope! 'view:users' - authorize! :view, user! - - present user.author || not_found!, with: ::V1::Entities::Author - end - - desc "Save a user's author info" - params do - optional :email - optional :firstname - optional :lastname - optional :personal - optional :facebook - optional :twitter - optional :google - optional :bio - end - put ':user_id/author' do - require_scope! 'modify:users' - authorize! :update, user! - - author = Author.find_or_create_by(user_id: params[:user_id]) - author.update_attributes!(declared(params, {include_missing: false})) - author.save! - - present author, with: ::V1::Entities::Author - end - - desc 'Create a new user' - params do - optional :email - optional :firstname - optional :lastname - optional :tenant_id - optional :password - optional :password_confirmation - end - post do - require_scope! 'modify:users' - authorize! :create, User - - allowed_params = [:password, :password_confirmation, :firstname, :lastname, :email, :tenant_id, :admin] - - @user = User.create!(declared(params, {include_missing: false}, allowed_params)) - - present @user, with: ::V1::Entities::User, full: true - end - - desc "Save a user's info" - params do - optional :current_password - optional :password - optional :password_confirmation - optional :firstname - optional :lastname - optional :email - optional :admin - end - put ':user_id' do - require_scope! 'modify:users' - authorize! :update, user! - - allowed_params = [:firstname, :lastname] - - # Extract into permission concerns - if current_user.is_admin? - allowed_params += [:email, :admin] - elsif user == current_user - forbidden! unless user.valid_password?(params[:current_password]) - allowed_params += [:password, :password_confirmation] - render_api_error!('Requires both password and password_confirmation fields', 422) unless params[:password] && params[:password_confirmation] - else - forbidden! - end - - user.update!(declared(params, {include_missing: false}, allowed_params)) - - present user, with: ::V1::Entities::User, full: true - end - - desc 'Show a user', {nickname: 'showUser'} - get ':user_id' do - require_scope! 'view:users' - authorize! :view, user! - - present user, with: ::V1::Entities::User, full: true - end - - desc 'Delete a user', {nickname: 'deleteUser'} - delete ':user_id' do - require_scope! 'modify:users' - authorize! :delete, user! - - begin - user.destroy - rescue Cortex::Exceptions::ResourceConsumed => e - error!({ - error: 'Conflict', - message: e.message, - status: 409 - }, 409) - end - end - - desc 'Bulk create users', { entity: ::V1::Entities::BulkJob, nickname: 'bulkCreateUsers' } - post :bulk_job do - require_scope! 'modify:users' - require_scope! 'modify:bulk_jobs' - authorize! :create, ::User - authorize! :create, ::BulkJob - - bulk_job_params = params[:bulkJob] || params - - @bulk_job = ::BulkJob.new(declared(bulk_job_params, { include_missing: false }, ::V1::Entities::BulkJob.documentation.keys)) - bulk_job.content_type = 'Users' - bulk_job.user = current_user! - bulk_job.save! - - BulkCreateUsersJob.perform_later(bulk_job) - - present bulk_job, with: ::V1::Entities::BulkJob - end - end - end - end -end diff --git a/app/api/v1/resources/webpages.rb b/app/api/v1/resources/webpages.rb deleted file mode 100644 index e59c1a996..000000000 --- a/app/api/v1/resources/webpages.rb +++ /dev/null @@ -1,99 +0,0 @@ -module V1 - module Resources - class Webpages < Grape::API - helpers ::V1::Helpers::ParamsHelper - - resource :webpages do - include Grape::Kaminari - helpers ::V1::Helpers::WebpagesHelper - paginate per_page: 25 - - desc 'Show all webpages', { entity: ::V1::Entities::Webpage, nickname: 'showAllWebpages' } - params do - optional :q, type: String - end - get do - authorize! :view, ::Webpage - require_scope! 'view:webpages' - - @webpages = ::GetWebpages.call(params: declared(clean_params(params), include_missing: false), tenant: current_tenant).webpages - ::V1::Entities::Webpage.represent paginate(@webpages).records, full: true - end - - desc 'Show Webpage Snippets as public feed by URL', { entity: ::V1::Entities::Webpage, nickname: 'showWebpageFeed' } - params do - requires :url, type: String - end - get 'feed' do - require_scope! 'view:webpages' - @webpage = ::GetWebpageFeed.call(params: declared(clean_params(params), include_missing: false), tenant: current_tenant).webpage - not_found! unless @webpage - authorize! :view, @webpage - present @webpage, with: ::V1::Entities::Webpage - end - - desc 'Get webpage', { entity: ::V1::Entities::Webpage, nickname: 'showWebpage' } - get ':id' do - require_scope! 'view:webpages' - authorize! :view, webpage! - - present webpage, with: ::V1::Entities::Webpage, full: true - end - - desc 'Create webpage', { entity: ::V1::Entities::Webpage, params: ::V1::Entities::Webpage.documentation, nickname: 'createWebpage' } - post do - require_scope! 'modify:webpages' - authorize! :create, ::Webpage - - webpage_params = params[:webpage] || params - - @webpage = ::Webpage.new(declared(webpage_params, { include_missing: false }, ::V1::Entities::Webpage.documentation.keys)) - webpage.user = current_user! - webpage.save! - - present webpage, with: ::V1::Entities::Webpage, full: true - end - - desc 'Update webpage', { entity: ::V1::Entities::Webpage, params: ::V1::Entities::Webpage.documentation, nickname: 'updateWebpage' } - put ':id' do - require_scope! 'modify:webpages' - authorize! :update, webpage! - - webpage_params = params[:webpage] || params - allowed_params = remove_params(::V1::Entities::Webpage.documentation.keys, :user) + [:snippets_attributes] - update_params = declared(webpage_params, { include_missing: false }, allowed_params) - update_params[:snippets_attributes].each {|snippet| - snippet.user = current_user! - snippet[:document_attributes].user = current_user! - } - - if params[:seo_keyword_list] - webpage.seo_keyword_list = params[:seo_keyword_list] - end - - webpage.update!(update_params.to_hash) - CacheBustWebpageJob.perform_later(webpage.url) - - present webpage, with: ::V1::Entities::Webpage, full: true - end - - desc 'Delete webpage', { nickname: 'deleteWebpage' } - delete ':id' do - require_scope! 'modify:webpages' - authorize! :delete, webpage! - - begin - webpage.destroy - rescue Cortex::Exceptions::ResourceConsumed => e - error = error!({ - error: 'Conflict', - message: e.message, - status: 409 - }, 409) - error - end - end - end - end - end -end diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 41c2b55dc..7d79a6e97 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -8,7 +8,7 @@ //= require bootstrap-tagsinput //= require clipboard //= require dialog-polyfill -//= require moment +//= require momentjs //= require cortex-plugins-core/application //= require webpack-bundle diff --git a/app/assets/javascripts/authentication.js b/app/assets/javascripts/authentication.js index 6cbbcb1d4..d71aa5d15 100644 --- a/app/assets/javascripts/authentication.js +++ b/app/assets/javascripts/authentication.js @@ -5,6 +5,5 @@ //= require material //= require base -//= require authentication/login // require turbolinks # temporarily disabled diff --git a/app/assets/javascripts/authentication/login.js b/app/assets/javascripts/authentication/login.js deleted file mode 100644 index 097ad78fc..000000000 --- a/app/assets/javascripts/authentication/login.js +++ /dev/null @@ -1,15 +0,0 @@ -var login_tab_change = function() { - $('.login_tab').on('click', function(ev) { - var value = this.text; - $('#user_email').focus(); - - if (value === 'Legacy') { - $('.legacy_value').val(1) - } else { - $('.legacy_value').val(0) - } - }); -}; - -$(document).ready(login_tab_change); -$(document).on('page:load', login_tab_change); diff --git a/app/assets/javascripts/legacy/controllers/applications/grid.js b/app/assets/javascripts/legacy/controllers/applications/grid.js deleted file mode 100644 index de1f19b87..000000000 --- a/app/assets/javascripts/legacy/controllers/applications/grid.js +++ /dev/null @@ -1,77 +0,0 @@ -angular.module('cortex.controllers.applications.grid', [ - 'ui.router.state', - 'ngTable', - 'ui.bootstrap', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters' -]) - - .controller('ApplicationsGridCtrl', function($scope, $window, $state, ngTableParams, cortex, flash) { - $scope.data = { - totalServerItems: 0, - applications: [], - query: null - }; - - $scope.applicationsTableParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - cortex.applications.searchPaged({page: params.page(), per_page: params.count()}, - function (applications, headers, paging) { - params.total(paging.total); - $defer.resolve(applications); - }, - function (data) { - $defer.reject(data); - } - ); - } - }); - - $scope.newApplication = function() { - var application = new cortex.applications(); - var name = $window.prompt("Provide a name for the application"); - if (name !== null && name !== '') { - application.name = name; - application.$save(function() { - flash.success = "Successfully created new application " + name; - $scope.applicationsTableParams.reload(); - }, - function () { - flash.error = "Could not create new application, please try again."; - }); - } - }; - - $scope.editApplication = function(application) { - var name = $window.prompt("Provide a new name for the application"); - if (name !== null && name !== '') { - application.name = name; - application.$save(function() { - flash.success = "Successfully renamed application " + name; - $scope.applicationsTableParams.reload(); - }, - function () { - flash.error = "Could not rename application, please try again."; - }); - } - }; - - $scope.deleteApplication = function (application) { - if ($window.confirm('Are you sure you want to delete "' + application.name + '?"')) { - cortex.applications.delete({id: application.id}, function () { - flash.warn = application.name + ' deleted.'; - $scope.applicationsTableParams.reload(); - }, function () { - flash.error = application.name + ' could not be deleted due to an error.'; - }); - } - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/bulk_jobs/grid.js b/app/assets/javascripts/legacy/controllers/bulk_jobs/grid.js deleted file mode 100644 index f3708ab57..000000000 --- a/app/assets/javascripts/legacy/controllers/bulk_jobs/grid.js +++ /dev/null @@ -1,40 +0,0 @@ -angular.module('cortex.controllers.bulk_jobs.grid', [ - 'ngTable', - 'ui.bootstrap', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters' -]) - - .controller('BulkJobsGridCtrl', function ($scope, ngTableParams, flash, cortex) { - $scope.data = { - totalServerItems: 0, - bulk_jobs: [], - query: null - }; - - $scope.bulkJobDataParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - cortex.bulk_jobs.searchPaged({page: params.page(), per_page: params.count()}, - function (bulk_jobs, headers, paging) { - params.total(paging.total); - $defer.resolve(bulk_jobs); - }, - function (data) { - $defer.reject(data); - } - ); - } - }); - - $scope.displayLog = function(bulkJob) { - alert(bulkJob.log.join('\n')); - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/credentials/edit.js b/app/assets/javascripts/legacy/controllers/credentials/edit.js deleted file mode 100644 index d3faa0366..000000000 --- a/app/assets/javascripts/legacy/controllers/credentials/edit.js +++ /dev/null @@ -1,30 +0,0 @@ -angular.module('cortex.controllers.credentials.edit', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.util' -]) - - .controller('CredentialsEditCtrl', function ($scope, $state, $stateParams, $anchorScroll, flash, cortex, util) { - $scope.data = $scope.data || {}; - - $scope.data.credentials = cortex.credentials.get({application_id: $stateParams.applicationId, - credentials_id: $stateParams.credentialsId}); - - $scope.saveCredentials = function() { - $scope.data.credentials.$save({application_id: $stateParams.applicationId, - credentials_id: $stateParams.credentialsId}, function() { - flash.success = "Successfully saved " + $scope.data.credentials.name; - $state.go('^'); - }, function(res) { - if (res.status === 402) { - flash.error = "Could not save " + $scope.data.credentials.name + " - " + res.data.errors[0]; - } else { - flash.error = "Could not save " + $scope.data.credentials.name; - } - }); - }; - $scope.cancel = function() { - $state.go('^'); - } - }); diff --git a/app/assets/javascripts/legacy/controllers/credentials/grid.js b/app/assets/javascripts/legacy/controllers/credentials/grid.js deleted file mode 100644 index 76e5c450e..000000000 --- a/app/assets/javascripts/legacy/controllers/credentials/grid.js +++ /dev/null @@ -1,48 +0,0 @@ -angular.module('cortex.controllers.credentials.grid', [ - 'ui.router.state', - 'ngTable', - 'ui.bootstrap', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters' -]) - - .controller('CredentialsGridCtrl', function($scope, $window, $state, $stateParams, ngTableParams, cortex, flash) { - $scope.data = { - totalServerItems: 0, - credentials: [], - query: null - }; - - $scope.credentialsTableParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - cortex.credentials.searchPaged({application_id: $stateParams.applicationId, page: params.page(), per_page: params.count()}, - function (applications, headers, paging) { - params.total(paging.total); - $defer.resolve(applications); - }, - function (data) { - $defer.reject(data); - } - ); - } - }); - - $scope.deleteCredential = function (credential) { - if ($window.confirm('Are you sure you want to delete "' + credential.name + '?"')) { - cortex.credentials.delete({application_id: $stateParams.applicationId, credential_id: credential.id}, function () { - flash.warn = credential.name + ' deleted.'; - $scope.credentialsTableParams.reload(); - }, function () { - flash.error = credential.name + ' could not be deleted due to an error.'; - }); - } - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/credentials/new.js b/app/assets/javascripts/legacy/controllers/credentials/new.js deleted file mode 100644 index 3ab931a1b..000000000 --- a/app/assets/javascripts/legacy/controllers/credentials/new.js +++ /dev/null @@ -1,28 +0,0 @@ -angular.module('cortex.controllers.credentials.new', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.util' -]) - - .controller('CredentialsNewCtrl', function ($scope, $state, $stateParams, flash, cortex, util) { - $scope.data = $scope.data || {}; - - $scope.data.credentials = new cortex.credentials(); - - $scope.saveCredentials = function() { - $scope.data.credentials.$save({application_id: $stateParams.applicationId}, function() { - flash.success = "Successfully saved " + $scope.data.credentials.name; - $state.go('^'); - }, function(res) { - if (res.status === 402) { - flash.error = "Could not save " + $scope.data.credentials.name + " - " + res.data.errors[0]; - } else { - flash.error = "Could not save " + $scope.data.credentials.name; - } - }); - }; - $scope.cancel = function() { - $state.go('^'); - } - }); diff --git a/app/assets/javascripts/legacy/controllers/locales/edit.js b/app/assets/javascripts/legacy/controllers/locales/edit.js deleted file mode 100644 index c0a2c0422..000000000 --- a/app/assets/javascripts/legacy/controllers/locales/edit.js +++ /dev/null @@ -1,39 +0,0 @@ -angular.module('cortex.controllers.locales.edit', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.util' -]) - -.controller('LocalesEditCtrl', function ($scope, $state, $stateParams, $anchorScroll, flash, cortex, util) { - $scope.data = $scope.data || {}; - var saveParams = {}; - - if (util.isEmpty($stateParams.localeName)) { - saveParams = {localization_id: $stateParams.localizationId}; - $scope.data.locale = new cortex.locales(); - } - else { - saveParams = {localization_id: $stateParams.localizationId, locale_name: $stateParams.localeName}; - $scope.data.locale = cortex.locales.get(saveParams); - } - - $scope.cancel = function () { - $state.go('^.edit'); - }; - - $scope.saveLocale = function () { - delete $scope.data.locale.json; - $scope.data.locale.$save(saveParams).then( - function () { - $anchorScroll(); - flash.success = 'Saved locale information'; - $state.go('^.edit'); - }, - function () { - $anchorScroll(); - flash.error = 'Error while saving locale information'; - } - ); - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/locales/grid.js b/app/assets/javascripts/legacy/controllers/locales/grid.js deleted file mode 100644 index 59f841bd1..000000000 --- a/app/assets/javascripts/legacy/controllers/locales/grid.js +++ /dev/null @@ -1,70 +0,0 @@ -angular.module('cortex.controllers.locales.grid', [ - 'ui.router.state', - 'ngTable', - 'ui.bootstrap', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters' -]) - - .controller('LocalesGridCtrl', function ($scope, $window, $state, $stateParams, ngTableParams, cortex, flash) { - $scope.data = { - totalServerItems: 0, - locales: [], - query: null - }; - - $scope.localeDataParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - cortex.locales.searchPaged({localization_id: $stateParams.localizationId, - page: params.page(), per_page: params.count()}, - function (locales, headers, paging) { - params.total(paging.total); - $defer.resolve(locales); - }, - function (data) { - $defer.reject(data); - } - ); - } - }); - - $scope.editLocale = function(locale) { - $state.go('cortex.localizations.localization.edit_locale', {localeName: locale.name}); - }; - - $scope.deleteLocale = function (locale) { - if ($window.confirm('Are you sure you want to delete "' + locale.name + '?"')) { - cortex.locales.delete({localization_id: $stateParams.localizationId, locale_name: locale.name}, function () { - flash.warn = locale.name + ' deleted.'; - $scope.localeDataParams.reload(); - }, function () { - flash.error = locale.name + ' could not be deleted due to an error.'; - }); - } - }; - - $scope.duplicateLocale = function (locale) { - if ($window.confirm('Are you sure you want to duplicate "' + locale.name + '?"')) { - var duplicate = new cortex.locales(locale); - delete duplicate.id; - delete duplicate.json; - duplicate.name += ' - Copy'; - duplicate.$save({localization_id: $stateParams.localizationId}).then( - function () { - flash.success = locale.name + ' duplicated.'; - $scope.localeDataParams.reload(); - }, - function () { - flash.error = locale.name + ' could not be duplicated due to an error.'; - }); - } - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/localizations/edit.js b/app/assets/javascripts/legacy/controllers/localizations/edit.js deleted file mode 100644 index f4ce0a56c..000000000 --- a/app/assets/javascripts/legacy/controllers/localizations/edit.js +++ /dev/null @@ -1,35 +0,0 @@ -angular.module('cortex.controllers.localizations.edit', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.util' -]) - -.controller('LocalizationsEditCtrl', function ($scope, $state, $stateParams, $anchorScroll, flash, cortex, util) { - $scope.data = $scope.data || {}; - - if (util.isEmpty($stateParams.localizationId)) { - $scope.data.localization = new cortex.localizations(); - } - else { - $scope.data.localization = cortex.localizations.get({id: $stateParams.localizationId}); - } - - $scope.cancel = function () { - $state.go('cortex.localizations.manage'); - }; - - $scope.saveLocalization = function () { - $scope.data.localization.$save().then( - function () { - $anchorScroll(); - flash.success = 'Saved localization information'; - $state.go('cortex.localizations.manage'); - }, - function () { - $anchorScroll(); - flash.error = 'Error while saving localization information'; - } - ); - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/localizations/grid.js b/app/assets/javascripts/legacy/controllers/localizations/grid.js deleted file mode 100644 index 3bc7a57d1..000000000 --- a/app/assets/javascripts/legacy/controllers/localizations/grid.js +++ /dev/null @@ -1,69 +0,0 @@ -angular.module('cortex.controllers.localizations.grid', [ - 'ui.router.state', - 'ngTable', - 'ui.bootstrap', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters' -]) - - .controller('LocalizationsGridCtrl', function ($scope, $window, $state, ngTableParams, flash, cortex) { - $scope.data = { - totalServerItems: 0, - localizations: [], - query: null - }; - - $scope.localizationDataParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - cortex.localizations.searchPaged({page: params.page(), per_page: params.count()}, - function (localizations, headers, paging) { - params.total(paging.total); - $defer.resolve(localizations); - }, - function (data) { - $defer.reject(data); - } - ); - } - }); - - $scope.editLocalization = function(localization) { - $state.go('^.localization.edit', {localizationId: localization.id}); - }; - - $scope.deleteLocalization = function (localization) { - if ($window.confirm('Are you sure you want to delete "' + localization.name + '?"')) { - cortex.localizations.delete({id: localization.id}, function () { - flash.warn = localization.name + ' deleted.'; - $scope.localizationDataParams.reload(); - }, function () { - flash.error = localization.name + ' could not be deleted due to an error.'; - }); - } - }; - - $scope.duplicateLocalization = function (localization) { - if ($window.confirm('Are you sure you want to duplicate "' + localization.name + '?"')) { - var duplicate = new cortex.localizations(localization); - delete duplicate.id; - duplicate.locales = _.map(duplicate.locales, function(locale) { return _.omit(locale, 'json'); }); - duplicate.name += ' - Copy'; - duplicate.$save().then( - function () { - flash.success = localization.name + ' duplicated.'; - $scope.localizationDataParams.reload(); - }, - function () { - flash.error = localization.name + ' could not be duplicated due to an error.'; - }); - } - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/media/bulk.js b/app/assets/javascripts/legacy/controllers/media/bulk.js deleted file mode 100644 index 085d7f679..000000000 --- a/app/assets/javascripts/legacy/controllers/media/bulk.js +++ /dev/null @@ -1,85 +0,0 @@ -angular.module('cortex.controllers.media.bulk', [ - 'ui.router.state', - 'ui.bootstrap.progressbar', - 'angular-flash.service', - 'angularFileUpload', - 'cortex.settings', - 'cortex.services.cortex', - 'cortex.directives.fileSelector' -]) - - .controller('MediaBulkCtrl', function ($scope, $timeout, $upload, $state, $q, flash, cortex, settings) { - $scope.data = $scope.data || {}; - $scope.data.mediaBulk = new cortex.media.bulkJob(); - $scope.data.upload = { - progress: 0 - }; - - function saveBulkJob() { - var d = $q.defer(); - - if (!$scope.data.mediaBulk.metadata) { - d.reject('No metadata present.'); - } - else { - var uploadError = false; - var httpConfig = { - url: settings.cortex_base_url + '/media/bulk_job', - method: 'POST', - fields: {bulkJob: $scope.data.mediaBulk}, - formDataAppender: function (formData, key, value) { - if (key === 'bulkJob') { - angular.forEach(value, function (v, k) { - formData.append('bulkJob[' + k + ']', v); - }); - } - } - }; - - $scope.data.upload.progress = 1; - $scope.data.upload = $upload.upload(httpConfig) - .then( - function (bulkJob) { //Success - d.resolve(); - }, - function (error, status) { //Error - uploadError = true; - $scope.data.upload.progress = 0; - $scope.data.upload.file = null; - - if (status === 422) { - d.reject('Selected file type is not supported. Please choose a different file.'); - } else if (status === 502) { - d.reject('The server is taking too long to respond. Please reduce the file size of the content you are uploading and try again.') - } - else { - d.reject('Unhandled error: ' + error.data.errors[0]); - } - }, - function (e) { //Progress - if (uploadError) { - return; - } - $scope.data.upload.progress = parseInt(100.0 * e.loaded / e.total); - } - ); - } - - return d.promise; - } - - $scope.saveMediaBulk = function () { - saveBulkJob().then( - function () { - flash.success = 'Bulk job created'; - $state.go('cortex.bulk_jobs.manage'); - }, - function (error) { - flash.error = error; - }); - }; - - $scope.cancel = function () { - $state.go('^.manage.components'); - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/media/edit.js b/app/assets/javascripts/legacy/controllers/media/edit.js deleted file mode 100644 index a6e7c1616..000000000 --- a/app/assets/javascripts/legacy/controllers/media/edit.js +++ /dev/null @@ -1,171 +0,0 @@ -angular.module('cortex.controllers.media.edit', [ - 'ui.router.state', - 'ui.bootstrap.datepicker', - 'ui.bootstrap.progressbar', - 'ui.bootstrap.tabs', - 'ui.bootstrap.dropdown', - 'angular-flash.service', - 'angularFileUpload', - 'ngTagsInput', - 'cortex.settings', - 'cortex.filters', - 'cortex.services.cortex', - 'cortex.directives.fileSelector', - 'cortex.directives.youtubeSelector', - 'cortex.directives.showErrors' -]) - - .controller('MediaEditCtrl', function ($scope, $timeout, $upload, $state, $stateParams, $q, flash, cortex, settings) { - $scope.data = $scope.data || {}; - $scope.data.currentTab = 'file'; - if ($stateParams.mediaId) { - $scope.data.media = cortex.media.get({id: $stateParams.mediaId}); - } - else { - $scope.data.media = new cortex.media(); - } - $scope.data.media.tag_list = []; - $scope.data.upload = { - progress: 0 - }; - - // angular-bootstrap datepicker settings - $scope.datepicker = { - format: 'yyyy/MM/dd', - expireAtOpen: false, - open: function (datepicker) { - $timeout(function () { - $scope.datepicker[datepicker] = true; - }); - } - }; - - function saveFile() { - var d = $q.defer(), - httpMethod, httpUrlSuffix = ''; - - $scope.data.media.type = 'Media'; - - if ($stateParams.mediaId) { - httpMethod = 'PUT'; - httpUrlSuffix = '/' + $stateParams.mediaId; - } - else { - httpMethod = 'POST'; - } - var uploadError = false, - httpConfig = { - url: settings.cortex_base_url + '/media' + httpUrlSuffix, - method: httpMethod, - fields: {media: $scope.data.media}, - file: $scope.data.media.$file, - fileFormDataName: 'media[attachment]', - formDataAppender: function (formData, key, value) { - if (key === 'media') { - angular.forEach(value, function (v, k) { - formData.append('media[' + k + ']', v); - }); - } - } - }; - - $scope.data.upload.progress = 1; - $scope.data.upload = $upload.upload(httpConfig) - .then( - function (media) { //Success - d.resolve(); - }, - function (error, status) { //Error - uploadError = true; - $scope.data.upload.progress = 0; - $scope.data.upload.file = null; - - if (status === 422) { - d.reject('Selected file type is not supported. Please choose a different file.'); - } else if (status === 502) { - d.reject('The server is taking too long to respond. Please reduce the file size of the content you are uploading and try again.') - } else { - d.reject('Unhandled error'); - } - }, - function (e) { //Progress - if (uploadError) { - return; - } - $scope.data.upload.progress = parseInt(100.0 * e.loaded / e.total); - } - ); - - return d.promise; - } - - // - - function saveYoutube() { - $scope.data.media.type = 'Youtube'; - $scope.data.media.video_id = $scope.data.media.$youtube; - return $scope.data.media.$save(); - } - - function saveWithoutAttachment() { - return $scope.data.media.$save(); - } - - $scope.saveMedia = function () { - var tab = $scope.currentTab; - var save; - - $scope.$broadcast('validateShowErrors'); - - $scope.data.media.tag_list = $scope.data.media.tag_list.map(function (tag) { - return tag.name; - }); - - if (tab === 'file' && $scope.data.media.$file) { - save = saveFile; - } - else if (tab === 'youtube' && $scope.data.media.$youtube) { - save = saveYoutube; - } - else if ($stateParams.mediaId) { - save = saveWithoutAttachment; - } - else { - flash.error = 'No attachment present. An attachment is required.'; - return; - } - - save().then( - function () { - flash.success = $scope.data.media.name + ' saved'; - $state.go('^.manage.components'); - }, - function (error) { - flash.error = error; - }); - }; - - $scope.selectTab = function (tab) { - $scope.currentTab = tab; - }; - - $scope.cancel = function () { - $state.go('^.manage.components'); - }; - - $scope.loadTags = function (search) { - return cortex.media.tags({s: search}).$promise; - }; - - $scope.data.popularTags = cortex.media.tags({popular: true}); - - // Adds a tag to tag_list if it doesn't already exist in array - $scope.addTag = function (tag) { - if (_.some($scope.data.media.tag_list, function (t) { - return t.name == tag.name; - })) { - return; - } - $scope.data.media.tag_list.push({name: tag.name, id: tag.id}); - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/media/grid.js b/app/assets/javascripts/legacy/controllers/media/grid.js deleted file mode 100644 index 54a477b36..000000000 --- a/app/assets/javascripts/legacy/controllers/media/grid.js +++ /dev/null @@ -1,92 +0,0 @@ -angular.module('cortex.controllers.media.grid', [ - 'ui.router.state', - 'ui.bootstrap', - 'placeholders.img', - 'angular-flash.service', - 'cortex.settings', - 'cortex.services.cortex', - 'cortex.services.postBodyEditor', - 'cortex.services.postsPopup', - 'cortex.directives.delayedInput', - 'cortex.filters' -]) - - .controller('MediaGridCtrl', function ($scope, $state, $stateParams, $window, cortex, settings, - mediaSelectType, flash, PostBodyEditorService, - PostsPopupService) { - - $scope.data = {}; - - var updatePage = function (newPage) { - $state.go('.', {page: newPage || $scope.page.page, perPage: $scope.page.perPage, query: $scope.page.query}); - }; - - $scope.page = { - query: $stateParams.query, - page: parseInt($stateParams.page) || 1, - perPage: parseInt($stateParams.perPage) || settings.paging.defaultPerPage, - next: function () { - $scope.page.page++; - updatePage(); - }, - previous: function () { - $scope.page.page--; - updatePage(); - }, - flip: function (page) { - $scope.page.page = page; - updatePage(); - } - }; - - $scope.$watch('page.query', function () { - updatePage(1); - }); - - $scope.$watch('page.perPage', function () { - updatePage(); - }); - - $scope.data.media = cortex.media.searchPaged({ - q: $scope.page.query, - per_page: $scope.page.perPage, - page: $scope.page.page - }, - function (media, headers, paging) { - $scope.data.paging = paging; - }); - - $scope.deleteMedia = function (media) { - if ($window.confirm('Are you sure you want to delete "' + media.name + '?"')) { - cortex.media.delete({id: media.id}, function () { - $scope.data.media = _.reject($scope.data.media, function (m) { - return m.id == media.id; - }); - flash.warn = media.name + " deleted."; - }, function (res) { - flash.error = media.name + " could not be deleted: " + res.data.message; - }); - } - }; - - $scope.selectMedia = function (media) { - if (PostBodyEditorService.mediaSelectType === mediaSelectType.ADD_MEDIA) { - PostBodyEditorService.addMediaToPost(media); - } - else if (PostBodyEditorService.mediaSelectType === mediaSelectType.SET_TILE) { - PostBodyEditorService.media.tile = media; - } - else if (PostBodyEditorService.mediaSelectType === mediaSelectType.SET_FEATURED) { - PostBodyEditorService.media.featured = media; - } - else { - throw 'No mediaSelectType set!'; - } - - PostsPopupService.popupOpen = false; - }; - - $scope.searchMedia = function (keyword) { - $scope.page.query = keyword; - } - }); diff --git a/app/assets/javascripts/legacy/controllers/organizations/manage.js b/app/assets/javascripts/legacy/controllers/organizations/manage.js deleted file mode 100644 index ac852c88c..000000000 --- a/app/assets/javascripts/legacy/controllers/organizations/manage.js +++ /dev/null @@ -1,37 +0,0 @@ -angular.module('cortex.controllers.organizations.manage', [ - 'ui.router.state', - 'angular-flash.service', - 'angular-flash.flash-alert-directive', - 'cortex.services.cortex', - 'cortex.settings' -]) - -.controller('OrganizationsManageCtrl', function($scope, $stateParams, $state, flash, events, cortex, TenantsTreeStatus) { - // Open tenant hierarchy and details panels if an organization is selected - if ($stateParams.organizationId && !$state.includes('cortex.organizations.manage.tenants')) { - $state.go('.tenants'); - } - - $scope.tenantsTreeStatus = TenantsTreeStatus; - - $scope.deleteTenant = function(tenant){ - if (confirm('Are you sure you want to delete "' + tenant.name + '"?')) { - cortex.tenants.delete({id: tenant.id}, function(data) { - var message; - - if (tenant.parent_id) { - $scope.$broadcast(events.TENANT_HIERARCHY_CHANGE); - message = '"' + tenant.name + '" tenant was deleted successfully'; - } - else { - $scope.$emit(events.ORGANIZATIONS_CHANGE); - message = '"' + tenant.name + '" organization was deleted successfully'; - - // Go to org manage if an org tenant was deleted - $state.go('cortex.organizations.manage'); - } - flash.warn = message; - }); - } - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/organizations/organizations.js b/app/assets/javascripts/legacy/controllers/organizations/organizations.js deleted file mode 100644 index 3cfaf812b..000000000 --- a/app/assets/javascripts/legacy/controllers/organizations/organizations.js +++ /dev/null @@ -1,22 +0,0 @@ -angular.module('cortex.controllers.organizations', [ - 'ui.router.state', - 'cortex.settings' -]) - -.controller('OrganizationsCtrl', function ($scope, $stateParams, $state, events, organizations) { - - $scope.data = { - organizations: organizations - }; - - var orgId = $stateParams.organizationId; - if (orgId) { - $scope.data.organization = _.find(organizations, function(o){ - return o.id == orgId; - }); - } - - $scope.$on(events.ORGANIZATIONS_CHANGE, function (event) { - loadOrganizations(); - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/edit.classify.js b/app/assets/javascripts/legacy/controllers/posts/edit.classify.js deleted file mode 100644 index fb945d7a4..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/edit.classify.js +++ /dev/null @@ -1,34 +0,0 @@ -angular.module('cortex.controllers.posts.edit.classify', [ - 'ngTagsInput', - 'cortex.directives.modalShow', - 'cortex.services.cortex' -]) - -.controller('PostsEditClassifyCtrl', function($scope, _, cortex) { - $scope.loadTags = function (search) { - return cortex.posts.tags({s: search}).$promise; - }; - - $scope.data.popularTags = cortex.posts.tags({popular: true}); - - // Adds a tag to tag_list if it doesn't already exist in array - $scope.addTag = function(tag) { - if (_.some($scope.data.post.tag_list, function(t) { return t.name == tag.name; })) { - return; - } - $scope.data.post.tag_list.push({name: tag.name, id: tag.id}); - }; - - $scope.$watch('data.post.job_phase', function(phase) { - if (phase === undefined) { - $scope.data.jobPhaseCategories = []; - return; - } - - var jobPhaseCategory = _.find($scope.data.categoriesHierarchy, function(category) { - return category.name == phase; - }); - - $scope.data.jobPhaseCategories = jobPhaseCategory.children; - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/edit.display.js b/app/assets/javascripts/legacy/controllers/posts/edit.display.js deleted file mode 100644 index 84922b48e..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/edit.display.js +++ /dev/null @@ -1,67 +0,0 @@ -angular.module('cortex.controllers.posts.edit.display', [ - 'cortex.filters', - 'cortex.settings', - 'cortex.services.mediaConstraints', - 'cortex.services.postBodyEditor', - 'cortex.services.postsPopup' -]) - -.controller('PostsEditDisplayCtrl', function($scope, $state, - AddMediaService, mediaSelectType, PostBodyEditorService, PostsPopupService, - featuredMediaConstraintsService, tileMediaConstraintsService) { - $scope.postBodyEditorService = PostBodyEditorService; - $scope.postBodyEditorService.media.featured = $scope.data.post.featured_media; - $scope.postBodyEditorService.media.tile = $scope.data.post.tile_media; - - $scope.media = { - setFeatured: function () { - AddMediaService.setMedia(mediaSelectType.SET_FEATURED, 'Set Featured Media from Media Library'); - }, - removeFeatured: function () { - $scope.data.post.featured_media = {}; - $scope.data.post.featured_media_id = null; - $scope.data.featured_media_too_small = false; - }, - setTile: function () { - AddMediaService.setMedia(mediaSelectType.SET_TILE, 'Set Tile Media from Media Library'); - }, - removeTile: function () { - $scope.data.post.tile_media = {}; - $scope.data.post.tile_media_id = null; - $scope.data.tile_media_too_small = false; - } - }; - - $scope.$watch('postBodyEditorService.media.featured', function (media) { - if (media) { - $scope.data.post.featured_media = media; - $scope.data.post.featured_media_id = media.id; - $scope.data.post.featured_media_warnings = []; - if (!featuredMediaConstraintsService.width(media)) { - if (featuredMediaConstraintsService.totalSize(media)) { - $scope.data.post.featured_media_warnings.push("Warning! Your featured media might appear stretched, as it is smaller than the featured image slot. Try an image at least 1100x600 ") - } - else { - $scope.data.post.featured_media_warnings.push("Warning! Your featured media might appear stretched, as it is smaller than our recommended width of 1100px.") - } - } - if (!featuredMediaConstraintsService.aspectratio(media)) { - $scope.data.post.featured_media_warnings.push("Warning! Your featured media might appear, as it does not match our recommended aspect ratio. Try 16:9"); - } - } - }); - - $scope.$watch('postBodyEditorService.media.tile', function (media) { - if (media) { - $scope.data.post.tile_media = media; - $scope.data.post.tile_media_id = media.id; - $scope.data.post.tile_media_warnings = []; - if (!tileMediaConstraintsService.width(media)) { - $scope.data.post.tile_media_warnings.push("Warning! Your tile media might appear stretched, as it is smaller than our recommended width of 375."); - } - if (!tileMediaConstraintsService.aspectratio(media)) { - $scope.data.post.tile_media_warnings.push("Warning! Your tile media might not display properly, as it does not match our recommended aspect ratio. Try 1:1"); - } - } - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/edit.info.js b/app/assets/javascripts/legacy/controllers/posts/edit.info.js deleted file mode 100644 index 61d8b3b8f..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/edit.info.js +++ /dev/null @@ -1,62 +0,0 @@ -angular.module('cortex.controllers.posts.edit.info', [ - 'cortex.services.cortex', - 'cortex.filters', - 'cortex.util', - 'cortex.directives.showErrors' -]) - -.controller('PostsEditInfoCtrl', function($scope, $filter, cortex, delayedBind, currentUser) { - // Set Slug dirty on form load if it's already been changed from the default - if ($scope.data.post.slug && $scope.data.post.slug !== $filter('slugify')($scope.data.post.title)) { - $scope.$on('$viewContentLoaded', function () { - $scope.postForm.slug.$dirty = true; - }); - } - - // Auto-generate slug when title changed and field isn't dirty - $scope.$watch('data.post.title', function(title) { - var slug = $filter('slugify')(title), - slugOverridden = $scope.postForm.slug.$dirty && $scope.postForm.slug; - - if (slugOverridden) { - return; - } - - $scope.data.post.slug = slug; - }); - - $scope.$watch('data.authorIsUser', function(authorIsUser) { - if (authorIsUser) { - $scope.data.post.custom_author = currentUser.firstname + ' ' + currentUser.lastname; - } - }); - - function slugCheck() { - var slug = $scope.data.post.slug; - if (!slug || !postForm.slug) { - return; - } - - cortex.posts.get({id: slug}, - // Slug already used - function(post) { - - // A post may have its own slug - if (post.id === $scope.data.post.id) { - $scope.postForm.slug.$setValidity('unavailable', true); - $scope.data.postWithDuplicateSlug = null; - } - else { - $scope.postForm.slug.$setValidity('unavailable', false); - $scope.data.postWithDuplicateSlug = post; - } - }, - // Slug unused - function() { - $scope.postForm.slug.$setValidity('unavailable', true); - $scope.data.postWithDuplicateSlug = null; - } - ); - } - delayedBind($scope, 'data.post.slug', 1000, slugCheck); -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/edit.js b/app/assets/javascripts/legacy/controllers/posts/edit.js deleted file mode 100644 index 18cbaa1bf..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/edit.js +++ /dev/null @@ -1,100 +0,0 @@ -angular.module('cortex.controllers.posts.edit', [ - 'ui.router.state', - 'ui.bootstrap.dropdown', - 'ui.bootstrap.buttons', - 'ui.bootstrap.datepicker', - 'ui.bootstrap.datetimepicker', - 'angular-flash.service', - 'angular-redactor', - 'cortex.vendor.underscore', - 'cortex.services.addMedia', - 'cortex.services.imageFit' -]) - -.controller('PostsEditCtrl', function($scope, $state, $timeout, flash, _, - post, filters, currentUserAuthor, categoriesHierarchy, AddMediaService, ImageFitService) { - $scope.data = { - savePost: function() { - $scope.$broadcast('validateShowErrors'); - if ($scope.postForm.$invalid) { - return; - } - $scope.data.post.category_ids = []; - angular.forEach($scope.data.post.postCategories, function(value, key) { - if (value) { - this.push(key); - } - }, $scope.data.post.category_ids); - $scope.data.post.primary_category_id = $scope.data.post.category_ids[0]; - $scope.data.post.industry_ids = [$scope.data.post.primary_industry_id]; - $scope.data.post.tag_list = $scope.data.post.tag_list.map(function(tag) { return tag.name; }); - $scope.data.post.seo_keyword_list = $scope.data.post.seo_keyword_list.map(function(seo_keyword) { return seo_keyword.name; }); - - if ($scope.data.authorIsUser) { - $scope.data.post.custom_author = null; - $scope.data.post.author_id = currentUserAuthor.id; - } else { - $scope.data.post.author_id = null; - } - - $scope.data.post.$save(function(post) { - flash.success = 'Saved "' + post.title + '"'; - $state.go('^.^.^.manage.components'); - }); - }, - cancel: function() { - $state.go('^.^.^.manage.components'); - }, - phases: _.map(filters.job_phases, function(job_phase) { - return job_phase.name; - }), - industries: filters.industries - }; - - AddMediaService.initRedactorMediaPlugin(); - ImageFitService.initRedactorImageFitPlugin(); - - $scope.redactorOptions = { - plugins: ['media', 'imageFit', 'inlinestyle'], - minHeight: 800, - buttonSource: true, - deniedTags: ['html', 'head', 'link', 'body', 'applet'] // Allow script, style - }; - - $scope.isAuthorUser = function(post) { - if (!post.id || post.author) { - return true; - } - else { - return false; - } - }; - - $scope.data.authorIsUser = $scope.isAuthorUser(post); - - if ($state.includes('cortex.posts.*.sections.article')) { - post.type = 'ArticlePost'; - } - else if ($state.includes('cortex.posts.*.sections.video')) { - post.type = 'VideoPost' - } - else if ($state.includes('cortex.posts.*.sections.infographic')) { - post.type = 'InfographicPost' - } - else if ($state.includes('cortex.posts.*.sections.promo')) { - post.type = 'PromoPost' - } - - $scope.data.post = post; - $scope.data.categoriesHierarchy = categoriesHierarchy; - - $scope.datepicker = { - expireAtOpen: false, - publishAtOpen: false, - open: function(datepicker) { - $timeout(function(){ - $scope.datepicker[datepicker] = true; - }); - } - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/edit.seo.js b/app/assets/javascripts/legacy/controllers/posts/edit.seo.js deleted file mode 100644 index 5c7407e61..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/edit.seo.js +++ /dev/null @@ -1,22 +0,0 @@ -angular.module('cortex.controllers.posts.edit.seo', [ - 'cortex.services.cortex', - 'cortex.filters' -]) - -.controller('PostsEditSeoCtrl', function($scope, $filter) { - // SEO Title should be pulled from the post title, unless it's been edited. - $scope.$watch('data.post.title', function(description) { - if ($scope.postForm.seo_title.$dirty && $scope.postForm.seo_title) { - return; - } - $scope.data.post.seo_title = $scope.data.post.title; - }); - - // Ditto SEO Description - $scope.$watch('data.post.short_description', function(description) { - if ($scope.postForm.seo_description.$dirty && $scope.postForm.seo_description) { - return; - } - $scope.data.post.seo_description = $scope.data.post.short_description; - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/grid.js b/app/assets/javascripts/legacy/controllers/posts/grid.js deleted file mode 100644 index 92b494c11..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/grid.js +++ /dev/null @@ -1,39 +0,0 @@ -angular.module('cortex.controllers.posts.grid', [ - 'ngTable', - 'ui.bootstrap', - 'cortex.services.cortex', - 'cortex.filters' -]) - -.controller('PostsGridCtrl', function($scope, ngTableParams, cortex) { - $scope.data = { - totalServerItems: 0, - posts: [], - query: null - }; - - $scope.postDataParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function($defer, params) { - cortex.posts.searchPaged({page: params.page(), per_page: params.count(), q: $scope.data.query}, - function(posts, headers, paging) { - params.total(paging.total); - $defer.resolve(posts); - }, - function(data) { - $defer.reject(data); - } - ); - } - }); - - $scope.$watch('data.query', function() { - $scope.postDataParams.reload(); - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/posts/popup.js b/app/assets/javascripts/legacy/controllers/posts/popup.js deleted file mode 100644 index 7b206048b..000000000 --- a/app/assets/javascripts/legacy/controllers/posts/popup.js +++ /dev/null @@ -1,27 +0,0 @@ -angular.module('cortex.controllers.posts.popup', [ - 'ui.router.state', - 'cortex.filters', - 'cortex.services.postsPopup' -]) - -.controller('PostsPopupCtrl', function ($scope, $timeout, $state, $filter, PostsPopupService) { - $scope.postsPopupService = PostsPopupService; - $scope.postsPopupService.popupOpen = true; - - $scope.$watch('postsPopupService.popupOpen', function (popupOpen) { - if (!popupOpen) { - // We are arbitrary levels deep, so we can't transition relative to our current state. - if ($state.includes('cortex.posts.new')) { - // We need to wait long enough for bootstrap-modal to fade away, otherwise we're stuck with a blocked-out page - $timeout(function () { - $state.go($filter('postNewState')($scope.data.post)); - }, 500); - } - else { - $timeout(function () { - $state.go($filter('postEditState')($scope.data.post, false), {postId: $scope.data.post.id}); - }, 500); - } - } - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/tenants/edit.js b/app/assets/javascripts/legacy/controllers/tenants/edit.js deleted file mode 100644 index 48217068b..000000000 --- a/app/assets/javascripts/legacy/controllers/tenants/edit.js +++ /dev/null @@ -1,97 +0,0 @@ -angular.module('cortex.controllers.tenants.edit', [ - 'ui.router.state', - 'ui.bootstrap.datepicker', - 'angular-flash.service', - 'angularBootstrapNavTree', - 'cortex.directives.tenantSettings', - 'cortex.settings', - 'cortex.util' -]) - -.controller('EditTenantsCtrl', function($scope, $stateParams, $state, $timeout, flash, events, cortex, util) { - - // angular-bootstrap datepicker settings - $scope.datepicker = { - format: 'yyyy/MM/dd', - activateAtOpen: false, - deactivateAtOpen: false, - open: function(datepicker) { - $timeout(function(){ - $scope.datepicker[datepicker] = true; - }); - } - }; - - $scope.levelName = $stateParams.organizationId ? 'tenant' : 'organization'; - $scope.creatingOrganization = util.isEmpty($stateParams.organizationId); - - // Fetch the tenant or create a new resource - if ($stateParams.tenantId) { - $scope.data.tenant = cortex.tenants.get({id: $stateParams.tenantId}); - } - else { - $scope.data.tenant = new cortex.tenants(); - } - - $scope.data.tenant.inherit_from_parent = true; - - // Initialize scope.data properties for organization tree and other directives - $scope.data.tenants = - { - hierarchy: [], - flattened: [], - selected: null - }; - - // Fetch organization hierarchy - if ($stateParams.organizationId) { - cortex.tenants.get({id: $stateParams.organizationId, include_children: true}, function(hierarchy) { - $scope.data.tenants.hierarchy = [hierarchy]; - }); - } - - $scope.creatingTenant = util.isEmpty($stateParams.tenantId); - - $scope.selectParent = function(tenant){ - $scope.data.tenants.selected = tenant; - $scope.data.tenant.parent_id = tenant.id; - }; - - $scope.save = function() { - var tenantIsNew = !$scope.data.tenant.id; - var tenantIsOrg = !$scope.data.tenant.parent_id; - - $scope.data.tenant.$save(function(tenant) { - - var message; - if ($scope.creatingOrganization) { - $scope.$emit(events.ORGANIZATIONS_CHANGE); - - if (tenantIsNew) { - message = 'Created new organization "' + tenant.name + '"'; - $state.go('.', {tenantId: tenant.id}); - } - else { - message = 'Saved organization "' + tenant.name + '"'; - } - } - else { - if (tenantIsNew) { - message = 'Created new tenant "' + tenant.name + '" under "' + $scope.data.tenants.selected.name + '"' ; - $state.go('.', {tenantId: tenant.id, organizationId: $stateParams.organizationId}); - } - else { - if (tenantIsOrg) { - message = 'Saved organization "' + tenant.name + '"'; - $scope.$emit(events.ORGANIZATIONS_CHANGE); - } - else { - message = 'Saved tenant "' + tenant.name + '"'; - } - } - } - - flash.success = message; - }); - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/tenants/manage.js b/app/assets/javascripts/legacy/controllers/tenants/manage.js deleted file mode 100644 index 0e752f99a..000000000 --- a/app/assets/javascripts/legacy/controllers/tenants/manage.js +++ /dev/null @@ -1,54 +0,0 @@ -angular.module('cortex.controllers.tenants.manage', [ - 'ui.router.state', - 'cortex.vendor.underscore', - 'cortex.services.cortex', - 'cortex.directives.tenantSettings', - 'angularBootstrapNavTree', - 'ngAnimate', - 'cortex.settings', - 'cortex.util' - ]) - -.factory('TenantsTreeStatus', function () { - return { - isLoaded: false - }; -}) - -.controller('TenantsTreeCtrl', function($scope, $stateParams, events, cortex, hierarchyUtils, TenantsTreeStatus, _) { - - var loadTenantHierarchy = function() { - TenantsTreeStatus.isLoaded = false; - - cortex.tenants.get({id: $stateParams.organizationId, include_children: true}, function(hierarchy){ - $scope.data.tenants.hierarchy = [hierarchy]; - var flattened = hierarchyUtils.flattenTenantHierarchy([hierarchy]); - $scope.data.tenants.flattened = flattened; - - // Set $scope.data.tenants.selected if tenantId was specified in URL - var tenantId = $stateParams.tenantId; - if (tenantId) { - $scope.data.tenants.selected = _.find(flattened, function(t) { return t.id == tenantId; }); - } - - TenantsTreeStatus.isLoaded = true; - }); - }; - - $scope.data.tenants = - { - hierarchy: [], - flattened: [], - selected: null - }; - - loadTenantHierarchy(); - - $scope.selectTenant = function(tenant){ - $scope.data.tenants.selected = tenant; - }; - - $scope.$on(events.TENANT_HIERARCHY_CHANGE, function (event) { - loadTenantHierarchy(); - }); -}); diff --git a/app/assets/javascripts/legacy/controllers/users/bulk.js b/app/assets/javascripts/legacy/controllers/users/bulk.js deleted file mode 100644 index 2f6bf6178..000000000 --- a/app/assets/javascripts/legacy/controllers/users/bulk.js +++ /dev/null @@ -1,83 +0,0 @@ -angular.module('cortex.controllers.users.bulk', [ - 'ui.router.state', - 'ui.bootstrap.progressbar', - 'angular-flash.service', - 'angularFileUpload', - 'cortex.settings', - 'cortex.services.cortex', - 'cortex.directives.fileSelector' -]) - - .controller('UsersBulkCtrl', function ($scope, $timeout, $upload, $state, $q, flash, cortex, settings) { - $scope.data = $scope.data || {}; - $scope.data.usersBulk = new cortex.users.bulkJob(); - $scope.data.upload = { - progress: 0 - }; - - function saveBulkJob() { - var d = $q.defer(); - - if (!$scope.data.usersBulk.metadata) { - d.reject('No metadata present.'); - } - else { - var uploadError = false; - var httpConfig = { - url: settings.cortex_base_url + '/users/bulk_job', - method: 'POST', - fields: {bulkJob: $scope.data.usersBulk}, - formDataAppender: function (formData, key, value) { - if (key === 'bulkJob') { - angular.forEach(value, function (v, k) { - formData.append('bulkJob[' + k + ']', v); - }); - } - } - }; - - $scope.data.upload.progress = 1; - $scope.data.upload = $upload.upload(httpConfig) - .then( - function (bulkJob) { //Success - d.resolve(); - }, - function (error, status) { //Error - uploadError = true; - $scope.data.upload.progress = 0; - $scope.data.upload.file = null; - - if (status === 422) { - d.reject('Selected file type is not supported. Please choose a different file.'); - } - else { - d.reject('Unhandled error: ' + error.data.errors[0]); - } - }, - function (e) { //Progress - if (uploadError) { - return; - } - $scope.data.upload.progress = parseInt(100.0 * e.loaded / e.total); - } - ); - } - - return d.promise; - } - - $scope.saveUsersBulk = function () { - saveBulkJob().then( - function () { - flash.success = 'Bulk job created'; - $state.go('cortex.bulk_jobs.manage'); - }, - function (error) { - flash.error = error; - }); - }; - - $scope.cancel = function () { - $state.go('^.manage.components'); - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/users/edit.js b/app/assets/javascripts/legacy/controllers/users/edit.js deleted file mode 100644 index d1131b8e6..000000000 --- a/app/assets/javascripts/legacy/controllers/users/edit.js +++ /dev/null @@ -1,27 +0,0 @@ -angular.module('cortex.controllers.users.edit', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.controllers.users.facets' -]) - -.controller('UsersEditCtrl', function($scope, $timeout, $state, $anchorScroll, flash, user) { - $scope.data = $scope.data || {}; - $scope.data.user = user; - - $scope.cancel = function () { - $state.go('^.facets.grid'); - }; - - $scope.saveUser = function() { - $scope.data.user.$save().then( - function() { - $state.go('^.facets.grid'); - flash.success = 'Saved user information'; - }, - function(res) { - $anchorScroll(); - flash.error = 'Error while saving user information'; - } - ); - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/users/facets.js b/app/assets/javascripts/legacy/controllers/users/facets.js deleted file mode 100644 index 5b90fc2ba..000000000 --- a/app/assets/javascripts/legacy/controllers/users/facets.js +++ /dev/null @@ -1,26 +0,0 @@ -angular.module('cortex.controllers.users.facets', [ - 'ui.router.state', - 'ngAnimate', - 'angularBootstrapNavTree', - 'cortex.util', - 'cortex.services.cortex', - 'cortex.directives.tenantSettings' -]) - - .factory('TenantTree', function () { - return { - selected: null - }; - }) - - .controller('UsersFacetCtrl', function ($scope, $stateParams, cortex, TenantTree) { - $scope.data = { - tenants: { - hierarchy: cortex.tenants.hierarchicalIndex() - } - }; - - $scope.selectTenant = function (tenant) { - TenantTree.selected = tenant; - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/users/grid.js b/app/assets/javascripts/legacy/controllers/users/grid.js deleted file mode 100644 index a7a1d20f5..000000000 --- a/app/assets/javascripts/legacy/controllers/users/grid.js +++ /dev/null @@ -1,68 +0,0 @@ -angular.module('cortex.controllers.users.grid', [ - 'ngTable', - 'ui.router.state', - 'ui.bootstrap', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters', - 'cortex.controllers.users.facets' -]) - - .controller('UsersGridCtrl', function ($scope, $window, $state, ngTableParams, flash, cortex, TenantTree) { - $scope.data = { - totalServerItems: 0, - users: [], - query: null, - tenantTree: TenantTree - }; - - $scope.userDataParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - if ($scope.data.tenantTree.selected) { - cortex.tenants.usersPaged({page: params.page(), per_page: params.count(), id: $scope.data.tenantTree.selected.id, q: $scope.data.query}, - function (users, headers, paging) { - params.total(paging.total); - $defer.resolve(users); - }, - function (data) { - $defer.reject(data); - } - ); - } - } - }); - - $scope.$watch('data.query', function () { - $scope.userDataParams.reload(); - }); - - $scope.$watch('data.tenantTree.selected', function () { - $scope.userDataParams.reload(); - }); - - $scope.editUser = function(user) { - $state.go('^.^.edit', {userId: user.id}); - }; - - $scope.deleteUser = function (user) { - if ($window.confirm('Are you sure you want to delete "' + user.email + '?"')) { - cortex.users.delete({id: user.id}, function () { - flash.warn = user.email + ' deleted.'; - $scope.userDataParams.reload(); - }, function (res) { - if (res.status === 409) { - flash.error = user.email + " is currently assigned to Content or Media and cannot be deleted"; - } else { - flash.error = user.email + " could not be deleted: " + res.data.message; - } - }); - } - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/users/new.js b/app/assets/javascripts/legacy/controllers/users/new.js deleted file mode 100644 index d469172a7..000000000 --- a/app/assets/javascripts/legacy/controllers/users/new.js +++ /dev/null @@ -1,34 +0,0 @@ -angular.module('cortex.controllers.users.new', [ - 'ui.router.state', - 'angular-flash.service', - 'validation.match', - 'cortex.controllers.users.facets' -]) - -.controller('UsersNewCtrl', function($scope, $timeout, $state, $anchorScroll, flash, user, TenantTree) { - $scope.data = $scope.data || {}; - $scope.data.user = user; - $scope.data.selectedTenant = TenantTree.selected; - - $scope.cancel = function () { - $state.go('^.facets.grid'); - }; - - $scope.saveUser = function() { - $scope.data.user.tenant_id = $scope.data.selectedTenant.id; - $scope.data.user.$save().then( - function() { - $state.go('^.facets.grid'); - flash.success = 'Saved user information'; - }, - function(res) { - $anchorScroll(); - if (res.status === 403) { - flash.error = "Chosen password is invalid"; - } else { - flash.error = 'Error while saving user information'; - } - } - ); - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/users/profile.js b/app/assets/javascripts/legacy/controllers/users/profile.js deleted file mode 100644 index 7d1bedc0f..000000000 --- a/app/assets/javascripts/legacy/controllers/users/profile.js +++ /dev/null @@ -1,41 +0,0 @@ -angular.module('cortex.controllers.users.profile', [ - 'ui.router.state', - 'angular-flash.service' -]) - -.controller('UsersProfileCtrl', function($scope, $timeout, $state, $anchorScroll, flash, user, author) { - $scope.data = $scope.data || {}; - $scope.data.user = user; - $scope.data.author = author; - - $scope.saveAuthor = function() { - $scope.data.author.$save().then( - function() { - $anchorScroll(); - flash.info = 'Saved author information'; - }, - function() { - $anchorScroll(); - flash.error = 'Error while saving author information'; - } - ); - }; - $scope.changePassword = function() { - $scope.data.user.$save().then( - function() { - flash.success = "Successfully updated password, redirecting to login page in 5 seconds..."; - $timeout(function () { $state.go('login') }, 5000); - }, - function(res) { - $anchorScroll(); - if (res.status === 403) { - flash.error = "Current password is invalid"; - } else if (res.data.errors[0] === "password_confirmation doesn't match Password") { - flash.error = "Passwords don't match."; - } else { - flash.error = "Could not change password, please try again'"; - } - } - ); - }; -}); diff --git a/app/assets/javascripts/legacy/controllers/webpages/edit.js b/app/assets/javascripts/legacy/controllers/webpages/edit.js deleted file mode 100644 index 367d907ae..000000000 --- a/app/assets/javascripts/legacy/controllers/webpages/edit.js +++ /dev/null @@ -1,87 +0,0 @@ -angular.module('cortex.controllers.webpages.edit', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex', - 'cortex.filters' - ]) - - .controller('WebpagesEditCtrl', function ($scope, $window, $document, $state, $stateParams, $anchorScroll, flash, cortex) { - $scope.data = $scope.data || {}; - $scope.data.webpage = cortex.webpages.get({id: $stateParams.webpageId}); - - var frameEventListener = function (event) { - switch (event.data.event) { - case 'cancel_editor': - cancel(); - break; - case 'save_webpage': - saveWebpage(event.data.webpage); - break; - case 'get_medias': - getMedias(event.data.page).$promise.then(function (media) { - sendFrameMessage({event: 'medias_data', medias: media}); - }); - break; - } - }; - - $window.addEventListener('message', frameEventListener, false); - $scope.$on("$destroy", function(){ - $window.removeEventListener('message', frameEventListener, false); - }); - - // Perhaps this should moved to a directive! - var sendFrameMessage = function (data) { - document.getElementById('webpage-frame').contentWindow.postMessage(JSON.parse(JSON.stringify(data)), '*'); - }; - - var cancel = function () { - $state.go('^.manage'); - }; - - var saveWebpage = function (webpage) { - delete $scope.data.webpage.snippets; - - var snippets_attributes = []; - _.each(webpage.snippets, function (value) { - snippets_attributes.push({ - id: value.id, - document_attributes: value.document - }); - }); - - $scope.data.webpage.snippets_attributes = snippets_attributes; - $scope.data.webpage.seo_keyword_list = $scope.data.webpage.seo_keyword_list.map(function(seo_keyword) { return seo_keyword.name; }); - $scope.data.webpage.$save().then( - function () { - $anchorScroll(); - flash.success = 'Saved Webpage information'; - $state.go('^.manage'); - }, - function () { - $anchorScroll(); - flash.error = 'Error while saving Webpage information'; - } - ); - }; - - var getMedias = function (page) { - return cortex.media.searchPaged({ - q: page.query, - per_page: page.perPage, - page: page.page - }); - } - - $scope.appendEditingParamsToUrl = function(url) { - var urlHasParams = _.includes(url, '?'); - - if (urlHasParams) { - url = url + '&editing_mode=1&disable_redirects=1'; - } else { - url = url + '?editing_mode=1&disable_redirects=1'; - } - - return url; - } - }); diff --git a/app/assets/javascripts/legacy/controllers/webpages/grid.js b/app/assets/javascripts/legacy/controllers/webpages/grid.js deleted file mode 100644 index 9e8b3f707..000000000 --- a/app/assets/javascripts/legacy/controllers/webpages/grid.js +++ /dev/null @@ -1,66 +0,0 @@ -angular.module('cortex.controllers.webpages.grid', [ - 'ngTable', - 'ui.bootstrap', - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex' -]) - - .controller('WebpagesGridCtrl', function ($scope, $window, $state, ngTableParams, cortex, flash) { - $scope.data = { - totalServerItems: 0, - webpages: [], - query: null - }; - - $scope.webpageDataParams = new ngTableParams({ - page: 1, - count: 10, - sorting: { - created_at: 'desc' - } - }, { - total: 0, - getData: function ($defer, params) { - cortex.webpages.searchPaged({page: params.page(), per_page: params.count(), q: $scope.data.query}, - function (webpages, headers, paging) { - params.total(paging.total); - $defer.resolve(webpages); - }, - function (data) { - $defer.reject(data); - } - ); - } - }); - - $scope.searchWebpages = function(event) { - if (event.which == 13) { - $scope.webpageDataParams.reload(); - } - - event.preventDefault(); - }; - - $scope.newWebpage = function () { - $state.go('^.new'); - }; - - $scope.editWebpage = function (webpage) { - $state.go('^.edit', {webpageId: webpage.id}); - }; - - $scope.deleteWebpage = function (webpage) { - if ($window.confirm('Are you sure you want to delete "' + webpage.name + '" with URL "' + webpage.url + '", and all associated Snippets/Documents?"')) { - cortex.webpages.delete({id: webpage.id}, function () { - $scope.data.webpages = _.reject($scope.data.webpages, function (w) { - return w.id == webpage.id; - }); - flash.warn = webpage.name + " deleted."; - $scope.webpageDataParams.reload(); - }, function (res) { - flash.error = webpage.name + " could not be deleted: " + res.data.message; - }); - } - }; - }); diff --git a/app/assets/javascripts/legacy/controllers/webpages/new.js b/app/assets/javascripts/legacy/controllers/webpages/new.js deleted file mode 100644 index 4d82adc4b..000000000 --- a/app/assets/javascripts/legacy/controllers/webpages/new.js +++ /dev/null @@ -1,26 +0,0 @@ -angular.module('cortex.controllers.webpages.new', [ - 'ui.router.state', - 'angular-flash.service', - 'cortex.services.cortex' -]) - -.controller('WebpagesNewCtrl', function ($scope, $state, $stateParams, flash, cortex) { - $scope.data = $scope.data || {}; - $scope.data.webpage = new cortex.webpages(); - - $scope.cancel = function () { - $state.go('^.manage'); - }; - - $scope.saveWebpage = function () { - $scope.data.webpage.$save().then( - function () { - flash.success = 'Saved webpage information'; - $state.go('^.manage'); - }, - function () { - flash.error = 'Error while saving webpage information'; - } - ); - }; -}); diff --git a/app/assets/javascripts/legacy/cortex.js b/app/assets/javascripts/legacy/cortex.js deleted file mode 100644 index 136d9c953..000000000 --- a/app/assets/javascripts/legacy/cortex.js +++ /dev/null @@ -1,84 +0,0 @@ -angular.module('cortex', [ - // Libraries/Vendor - 'ui.router', - 'ui.router.state', - 'angular-flash.service', - 'angular-flash.flash-alert-directive', - 'ncy-angular-breadcrumb', - 'ng-rails-csrf', - 'toggle-switch', - 'ngSanitize', - - // Cortex - 'cortex.states', - 'cortex.session', - 'cortex.vendor.moment' -]) - -.config(function ($provide, $urlRouterProvider, $httpProvider, flashProvider) { - var copy = angular.copy; - - $provide.constant('currentUser', copy(window.gon.current_user)); - $provide.constant('settings', copy(window.gon.settings)); - - $urlRouterProvider.when('/media/', '/media///'); - - $urlRouterProvider.otherwise(function($injector) { - var $state = $injector.get('$state'); - - if ($injector.get('currentUser')) { - if ($injector.get('currentUser').admin) { - $state.go('cortex.organizations.manage') - } - else { - $state.go('cortex.media.manage.components') - } - } - else { - $state.go('login'); - } - }); - - // Override the default Accept header value of 'application/json, text/plain, */*' - // as "*/*" invalidates all specificity. - // https://github.com/rails/rails/issues/9940 - // http://blog.bigbinary.com/2010/11/23/mime-type-resolution-in-rails.html - $httpProvider.defaults.headers.common['Accept'] = 'application/json, text/plain'; - - // Add Bootstrap classes to flash element - flashProvider.warnClassnames.push('alert-warning'); - flashProvider.infoClassnames.push('alert-info'); - flashProvider.successClassnames.push('alert-success'); - flashProvider.errorClassnames.push('alert-danger'); -}) - -// CortexAdminCtrl -// --------------- -// Cortex's root-level application controller -.controller('CortexCtrl', function ($rootScope, $scope, $state, $stateParams, $http, $window, currentUser, moment) { - var isDefined = angular.isDefined; - // Add $state and $stateParams to root scope for universal access within views - $rootScope.$state = $state; - $rootScope.$stateParams = $stateParams; - $rootScope.currentUser = currentUser; - $rootScope.moment = moment; - - $scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { - if (isDefined(toState.data) && isDefined(toState.data.pageTitle)) { - $scope.pageTitle = toState.data.pageTitle + " | Cortex"; - } - }); - - // Push page views google analytics, if available - if ($window._gaq) { - $scope.$on('$viewContentLoaded', function(event) { - $window._gaq.push(['_trackPageview', $location.path()]); - }); - } - - $rootScope.logout = function() { - $http.delete('/users/sign_out.json').success(function() { - $window.location.href = "/"; - }); - }; -}); diff --git a/app/assets/javascripts/legacy/directives/delayed-input.js b/app/assets/javascripts/legacy/directives/delayed-input.js deleted file mode 100644 index 2fcb8e4b7..000000000 --- a/app/assets/javascripts/legacy/directives/delayed-input.js +++ /dev/null @@ -1,28 +0,0 @@ -angular.module('cortex.directives.delayedInput', []) - -.directive('delayedInput', function($timeout) { - return { - restrict: 'E', - require: 'ngModel', - template: '', - scope: { - delay: '@', - placeholder: '@', - class: '@', - value: '=ngModel', - change: '&ngChange' - }, - link: function(scope, elem, attr, ctrl) { - scope.pendingValue = scope.value; - elem.removeClass(scope.class); - - scope.pendingChange = function() { - if (scope.pending) { $timeout.cancel(scope.pending); } - scope.pending = $timeout(function() { - scope.value = scope.pendingValue; - ctrl.$setViewValue(scope.value); - }, parseInt(scope.delay)); - }; - } - }; -}); diff --git a/app/assets/javascripts/legacy/directives/file-selector.js b/app/assets/javascripts/legacy/directives/file-selector.js deleted file mode 100644 index 7f27001cc..000000000 --- a/app/assets/javascripts/legacy/directives/file-selector.js +++ /dev/null @@ -1,46 +0,0 @@ -angular.module('cortex.directives.fileSelector', [ - 'angularFileUpload' -]) - -.directive('fileSelector', function() { - return { - restrict: 'E', - require: '^ngModel', - templateUrl: 'directives/file-selector-tpl.html', - scope: { - 'ngModel': '=', - 'multiple': '=' - }, - link: function(scope, element) { - // The file input is required to trigger an open file dialog (OFD) - var fileInput = element.find('input[type="file"]'); - var multiple = scope.multiple; - - // Allow multiple file selection - if (multiple) { - fileInput.attr('multiple', ''); - } - - scope.selectFiles = function(files) { - if (multiple) { - scope.ngModel = files; - scope.files = files; - } - else { - scope.ngModel = files[0]; - scope.files = [files[0]]; - } - }; - - // Trigger OFD - scope.browseForFiles = function() { - fileInput.click(); - }; - - scope.remove = function(file) { - scope.files.splice(scope.files.indexOf(file), 1); - scope.ngModel = scope.files; - }; - } - }; -}); diff --git a/app/assets/javascripts/legacy/directives/modal-show.js b/app/assets/javascripts/legacy/directives/modal-show.js deleted file mode 100644 index 2bf46b6a2..000000000 --- a/app/assets/javascripts/legacy/directives/modal-show.js +++ /dev/null @@ -1,36 +0,0 @@ -angular.module('cortex.directives.modalShow', []) - -.directive("modalShow", function () { - return { - restrict: "A", - scope: { - modalVisible: "=" - }, - link: function (scope, element, attrs) { - scope.showModal = function (visible) { - if (visible) { - element.modal("show"); - } - else { - element.modal("hide"); - } - }; - - if (!attrs.modalVisible) { - scope.showModal(true); - } - else { - scope.$watch("modalVisible", function (newValue, oldValue) { - scope.showModal(newValue); - }); - - element.bind("hide.bs.modal", function () { - scope.modalVisible = false; - if (!scope.$$phase && !scope.$root.$$phase) { - scope.$apply(); - } - }); - } - } - }; -}); diff --git a/app/assets/javascripts/legacy/directives/show-errors.js b/app/assets/javascripts/legacy/directives/show-errors.js deleted file mode 100644 index 092ae494f..000000000 --- a/app/assets/javascripts/legacy/directives/show-errors.js +++ /dev/null @@ -1,52 +0,0 @@ -angular.module('cortex.directives.showErrors', []) - -.factory('errorCounter', function() { - return {} -}) - -.directive('showErrors', function (errorCounter, $rootScope) { - return { - restrict: 'A', - require: '^form', - link: function (scope, el, attrs, formCtrl) { - var inputEl = el[0].querySelector("[name]"); - var inputNgEl = angular.element(inputEl); - var inputName = inputNgEl.attr('name'); - - var toggleErrors = function() { - var invalid = formCtrl[inputName].$invalid; - el.toggleClass('has-error', invalid); - var parentSelector = attrs['parentSelector']; - if (parentSelector) { - var errors = errorCounter[parentSelector] || {}; - if (invalid) { - errors[inputName] = true; - } - else if (!invalid) { - delete errors[inputName]; - } - errorCounter[parentSelector] = errors; - } - $rootScope.$broadcast('errorCountChange'); - }; - - inputNgEl.on('blur select change', toggleErrors); - scope.$on('validateShowErrors', toggleErrors); - } - } -}) -.directive('tabErrors', function(errorCounter) { - return { - restrict: 'A', - link: function(scope, el, attrs) { - scope.$on('errorCountChange', function() { - var name = attrs.selectorName; - var obj = errorCounter[name]; - if (typeof obj === 'object') { - var count = Object.keys(obj).length; - el.toggleClass('has-error', count > 0); - } - }); - } - } -}); \ No newline at end of file diff --git a/app/assets/javascripts/legacy/directives/tenant-settings.js b/app/assets/javascripts/legacy/directives/tenant-settings.js deleted file mode 100644 index 1daf3aafe..000000000 --- a/app/assets/javascripts/legacy/directives/tenant-settings.js +++ /dev/null @@ -1,8 +0,0 @@ -angular.module('cortex.directives.tenantSettings', []) - -.directive('tenantSettings', function() { - return { - restrict: 'EA', - templateUrl: 'directives/tenant-settings-tpl.html' - }; -}); \ No newline at end of file diff --git a/app/assets/javascripts/legacy/directives/youtube-selector.js b/app/assets/javascripts/legacy/directives/youtube-selector.js deleted file mode 100644 index 17eb10b8b..000000000 --- a/app/assets/javascripts/legacy/directives/youtube-selector.js +++ /dev/null @@ -1,48 +0,0 @@ -function youtubeIdFromUrl(url) { - var match = url.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/); - return match && match[2].length == 11 ? match[2] : null; -}; - -angular.module('cortex.directives.youtubeSelector', [ -]) - -// http://stackoverflow.com/questions/20447867/create-a-youtube-angularjs-directive -.directive('youtube', function($sce) { - return { - restrict: 'EA', - scope: { code: '=' }, - replace: true, - template: '
', - link: function (scope) { - scope.$watch('code', function (newVal) { - if (newVal) { - scope.url = $sce.trustAsResourceUrl("http://www.youtube.com/embed/" + newVal); - } - }); - } - }; -}) - -.controller('YoutubeSelectorCtrl', function($scope) { - $scope.$watch('youtubeLink', function() { - - if (!$scope.youtubeLink) { - $scope.ngModel = null; - return; - } - - $scope.ngModel = youtubeIdFromUrl($scope.youtubeLink); - }); -}) - -.directive('youtubeSelector', function() { - return { - restrict: 'E', - require: '^ngModel', - templateUrl: 'directives/youtube-selector-tpl.html', - controller: 'YoutubeSelectorCtrl', - scope: { - 'ngModel': '=' - } - }; -}); diff --git a/app/assets/javascripts/legacy/filters.js b/app/assets/javascripts/legacy/filters.js deleted file mode 100644 index 6c557fdf8..000000000 --- a/app/assets/javascripts/legacy/filters.js +++ /dev/null @@ -1,117 +0,0 @@ -angular.module('cortex.filters', [ - 'cortex.vendor.moment' -]) - -// Turns underscores into spaces, capitalizes first letter of string -.filter('humanize', function () { - return function (string) { - string = string.split('_').join(' ').toLowerCase(); - return string.charAt(0).toUpperCase() + string.slice(1); - }; -}) - -// Turns Media into its HTML representation -.filter('mediaToHtml', function () { - return function (media) { - var outputHtml; - - if (media.content_type === 'image') { - outputHtml = ''; - } - else { - outputHtml = '' + - media.name + - ''; - } - - return outputHtml; - }; -}) - -.filter('tagList', function () { - return function (tags) { - return _.map(tags, function (t) { - return t.name; - }).join(', '); - }; -}) - -.filter('prettifyArrayString', function () { - return function (arrayString) { - return JSON.parse(arrayString).join(", ") - }; -}) - -.filter('publishStatus', function (moment) { - return function (value, draft) { - if (!value || draft) { - return 'Draft'; - } - var publishedAt = moment(value); - var now = moment(); - return publishedAt.diff(now) <= 0 ? 'Published' : 'Scheduled'; - }; -}) - -// https://gist.github.com/thomseddon/3511330 -.filter('bytes', function () { - return function (bytes, precision) { - - if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) { - return '-'; - } - - if (typeof precision === 'undefined') { - precision = 1; - } - - var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], - number = Math.floor(Math.log(bytes) / Math.log(1024)); - - return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number]; - }; -}) - -.filter('slugify', function () { - return function (value, delim) { - if (!value) { - return ''; - } - delim = delim || "-"; - return value.toLowerCase().replace(/[^\w ]+/g, '').replace(/ +/g, delim); - }; -}) - -.filter('postEditState', function () { - return function (post, sref) { - var state = "cortex.posts.edit.sections." + post.type.replace('Post', '').toLowerCase(); - if (sref) { - state = state + "({postId: " + post.id + "})"; - } - return state; - }; -}) - -.filter('trustAsResourceUrl', function ($sce) { - return function (url) { - return $sce.trustAsResourceUrl(url); - } -}) - -.filter('postNewState', function () { - return function (post) { - return "cortex.posts.new.sections." + post.type.replace('Post', '').toLowerCase(); - }; -}); diff --git a/app/assets/javascripts/legacy/resources.js b/app/assets/javascripts/legacy/resources.js deleted file mode 100644 index a7b3e54e1..000000000 --- a/app/assets/javascripts/legacy/resources.js +++ /dev/null @@ -1,89 +0,0 @@ -angular.module('cortex.resources', [ - 'ngResource', - 'cortex.settings', - 'cortex.session' -]) - -.constant('defaultActions', { - 'get': {method: 'GET'}, - 'save': {method: 'POST'}, - 'query': {method: 'GET', isArray: true}, - 'remove': {method: 'DELETE'}, - 'delete': {method: 'DELETE'} -}) - -.constant('updateCreateActions', { - update: {method: 'PUT', inArray: false}, - create: {method: 'POST'} -}) - -.factory('cortexResource', function($resource, settings, currentUser, updateCreateActions) { - return function (url, params, actions) { - actions = angular.extend(updateCreateActions, actions); - - var resource = $resource(settings.cortex_base_url + url, params, actions); - - resource.prototype.$save = function(params, success, error) { - return this.id ? this.$update(params, success, error) : this.$create(params, success, error); - }; - return resource; - }; -}) - -.factory('paginatedResource', function(cortexResource, defaultActions) { - var forEach = angular.forEach, - extend = angular.extend, - isFunction = angular.isFunction; - - return function(url, params, actions) { - actions = extend(actions, defaultActions); - - var resource = cortexResource(url, params, actions); - - forEach(actions, function(action, name) { - // If action is paginated ($query() or pagination == true in action config) - - if (/^(QUERY)$/i.test(name) || action.paginated) { - - // Wrap action function in pagination handler - resource[name + 'Paged'] = function(params, success, error) { - if (isFunction(params)) { - error = success; success = params; params = {}; - } - - var wrappedSuccess = function(data, headers) { - var pagination; - var range = headers('X-Total'); - if (range) { - - var start = (headers('X-Page') - 1) * headers('X-Per-Page'); - var end = parseInt(headers('X-Per-Page')) + start; - var per_page = headers('X-Per-Page'); - var total = headers('X-Total'); - var page = headers('X-Page') || 1; - - pagination = { - page: page, - pages: parseInt(total / per_page) + 1, - start: start, - end: end, - per_page: per_page, - total: total - }; - } - - // Call original callback - if (isFunction(success)) { - success(data, headers, pagination); - } - - }; - - return resource[name](params, wrappedSuccess, error); - }; - } - }); - - return resource; - }; -}); diff --git a/app/assets/javascripts/legacy/services/add-media.js b/app/assets/javascripts/legacy/services/add-media.js deleted file mode 100644 index 8d7e43abc..000000000 --- a/app/assets/javascripts/legacy/services/add-media.js +++ /dev/null @@ -1,42 +0,0 @@ -angular.module('cortex.services.addMedia', [ - 'cortex.services.postBodyEditor', - 'cortex.services.postsPopup' -]) - -.factory('AddMediaService', function($state, $window, - mediaSelectType, PostBodyEditorService, PostsPopupService) { - return { - setMedia: function(type, title) { - PostBodyEditorService.mediaSelectType = type; - PostsPopupService.title = title; - $state.go('.media.manage.components'); - }, - initRedactorMediaPlugin: function() { - var that = this; - - if (!$window.RedactorPlugins) { - $window.RedactorPlugins = {}; - } - - $window.RedactorPlugins.media = function() { - return { - init: function() - { - var mediaButton = this.button.add('media', 'Media'); - this.button.setAwesome('media', 'fa-picture-o'); - this.button.addCallback(mediaButton, this.media.addMediaPopup); - - this.button.remove('image'); - this.button.remove('video'); - - PostBodyEditorService.redactor = this; - }, - addMediaPopup: function() - { - that.setMedia(mediaSelectType.ADD_MEDIA, 'Insert Media from Media Library'); - } - }; - }; - } - }; -}); diff --git a/app/assets/javascripts/legacy/services/cortex.js b/app/assets/javascripts/legacy/services/cortex.js deleted file mode 100644 index f12ef68ff..000000000 --- a/app/assets/javascripts/legacy/services/cortex.js +++ /dev/null @@ -1,95 +0,0 @@ -angular.module('cortex.services.cortex', [ - 'cortex.settings', - 'cortex.resources' -]) - -.factory('cortex', function($rootScope, $http, cortexResource, paginatedResource, settings) { - var categories = cortexResource('/categories/:id', {id: '@id'}, { - hierarchy: { - method: 'GET', - url: settings.cortex_base_url + '/categories/:id/hierarchy', - isArray: true - } - }); - - var locales = paginatedResource('/localizations/:localization_id/locales/:locale_name', {locale_name: '@locale_name'}, { - search: {method: 'GET', params: {}, isArray: true, paginated: true} - }); - - var localizations = paginatedResource('/localizations/:id', {id: '@id'}, { - search: {method: 'GET', params: {}, isArray: true, paginated: true} - }); - - var posts = paginatedResource('/posts/:id', {id: '@id'}, { - feed: {method: 'GET', params: {id: 'feed'}, isArray: true, paginated: true}, - tags: {method: 'GET', params: {id: 'tags'}, isArray: true}, - search: {method: 'GET', params: { }, isArray: true, paginated: true}, - filters: {method: 'GET', params: {id: 'filters'} } - }); - - var media = paginatedResource('/media/:id', {id: '@id'}, { - tags: {method: 'GET', params: {id: 'tags'}, isArray: true}, - search: {method: 'GET', params: { }, isArray: true, paginated: true}, - bulkJob: { - method: 'POST', - url: settings.cortex_base_url + '/media/bulk_job' - } - }); - - var users = paginatedResource('/users/:id', {id: '@id'}, { - me: {method: 'GET', params: {id: 'me'}}, - bulkJob: { - method: 'POST', - url: settings.cortex_base_url + '/users/bulk_job' - } - }); - - var tenants = paginatedResource('/tenants/:id', {id: '@id'}, { - hierarchicalIndex: {method: 'GET', params: {include_children: true}, isArray: true}, - users: { - method: 'GET', - url: settings.cortex_base_url + '/tenants/:id/users', - isArray: true, - paginated: true - } - }); - - var userAuthor = cortexResource('/users/:user_id/author', {user_id: '@user_id'}); - - var occupations = cortexResource('/occupations/:id', {id: '@id', isArray: true}, { - industries: {method: 'GET', params: {id: 'industries'}, isArray: true} - }); - - var applications = paginatedResource('/applications/:id', {id: '@id', isArray: true}, { - search: {method: 'GET', params: {}, isArray: true, paginated: true} - }); - - var credentials = paginatedResource('/applications/:application_id/credentials/:credentials_id', {credential_ids: '@credentials_id'}, { - search: {method: 'GET', params: {}, isArray: true, paginated: true} - }); - - var bulkJobs = paginatedResource('/bulk_jobs/:id', {id: '@id'}, { - search: {method: 'GET', params: { }, isArray: true, paginated: true} - }); - - var webpages = paginatedResource('/webpages/:id', {id: '@id'}, { - search: {method: 'GET', params: { }, isArray: true, paginated: true}, - feed: {method: 'GET', params: {id: 'feed'}, isArray: true, paginated: true} - }); - - return { - categories: categories, - locales: locales, - localizations: localizations, - posts: posts, - media: media, - tenants: tenants, - users: users, - userAuthor: userAuthor, - occupations: occupations, - applications: applications, - credentials: credentials, - bulk_jobs: bulkJobs, - webpages: webpages - }; -}); diff --git a/app/assets/javascripts/legacy/services/image-fit.js b/app/assets/javascripts/legacy/services/image-fit.js deleted file mode 100644 index a63cf19a0..000000000 --- a/app/assets/javascripts/legacy/services/image-fit.js +++ /dev/null @@ -1,34 +0,0 @@ -angular.module('cortex.services.imageFit', [ -]) - -.factory('ImageFitService', function($window, flash) { - return { - initRedactorImageFitPlugin: function() { - if (!$window.RedactorPlugins) { - $window.RedactorPlugins = {}; - } - - $window.RedactorPlugins.imageFit = function() { - return { - init: function() - { - var imageFitButton = this.button.add('imageFit', 'Fit to Page'); - this.button.setAwesome('imageFit', 'fa-arrows-alt'); - this.button.addCallback(imageFitButton, this.imageFit.fitImageToPage); - }, - fitImageToPage: function() - { - var imgElement = angular.element(this.selection.getCurrent()).find('img'); - - if (imgElement.length) { - imgElement.css( "width", "100%" ); - } - else { - flash.error = 'Image not found at selection.'; - } - } - }; - }; - } - }; -}); diff --git a/app/assets/javascripts/legacy/services/media-constraints.js b/app/assets/javascripts/legacy/services/media-constraints.js deleted file mode 100644 index 2f040956f..000000000 --- a/app/assets/javascripts/legacy/services/media-constraints.js +++ /dev/null @@ -1,77 +0,0 @@ -angular.module('cortex.services.mediaConstraints', []) - -.factory('mediaConstraintsService', function($rootScope) { - var filesize = function(media, max) { - return media.attachment_file_size <= max; - }; - - var width = function(media, min, max) { - return media.dimensions[0] >= min && (media.dimensions[0] <= max || max === -1); - }; - - var height = function(media, min, max) { - return media.dimensions[1] >= min && (media.dimensions[1] <= max || max === -1); - }; - - var aspectratio = function(media, valid) { - var aspectRatio = media.dimensions[0] / media.dimensions[1]; - if (angular.isNumber(valid)) { - return aspectRatio.toFixed(1) === valid.toFixed(1); - } - else if (angular.isArray(valid)) { - return valid.filter(function(x) { - return compareDecimal(x, aspectRatio) - }).length; - } - }; - - function compareDecimal(x, y) { - return x.toFixed(1) === y.toFixed(1); - } - - var totalSize = function(media, valid, decimal) { - return decimal * valid <= media.dimensions[0] * media.dimensions[1]; - }; - - return { - filesize: filesize, - width: width, - height: height, - aspectratio: aspectratio, - totalSize: totalSize - }; - -}) - -.factory('featuredMediaConstraintsService', function($rootScope, mediaConstraintsService) { - var parent = mediaConstraintsService; - var child = angular.copy(parent); - child.width = function(media) { - return parent.width(media, 1100, -1); - }; - child.totalSize = function(media) { - return parent.totalSize(media, 660000, .9); - }; - - child.aspectratio = function(media) { - return parent.aspectratio(media, [1.6, 1.7, 1.8]); - }; - - return child; - -}) - -.factory('tileMediaConstraintsService', function($rootScope, mediaConstraintsService) { - var parent = mediaConstraintsService; - var child = angular.copy(parent); - - child.width = function(media) { - return parent.width(media, 375, -1); - }; - - child.aspectratio = function(media) { - return parent.aspectratio(media, [1.0, 1.1, 1.2]); - }; - - return child; -}); \ No newline at end of file diff --git a/app/assets/javascripts/legacy/services/post-body-editor.js b/app/assets/javascripts/legacy/services/post-body-editor.js deleted file mode 100644 index 695600a7a..000000000 --- a/app/assets/javascripts/legacy/services/post-body-editor.js +++ /dev/null @@ -1,17 +0,0 @@ -angular.module('cortex.services.postBodyEditor', [ - 'cortex.filters' -]) - -.factory('PostBodyEditorService', function($filter) { - return { - redactor: {}, - mediaSelectType: '', - media: { - featured: {}, - tile: {} - }, - addMediaToPost: function (media) { - this.redactor.insert.htmlWithoutClean($filter('mediaToHtml')(media)); - } - }; -}); diff --git a/app/assets/javascripts/legacy/services/posts-popup.js b/app/assets/javascripts/legacy/services/posts-popup.js deleted file mode 100644 index 135ce7117..000000000 --- a/app/assets/javascripts/legacy/services/posts-popup.js +++ /dev/null @@ -1,9 +0,0 @@ -angular.module('cortex.services.postsPopup', [ -]) - - .factory('PostsPopupService', function() { - return { - popupOpen: true, - title: '' - }; -}); diff --git a/app/assets/javascripts/legacy/session.js b/app/assets/javascripts/legacy/session.js deleted file mode 100644 index 5dd740ee5..000000000 --- a/app/assets/javascripts/legacy/session.js +++ /dev/null @@ -1,5 +0,0 @@ -angular.module('cortex.session', []) - -.config(function($provide) { - $provide.constant('currentUser', angular.copy(window.gon.current_user)); -}); diff --git a/app/assets/javascripts/legacy/settings.js b/app/assets/javascripts/legacy/settings.js deleted file mode 100644 index e56b7ad8d..000000000 --- a/app/assets/javascripts/legacy/settings.js +++ /dev/null @@ -1,17 +0,0 @@ -angular.module('cortex.settings', []) - -.config(function($provide) { - $provide.constant('settings', angular.copy(window.gon.settings)); -}) - -.constant('events', { - // Events that should be replaced with refactored states - TENANT_HIERARCHY_CHANGE: '$tenantHierarchyChange', - ORGANIZATIONS_CHANGE: '$organizationsChange' -}) - -.constant('mediaSelectType', { - ADD_MEDIA: 'addMedia', - SET_FEATURED: 'setFeatured', - SET_TILE: 'setTile' -}); diff --git a/app/assets/javascripts/legacy/states.js b/app/assets/javascripts/legacy/states.js deleted file mode 100644 index 0ded3a012..000000000 --- a/app/assets/javascripts/legacy/states.js +++ /dev/null @@ -1,1311 +0,0 @@ -angular.module('cortex.states', [ - 'ui.router.state', - - 'cortex.services.cortex', - 'cortex.templates', - - 'cortex.controllers.users.facets', - 'cortex.controllers.users.profile', - 'cortex.controllers.users.grid', - 'cortex.controllers.users.edit', - 'cortex.controllers.users.new', - 'cortex.controllers.users.bulk', - - 'cortex.controllers.media.edit', - 'cortex.controllers.media.grid', - 'cortex.controllers.media.bulk', - - 'cortex.controllers.organizations', - 'cortex.controllers.organizations.manage', - 'cortex.controllers.tenants.edit', - 'cortex.controllers.tenants.manage', - - 'cortex.controllers.posts.edit', - 'cortex.controllers.posts.edit.info', - 'cortex.controllers.posts.edit.classify', - 'cortex.controllers.posts.edit.display', - 'cortex.controllers.posts.edit.seo', - 'cortex.controllers.posts.grid', - 'cortex.controllers.posts.popup', - - 'cortex.controllers.localizations.edit', - 'cortex.controllers.localizations.grid', - 'cortex.controllers.locales.edit', - 'cortex.controllers.locales.grid', - - 'cortex.controllers.applications.grid', - 'cortex.controllers.credentials.grid', - 'cortex.controllers.credentials.edit', - 'cortex.controllers.credentials.new', - - 'cortex.controllers.bulk_jobs.grid', - - 'cortex.controllers.webpages.grid', - 'cortex.controllers.webpages.new', - 'cortex.controllers.webpages.edit' -]) - -.config(function ($stateProvider, $urlRouterProvider) { - - // Catch /admin/media link from breadcrumb - $urlRouterProvider.when('/media', '/media///'); - - $stateProvider - .state('login', { - url: '/login', - templateUrl: 'login', - data: {pageTitle: 'Login'} - }) - - .state('cortex', { - abstract: true, - url: '', - templateUrl: 'main.html', - data: { - ncyBreadcrumbLabel: 'Home' - } - }) - - // Bulk Jobs - - .state('cortex.bulk_jobs', { - url: '/bulk_jobs', - abstract: true, - template: '', - data: { - ncyBreadcrumbLabel: 'Bulk Jobs' - } - }) - - .state('cortex.bulk_jobs.manage', { - url: '', - views: { - 'bulk-jobs@cortex.bulk_jobs': { - templateUrl: 'bulk_jobs/grid.html', - controller: 'BulkJobsGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // Localizations - - .state('cortex.localizations', { - url: '/localizations', - abstract: true, - template: '' + - '', - data: { - ncyBreadcrumbLabel: 'Localizations' - } - }) - - .state('cortex.localizations.new', { - url: '/new', - views: { - 'localizations@cortex.localizations': { - templateUrl: 'localizations/edit.html', - controller: 'LocalizationsEditCtrl' - } - }, - data: { - ncyBreadcrumbLabel: 'Add Localization' - } - }) - - .state('cortex.localizations.localization', { - url: '/:localizationId', - abstract: true, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.localizations.localization.edit', { - url: '/edit', - templateUrl: 'localizations/edit.html', - controller: 'LocalizationsEditCtrl', - views: { - 'localizations@cortex.localizations': { - templateUrl: 'localizations/edit.html', - controller: 'LocalizationsEditCtrl' - }, - 'locales-grid@cortex.localizations': { - templateUrl: 'locales/grid.html', - controller: 'LocalesGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: 'Edit Localization' - } - }) - - .state('cortex.localizations.manage', { - url: '', - views: { - 'localizations@cortex.localizations': { - templateUrl: 'localizations/grid.html', - controller: 'LocalizationsGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // Locales - - .state('cortex.localizations.localization.new_locale', { - url: '/new', - views: { - 'localizations@cortex.localizations': { - templateUrl: 'locales/edit.html', - controller: 'LocalesEditCtrl' - } - }, - data: { - ncyBreadcrumbLabel: 'Add Locale' - } - }) - - .state('cortex.localizations.localization.edit_locale', { - url: '/:localeName/edit', - views: { - 'localizations@cortex.localizations': { - templateUrl: 'locales/edit.html', - controller: 'LocalesEditCtrl' - } - }, - data: { - ncyBreadcrumbLabel: 'Edit Locale' - } - }) - - // Media - - .state('cortex.media', { - url: '/media', - abstract: true, - template: '', - data: { - ncyBreadcrumbLabel: 'Media', - ncyBreadcrumbLink: '/media///' - } - }) - - .state('cortex.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: 'Add Media' - } - }) - - .state('cortex.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: 'Edit Media' - } - }) - - .state('cortex.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // Posts - - .state('cortex.posts', { - url: '/posts', - abstract: true, - template: '', - data: { - ncyBreadcrumbLabel: 'Posts' - } - }) - - .state('cortex.posts.new', { - url: '/new', - abstract: true, - templateUrl: 'posts/edit.html', - controller: 'PostsEditCtrl', - resolve: { - post: ['$q', 'cortex', 'currentUser', function($q, cortex, currentUser) { - var defer = $q.defer(); - - var post = new cortex.posts(); - post.body = ''; - post.draft = true; - post.is_wysiwyg = true; - post.author = currentUser.full_name; - post.copyright_owner = post.copyright_owner || "CareerBuilder, LLC"; - post.tag_list = ''; - post.seo_keyword_list = ''; - post.published_at = new Date(); - post.display = 'medium'; - post.postCategories = {}; - - defer.resolve(post); - return defer.promise; - }], - categoriesHierarchy: ['cortex', function(cortex) { - return cortex.categories.hierarchy().$promise; - }], - filters: ['cortex', function(cortex) { - return cortex.posts.filters().$promise; - }], - currentUserAuthor: ['cortex', 'currentUser', function(cortex, currentUser) { - return cortex.userAuthor.get({user_id: currentUser.id}).$promise; - }] - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections', { - url: '', - abstract: true, - views: { - 'info': { - templateUrl: 'posts/article/info.html', - controller: 'PostsEditInfoCtrl' - }, - 'classify': { - templateUrl: 'posts/article/classify.html', - controller: 'PostsEditClassifyCtrl' - }, - 'display': { - templateUrl: 'posts/article/display.html', - controller: 'PostsEditDisplayCtrl' - }, - 'seo': { - templateUrl: 'posts/article/seo.html', - controller: 'PostsEditSeoCtrl' - } - } - }) - - .state('cortex.posts.new.sections.article', { - url: '/article', - data: { - ncyBreadcrumbLabel: 'New Post' - } - }) - - .state('cortex.posts.new.sections.video', { - url: '/video', - data: { - ncyBreadcrumbLabel: 'New Post' - } - }) - - .state('cortex.posts.new.sections.infographic', { - url: '/infographic', - data: { - ncyBreadcrumbLabel: 'New Post' - } - }) - - .state('cortex.posts.new.sections.promo', { - url: '/promo', - views: { - 'info@cortex.posts.new': { - templateUrl: 'posts/promo/info.html', - controller: 'PostsEditInfoCtrl' - }, - 'display@cortex.posts.new': { - templateUrl: 'posts/promo/display.html', - controller: 'PostsEditDisplayCtrl' - }, - 'seo@cortex.posts.new': { - templateUrl: 'posts/promo/seo.html', - controller: 'PostsEditSeoCtrl' - } - }, - data: { - ncyBreadcrumbLabel: 'New Post' - } - }) - - .state('cortex.posts.edit', { - url: '/:postId/edit', - abstract: true, - templateUrl: 'posts/edit.html', - controller: 'PostsEditCtrl', - resolve: { - categoriesHierarchy: ['cortex', function(cortex) { - return cortex.categories.hierarchy().$promise; - }], - filters: ['cortex', function(cortex) { - return cortex.posts.filters().$promise; - }], - currentUserAuthor: ['cortex', 'currentUser', function(cortex, currentUser) { - return cortex.userAuthor.get({user_id: currentUser.id}).$promise; - }], - post: ['$stateParams', '$q', 'cortex', function($stateParams, $q, cortex) { - var defer = $q.defer(); - - cortex.posts.get({id: $stateParams.postId}).$promise - .then(function(post) { - if (post.industry) { - post.industry_id = post.industry.id; - } - - var selectedCategoryIds = _.map(post.categories, function (c) { - return c.id; - }); - - postCategories = {}; - angular.forEach(selectedCategoryIds, function(id) { - postCategories[id] = true; - }); - post.postCategories = postCategories; - - defer.resolve(post); - }, function(response) { - defer.reject(response); - }); - - return defer.promise; - }] - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections', { - url: '', - abstract: true, - views: { - 'info': { - templateUrl: 'posts/article/info.html', - controller: 'PostsEditInfoCtrl' - }, - 'classify': { - templateUrl: 'posts/article/classify.html', - controller: 'PostsEditClassifyCtrl' - }, - 'display': { - templateUrl: 'posts/article/display.html', - controller: 'PostsEditDisplayCtrl' - }, - 'seo': { - templateUrl: 'posts/article/seo.html', - controller: 'PostsEditSeoCtrl' - } - } - }) - - .state('cortex.posts.edit.sections.article', { - url: '/article', - data: { - ncyBreadcrumbLabel: 'Edit Post' - } - }) - - .state('cortex.posts.edit.sections.video', { - url: '/video', - data: { - ncyBreadcrumbLabel: 'Edit Post' - } - }) - - .state('cortex.posts.edit.sections.infographic', { - url: '/infographic', - data: { - ncyBreadcrumbLabel: 'Edit Post' - } - }) - - .state('cortex.posts.edit.sections.promo', { - url: '/promo', - views: { - 'info@cortex.posts.edit': { - templateUrl: 'posts/promo/info.html', - controller: 'PostsEditInfoCtrl' - }, - 'display@cortex.posts.edit': { - templateUrl: 'posts/promo/display.html', - controller: 'PostsEditDisplayCtrl' - }, - 'seo@cortex.posts.edit': { - templateUrl: 'posts/promo/seo.html', - controller: 'PostsEditSeoCtrl' - } - }, - data: { - ncyBreadcrumbLabel: 'Edit Post' - } - }) - - // Posts Edit + Media Popup - // ********************** - - // ** Article/Media Popup (Edit) - - .state('cortex.posts.edit.sections.article.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.edit': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.article.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.article.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.edit.sections.article.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.article.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.article.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Video/Media Popup (Edit) - - .state('cortex.posts.edit.sections.video.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.edit': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.video.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.video.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.edit.sections.video.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.video.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.video.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Infographic/Media Popup (Edit) - - .state('cortex.posts.edit.sections.infographic.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.edit': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.infographic.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.infographic.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.edit.sections.infographic.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.infographic.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.infographic.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Promo/Media Popup (Edit) - - .state('cortex.posts.edit.sections.promo.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.edit': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.promo.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.promo.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.edit.sections.promo.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.promo.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.edit.sections.promo.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Article/Media Popup (New) - - .state('cortex.posts.new.sections.article.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.new': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.article.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.article.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.new.sections.article.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.article.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.article.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Video/Media Popup (New) - - .state('cortex.posts.new.sections.video.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.new': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.video.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.video.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.new.sections.video.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.video.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.video.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Infographic/Media Popup (New) - - .state('cortex.posts.new.sections.infographic.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.new': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.infographic.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.infographic.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.new.sections.infographic.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.infographic.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.infographic.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ** Promo/Media Popup (New) - - .state('cortex.posts.new.sections.promo.media', { - url: '/media', - abstract: true, - views: { - 'popup@cortex.posts.new': { - templateUrl: 'posts/popup.html', - controller: 'PostsPopupCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.promo.media.new', { - url: '/new', - templateUrl: 'media/new.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.promo.media.bulk', { - url: '/bulk', - templateUrl: 'media/bulk.html', - controller: 'MediaBulkCtrl', - data: { - ncyBreadcrumbLabel: 'Bulk Add Media' - } - }) - - .state('cortex.posts.new.sections.promo.media.edit', { - url: '/:mediaId/edit', - templateUrl: 'media/edit.html', - controller: 'MediaEditCtrl', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.promo.media.manage', { - url: '', - abstract: true, - templateUrl: 'media/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.new.sections.promo.media.manage.components', { - url: '/:page/:perPage/:query', - views: { - 'media-grid': { - templateUrl: 'media/grid.html', - controller: 'MediaGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - - // ********************** - - .state('cortex.posts.manage', { - url: '', - abstract: true, - templateUrl: 'posts/manage.html', - data: { - ncyBreadcrumbLabel: false - } - }) - - .state('cortex.posts.manage.components', { - url: '', - views: { - 'posts-grid': { - templateUrl: 'posts/grid.html', - controller: 'PostsGridCtrl' - } - }, - data: { - ncyBreadcrumbLabel: false - } - }) - // Tenants - - .state('cortex.organizations', { - url: '/organizations/:organizationId', - template: '
', - invisibleSpace: '', - imageTypes: ['image/png', 'image/jpeg', 'image/gif'], - indentValue: 20, - verifiedTags: ['a', 'img', 'b', 'strong', 'sub', 'sup', 'i', 'em', 'u', 'small', 'strike', 'del', 'cite', 'ul', 'ol', 'li'], // and for span tag special rule - inlineTags: ['strong', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small'], - alignmentTags: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DL', 'DT', 'DD', 'DIV', 'TD', 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'ADDRESS', 'SECTION', 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE'], - blockLevelElements: ['PRE', 'UL', 'OL', 'LI'], - highContrast: false, - observe: { - dropdowns: [] - }, - - // lang - langs: { - en: { - html: 'HTML', - video: 'Insert Video', - image: 'Insert Image', - table: 'Table', - link: 'Link', - link_insert: 'Insert link', - link_edit: 'Edit link', - unlink: 'Unlink', - formatting: 'Formatting', - paragraph: 'Normal text', - quote: 'Quote', - code: 'Code', - header1: 'Header 1', - header2: 'Header 2', - header3: 'Header 3', - header4: 'Header 4', - header5: 'Header 5', - bold: 'Bold', - italic: 'Italic', - fontcolor: 'Font Color', - backcolor: 'Back Color', - unorderedlist: 'Unordered List', - orderedlist: 'Ordered List', - outdent: 'Outdent', - indent: 'Indent', - cancel: 'Cancel', - insert: 'Insert', - save: 'Save', - _delete: 'Delete', - insert_table: 'Insert Table', - insert_row_above: 'Add Row Above', - insert_row_below: 'Add Row Below', - insert_column_left: 'Add Column Left', - insert_column_right: 'Add Column Right', - delete_column: 'Delete Column', - delete_row: 'Delete Row', - delete_table: 'Delete Table', - rows: 'Rows', - columns: 'Columns', - add_head: 'Add Head', - delete_head: 'Delete Head', - alt: 'Alt', - image_position: 'Position', - none: 'None', - left: 'Left', - right: 'Right', - center: 'Center', - image_web_link: 'Image Web Link', - text: 'Text', - mailto: 'Email', - web: 'URL', - video_html_code: 'Video Embed Code or Youtube/Vimeo Link', - file: 'Insert File', - upload: 'Upload', - download: 'Download', - choose: 'Choose', - or_choose: 'Or choose', - drop_file_here: 'Drop file here', - align_left: 'Align text to the left', - align_center: 'Center text', - align_right: 'Align text to the right', - align_justify: 'Justify text', - horizontalrule: 'Insert Horizontal Rule', - deleted: 'Deleted', - anchor: 'Anchor', - link_new_tab: 'Open link in new tab', - /* concrete5 */ - link_same_window: 'Open link in same window', - in_lightbox: 'Open link in Lightbox', - lightbox_link_type: 'Link Type', - lightbox_link_type_iframe: 'Web Page', - lightbox_link_type_image: 'Image', - lightbox_link_type_iframe_options: 'Frame Options', - lightbox_link_type_iframe_width: 'Width', - lightbox_link_type_iframe_height: 'Height', - customStyles: 'Custom Styles', - remove_font: 'Remove font', - change_font_family: 'Change font family', - remove_font_size: 'Remove font size', - change_font_size: 'Change font size', - remove_style: 'Remove Style', - insert_character: 'Insert Character', - undo: 'Undo', - redo: 'Redo', - remove_font_family: 'Remove Font Family', - // Remember to add new strings also in in /concrete/controllers/frontend/assets_localization.php, function getRedactorJavascript - /* end concrete5 */ - underline: 'Underline', - alignment: 'Alignment', - filename: 'Name (optional)', - edit: 'Edit', - upload_label: 'Drop file here or ' - } - }, - - linkify: { - regexps: { - youtube: /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig, - vimeo: /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/, - image: /((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/ig, - url: /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/ig, - } - }, - - codemirror: false - }; - - // Functionality - Redactor.fn = $.Redactor.prototype = { - - keyCode: { - BACKSPACE: 8, - DELETE: 46, - UP: 38, - DOWN: 40, - ENTER: 13, - SPACE: 32, - ESC: 27, - TAB: 9, - CTRL: 17, - META: 91, - SHIFT: 16, - ALT: 18, - RIGHT: 39, - LEFT: 37, - LEFT_WIN: 91 - }, - - // Initialization - init: function(el, options) - { - this.$element = $(el); - this.uuid = uuid++; - - // if paste event detected = true - this.rtePaste = false; - this.$pasteBox = false; - - this.loadOptions(options); - this.loadModules(); - - // formatting storage - this.formatting = {}; - - // block level tags - $.merge(this.opts.blockLevelElements, this.opts.alignmentTags); - this.reIsBlock = new RegExp('^(' + this.opts.blockLevelElements.join('|' ) + ')$', 'i'); - - // setup allowed and denied tags - this.tidy.setupAllowed(); - - // setup denied tags - if (this.opts.deniedTags !== false) - { - var tags = ['html', 'head', 'link', 'body', 'meta', 'applet']; - for (var i = 0; i < tags.length; i++) - { - this.opts.deniedTags.push(tags[i]); - } - } - - // load lang - this.lang.load(); - - // extend shortcuts - $.extend(this.opts.shortcuts, this.opts.shortcutsAdd); - - // start callback - this.core.setCallback('start'); - - // build - this.start = true; - this.build.run(); - }, - - loadOptions: function(options) - { - this.opts = $.extend( - {}, - $.extend(true, {}, $.Redactor.opts), - this.$element.data(), - options - ); - }, - getModuleMethods: function(object) - { - return Object.getOwnPropertyNames(object).filter(function(property) - { - return typeof object[property] == 'function'; - }); - }, - loadModules: function() - { - var len = $.Redactor.modules.length; - for (var i = 0; i < len; i++) - { - this.bindModuleMethods($.Redactor.modules[i]); - } - }, - bindModuleMethods: function(module) - { - if (typeof this[module] == 'undefined') return; - - // init module - this[module] = this[module](); - - var methods = this.getModuleMethods(this[module]); - var len = methods.length; - - // bind methods - for (var z = 0; z < len; z++) - { - this[module][methods[z]] = this[module][methods[z]].bind(this); - } - }, - alignment: function() - { - return { - left: function() - { - this.alignment.set(''); - }, - right: function() - { - this.alignment.set('right'); - }, - center: function() - { - this.alignment.set('center'); - }, - justify: function() - { - this.alignment.set('justify'); - }, - set: function(type) - { - // focus - if (!this.utils.browser('msie')) this.$editor.focus(); - - this.buffer.set(); - this.selection.save(); - - // get blocks - this.alignment.blocks = this.selection.getBlocks(); - this.alignment.type = type; - - // set alignment - if (this.alignment.isLinebreaksOrNoBlocks()) - { - this.alignment.setText(); - } - else - { - this.alignment.setBlocks(); - } - - // sync - this.selection.restore(); - this.code.sync(); - }, - setText: function() - { - var wrapper = this.selection.wrap('div'); - $(wrapper).attr('data-tagblock', 'redactor').css('text-align', this.alignment.type); - }, - setBlocks: function() - { - $.each(this.alignment.blocks, $.proxy(function(i, el) - { - var $el = this.utils.getAlignmentElement(el); - if (!$el) return; - - if (this.alignment.isNeedReplaceElement($el)) - { - this.alignment.replaceElement($el); - } - else - { - this.alignment.alignElement($el); - } - - }, this)); - }, - isLinebreaksOrNoBlocks: function() - { - return (this.opts.linebreaks && this.alignment.blocks[0] === false); - }, - isNeedReplaceElement: function($el) - { - return (this.alignment.type === '' && typeof($el.data('tagblock')) !== 'undefined'); - }, - replaceElement: function($el) - { - $el.replaceWith($el.html()); - }, - alignElement: function($el) - { - $el.css('text-align', this.alignment.type); - this.utils.removeEmptyAttr($el, 'style'); - } - }; - }, - autosave: function() - { - return { - html: false, - enable: function() - { - if (!this.opts.autosave) return; - - this.autosave.name = (this.opts.autosaveName) ? this.opts.autosaveName : this.$textarea.attr('name'); - - if (this.opts.autosaveOnChange) return; - this.autosaveInterval = setInterval(this.autosave.load, this.opts.autosaveInterval * 1000); - }, - onChange: function() - { - if (!this.opts.autosaveOnChange) return; - this.autosave.load(); - }, - load: function() - { - this.autosave.source = this.code.get(); - - if (this.autosave.html === this.autosave.source) return; - - // data - var data = {}; - data['name'] = this.autosave.name; - data[this.autosave.name] = this.autosave.source; - data = this.autosave.getHiddenFields(data); - - // ajax - var jsxhr = $.ajax({ - url: this.opts.autosave, - type: 'post', - data: data - }); - - jsxhr.done(this.autosave.success); - }, - getHiddenFields: function(data) - { - if (this.opts.autosaveFields === false || typeof this.opts.autosaveFields !== 'object') - { - return data; - } - - $.each(this.opts.autosaveFields, $.proxy(function(k, v) - { - if (v !== null && v.toString().indexOf('#') === 0) v = $(v).val(); - data[k] = v; - - }, this)); - - return data; - - }, - success: function(data) - { - var json; - try - { - json = $.parseJSON(data); - } - catch(e) - { - //data has already been parsed - json = data; - } - - var callbackName = (typeof json.error == 'undefined') ? 'autosave' : 'autosaveError'; - - this.core.setCallback(callbackName, this.autosave.name, json); - this.autosave.html = this.autosave.source; - }, - disable: function() - { - clearInterval(this.autosaveInterval); - } - }; - }, - block: function() - { - return { - formatting: function(name) - { - this.block.clearStyle = false; - var type, value; - - if (typeof this.formatting[name].data != 'undefined') type = 'data'; - else if (typeof this.formatting[name].attr != 'undefined') type = 'attr'; - else if (typeof this.formatting[name]['class'] != 'undefined') type = 'class'; - - if (typeof this.formatting[name].clear != 'undefined') - { - this.block.clearStyle = true; - } - - if (type) value = this.formatting[name][type]; - - this.block.format(this.formatting[name].tag, type, value); - - }, - format: function(tag, type, value) - { - if (tag == 'quote') tag = 'blockquote'; - - var formatTags = ['p', 'pre', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; - if ($.inArray(tag, formatTags) == -1) return; - - this.block.isRemoveInline = (tag == 'pre' || tag.search(/h[1-6]/i) != -1); - - // focus - if (!this.utils.browser('msie')) this.$editor.focus(); - - var html = $.trim(this.$editor.html()); - this.block.isEmpty = this.utils.isEmpty(html); - - // FF focus - if (this.utils.browser('mozilla') && !this.focus.isFocused()) - { - if (this.block.isEmpty) - { - var $first; - if (!this.opts.linebreaks) - { - $first = this.$editor.children().first(); - this.caret.setEnd($first); - } - } - } - - this.block.blocks = this.selection.getBlocks(); - - this.block.blocksSize = this.block.blocks.length; - this.block.type = type; - this.block.value = value; - - this.buffer.set(); - this.selection.save(); - - this.block.set(tag); - - this.selection.restore(); - this.code.sync(); - this.observe.load(); - - }, - set: function(tag) - { - - this.selection.get(); - this.block.containerTag = this.range.commonAncestorContainer.tagName; - - if (this.range.collapsed) - { - this.block.setCollapsed(tag); - } - else - { - this.block.setMultiple(tag); - } - }, - setCollapsed: function(tag) - { - if (this.opts.linebreaks && this.block.isEmpty && tag != 'p') - { - var node = document.createElement(tag); - this.$editor.html(node); - this.caret.setEnd(node); - - return; - } - - - var block = this.block.blocks[0]; - if (block === false) return; - - if (block.tagName == 'LI') - { - if (tag != 'blockquote') return; - - this.block.formatListToBlockquote(); - return; - } - - var isContainerTable = (this.block.containerTag == 'TD' || this.block.containerTag == 'TH'); - if (isContainerTable && !this.opts.linebreaks) - { - document.execCommand('formatblock', false, '<' + tag + '>'); - - block = this.selection.getBlock(); - this.block.toggle($(block)); - - } - else if (block.tagName.toLowerCase() != tag) - { - if (this.opts.linebreaks && tag == 'p') - { - $(block).append('