Merge master
10
.gitignore
vendored
@ -8,13 +8,14 @@
|
|||||||
._.DS_Store
|
._.DS_Store
|
||||||
dump.rdb
|
dump.rdb
|
||||||
|
|
||||||
|
bin/*
|
||||||
|
|
||||||
.sass-cache/*
|
.sass-cache/*
|
||||||
public/csv/*
|
public/csv/*
|
||||||
public/plugins/*
|
public/plugins/*
|
||||||
public/tombstone/*
|
public/tombstone/*
|
||||||
|
|
||||||
# Ignore bundler config
|
# Ignore bundler config
|
||||||
/bin
|
|
||||||
/.bundle
|
/.bundle
|
||||||
/.vagrant
|
/.vagrant
|
||||||
/.vagrantfile
|
/.vagrantfile
|
||||||
@ -29,9 +30,9 @@ config/discourse.pill
|
|||||||
config/discourse.conf
|
config/discourse.conf
|
||||||
|
|
||||||
# Ignore the default SQLite database and db dumps
|
# Ignore the default SQLite database and db dumps
|
||||||
|
*.sql
|
||||||
|
*.sql.gz
|
||||||
/db/*.sqlite3
|
/db/*.sqlite3
|
||||||
/dbs/*.sql
|
|
||||||
/dbs/*.sql.gz
|
|
||||||
/db/structure.sql
|
/db/structure.sql
|
||||||
|
|
||||||
# Ignore all logfiles and tempfiles.
|
# Ignore all logfiles and tempfiles.
|
||||||
@ -108,3 +109,6 @@ bundler_stubs/*
|
|||||||
|
|
||||||
vendor/bundle/*
|
vendor/bundle/*
|
||||||
*.db
|
*.db
|
||||||
|
|
||||||
|
#ignore jetbrains ide file
|
||||||
|
*.iml
|
||||||
|
@ -1 +1 @@
|
|||||||
ruby-2.0.0-p195
|
2.3.0
|
||||||
|
10
.travis.yml
@ -9,7 +9,7 @@ env:
|
|||||||
- "RAILS_MASTER=1"
|
- "RAILS_MASTER=1"
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
postgresql: 9.3
|
postgresql: 9.5
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- gifsicle
|
- gifsicle
|
||||||
@ -38,6 +38,10 @@ cache:
|
|||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- gem install bundler
|
- gem install bundler
|
||||||
|
- git clone --depth=1 https://github.com/discourse/discourse-backup-uploads-to-s3.git plugins/discourse-backup-uploads-to-s3
|
||||||
|
- git clone --depth=1 https://github.com/discourse/discourse-spoiler-alert.git plugins/discourse-spoiler-alert
|
||||||
|
- git clone --depth=1 https://github.com/discourse/discourse-cakeday.git plugins/discourse-cakeday
|
||||||
|
- git clone --depth=1 https://github.com/discourse/discourse-canned-replies.git plugins/discourse-canned-replies
|
||||||
- npm i -g eslint babel-eslint
|
- npm i -g eslint babel-eslint
|
||||||
- eslint app/assets/javascripts
|
- eslint app/assets/javascripts
|
||||||
- eslint --ext .es6 app/assets/javascripts
|
- eslint --ext .es6 app/assets/javascripts
|
||||||
@ -49,7 +53,7 @@ before_script:
|
|||||||
- bundle exec rake db:create db:migrate
|
- bundle exec rake db:create db:migrate
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- bash -c "if [ '$RAILS_MASTER' == '1' ]; then bundle update --retry=3 --jobs=3 arel rails rails-observers seed-fu; fi"
|
- bash -c "if [ '$RAILS_MASTER' == '1' ]; then bundle update --retry=3 --jobs=3 arel rails seed-fu; fi"
|
||||||
- bash -c "if [ '$RAILS_MASTER' == '0' ]; then bundle install --without development --deployment --retry=3 --jobs=3; fi"
|
- bash -c "if [ '$RAILS_MASTER' == '0' ]; then bundle install --without development --deployment --retry=3 --jobs=3; fi"
|
||||||
|
|
||||||
script: 'bundle exec rspec && bundle exec rake plugin:spec && bundle exec rake qunit:test'
|
script: "bundle exec rspec && bundle exec rake plugin:spec && bundle exec rake qunit:test['200000']"
|
||||||
|
33
Gemfile
@ -9,7 +9,6 @@ end
|
|||||||
if rails_master?
|
if rails_master?
|
||||||
gem 'arel', git: 'https://github.com/rails/arel.git'
|
gem 'arel', git: 'https://github.com/rails/arel.git'
|
||||||
gem 'rails', git: 'https://github.com/rails/rails.git'
|
gem 'rails', git: 'https://github.com/rails/rails.git'
|
||||||
gem 'rails-observers', git: 'https://github.com/rails/rails-observers.git'
|
|
||||||
gem 'seed-fu', git: 'https://github.com/SamSaffron/seed-fu.git', branch: 'discourse'
|
gem 'seed-fu', git: 'https://github.com/SamSaffron/seed-fu.git', branch: 'discourse'
|
||||||
else
|
else
|
||||||
# Rails 5 is going to ship with Action Cable, we have no use for it as
|
# Rails 5 is going to ship with Action Cable, we have no use for it as
|
||||||
@ -29,8 +28,6 @@ else
|
|||||||
# gem 'railties'
|
# gem 'railties'
|
||||||
# gem 'sprockets-rails'
|
# gem 'sprockets-rails'
|
||||||
gem 'rails', '~> 4.2'
|
gem 'rails', '~> 4.2'
|
||||||
|
|
||||||
gem 'rails-observers'
|
|
||||||
gem 'seed-fu', '~> 2.3.5'
|
gem 'seed-fu', '~> 2.3.5'
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -48,7 +45,8 @@ gem 'onebox'
|
|||||||
gem 'http_accept_language', '~>2.0.5', require: false
|
gem 'http_accept_language', '~>2.0.5', require: false
|
||||||
|
|
||||||
gem 'ember-rails', '0.18.5'
|
gem 'ember-rails', '0.18.5'
|
||||||
gem 'ember-source', '1.12.2'
|
gem 'ember-source', '2.10.0'
|
||||||
|
gem 'ember-handlebars-template', '0.7.5'
|
||||||
gem 'barber'
|
gem 'barber'
|
||||||
gem 'babel-transpiler'
|
gem 'babel-transpiler'
|
||||||
|
|
||||||
@ -66,7 +64,7 @@ gem 'aws-sdk', require: false
|
|||||||
gem 'excon', require: false
|
gem 'excon', require: false
|
||||||
gem 'unf', require: false
|
gem 'unf', require: false
|
||||||
|
|
||||||
gem 'email_reply_trimmer', '0.1.3'
|
gem 'email_reply_trimmer', '0.1.6'
|
||||||
|
|
||||||
# note: for image_optim to correctly work you need to follow
|
# note: for image_optim to correctly work you need to follow
|
||||||
# https://github.com/toy/image_optim
|
# https://github.com/toy/image_optim
|
||||||
@ -122,6 +120,7 @@ end
|
|||||||
group :test do
|
group :test do
|
||||||
gem 'fakeweb', '~> 1.3.0', require: false
|
gem 'fakeweb', '~> 1.3.0', require: false
|
||||||
gem 'minitest', require: false
|
gem 'minitest', require: false
|
||||||
|
gem 'timecop'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test, :development do
|
group :test, :development do
|
||||||
@ -137,9 +136,6 @@ group :test, :development do
|
|||||||
gem 'rb-inotify', '~> 0.9', require: RUBY_PLATFORM =~ /linux/i ? 'rb-inotify' : false
|
gem 'rb-inotify', '~> 0.9', require: RUBY_PLATFORM =~ /linux/i ? 'rb-inotify' : false
|
||||||
gem 'rspec-rails', require: false
|
gem 'rspec-rails', require: false
|
||||||
gem 'shoulda', require: false
|
gem 'shoulda', require: false
|
||||||
gem 'simplecov', require: false
|
|
||||||
gem 'timecop'
|
|
||||||
gem 'rspec-given'
|
|
||||||
gem 'rspec-html-matchers'
|
gem 'rspec-html-matchers'
|
||||||
gem 'spork-rails'
|
gem 'spork-rails'
|
||||||
gem 'pry-nav'
|
gem 'pry-nav'
|
||||||
@ -150,7 +146,6 @@ group :development do
|
|||||||
gem 'bullet', require: !!ENV['BULLET']
|
gem 'bullet', require: !!ENV['BULLET']
|
||||||
gem 'better_errors'
|
gem 'better_errors'
|
||||||
gem 'binding_of_caller'
|
gem 'binding_of_caller'
|
||||||
gem 'librarian', '>= 0.0.25', require: false
|
|
||||||
gem 'annotate'
|
gem 'annotate'
|
||||||
gem 'foreman', require: false
|
gem 'foreman', require: false
|
||||||
end
|
end
|
||||||
@ -169,35 +164,21 @@ gem 'htmlentities', require: false
|
|||||||
# If you want to amend mini profiler to do the monkey patches in the railties
|
# If you want to amend mini profiler to do the monkey patches in the railties
|
||||||
# we are open to it. by deferring require to the initializer we can configure discourse installs without it
|
# we are open to it. by deferring require to the initializer we can configure discourse installs without it
|
||||||
|
|
||||||
gem 'fast_stack', require: false, platform: [:mri_20]
|
|
||||||
gem 'flamegraph', require: false
|
gem 'flamegraph', require: false
|
||||||
gem 'rack-mini-profiler', require: false
|
gem 'rack-mini-profiler', require: false
|
||||||
|
|
||||||
gem 'unicorn', require: false
|
gem 'unicorn', require: false
|
||||||
gem 'puma', require: false
|
gem 'puma', require: false
|
||||||
gem 'rbtrace', require: false, platform: :mri
|
gem 'rbtrace', require: false, platform: :mri
|
||||||
|
gem 'gc_tracer', require: false, platform: :mri
|
||||||
|
|
||||||
# required for feed importing and embedding
|
# required for feed importing and embedding
|
||||||
#
|
#
|
||||||
gem 'ruby-readability', require: false
|
gem 'ruby-readability', require: false
|
||||||
|
|
||||||
gem 'simple-rss', require: false
|
gem 'simple-rss', require: false
|
||||||
|
|
||||||
gem 'gctools', require: false, platform: :mri_21
|
gem 'stackprof', require: false, platform: :mri
|
||||||
|
gem 'memory_profiler', require: false, platform: :mri
|
||||||
begin
|
|
||||||
gem 'stackprof', require: false, platform: [:mri_21, :mri_22, :mri_23]
|
|
||||||
gem 'memory_profiler', require: false, platform: [:mri_21, :mri_22, :mri_23]
|
|
||||||
rescue Bundler::GemfileError
|
|
||||||
begin
|
|
||||||
STDERR.puts "You are running an old version of bundler, please upgrade bundler ASAP, if you are using Discourse docker, rebuild your container."
|
|
||||||
gem 'stackprof', require: false, platform: [:mri_21, :mri_22]
|
|
||||||
gem 'memory_profiler', require: false, platform: [:mri_21, :mri_22]
|
|
||||||
rescue Bundler::GemfileError
|
|
||||||
gem 'stackprof', require: false, platform: [:mri_21]
|
|
||||||
gem 'memory_profiler', require: false, platform: [:mri_21]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
gem 'rmmseg-cpp', require: false
|
gem 'rmmseg-cpp', require: false
|
||||||
|
|
||||||
|
186
Gemfile.lock
@ -1,38 +1,38 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.2.7)
|
actionmailer (4.2.7.1)
|
||||||
actionpack (= 4.2.7)
|
actionpack (= 4.2.7.1)
|
||||||
actionview (= 4.2.7)
|
actionview (= 4.2.7.1)
|
||||||
activejob (= 4.2.7)
|
activejob (= 4.2.7.1)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
actionpack (4.2.7)
|
actionpack (4.2.7.1)
|
||||||
actionview (= 4.2.7)
|
actionview (= 4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
rack (~> 1.6)
|
rack (~> 1.6)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.2)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (4.2.7)
|
actionview (4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
active_model_serializers (0.8.3)
|
active_model_serializers (0.8.3)
|
||||||
activemodel (>= 3.0)
|
activemodel (>= 3.0)
|
||||||
activejob (4.2.7)
|
activejob (4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
globalid (>= 0.3.0)
|
globalid (>= 0.3.0)
|
||||||
activemodel (4.2.7)
|
activemodel (4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.2.7)
|
activerecord (4.2.7.1)
|
||||||
activemodel (= 4.2.7)
|
activemodel (= 4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
arel (~> 6.0)
|
arel (~> 6.0)
|
||||||
activesupport (4.2.7)
|
activesupport (4.2.7.1)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
json (~> 1.7, >= 1.7.7)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
@ -42,17 +42,17 @@ GEM
|
|||||||
activerecord (>= 3.2, < 6.0)
|
activerecord (>= 3.2, < 6.0)
|
||||||
rake (>= 10.4, < 12.0)
|
rake (>= 10.4, < 12.0)
|
||||||
arel (6.0.3)
|
arel (6.0.3)
|
||||||
aws-sdk (2.3.22)
|
aws-sdk (2.5.3)
|
||||||
aws-sdk-resources (= 2.3.22)
|
aws-sdk-resources (= 2.5.3)
|
||||||
aws-sdk-core (2.3.22)
|
aws-sdk-core (2.5.3)
|
||||||
jmespath (~> 1.0)
|
jmespath (~> 1.0)
|
||||||
aws-sdk-resources (2.3.22)
|
aws-sdk-resources (2.5.3)
|
||||||
aws-sdk-core (= 2.3.22)
|
aws-sdk-core (= 2.5.3)
|
||||||
babel-source (5.8.34)
|
babel-source (5.8.34)
|
||||||
babel-transpiler (0.7.0)
|
babel-transpiler (0.7.0)
|
||||||
babel-source (>= 4.0, < 6)
|
babel-source (>= 4.0, < 6)
|
||||||
execjs (~> 2.0)
|
execjs (~> 2.0)
|
||||||
barber (0.11.1)
|
barber (0.11.2)
|
||||||
ember-source (>= 1.0, < 3)
|
ember-source (>= 1.0, < 3)
|
||||||
execjs (>= 1.2, < 3)
|
execjs (>= 1.2, < 3)
|
||||||
better_errors (2.1.1)
|
better_errors (2.1.1)
|
||||||
@ -62,28 +62,27 @@ GEM
|
|||||||
binding_of_caller (0.7.2)
|
binding_of_caller (0.7.2)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
builder (3.2.2)
|
builder (3.2.2)
|
||||||
bullet (5.0.0)
|
bullet (5.4.2)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
uniform_notifier (~> 1.9.0)
|
uniform_notifier (~> 1.10.0)
|
||||||
byebug (8.2.1)
|
byebug (9.0.6)
|
||||||
certified (1.0.0)
|
certified (1.0.0)
|
||||||
coderay (1.1.0)
|
coderay (1.1.1)
|
||||||
concurrent-ruby (1.0.2)
|
concurrent-ruby (1.0.2)
|
||||||
connection_pool (2.2.0)
|
connection_pool (2.2.0)
|
||||||
crass (1.0.2)
|
crass (1.0.2)
|
||||||
daemons (1.2.3)
|
daemons (1.2.4)
|
||||||
debug_inspector (0.0.2)
|
debug_inspector (0.0.2)
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.2.5)
|
||||||
discourse-qunit-rails (0.0.9)
|
discourse-qunit-rails (0.0.9)
|
||||||
railties
|
railties
|
||||||
discourse_fastimage (2.0.3)
|
discourse_fastimage (2.0.3)
|
||||||
docile (1.1.5)
|
|
||||||
domain_name (0.5.25)
|
domain_name (0.5.25)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
email_reply_trimmer (0.1.3)
|
email_reply_trimmer (0.1.6)
|
||||||
ember-data-source (1.0.0.beta.16.1)
|
ember-data-source (2.2.1)
|
||||||
ember-source (~> 1.8)
|
ember-source (>= 1.8, < 3.0)
|
||||||
ember-handlebars-template (0.7.3)
|
ember-handlebars-template (0.7.5)
|
||||||
barber (>= 0.11.0)
|
barber (>= 0.11.0)
|
||||||
sprockets (>= 3.3, < 4)
|
sprockets (>= 3.3, < 4)
|
||||||
ember-rails (0.18.5)
|
ember-rails (0.18.5)
|
||||||
@ -93,10 +92,10 @@ GEM
|
|||||||
ember-source (>= 1.1.0)
|
ember-source (>= 1.1.0)
|
||||||
jquery-rails (>= 1.0.17)
|
jquery-rails (>= 1.0.17)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
ember-source (1.12.2)
|
ember-source (2.10.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (1.2.0.1)
|
eventmachine (1.2.0.1)
|
||||||
excon (0.45.4)
|
excon (0.53.0)
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
exifr (1.2.4)
|
exifr (1.2.4)
|
||||||
fabrication (2.9.8)
|
fabrication (2.9.8)
|
||||||
@ -104,7 +103,6 @@ GEM
|
|||||||
faraday (0.9.2)
|
faraday (0.9.2)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
fast_blank (1.0.0)
|
fast_blank (1.0.0)
|
||||||
fast_stack (0.2.0)
|
|
||||||
fast_xor (1.1.3)
|
fast_xor (1.1.3)
|
||||||
rake
|
rake
|
||||||
rake-compiler
|
rake-compiler
|
||||||
@ -114,10 +112,8 @@ GEM
|
|||||||
foreman (0.82.0)
|
foreman (0.82.0)
|
||||||
thor (~> 0.19.1)
|
thor (~> 0.19.1)
|
||||||
fspath (2.1.1)
|
fspath (2.1.1)
|
||||||
gctools (0.2.3)
|
gc_tracer (1.5.1)
|
||||||
given_core (3.7.1)
|
globalid (0.3.7)
|
||||||
sorcerer (>= 0.3.7)
|
|
||||||
globalid (0.3.6)
|
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
guess_html_encoding (0.0.11)
|
guess_html_encoding (0.0.11)
|
||||||
hashie (3.4.4)
|
hashie (3.4.4)
|
||||||
@ -136,18 +132,15 @@ GEM
|
|||||||
progress (~> 3.0, >= 3.0.1)
|
progress (~> 3.0, >= 3.0.1)
|
||||||
image_size (1.4.1)
|
image_size (1.4.1)
|
||||||
in_threads (1.3.1)
|
in_threads (1.3.1)
|
||||||
jmespath (1.3.0)
|
jmespath (1.3.1)
|
||||||
jquery-rails (4.0.5)
|
jquery-rails (4.2.1)
|
||||||
rails-dom-testing (~> 1.0)
|
rails-dom-testing (>= 1, < 3)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
json (1.8.3)
|
json (1.8.3)
|
||||||
jwt (1.5.2)
|
jwt (1.5.2)
|
||||||
kgio (2.10.0)
|
kgio (2.10.0)
|
||||||
librarian (0.1.2)
|
libv8 (5.3.332.38.3)
|
||||||
highline
|
|
||||||
thor (~> 0.15)
|
|
||||||
libv8 (5.3.332.38.1)
|
|
||||||
listen (0.7.3)
|
listen (0.7.3)
|
||||||
logster (1.2.5)
|
logster (1.2.5)
|
||||||
loofah (2.0.3)
|
loofah (2.0.3)
|
||||||
@ -155,8 +148,8 @@ GEM
|
|||||||
lru_redux (1.1.0)
|
lru_redux (1.1.0)
|
||||||
mail (2.6.4)
|
mail (2.6.4)
|
||||||
mime-types (>= 1.16, < 4)
|
mime-types (>= 1.16, < 4)
|
||||||
memory_profiler (0.9.6)
|
memory_profiler (0.9.7)
|
||||||
message_bus (2.0.1)
|
message_bus (2.0.2)
|
||||||
rack (>= 1.1.3)
|
rack (>= 1.1.3)
|
||||||
metaclass (0.0.4)
|
metaclass (0.0.4)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
@ -164,7 +157,7 @@ GEM
|
|||||||
mini_portile2 (2.1.0)
|
mini_portile2 (2.1.0)
|
||||||
mini_racer (0.1.7)
|
mini_racer (0.1.7)
|
||||||
libv8 (~> 5.3)
|
libv8 (~> 5.3)
|
||||||
minitest (5.9.0)
|
minitest (5.9.1)
|
||||||
mocha (1.1.0)
|
mocha (1.1.0)
|
||||||
metaclass (~> 0.0.1)
|
metaclass (~> 0.0.1)
|
||||||
mock_redis (0.15.4)
|
mock_redis (0.15.4)
|
||||||
@ -175,9 +168,8 @@ GEM
|
|||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
mustache (1.0.3)
|
mustache (1.0.3)
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
nokogiri (1.6.8)
|
nokogiri (1.6.8.1)
|
||||||
mini_portile2 (~> 2.1.0)
|
mini_portile2 (~> 2.1.0)
|
||||||
pkg-config (~> 1.1.7)
|
|
||||||
nokogumbo (1.4.7)
|
nokogumbo (1.4.7)
|
||||||
nokogiri
|
nokogiri
|
||||||
oauth (0.4.7)
|
oauth (0.4.7)
|
||||||
@ -187,7 +179,7 @@ GEM
|
|||||||
multi_json (~> 1.3)
|
multi_json (~> 1.3)
|
||||||
multi_xml (~> 0.5)
|
multi_xml (~> 0.5)
|
||||||
rack (~> 1.2)
|
rack (~> 1.2)
|
||||||
oj (2.14.3)
|
oj (2.17.5)
|
||||||
omniauth (1.3.1)
|
omniauth (1.3.1)
|
||||||
hashie (>= 1.2, < 4)
|
hashie (>= 1.2, < 4)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
@ -216,7 +208,7 @@ GEM
|
|||||||
omniauth-twitter (1.2.1)
|
omniauth-twitter (1.2.1)
|
||||||
json (~> 1.3)
|
json (~> 1.3)
|
||||||
omniauth-oauth (~> 1.1)
|
omniauth-oauth (~> 1.1)
|
||||||
onebox (1.6.7)
|
onebox (1.7.2)
|
||||||
fast_blank (>= 1.0.0)
|
fast_blank (>= 1.0.0)
|
||||||
htmlentities (~> 4.3.4)
|
htmlentities (~> 4.3.4)
|
||||||
moneta (~> 0.8)
|
moneta (~> 0.8)
|
||||||
@ -226,10 +218,9 @@ GEM
|
|||||||
openid-redis-store (0.0.2)
|
openid-redis-store (0.0.2)
|
||||||
redis
|
redis
|
||||||
ruby-openid
|
ruby-openid
|
||||||
pg (0.18.4)
|
pg (0.19.0)
|
||||||
pkg-config (1.1.7)
|
|
||||||
progress (3.1.1)
|
progress (3.1.1)
|
||||||
pry (0.10.3)
|
pry (0.10.4)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8.1)
|
method_source (~> 0.8.1)
|
||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
@ -237,9 +228,9 @@ GEM
|
|||||||
pry (>= 0.9.10, < 0.11.0)
|
pry (>= 0.9.10, < 0.11.0)
|
||||||
pry-rails (0.3.4)
|
pry-rails (0.3.4)
|
||||||
pry (>= 0.9.10)
|
pry (>= 0.9.10)
|
||||||
puma (3.2.0)
|
puma (3.6.0)
|
||||||
r2 (0.2.6)
|
r2 (0.2.6)
|
||||||
rack (1.6.4)
|
rack (1.6.5)
|
||||||
rack-mini-profiler (0.10.1)
|
rack-mini-profiler (0.10.1)
|
||||||
rack (>= 1.2.0)
|
rack (>= 1.2.0)
|
||||||
rack-openid (1.3.1)
|
rack-openid (1.3.1)
|
||||||
@ -249,16 +240,16 @@ GEM
|
|||||||
rack
|
rack
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.7)
|
rails (4.2.7.1)
|
||||||
actionmailer (= 4.2.7)
|
actionmailer (= 4.2.7.1)
|
||||||
actionpack (= 4.2.7)
|
actionpack (= 4.2.7.1)
|
||||||
actionview (= 4.2.7)
|
actionview (= 4.2.7.1)
|
||||||
activejob (= 4.2.7)
|
activejob (= 4.2.7.1)
|
||||||
activemodel (= 4.2.7)
|
activemodel (= 4.2.7.1)
|
||||||
activerecord (= 4.2.7)
|
activerecord (= 4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.7)
|
railties (= 4.2.7.1)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
rails-deprecated_sanitizer (1.0.3)
|
rails-deprecated_sanitizer (1.0.3)
|
||||||
activesupport (>= 4.2.0.alpha)
|
activesupport (>= 4.2.0.alpha)
|
||||||
@ -268,15 +259,14 @@ GEM
|
|||||||
rails-deprecated_sanitizer (>= 1.0.1)
|
rails-deprecated_sanitizer (>= 1.0.1)
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.3)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
rails-observers (0.1.2)
|
rails_multisite (1.0.6)
|
||||||
activemodel (~> 4.0)
|
rails (> 4.2, < 5)
|
||||||
rails_multisite (1.0.4)
|
railties (4.2.7.1)
|
||||||
railties (4.2.7)
|
actionpack (= 4.2.7.1)
|
||||||
actionpack (= 4.2.7)
|
activesupport (= 4.2.7.1)
|
||||||
activesupport (= 4.2.7)
|
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
raindrops (0.16.0)
|
raindrops (0.17.0)
|
||||||
rake (11.2.2)
|
rake (11.2.2)
|
||||||
rake-compiler (0.9.9)
|
rake-compiler (0.9.9)
|
||||||
rake
|
rake
|
||||||
@ -287,7 +277,7 @@ GEM
|
|||||||
ffi (>= 1.0.6)
|
ffi (>= 1.0.6)
|
||||||
msgpack (>= 0.4.3)
|
msgpack (>= 0.4.3)
|
||||||
trollop (>= 1.16.2)
|
trollop (>= 1.16.2)
|
||||||
redis (3.3.0)
|
redis (3.3.1)
|
||||||
redis-namespace (1.5.2)
|
redis-namespace (1.5.2)
|
||||||
redis (~> 3.0, >= 3.0.4)
|
redis (~> 3.0, >= 3.0.4)
|
||||||
rest-client (1.8.0)
|
rest-client (1.8.0)
|
||||||
@ -305,9 +295,6 @@ GEM
|
|||||||
rspec-expectations (3.4.0)
|
rspec-expectations (3.4.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.4.0)
|
rspec-support (~> 3.4.0)
|
||||||
rspec-given (3.7.1)
|
|
||||||
given_core (= 3.7.1)
|
|
||||||
rspec (>= 2.14.0)
|
|
||||||
rspec-html-matchers (0.7.0)
|
rspec-html-matchers (0.7.0)
|
||||||
nokogiri (~> 1)
|
nokogiri (~> 1)
|
||||||
rspec (~> 3)
|
rspec (~> 3)
|
||||||
@ -345,27 +332,22 @@ GEM
|
|||||||
shoulda (3.5.0)
|
shoulda (3.5.0)
|
||||||
shoulda-context (~> 1.0, >= 1.0.1)
|
shoulda-context (~> 1.0, >= 1.0.1)
|
||||||
shoulda-matchers (>= 1.4.1, < 3.0)
|
shoulda-matchers (>= 1.4.1, < 3.0)
|
||||||
shoulda-context (1.2.1)
|
shoulda-context (1.2.2)
|
||||||
shoulda-matchers (2.8.0)
|
shoulda-matchers (2.8.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
sidekiq (4.1.2)
|
sidekiq (4.2.4)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
connection_pool (~> 2.2, >= 2.2.0)
|
connection_pool (~> 2.2, >= 2.2.0)
|
||||||
|
rack-protection (>= 1.5.0)
|
||||||
redis (~> 3.2, >= 3.2.1)
|
redis (~> 3.2, >= 3.2.1)
|
||||||
sidekiq-statistic (1.2.0)
|
sidekiq-statistic (1.2.0)
|
||||||
sidekiq (>= 3.3.4, < 5)
|
sidekiq (>= 3.3.4, < 5)
|
||||||
simple-rss (1.3.1)
|
simple-rss (1.3.1)
|
||||||
simplecov (0.11.1)
|
|
||||||
docile (~> 1.1.0)
|
|
||||||
json (~> 1.8)
|
|
||||||
simplecov-html (~> 0.10.0)
|
|
||||||
simplecov-html (0.10.0)
|
|
||||||
sinatra (1.4.6)
|
sinatra (1.4.6)
|
||||||
rack (~> 1.4)
|
rack (~> 1.4)
|
||||||
rack-protection (~> 1.4)
|
rack-protection (~> 1.4)
|
||||||
tilt (>= 1.3, < 3)
|
tilt (>= 1.3, < 3)
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
sorcerer (1.0.2)
|
|
||||||
spork (1.0.0rc4)
|
spork (1.0.0rc4)
|
||||||
spork-rails (4.0.0)
|
spork-rails (4.0.0)
|
||||||
rails (>= 3.0.0, < 5)
|
rails (>= 3.0.0, < 5)
|
||||||
@ -377,27 +359,27 @@ GEM
|
|||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
stackprof (0.2.9)
|
stackprof (0.2.10)
|
||||||
thin (1.6.4)
|
thin (1.7.0)
|
||||||
daemons (~> 1.0, >= 1.0.9)
|
daemons (~> 1.0, >= 1.0.9)
|
||||||
eventmachine (~> 1.0, >= 1.0.4)
|
eventmachine (~> 1.0, >= 1.0.4)
|
||||||
rack (~> 1.0)
|
rack (>= 1, < 3)
|
||||||
thor (0.19.1)
|
thor (0.19.1)
|
||||||
thread_safe (0.3.5)
|
thread_safe (0.3.5)
|
||||||
tilt (2.0.2)
|
tilt (2.0.5)
|
||||||
timecop (0.8.0)
|
timecop (0.8.1)
|
||||||
trollop (2.1.2)
|
trollop (2.1.2)
|
||||||
tzinfo (1.2.2)
|
tzinfo (1.2.2)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.0.0)
|
uglifier (3.0.2)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.1)
|
unf_ext (0.0.7.1)
|
||||||
unicorn (5.1.0)
|
unicorn (5.2.0)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
uniform_notifier (1.9.0)
|
uniform_notifier (1.10.0)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
@ -415,26 +397,25 @@ DEPENDENCIES
|
|||||||
certified
|
certified
|
||||||
discourse-qunit-rails
|
discourse-qunit-rails
|
||||||
discourse_fastimage (= 2.0.3)
|
discourse_fastimage (= 2.0.3)
|
||||||
email_reply_trimmer (= 0.1.3)
|
email_reply_trimmer (= 0.1.6)
|
||||||
|
ember-handlebars-template (= 0.7.5)
|
||||||
ember-rails (= 0.18.5)
|
ember-rails (= 0.18.5)
|
||||||
ember-source (= 1.12.2)
|
ember-source (= 2.10.0)
|
||||||
excon
|
excon
|
||||||
execjs
|
execjs
|
||||||
fabrication (= 2.9.8)
|
fabrication (= 2.9.8)
|
||||||
fakeweb (~> 1.3.0)
|
fakeweb (~> 1.3.0)
|
||||||
fast_blank
|
fast_blank
|
||||||
fast_stack
|
|
||||||
fast_xor
|
fast_xor
|
||||||
fast_xs
|
fast_xs
|
||||||
flamegraph
|
flamegraph
|
||||||
foreman
|
foreman
|
||||||
gctools
|
gc_tracer
|
||||||
highline
|
highline
|
||||||
hiredis
|
hiredis
|
||||||
htmlentities
|
htmlentities
|
||||||
http_accept_language (~> 2.0.5)
|
http_accept_language (~> 2.0.5)
|
||||||
image_optim (= 0.20.2)
|
image_optim (= 0.20.2)
|
||||||
librarian (>= 0.0.25)
|
|
||||||
listen (= 0.7.3)
|
listen (= 0.7.3)
|
||||||
logster
|
logster
|
||||||
lru_redux
|
lru_redux
|
||||||
@ -468,7 +449,6 @@ DEPENDENCIES
|
|||||||
rack-mini-profiler
|
rack-mini-profiler
|
||||||
rack-protection
|
rack-protection
|
||||||
rails (~> 4.2)
|
rails (~> 4.2)
|
||||||
rails-observers
|
|
||||||
rails_multisite
|
rails_multisite
|
||||||
rake
|
rake
|
||||||
rb-fsevent
|
rb-fsevent
|
||||||
@ -480,7 +460,6 @@ DEPENDENCIES
|
|||||||
rinku
|
rinku
|
||||||
rmmseg-cpp
|
rmmseg-cpp
|
||||||
rspec
|
rspec
|
||||||
rspec-given
|
|
||||||
rspec-html-matchers
|
rspec-html-matchers
|
||||||
rspec-rails
|
rspec-rails
|
||||||
rtlit
|
rtlit
|
||||||
@ -493,7 +472,6 @@ DEPENDENCIES
|
|||||||
sidekiq
|
sidekiq
|
||||||
sidekiq-statistic
|
sidekiq-statistic
|
||||||
simple-rss
|
simple-rss
|
||||||
simplecov
|
|
||||||
sinatra
|
sinatra
|
||||||
spork-rails
|
spork-rails
|
||||||
stackprof
|
stackprof
|
||||||
@ -504,4 +482,4 @@ DEPENDENCIES
|
|||||||
unicorn
|
unicorn
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.13.6
|
1.13.7
|
||||||
|
@ -11,9 +11,9 @@ To learn more about the philosophy and goals of the project, [visit **discourse.
|
|||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
<a href="https://bbs.boingboing.net"><img src="https://www.discourse.org/faq/14/boing-boing-discourse.png" width="720px"></a>
|
<a href="https://bbs.boingboing.net"><img src="https://www.discourse.org/faq/14/boing-boing-discourse.png" width="720px"></a>
|
||||||
<a href="https://discuss.newrelic.com/"><img src="https://www.discourse.org/faq/14/new-relic-discourse.png" width="720px"></a>
|
<a href="https://twittercommunity.com/"><img src="https://www.discourse.org/faq/17/twitter-discourse.png" width="720px"></a>
|
||||||
<a href="http://discuss.howtogeek.com"><img src="https://www.discourse.org/faq/14/how-to-geek-discourse.png" width="720px"></a>
|
<a href="http://discuss.howtogeek.com"><img src="https://www.discourse.org/faq/17/how-to-geek-discourse.png" width="720px"></a>
|
||||||
<a href="https://talk.turtlerockstudios.com/"><img src="https://www.discourse.org/faq/14/turtle-rock-discourse.jpg" width="720px"></a>
|
<a href="https://talk.turtlerockstudios.com/"><img src="https://www.discourse.org/faq/17/turtle-rock-discourse.png" width="720px"></a>
|
||||||
|
|
||||||
<a href="https://discuss.atom.io"><img src="https://www.discourse.org/faq/15/nexus-7-2013-mobile-discourse.png?v=2" alt="Atom" width="430px"></a>
|
<a href="https://discuss.atom.io"><img src="https://www.discourse.org/faq/15/nexus-7-2013-mobile-discourse.png?v=2" alt="Atom" width="430px"></a>
|
||||||
<a href="//discourse.soylent.com"><img src="https://www.discourse.org/faq/15/iphone-5s-mobile-discourse.png" alt="Soylent" width="270px"></a>
|
<a href="//discourse.soylent.com"><img src="https://www.discourse.org/faq/15/iphone-5s-mobile-discourse.png" alt="Soylent" width="270px"></a>
|
||||||
|
Before Width: | Height: | Size: 2.4 KiB |
BIN
app/assets/images/favicons/google_branding/logo_docs_48px.png
Normal file
After Width: | Height: | Size: 919 B |
Before Width: | Height: | Size: 5.6 KiB |
BIN
app/assets/images/favicons/google_branding/logo_drive_48px.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.8 KiB |
BIN
app/assets/images/favicons/google_branding/logo_forms_48px.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.6 KiB |
BIN
app/assets/images/favicons/google_branding/logo_sheets_48px.png
Normal file
After Width: | Height: | Size: 1021 B |
Before Width: | Height: | Size: 2.5 KiB |
BIN
app/assets/images/favicons/google_branding/logo_slides_48px.png
Normal file
After Width: | Height: | Size: 932 B |
@ -0,0 +1,7 @@
|
|||||||
|
import RESTAdapter from 'discourse/adapters/rest';
|
||||||
|
|
||||||
|
export default RESTAdapter.extend({
|
||||||
|
basePath() {
|
||||||
|
return '/admin/api/';
|
||||||
|
}
|
||||||
|
});
|
7
app/assets/javascripts/admin/adapters/web-hook.js.es6
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import RESTAdapter from 'discourse/adapters/rest';
|
||||||
|
|
||||||
|
export default RESTAdapter.extend({
|
||||||
|
basePath() {
|
||||||
|
return '/admin/api/';
|
||||||
|
}
|
||||||
|
});
|
@ -1,6 +1,5 @@
|
|||||||
/* global ace:true */
|
|
||||||
import loadScript from 'discourse/lib/load-script';
|
import loadScript from 'discourse/lib/load-script';
|
||||||
import { escapeExpression } from 'discourse/lib/utilities';
|
import { observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
mode: 'css',
|
mode: 'css',
|
||||||
@ -8,18 +7,11 @@ export default Ember.Component.extend({
|
|||||||
_editor: null,
|
_editor: null,
|
||||||
_skipContentChangeEvent: null,
|
_skipContentChangeEvent: null,
|
||||||
|
|
||||||
contentChanged: function() {
|
@observes('content')
|
||||||
|
contentChanged() {
|
||||||
if (this._editor && !this._skipContentChangeEvent) {
|
if (this._editor && !this._skipContentChangeEvent) {
|
||||||
this._editor.getSession().setValue(this.get('content'));
|
this._editor.getSession().setValue(this.get('content'));
|
||||||
}
|
}
|
||||||
}.observes('content'),
|
|
||||||
|
|
||||||
render(buffer) {
|
|
||||||
buffer.push("<div class='ace'>");
|
|
||||||
if (this.get('content')) {
|
|
||||||
buffer.push(escapeExpression(this.get('content')));
|
|
||||||
}
|
|
||||||
buffer.push("</div>");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_destroyEditor: function() {
|
_destroyEditor: function() {
|
||||||
@ -39,31 +31,31 @@ export default Ember.Component.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_initEditor: function() {
|
didInsertElement() {
|
||||||
const self = this;
|
this._super();
|
||||||
|
|
||||||
loadScript("/javascripts/ace/ace.js", { scriptTag: true }).then(function() {
|
loadScript("/javascripts/ace/ace.js", { scriptTag: true }).then(() => {
|
||||||
ace.require(['ace/ace'], function(loadedAce) {
|
window.ace.require(['ace/ace'], loadedAce => {
|
||||||
const editor = loadedAce.edit(self.$('.ace')[0]);
|
if (!this.element || this.isDestroying || this.isDestroyed) { return; }
|
||||||
|
const editor = loadedAce.edit(this.$('.ace')[0]);
|
||||||
|
|
||||||
editor.setTheme("ace/theme/chrome");
|
editor.setTheme("ace/theme/chrome");
|
||||||
editor.setShowPrintMargin(false);
|
editor.setShowPrintMargin(false);
|
||||||
editor.getSession().setMode("ace/mode/" + self.get('mode'));
|
editor.getSession().setMode("ace/mode/" + this.get('mode'));
|
||||||
editor.on('change', function() {
|
editor.on('change', () => {
|
||||||
self._skipContentChangeEvent = true;
|
this._skipContentChangeEvent = true;
|
||||||
self.set('content', editor.getSession().getValue());
|
this.set('content', editor.getSession().getValue());
|
||||||
self._skipContentChangeEvent = false;
|
this._skipContentChangeEvent = false;
|
||||||
});
|
});
|
||||||
editor.$blockScrolling = Infinity;
|
editor.$blockScrolling = Infinity;
|
||||||
|
|
||||||
self.$().data('editor', editor);
|
this.$().data('editor', editor);
|
||||||
self._editor = editor;
|
this._editor = editor;
|
||||||
if (self.appEvents) {
|
if (this.appEvents) {
|
||||||
// xxx: don't run during qunit tests
|
// xxx: don't run during qunit tests
|
||||||
self.appEvents.on('ace:resize', self, self.resize);
|
this.appEvents.on('ace:resize', self, self.resize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}.on('didInsertElement')
|
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,27 @@
|
|||||||
import debounce from 'discourse/lib/debounce';
|
import debounce from 'discourse/lib/debounce';
|
||||||
import { renderSpinner } from 'discourse/helpers/loading-spinner';
|
import { renderSpinner } from 'discourse/helpers/loading-spinner';
|
||||||
import { escapeExpression } from 'discourse/lib/utilities';
|
import { escapeExpression } from 'discourse/lib/utilities';
|
||||||
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
export default Ember.View.extend({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
classNames: ["admin-backups-logs"],
|
classNames: ["admin-backups-logs"],
|
||||||
|
|
||||||
_initialize: function() { this._reset(); }.on("init"),
|
init() {
|
||||||
|
this._super();
|
||||||
|
this._reset();
|
||||||
|
},
|
||||||
|
|
||||||
_reset() {
|
_reset() {
|
||||||
this.setProperties({ formattedLogs: "", index: 0 });
|
this.setProperties({ formattedLogs: "", index: 0 });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_scrollDown() {
|
||||||
|
const $div = this.$()[0];
|
||||||
|
$div.scrollTop = $div.scrollHeight;
|
||||||
|
},
|
||||||
|
|
||||||
_updateFormattedLogs: debounce(function() {
|
_updateFormattedLogs: debounce(function() {
|
||||||
const logs = this.get("controller.model");
|
const logs = this.get("logs");
|
||||||
if (logs.length === 0) {
|
if (logs.length === 0) {
|
||||||
this._reset(); // reset the cached logs whenever the model is reset
|
this._reset(); // reset the cached logs whenever the model is reset
|
||||||
} else {
|
} else {
|
||||||
@ -26,11 +35,12 @@ export default Ember.View.extend({
|
|||||||
// update the formatted logs & cache index
|
// update the formatted logs & cache index
|
||||||
this.setProperties({ formattedLogs: formattedLogs, index: logs.length });
|
this.setProperties({ formattedLogs: formattedLogs, index: logs.length });
|
||||||
// force rerender
|
// force rerender
|
||||||
this.rerender();
|
this.rerenderBuffer();
|
||||||
}
|
}
|
||||||
}, 150).observes("controller.model.[]"),
|
Ember.run.scheduleOnce('afterRender', this, this._scrollDown);
|
||||||
|
}, 150).observes("logs.[]").on('init'),
|
||||||
|
|
||||||
render(buffer) {
|
buildBuffer(buffer) {
|
||||||
const formattedLogs = this.get("formattedLogs");
|
const formattedLogs = this.get("formattedLogs");
|
||||||
if (formattedLogs && formattedLogs.length > 0) {
|
if (formattedLogs && formattedLogs.length > 0) {
|
||||||
buffer.push("<pre>");
|
buffer.push("<pre>");
|
||||||
@ -40,14 +50,8 @@ export default Ember.View.extend({
|
|||||||
buffer.push("<p>" + I18n.t("admin.backups.logs.none") + "</p>");
|
buffer.push("<p>" + I18n.t("admin.backups.logs.none") + "</p>");
|
||||||
}
|
}
|
||||||
// add a loading indicator
|
// add a loading indicator
|
||||||
if (this.get("controller.status.model.isOperationRunning")) {
|
if (this.get("status.isOperationRunning")) {
|
||||||
buffer.push(renderSpinner('small'));
|
buffer.push(renderSpinner('small'));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}));
|
||||||
_forceScrollToBottom: function() {
|
|
||||||
const $div = this.$()[0];
|
|
||||||
$div.scrollTop = $div.scrollHeight;
|
|
||||||
}.on("didInsertElement")
|
|
||||||
|
|
||||||
});
|
|
@ -0,0 +1,42 @@
|
|||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['hook-event'],
|
||||||
|
typeName: Ember.computed.alias('type.name'),
|
||||||
|
|
||||||
|
@computed('typeName')
|
||||||
|
name(typeName) {
|
||||||
|
return I18n.t(`admin.web_hooks.${typeName}_event.name`);
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('typeName')
|
||||||
|
details(typeName) {
|
||||||
|
return I18n.t(`admin.web_hooks.${typeName}_event.details`);
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.[]', 'typeName')
|
||||||
|
eventTypeExists(eventTypes, typeName) {
|
||||||
|
return eventTypes.any(event => event.name === typeName);
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('eventTypeExists')
|
||||||
|
enabled: {
|
||||||
|
get(eventTypeExists) {
|
||||||
|
return eventTypeExists;
|
||||||
|
},
|
||||||
|
set(value, eventTypeExists) {
|
||||||
|
const type = this.get('type');
|
||||||
|
const model = this.get('model');
|
||||||
|
// add an association when not exists
|
||||||
|
if (value !== eventTypeExists) {
|
||||||
|
if (value) {
|
||||||
|
model.addObject(type);
|
||||||
|
} else {
|
||||||
|
model.removeObjects(model.filter(eventType => eventType.name === type.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,78 @@
|
|||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
|
import { ensureJSON, plainJSON, prettyJSON } from 'discourse/lib/formatter';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'li',
|
||||||
|
expandDetails: null,
|
||||||
|
|
||||||
|
@computed('model.status')
|
||||||
|
statusColorClasses(status) {
|
||||||
|
if (!status) return '';
|
||||||
|
|
||||||
|
if (status >= 200 && status <= 299) {
|
||||||
|
return 'text-successful';
|
||||||
|
} else {
|
||||||
|
return 'text-danger';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.created_at')
|
||||||
|
createdAt(createdAt) {
|
||||||
|
return moment(createdAt).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.duration')
|
||||||
|
completion(duration) {
|
||||||
|
const seconds = Math.floor(duration / 10.0) / 100.0;
|
||||||
|
return I18n.t('admin.web_hooks.events.completed_in', { count: seconds });
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
redeliver() {
|
||||||
|
return bootbox.confirm(I18n.t('admin.web_hooks.events.redeliver_confirm'), I18n.t('no_value'), I18n.t('yes_value'), result => {
|
||||||
|
if (result) {
|
||||||
|
ajax(`/admin/api/web_hooks/${this.get('model.web_hook_id')}/events/${this.get('model.id')}/redeliver`, { type: 'POST' }).then(json => {
|
||||||
|
this.set('model', json.web_hook_event);
|
||||||
|
}).catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleRequest() {
|
||||||
|
const expandDetailsKey = 'request';
|
||||||
|
|
||||||
|
if (this.get('expandDetails') !== expandDetailsKey) {
|
||||||
|
let headers = _.extend({
|
||||||
|
'Request URL': this.get('model.request_url'),
|
||||||
|
'Request method': 'POST'
|
||||||
|
}, ensureJSON(this.get('model.headers')));
|
||||||
|
this.setProperties({
|
||||||
|
headers: plainJSON(headers),
|
||||||
|
body: prettyJSON(this.get('model.payload')),
|
||||||
|
expandDetails: expandDetailsKey,
|
||||||
|
bodyLabel: I18n.t('admin.web_hooks.events.payload')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.set('expandDetails', null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleResponse() {
|
||||||
|
const expandDetailsKey = 'response';
|
||||||
|
|
||||||
|
if (this.get('expandDetails') !== expandDetailsKey) {
|
||||||
|
this.setProperties({
|
||||||
|
headers: plainJSON(this.get('model.response_headers')),
|
||||||
|
body: this.get('model.response_body'),
|
||||||
|
expandDetails: expandDetailsKey,
|
||||||
|
bodyLabel: I18n.t('admin.web_hooks.events.body')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.set('expandDetails', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,28 @@
|
|||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
||||||
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
classes: ["text-muted", "text-danger", "text-successful"],
|
||||||
|
icons: ["circle-o", "times-circle", "circle"],
|
||||||
|
|
||||||
|
@computed('deliveryStatuses', 'model.last_delivery_status')
|
||||||
|
status(deliveryStatuses, lastDeliveryStatus) {
|
||||||
|
return deliveryStatuses.find(s => s.id === lastDeliveryStatus);
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('status.id', 'icons')
|
||||||
|
icon(statusId, icons) {
|
||||||
|
return icons[statusId - 1];
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('status.id', 'classes')
|
||||||
|
class(statusId, classes) {
|
||||||
|
return classes[statusId - 1];
|
||||||
|
},
|
||||||
|
|
||||||
|
buildBuffer(buffer) {
|
||||||
|
buffer.push(iconHTML(this.get('icon'), { class: this.get('class') }));
|
||||||
|
buffer.push(I18n.t(`admin.web_hooks.delivery_status.${this.get('status.name')}`));
|
||||||
|
}
|
||||||
|
}));
|
@ -1,6 +1,8 @@
|
|||||||
|
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
router: function() {
|
router: function() {
|
||||||
return this.container.lookup('router:main');
|
return getOwner(this).lookup('router:main');
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
active: function() {
|
active: function() {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
export default Ember.View.extend({
|
export default Ember.Component.extend({
|
||||||
_disableCustomStylesheets: function() {
|
willInsertElement() {
|
||||||
|
this._super();
|
||||||
if (this.session.get("disableCustomCSS")) {
|
if (this.session.get("disableCustomCSS")) {
|
||||||
$("link.custom-css").attr("rel", "");
|
$("link.custom-css").attr("rel", "");
|
||||||
this.session.set("disableCustomCSS", false);
|
this.session.set("disableCustomCSS", false);
|
||||||
}
|
}
|
||||||
}.on("willInsertElement"),
|
},
|
||||||
|
|
||||||
_enableCustomStylesheets: function() {
|
willDestroyElement() {
|
||||||
|
this._super();
|
||||||
$("link.custom-css").attr("rel", "stylesheet");
|
$("link.custom-css").attr("rel", "stylesheet");
|
||||||
}.on("willDestroyElement")
|
}
|
||||||
});
|
});
|
@ -30,10 +30,11 @@ export default Ember.Component.extend(bufferedProperty('host'), {
|
|||||||
save() {
|
save() {
|
||||||
if (this.get('cantSave')) { return; }
|
if (this.get('cantSave')) { return; }
|
||||||
|
|
||||||
const props = this.get('buffered').getProperties('host');
|
const props = this.get('buffered').getProperties('host', 'path_whitelist');
|
||||||
props.category_id = this.get('categoryId');
|
props.category_id = this.get('categoryId');
|
||||||
|
|
||||||
const host = this.get('host');
|
const host = this.get('host');
|
||||||
|
|
||||||
host.save(props).then(() => {
|
host.save(props).then(() => {
|
||||||
host.set('category', Discourse.Category.findById(this.get('categoryId')));
|
host.set('category', Discourse.Category.findById(this.get('categoryId')));
|
||||||
this.set('editToggled', false);
|
this.set('editToggled', false);
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import ListView from 'ember-addons/list-view';
|
|
||||||
import ListItemView from 'ember-addons/list-item-view';
|
|
||||||
|
|
||||||
export default ListView.extend({
|
|
||||||
height: 700,
|
|
||||||
rowHeight: 32,
|
|
||||||
itemViewClass: ListItemView.extend({templateName: "admin/templates/permalinks_list_item"})
|
|
||||||
});
|
|
@ -1,3 +1,5 @@
|
|||||||
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
/*global Resumable:true */
|
/*global Resumable:true */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,7 +12,7 @@
|
|||||||
uploadText="UPLOAD"
|
uploadText="UPLOAD"
|
||||||
}}
|
}}
|
||||||
**/
|
**/
|
||||||
const ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer, {
|
export default Ember.Component.extend(bufferedRender({
|
||||||
tagName: "button",
|
tagName: "button",
|
||||||
classNames: ["btn", "ru"],
|
classNames: ["btn", "ru"],
|
||||||
classNameBindings: ["isUploading"],
|
classNameBindings: ["isUploading"],
|
||||||
@ -36,9 +38,9 @@ const ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer,
|
|||||||
}
|
}
|
||||||
}.property("isUploading", "progress"),
|
}.property("isUploading", "progress"),
|
||||||
|
|
||||||
renderString: function(buffer) {
|
buildBuffer(buffer) {
|
||||||
var icon = this.get("isUploading") ? "times" : "upload";
|
const icon = this.get("isUploading") ? "times" : "upload";
|
||||||
buffer.push("<i class='fa fa-" + icon + "'></i>");
|
buffer.push(`<i class="fa fa-${icon}"></i>`);
|
||||||
buffer.push("<span class='ru-label'>" + this.get("text") + "</span>");
|
buffer.push("<span class='ru-label'>" + this.get("text") + "</span>");
|
||||||
buffer.push("<span class='ru-progress' style='width:" + this.get("progress") + "%'></span>");
|
buffer.push("<span class='ru-progress' style='width:" + this.get("progress") + "%'></span>");
|
||||||
},
|
},
|
||||||
@ -117,6 +119,4 @@ const ResumableUploadComponent = Ember.Component.extend(Discourse.StringBuffer,
|
|||||||
}
|
}
|
||||||
}.on("willDestroyElement")
|
}.on("willDestroyElement")
|
||||||
|
|
||||||
});
|
}));
|
||||||
|
|
||||||
export default ResumableUploadComponent;
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import ListView from 'ember-addons/list-view';
|
|
||||||
import ListItemView from 'ember-addons/list-item-view';
|
|
||||||
|
|
||||||
export default ListView.extend({
|
|
||||||
height: 700,
|
|
||||||
rowHeight: 32,
|
|
||||||
itemViewClass: ListItemView.extend({templateName: "admin/templates/logs/screened_emails_list_item"})
|
|
||||||
});
|
|
@ -1,8 +0,0 @@
|
|||||||
import ListView from 'ember-addons/list-view';
|
|
||||||
import ListItemView from 'ember-addons/list-item-view';
|
|
||||||
|
|
||||||
export default ListView.extend({
|
|
||||||
height: 700,
|
|
||||||
rowHeight: 32,
|
|
||||||
itemViewClass: ListItemView.extend({templateName: "admin/templates/logs/screened_ip_addresses_list_item"})
|
|
||||||
});
|
|
@ -1,8 +0,0 @@
|
|||||||
import ListView from 'ember-addons/list-view';
|
|
||||||
import ListItemView from 'ember-addons/list-item-view';
|
|
||||||
|
|
||||||
export default ListView.extend({
|
|
||||||
height: 700,
|
|
||||||
rowHeight: 32,
|
|
||||||
itemViewClass: ListItemView.extend({templateName: "admin/templates/logs/screened_urls_list_item"})
|
|
||||||
});
|
|
@ -1,12 +1,11 @@
|
|||||||
import BufferedContent from 'discourse/mixins/buffered-content';
|
import BufferedContent from 'discourse/mixins/buffered-content';
|
||||||
import ScrollTop from 'discourse/mixins/scroll-top';
|
|
||||||
import SiteSetting from 'admin/models/site-setting';
|
import SiteSetting from 'admin/models/site-setting';
|
||||||
import { propertyNotEqual } from 'discourse/lib/computed';
|
import { propertyNotEqual } from 'discourse/lib/computed';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list', 'category_list', 'value_list'];
|
const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list', 'category_list', 'value_list'];
|
||||||
|
|
||||||
export default Ember.Component.extend(BufferedContent, ScrollTop, {
|
export default Ember.Component.extend(BufferedContent, {
|
||||||
classNameBindings: [':row', ':setting', 'setting.overridden', 'typeClass'],
|
classNameBindings: [':row', ':setting', 'setting.overridden', 'typeClass'],
|
||||||
content: Ember.computed.alias('setting'),
|
content: Ember.computed.alias('setting'),
|
||||||
dirty: propertyNotEqual('buffered.value', 'setting.value'),
|
dirty: propertyNotEqual('buffered.value', 'setting.value'),
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import ListView from 'ember-addons/list-view';
|
|
||||||
import ListItemView from 'ember-addons/list-item-view';
|
|
||||||
|
|
||||||
export default ListView.extend({
|
|
||||||
height: 700,
|
|
||||||
rowHeight: 75,
|
|
||||||
itemViewClass: ListItemView.extend({templateName: "admin/templates/logs/staff_action_logs_list_item"})
|
|
||||||
});
|
|
@ -0,0 +1,32 @@
|
|||||||
|
import ApiKey from 'admin/models/api-key';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
generateMasterKey() {
|
||||||
|
ApiKey.generateMasterKey().then(key => this.get('model').pushObject(key));
|
||||||
|
},
|
||||||
|
|
||||||
|
regenerateKey(key) {
|
||||||
|
bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||||
|
if (result) {
|
||||||
|
key.regenerate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
revokeKey(key) {
|
||||||
|
bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||||
|
if (result) {
|
||||||
|
key.revoke().then(() => this.get('model').removeObject(key));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Has a master key already been generated?
|
||||||
|
hasMasterKey: function() {
|
||||||
|
return !!this.get('model').findBy('user', null);
|
||||||
|
}.property('model.[]')
|
||||||
|
|
||||||
|
});
|
@ -1,68 +0,0 @@
|
|||||||
import ApiKey from 'admin/models/api-key';
|
|
||||||
|
|
||||||
/**
|
|
||||||
This controller supports the interface for dealing with API keys
|
|
||||||
|
|
||||||
@class AdminApiController
|
|
||||||
@extends Ember.ArrayController
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
export default Ember.ArrayController.extend({
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
/**
|
|
||||||
Generates a master api key
|
|
||||||
|
|
||||||
@method generateMasterKey
|
|
||||||
**/
|
|
||||||
generateMasterKey: function() {
|
|
||||||
var self = this;
|
|
||||||
ApiKey.generateMasterKey().then(function (key) {
|
|
||||||
self.get('model').pushObject(key);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
Creates an API key instance with internal user object
|
|
||||||
|
|
||||||
@method regenerateKey
|
|
||||||
@param {ApiKey} key the key to regenerate
|
|
||||||
**/
|
|
||||||
regenerateKey: function(key) {
|
|
||||||
bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
|
||||||
if (result) {
|
|
||||||
key.regenerate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
Revokes an API key
|
|
||||||
|
|
||||||
@method revokeKey
|
|
||||||
@param {ApiKey} key the key to revoke
|
|
||||||
**/
|
|
||||||
revokeKey: function(key) {
|
|
||||||
var self = this;
|
|
||||||
bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
|
||||||
if (result) {
|
|
||||||
key.revoke().then(function() {
|
|
||||||
self.get('model').removeObject(key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
Has a master key already been generated?
|
|
||||||
|
|
||||||
@property hasMasterKey
|
|
||||||
@type {Boolean}
|
|
||||||
**/
|
|
||||||
hasMasterKey: function() {
|
|
||||||
return !!this.get('model').findBy('user', null);
|
|
||||||
}.property('model.[]')
|
|
||||||
|
|
||||||
});
|
|
@ -1,19 +1,21 @@
|
|||||||
|
import DiscourseURL from 'discourse/lib/url';
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
export default Ember.ArrayController.extend({
|
|
||||||
needs: ["adminBackups"],
|
export default Ember.Controller.extend({
|
||||||
status: Ember.computed.alias("controllers.adminBackups"),
|
adminBackups: Ember.inject.controller(),
|
||||||
|
status: Ember.computed.alias('adminBackups.model'),
|
||||||
|
|
||||||
uploadLabel: function() { return I18n.t("admin.backups.upload.label"); }.property(),
|
uploadLabel: function() { return I18n.t("admin.backups.upload.label"); }.property(),
|
||||||
|
|
||||||
restoreTitle: function() {
|
restoreTitle: function() {
|
||||||
if (!this.get('status.model.allowRestore')) {
|
if (!this.get('status.allowRestore')) {
|
||||||
return "admin.backups.operations.restore.is_disabled";
|
return "admin.backups.operations.restore.is_disabled";
|
||||||
} else if (this.get("status.model.isOperationRunning")) {
|
} else if (this.get("status.isOperationRunning")) {
|
||||||
return "admin.backups.operations.is_running";
|
return "admin.backups.operations.is_running";
|
||||||
} else {
|
} else {
|
||||||
return "admin.backups.operations.restore.title";
|
return "admin.backups.operations.restore.title";
|
||||||
}
|
}
|
||||||
}.property("status.model.{allowRestore,isOperationRunning}"),
|
}.property("status.{allowRestore,isOperationRunning}"),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
@ -34,8 +36,11 @@ export default Ember.ArrayController.extend({
|
|||||||
} else {
|
} else {
|
||||||
this._toggleReadOnlyMode(false);
|
this._toggleReadOnlyMode(false);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
download(backup) {
|
||||||
|
DiscourseURL.redirectTo(backup.get('link'));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_toggleReadOnlyMode(enable) {
|
_toggleReadOnlyMode(enable) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ["adminBackups"],
|
logs: [],
|
||||||
status: Em.computed.alias("controllers.adminBackups")
|
adminBackups: Ember.inject.controller(),
|
||||||
|
status: Em.computed.alias("adminBackups.model")
|
||||||
});
|
});
|
||||||
|
@ -3,14 +3,14 @@ import BufferedContent from 'discourse/mixins/buffered-content';
|
|||||||
import { propertyNotEqual } from 'discourse/lib/computed';
|
import { propertyNotEqual } from 'discourse/lib/computed';
|
||||||
|
|
||||||
export default Ember.Controller.extend(BufferedContent, {
|
export default Ember.Controller.extend(BufferedContent, {
|
||||||
needs: ['admin-badges'],
|
adminBadges: Ember.inject.controller(),
|
||||||
saving: false,
|
saving: false,
|
||||||
savingStatus: '',
|
savingStatus: '',
|
||||||
|
|
||||||
badgeTypes: Em.computed.alias('controllers.admin-badges.badgeTypes'),
|
badgeTypes: Ember.computed.alias('adminBadges.badgeTypes'),
|
||||||
badgeGroupings: Em.computed.alias('controllers.admin-badges.badgeGroupings'),
|
badgeGroupings: Ember.computed.alias('adminBadges.badgeGroupings'),
|
||||||
badgeTriggers: Em.computed.alias('controllers.admin-badges.badgeTriggers'),
|
badgeTriggers: Ember.computed.alias('adminBadges.badgeTriggers'),
|
||||||
protectedSystemFields: Em.computed.alias('controllers.admin-badges.protectedSystemFields'),
|
protectedSystemFields: Ember.computed.alias('adminBadges.protectedSystemFields'),
|
||||||
|
|
||||||
readOnly: Ember.computed.alias('buffered.system'),
|
readOnly: Ember.computed.alias('buffered.system'),
|
||||||
showDisplayName: propertyNotEqual('name', 'displayName'),
|
showDisplayName: propertyNotEqual('name', 'displayName'),
|
||||||
@ -30,16 +30,15 @@ export default Ember.Controller.extend(BufferedContent, {
|
|||||||
}.observes('model.id'),
|
}.observes('model.id'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
save: function() {
|
save() {
|
||||||
if (!this.get('saving')) {
|
if (!this.get('saving')) {
|
||||||
var fields = ['allow_title', 'multiple_grant',
|
let fields = ['allow_title', 'multiple_grant',
|
||||||
'listable', 'auto_revoke',
|
'listable', 'auto_revoke',
|
||||||
'enabled', 'show_posts',
|
'enabled', 'show_posts',
|
||||||
'target_posts', 'name', 'description',
|
'target_posts', 'name', 'description',
|
||||||
'long_description',
|
'long_description',
|
||||||
'icon', 'image', 'query', 'badge_grouping_id',
|
'icon', 'image', 'query', 'badge_grouping_id',
|
||||||
'trigger', 'badge_type_id'],
|
'trigger', 'badge_type_id'];
|
||||||
self = this;
|
|
||||||
|
|
||||||
if (this.get('buffered.system')){
|
if (this.get('buffered.system')){
|
||||||
var protectedFields = this.get('protectedSystemFields');
|
var protectedFields = this.get('protectedSystemFields');
|
||||||
@ -51,54 +50,55 @@ export default Ember.Controller.extend(BufferedContent, {
|
|||||||
this.set('saving', true);
|
this.set('saving', true);
|
||||||
this.set('savingStatus', I18n.t('saving'));
|
this.set('savingStatus', I18n.t('saving'));
|
||||||
|
|
||||||
var boolFields = ['allow_title', 'multiple_grant',
|
const boolFields = ['allow_title', 'multiple_grant',
|
||||||
'listable', 'auto_revoke',
|
'listable', 'auto_revoke',
|
||||||
'enabled', 'show_posts',
|
'enabled', 'show_posts',
|
||||||
'target_posts' ];
|
'target_posts' ];
|
||||||
|
|
||||||
var data = {},
|
const data = {};
|
||||||
buffered = this.get('buffered');
|
const buffered = this.get('buffered');
|
||||||
fields.forEach(function(field){
|
fields.forEach(function(field){
|
||||||
var d = buffered.get(field);
|
var d = buffered.get(field);
|
||||||
if (_.include(boolFields, field)) { d = !!d; }
|
if (_.include(boolFields, field)) { d = !!d; }
|
||||||
data[field] = d;
|
data[field] = d;
|
||||||
});
|
});
|
||||||
|
|
||||||
var newBadge = !this.get('id'),
|
const newBadge = !this.get('id');
|
||||||
model = this.get('model');
|
const model = this.get('model');
|
||||||
this.get('model').save(data).then(function() {
|
this.get('model').save(data).then(() => {
|
||||||
if (newBadge) {
|
if (newBadge) {
|
||||||
var adminBadgesController = self.get('controllers.admin-badges');
|
const adminBadges = this.get('adminBadges.model');
|
||||||
if (!adminBadgesController.contains(model)) adminBadgesController.pushObject(model);
|
if (!adminBadges.includes(model)) {
|
||||||
self.transitionToRoute('adminBadges.show', model.get('id'));
|
adminBadges.pushObject(model);
|
||||||
|
}
|
||||||
|
this.transitionToRoute('adminBadges.show', model.get('id'));
|
||||||
} else {
|
} else {
|
||||||
self.commitBuffer();
|
this.commitBuffer();
|
||||||
self.set('savingStatus', I18n.t('saved'));
|
this.set('savingStatus', I18n.t('saved'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch(popupAjaxError).finally(function() {
|
}).catch(popupAjaxError).finally(() => {
|
||||||
self.set('saving', false);
|
this.set('saving', false);
|
||||||
self.set('savingStatus', '');
|
this.set('savingStatus', '');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy() {
|
||||||
var self = this,
|
const adminBadges = this.get('adminBadges.model');
|
||||||
adminBadgesController = this.get('controllers.admin-badges'),
|
const model = this.get('model');
|
||||||
model = this.get('model');
|
|
||||||
|
|
||||||
if (!model.get('id')) {
|
if (!model.get('id')) {
|
||||||
self.transitionToRoute('adminBadges.index');
|
this.transitionToRoute('adminBadges.index');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||||
if (result) {
|
if (result) {
|
||||||
model.destroy().then(function() {
|
model.destroy().then(() => {
|
||||||
adminBadgesController.removeObject(model);
|
adminBadges.removeObject(model);
|
||||||
self.transitionToRoute('adminBadges.index');
|
this.transitionToRoute('adminBadges.index');
|
||||||
}).catch(function() {
|
}).catch(() => {
|
||||||
bootbox.alert(I18n.t('generic_error'));
|
bootbox.alert(I18n.t('generic_error'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export default Ember.ArrayController.extend();
|
export default Ember.Controller.extend();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
onlyOverridden: false,
|
onlyOverridden: false,
|
||||||
|
|
||||||
baseColorScheme: function() {
|
baseColorScheme: function() {
|
||||||
@ -13,8 +13,8 @@ export default Ember.ArrayController.extend({
|
|||||||
return baseColorsHash;
|
return baseColorsHash;
|
||||||
}.property('baseColorScheme'),
|
}.property('baseColorScheme'),
|
||||||
|
|
||||||
removeSelected: function() {
|
removeSelected() {
|
||||||
this.removeObject(this.get('selectedItem'));
|
this.get('model').removeObject(this.get('selectedItem'));
|
||||||
this.set('selectedItem', null);
|
this.set('selectedItem', null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -26,8 +26,7 @@ export default Ember.ArrayController.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var matches = Em.A();
|
const matches = [];
|
||||||
|
|
||||||
_.each(this.get('selectedItem.colors'), function(color){
|
_.each(this.get('selectedItem.colors'), function(color){
|
||||||
if (color.get('overridden')) matches.pushObject(color);
|
if (color.get('overridden')) matches.pushObject(color);
|
||||||
});
|
});
|
||||||
@ -58,10 +57,10 @@ export default Ember.ArrayController.extend({
|
|||||||
this.filterContent();
|
this.filterContent();
|
||||||
},
|
},
|
||||||
|
|
||||||
newColorScheme: function() {
|
newColorScheme() {
|
||||||
var newColorScheme = Em.copy(this.get('baseColorScheme'), true);
|
const newColorScheme = Em.copy(this.get('baseColorScheme'), true);
|
||||||
newColorScheme.set('name', I18n.t('admin.customize.colors.new_name'));
|
newColorScheme.set('name', I18n.t('admin.customize.colors.new_name'));
|
||||||
this.pushObject(newColorScheme);
|
this.get('model').pushObject(newColorScheme);
|
||||||
this.send('selectColorScheme', newColorScheme);
|
this.send('selectColorScheme', newColorScheme);
|
||||||
this.set('onlyOverridden', false);
|
this.set('onlyOverridden', false);
|
||||||
},
|
},
|
||||||
@ -86,10 +85,10 @@ export default Ember.ArrayController.extend({
|
|||||||
this.updateEnabled();
|
this.updateEnabled();
|
||||||
},
|
},
|
||||||
|
|
||||||
copy: function(colorScheme) {
|
copy(colorScheme) {
|
||||||
var newColorScheme = Em.copy(colorScheme, true);
|
var newColorScheme = Em.copy(colorScheme, true);
|
||||||
newColorScheme.set('name', I18n.t('admin.customize.colors.copy_name_prefix') + ' ' + colorScheme.get('name'));
|
newColorScheme.set('name', I18n.t('admin.customize.colors.copy_name_prefix') + ' ' + colorScheme.get('name'));
|
||||||
this.pushObject(newColorScheme);
|
this.get('model').pushObject(newColorScheme);
|
||||||
this.send('selectColorScheme', newColorScheme);
|
this.send('selectColorScheme', newColorScheme);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ export default Ember.Controller.extend(activeSections, {
|
|||||||
return !this.get('model.changed') || this.get('model.isSaving');
|
return !this.get('model.changed') || this.get('model.isSaving');
|
||||||
}.property('model.changed', 'model.isSaving'),
|
}.property('model.changed', 'model.isSaving'),
|
||||||
|
|
||||||
needs: ['adminCustomizeCssHtml'],
|
adminCustomizeCssHtml: Ember.inject.controller(),
|
||||||
|
|
||||||
undoPreviewUrl: url('/?preview-style='),
|
undoPreviewUrl: url('/?preview-style='),
|
||||||
defaultStyleUrl: url('/?preview-style=default'),
|
defaultStyleUrl: url('/?preview-style=default'),
|
||||||
@ -44,13 +44,12 @@ export default Ember.Controller.extend(activeSections, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
const self = this;
|
return bootbox.confirm(I18n.t("admin.customize.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||||
return bootbox.confirm(I18n.t("admin.customize.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const model = self.get('model');
|
const model = this.get('model');
|
||||||
model.destroyRecord().then(function() {
|
model.destroyRecord().then(() => {
|
||||||
self.get('controllers.adminCustomizeCssHtml').get('model').removeObject(model);
|
this.get('adminCustomizeCssHtml').get('model').removeObject(model);
|
||||||
self.transitionToRoute('adminCustomizeCssHtml');
|
this.transitionToRoute('adminCustomizeCssHtml');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -22,7 +22,7 @@ export default Ember.Controller.extend({
|
|||||||
|
|
||||||
@computed('problems.length')
|
@computed('problems.length')
|
||||||
foundProblems(problemsLength) {
|
foundProblems(problemsLength) {
|
||||||
return this.currentUser.get('admin') && (problemsLength || 0) > 1;
|
return this.currentUser.get('admin') && (problemsLength || 0) > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('foundProblems')
|
@computed('foundProblems')
|
||||||
|
@ -1,12 +1,23 @@
|
|||||||
import EmailPreview from 'admin/models/email-preview';
|
import EmailPreview from 'admin/models/email-preview';
|
||||||
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
|
|
||||||
|
emailEmpty: Em.computed.empty('email'),
|
||||||
|
sendEmailDisabled: Em.computed.or('emailEmpty', 'sendingEmail'),
|
||||||
|
showSendEmailForm: Em.computed.notEmpty('model.html_content'),
|
||||||
|
htmlEmpty: Em.computed.empty('model.html_content'),
|
||||||
|
|
||||||
|
iframeSrc: function() {
|
||||||
|
return ('data:text/html;charset=utf-8,' + encodeURI(this.get('model.html_content')));
|
||||||
|
}.property('model.html_content'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
refresh() {
|
refresh() {
|
||||||
const model = this.get('model');
|
const model = this.get('model');
|
||||||
|
|
||||||
this.set('loading', true);
|
this.set('loading', true);
|
||||||
|
this.set('sentEmail', false);
|
||||||
EmailPreview.findDigest(this.get('lastSeen'), this.get('username')).then(email => {
|
EmailPreview.findDigest(this.get('lastSeen'), this.get('username')).then(email => {
|
||||||
model.setProperties(email.getProperties('html_content', 'text_content'));
|
model.setProperties(email.getProperties('html_content', 'text_content'));
|
||||||
this.set('loading', false);
|
this.set('loading', false);
|
||||||
@ -15,6 +26,23 @@ export default Ember.Controller.extend({
|
|||||||
|
|
||||||
toggleShowHtml() {
|
toggleShowHtml() {
|
||||||
this.toggleProperty('showHtml');
|
this.toggleProperty('showHtml');
|
||||||
|
},
|
||||||
|
|
||||||
|
sendEmail() {
|
||||||
|
this.set('sendingEmail', true);
|
||||||
|
this.set('sentEmail', false);
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
EmailPreview.sendDigest(this.get('lastSeen'), this.get('username'), this.get('email')).then(result => {
|
||||||
|
if (result.errors) {
|
||||||
|
bootbox.alert(result.errors);
|
||||||
|
} else {
|
||||||
|
self.set('sentEmail', true);
|
||||||
|
}
|
||||||
|
}).catch(popupAjaxError).finally(function() {
|
||||||
|
self.set('sendingEmail', false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ export default Ember.Controller.extend({
|
|||||||
@computed('embedding.embeddable_hosts.@each.isCreated')
|
@computed('embedding.embeddable_hosts.@each.isCreated')
|
||||||
showSecondary() {
|
showSecondary() {
|
||||||
const hosts = this.get('embedding.embeddable_hosts');
|
const hosts = this.get('embedding.embeddable_hosts');
|
||||||
return hosts.length && hosts.findProperty('isCreated');
|
return hosts.length && hosts.findBy('isCreated');
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('embedding.base_url')
|
@computed('embedding.base_url')
|
||||||
@ -38,9 +38,7 @@ export default Ember.Controller.extend({
|
|||||||
const updates = embedding.getProperties(embedding.get('fields'));
|
const updates = embedding.getProperties(embedding.get('fields'));
|
||||||
|
|
||||||
this.set('saved', false);
|
this.set('saved', false);
|
||||||
this.get('embedding').update(updates).then(() => {
|
this.get('embedding').update(updates).then(() => this.set('saved', true)).catch(popupAjaxError);
|
||||||
this.set('saved', true);
|
|
||||||
}).catch(popupAjaxError);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addHost() {
|
addHost() {
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
sortProperties: ["name"],
|
sortedEmojis: Ember.computed.sort('model', 'emojiSorting'),
|
||||||
|
emojiSorting: ['name'],
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
emojiUploaded(emoji) {
|
emojiUploaded(emoji) {
|
||||||
emoji.url += "?t=" + new Date().getTime();
|
emoji.url += "?t=" + new Date().getTime();
|
||||||
this.pushObject(Ember.Object.create(emoji));
|
this.get('model').pushObject(Ember.Object.create(emoji));
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy(emoji) {
|
destroy(emoji) {
|
||||||
const self = this;
|
|
||||||
return bootbox.confirm(
|
return bootbox.confirm(
|
||||||
I18n.t("admin.emoji.delete_confirm", { name: emoji.get("name") }),
|
I18n.t("admin.emoji.delete_confirm", { name: emoji.get("name") }),
|
||||||
I18n.t("no_value"),
|
I18n.t("no_value"),
|
||||||
I18n.t("yes_value"),
|
I18n.t("yes_value"),
|
||||||
function(destroy) {
|
destroy => {
|
||||||
if (destroy) {
|
if (destroy) {
|
||||||
return ajax("/admin/customize/emojis/" + emoji.get("name"), { type: "DELETE" }).then(function() {
|
return ajax("/admin/customize/emojis/" + emoji.get("name"), { type: "DELETE" }).then(() => {
|
||||||
self.removeObject(emoji);
|
this.get('model').removeObject(emoji);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import FlaggedPost from 'admin/models/flagged-post';
|
import FlaggedPost from 'admin/models/flagged-post';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
query: null,
|
query: null,
|
||||||
|
|
||||||
adminOldFlagsView: Em.computed.equal("query", "old"),
|
adminOldFlagsView: Em.computed.equal("query", "old"),
|
||||||
@ -8,18 +8,16 @@ export default Ember.ArrayController.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
disagreeFlags(flaggedPost) {
|
disagreeFlags(flaggedPost) {
|
||||||
var self = this;
|
flaggedPost.disagreeFlags().then(() => {
|
||||||
flaggedPost.disagreeFlags().then(function () {
|
this.get('model').removeObject(flaggedPost);
|
||||||
self.removeObject(flaggedPost);
|
|
||||||
}, function () {
|
}, function () {
|
||||||
bootbox.alert(I18n.t("admin.flags.error"));
|
bootbox.alert(I18n.t("admin.flags.error"));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deferFlags(flaggedPost) {
|
deferFlags(flaggedPost) {
|
||||||
var self = this;
|
flaggedPost.deferFlags().then(() => {
|
||||||
flaggedPost.deferFlags().then(function () {
|
this.get('model').removeObject(flaggedPost);
|
||||||
self.removeObject(flaggedPost);
|
|
||||||
}, function () {
|
}, function () {
|
||||||
bootbox.alert(I18n.t("admin.flags.error"));
|
bootbox.alert(I18n.t("admin.flags.error"));
|
||||||
});
|
});
|
||||||
@ -29,7 +27,7 @@ export default Ember.ArrayController.extend({
|
|||||||
this.send("disagreeFlags", item);
|
this.send("disagreeFlags", item);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadMore(){
|
loadMore() {
|
||||||
const flags = this.get('model');
|
const flags = this.get('model');
|
||||||
return FlaggedPost.findAll(this.get('query'), flags.length+1).then(data => {
|
return FlaggedPost.findAll(this.get('query'), flags.length+1).then(data => {
|
||||||
if (data.length===0) {
|
if (data.length===0) {
|
||||||
|
@ -1,24 +1,11 @@
|
|||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
import { propertyEqual } from 'discourse/lib/computed';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ['adminGroupsType'],
|
adminGroupsType: Ember.inject.controller(),
|
||||||
disableSave: false,
|
disableSave: false,
|
||||||
savingStatus: '',
|
savingStatus: '',
|
||||||
|
|
||||||
currentPage: function() {
|
|
||||||
if (this.get("model.user_count") === 0) { return 0; }
|
|
||||||
return Math.floor(this.get("model.offset") / this.get("model.limit")) + 1;
|
|
||||||
}.property("model.limit", "model.offset", "model.user_count"),
|
|
||||||
|
|
||||||
totalPages: function() {
|
|
||||||
if (this.get("model.user_count") === 0) { return 0; }
|
|
||||||
return Math.floor(this.get("model.user_count") / this.get("model.limit")) + 1;
|
|
||||||
}.property("model.limit", "model.user_count"),
|
|
||||||
|
|
||||||
showingFirst: Em.computed.lte("currentPage", 1),
|
|
||||||
showingLast: propertyEqual("currentPage", "totalPages"),
|
|
||||||
|
|
||||||
aliasLevelOptions: function() {
|
aliasLevelOptions: function() {
|
||||||
return [
|
return [
|
||||||
{ name: I18n.t("groups.alias_levels.nobody"), value: 0 },
|
{ name: I18n.t("groups.alias_levels.nobody"), value: 0 },
|
||||||
@ -35,39 +22,17 @@ export default Ember.Controller.extend({
|
|||||||
];
|
];
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
|
@computed('model.visible', 'model.public', 'model.alias_level')
|
||||||
|
disableMembershipRequestSetting(visible, publicGroup) {
|
||||||
|
return !visible || publicGroup || !this.get('model.canEveryoneMention');
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.visible', 'model.allow_membership_requests')
|
||||||
|
disablePublicSetting(visible, allowMembershipRequests) {
|
||||||
|
return !visible || allowMembershipRequests;
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
next() {
|
|
||||||
if (this.get("showingLast")) { return; }
|
|
||||||
|
|
||||||
const group = this.get("model"),
|
|
||||||
offset = Math.min(group.get("offset") + group.get("limit"), group.get("user_count"));
|
|
||||||
|
|
||||||
group.set("offset", offset);
|
|
||||||
|
|
||||||
return group.findMembers();
|
|
||||||
},
|
|
||||||
|
|
||||||
previous() {
|
|
||||||
if (this.get("showingFirst")) { return; }
|
|
||||||
|
|
||||||
const group = this.get("model"),
|
|
||||||
offset = Math.max(group.get("offset") - group.get("limit"), 0);
|
|
||||||
|
|
||||||
group.set("offset", offset);
|
|
||||||
|
|
||||||
return group.findMembers();
|
|
||||||
},
|
|
||||||
|
|
||||||
removeMember(member) {
|
|
||||||
const self = this,
|
|
||||||
message = I18n.t("admin.groups.delete_member_confirm", { username: member.get("username"), group: this.get("model.name") });
|
|
||||||
return bootbox.confirm(message, I18n.t("no_value"), I18n.t("yes_value"), function(confirm) {
|
|
||||||
if (confirm) {
|
|
||||||
self.get("model").removeMember(member);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
removeOwner(member) {
|
removeOwner(member) {
|
||||||
const self = this,
|
const self = this,
|
||||||
message = I18n.t("admin.groups.delete_owner_confirm", { username: member.get("username"), group: this.get("model.name") });
|
message = I18n.t("admin.groups.delete_owner_confirm", { username: member.get("username"), group: this.get("model.name") });
|
||||||
@ -84,21 +49,15 @@ export default Ember.Controller.extend({
|
|||||||
this.set("model.ownerUsernames", null);
|
this.set("model.ownerUsernames", null);
|
||||||
},
|
},
|
||||||
|
|
||||||
addMembers() {
|
|
||||||
if (Em.isEmpty(this.get("model.usernames"))) { return; }
|
|
||||||
this.get("model").addMembers(this.get("model.usernames")).catch(popupAjaxError);
|
|
||||||
this.set("model.usernames", null);
|
|
||||||
},
|
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
const group = this.get('model'),
|
const group = this.get('model'),
|
||||||
groupsController = this.get("controllers.adminGroupsType"),
|
groupsController = this.get("adminGroupsType"),
|
||||||
groupType = groupsController.get("type");
|
groupType = groupsController.get("type");
|
||||||
|
|
||||||
this.set('disableSave', true);
|
this.set('disableSave', true);
|
||||||
this.set('savingStatus', I18n.t('saving'));
|
this.set('savingStatus', I18n.t('saving'));
|
||||||
|
|
||||||
let promise = group.get("id") ? group.save() : group.create().then(() => groupsController.addObject(group));
|
let promise = group.get("id") ? group.save() : group.create().then(() => groupsController.get('model').addObject(group));
|
||||||
|
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
this.transitionToRoute("adminGroup", groupType, group.get('name'));
|
this.transitionToRoute("adminGroup", groupType, group.get('name'));
|
||||||
@ -109,7 +68,7 @@ export default Ember.Controller.extend({
|
|||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
const group = this.get('model'),
|
const group = this.get('model'),
|
||||||
groupsController = this.get('controllers.adminGroupsType'),
|
groupsController = this.get('adminGroupsType'),
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
if (!group.get('id')) {
|
if (!group.get('id')) {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
sortProperties: ['name'],
|
sortedGroups: Ember.computed.sort('model', 'groupSorting'),
|
||||||
|
groupSorting: ['name'],
|
||||||
|
|
||||||
refreshingAutoGroups: false,
|
refreshingAutoGroups: false,
|
||||||
isAuto: function(){
|
|
||||||
return this.get('type') === 'automatic';
|
isAuto: Ember.computed.equal('type', 'automatic'),
|
||||||
}.property('type'),
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
refreshAutoGroups: function(){
|
refreshAutoGroups() {
|
||||||
var self = this;
|
|
||||||
this.set('refreshingAutoGroups', true);
|
this.set('refreshingAutoGroups', true);
|
||||||
ajax('/admin/groups/refresh_automatic_groups', {type: 'POST'}).then(function() {
|
ajax('/admin/groups/refresh_automatic_groups', {type: 'POST'}).then(() => {
|
||||||
self.transitionToRoute("adminGroupsType", "automatic").then(function() {
|
this.transitionToRoute("adminGroupsType", "automatic").then(() => {
|
||||||
self.set('refreshingAutoGroups', false);
|
this.set('refreshingAutoGroups', false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ import { exportEntity } from 'discourse/lib/export-csv';
|
|||||||
import { outputExportResult } from 'discourse/lib/export-result';
|
import { outputExportResult } from 'discourse/lib/export-result';
|
||||||
import ScreenedEmail from 'admin/models/screened-email';
|
import ScreenedEmail from 'admin/models/screened-email';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
clearBlock(row){
|
clearBlock(row){
|
||||||
row.clearBlock().then(function(){
|
row.clearBlock().then(function() {
|
||||||
// feeling lazy
|
// feeling lazy
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
@ -19,11 +19,10 @@ export default Ember.ArrayController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
var self = this;
|
this.set('loading', true);
|
||||||
self.set('loading', true);
|
ScreenedEmail.findAll().then(result => {
|
||||||
ScreenedEmail.findAll().then(function(result) {
|
this.set('model', result);
|
||||||
self.set('model', result);
|
this.set('loading', false);
|
||||||
self.set('loading', false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,7 @@ import { outputExportResult } from 'discourse/lib/export-result';
|
|||||||
import { exportEntity } from 'discourse/lib/export-csv';
|
import { exportEntity } from 'discourse/lib/export-csv';
|
||||||
import ScreenedIpAddress from 'admin/models/screened-ip-address';
|
import ScreenedIpAddress from 'admin/models/screened-ip-address';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
filter: null,
|
filter: null,
|
||||||
savedIpAddress: null,
|
savedIpAddress: null,
|
||||||
@ -63,16 +63,15 @@ export default Ember.ArrayController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
destroy(record) {
|
destroy(record) {
|
||||||
const self = this;
|
|
||||||
return bootbox.confirm(
|
return bootbox.confirm(
|
||||||
I18n.t("admin.logs.screened_ips.delete_confirm", { ip_address: record.get('ip_address') }),
|
I18n.t("admin.logs.screened_ips.delete_confirm", { ip_address: record.get('ip_address') }),
|
||||||
I18n.t("no_value"),
|
I18n.t("no_value"),
|
||||||
I18n.t("yes_value"),
|
I18n.t("yes_value"),
|
||||||
function (result) {
|
result => {
|
||||||
if (result) {
|
if (result) {
|
||||||
record.destroy().then(deleted => {
|
record.destroy().then(deleted => {
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
self.get("content").removeObject(record);
|
this.get("model").removeObject(record);
|
||||||
} else {
|
} else {
|
||||||
bootbox.alert(I18n.t("generic_error"));
|
bootbox.alert(I18n.t("generic_error"));
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,14 @@ import { exportEntity } from 'discourse/lib/export-csv';
|
|||||||
import { outputExportResult } from 'discourse/lib/export-result';
|
import { outputExportResult } from 'discourse/lib/export-result';
|
||||||
import ScreenedUrl from 'admin/models/screened-url';
|
import ScreenedUrl from 'admin/models/screened-url';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
const self = this;
|
this.set('loading', true);
|
||||||
self.set('loading', true);
|
ScreenedUrl.findAll().then(result => {
|
||||||
ScreenedUrl.findAll().then(function(result) {
|
this.set('model', result);
|
||||||
self.set('model', result);
|
this.set('loading', false);
|
||||||
self.set('loading', false);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { exportEntity } from 'discourse/lib/export-csv';
|
|||||||
import { outputExportResult } from 'discourse/lib/export-result';
|
import { outputExportResult } from 'discourse/lib/export-result';
|
||||||
import StaffActionLog from 'admin/models/staff-action-log';
|
import StaffActionLog from 'admin/models/staff-action-log';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
filters: null,
|
filters: null,
|
||||||
|
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
import debounce from 'discourse/lib/debounce';
|
import debounce from 'discourse/lib/debounce';
|
||||||
import Permalink from 'admin/models/permalink';
|
import Permalink from 'admin/models/permalink';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
filter: null,
|
filter: null,
|
||||||
|
|
||||||
show: debounce(function() {
|
show: debounce(function() {
|
||||||
var self = this;
|
Permalink.findAll(this.get("filter")).then(result => {
|
||||||
self.set('loading', true);
|
this.set('model', result);
|
||||||
Permalink.findAll(self.get("filter")).then(function(result) {
|
this.set('loading', false);
|
||||||
self.set('model', result);
|
|
||||||
self.set('loading', false);
|
|
||||||
});
|
});
|
||||||
}, 250).observes("filter"),
|
}, 250).observes("filter"),
|
||||||
|
|
||||||
@ -20,12 +18,11 @@ export default Ember.ArrayController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
destroy: function(record) {
|
destroy: function(record) {
|
||||||
const self = this;
|
return bootbox.confirm(I18n.t("admin.permalink.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||||
return bootbox.confirm(I18n.t("admin.permalink.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
|
||||||
if (result) {
|
if (result) {
|
||||||
record.destroy().then(function(deleted) {
|
record.destroy().then(deleted => {
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
self.removeObject(record);
|
this.get('model').removeObject(record);
|
||||||
} else {
|
} else {
|
||||||
bootbox.alert(I18n.t("generic_error"));
|
bootbox.alert(I18n.t("generic_error"));
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
|
|
||||||
adminRoutes: function() {
|
adminRoutes: function() {
|
||||||
return this.get('model').map(function(p) {
|
return this.get('model').map(p => {
|
||||||
if (p.get('enabled')) {
|
if (p.get('enabled')) {
|
||||||
return p.admin_route;
|
return p.admin_route;
|
||||||
}
|
}
|
||||||
}).compact();
|
}).compact();
|
||||||
}.property()
|
}.property()
|
||||||
});
|
});
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
categoryNameKey: null,
|
categoryNameKey: null,
|
||||||
needs: ['adminSiteSettings'],
|
adminSiteSettings: Ember.inject.controller(),
|
||||||
|
|
||||||
filteredContent: function() {
|
filteredContent: function() {
|
||||||
if (!this.get('categoryNameKey')) { return []; }
|
if (!this.get('categoryNameKey')) { return []; }
|
||||||
|
|
||||||
const category = this.get('controllers.adminSiteSettings.content').findProperty('nameKey', this.get('categoryNameKey'));
|
const category = (this.get('adminSiteSettings.model') || []).findBy('nameKey', this.get('categoryNameKey'));
|
||||||
if (category) {
|
if (category) {
|
||||||
return category.siteSettings;
|
return category.siteSettings;
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}.property('controllers.adminSiteSettings.content', 'categoryNameKey')
|
}.property('adminSiteSettings.model', 'categoryNameKey')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import debounce from 'discourse/lib/debounce';
|
import debounce from 'discourse/lib/debounce';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
|
queryParams: ["filter"],
|
||||||
filter: null,
|
filter: null,
|
||||||
onlyOverridden: false,
|
onlyOverridden: false,
|
||||||
filtered: Ember.computed.notEmpty('filter'),
|
filtered: Ember.computed.notEmpty('filter'),
|
||||||
|
@ -1,38 +1,14 @@
|
|||||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
|
||||||
|
|
||||||
let lastSearch;
|
let lastSearch;
|
||||||
|
let lastOverridden;
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
_q: null,
|
|
||||||
searching: false,
|
searching: false,
|
||||||
siteTexts: null,
|
siteTexts: null,
|
||||||
preferred: false,
|
preferred: false,
|
||||||
_overridden: null,
|
|
||||||
queryParams: ['q', 'overridden'],
|
queryParams: ['q', 'overridden'],
|
||||||
|
|
||||||
@computed
|
q: null,
|
||||||
overridden: {
|
overridden: null,
|
||||||
set(value) {
|
|
||||||
if (!value || value === "false") { value = false; }
|
|
||||||
this._overridden = value;
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
get() {
|
|
||||||
return this._overridden;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
@computed
|
|
||||||
q: {
|
|
||||||
set(value) {
|
|
||||||
if (Ember.isEmpty(value)) { value = null; }
|
|
||||||
this._q = value;
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
get() {
|
|
||||||
return this._q;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_performSearch() {
|
_performSearch() {
|
||||||
this.store.find('site-text', this.getProperties('q', 'overridden')).then(results => {
|
this.store.find('site-text', this.getProperties('q', 'overridden')).then(results => {
|
||||||
@ -46,11 +22,14 @@ export default Ember.Controller.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
search(overridden) {
|
search(overridden) {
|
||||||
|
this.set('overridden', overridden);
|
||||||
|
|
||||||
const q = this.get('q');
|
const q = this.get('q');
|
||||||
if (q !== lastSearch || overridden) {
|
if (q !== lastSearch || overridden !== lastOverridden) {
|
||||||
this.set('searching', true);
|
this.set('searching', true);
|
||||||
Ember.run.debounce(this, this._performSearch, 400);
|
Ember.run.debounce(this, this._performSearch, 400);
|
||||||
lastSearch = q;
|
lastSearch = q;
|
||||||
|
lastOverridden = overridden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import UserBadge from 'discourse/models/user-badge';
|
import UserBadge from 'discourse/models/user-badge';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ["adminUser"],
|
adminUser: Ember.inject.controller(),
|
||||||
user: Em.computed.alias('controllers.adminUser.model'),
|
user: Ember.computed.alias('adminUser.model'),
|
||||||
sortProperties: ['granted_at'],
|
|
||||||
sortAscending: false,
|
sortedBadges: Ember.computed.sort('model', 'badgeSortOrder'),
|
||||||
|
badgeSortOrder: ['granted_at:desc'],
|
||||||
|
|
||||||
groupedBadges: function(){
|
groupedBadges: function(){
|
||||||
const allBadges = this.get('model');
|
const allBadges = this.get('model');
|
||||||
@ -38,8 +39,6 @@ export default Ember.ArrayController.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return _(expanded).sortBy(group => group.granted_at).reverse().value();
|
return _(expanded).sortBy(group => group.granted_at).reverse().value();
|
||||||
|
|
||||||
|
|
||||||
}.property('model', 'model.[]', 'model.expandedBadges.[]'),
|
}.property('model', 'model.[]', 'model.expandedBadges.[]'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,22 +79,15 @@ export default Ember.ArrayController.extend({
|
|||||||
model.get('expandedBadges').pushObject(userBadge.badge.id);
|
model.get('expandedBadges').pushObject(userBadge.badge.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
grantBadge(badgeId) {
|
||||||
Grant the selected badge to the user.
|
UserBadge.grant(badgeId, this.get('user.username'), this.get('badgeReason')).then(userBadge => {
|
||||||
|
this.set('badgeReason', '');
|
||||||
@method grantBadge
|
this.get('model').pushObject(userBadge);
|
||||||
@param {Integer} badgeId id of the badge we want to grant.
|
Ember.run.next(() => {
|
||||||
**/
|
|
||||||
grantBadge: function(badgeId) {
|
|
||||||
var self = this;
|
|
||||||
UserBadge.grant(badgeId, this.get('user.username'), this.get('badgeReason')).then(function(userBadge) {
|
|
||||||
self.set('badgeReason', '');
|
|
||||||
self.pushObject(userBadge);
|
|
||||||
Ember.run.next(function() {
|
|
||||||
// Update the selected badge ID after the combobox has re-rendered.
|
// Update the selected badge ID after the combobox has re-rendered.
|
||||||
var newSelectedBadge = self.get('grantableBadges')[0];
|
const newSelectedBadge = this.get('grantableBadges')[0];
|
||||||
if (newSelectedBadge) {
|
if (newSelectedBadge) {
|
||||||
self.set('selectedBadgeId', newSelectedBadge.get('id'));
|
this.set('selectedBadgeId', newSelectedBadge.get('id'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, function() {
|
}, function() {
|
||||||
@ -104,12 +96,11 @@ export default Ember.ArrayController.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
revokeBadge: function(userBadge) {
|
revokeBadge(userBadge) {
|
||||||
var self = this;
|
return bootbox.confirm(I18n.t("admin.badges.revoke_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||||
return bootbox.confirm(I18n.t("admin.badges.revoke_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
|
||||||
if (result) {
|
if (result) {
|
||||||
userBadge.revoke().then(function() {
|
userBadge.revoke().then(() => {
|
||||||
self.get('model').removeObject(userBadge);
|
this.get('model').removeObject(userBadge);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,12 +6,8 @@ export default Ember.Controller.extend({
|
|||||||
fieldTypes: null,
|
fieldTypes: null,
|
||||||
createDisabled: Em.computed.gte('model.length', MAX_FIELDS),
|
createDisabled: Em.computed.gte('model.length', MAX_FIELDS),
|
||||||
|
|
||||||
arrangedContent: function() {
|
fieldSortOrder: ['position'],
|
||||||
return Ember.ArrayProxy.extend(Ember.SortableMixin).create({
|
sortedFields: Ember.computed.sort('model', 'fieldSortOrder'),
|
||||||
sortProperties: ['position'],
|
|
||||||
content: this.get('model')
|
|
||||||
});
|
|
||||||
}.property('model'),
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
createField() {
|
createField() {
|
||||||
@ -20,9 +16,9 @@ export default Ember.Controller.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
moveUp(f) {
|
moveUp(f) {
|
||||||
const idx = this.get('arrangedContent').indexOf(f);
|
const idx = this.get('sortedFields').indexOf(f);
|
||||||
if (idx) {
|
if (idx) {
|
||||||
const prev = this.get('arrangedContent').objectAt(idx-1);
|
const prev = this.get('sortedFields').objectAt(idx-1);
|
||||||
const prevPos = prev.get('position');
|
const prevPos = prev.get('position');
|
||||||
|
|
||||||
prev.update({ position: f.get('position') });
|
prev.update({ position: f.get('position') });
|
||||||
@ -31,9 +27,9 @@ export default Ember.Controller.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
moveDown(f) {
|
moveDown(f) {
|
||||||
const idx = this.get('arrangedContent').indexOf(f);
|
const idx = this.get('sortedFields').indexOf(f);
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
const next = this.get('arrangedContent').objectAt(idx+1);
|
const next = this.get('sortedFields').objectAt(idx+1);
|
||||||
const nextPos = next.get('position');
|
const nextPos = next.get('position');
|
||||||
|
|
||||||
next.update({ position: f.get('position') });
|
next.update({ position: f.get('position') });
|
||||||
|
@ -31,6 +31,29 @@ export default Ember.Controller.extend(CanCheckEmails, {
|
|||||||
}.property('model.user_fields.[]'),
|
}.property('model.user_fields.[]'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
|
impersonate() { return this.get("model").impersonate(); },
|
||||||
|
logOut() { return this.get("model").logOut(); },
|
||||||
|
resetBounceScore() { return this.get("model").resetBounceScore(); },
|
||||||
|
refreshBrowsers() { return this.get("model").refreshBrowsers(); },
|
||||||
|
approve() { return this.get("model").approve(); },
|
||||||
|
deactivate() { return this.get("model").deactivate(); },
|
||||||
|
sendActivationEmail() { return this.get("model").sendActivationEmail(); },
|
||||||
|
activate() { return this.get("model").activate(); },
|
||||||
|
revokeAdmin() { return this.get("model").revokeAdmin(); },
|
||||||
|
grantAdmin() { return this.get("model").grantAdmin(); },
|
||||||
|
revokeModeration() { return this.get("model").revokeModeration(); },
|
||||||
|
grantModeration() { return this.get("model").grantModeration(); },
|
||||||
|
saveTrustLevel() { return this.get("model").saveTrustLevel(); },
|
||||||
|
restoreTrustLevel() { return this.get("model").restoreTrustLevel(); },
|
||||||
|
lockTrustLevel(locked) { return this.get("model").lockTrustLevel(locked); },
|
||||||
|
unsuspend() { return this.get("model").unsuspend(); },
|
||||||
|
unblock() { return this.get("model").unblock(); },
|
||||||
|
block() { return this.get("model").block(); },
|
||||||
|
deleteAllPosts() { return this.get("model").deleteAllPosts(); },
|
||||||
|
anonymize() { return this.get('model').anonymize(); },
|
||||||
|
destroy() { return this.get('model').destroy(); },
|
||||||
|
|
||||||
toggleTitleEdit() {
|
toggleTitleEdit() {
|
||||||
this.set('userTitleValue', this.get('model.title'));
|
this.set('userTitleValue', this.get('model.title'));
|
||||||
this.toggleProperty('editingTitle');
|
this.toggleProperty('editingTitle');
|
||||||
@ -39,7 +62,7 @@ export default Ember.Controller.extend(CanCheckEmails, {
|
|||||||
saveTitle() {
|
saveTitle() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
return ajax("/users/" + this.get('model.username').toLowerCase(), {
|
return ajax(`/users/${this.get('model.username').toLowerCase()}.json`, {
|
||||||
data: {title: this.get('userTitleValue')},
|
data: {title: this.get('userTitleValue')},
|
||||||
type: 'PUT'
|
type: 'PUT'
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
@ -107,14 +130,6 @@ export default Ember.Controller.extend(CanCheckEmails, {
|
|||||||
if (result) { self.get('model').revokeApiKey(); }
|
if (result) { self.get('model').revokeApiKey(); }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
|
||||||
|
|
||||||
anonymize() {
|
|
||||||
this.get('model').anonymize();
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this.get('model').destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import debounce from 'discourse/lib/debounce';
|
|||||||
import { i18n } from 'discourse/lib/computed';
|
import { i18n } from 'discourse/lib/computed';
|
||||||
import AdminUser from 'admin/models/admin-user';
|
import AdminUser from 'admin/models/admin-user';
|
||||||
|
|
||||||
export default Ember.ArrayController.extend({
|
export default Ember.Controller.extend({
|
||||||
query: null,
|
query: null,
|
||||||
showEmails: false,
|
showEmails: false,
|
||||||
refreshing: false,
|
refreshing: false,
|
||||||
@ -19,7 +19,7 @@ export default Ember.ArrayController.extend({
|
|||||||
selectedCount: function() {
|
selectedCount: function() {
|
||||||
var model = this.get('model');
|
var model = this.get('model');
|
||||||
if (!model || !model.length) return 0;
|
if (!model || !model.length) return 0;
|
||||||
return model.filterProperty('selected').length;
|
return model.filterBy('selected').length;
|
||||||
}.property('model.@each.selected'),
|
}.property('model.@each.selected'),
|
||||||
|
|
||||||
selectAllChanged: function() {
|
selectAllChanged: function() {
|
||||||
@ -52,14 +52,14 @@ export default Ember.ArrayController.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
approveUsers: function() {
|
approveUsers: function() {
|
||||||
AdminUser.bulkApprove(this.get('model').filterProperty('selected'));
|
AdminUser.bulkApprove(this.get('model').filterBy('selected'));
|
||||||
this._refreshUsers();
|
this._refreshUsers();
|
||||||
},
|
},
|
||||||
|
|
||||||
rejectUsers: function() {
|
rejectUsers: function() {
|
||||||
var maxPostAge = this.siteSettings.delete_user_max_post_age;
|
var maxPostAge = this.siteSettings.delete_user_max_post_age;
|
||||||
var controller = this;
|
var controller = this;
|
||||||
AdminUser.bulkReject(this.get('model').filterProperty('selected')).then(function(result){
|
AdminUser.bulkReject(this.get('model').filterBy('selected')).then(function(result){
|
||||||
var message = I18n.t("admin.users.reject_successful", {count: result.success});
|
var message = I18n.t("admin.users.reject_successful", {count: result.success});
|
||||||
if (result.failed > 0) {
|
if (result.failed > 0) {
|
||||||
message += ' ' + I18n.t("admin.users.reject_failures", {count: result.failed});
|
message += ' ' + I18n.t("admin.users.reject_failures", {count: result.failed});
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
pingDisabled: false,
|
||||||
|
incomingEventIds: [],
|
||||||
|
incomingCount: Ember.computed.alias("incomingEventIds.length"),
|
||||||
|
|
||||||
|
@computed('incomingCount')
|
||||||
|
hasIncoming(incomingCount) {
|
||||||
|
return incomingCount > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
subscribe() {
|
||||||
|
this.messageBus.subscribe(`/web_hook_events/${this.get('model.extras.web_hook_id')}`, data => {
|
||||||
|
if (data.event_type === 'ping') {
|
||||||
|
this.set('pingDisabled', false);
|
||||||
|
}
|
||||||
|
this._addIncoming(data.web_hook_event_id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unsubscribe() {
|
||||||
|
this.messageBus.unsubscribe('/web_hook_events/*');
|
||||||
|
},
|
||||||
|
|
||||||
|
_addIncoming(eventId) {
|
||||||
|
const incomingEventIds = this.get("incomingEventIds");
|
||||||
|
|
||||||
|
if (incomingEventIds.indexOf(eventId) === -1) {
|
||||||
|
incomingEventIds.pushObject(eventId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
loadMore() {
|
||||||
|
this.get('model').loadMore();
|
||||||
|
},
|
||||||
|
|
||||||
|
ping() {
|
||||||
|
this.set('pingDisabled', true);
|
||||||
|
|
||||||
|
ajax(`/admin/api/web_hooks/${this.get('model.extras.web_hook_id')}/ping`, {
|
||||||
|
type: 'POST'
|
||||||
|
}).catch(error => {
|
||||||
|
this.set('pingDisabled', false);
|
||||||
|
popupAjaxError(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
showInserted() {
|
||||||
|
const webHookId = this.get('model.extras.web_hook_id');
|
||||||
|
|
||||||
|
ajax(`/admin/api/web_hooks/${webHookId}/events/bulk`, {
|
||||||
|
type: 'GET',
|
||||||
|
data: { ids: this.get('incomingEventIds') }
|
||||||
|
}).then(data => {
|
||||||
|
const objects = data.map(event => this.store.createRecord('web-hook-event', event));
|
||||||
|
this.get("model").unshiftObjects(objects);
|
||||||
|
this.set("incomingEventIds", []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,98 @@
|
|||||||
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
|
import { extractDomainFromUrl } from 'discourse/lib/utilities';
|
||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
import InputValidation from 'discourse/models/input-validation';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
adminWebHooks: Ember.inject.controller(),
|
||||||
|
eventTypes: Ember.computed.alias('adminWebHooks.eventTypes'),
|
||||||
|
defaultEventTypes: Ember.computed.alias('adminWebHooks.defaultEventTypes'),
|
||||||
|
contentTypes: Ember.computed.alias('adminWebHooks.contentTypes'),
|
||||||
|
|
||||||
|
@computed('model.isSaving', 'saved', 'saveButtonDisabled')
|
||||||
|
savingStatus(isSaving, saved, saveButtonDisabled) {
|
||||||
|
if (isSaving) {
|
||||||
|
return I18n.t('saving');
|
||||||
|
} else if (!saveButtonDisabled && saved) {
|
||||||
|
return I18n.t('saved');
|
||||||
|
}
|
||||||
|
// Use side effect of validation to clear saved text
|
||||||
|
this.set('saved', false);
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.isNew')
|
||||||
|
saveButtonText(isNew) {
|
||||||
|
return isNew ? I18n.t('admin.web_hooks.create') : I18n.t('admin.web_hooks.save');
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.secret')
|
||||||
|
secretValidation(secret) {
|
||||||
|
if (!Ember.isEmpty(secret)) {
|
||||||
|
if (secret.indexOf(' ') !== -1) {
|
||||||
|
return InputValidation.create({
|
||||||
|
failed: true,
|
||||||
|
reason: I18n.t('admin.web_hooks.secret_invalid')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secret.length < 12) {
|
||||||
|
return InputValidation.create({
|
||||||
|
failed: true,
|
||||||
|
reason: I18n.t('admin.web_hooks.secret_too_short')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.wildcard_web_hook', 'model.web_hook_event_types.[]')
|
||||||
|
eventTypeValidation(isWildcard, eventTypes) {
|
||||||
|
if (!isWildcard && Ember.isEmpty(eventTypes)) {
|
||||||
|
return InputValidation.create({
|
||||||
|
failed: true,
|
||||||
|
reason: I18n.t('admin.web_hooks.event_type_missing')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('model.isSaving', 'secretValidation', 'eventTypeValidation')
|
||||||
|
saveButtonDisabled(isSaving, secretValidation, eventTypeValidation) {
|
||||||
|
return isSaving ? false : secretValidation || eventTypeValidation;
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
save() {
|
||||||
|
this.set('saved', false);
|
||||||
|
const url = extractDomainFromUrl(this.get('model.payload_url'));
|
||||||
|
const model = this.get('model');
|
||||||
|
const saveWebHook = () => {
|
||||||
|
return model.save().then(() => {
|
||||||
|
this.set('saved', true);
|
||||||
|
this.get('adminWebHooks').get('model').addObject(model);
|
||||||
|
}).catch(popupAjaxError);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (url === 'localhost' || url.match(/192\.168\.\d+\.\d+/) || url.match(/127\.\d+\.\d+\.\d+/) || url === Discourse.BaseUrl) {
|
||||||
|
return bootbox.confirm(I18n.t('admin.web_hooks.warn_local_payload_url'), I18n.t('no_value'), I18n.t('yes_value'), result => {
|
||||||
|
if (result) {
|
||||||
|
return saveWebHook();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return saveWebHook();
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
return bootbox.confirm(I18n.t('admin.web_hooks.delete_confirm'), I18n.t('no_value'), I18n.t('yes_value'), result => {
|
||||||
|
if (result) {
|
||||||
|
const model = this.get('model');
|
||||||
|
model.destroyRecord().then(() => {
|
||||||
|
this.get('adminWebHooks').get('model').removeObject(model);
|
||||||
|
this.transitionToRoute('adminWebHooks');
|
||||||
|
}).catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,19 @@
|
|||||||
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
actions: {
|
||||||
|
destroy(webhook) {
|
||||||
|
return bootbox.confirm(I18n.t('admin.web_hooks.delete_confirm'), I18n.t('no_value'), I18n.t('yes_value'), result => {
|
||||||
|
if (result) {
|
||||||
|
webhook.destroyRecord().then(() => {
|
||||||
|
this.get('model').removeObject(webhook);
|
||||||
|
}).catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMore() {
|
||||||
|
this.get('model').loadMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -1,16 +1,15 @@
|
|||||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||||
|
|
||||||
export default Ember.Controller.extend(ModalFunctionality, {
|
export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
needs: ["admin-flags-list"],
|
adminFlagsList: Ember.inject.controller(),
|
||||||
|
|
||||||
_agreeFlag: function (actionOnPost) {
|
_agreeFlag: function (actionOnPost) {
|
||||||
var adminFlagController = this.get("controllers.admin-flags-list");
|
const adminFlagController = this.get("adminFlagsList");
|
||||||
var post = this.get("content");
|
const post = this.get("content");
|
||||||
var self = this;
|
|
||||||
|
|
||||||
return post.agreeFlags(actionOnPost).then(function () {
|
return post.agreeFlags(actionOnPost).then(() => {
|
||||||
adminFlagController.removeObject(post);
|
adminFlagController.get('model').removeObject(post);
|
||||||
self.send("closeModal");
|
this.send("closeModal");
|
||||||
}, function () {
|
}, function () {
|
||||||
bootbox.alert(I18n.t("admin.flags.error"));
|
bootbox.alert(I18n.t("admin.flags.error"));
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { escapeExpression } from 'discourse/lib/utilities';
|
import { escapeExpression } from 'discourse/lib/utilities';
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ['modal'],
|
sample: Ember.computed.alias('model.sample'),
|
||||||
|
errors: Ember.computed.alias('model.errors'),
|
||||||
sample: Em.computed.alias('model.sample'),
|
count: Ember.computed.alias('model.grant_count'),
|
||||||
errors: Em.computed.alias('model.errors'),
|
|
||||||
count: Em.computed.alias('model.grant_count'),
|
|
||||||
|
|
||||||
count_warning: function() {
|
count_warning: function() {
|
||||||
if (this.get('count') <= 10) {
|
if (this.get('count') <= 10) {
|
||||||
|
@ -1,36 +1,31 @@
|
|||||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||||
|
|
||||||
export default Ember.Controller.extend(ModalFunctionality, {
|
export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
needs: ["admin-flags-list"],
|
adminFlagsList: Ember.inject.controller(),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
deletePostDeferFlag() {
|
||||||
|
const adminFlagController = this.get("adminFlagsList");
|
||||||
|
const post = this.get("content");
|
||||||
|
|
||||||
deletePostDeferFlag: function () {
|
return post.deferFlags(true).then(() => {
|
||||||
var adminFlagController = this.get("controllers.admin-flags-list");
|
adminFlagController.get('model').removeObject(post);
|
||||||
var post = this.get("content");
|
this.send("closeModal");
|
||||||
var self = this;
|
|
||||||
|
|
||||||
return post.deferFlags(true).then(function () {
|
|
||||||
adminFlagController.removeObject(post);
|
|
||||||
self.send("closeModal");
|
|
||||||
}, function () {
|
}, function () {
|
||||||
bootbox.alert(I18n.t("admin.flags.error"));
|
bootbox.alert(I18n.t("admin.flags.error"));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deletePostAgreeFlag: function () {
|
deletePostAgreeFlag() {
|
||||||
var adminFlagController = this.get("controllers.admin-flags-list");
|
const adminFlagController = this.get("adminFlagsList");
|
||||||
var post = this.get("content");
|
const post = this.get("content");
|
||||||
var self = this;
|
|
||||||
|
|
||||||
return post.agreeFlags("delete").then(function () {
|
return post.agreeFlags("delete").then(() => {
|
||||||
adminFlagController.removeObject(post);
|
adminFlagController.get('model').removeObject(post);
|
||||||
self.send("closeModal");
|
this.send("closeModal");
|
||||||
}, function () {
|
}, function () {
|
||||||
bootbox.alert(I18n.t("admin.flags.error"));
|
bootbox.alert(I18n.t("admin.flags.error"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ['modal'],
|
|
||||||
|
|
||||||
modelChanged: function(){
|
modelChanged: function(){
|
||||||
const model = this.get('model');
|
const model = this.get('model');
|
||||||
|
@ -2,31 +2,27 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
|||||||
import Backup from 'admin/models/backup';
|
import Backup from 'admin/models/backup';
|
||||||
|
|
||||||
export default Ember.Controller.extend(ModalFunctionality, {
|
export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
needs: ["adminBackupsLogs"],
|
adminBackupsLogs: Ember.inject.controller(),
|
||||||
|
|
||||||
_startBackup: function (withUploads) {
|
_startBackup(withUploads) {
|
||||||
var self = this;
|
this.currentUser.set('hideReadOnlyAlert', true);
|
||||||
Discourse.User.currentProp("hideReadOnlyAlert", true);
|
Backup.start(withUploads).then(() => {
|
||||||
Backup.start(withUploads).then(function() {
|
this.get("adminBackupsLogs.logs").clear();
|
||||||
self.get("controllers.adminBackupsLogs").clear();
|
this.send("backupStarted");
|
||||||
self.send("backupStarted");
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
startBackup() {
|
||||||
startBackup: function () {
|
|
||||||
this._startBackup();
|
this._startBackup();
|
||||||
},
|
},
|
||||||
|
|
||||||
startBackupWithoutUpload: function () {
|
startBackupWithoutUpload() {
|
||||||
this._startBackup(false);
|
this._startBackup(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel: function () {
|
cancel() {
|
||||||
this.send("closeModal");
|
this.send("closeModal");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import ChangeSiteCustomizationDetailsController from "admin/controllers/modals/change-site-customization-details";
|
import ChangeSiteCustomizationDetailsController from "admin/controllers/modals/change-site-customization-details";
|
||||||
|
|
||||||
export default ChangeSiteCustomizationDetailsController.extend({
|
export default ChangeSiteCustomizationDetailsController.extend({
|
||||||
onShow: function() {
|
onShow() {
|
||||||
this.send("selectPrevious");
|
this.send("selectPrevious");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
import { htmlHelper } from 'discourse/lib/helpers';
|
import { htmlHelper } from 'discourse-common/lib/helpers';
|
||||||
|
|
||||||
export default htmlHelper(size => I18n.toHumanSize(size));
|
export default htmlHelper(size => I18n.toHumanSize(size));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { htmlHelper } from 'discourse/lib/helpers';
|
import { htmlHelper } from 'discourse-common/lib/helpers';
|
||||||
import { escapeExpression } from 'discourse/lib/utilities';
|
import { escapeExpression } from 'discourse/lib/utilities';
|
||||||
|
|
||||||
export default htmlHelper(str => escapeExpression(str).replace(/\n/g, "<br>"));
|
export default htmlHelper(str => escapeExpression(str).replace(/\n/g, "<br>"));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { registerUnbound } from 'discourse/lib/helpers';
|
import { registerUnbound } from 'discourse-common/lib/helpers';
|
||||||
|
|
||||||
registerUnbound('value-at-tl', function(data, params) {
|
registerUnbound('value-at-tl', function(data, params) {
|
||||||
var tl = parseInt(params.level, 10);
|
var tl = parseInt(params.level, 10);
|
||||||
|
@ -96,7 +96,7 @@ const AdminUser = Discourse.User.extend({
|
|||||||
|
|
||||||
deleteAllPosts() {
|
deleteAllPosts() {
|
||||||
const user = this,
|
const user = this,
|
||||||
message = I18n.t('admin.user.delete_all_posts_confirm', { posts: user.get('post_count'), topics: user.get('topic_count') }),
|
message = I18n.messageFormat('admin.user.delete_all_posts_confirm_MF', { "POSTS": user.get('post_count'), "TOPICS": user.get('topic_count') }),
|
||||||
buttons = [{
|
buttons = [{
|
||||||
"label": I18n.t("composer.cancel"),
|
"label": I18n.t("composer.cancel"),
|
||||||
"class": "cancel-inline",
|
"class": "cancel-inline",
|
||||||
@ -257,7 +257,7 @@ const AdminUser = Discourse.User.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
log_out() {
|
logOut() {
|
||||||
return ajax("/admin/users/" + this.id + "/log_out", {
|
return ajax("/admin/users/" + this.id + "/log_out", {
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: { username_or_email: this.get('username') }
|
data: { username_or_email: this.get('username') }
|
||||||
@ -467,13 +467,13 @@ const AdminUser = Discourse.User.extend({
|
|||||||
|
|
||||||
user.checkEmail().then(function() {
|
user.checkEmail().then(function() {
|
||||||
const data = {
|
const data = {
|
||||||
posts: user.get('post_count'),
|
"POSTS": user.get('post_count'),
|
||||||
topics: user.get('topic_count'),
|
"TOPICS": user.get('topic_count'),
|
||||||
email: user.get('email') || I18n.t("flagging.hidden_email_address"),
|
email: user.get('email') || I18n.t("flagging.hidden_email_address"),
|
||||||
ip_address: user.get('ip_address') || I18n.t("flagging.ip_address_missing")
|
ip_address: user.get('ip_address') || I18n.t("flagging.ip_address_missing")
|
||||||
};
|
};
|
||||||
|
|
||||||
const message = I18n.t('flagging.delete_confirm', data),
|
const message = I18n.messageFormat('flagging.delete_confirm_MF', data),
|
||||||
buttons = [{
|
buttons = [{
|
||||||
"label": I18n.t("composer.cancel"),
|
"label": I18n.t("composer.cancel"),
|
||||||
"class": "cancel-inline",
|
"class": "cancel-inline",
|
||||||
|
@ -52,7 +52,7 @@ ApiKey.reopenClass({
|
|||||||
@returns {Promise} a promise that resolves to the array of `ApiKey` instances
|
@returns {Promise} a promise that resolves to the array of `ApiKey` instances
|
||||||
**/
|
**/
|
||||||
find: function() {
|
find: function() {
|
||||||
return ajax("/admin/api").then(function(keys) {
|
return ajax("/admin/api/keys").then(function(keys) {
|
||||||
return keys.map(function (key) {
|
return keys.map(function (key) {
|
||||||
return ApiKey.create(key);
|
return ApiKey.create(key);
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,6 @@ import { ajax } from 'discourse/lib/ajax';
|
|||||||
import PreloadStore from 'preload-store';
|
import PreloadStore from 'preload-store';
|
||||||
|
|
||||||
const Backup = Discourse.Model.extend({
|
const Backup = Discourse.Model.extend({
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
return ajax("/admin/backups/" + this.get("filename"), { type: "DELETE" });
|
return ajax("/admin/backups/" + this.get("filename"), { type: "DELETE" });
|
||||||
},
|
},
|
||||||
@ -13,11 +12,9 @@ const Backup = Discourse.Model.extend({
|
|||||||
data: { client_id: window.MessageBus.clientId }
|
data: { client_id: window.MessageBus.clientId }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Backup.reopenClass({
|
Backup.reopenClass({
|
||||||
|
|
||||||
find() {
|
find() {
|
||||||
return PreloadStore.getAndRemove("backups", () => ajax("/admin/backups.json"))
|
return PreloadStore.getAndRemove("backups", () => ajax("/admin/backups.json"))
|
||||||
.then(backups => backups.map(backup => Backup.create(backup)));
|
.then(backups => backups.map(backup => Backup.create(backup)));
|
||||||
|
@ -5,7 +5,7 @@ EmailPreview.reopenClass({
|
|||||||
findDigest: function(lastSeenAt, username) {
|
findDigest: function(lastSeenAt, username) {
|
||||||
|
|
||||||
if (Em.isEmpty(lastSeenAt)) {
|
if (Em.isEmpty(lastSeenAt)) {
|
||||||
lastSeenAt = moment().subtract(7, 'days').format('YYYY-MM-DD');
|
lastSeenAt = this.oneWeekAgo();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Em.isEmpty(username)) {
|
if (Em.isEmpty(username)) {
|
||||||
@ -17,6 +17,25 @@ EmailPreview.reopenClass({
|
|||||||
}).then(function (result) {
|
}).then(function (result) {
|
||||||
return EmailPreview.create(result);
|
return EmailPreview.create(result);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sendDigest: function(lastSeenAt, username, email) {
|
||||||
|
if (Em.isEmpty(lastSeenAt)) {
|
||||||
|
lastSeenAt = this.oneWeekAgo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Em.isEmpty(username)) {
|
||||||
|
username = Discourse.User.current().username;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ajax("/admin/email/send-digest.json", {
|
||||||
|
data: { last_seen_at: lastSeenAt, username: username, email: email }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
oneWeekAgo() {
|
||||||
|
const en = moment().locale('en');
|
||||||
|
return en.subtract(7, 'days').format('YYYY-MM-DD');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -81,7 +81,8 @@ const Report = Discourse.Model.extend({
|
|||||||
switch (this.get("type")) {
|
switch (this.get("type")) {
|
||||||
case "flags": return "flag";
|
case "flags": return "flag";
|
||||||
case "likes": return "heart";
|
case "likes": return "heart";
|
||||||
default: return null;
|
case "bookmarks": return "bookmark";
|
||||||
|
default: return null;
|
||||||
}
|
}
|
||||||
}.property("type"),
|
}.property("type"),
|
||||||
|
|
||||||
|
85
app/assets/javascripts/admin/models/web-hook.js.es6
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import RestModel from 'discourse/models/rest';
|
||||||
|
import Category from 'discourse/models/category';
|
||||||
|
import Group from 'discourse/models/group';
|
||||||
|
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default RestModel.extend({
|
||||||
|
content_type: 1, // json
|
||||||
|
last_delivery_status: 1, // inactive
|
||||||
|
wildcard_web_hook: false,
|
||||||
|
verify_certificate: true,
|
||||||
|
active: false,
|
||||||
|
web_hook_event_types: null,
|
||||||
|
categoriesFilter: null,
|
||||||
|
groupsFilterInName: null,
|
||||||
|
|
||||||
|
@computed('wildcard_web_hook')
|
||||||
|
webHookType: {
|
||||||
|
get(wildcard) {
|
||||||
|
return wildcard ? 'wildcard' : 'individual';
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.set('wildcard_web_hook', value === 'wildcard');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes('category_ids')
|
||||||
|
updateCategoriesFilter() {
|
||||||
|
this.set('categoriesFilter', Category.findByIds(this.get('category_ids')));
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes('group_ids')
|
||||||
|
updateGroupsFilter() {
|
||||||
|
const groupIds = this.get('group_ids');
|
||||||
|
this.set('groupsFilterInName', Discourse.Site.currentProp('groups').reduce((groupNames, g) => {
|
||||||
|
if (groupIds.includes(g.id)) { groupNames.push(g.name); }
|
||||||
|
return groupNames;
|
||||||
|
}, []));
|
||||||
|
},
|
||||||
|
|
||||||
|
groupFinder(term) {
|
||||||
|
return Group.findAll({search: term, ignore_automatic: false});
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('wildcard_web_hook', 'web_hook_event_types.[]')
|
||||||
|
description(isWildcardWebHook, types) {
|
||||||
|
let desc = '';
|
||||||
|
|
||||||
|
types.forEach(type => {
|
||||||
|
const name = `${type.name.toLowerCase()}_event`;
|
||||||
|
desc += (desc !== '' ? `, ${name}` : name);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (isWildcardWebHook ? '*' : desc);
|
||||||
|
},
|
||||||
|
|
||||||
|
createProperties() {
|
||||||
|
const types = this.get('web_hook_event_types');
|
||||||
|
const categories = this.get('categoriesFilter');
|
||||||
|
// Hack as {{group-selector}} accepts a comma-separated string as data source, but
|
||||||
|
// we use an array to populate the datasource above.
|
||||||
|
const groupsFilter = this.get('groupsFilterInName');
|
||||||
|
const groupNames = typeof groupsFilter === 'string' ? groupsFilter.split(',') : groupsFilter;
|
||||||
|
|
||||||
|
return {
|
||||||
|
payload_url: this.get('payload_url'),
|
||||||
|
content_type: this.get('content_type'),
|
||||||
|
secret: this.get('secret'),
|
||||||
|
wildcard_web_hook: this.get('wildcard_web_hook'),
|
||||||
|
verify_certificate: this.get('verify_certificate'),
|
||||||
|
active: this.get('active'),
|
||||||
|
web_hook_event_type_ids: Ember.isEmpty(types) ? [null] : types.map(type => type.id),
|
||||||
|
category_ids: Ember.isEmpty(categories) ? [null] : categories.map(c => c.id),
|
||||||
|
group_ids: Ember.isEmpty(groupNames) || Ember.isEmpty(groupNames[0]) ? [null] : Discourse.Site.currentProp('groups')
|
||||||
|
.reduce((groupIds, g) => {
|
||||||
|
if (groupNames.includes(g.name)) { groupIds.push(g.id); }
|
||||||
|
return groupIds;
|
||||||
|
}, [])
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
updateProperties() {
|
||||||
|
return this.createProperties();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
export default Ember.Route.extend({
|
||||||
|
beforeModel() {
|
||||||
|
this.transitionTo('adminApiKeys');
|
||||||
|
}
|
||||||
|
});
|
@ -5,17 +5,17 @@ export default Ember.Route.extend({
|
|||||||
// since the logs are pushed via the message bus
|
// since the logs are pushed via the message bus
|
||||||
// we only want to preload them (hence the beforeModel hook)
|
// we only want to preload them (hence the beforeModel hook)
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
const logsController = this.controllerFor("adminBackupsLogs");
|
const logs = this.controllerFor("adminBackupsLogs").get('logs');
|
||||||
// preload the logs if any
|
// preload the logs if any
|
||||||
PreloadStore.getAndRemove("logs").then(function (preloadedLogs) {
|
PreloadStore.getAndRemove("logs").then(function (preloadedLogs) {
|
||||||
if (preloadedLogs && preloadedLogs.length) {
|
if (preloadedLogs && preloadedLogs.length) {
|
||||||
// we need to filter out message like: "[SUCCESS]"
|
// we need to filter out message like: "[SUCCESS]"
|
||||||
// and convert POJOs to Ember Objects
|
// and convert POJOs to Ember Objects
|
||||||
const logs = _.chain(preloadedLogs)
|
const newLogs = _.chain(preloadedLogs)
|
||||||
.reject(function (log) { return log.message.length === 0 || log.message[0] === "["; })
|
.reject(function (log) { return log.message.length === 0 || log.message[0] === "["; })
|
||||||
.map(function (log) { return Em.Object.create(log); })
|
.map(function (log) { return Em.Object.create(log); })
|
||||||
.value();
|
.value();
|
||||||
logsController.pushObjects(logs);
|
logs.pushObjects(newLogs);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@ export default Discourse.Route.extend({
|
|||||||
_processLogMessage(log) {
|
_processLogMessage(log) {
|
||||||
if (log.message === "[STARTED]") {
|
if (log.message === "[STARTED]") {
|
||||||
this.controllerFor("adminBackups").set("model.isOperationRunning", true);
|
this.controllerFor("adminBackups").set("model.isOperationRunning", true);
|
||||||
this.controllerFor("adminBackupsLogs").clear();
|
this.controllerFor("adminBackupsLogs").get('logs').clear();
|
||||||
} else if (log.message === "[FAILED]") {
|
} else if (log.message === "[FAILED]") {
|
||||||
this.controllerFor("adminBackups").set("model.isOperationRunning", false);
|
this.controllerFor("adminBackups").set("model.isOperationRunning", false);
|
||||||
bootbox.alert(I18n.t("admin.backups.operations.failed", { operation: log.operation }));
|
bootbox.alert(I18n.t("admin.backups.operations.failed", { operation: log.operation }));
|
||||||
@ -27,7 +27,7 @@ export default Discourse.Route.extend({
|
|||||||
window.location.pathname = Discourse.getURL("/");
|
window.location.pathname = Discourse.getURL("/");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.controllerFor("adminBackupsLogs").pushObject(Em.Object.create(log));
|
this.controllerFor("adminBackupsLogs").get('logs').pushObject(Em.Object.create(log));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export default Discourse.Route.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
startBackup() {
|
startBackup() {
|
||||||
showModal('modals/admin-start-backup');
|
showModal('admin-start-backup', { admin: true });
|
||||||
this.controllerFor('modal').set('modalClass', 'start-backup-modal');
|
this.controllerFor('modal').set('modalClass', 'start-backup-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export default Ember.Route.extend({
|
|||||||
name: I18n.t('admin.badges.new_badge')
|
name: I18n.t('admin.badges.new_badge')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this.modelFor('adminBadges').findProperty('id', parseInt(params.badge_id));
|
return this.modelFor('adminBadges').findBy('id', parseInt(params.badge_id));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@ -27,7 +27,7 @@ export default Ember.Route.extend({
|
|||||||
|
|
||||||
editGroupings() {
|
editGroupings() {
|
||||||
const model = this.controllerFor('admin-badges').get('badgeGroupings');
|
const model = this.controllerFor('admin-badges').get('badgeGroupings');
|
||||||
showModal('modals/admin-edit-badge-groupings', { model });
|
showModal('admin-edit-badge-groupings', { model, admin: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
preview(badge, explain) {
|
preview(badge, explain) {
|
||||||
@ -42,7 +42,7 @@ export default Ember.Route.extend({
|
|||||||
}
|
}
|
||||||
}).then(function(model) {
|
}).then(function(model) {
|
||||||
badge.set('preview_loading', false);
|
badge.set('preview_loading', false);
|
||||||
showModal('modals/admin-badge-preview', { model });
|
showModal('admin-badge-preview', { model, admin: true });
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
badge.set('preview_loading', false);
|
badge.set('preview_loading', false);
|
||||||
Em.Logger.error(error);
|
Em.Logger.error(error);
|
||||||
|
@ -5,21 +5,20 @@ import BadgeGrouping from 'discourse/models/badge-grouping';
|
|||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
_json: null,
|
_json: null,
|
||||||
|
|
||||||
model: function() {
|
model() {
|
||||||
var self = this;
|
return ajax('/admin/badges.json').then(json => {
|
||||||
return ajax('/admin/badges.json').then(function(json) {
|
this._json = json;
|
||||||
self._json = json;
|
|
||||||
return Badge.createFromJson(json);
|
return Badge.createFromJson(json);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
setupController(controller, model) {
|
||||||
var json = this._json,
|
const json = this._json;
|
||||||
triggers = [],
|
const badgeTriggers = [];
|
||||||
badgeGroupings = [];
|
const badgeGroupings = [];
|
||||||
|
|
||||||
_.each(json.admin_badges.triggers,function(v,k){
|
_.each(json.admin_badges.triggers,function(v,k){
|
||||||
triggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)});
|
badgeTriggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)});
|
||||||
});
|
});
|
||||||
|
|
||||||
json.badge_groupings.forEach(function(badgeGroupingJson) {
|
json.badge_groupings.forEach(function(badgeGroupingJson) {
|
||||||
@ -30,8 +29,8 @@ export default Discourse.Route.extend({
|
|||||||
badgeGroupings: badgeGroupings,
|
badgeGroupings: badgeGroupings,
|
||||||
badgeTypes: json.badge_types,
|
badgeTypes: json.badge_types,
|
||||||
protectedSystemFields: json.admin_badges.protected_system_fields,
|
protectedSystemFields: json.admin_badges.protected_system_fields,
|
||||||
badgeTriggers: triggers,
|
badgeTriggers,
|
||||||
model: model
|
model
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
const all = this.modelFor('adminCustomizeCssHtml');
|
const all = this.modelFor('adminCustomizeCssHtml');
|
||||||
const model = all.findProperty('id', parseInt(params.site_customization_id));
|
const model = all.findBy('id', parseInt(params.site_customization_id));
|
||||||
return model ? { model, section: params.section } : this.replaceWith('adminCustomizeCssHtml.index');
|
return model ? { model, section: params.section } : this.replaceWith('adminCustomizeCssHtml.index');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { scrollTop } from 'discourse/mixins/scroll-top';
|
|||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
const all = this.modelFor('adminCustomizeEmailTemplates');
|
const all = this.modelFor('adminCustomizeEmailTemplates');
|
||||||
return all.findProperty('id', params.id);
|
return all.findBy('id', params.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, emailTemplate) {
|
setupController(controller, emailTemplate) {
|
||||||
|
@ -3,9 +3,5 @@ import EmailSettings from 'admin/models/email-settings';
|
|||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
model() {
|
model() {
|
||||||
return EmailSettings.find();
|
return EmailSettings.find();
|
||||||
},
|
|
||||||
|
|
||||||
renderTemplate() {
|
|
||||||
this.render('admin/templates/email_index', { into: 'adminEmail' });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@ export default AdminEmailIncomings.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showIncomingEmail(id) {
|
showIncomingEmail(id) {
|
||||||
showModal('modals/admin-incoming-email');
|
showModal('admin-incoming-email', { admin: true });
|
||||||
this.controllerFor("modals/admin-incoming-email").load(id);
|
this.controllerFor("modals/admin-incoming-email").load(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@ export default Discourse.Route.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showAgreeFlagModal(model) {
|
showAgreeFlagModal(model) {
|
||||||
showModal('modals/admin-agree-flag', { model });
|
showModal('admin-agree-flag', { model, admin: true });
|
||||||
this.controllerFor('modal').set('modalClass', 'agree-flag-modal');
|
this.controllerFor('modal').set('modalClass', 'agree-flag-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
showDeleteFlagModal(model) {
|
showDeleteFlagModal(model) {
|
||||||
showModal('modals/admin-delete-flag', { model });
|
showModal('admin-delete-flag', { model, admin: true });
|
||||||
this.controllerFor('modal').set('modalClass', 'delete-flag-modal');
|
this.controllerFor('modal').set('modalClass', 'delete-flag-modal');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@ export default Discourse.Route.extend({
|
|||||||
return Group.create({ automatic: false, visible: true });
|
return Group.create({ automatic: false, visible: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const group = this.modelFor('adminGroupsType')
|
const group = this.modelFor('adminGroupsType').findBy('name', params.name);
|
||||||
.findProperty('name', params.name);
|
|
||||||
|
|
||||||
if (!group) { return this.transitionTo('adminGroups.index'); }
|
if (!group) { return this.transitionTo('adminGroups.index'); }
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
renderTemplate: function() {
|
renderTemplate: function() {
|
||||||
this.render('admin/templates/logs/screened_emails', {into: 'adminLogs'});
|
this.render('admin/templates/logs/screened-emails', {into: 'adminLogs'});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function() {
|
setupController: function() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
renderTemplate() {
|
renderTemplate() {
|
||||||
this.render('admin/templates/logs/screened_ip_addresses', {into: 'adminLogs'});
|
this.render('admin/templates/logs/screened-ip-addresses', {into: 'adminLogs'});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController() {
|
setupController() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
renderTemplate: function() {
|
renderTemplate: function() {
|
||||||
this.render('admin/templates/logs/screened_urls', {into: 'adminLogs'});
|
this.render('admin/templates/logs/screened-urls', {into: 'adminLogs'});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function() {
|
setupController: function() {
|
||||||
|
@ -3,7 +3,7 @@ import showModal from 'discourse/lib/show-modal';
|
|||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
// TODO: make this automatic using an `{{outlet}}`
|
// TODO: make this automatic using an `{{outlet}}`
|
||||||
renderTemplate: function() {
|
renderTemplate: function() {
|
||||||
this.render('admin/templates/logs/staff_action_logs', {into: 'adminLogs'});
|
this.render('admin/templates/logs/staff-action-logs', {into: 'adminLogs'});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller) {
|
setupController: function(controller) {
|
||||||
@ -13,13 +13,18 @@ export default Discourse.Route.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showDetailsModal(model) {
|
showDetailsModal(model) {
|
||||||
showModal('modals/admin-staff-action-log-details', { model });
|
showModal('admin-staff-action-log-details', { model, admin: true });
|
||||||
this.controllerFor('modal').set('modalClass', 'log-details-modal');
|
this.controllerFor('modal').set('modalClass', 'log-details-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
showCustomDetailsModal(model) {
|
showCustomDetailsModal(model) {
|
||||||
const modalName = "modals/" + (model.action_name + '_details').replace("_", "-");
|
const modalName = (model.action_name + '_details').replace(/\_/g, "-");
|
||||||
showModal(modalName, { model });
|
|
||||||
|
showModal(modalName, {
|
||||||
|
model,
|
||||||
|
admin: true,
|
||||||
|
templateName: 'site-customization-change'
|
||||||
|
});
|
||||||
this.controllerFor('modal').set('modalClass', 'tabbed-modal log-details-modal');
|
this.controllerFor('modal').set('modalClass', 'tabbed-modal log-details-modal');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
export default {
|
export default function() {
|
||||||
resource: 'admin',
|
this.route('admin', { resetNamespace: true }, function() {
|
||||||
|
|
||||||
map() {
|
|
||||||
this.route('dashboard', { path: '/' });
|
this.route('dashboard', { path: '/' });
|
||||||
this.resource('adminSiteSettings', { path: '/site_settings' }, function() {
|
this.route('adminSiteSettings', { path: '/site_settings', resetNamespace: true }, function() {
|
||||||
this.resource('adminSiteSettingsCategory', { path: 'category/:category_id'} );
|
this.route('adminSiteSettingsCategory', { path: 'category/:category_id', resetNamespace: true} );
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminEmail', { path: '/email'}, function() {
|
this.route('adminEmail', { path: '/email', resetNamespace: true}, function() {
|
||||||
this.route('sent');
|
this.route('sent');
|
||||||
this.route('skipped');
|
this.route('skipped');
|
||||||
this.route('bounced');
|
this.route('bounced');
|
||||||
@ -16,65 +14,77 @@ export default {
|
|||||||
this.route('previewDigest', { path: '/preview-digest' });
|
this.route('previewDigest', { path: '/preview-digest' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminCustomize', { path: '/customize' } ,function() {
|
this.route('adminCustomize', { path: '/customize', resetNamespace: true } ,function() {
|
||||||
this.route('colors');
|
this.route('colors');
|
||||||
|
|
||||||
this.resource('adminCustomizeCssHtml', { path: 'css_html' }, function() {
|
this.route('adminCustomizeCssHtml', { path: 'css_html', resetNamespace: true }, function() {
|
||||||
this.route('show', {path: '/:site_customization_id/:section'});
|
this.route('show', {path: '/:site_customization_id/:section'});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminSiteText', { path: '/site_texts' }, function() {
|
this.route('adminSiteText', { path: '/site_texts', resetNamespace: true }, function() {
|
||||||
this.route('edit', { path: '/:id' });
|
this.route('edit', { path: '/:id' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminUserFields', { path: '/user_fields' });
|
this.route('adminUserFields', { path: '/user_fields', resetNamespace: true });
|
||||||
this.resource('adminEmojis', { path: '/emojis' });
|
this.route('adminEmojis', { path: '/emojis', resetNamespace: true });
|
||||||
this.resource('adminPermalinks', { path: '/permalinks' });
|
this.route('adminPermalinks', { path: '/permalinks', resetNamespace: true });
|
||||||
this.resource('adminEmbedding', { path: '/embedding' });
|
this.route('adminEmbedding', { path: '/embedding', resetNamespace: true });
|
||||||
this.resource('adminCustomizeEmailTemplates', { path: '/email_templates' }, function() {
|
this.route('adminCustomizeEmailTemplates', { path: '/email_templates', resetNamespace: true }, function() {
|
||||||
this.route('edit', { path: '/:id' });
|
this.route('edit', { path: '/:id' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.route('api');
|
|
||||||
|
|
||||||
this.resource('admin.backups', { path: '/backups' }, function() {
|
this.route('adminApi', { path: '/api', resetNamespace: true }, function() {
|
||||||
|
this.route('adminApiKeys', { path: '/keys', resetNamespace: true });
|
||||||
|
|
||||||
|
this.route('adminWebHooks', { path: '/web_hooks', resetNamespace: true }, function() {
|
||||||
|
this.route('show', { path: '/:web_hook_id' });
|
||||||
|
this.route('showEvents', { path: '/:web_hook_id/events' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route('admin.backups', { path: '/backups', resetNamespace: true }, function() {
|
||||||
this.route('logs');
|
this.route('logs');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminReports', { path: '/reports/:type' });
|
this.route('adminReports', { path: '/reports/:type', resetNamespace: true });
|
||||||
|
|
||||||
this.resource('adminFlags', { path: '/flags' }, function() {
|
this.route('adminFlags', { path: '/flags', resetNamespace: true }, function() {
|
||||||
this.route('list', { path: '/:filter' });
|
this.route('list', { path: '/:filter' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminLogs', { path: '/logs' }, function() {
|
this.route('adminLogs', { path: '/logs', resetNamespace: true }, function() {
|
||||||
this.route('staffActionLogs', { path: '/staff_action_logs' });
|
this.route('staffActionLogs', { path: '/staff_action_logs' });
|
||||||
this.route('screenedEmails', { path: '/screened_emails' });
|
this.route('screenedEmails', { path: '/screened_emails' });
|
||||||
this.route('screenedIpAddresses', { path: '/screened_ip_addresses' });
|
this.route('screenedIpAddresses', { path: '/screened_ip_addresses' });
|
||||||
this.route('screenedUrls', { path: '/screened_urls' });
|
this.route('screenedUrls', { path: '/screened_urls' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminGroups', { path: '/groups' }, function() {
|
this.route('adminGroups', { path: '/groups', resetNamespace: true }, function() {
|
||||||
this.route('bulk');
|
this.route('bulk');
|
||||||
this.route('bulkComplete', { path: 'bulk-complete' });
|
this.route('bulkComplete', { path: 'bulk-complete' });
|
||||||
this.resource('adminGroupsType', { path: '/:type' }, function() {
|
this.route('adminGroupsType', { path: '/:type', resetNamespace: true }, function() {
|
||||||
this.resource('adminGroup', { path: '/:name' });
|
this.route('adminGroup', { path: '/:name', resetNamespace: true });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminUsers', { path: '/users' }, function() {
|
this.route('adminUsers', { path: '/users', resetNamespace: true }, function() {
|
||||||
this.resource('adminUser', { path: '/:user_id/:username' }, function() {
|
this.route('adminUser', { path: '/:user_id/:username', resetNamespace: true }, function() {
|
||||||
this.route('badges');
|
this.route('badges');
|
||||||
this.route('tl3Requirements', { path: '/tl3_requirements' });
|
this.route('tl3Requirements', { path: '/tl3_requirements' });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminUsersList', { path: '/list' }, function() {
|
this.route('adminUsersList', { path: '/list', resetNamespace: true }, function() {
|
||||||
this.route('show', { path: '/:filter' });
|
this.route('show', { path: '/:filter' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminBadges', { path: '/badges' }, function() {
|
this.route('adminBadges', { path: '/badges', resetNamespace: true }, function() {
|
||||||
this.route('show', { path: '/:badge_id' });
|
this.route('show', { path: '/:badge_id' });
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
this.route('adminPlugins', { path: '/plugins', resetNamespace: true }, function() {
|
||||||
|
this.route('index', { path: '/' });
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,7 @@ export default Discourse.Route.extend({
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showSuspendModal(model) {
|
showSuspendModal(model) {
|
||||||
showModal('modals/admin-suspend-user', { model });
|
showModal('admin-suspend-user', { model, admin: true });
|
||||||
this.controllerFor('modal').set('modalClass', 'suspend-user-modal');
|
this.controllerFor('modal').set('modalClass', 'suspend-user-modal');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
export default Discourse.Route.extend({
|
||||||
|
model(params) {
|
||||||
|
return this.store.findAll('web-hook-event', Ember.get(params, 'web_hook_id'));
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
controller.set('model', model);
|
||||||
|
controller.subscribe();
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivate() {
|
||||||
|
this.controllerFor('adminWebHooks.showEvents').unsubscribe();
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTemplate() {
|
||||||
|
this.render('admin/templates/web-hooks-show-events', { into: 'adminApi' });
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,26 @@
|
|||||||
|
export default Discourse.Route.extend({
|
||||||
|
serialize(model) {
|
||||||
|
return { web_hook_id: model.get('id') || 'new' };
|
||||||
|
},
|
||||||
|
|
||||||
|
model(params) {
|
||||||
|
if (params.web_hook_id === 'new') {
|
||||||
|
return this.store.createRecord('web-hook');
|
||||||
|
}
|
||||||
|
return this.store.find('web-hook', Ember.get(params, 'web_hook_id'));
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
if (model.get('isNew') || Ember.isEmpty(model.get('web_hook_event_types'))) {
|
||||||
|
model.set('web_hook_event_types', controller.get('defaultEventTypes'));
|
||||||
|
}
|
||||||
|
|
||||||
|
model.set('category_ids', model.get('category_ids'));
|
||||||
|
model.set('group_ids', model.get('group_ids'));
|
||||||
|
controller.setProperties({ model, saved: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTemplate() {
|
||||||
|
this.render('admin/templates/web-hooks-show', { into: 'adminApi' });
|
||||||
|
}
|
||||||
|
});
|
15
app/assets/javascripts/admin/routes/admin-web-hooks.js.es6
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export default Ember.Route.extend({
|
||||||
|
model() {
|
||||||
|
return this.store.findAll('web-hook');
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
controller.setProperties({
|
||||||
|
model,
|
||||||
|
eventTypes: model.extras.event_types,
|
||||||
|
defaultEventTypes: model.extras.default_event_types,
|
||||||
|
contentTypes: model.extras.content_types,
|
||||||
|
deliveryStatuses: model.extras.delivery_statuses
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|