Merge branch 'master' into fix_limited_search_results
This commit is contained in:
commit
7c1d7fb423
|
@ -1,12 +0,0 @@
|
||||||
skip_missing_workers: true
|
|
||||||
allow_lossy: false
|
|
||||||
# PNG
|
|
||||||
advpng: false
|
|
||||||
optipng:
|
|
||||||
level: 2
|
|
||||||
pngcrush: false
|
|
||||||
pngout: false
|
|
||||||
pngquant: false
|
|
||||||
# JPG
|
|
||||||
jpegrecompress: false
|
|
||||||
timeout: 15
|
|
110
.rubocop.yml
110
.rubocop.yml
|
@ -1,14 +1,104 @@
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 2.3
|
TargetRubyVersion: 2.4
|
||||||
|
DisabledByDefault: true
|
||||||
|
|
||||||
Metrics/LineLength:
|
# Prefer &&/|| over and/or.
|
||||||
Max: 120
|
Style/AndOr:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
Metrics/MethodLength:
|
# Do not use braces for hash literals when they are the last argument of a
|
||||||
|
# method call.
|
||||||
|
Style/BracesAroundHashParameters:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Align `when` with `case`.
|
||||||
|
Layout/CaseIndentation:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Align comments with method definitions.
|
||||||
|
Layout/CommentIndentation:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# No extra empty lines.
|
||||||
|
Layout/EmptyLines:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
||||||
|
Style/HashSyntax:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Two spaces, no tabs (for indentation).
|
||||||
|
Layout/IndentationWidth:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceAfterColon:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceAfterComma:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceAroundEqualsInParameterDefault:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceAroundKeyword:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceAroundOperators:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceBeforeFirstArg:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Defining a method with parameters needs parentheses.
|
||||||
|
Style/MethodDefParentheses:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use `foo {}` not `foo{}`.
|
||||||
|
Layout/SpaceBeforeBlockBraces:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use `foo { bar }` not `foo {bar}`.
|
||||||
|
Layout/SpaceInsideBlockBraces:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use `{ a: 1 }` not `{a:1}`.
|
||||||
|
Layout/SpaceInsideHashLiteralBraces:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceInsideParens:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Detect hard tabs, no hard tabs.
|
||||||
|
Layout/Tab:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Blank lines should not have any spaces.
|
||||||
|
Layout/TrailingBlankLines:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# No trailing whitespace.
|
||||||
|
Layout/TrailingWhitespace:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/BlockAlignment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Align `end` with the matching keyword or starting expression except for
|
||||||
|
# assignments, where it should be aligned with the LHS.
|
||||||
|
Lint/EndAlignment:
|
||||||
|
Enabled: true
|
||||||
|
EnforcedStyleAlignWith: variable
|
||||||
|
|
||||||
|
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
||||||
|
Lint/RequireParentheses:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/MultilineMethodCallIndentation:
|
||||||
|
Enabled: true
|
||||||
|
EnforcedStyle: indented
|
||||||
|
|
||||||
|
Layout/AlignHash:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Bundler/OrderedGems:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/Documentation:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Style/FrozenStringLiteralComment:
|
|
||||||
Enabled: False
|
|
||||||
|
|
10
.travis.yml
10
.travis.yml
|
@ -6,9 +6,7 @@ env:
|
||||||
- RUBY_GC_MALLOC_LIMIT=50000000
|
- RUBY_GC_MALLOC_LIMIT=50000000
|
||||||
matrix:
|
matrix:
|
||||||
- "RAILS_MASTER=0 QUNIT_RUN=0"
|
- "RAILS_MASTER=0 QUNIT_RUN=0"
|
||||||
- "RAILS_MASTER=1 QUNIT_RUN=0"
|
|
||||||
- "RAILS_MASTER=0 QUNIT_RUN=1"
|
- "RAILS_MASTER=0 QUNIT_RUN=1"
|
||||||
- "RAILS_MASTER=1 QUNIT_RUN=1"
|
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
postgresql: 9.5
|
postgresql: 9.5
|
||||||
|
@ -20,9 +18,6 @@ addons:
|
||||||
- jhead
|
- jhead
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
|
||||||
- env: "RAILS_MASTER=1 QUNIT_RUN=0"
|
|
||||||
- env: "RAILS_MASTER=1 QUNIT_RUN=1"
|
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
|
@ -41,7 +36,7 @@ cache:
|
||||||
- vendor/bundle
|
- vendor/bundle
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- gem install bundler
|
- gem install bundler rubocop
|
||||||
- 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-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-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-cakeday.git plugins/discourse-cakeday
|
||||||
|
@ -53,6 +48,7 @@ before_install:
|
||||||
- eslint --ext .es6 test/javascripts
|
- eslint --ext .es6 test/javascripts
|
||||||
- eslint --ext .es6 plugins/**/assets/javascripts
|
- eslint --ext .es6 plugins/**/assets/javascripts
|
||||||
- eslint test/javascripts
|
- eslint test/javascripts
|
||||||
|
- rubocop --parallel
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- bundle exec rake db:create db:migrate
|
- bundle exec rake db:create db:migrate
|
||||||
|
@ -62,4 +58,4 @@ install:
|
||||||
- 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:
|
script:
|
||||||
- bash -c "if [ '$QUNIT_RUN' == '0' ]; then bundle exec rspec && bundle exec rake plugin:spec; else LOAD_PLUGINS=1 bundle exec rake qunit:test['200000']; fi"
|
- bash -c "if [ '$QUNIT_RUN' == '0' ]; then bundle exec rspec && bundle exec rake plugin:spec; else LOAD_PLUGINS=1 bundle exec rake qunit:test['300000']; fi"
|
||||||
|
|
4
Gemfile
4
Gemfile
|
@ -66,7 +66,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.6'
|
gem 'email_reply_trimmer', '0.1.7'
|
||||||
|
|
||||||
# TODO Use official image_optim gem once https://github.com/toy/image_optim/pull/149
|
# TODO Use official image_optim gem once https://github.com/toy/image_optim/pull/149
|
||||||
# is merged.
|
# is merged.
|
||||||
|
@ -122,7 +122,6 @@ group :test do
|
||||||
gem 'webmock', require: false
|
gem 'webmock', require: false
|
||||||
gem 'fakeweb', '~> 1.3.0', require: false
|
gem 'fakeweb', '~> 1.3.0', require: false
|
||||||
gem 'minitest', require: false
|
gem 'minitest', require: false
|
||||||
gem 'timecop'
|
|
||||||
# TODO: Remove once we upgrade to Rails 5.
|
# TODO: Remove once we upgrade to Rails 5.
|
||||||
gem 'test_after_commit'
|
gem 'test_after_commit'
|
||||||
end
|
end
|
||||||
|
@ -190,7 +189,6 @@ gem 'logster'
|
||||||
|
|
||||||
gem 'sassc', require: false
|
gem 'sassc', require: false
|
||||||
|
|
||||||
|
|
||||||
if ENV["IMPORT"] == "1"
|
if ENV["IMPORT"] == "1"
|
||||||
gem 'mysql2'
|
gem 'mysql2'
|
||||||
gem 'redcarpet'
|
gem 'redcarpet'
|
||||||
|
|
82
Gemfile.lock
82
Gemfile.lock
|
@ -1,38 +1,38 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.2.8)
|
actionmailer (4.2.9)
|
||||||
actionpack (= 4.2.8)
|
actionpack (= 4.2.9)
|
||||||
actionview (= 4.2.8)
|
actionview (= 4.2.9)
|
||||||
activejob (= 4.2.8)
|
activejob (= 4.2.9)
|
||||||
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.8)
|
actionpack (4.2.9)
|
||||||
actionview (= 4.2.8)
|
actionview (= 4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
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.8)
|
actionview (4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
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.3)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
active_model_serializers (0.8.3)
|
active_model_serializers (0.8.3)
|
||||||
activemodel (>= 3.0)
|
activemodel (>= 3.0)
|
||||||
activejob (4.2.8)
|
activejob (4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
globalid (>= 0.3.0)
|
globalid (>= 0.3.0)
|
||||||
activemodel (4.2.8)
|
activemodel (4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.2.8)
|
activerecord (4.2.9)
|
||||||
activemodel (= 4.2.8)
|
activemodel (= 4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
arel (~> 6.0)
|
arel (~> 6.0)
|
||||||
activesupport (4.2.8)
|
activesupport (4.2.9)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
thread_safe (~> 0.3, >= 0.3.4)
|
thread_safe (~> 0.3, >= 0.3.4)
|
||||||
|
@ -84,7 +84,7 @@ GEM
|
||||||
image_size (~> 1.5)
|
image_size (~> 1.5)
|
||||||
in_threads (~> 1.3)
|
in_threads (~> 1.3)
|
||||||
progress (~> 3.0, >= 3.0.1)
|
progress (~> 3.0, >= 3.0.1)
|
||||||
email_reply_trimmer (0.1.6)
|
email_reply_trimmer (0.1.7)
|
||||||
ember-data-source (2.2.1)
|
ember-data-source (2.2.1)
|
||||||
ember-source (>= 1.8, < 3.0)
|
ember-source (>= 1.8, < 3.0)
|
||||||
ember-handlebars-template (0.7.5)
|
ember-handlebars-template (0.7.5)
|
||||||
|
@ -127,7 +127,7 @@ GEM
|
||||||
hiredis (0.6.1)
|
hiredis (0.6.1)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
http_accept_language (2.0.5)
|
http_accept_language (2.0.5)
|
||||||
i18n (0.8.4)
|
i18n (0.8.6)
|
||||||
image_size (1.5.0)
|
image_size (1.5.0)
|
||||||
in_threads (1.4.0)
|
in_threads (1.4.0)
|
||||||
jmespath (1.3.1)
|
jmespath (1.3.1)
|
||||||
|
@ -137,7 +137,7 @@ GEM
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
jwt (1.5.6)
|
jwt (1.5.6)
|
||||||
kgio (2.11.0)
|
kgio (2.11.0)
|
||||||
libv8 (5.3.332.38.5)
|
libv8 (5.9.211.38.1)
|
||||||
listen (3.1.5)
|
listen (3.1.5)
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
|
@ -153,12 +153,14 @@ GEM
|
||||||
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)
|
||||||
mime-types (2.99.3)
|
mime-types (3.1)
|
||||||
|
mime-types-data (~> 3.2015)
|
||||||
|
mime-types-data (3.2016.0521)
|
||||||
mini_mime (0.1.3)
|
mini_mime (0.1.3)
|
||||||
mini_portile2 (2.2.0)
|
mini_portile2 (2.2.0)
|
||||||
mini_racer (0.1.10)
|
mini_racer (0.1.11)
|
||||||
libv8 (~> 5.3)
|
libv8 (~> 5.7)
|
||||||
minitest (5.10.2)
|
minitest (5.10.3)
|
||||||
mocha (1.2.1)
|
mocha (1.2.1)
|
||||||
metaclass (~> 0.0.1)
|
metaclass (~> 0.0.1)
|
||||||
mock_redis (0.17.3)
|
mock_redis (0.17.3)
|
||||||
|
@ -211,7 +213,7 @@ GEM
|
||||||
omniauth-twitter (1.3.0)
|
omniauth-twitter (1.3.0)
|
||||||
omniauth-oauth (~> 1.1)
|
omniauth-oauth (~> 1.1)
|
||||||
rack
|
rack
|
||||||
onebox (1.8.15)
|
onebox (1.8.16)
|
||||||
fast_blank (>= 1.0.0)
|
fast_blank (>= 1.0.0)
|
||||||
htmlentities (~> 4.3)
|
htmlentities (~> 4.3)
|
||||||
moneta (~> 1.0)
|
moneta (~> 1.0)
|
||||||
|
@ -245,16 +247,16 @@ GEM
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.8)
|
rails (4.2.9)
|
||||||
actionmailer (= 4.2.8)
|
actionmailer (= 4.2.9)
|
||||||
actionpack (= 4.2.8)
|
actionpack (= 4.2.9)
|
||||||
actionview (= 4.2.8)
|
actionview (= 4.2.9)
|
||||||
activejob (= 4.2.8)
|
activejob (= 4.2.9)
|
||||||
activemodel (= 4.2.8)
|
activemodel (= 4.2.9)
|
||||||
activerecord (= 4.2.8)
|
activerecord (= 4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.8)
|
railties (= 4.2.9)
|
||||||
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)
|
||||||
|
@ -266,9 +268,9 @@ GEM
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
rails_multisite (1.0.6)
|
rails_multisite (1.0.6)
|
||||||
rails (> 4.2, < 5)
|
rails (> 4.2, < 5)
|
||||||
railties (4.2.8)
|
railties (4.2.9)
|
||||||
actionpack (= 4.2.8)
|
actionpack (= 4.2.9)
|
||||||
activesupport (= 4.2.8)
|
activesupport (= 4.2.9)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
raindrops (0.18.0)
|
raindrops (0.18.0)
|
||||||
|
@ -363,7 +365,6 @@ GEM
|
||||||
thor (0.19.4)
|
thor (0.19.4)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.7)
|
tilt (2.0.7)
|
||||||
timecop (0.8.1)
|
|
||||||
trollop (2.1.2)
|
trollop (2.1.2)
|
||||||
tzinfo (1.2.3)
|
tzinfo (1.2.3)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
|
@ -397,7 +398,7 @@ DEPENDENCIES
|
||||||
certified
|
certified
|
||||||
discourse-qunit-rails
|
discourse-qunit-rails
|
||||||
discourse_image_optim
|
discourse_image_optim
|
||||||
email_reply_trimmer (= 0.1.6)
|
email_reply_trimmer (= 0.1.7)
|
||||||
ember-handlebars-template (= 0.7.5)
|
ember-handlebars-template (= 0.7.5)
|
||||||
ember-rails (= 0.18.5)
|
ember-rails (= 0.18.5)
|
||||||
ember-source
|
ember-source
|
||||||
|
@ -476,11 +477,10 @@ DEPENDENCIES
|
||||||
test_after_commit
|
test_after_commit
|
||||||
thor
|
thor
|
||||||
tilt
|
tilt
|
||||||
timecop
|
|
||||||
uglifier
|
uglifier
|
||||||
unf
|
unf
|
||||||
unicorn
|
unicorn
|
||||||
webmock
|
webmock
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.15.1
|
1.15.3
|
||||||
|
|
1
Rakefile
1
Rakefile
|
@ -9,4 +9,3 @@ Discourse::Application.load_tasks
|
||||||
# this prevents crashes when migrating a database in production in certain
|
# this prevents crashes when migrating a database in production in certain
|
||||||
# PostgreSQL configuations when trying to create structure.sql
|
# PostgreSQL configuations when trying to create structure.sql
|
||||||
Rake::Task["db:structure:dump"].clear if Rails.env.production?
|
Rake::Task["db:structure:dump"].clear if Rails.env.production?
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
classNames: ['watched-word'],
|
||||||
|
|
||||||
|
buildBuffer(buffer) {
|
||||||
|
buffer.push(iconHTML('times'));
|
||||||
|
buffer.push(' ' + this.get('word.word'));
|
||||||
|
},
|
||||||
|
|
||||||
|
click() {
|
||||||
|
this.get('word').destroy().then(() => {
|
||||||
|
this.sendAction('action', this.get('word'));
|
||||||
|
}).catch(e => {
|
||||||
|
bootbox.alert(I18n.t("generic_error_with_reason", {error: `http: ${e.status} - ${e.body}`}));
|
||||||
|
});;
|
||||||
|
}
|
||||||
|
}));
|
|
@ -1,5 +1,5 @@
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
/*global Resumable:true */
|
/*global Resumable:true */
|
||||||
|
@ -40,7 +41,7 @@ export default Ember.Component.extend(bufferedRender({
|
||||||
|
|
||||||
buildBuffer(buffer) {
|
buildBuffer(buffer) {
|
||||||
const icon = this.get("isUploading") ? "times" : "upload";
|
const icon = this.get("isUploading") ? "times" : "upload";
|
||||||
buffer.push(`<i class="fa fa-${icon}"></i>`);
|
buffer.push(iconHTML(icon));
|
||||||
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>");
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import WatchedWord from 'admin/models/watched-word';
|
||||||
|
import { on, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
classNames: ['watched-word-form'],
|
||||||
|
formSubmitted: false,
|
||||||
|
actionKey: null,
|
||||||
|
showSuccessMessage: false,
|
||||||
|
|
||||||
|
@observes('word')
|
||||||
|
removeSuccessMessage() {
|
||||||
|
if (this.get('showSuccessMessage') && !Ember.isEmpty(this.get('word'))) {
|
||||||
|
this.set('showSuccessMessage', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
submit() {
|
||||||
|
if (!this.get('formSubmitted')) {
|
||||||
|
this.set('formSubmitted', true);
|
||||||
|
|
||||||
|
const watchedWord = WatchedWord.create({ word: this.get('word'), action: this.get('actionKey') });
|
||||||
|
|
||||||
|
watchedWord.save().then(result => {
|
||||||
|
this.setProperties({ word: '', formSubmitted: false, showSuccessMessage: true });
|
||||||
|
this.sendAction('action', WatchedWord.create(result));
|
||||||
|
Ember.run.schedule('afterRender', () => this.$('.watched-word-input').focus());
|
||||||
|
}).catch(e => {
|
||||||
|
this.set('formSubmitted', false);
|
||||||
|
const msg = (e.responseJSON && e.responseJSON.errors) ?
|
||||||
|
I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')}) :
|
||||||
|
I18n.t("generic_error");
|
||||||
|
bootbox.alert(msg, () => this.$('.watched-word-input').focus());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@on("didInsertElement")
|
||||||
|
_init() {
|
||||||
|
Ember.run.schedule('afterRender', () => {
|
||||||
|
this.$('.watched-word-input').keydown(e => {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
this.send('submit');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,25 @@
|
||||||
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
import UploadMixin from "discourse/mixins/upload";
|
||||||
|
|
||||||
|
export default Em.Component.extend(UploadMixin, {
|
||||||
|
type: 'csv',
|
||||||
|
classNames: 'watched-words-uploader',
|
||||||
|
uploadUrl: '/admin/watched_words/upload',
|
||||||
|
addDisabled: Em.computed.alias("uploading"),
|
||||||
|
|
||||||
|
validateUploadedFilesOptions() {
|
||||||
|
return { csvOnly: true };
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('actionKey')
|
||||||
|
data(actionKey) {
|
||||||
|
return { action_key: actionKey };
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadDone() {
|
||||||
|
if (this) {
|
||||||
|
bootbox.alert(I18n.t("admin.watched_words.form.upload_successful"));
|
||||||
|
this.sendAction("done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -31,10 +31,10 @@ export default Ember.Controller.extend({
|
||||||
];
|
];
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
@computed('model.visibility_level', 'model.public')
|
@computed('model.visibility_level', 'model.public_admission')
|
||||||
disableMembershipRequestSetting(visibility_level, publicGroup) {
|
disableMembershipRequestSetting(visibility_level, publicAdmission) {
|
||||||
visibility_level = parseInt(visibility_level);
|
visibility_level = parseInt(visibility_level);
|
||||||
return (visibility_level !== 0) || publicGroup;
|
return (visibility_level !== 0) || publicAdmission;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('model.visibility_level', 'model.allow_membership_requests')
|
@computed('model.visibility_level', 'model.allow_membership_requests')
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
import WatchedWord from 'admin/models/watched-word';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
actionNameKey: null,
|
||||||
|
adminWatchedWords: Ember.inject.controller(),
|
||||||
|
showWordsList: Ember.computed.or('adminWatchedWords.filtered', 'adminWatchedWords.showWords'),
|
||||||
|
|
||||||
|
findAction(actionName) {
|
||||||
|
return (this.get('adminWatchedWords.model') || []).findBy('nameKey', actionName);
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('adminWatchedWords.model', 'actionNameKey')
|
||||||
|
filteredContent() {
|
||||||
|
if (!this.get('actionNameKey')) { return []; }
|
||||||
|
|
||||||
|
const a = this.findAction(this.get('actionNameKey'));
|
||||||
|
return a ? a.words : [];
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('actionNameKey')
|
||||||
|
actionDescription(actionNameKey) {
|
||||||
|
return I18n.t('admin.watched_words.action_descriptions.' + actionNameKey);
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
recordAdded(arg) {
|
||||||
|
const a = this.findAction(this.get('actionNameKey'));
|
||||||
|
if (a) {
|
||||||
|
a.words.unshiftObject(arg);
|
||||||
|
a.incrementProperty('count');
|
||||||
|
Em.run.schedule('afterRender', () => {
|
||||||
|
// remove from other actions lists
|
||||||
|
let match = null;
|
||||||
|
this.get('adminWatchedWords.model').forEach(action => {
|
||||||
|
if (match) return;
|
||||||
|
|
||||||
|
if (action.nameKey !== this.get('actionNameKey')) {
|
||||||
|
match = action.words.findBy('id', arg.id);
|
||||||
|
if (match) {
|
||||||
|
action.words.removeObject(match);
|
||||||
|
action.decrementProperty('count');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
recordRemoved(arg) {
|
||||||
|
const a = this.findAction(this.get('actionNameKey'));
|
||||||
|
if (a) {
|
||||||
|
a.words.removeObject(arg);
|
||||||
|
a.decrementProperty('count');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadComplete() {
|
||||||
|
WatchedWord.findAll().then(data => {
|
||||||
|
this.set('adminWatchedWords.model', data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,51 @@
|
||||||
|
import debounce from 'discourse/lib/debounce';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
filter: null,
|
||||||
|
filtered: false,
|
||||||
|
showWords: false,
|
||||||
|
disableShowWords: Ember.computed.alias('filtered'),
|
||||||
|
|
||||||
|
filterContentNow() {
|
||||||
|
|
||||||
|
if (!!Ember.isEmpty(this.get('allWatchedWords'))) return;
|
||||||
|
|
||||||
|
let filter;
|
||||||
|
if (this.get('filter')) {
|
||||||
|
filter = this.get('filter').toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter === undefined || filter.length < 1) {
|
||||||
|
this.set('model', this.get('allWatchedWords'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchesByAction = [];
|
||||||
|
|
||||||
|
this.get('allWatchedWords').forEach(wordsForAction => {
|
||||||
|
const wordRecords = wordsForAction.words.filter(wordRecord => {
|
||||||
|
return (wordRecord.word.indexOf(filter) > -1);
|
||||||
|
});
|
||||||
|
matchesByAction.pushObject( Ember.Object.create({
|
||||||
|
nameKey: wordsForAction.nameKey,
|
||||||
|
name: wordsForAction.name,
|
||||||
|
words: wordRecords,
|
||||||
|
count: wordRecords.length
|
||||||
|
}) );
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set('model', matchesByAction);
|
||||||
|
},
|
||||||
|
|
||||||
|
filterContent: debounce(function() {
|
||||||
|
this.filterContentNow();
|
||||||
|
this.set('filtered', !Ember.isEmpty(this.get('filter')));
|
||||||
|
}, 250).observes('filter'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
clearFilter() {
|
||||||
|
this.setProperties({ filter: '' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { registerUnbound } from 'discourse-common/lib/helpers';
|
||||||
|
import { renderIcon } from 'discourse-common/lib/icon-library';
|
||||||
|
|
||||||
|
registerUnbound('check-icon', function(value) {
|
||||||
|
let icon = value ? "check" : "times";
|
||||||
|
return new Handlebars.SafeString(renderIcon('string', icon));
|
||||||
|
});
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
import { propertyNotEqual } from 'discourse/lib/computed';
|
import { propertyNotEqual } from 'discourse/lib/computed';
|
||||||
|
@ -108,7 +109,7 @@ const AdminUser = Discourse.User.extend({
|
||||||
"class": "cancel-inline",
|
"class": "cancel-inline",
|
||||||
"link": true
|
"link": true
|
||||||
}, {
|
}, {
|
||||||
"label": '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("admin.user.delete_all_posts"),
|
"label": `${iconHTML('exclamation-triangle')} ` + I18n.t("admin.user.delete_all_posts"),
|
||||||
"class": "btn btn-danger",
|
"class": "btn btn-danger",
|
||||||
"callback": function() {
|
"callback": function() {
|
||||||
ajax("/admin/users/" + user.get('id') + "/delete_all_posts", {
|
ajax("/admin/users/" + user.get('id') + "/delete_all_posts", {
|
||||||
|
@ -337,7 +338,7 @@ const AdminUser = Discourse.User.extend({
|
||||||
"class": "cancel",
|
"class": "cancel",
|
||||||
"link": true
|
"link": true
|
||||||
}, {
|
}, {
|
||||||
"label": '<i class="fa fa-exclamation-triangle"></i>' + I18n.t('admin.user.block_accept'),
|
"label": `${iconHTML('exclamation-triangle')} ` + I18n.t('admin.user.block_accept'),
|
||||||
"class": "btn btn-danger",
|
"class": "btn btn-danger",
|
||||||
"callback": function() { performBlock(); }
|
"callback": function() { performBlock(); }
|
||||||
}];
|
}];
|
||||||
|
@ -386,7 +387,7 @@ const AdminUser = Discourse.User.extend({
|
||||||
"class": "cancel",
|
"class": "cancel",
|
||||||
"link": true
|
"link": true
|
||||||
}, {
|
}, {
|
||||||
"label": '<i class="fa fa-exclamation-triangle"></i>' + I18n.t('admin.user.anonymize_yes'),
|
"label": `${iconHTML('exclamation-triangle')} ` + I18n.t('admin.user.anonymize_yes'),
|
||||||
"class": "btn btn-danger",
|
"class": "btn btn-danger",
|
||||||
"callback": function() { performAnonymize(); }
|
"callback": function() { performAnonymize(); }
|
||||||
}];
|
}];
|
||||||
|
@ -450,7 +451,7 @@ const AdminUser = Discourse.User.extend({
|
||||||
"class": "btn",
|
"class": "btn",
|
||||||
"link": true
|
"link": true
|
||||||
}, {
|
}, {
|
||||||
"label": '<i class="fa fa-exclamation-triangle"></i>' + I18n.t('admin.user.delete_and_block'),
|
"label": `${iconHTML('exclamation-triangle')} ` + I18n.t('admin.user.delete_and_block'),
|
||||||
"class": "btn btn-danger",
|
"class": "btn btn-danger",
|
||||||
"callback": function(){ performDestroy(true); }
|
"callback": function(){ performDestroy(true); }
|
||||||
}, {
|
}, {
|
||||||
|
@ -479,7 +480,7 @@ const AdminUser = Discourse.User.extend({
|
||||||
"class": "cancel-inline",
|
"class": "cancel-inline",
|
||||||
"link": true
|
"link": true
|
||||||
}, {
|
}, {
|
||||||
"label": '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("flagging.yes_delete_spammer"),
|
"label": `${iconHTML('exclamation-triangle')} ` + I18n.t("flagging.yes_delete_spammer"),
|
||||||
"class": "btn btn-danger",
|
"class": "btn btn-danger",
|
||||||
"callback": function() {
|
"callback": function() {
|
||||||
return ajax("/admin/users/" + user.get('id') + '.json', {
|
return ajax("/admin/users/" + user.get('id') + '.json', {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { ajax } from 'discourse/lib/ajax';
|
||||||
import AdminUser from 'admin/models/admin-user';
|
import AdminUser from 'admin/models/admin-user';
|
||||||
import Topic from 'discourse/models/topic';
|
import Topic from 'discourse/models/topic';
|
||||||
import Post from 'discourse/models/post';
|
import Post from 'discourse/models/post';
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
|
|
||||||
const FlaggedPost = Post.extend({
|
const FlaggedPost = Post.extend({
|
||||||
|
|
||||||
|
@ -35,13 +35,14 @@ const FlaggedPost = Post.extend({
|
||||||
|
|
||||||
dispositionIcon: function (disposition) {
|
dispositionIcon: function (disposition) {
|
||||||
if (!disposition) { return null; }
|
if (!disposition) { return null; }
|
||||||
var icon, title = I18n.t('admin.flags.dispositions.' + disposition);
|
let icon;
|
||||||
|
let title = 'admin.flags.dispositions.' + disposition;
|
||||||
switch (disposition) {
|
switch (disposition) {
|
||||||
case "deferred": { icon = "fa-external-link"; break; }
|
case "deferred": { icon = "external-link"; break; }
|
||||||
case "agreed": { icon = "fa-thumbs-o-up"; break; }
|
case "agreed": { icon = "thumbs-o-up"; break; }
|
||||||
case "disagreed": { icon = "fa-thumbs-o-down"; break; }
|
case "disagreed": { icon = "thumbs-o-down"; break; }
|
||||||
}
|
}
|
||||||
return "<i class='fa " + icon + "' title='" + title + "'></i>";
|
return iconHTML(icon, { title });
|
||||||
},
|
},
|
||||||
|
|
||||||
wasEdited: function () {
|
wasEdited: function () {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
|
|
||||||
|
const WatchedWord = Discourse.Model.extend({
|
||||||
|
save() {
|
||||||
|
return ajax("/admin/watched_words" + (this.id ? '/' + this.id : '') + ".json", {
|
||||||
|
type: this.id ? 'PUT' : 'POST',
|
||||||
|
data: {word: this.get('word'), action_key: this.get('action')},
|
||||||
|
dataType: 'json'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
return ajax("/admin/watched_words/" + this.get('id') + ".json", {type: 'DELETE'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
WatchedWord.reopenClass({
|
||||||
|
findAll() {
|
||||||
|
return ajax("/admin/watched_words").then(function (list) {
|
||||||
|
const actions = {};
|
||||||
|
list.words.forEach(s => {
|
||||||
|
if (!actions[s.action]) { actions[s.action] = []; }
|
||||||
|
actions[s.action].pushObject(WatchedWord.create(s));
|
||||||
|
});
|
||||||
|
|
||||||
|
list.actions.forEach(a => {
|
||||||
|
if (!actions[a]) { actions[a] = []; }
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.keys(actions).map(function(n) {
|
||||||
|
return Ember.Object.create({nameKey: n, name: I18n.t('admin.watched_words.actions.' + n), words: actions[n], count: actions[n].length});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default WatchedWord;
|
|
@ -37,7 +37,7 @@ export default RestModel.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
groupFinder(term) {
|
groupFinder(term) {
|
||||||
return Group.findAll({search: term, ignore_automatic: false});
|
return Group.findAll({ term: term, ignore_automatic: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('wildcard_web_hook', 'web_hook_event_types.[]')
|
@computed('wildcard_web_hook', 'web_hook_event_types.[]')
|
||||||
|
@ -82,4 +82,3 @@ export default RestModel.extend({
|
||||||
return this.createProperties();
|
return this.createProperties();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -90,5 +90,10 @@ export default function() {
|
||||||
this.route('adminPlugins', { path: '/plugins', resetNamespace: true }, function() {
|
this.route('adminPlugins', { path: '/plugins', resetNamespace: true }, function() {
|
||||||
this.route('index', { path: '/' });
|
this.route('index', { path: '/' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.route('adminWatchedWords', { path: '/watched_words', resetNamespace: true}, function() {
|
||||||
|
this.route('index', { path: '/' } );
|
||||||
|
this.route('action', { path: '/action/:action_id' } );
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export default Discourse.Route.extend({
|
||||||
|
model(params) {
|
||||||
|
this.controllerFor('adminWatchedWordsAction').set('actionNameKey', params.action_id);
|
||||||
|
let filteredContent = this.controllerFor('adminWatchedWordsAction').get('filteredContent');
|
||||||
|
return Ember.Object.create({
|
||||||
|
nameKey: params.action_id,
|
||||||
|
name: I18n.t('admin.watched_words.actions.' + params.action_id),
|
||||||
|
words: filteredContent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
export default Discourse.Route.extend({
|
||||||
|
beforeModel() {
|
||||||
|
this.replaceWith('adminWatchedWords.action', this.modelFor('adminWatchedWords')[0].nameKey);
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
import WatchedWord from 'admin/models/watched-word';
|
||||||
|
|
||||||
|
export default Discourse.Route.extend({
|
||||||
|
queryParams: {
|
||||||
|
filter: { replace: true }
|
||||||
|
},
|
||||||
|
|
||||||
|
model() {
|
||||||
|
return WatchedWord.findAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
afterModel(watchedWordsList) {
|
||||||
|
this.controllerFor('adminWatchedWords').set('allWatchedWords', watchedWordsList);
|
||||||
|
}
|
||||||
|
});
|
|
@ -22,6 +22,7 @@
|
||||||
{{nav-item route='adminApi' label='admin.api.title'}}
|
{{nav-item route='adminApi' label='admin.api.title'}}
|
||||||
{{nav-item route='admin.backups' label='admin.backups.title'}}
|
{{nav-item route='admin.backups' label='admin.backups.title'}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{nav-item route='adminWatchedWords' label='admin.watched_words.title'}}
|
||||||
{{nav-item route='adminPlugins' label='admin.plugins.title'}}
|
{{nav-item route='adminPlugins' label='admin.plugins.title'}}
|
||||||
{{plugin-outlet name="admin-menu" connectorTagName="li"}}
|
{{plugin-outlet name="admin-menu" connectorTagName="li"}}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -29,5 +29,5 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#unless hasMasterKey}}
|
{{#unless hasMasterKey}}
|
||||||
<button class='btn' {{action "generateMasterKey"}}><i class="fa fa-key"></i>{{i18n 'admin.api.generate_master'}}</button>
|
<button class='btn' {{action "generateMasterKey"}}>{{d-icon "key"}}</button>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{#link-to 'adminBadges.show' 'new' class="btn"}}
|
{{#link-to 'adminBadges.show' 'new' class="btn"}}
|
||||||
{{fa-icon "plus"}} {{i18n 'admin.badges.new'}}
|
{{d-icon "plus"}} {{i18n 'admin.badges.new'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
{{/d-section}}
|
{{/d-section}}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
content=badgeGroupings
|
content=badgeGroupings
|
||||||
optionValuePath="content.id"
|
optionValuePath="content.id"
|
||||||
optionLabelPath="content.displayName"}}
|
optionLabelPath="content.displayName"}}
|
||||||
<button {{action "editGroupings"}} class='btn'>{{fa-icon 'pencil'}}</button>
|
<button {{action "editGroupings"}} class='btn'>{{d-icon 'pencil'}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
{{#link-to 'adminBadges.show' 'new' class="btn"}}
|
{{#link-to 'adminBadges.show' 'new' class="btn"}}
|
||||||
{{fa-icon "plus"}} {{i18n 'admin.badges.new'}}
|
{{d-icon "plus"}} {{i18n 'admin.badges.new'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<td class="title">
|
<td class="title">
|
||||||
{{#if report.icon}}
|
{{#if report.icon}}
|
||||||
{{fa-icon report.icon}}
|
{{d-icon report.icon}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<a href="{{report.reportUrl}}">{{report.title}}</a>
|
<a href="{{report.reportUrl}}">{{report.title}}</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -8,15 +8,15 @@
|
||||||
<td class="value">{{number report.todayCount}}</td>
|
<td class="value">{{number report.todayCount}}</td>
|
||||||
|
|
||||||
<td class="value {{report.yesterdayTrend}}" title={{report.yesterdayCountTitle}}>
|
<td class="value {{report.yesterdayTrend}}" title={{report.yesterdayCountTitle}}>
|
||||||
{{number report.yesterdayCount}} {{fa-icon "caret-up" class="up"}} {{fa-icon "caret-down" class="down"}}
|
{{number report.yesterdayCount}} {{d-icon "caret-up" class="up"}} {{d-icon "caret-down" class="down"}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="value {{report.sevenDayTrend}}" title={{report.sevenDayCountTitle}}>
|
<td class="value {{report.sevenDayTrend}}" title={{report.sevenDayCountTitle}}>
|
||||||
{{number report.lastSevenDaysCount}} {{fa-icon "caret-up" class="up"}} {{fa-icon "caret-down" class="down"}}
|
{{number report.lastSevenDaysCount}} {{d-icon "caret-up" class="up"}} {{d-icon "caret-down" class="down"}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="value {{report.thirtyDayTrend}}" title={{report.thirtyDayCountTitle}}>
|
<td class="value {{report.thirtyDayTrend}}" title={{report.thirtyDayCountTitle}}>
|
||||||
{{number report.lastThirtyDaysCount}} {{fa-icon "caret-up" class="up"}} {{fa-icon "caret-down" class="down"}}
|
{{number report.lastThirtyDaysCount}} {{d-icon "caret-up" class="up"}} {{d-icon "caret-down" class="down"}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="value">{{number report.total}}</td>
|
<td class="value">{{number report.total}}</td>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="validation-error {{unless message 'hidden'}}">
|
<div class="validation-error {{unless message 'hidden'}}">
|
||||||
{{fa-icon "times"}}
|
{{d-icon "times"}}
|
||||||
{{message}}
|
{{message}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<b>{{i18n 'admin.watched_words.form.label'}}</b>
|
||||||
|
{{text-field value=word disabled=formSubmitted class="watched-word-input" autocorrect="off" autocapitalize="off"}}
|
||||||
|
{{d-button action="submit" disabled=formSubmitted label="admin.watched_words.form.add"}}
|
||||||
|
|
||||||
|
{{#if showSuccessMessage}}
|
||||||
|
<span class="success-message">{{i18n 'admin.watched_words.form.success'}}</span>
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<label class="btn {{if addDisabled 'disabled'}}">
|
||||||
|
{{d-icon "upload"}}
|
||||||
|
{{i18n 'admin.watched_words.form.upload'}}
|
||||||
|
<input disabled={{addDisabled}} type="file" accept="text/plain,text/csv" style="visibility: hidden; position: absolute;" />
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
<span class="instructions">One word per line</span>
|
|
@ -5,13 +5,13 @@
|
||||||
{{#unless model.theme_id}}
|
{{#unless model.theme_id}}
|
||||||
<button {{action "save"}} disabled={{model.disableSave}} class='btn'>{{i18n 'admin.customize.save'}}</button>
|
<button {{action "save"}} disabled={{model.disableSave}} class='btn'>{{i18n 'admin.customize.save'}}</button>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
<button {{action "copy" model}} class='btn'><i class="fa fa-copy"></i> {{i18n 'admin.customize.copy'}}</button>
|
<button {{action "copy" model}} class='btn'>{{d-icon "copy"}} {{i18n 'admin.customize.copy'}}</button>
|
||||||
<button {{action "copyToClipboard" model}} class='btn'><i class="fa fa-clipboard"></i> {{i18n 'admin.customize.copy_to_clipboard'}}</button>
|
<button {{action "copyToClipboard" model}} class='btn'>{{d-icon "clipboard"}} {{i18n 'admin.customize.copy_to_clipboard'}}</button>
|
||||||
{{#if model.theme_id}}
|
{{#if model.theme_id}}
|
||||||
{{i18n "admin.customize.theme_owner"}}
|
{{i18n "admin.customize.theme_owner"}}
|
||||||
{{#link-to "adminCustomizeThemes.show" model.theme_id}}{{model.theme_name}}{{/link-to}}
|
{{#link-to "adminCustomizeThemes.show" model.theme_id}}{{model.theme_name}}{{/link-to}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<button {{action "destroy"}} class='btn btn-danger'><i class="fa fa-trash-o"></i> {{i18n 'admin.customize.delete'}}</button>
|
<button {{action "destroy"}} class='btn btn-danger'>{{d-icon "trash-o"}} {{i18n 'admin.customize.delete'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<span class="saving {{unless model.savingStatus 'hidden'}}">{{model.savingStatus}}</span>
|
<span class="saving {{unless model.savingStatus 'hidden'}}">{{model.savingStatus}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
{{#each model as |scheme|}}
|
{{#each model as |scheme|}}
|
||||||
{{#unless scheme.is_base}}
|
{{#unless scheme.is_base}}
|
||||||
<li>
|
<li>
|
||||||
{{#link-to 'adminCustomize.colors.show' scheme replace=true}}{{fa-icon 'paint-brush'}}{{scheme.description}}{{/link-to}}
|
{{#link-to 'adminCustomize.colors.show' scheme replace=true}}{{d-icon 'paint-brush'}}{{scheme.description}}{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
<button {{action "newColorScheme"}} class='btn'>{{fa-icon 'plus'}}{{i18n 'admin.customize.new'}}</button>
|
<button {{action "newColorScheme"}} class='btn'>{{d-icon 'plus'}}{{i18n 'admin.customize.new'}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<li>
|
<li>
|
||||||
{{#link-to 'adminCustomizeThemes.edit' model.id 'desktop' fieldName replace=true title=field.title}}
|
{{#link-to 'adminCustomizeThemes.edit' model.id 'desktop' fieldName replace=true title=field.title}}
|
||||||
{{i18n 'admin.customize.theme.desktop'}}
|
{{i18n 'admin.customize.theme.desktop'}}
|
||||||
{{fa-icon 'desktop'}}
|
{{d-icon 'desktop'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<li class='mobile'>
|
<li class='mobile'>
|
||||||
{{#link-to 'adminCustomizeThemes.edit' model.id 'mobile' fieldName replace=true title=field.title}}
|
{{#link-to 'adminCustomizeThemes.edit' model.id 'mobile' fieldName replace=true title=field.title}}
|
||||||
{{i18n 'admin.customize.theme.mobile'}}
|
{{i18n 'admin.customize.theme.mobile'}}
|
||||||
{{fa-icon 'mobile'}}
|
{{d-icon 'mobile'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -46,14 +46,14 @@
|
||||||
{{#each fields as |field|}}
|
{{#each fields as |field|}}
|
||||||
<li>
|
<li>
|
||||||
{{#link-to 'adminCustomizeThemes.edit' model.id currentTargetName field.name replace=true title=field.title}}
|
{{#link-to 'adminCustomizeThemes.edit' model.id currentTargetName field.name replace=true title=field.title}}
|
||||||
{{#if field.icon}}{{fa-icon field.icon}} {{/if}}
|
{{#if field.icon}}{{d-icon field.icon}} {{/if}}
|
||||||
{{i18n field.key}}
|
{{i18n field.key}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
<li class='toggle-maximize'>
|
<li class='toggle-maximize'>
|
||||||
<a {{action "toggleMaximize"}}>
|
<a {{action "toggleMaximize"}}>
|
||||||
<i class="fa fa-{{maximizeIcon}}"></i>
|
{{d-icon maximizeIcon}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{{d-button action="finishedEditingName" class="btn-primary btn-small submit-edit" icon="check"}}
|
{{d-button action="finishedEditingName" class="btn-primary btn-small submit-edit" icon="check"}}
|
||||||
{{d-button action="cancelEditingName" class="btn-small cancel-edit" icon="times"}}
|
{{d-button action="cancelEditingName" class="btn-small cancel-edit" icon="times"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{model.name}} <a {{action "startEditingName"}}>{{fa-icon "pencil"}}</a>
|
{{model.name}} <a {{action "startEditingName"}}>{{d-icon "pencil"}}</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</p>
|
</p>
|
||||||
{{#if model.remote_theme.license_url}}
|
{{#if model.remote_theme.license_url}}
|
||||||
<p>
|
<p>
|
||||||
<a href="{{model.remote_theme.license_url}}">{{i18n "admin.customize.theme.license"}} {{fa-icon "copyright"}}</a>
|
<a href="{{model.remote_theme.license_url}}">{{i18n "admin.customize.theme.license"}} {{d-icon "copyright"}}</a>
|
||||||
</p>
|
</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -133,8 +133,8 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<a href='{{previewUrl}}' title="{{i18n 'admin.customize.explain_preview'}}" target='_blank' class='btn'>{{fa-icon 'desktop'}}{{i18n 'admin.customize.theme.preview'}}</a>
|
<a href='{{previewUrl}}' title="{{i18n 'admin.customize.explain_preview'}}" target='_blank' class='btn'>{{d-icon 'desktop'}}{{i18n 'admin.customize.theme.preview'}}</a>
|
||||||
<a class="btn export" target="_blank" href={{downloadUrl}}>{{fa-icon "download"}} {{i18n 'admin.export_json.button_text'}}</a>
|
<a class="btn export" target="_blank" href={{downloadUrl}}>{{d-icon "download"}} {{i18n 'admin.export_json.button_text'}}</a>
|
||||||
|
|
||||||
{{d-button action="destroy" label="admin.customize.delete" icon="trash" class="btn-danger"}}
|
{{d-button action="destroy" label="admin.customize.delete" icon="trash" class="btn-danger"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
{{#link-to 'adminCustomizeThemes.show' theme replace=true}}
|
{{#link-to 'adminCustomizeThemes.show' theme replace=true}}
|
||||||
{{theme.name}}
|
{{theme.name}}
|
||||||
{{#if theme.user_selectable}}
|
{{#if theme.user_selectable}}
|
||||||
{{fa-icon "user"}}
|
{{d-icon "user"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if theme.default}}
|
{{#if theme.default}}
|
||||||
{{fa-icon "asterisk"}}
|
{{d-icon "asterisk"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -29,15 +29,15 @@
|
||||||
<div class="dashboard-stats totals">
|
<div class="dashboard-stats totals">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="title">{{fa-icon "shield"}} {{i18n 'admin.dashboard.admins'}}</td>
|
<td class="title">{{d-icon "shield"}} {{i18n 'admin.dashboard.admins'}}</td>
|
||||||
<td class="value">{{#link-to 'adminUsersList.show' 'admins'}}{{admins}}{{/link-to}}</td>
|
<td class="value">{{#link-to 'adminUsersList.show' 'admins'}}{{admins}}{{/link-to}}</td>
|
||||||
<td class="title">{{fa-icon "ban"}} {{i18n 'admin.dashboard.suspended'}}</td>
|
<td class="title">{{d-icon "ban"}} {{i18n 'admin.dashboard.suspended'}}</td>
|
||||||
<td class="value">{{#link-to 'adminUsersList.show' 'suspended'}}{{suspended}}{{/link-to}}</td>
|
<td class="value">{{#link-to 'adminUsersList.show' 'suspended'}}{{suspended}}{{/link-to}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="title">{{fa-icon "shield"}} {{i18n 'admin.dashboard.moderators'}}</td>
|
<td class="title">{{d-icon "shield"}} {{i18n 'admin.dashboard.moderators'}}</td>
|
||||||
<td class="value">{{#link-to 'adminUsersList.show' 'moderators'}}{{moderators}}{{/link-to}}</td>
|
<td class="value">{{#link-to 'adminUsersList.show' 'moderators'}}{{moderators}}{{/link-to}}</td>
|
||||||
<td class="title">{{fa-icon "ban"}} {{i18n 'admin.dashboard.blocked'}}</td>
|
<td class="title">{{d-icon "ban"}} {{i18n 'admin.dashboard.blocked'}}</td>
|
||||||
<td class="value">{{#link-to 'adminUsersList.show' 'blocked'}}{{blocked}}{{/link-to}}</td>
|
<td class="value">{{#link-to 'adminUsersList.show' 'blocked'}}{{blocked}}{{/link-to}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
<table class="table table-condensed table-hover">
|
<table class="table table-condensed table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="title" title="{{i18n 'admin.dashboard.private_messages_title'}}">{{fa-icon "envelope"}} {{i18n 'admin.dashboard.private_messages_short'}}</th>
|
<th class="title" title="{{i18n 'admin.dashboard.private_messages_title'}}">{{d-icon "envelope"}} {{i18n 'admin.dashboard.private_messages_short'}}</th>
|
||||||
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
<th>{{i18n 'admin.dashboard.reports.today'}}</th>
|
||||||
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
<th>{{i18n 'admin.dashboard.reports.yesterday'}}</th>
|
||||||
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
<th>{{i18n 'admin.dashboard.reports.last_7_days'}}</th>
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
<div class="dashboard-right">
|
<div class="dashboard-right">
|
||||||
{{#if foundProblems}}
|
{{#if foundProblems}}
|
||||||
<div class="dashboard-stats detected-problems">
|
<div class="dashboard-stats detected-problems">
|
||||||
<div class="look-here">{{fa-icon "exclamation-triangle"}}</div>
|
<div class="look-here">{{d-icon "exclamation-triangle"}}</div>
|
||||||
<div class="problem-messages">
|
<div class="problem-messages">
|
||||||
{{#conditional-loading-spinner condition=loadingProblems}}
|
{{#conditional-loading-spinner condition=loadingProblems}}
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{#if l.bounced}}{{fa-icon "repeat" title="admin.email.bounced"}}{{/if}}
|
{{#if l.bounced}}{{d-icon "repeat" title="admin.email.bounced"}}{{/if}}
|
||||||
<a href='mailto:{{unbound l.to_address}}'>{{l.to_address}}</a>
|
<a href='mailto:{{unbound l.to_address}}'>{{l.to_address}}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>{{l.email_type}}</td>
|
<td>{{l.email_type}}</td>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th><img class="emoji emoji-custom" src="{{unbound e.url}}" title="{{unbound e.name}}"></th>
|
<th><img class="emoji emoji-custom" src="{{unbound e.url}}" title="{{unbound e.name}}"></th>
|
||||||
<th>:{{e.name}}:</th>
|
<th>:{{e.name}}:</th>
|
||||||
<th><button {{action "destroy" e}} class='btn btn-danger no-text pull-right'>{{fa-icon 'trash-o'}} </button></th>
|
<th><button {{action "destroy" e}} class='btn btn-danger no-text pull-right'>{{d-icon 'trash-o'}} </button></th>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
{{#if flaggedPost.postAuthorFlagged}}
|
{{#if flaggedPost.postAuthorFlagged}}
|
||||||
{{#if flaggedPost.user}}
|
{{#if flaggedPost.user}}
|
||||||
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="large"}}{{/link-to}}
|
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="large"}}{{/link-to}}
|
||||||
{{#if flaggedPost.wasEdited}}<i class="fa fa-pencil" title="{{i18n 'admin.flags.was_edited'}}"></i>{{/if}}
|
{{#if flaggedPost.wasEdited}}
|
||||||
|
{{d-icon "pencil" title="admin.flags.was_edited"}}
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if adminActiveFlagsView}}
|
{{#if adminActiveFlagsView}}
|
||||||
|
@ -31,7 +33,7 @@
|
||||||
<div class="topic-excerpt">
|
<div class="topic-excerpt">
|
||||||
<h3>
|
<h3>
|
||||||
{{#if flaggedPost.topic.isPrivateMessage}}
|
{{#if flaggedPost.topic.isPrivateMessage}}
|
||||||
<span class="private-message-glyph">{{fa-icon "envelope"}}</span>
|
<span class="private-message-glyph">{{d-icon "envelope"}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{topic-status topic=flaggedPost.topic}}
|
{{topic-status topic=flaggedPost.topic}}
|
||||||
<a href='{{unbound flaggedPost.url}}'>{{{unbound flaggedPost.topic.fancyTitle}}}</a>
|
<a href='{{unbound flaggedPost.url}}'>{{{unbound flaggedPost.topic.fancyTitle}}}</a>
|
||||||
|
@ -90,7 +92,7 @@
|
||||||
{{format-age flagger.disposedAt}}
|
{{format-age flagger.disposedAt}}
|
||||||
{{{flagger.dispositionIcon}}}
|
{{{flagger.dispositionIcon}}}
|
||||||
{{#if flagger.tookAction}}
|
{{#if flagger.tookAction}}
|
||||||
<i class='fa fa-gavel' title='{{i18n 'admin.flags.took_action'}}'></i>
|
{{d-icon "gavel" title="admin.flags.took_action"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -129,7 +131,8 @@
|
||||||
</p>
|
</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<a href="{{unbound c.permalink}}">
|
<a href="{{unbound c.permalink}}">
|
||||||
<button class='btn btn-reply'><i class="fa fa-reply"></i> {{i18n 'admin.flags.reply_message'}}</button>
|
<button class='btn btn-reply'>{{d-icon "reply"}} {{i18n 'admin.flags.reply_message'}}</button>
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -141,14 +144,14 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="action">
|
<td colspan="3" class="action">
|
||||||
{{#if adminActiveFlagsView}}
|
{{#if adminActiveFlagsView}}
|
||||||
<button title='{{i18n 'admin.flags.agree_title'}}' class='btn' {{action "showAgreeFlagModal" flaggedPost}}><i class="fa fa-thumbs-o-up"></i>{{i18n 'admin.flags.agree'}}…</button>
|
<button title='{{i18n 'admin.flags.agree_title'}}' class='btn' {{action "showAgreeFlagModal" flaggedPost}}>{{d-icon "thumbs-o-up"}}{{i18n 'admin.flags.agree'}}…</button>
|
||||||
{{#if flaggedPost.postHidden}}
|
{{#if flaggedPost.postHidden}}
|
||||||
<button title='{{i18n 'admin.flags.disagree_flag_unhide_post_title'}}' class='btn' {{action "disagreeFlags" flaggedPost}}><i class="fa fa-thumbs-o-down"></i>{{i18n 'admin.flags.disagree_flag_unhide_post'}}</button>
|
<button title='{{i18n 'admin.flags.disagree_flag_unhide_post_title'}}' class='btn' {{action "disagreeFlags" flaggedPost}}>{{d-icon "thumbs-o-down"}}{{i18n 'admin.flags.disagree_flag_unhide_post'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<button title='{{i18n 'admin.flags.disagree_flag_title'}}' class='btn' {{action "disagreeFlags" flaggedPost}}><i class="fa fa-thumbs-o-down"></i>{{i18n 'admin.flags.disagree_flag'}}</button>
|
<button title='{{i18n 'admin.flags.disagree_flag_title'}}' class='btn' {{action "disagreeFlags" flaggedPost}}>{{d-icon "thumbs-o-down"}}{{i18n 'admin.flags.disagree_flag'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<button title='{{i18n 'admin.flags.defer_flag_title'}}' class='btn' {{action "deferFlags" flaggedPost}}><i class="fa fa-external-link"></i>{{i18n 'admin.flags.defer_flag'}}</button>
|
<button title='{{i18n 'admin.flags.defer_flag_title'}}' class='btn' {{action "deferFlags" flaggedPost}}>{{d-icon "external-link"}}{{i18n 'admin.flags.defer_flag'}}</button>
|
||||||
<button title='{{i18n 'admin.flags.delete_title'}}' class='btn btn-danger' {{action "showDeleteFlagModal" flaggedPost}}><i class="fa fa-trash-o"></i>{{i18n 'admin.flags.delete'}}…</button>
|
<button title='{{i18n 'admin.flags.delete_title'}}' class='btn btn-danger' {{action "showDeleteFlagModal" flaggedPost}}>{{d-icon "trash-o"}}{{i18n 'admin.flags.delete'}}…</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -9,19 +9,18 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if model.id}}
|
{{#unless model.automatic}}
|
||||||
{{#unless model.automatic}}
|
<div>
|
||||||
<div>
|
<label for='full_name'>{{i18n 'groups.edit.full_name'}}</label>
|
||||||
<label for='full_name'>{{i18n 'groups.edit.full_name'}}</label>
|
{{input type='text' name='full_name' value=model.full_name class='group-edit-full-name'}}
|
||||||
{{input type='text' name='full_name' value=model.full_name class='group-edit-full-name'}}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="bio">{{i18n 'groups.bio'}}</label>
|
<label for="bio">{{i18n 'groups.bio'}}</label>
|
||||||
{{d-editor value=model.bio_raw}}
|
{{d-editor value=model.bio_raw}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if model.hasOwners}}
|
{{#if model.hasOwners}}
|
||||||
<div>
|
<div>
|
||||||
<label for='owner-list'>{{i18n 'admin.groups.group_owners'}}</label>
|
<label for='owner-list'>{{i18n 'admin.groups.group_owners'}}</label>
|
||||||
<div class="ac-wrap clearfix" id='owner-list'>
|
<div class="ac-wrap clearfix" id='owner-list'>
|
||||||
|
@ -30,31 +29,55 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div>
|
|
||||||
<label for="owner-selector">{{i18n 'admin.groups.add_owners'}}</label>
|
|
||||||
{{user-selector usernames=model.ownerUsernames placeholderKey="admin.groups.selector_placeholder" id="owner-selector"}}
|
|
||||||
{{d-button action="addOwners" class="add" icon="plus" label="admin.groups.add"}}
|
|
||||||
</div>
|
|
||||||
{{/unless}}
|
|
||||||
<div>
|
<div>
|
||||||
{{group-members-input model=model}}
|
<label for="owner-selector">{{i18n 'admin.groups.add_owners'}}</label>
|
||||||
|
|
||||||
|
{{user-selector usernames=model.ownerUsernames
|
||||||
|
placeholderKey="admin.groups.selector_placeholder"
|
||||||
|
id="owner-selector"}}
|
||||||
|
|
||||||
|
{{#if model.id}}
|
||||||
|
{{d-button
|
||||||
|
action="addOwners"
|
||||||
|
class="add"
|
||||||
|
icon="plus"
|
||||||
|
label="admin.groups.add"}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/unless}}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{group-members-input model=model addButton=model.id}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="visiblity">{{i18n 'groups.visibility_levels.title'}}</label>
|
<label for="visiblity">{{i18n 'groups.visibility_levels.title'}}</label>
|
||||||
{{combo-box name="alias" valueAttribute="value" value=model.visibility_level content=visibilityLevelOptions}}
|
{{combo-box name="alias"
|
||||||
|
valueAttribute="value"
|
||||||
|
value=model.visibility_level
|
||||||
|
content=visibilityLevelOptions
|
||||||
|
castInteger=true}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#unless model.automatic}}
|
{{#unless model.automatic}}
|
||||||
<div>
|
<div>
|
||||||
<label>
|
<label>
|
||||||
{{input type="checkbox"
|
{{input type="checkbox"
|
||||||
checked=model.public
|
checked=model.public_admission
|
||||||
disabled=disablePublicSetting}}
|
disabled=disablePublicSetting}}
|
||||||
|
|
||||||
{{i18n 'groups.public'}}
|
{{i18n 'groups.public_admission'}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
{{input type='checkbox'
|
||||||
|
checked=model.public_exit}}
|
||||||
|
|
||||||
|
{{i18n 'groups.public_exit'}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -123,7 +146,7 @@
|
||||||
<div class='buttons'>
|
<div class='buttons'>
|
||||||
<button {{action "save"}} disabled={{disableSave}} class='btn btn-primary'>{{i18n 'admin.customize.save'}}</button>
|
<button {{action "save"}} disabled={{disableSave}} class='btn btn-primary'>{{i18n 'admin.customize.save'}}</button>
|
||||||
{{#unless model.automatic}}
|
{{#unless model.automatic}}
|
||||||
<button {{action "destroy"}} class='btn btn-danger'>{{fa-icon "trash-o"}}{{i18n 'admin.customize.delete'}}</button>
|
<button {{action "destroy"}} class='btn btn-danger'>{{d-icon "trash-o"}}{{i18n 'admin.customize.delete'}}</button>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
<span class="saving {{unless savingStatus 'hidden'}}">{{savingStatus}}</span>
|
<span class="saving {{unless savingStatus 'hidden'}}">{{savingStatus}}</span>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{#link-to 'adminGroup' 'new' class="btn"}}
|
{{#link-to 'adminGroup' 'new' class="btn"}}
|
||||||
{{fa-icon "plus"}} {{i18n 'admin.groups.new'}}
|
{{d-icon "plus"}} {{i18n 'admin.groups.new'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
{{d-button action="refreshAutoGroups" icon="refresh" label="admin.groups.refresh" disabled=refreshingAutoGroups}}
|
{{d-button action="refreshAutoGroups" icon="refresh" label="admin.groups.refresh" disabled=refreshingAutoGroups}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#link-to 'adminGroup' 'new' class="btn"}}
|
{{#link-to 'adminGroup' 'new' class="btn"}}
|
||||||
{{fa-icon "plus"}} {{i18n 'admin.groups.new'}}
|
{{d-icon "plus"}} {{i18n 'admin.groups.new'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<p>
|
<p>
|
||||||
{{i18n 'admin.logs.screened_emails.description'}}
|
{{i18n 'admin.logs.screened_emails.description'}}
|
||||||
<button class="btn pull-right" {{action "exportScreenedEmailList"}} title="{{i18n 'admin.export_csv.button_title.screened_email'}}">{{fa-icon "download"}}{{i18n 'admin.export_csv.button_text'}}</button>
|
<button class="btn pull-right" {{action "exportScreenedEmailList"}} title="{{i18n 'admin.export_csv.button_title.screened_email'}}">{{d-icon "download"}}{{i18n 'admin.export_csv.button_text'}}</button>
|
||||||
</p>
|
</p>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col action">
|
<div class="col action">
|
||||||
{{#if item.isBlocked}}
|
{{#if item.isBlocked}}
|
||||||
{{fa-icon "ban"}}
|
{{d-icon "ban"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{fa-icon "check"}}
|
{{d-icon "check"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{item.actionName}}
|
{{item.actionName}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<p>
|
<p>
|
||||||
{{i18n 'admin.logs.screened_urls.description'}}
|
{{i18n 'admin.logs.screened_urls.description'}}
|
||||||
<button class="btn pull-right" {{action "exportScreenedUrlList"}} title="{{i18n 'admin.export_csv.button_title.screened_url'}}">{{fa-icon "download"}}{{i18n 'admin.export_csv.button_text'}}</button>
|
<button class="btn pull-right" {{action "exportScreenedUrlList"}} title="{{i18n 'admin.export_csv.button_title.screened_url'}}">{{d-icon "download"}}{{i18n 'admin.export_csv.button_text'}}</button>
|
||||||
</p>
|
</p>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
|
@ -7,25 +7,25 @@
|
||||||
{{#if actionFilter}}
|
{{#if actionFilter}}
|
||||||
<a {{action "clearFilter" "actionFilter"}} class="filter">
|
<a {{action "clearFilter" "actionFilter"}} class="filter">
|
||||||
<span class="label">{{i18n 'admin.logs.action'}}</span>: {{actionFilter}}
|
<span class="label">{{i18n 'admin.logs.action'}}</span>: {{actionFilter}}
|
||||||
{{fa-icon "times-circle"}}
|
{{d-icon "times-circle"}}
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if filters.acting_user}}
|
{{#if filters.acting_user}}
|
||||||
<a {{action "clearFilter" "acting_user"}} class="filter">
|
<a {{action "clearFilter" "acting_user"}} class="filter">
|
||||||
<span class="label">{{i18n 'admin.logs.staff_actions.staff_user'}}</span>: {{filters.acting_user}}
|
<span class="label">{{i18n 'admin.logs.staff_actions.staff_user'}}</span>: {{filters.acting_user}}
|
||||||
{{fa-icon "times-circle"}}
|
{{d-icon "times-circle"}}
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if filters.target_user}}
|
{{#if filters.target_user}}
|
||||||
<a {{action "clearFilter" "target_user"}} class="filter">
|
<a {{action "clearFilter" "target_user"}} class="filter">
|
||||||
<span class="label">{{i18n 'admin.logs.staff_actions.target_user'}}</span>: {{filters.target_user}}
|
<span class="label">{{i18n 'admin.logs.staff_actions.target_user'}}</span>: {{filters.target_user}}
|
||||||
{{fa-icon "times-circle"}}
|
{{d-icon "times-circle"}}
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if filters.subject}}
|
{{#if filters.subject}}
|
||||||
<a {{action "clearFilter" "subject"}} class="filter">
|
<a {{action "clearFilter" "subject"}} class="filter">
|
||||||
<span class="label">{{i18n 'admin.logs.staff_actions.subject'}}</span>: {{filters.subject}}
|
<span class="label">{{i18n 'admin.logs.staff_actions.subject'}}</span>: {{filters.subject}}
|
||||||
{{fa-icon "times-circle"}}
|
{{d-icon "times-circle"}}
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{{#d-modal-body title="admin.flags.agree_flag_modal_title"}}
|
{{#d-modal-body title="admin.flags.agree_flag_modal_title"}}
|
||||||
{{#if model.user_deleted}}
|
{{#if model.user_deleted}}
|
||||||
<button title="{{i18n 'admin.flags.agree_flag_restore_post_title'}}" {{action "agreeFlagRestorePost"}} class="btn"><i class="fa fa-thumbs-o-up"></i><i class="fa fa-eye"></i>{{i18n 'admin.flags.agree_flag_restore_post'}}</button>
|
<button title={{i18n 'admin.flags.agree_flag_restore_post_title'}} {{action "agreeFlagRestorePost"}} class="btn">{{d-icon "thumbs-o-up"}}{{d-icon "eye"}}{{i18n 'admin.flags.agree_flag_restore_post'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#unless model.postHidden}}
|
{{#unless model.postHidden}}
|
||||||
<button title="{{i18n 'admin.flags.agree_flag_hide_post_title'}}" {{action "agreeFlagHidePost"}} class="btn"><i class="fa fa-thumbs-o-up"></i><i class="fa fa-eye-slash"></i>{{i18n 'admin.flags.agree_flag_hide_post'}}</button>
|
<button title="{{i18n 'admin.flags.agree_flag_hide_post_title'}}" {{action "agreeFlagHidePost"}} class="btn">{{d-icon "thumbs-o-up"}}{{d-icon "eye-slash"}}{{i18n 'admin.flags.agree_flag_hide_post'}}</button>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<button title="{{i18n 'admin.flags.agree_flag_title'}}" {{action "agreeFlagKeepPost"}} class="btn"><i class="fa fa-thumbs-o-up"></i>{{i18n 'admin.flags.agree_flag'}}</button>
|
<button title="{{i18n 'admin.flags.agree_flag_title'}}" {{action "agreeFlagKeepPost"}} class="btn">{{d-icon "thumbs-o-up"}}{{i18n 'admin.flags.agree_flag'}}</button>
|
||||||
{{#if model.canDeleteAsSpammer}}
|
{{#if model.canDeleteAsSpammer}}
|
||||||
<button title="{{i18n 'admin.flags.delete_spammer_title'}}" {{action "deleteSpammer" model.user}} class="btn btn-danger"><i class="fa fa-exclamation-triangle"></i>{{i18n 'admin.flags.delete_spammer'}}</button>
|
<button title="{{i18n 'admin.flags.delete_spammer_title'}}" {{action "deleteSpammer" model.user}} class="btn btn-danger">{{d-icon "exclamation-triangle"}}{{i18n 'admin.flags.delete_spammer'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/d-modal-body}}
|
{{/d-modal-body}}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
{{#if count_warning}}
|
{{#if count_warning}}
|
||||||
<div class="count-warning">
|
<div class="count-warning">
|
||||||
<p class="heading"><i class="fa fa-warning"></i> {{i18n 'admin.badges.preview.bad_count_warning.header'}}</p>
|
<p class="heading">{{d-icon "warning"}} {{i18n 'admin.badges.preview.bad_count_warning.header'}}</p>
|
||||||
<p class="body">{{i18n 'admin.badges.preview.bad_count_warning.text'}}</p>
|
<p class="body">{{i18n 'admin.badges.preview.bad_count_warning.text'}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
valueAttribute="base_scheme_id"}}
|
valueAttribute="base_scheme_id"}}
|
||||||
{{/d-modal-body}}
|
{{/d-modal-body}}
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class='btn btn-primary' {{action "selectBase"}}>{{fa-icon 'plus'}}{{i18n 'admin.customize.new'}}</button>
|
<button class='btn btn-primary' {{action "selectBase"}}>{{d-icon 'plus'}}{{i18n 'admin.customize.new'}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{{#d-modal-body title="admin.flags.delete_flag_modal_title"}}
|
{{#d-modal-body title="admin.flags.delete_flag_modal_title"}}
|
||||||
<button title="{{i18n 'admin.flags.delete_post_defer_flag_title'}}" {{action "deletePostDeferFlag"}} class="btn"><i class="fa fa-trash-o"></i><i class="fa fa-external-link"></i>{{i18n 'admin.flags.delete_post_defer_flag'}}</button>
|
<button title="{{i18n 'admin.flags.delete_post_defer_flag_title'}}" {{action "deletePostDeferFlag"}} class="btn">{{d-icon "trash-o"}}{{d-icon "external-link"}}{{i18n 'admin.flags.delete_post_defer_flag'}}</button>
|
||||||
<button title="{{i18n 'admin.flags.delete_post_agree_flag_title'}}" {{action "deletePostAgreeFlag"}} class="btn"><i class="fa fa-trash-o"></i><i class="fa fa-thumbs-o-up"></i>{{i18n 'admin.flags.delete_post_agree_flag'}}</button>
|
<button title="{{i18n 'admin.flags.delete_post_agree_flag_title'}}" {{action "deletePostAgreeFlag"}} class="btn">{{d-icon "trash-o"}}{{d-icon "thumbs-o-up"}}{{i18n 'admin.flags.delete_post_agree_flag'}}</button>
|
||||||
{{#if model.canDeleteAsSpammer}}
|
{{#if model.canDeleteAsSpammer}}
|
||||||
<button title="{{i18n 'admin.flags.delete_spammer_title'}}" {{action "deleteSpammer" model.user}} class="btn btn-danger"><i class="fa fa-exclamation-triangle"></i>{{i18n 'admin.flags.delete_spammer'}}</button>
|
<button title="{{i18n 'admin.flags.delete_spammer_title'}}" {{action "deleteSpammer" model.user}} class="btn btn-danger">{{d-icon "exclamation-triangle"}}{{i18n 'admin.flags.delete_spammer'}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/d-modal-body}}
|
{{/d-modal-body}}
|
||||||
|
|
|
@ -5,15 +5,15 @@
|
||||||
<li>
|
<li>
|
||||||
{{#if wc.editing}}
|
{{#if wc.editing}}
|
||||||
{{input value=wc.name}}
|
{{input value=wc.name}}
|
||||||
<button {{action "save" wc}} class="btn no-text">{{fa-icon 'check'}}</button>
|
<button {{action "save" wc}} class="btn no-text">{{d-icon 'check'}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{wc.displayName}}
|
{{wc.displayName}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class='actions'>
|
<div class='actions'>
|
||||||
<button {{action "edit" wc}} class="btn no-text" disabled={{wc.system}}>{{fa-icon 'pencil'}}</button>
|
<button {{action "edit" wc}} class="btn no-text" disabled={{wc.system}}>{{d-icon 'pencil'}}</button>
|
||||||
<button {{action "up" wc}} class="btn no-text">{{fa-icon 'toggle-up'}}</button>
|
<button {{action "up" wc}} class="btn no-text">{{d-icon 'toggle-up'}}</button>
|
||||||
<button {{action "down" wc}} class="btn no-text">{{fa-icon 'toggle-down'}}</button>
|
<button {{action "down" wc}} class="btn no-text">{{d-icon 'toggle-down'}}</button>
|
||||||
<button {{action "delete" wc}} class="btn no-text btn-danger" disabled={{wc.system}}>{{fa-icon 'times'}}</button>
|
<button {{action "delete" wc}} class="btn no-text btn-danger" disabled={{wc.system}}>{{d-icon 'times'}}</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -11,6 +11,6 @@
|
||||||
{{/d-modal-body}}
|
{{/d-modal-body}}
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class='btn btn-danger' {{action "suspend"}} disabled={{submitDisabled}}><i class='fa fa-ban'></i>{{i18n 'admin.user.suspend'}}</button>
|
<button class='btn btn-danger' {{action "suspend"}} disabled={{submitDisabled}}>{{d-icon "ban"}}{{i18n 'admin.user.suspend'}}</button>
|
||||||
<a {{action "closeModal"}}>{{i18n 'cancel'}}</a>
|
<a {{action "closeModal"}}>{{i18n 'cancel'}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
{{/save-controls}}
|
{{/save-controls}}
|
||||||
|
|
||||||
{{#link-to 'adminSiteText.index' class="go-back"}}
|
{{#link-to 'adminSiteText.index' class="go-back"}}
|
||||||
{{fa-icon 'arrow-left'}}
|
{{d-icon 'arrow-left'}}
|
||||||
{{i18n 'admin.site_text.go_back'}}
|
{{i18n 'admin.site_text.go_back'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class='admin-controls'>
|
<div class='admin-controls'>
|
||||||
<div class='span15'>
|
<div class='span15'>
|
||||||
<ul class='nav nav-pills'>
|
<ul class='nav nav-pills'>
|
||||||
<li>{{#link-to 'adminUser' user}}<i class="fa fa-caret-left"></i> {{user.username}}{{/link-to}}</li>
|
<li>{{#link-to 'adminUser' user}}{{d-icon "caret-left"}} {{user.username}}{{/link-to}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class='user-controls'>
|
<div class='user-controls'>
|
||||||
{{#if model.canViewProfile}}
|
{{#if model.canViewProfile}}
|
||||||
{{#link-to 'user' model class="btn"}}
|
{{#link-to 'user' model class="btn"}}
|
||||||
{{fa-icon "user"}}
|
{{d-icon "user"}}
|
||||||
{{i18n 'admin.user.show_public_profile'}}
|
{{i18n 'admin.user.show_public_profile'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
{{i18n 'badges.badge_count' count=model.badge_count}}
|
{{i18n 'badges.badge_count' count=model.badge_count}}
|
||||||
</div>
|
</div>
|
||||||
<div class='controls'>
|
<div class='controls'>
|
||||||
{{#link-to 'adminUser.badges' model class="btn"}}{{fa-icon "certificate"}}{{i18n 'admin.badges.edit_badges'}}{{/link-to}}
|
{{#link-to 'adminUser.badges' model class="btn"}}{{d-icon "certificate"}}{{i18n 'admin.badges.edit_badges'}}{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -281,9 +281,11 @@
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{#if model.canLockTrustLevel}}
|
{{#if model.canLockTrustLevel}}
|
||||||
{{#if model.trust_level_locked}}
|
{{#if model.trust_level_locked}}
|
||||||
<i title='{{i18n 'admin.user.trust_level_locked_tip'}}' class='fa fa-lock'></i> {{d-button action="lockTrustLevel" actionParam=false label="admin.user.unlock_trust_level"}}
|
{{d-icon "lock" title="admin.user.trust_level_locked_tip"}}
|
||||||
|
{{d-button action="lockTrustLevel" actionParam=false label="admin.user.unlock_trust_level"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<i title='{{i18n 'admin.user.trust_level_unlocked_tip'}}' class='fa fa-unlock'></i> {{d-button action="lockTrustLevel" actionParam=true label="admin.user.lock_trust_level"}}
|
{{d-icon "unlock" title="admin.user.trust_level_unlocked_tip"}}
|
||||||
|
{{d-button action="lockTrustLevel" actionParam=true label="admin.user.lock_trust_level"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if model.tl3Requirements}}
|
{{#if model.tl3Requirements}}
|
||||||
|
@ -487,7 +489,7 @@
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
{{fa-icon "exclamation-triangle"}} {{model.deleteExplanation}}
|
{{d-icon "exclamation-triangle"}} {{model.deleteExplanation}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class='admin-controls'>
|
<div class='admin-controls'>
|
||||||
<div class='span15'>
|
<div class='span15'>
|
||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
<li>{{#link-to 'adminUser' model}}<i class="fa fa-caret-left"></i> {{model.username}}{{/link-to}}</li>
|
<li>{{#link-to 'adminUser' model}}{{d-icon "caret-left"}} {{model.username}}{{/link-to}}</li>
|
||||||
<li>{{#link-to 'adminUsersList.show' 'member'}}{{i18n 'admin.user.trust_level_2_users'}}{{/link-to}}</li>
|
<li>{{#link-to 'adminUsersList.show' 'member'}}{{i18n 'admin.user.trust_level_2_users'}}{{/link-to}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.visits'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.visits'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.days_visited 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.days_visited}}</td>
|
||||||
<td>
|
<td>
|
||||||
{{model.tl3Requirements.days_visited_percent}}% ({{model.tl3Requirements.days_visited}} / {{model.tl3Requirements.time_period}} {{i18n 'admin.user.tl3_requirements.days'}})
|
{{model.tl3Requirements.days_visited_percent}}% ({{model.tl3Requirements.days_visited}} / {{model.tl3Requirements.time_period}} {{i18n 'admin.user.tl3_requirements.days'}})
|
||||||
</td>
|
</td>
|
||||||
|
@ -32,67 +32,67 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.topics_replied_to'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.topics_replied_to'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.topics_replied_to 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.topics_replied_to}}</td>
|
||||||
<td>{{model.tl3Requirements.num_topics_replied_to}}</td>
|
<td>{{model.tl3Requirements.num_topics_replied_to}}</td>
|
||||||
<td>{{model.tl3Requirements.min_topics_replied_to}}</td>
|
<td>{{model.tl3Requirements.min_topics_replied_to}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.topics_viewed'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.topics_viewed'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.topics_viewed 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.topics_viewed}}</td>
|
||||||
<td>{{model.tl3Requirements.topics_viewed}}</td>
|
<td>{{model.tl3Requirements.topics_viewed}}</td>
|
||||||
<td>{{model.tl3Requirements.min_topics_viewed}}</td>
|
<td>{{model.tl3Requirements.min_topics_viewed}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.topics_viewed_all_time'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.topics_viewed_all_time'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.topics_viewed_all_time 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.topics_viewed_all_time}}</td>
|
||||||
<td>{{model.tl3Requirements.topics_viewed_all_time}}</td>
|
<td>{{model.tl3Requirements.topics_viewed_all_time}}</td>
|
||||||
<td>{{model.tl3Requirements.min_topics_viewed_all_time}}</td>
|
<td>{{model.tl3Requirements.min_topics_viewed_all_time}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.posts_read'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.posts_read'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.posts_read 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.posts_read}}</td>
|
||||||
<td>{{model.tl3Requirements.posts_read}}</td>
|
<td>{{model.tl3Requirements.posts_read}}</td>
|
||||||
<td>{{model.tl3Requirements.min_posts_read}}</td>
|
<td>{{model.tl3Requirements.min_posts_read}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.posts_read_all_time'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.posts_read_all_time'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.posts_read_all_time 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.posts_read_all_time}}</td>
|
||||||
<td>{{model.tl3Requirements.posts_read_all_time}}</td>
|
<td>{{model.tl3Requirements.posts_read_all_time}}</td>
|
||||||
<td>{{model.tl3Requirements.min_posts_read_all_time}}</td>
|
<td>{{model.tl3Requirements.min_posts_read_all_time}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.flagged_posts'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.flagged_posts'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.flagged_posts 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.flagged_posts}}</td>
|
||||||
<td>{{model.tl3Requirements.num_flagged_posts}}</td>
|
<td>{{model.tl3Requirements.num_flagged_posts}}</td>
|
||||||
<td>{{i18n 'max_of_count' count=model.tl3Requirements.max_flagged_posts}}</td>
|
<td>{{i18n 'max_of_count' count=model.tl3Requirements.max_flagged_posts}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.flagged_by_users'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.flagged_by_users'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.flagged_by_users 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.flagged_by_users}}</td>
|
||||||
<td>{{model.tl3Requirements.num_flagged_by_users}}</td>
|
<td>{{model.tl3Requirements.num_flagged_by_users}}</td>
|
||||||
<td>{{i18n 'max_of_count' count=model.tl3Requirements.max_flagged_by_users}}</td>
|
<td>{{i18n 'max_of_count' count=model.tl3Requirements.max_flagged_by_users}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.likes_given'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.likes_given'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.likes_given 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.likes_given}}</td>
|
||||||
<td>{{model.tl3Requirements.num_likes_given}}</td>
|
<td>{{model.tl3Requirements.num_likes_given}}</td>
|
||||||
<td>{{model.tl3Requirements.min_likes_given}}</td>
|
<td>{{model.tl3Requirements.min_likes_given}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.likes_received'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.likes_received'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.likes_received 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.likes_received}}</td>
|
||||||
<td>{{model.tl3Requirements.num_likes_received}}</td>
|
<td>{{model.tl3Requirements.num_likes_received}}</td>
|
||||||
<td>{{model.tl3Requirements.min_likes_received}}</td>
|
<td>{{model.tl3Requirements.min_likes_received}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.likes_received_days'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.likes_received_days'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.likes_received_days 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.likes_received_days}}</td>
|
||||||
<td>{{model.tl3Requirements.num_likes_received_days}}</td>
|
<td>{{model.tl3Requirements.num_likes_received_days}}</td>
|
||||||
<td>{{model.tl3Requirements.min_likes_received_days}}</td>
|
<td>{{model.tl3Requirements.min_likes_received_days}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.user.tl3_requirements.likes_received_users'}}</th>
|
<th>{{i18n 'admin.user.tl3_requirements.likes_received_users'}}</th>
|
||||||
<td><i class="fa {{if model.tl3Requirements.met.likes_received_users 'fa-check' 'fa-times'}}"></i></td>
|
<td>{{check-icon model.tl3Requirements.met.likes_received_users}}</td>
|
||||||
<td>{{model.tl3Requirements.num_likes_received_users}}</td>
|
<td>{{model.tl3Requirements.num_likes_received_users}}</td>
|
||||||
<td>{{model.tl3Requirements.min_likes_received_users}}</td>
|
<td>{{model.tl3Requirements.min_likes_received_users}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -105,16 +105,16 @@
|
||||||
{{#if model.tl3Requirements.requirements_lost}}
|
{{#if model.tl3Requirements.requirements_lost}}
|
||||||
{{! tl implicitly not locked }}
|
{{! tl implicitly not locked }}
|
||||||
{{#if model.tl3Requirements.on_grace_period}}
|
{{#if model.tl3Requirements.on_grace_period}}
|
||||||
<i class="fa fa-times"></i> {{i18n 'admin.user.tl3_requirements.on_grace_period'}}
|
{{d-icon "times"}} {{i18n 'admin.user.tl3_requirements.on_grace_period'}}
|
||||||
{{else}} {{! not on grace period }}
|
{{else}} {{! not on grace period }}
|
||||||
<i class="fa fa-times"></i> {{i18n 'admin.user.tl3_requirements.does_not_qualify'}}
|
{{d-icon "times"}} {{i18n 'admin.user.tl3_requirements.does_not_qualify'}}
|
||||||
{{i18n 'admin.user.tl3_requirements.will_be_demoted'}}
|
{{i18n 'admin.user.tl3_requirements.will_be_demoted'}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}} {{! requirements not lost - remains tl3 }}
|
{{else}} {{! requirements not lost - remains tl3 }}
|
||||||
{{#if model.tl3Requirements.trust_level_locked}}
|
{{#if model.tl3Requirements.trust_level_locked}}
|
||||||
<i class="fa fa-lock"></i> {{i18n 'admin.user.tl3_requirements.locked_will_not_be_demoted'}}
|
{{d-icon "lock"}} {{i18n 'admin.user.tl3_requirements.locked_will_not_be_demoted'}}
|
||||||
{{else}} {{! tl not locked }}
|
{{else}} {{! tl not locked }}
|
||||||
<i class="fa fa-check"></i> {{i18n 'admin.user.tl3_requirements.qualifies'}}
|
{{d-icon "check"}} {{i18n 'admin.user.tl3_requirements.qualifies'}}
|
||||||
{{#if model.tl3Requirements.on_grace_period}}
|
{{#if model.tl3Requirements.on_grace_period}}
|
||||||
{{i18n 'admin.user.tl3_requirements.on_grace_period'}}
|
{{i18n 'admin.user.tl3_requirements.on_grace_period'}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -123,13 +123,13 @@
|
||||||
{{else}} {{! is not tl3 }}
|
{{else}} {{! is not tl3 }}
|
||||||
{{#if model.tl3Requirements.requirements_met}}
|
{{#if model.tl3Requirements.requirements_met}}
|
||||||
{{! met & not tl3 - will be promoted}}
|
{{! met & not tl3 - will be promoted}}
|
||||||
<i class="fa fa-check"></i> {{i18n 'admin.user.tl3_requirements.qualifies'}}
|
{{d-icon "check"}} {{i18n 'admin.user.tl3_requirements.qualifies'}}
|
||||||
{{i18n 'admin.user.tl3_requirements.will_be_promoted'}}
|
{{i18n 'admin.user.tl3_requirements.will_be_promoted'}}
|
||||||
{{else}} {{! requirements not met - remains regular }}
|
{{else}} {{! requirements not met - remains regular }}
|
||||||
{{#if model.tl3Requirements.trust_level_locked}}
|
{{#if model.tl3Requirements.trust_level_locked}}
|
||||||
<i class="fa fa-lock"></i> {{i18n 'admin.user.tl3_requirements.locked_will_not_be_promoted'}}
|
{{d-icon "lock"}} {{i18n 'admin.user.tl3_requirements.locked_will_not_be_promoted'}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<i class="fa fa-times"></i> {{i18n 'admin.user.tl3_requirements.does_not_qualify'}}
|
{{d-icon "times"}} {{i18n 'admin.user.tl3_requirements.does_not_qualify'}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -92,10 +92,10 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<td>
|
<td>
|
||||||
{{#if user.admin}}
|
{{#if user.admin}}
|
||||||
{{fa-icon "shield" title="admin.title" }}
|
{{d-icon "shield" title="admin.title" }}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if user.moderator}}
|
{{#if user.moderator}}
|
||||||
{{fa-icon "shield" title="admin.moderator" }}
|
{{d-icon "shield" title="admin.moderator" }}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
{{#if versionCheck.noCheckPerformed}}
|
{{#if versionCheck.noCheckPerformed}}
|
||||||
<td class="version-number">—</td>
|
<td class="version-number">—</td>
|
||||||
<td class="face">
|
<td class="face">
|
||||||
<span class="icon critical-updates-available">{{fa-icon "frown-o"}}</span>
|
<span class="icon critical-updates-available">{{d-icon "frown-o"}}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="version-notes">
|
<td class="version-notes">
|
||||||
<span class="normal-note">{{i18n 'admin.dashboard.no_check_performed'}}</span>
|
<span class="normal-note">{{i18n 'admin.dashboard.no_check_performed'}}</span>
|
||||||
|
@ -28,9 +28,9 @@
|
||||||
<td class="version-number">{{#if versionCheck.version_check_pending}}{{dash-if-empty versionCheck.installed_version}}{{/if}}</td>
|
<td class="version-number">{{#if versionCheck.version_check_pending}}{{dash-if-empty versionCheck.installed_version}}{{/if}}</td>
|
||||||
<td class="face">
|
<td class="face">
|
||||||
{{#if versionCheck.version_check_pending}}
|
{{#if versionCheck.version_check_pending}}
|
||||||
<span class='icon up-to-date'>{{fa-icon "smile-o"}}</span>
|
<span class='icon up-to-date'>{{d-icon "smile-o"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="icon critical-updates-available">{{fa-icon "frown-o"}}</span>
|
<span class="icon critical-updates-available">{{d-icon "frown-o"}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td class="version-notes">
|
<td class="version-notes">
|
||||||
|
@ -46,13 +46,13 @@
|
||||||
<td class="version-number">{{dash-if-empty versionCheck.latest_version}}</td>
|
<td class="version-number">{{dash-if-empty versionCheck.latest_version}}</td>
|
||||||
<td class="face">
|
<td class="face">
|
||||||
{{#if versionCheck.upToDate }}
|
{{#if versionCheck.upToDate }}
|
||||||
<span class='icon up-to-date'>{{fa-icon "smile-o"}}</span>
|
<span class='icon up-to-date'>{{d-icon "smile-o"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="icon {{if versionCheck.critical_updates 'critical-updates-available' 'updates-available'}}">
|
<span class="icon {{if versionCheck.critical_updates 'critical-updates-available' 'updates-available'}}">
|
||||||
{{#if versionCheck.behindByOneVersion}}
|
{{#if versionCheck.behindByOneVersion}}
|
||||||
{{fa-icon "meh-o"}}
|
{{d-icon "meh-o"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{fa-icon "frown-o"}}
|
{{d-icon "frown-o"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</span>
|
</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<h2>{{model.name}}</h2>
|
||||||
|
|
||||||
|
<p class="about">{{actionDescription}}</p>
|
||||||
|
|
||||||
|
{{watched-word-form actionKey=actionNameKey action="recordAdded"}}
|
||||||
|
|
||||||
|
{{watched-word-uploader uploading=uploading actionKey=actionNameKey done="uploadComplete"}}
|
||||||
|
|
||||||
|
<div class='clearfix'></div>
|
||||||
|
<div class="watched-words-list">
|
||||||
|
{{#if showWordsList}}
|
||||||
|
{{#each filteredContent as |word| }}
|
||||||
|
<div class="watched-word-box">{{admin-watched-word word=word action="recordRemoved"}}</div>
|
||||||
|
{{/each}}
|
||||||
|
{{else}}
|
||||||
|
{{i18n 'admin.watched_words.word_count' count=model.words.length}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<div class='admin-controls'>
|
||||||
|
<div class='search controls'>
|
||||||
|
<label class="show-words-checkbox">
|
||||||
|
{{input type="checkbox" checked=showWords disabled=disableShowWords}}
|
||||||
|
{{i18n 'admin.watched_words.show_words'}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class='controls'>
|
||||||
|
{{text-field value=filter placeholderKey="admin.watched_words.search" class="no-blur"}}
|
||||||
|
{{d-button action="clearFilter" label="admin.watched_words.clear_filter"}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="admin-nav pull-left">
|
||||||
|
<ul class="nav nav-stacked">
|
||||||
|
{{#each model as |action|}}
|
||||||
|
{{#link-to 'adminWatchedWords.action' action.nameKey tagName='li' class=action.nameKey}}
|
||||||
|
{{#link-to 'adminWatchedWords.action' action.nameKey}}
|
||||||
|
{{action.name}}
|
||||||
|
{{#if action.count}}<span class="count">({{action.count}})</span>{{/if}}
|
||||||
|
{{/link-to}}
|
||||||
|
{{/link-to}}
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="admin-detail pull-left mobile-closed watched-words-detail">
|
||||||
|
{{outlet}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix"></div>
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="web-hook-direction">
|
<div class="web-hook-direction">
|
||||||
{{#link-to 'adminWebHooks' tagName='button' classNames='btn'}}
|
{{#link-to 'adminWebHooks' tagName='button' classNames='btn'}}
|
||||||
{{fa-icon 'list'}} {{i18n 'admin.web_hooks.events.go_list'}}
|
{{d-icon 'list'}} {{i18n 'admin.web_hooks.events.go_list'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
{{d-button icon="send" label="admin.web_hooks.events.ping" action="ping" disabled=pingDisabled}}
|
{{d-button icon="send" label="admin.web_hooks.events.ping" action="ping" disabled=pingDisabled}}
|
||||||
{{#link-to 'adminWebHooks.show' model.extras.web_hook_id tagName='button' classNames='btn'}}
|
{{#link-to 'adminWebHooks.show' model.extras.web_hook_id tagName='button' classNames='btn'}}
|
||||||
{{fa-icon 'edit'}} {{i18n 'admin.web_hooks.events.go_details'}}
|
{{d-icon 'edit'}} {{i18n 'admin.web_hooks.events.go_details'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{#link-to 'adminWebHooks' class="go-back"}}
|
{{#link-to 'adminWebHooks' class="go-back"}}
|
||||||
{{fa-icon 'arrow-left'}}
|
{{d-icon 'arrow-left'}}
|
||||||
{{i18n 'admin.web_hooks.go_back'}}
|
{{i18n 'admin.web_hooks.go_back'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
|
|
||||||
|
@ -49,12 +49,12 @@
|
||||||
|
|
||||||
<div class='filters'>
|
<div class='filters'>
|
||||||
<div>
|
<div>
|
||||||
<label>{{fa-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.categories_filter'}}</label>
|
<label>{{d-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.categories_filter'}}</label>
|
||||||
{{category-selector categories=model.categories blacklist=model.categories}}
|
{{category-selector categories=model.categories blacklist=model.categories}}
|
||||||
<div class="instructions">{{i18n 'admin.web_hooks.categories_filter_instructions'}}</div>
|
<div class="instructions">{{i18n 'admin.web_hooks.categories_filter_instructions'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>{{fa-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.groups_filter'}}</label>
|
<label>{{d-icon 'circle' class='tracking'}}{{i18n 'admin.web_hooks.groups_filter'}}</label>
|
||||||
{{group-selector groupNames=model.groupsFilterInName groupFinder=model.groupFinder}}
|
{{group-selector groupNames=model.groupsFilterInName groupFinder=model.groupFinder}}
|
||||||
<div class="instructions">{{i18n 'admin.web_hooks.groups_filter_instructions'}}</div>
|
<div class="instructions">{{i18n 'admin.web_hooks.groups_filter_instructions'}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class='pull-right'>
|
<div class='pull-right'>
|
||||||
{{#link-to 'adminWebHooks.show' 'new' tagName='button' classNames='btn'}}
|
{{#link-to 'adminWebHooks.show' 'new' tagName='button' classNames='btn'}}
|
||||||
{{fa-icon 'plus'}} {{i18n 'admin.web_hooks.new'}}
|
{{d-icon 'plus'}} {{i18n 'admin.web_hooks.new'}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
<div class='clearfix'></div>
|
<div class='clearfix'></div>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<td>{{#link-to 'adminWebHooks.show' webHook}}{{webHook.payload_url}}{{/link-to}}</td>
|
<td>{{#link-to 'adminWebHooks.show' webHook}}{{webHook.payload_url}}{{/link-to}}</td>
|
||||||
<td class='description'>{{webHook.description}}</td>
|
<td class='description'>{{webHook.description}}</td>
|
||||||
<td class='controls'>
|
<td class='controls'>
|
||||||
{{#link-to 'adminWebHooks.show' webHook tagName='button' classNames='btn btn-default no-text'}}{{fa-icon 'edit'}}{{/link-to}}
|
{{#link-to 'adminWebHooks.show' webHook tagName='button' classNames='btn btn-default no-text'}}{{d-icon 'edit'}}{{/link-to}}
|
||||||
{{d-button class="destroy btn-danger" action='destroy' actionParam=webHook icon="remove"}}
|
{{d-button class="destroy btn-danger" action='destroy' actionParam=webHook icon="remove"}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -69,8 +69,6 @@
|
||||||
//= require ./discourse/components/notifications-button
|
//= require ./discourse/components/notifications-button
|
||||||
//= require ./discourse/lib/link-mentions
|
//= require ./discourse/lib/link-mentions
|
||||||
//= require ./discourse/components/site-header
|
//= require ./discourse/components/site-header
|
||||||
//= require ./discourse/lib/emoji/groups
|
|
||||||
//= require ./discourse/lib/emoji/toolbar
|
|
||||||
//= require ./discourse/components/d-editor
|
//= require ./discourse/components/d-editor
|
||||||
//= require ./discourse/lib/screen-track
|
//= require ./discourse/lib/screen-track
|
||||||
//= require ./discourse/routes/discourse
|
//= require ./discourse/routes/discourse
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
import { on, observes } from 'ember-addons/ember-computed-decorators';
|
import { on, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
tagName: 'select',
|
tagName: 'select',
|
||||||
|
@ -97,7 +98,7 @@ export default Ember.Component.extend(bufferedRender({
|
||||||
this.selectionTemplate = (item) => {
|
this.selectionTemplate = (item) => {
|
||||||
let name = Em.get(item, 'text');
|
let name = Em.get(item, 'text');
|
||||||
name = Handlebars.escapeExpression(name);
|
name = Handlebars.escapeExpression(name);
|
||||||
return `<i class='fa fa-${this.get("selectionIcon")}'></i>${name}`;
|
return iconHTML(this.get('selectionIcon')) + name;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { registerUnbound } from 'discourse-common/lib/helpers';
|
||||||
|
import { renderIcon } from 'discourse-common/lib/icon-library';
|
||||||
|
|
||||||
|
registerUnbound('d-icon', function(id, params) {
|
||||||
|
return new Handlebars.SafeString(renderIcon('string', id, params));
|
||||||
|
});
|
|
@ -1,25 +1,12 @@
|
||||||
import { registerUnbound } from 'discourse-common/lib/helpers';
|
import { registerUnbound } from 'discourse-common/lib/helpers';
|
||||||
|
import { renderIcon } from 'discourse-common/lib/icon-library';
|
||||||
|
import deprecated from 'discourse-common/lib/deprecated';
|
||||||
|
|
||||||
export function iconClasses(icon, params) {
|
export function iconHTML(id, params) {
|
||||||
let classes = "fa fa-" + icon;
|
return renderIcon('string', id, params);
|
||||||
if (params.modifier) { classes += " fa-" + params.modifier; }
|
|
||||||
if (params['class']) { classes += ' ' + params['class']; }
|
|
||||||
return classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function iconHTML(icon, params) {
|
|
||||||
params = params || {};
|
|
||||||
|
|
||||||
var html = "<i class='" + iconClasses(icon, params) + "'";
|
|
||||||
if (params.title) { html += ` title='${I18n.t(params.title)}'`; }
|
|
||||||
if (params.label) { html += " aria-hidden='true'"; }
|
|
||||||
html += "></i>";
|
|
||||||
if (params.label) {
|
|
||||||
html += "<span class='sr-only'>" + I18n.t(params.label) + "</span>";
|
|
||||||
}
|
|
||||||
return html;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerUnbound('fa-icon', function(icon, params) {
|
registerUnbound('fa-icon', function(icon, params) {
|
||||||
|
deprecated("Use `{{d-icon}}` instead of `{{fa-icon}}");
|
||||||
return new Handlebars.SafeString(iconHTML(icon, params));
|
return new Handlebars.SafeString(iconHTML(icon, params));
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { h } from 'virtual-dom';
|
||||||
|
let _renderers = [];
|
||||||
|
|
||||||
|
export function renderIcon(renderType, id, params) {
|
||||||
|
for (let i=0; i<_renderers.length; i++) {
|
||||||
|
let renderer = _renderers[i];
|
||||||
|
let rendererForType = renderer[renderType];
|
||||||
|
|
||||||
|
if (rendererForType) {
|
||||||
|
let result = rendererForType(id, params || {});
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function iconHTML(id, params) {
|
||||||
|
return renderIcon('string', id, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function iconNode(id, params) {
|
||||||
|
return renderIcon('node', id, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerIconRenderer(renderer) {
|
||||||
|
_renderers.unshift(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support for font awesome icons
|
||||||
|
function faClasses(id, params) {
|
||||||
|
let classNames = `fa fa-${id} d-icon d-icon-${id}`;
|
||||||
|
if (params) {
|
||||||
|
if (params.modifier) { classNames += " fa-" + params.modifier; }
|
||||||
|
if (params['class']) { classNames += ' ' + params['class']; }
|
||||||
|
}
|
||||||
|
return classNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default resolver is font awesome
|
||||||
|
registerIconRenderer({
|
||||||
|
name: 'font-awesome',
|
||||||
|
|
||||||
|
string(id, params) {
|
||||||
|
let tagName = params.tagName || 'i';
|
||||||
|
let html = `<${tagName} class='${faClasses(id, params)}'`;
|
||||||
|
if (params.title) { html += ` title='${I18n.t(params.title)}'`; }
|
||||||
|
if (params.label) { html += " aria-hidden='true'"; }
|
||||||
|
html += `></${tagName}>`;
|
||||||
|
if (params.label) {
|
||||||
|
html += "<span class='sr-only'>" + I18n.t(params.label) + "</span>";
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
node(id, params) {
|
||||||
|
let tagName = params.tagName || 'i';
|
||||||
|
|
||||||
|
const properties = {
|
||||||
|
className: faClasses(id, params),
|
||||||
|
attributes: { "aria-hidden": true }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (params.title) { properties.attributes.title = params.title; }
|
||||||
|
if (params.label) {
|
||||||
|
return h(tagName, properties, h('span.sr-only', I18n.t(params.label)));
|
||||||
|
} else {
|
||||||
|
return h(tagName, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
|
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
|
||||||
import Combobox from 'discourse-common/components/combo-box';
|
import Combobox from 'discourse-common/components/combo-box';
|
||||||
import { CLOSE_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer';
|
import { CLOSE_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer';
|
||||||
|
@ -111,9 +112,7 @@ export default Combobox.extend({
|
||||||
let icons;
|
let icons;
|
||||||
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
icons = icon.split(',').map(i => {
|
icons = icon.split(',').map(i => iconHTML(i)).join(" ");
|
||||||
return `<i class='fa fa-${i}'/>`;
|
|
||||||
}).join(" ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time) {
|
if (time) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import DropdownButton from 'discourse/components/dropdown-button';
|
import DropdownButton from 'discourse/components/dropdown-button';
|
||||||
import computed from "ember-addons/ember-computed-decorators";
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
@ -15,14 +15,14 @@ export default DropdownButton.extend({
|
||||||
{ id: 'create',
|
{ id: 'create',
|
||||||
title: I18n.t('category.create'),
|
title: I18n.t('category.create'),
|
||||||
description: I18n.t('category.create_long'),
|
description: I18n.t('category.create_long'),
|
||||||
styleClasses: 'fa fa-plus' }
|
icon: 'plus' }
|
||||||
];
|
];
|
||||||
if (includeReorder) {
|
if (includeReorder) {
|
||||||
items.push({
|
items.push({
|
||||||
id: 'reorder',
|
id: 'reorder',
|
||||||
title: I18n.t('categories.reorder.title'),
|
title: I18n.t('categories.reorder.title'),
|
||||||
description: I18n.t('categories.reorder.title_long'),
|
description: I18n.t('categories.reorder.title_long'),
|
||||||
styleClasses: 'fa fa-random'
|
icon: 'random'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { setting } from 'discourse/lib/computed';
|
import { setting } from 'discourse/lib/computed';
|
||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
var get = Ember.get;
|
var get = Ember.get;
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
@ -8,10 +10,10 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
tagName: 'li',
|
tagName: 'li',
|
||||||
|
|
||||||
iconClass: function() {
|
@computed('expanded')
|
||||||
if (this.get('expanded')) { return "fa fa-caret-down"; }
|
expandIcon(expanded) {
|
||||||
return "fa fa-caret-right";
|
return expanded ? 'caret-down' : 'caret-right';
|
||||||
}.property('expanded'),
|
},
|
||||||
|
|
||||||
allCategoriesUrl: function() {
|
allCategoriesUrl: function() {
|
||||||
if (this.get('subCategory')) {
|
if (this.get('subCategory')) {
|
||||||
|
@ -33,7 +35,7 @@ export default Ember.Component.extend({
|
||||||
}.property('category'),
|
}.property('category'),
|
||||||
|
|
||||||
dropdownButtonClass: function() {
|
dropdownButtonClass: function() {
|
||||||
var result = 'badge-category category-dropdown-button';
|
let result = 'dropdown-header category-dropdown-button';
|
||||||
if (Em.isNone(this.get('category'))) {
|
if (Em.isNone(this.get('category'))) {
|
||||||
result += ' home';
|
result += ' home';
|
||||||
}
|
}
|
||||||
|
@ -57,21 +59,35 @@ export default Ember.Component.extend({
|
||||||
}.property('category'),
|
}.property('category'),
|
||||||
|
|
||||||
badgeStyle: function() {
|
badgeStyle: function() {
|
||||||
var category = this.get('category');
|
let category = this.get('category');
|
||||||
|
|
||||||
|
const categoryStyle = this.siteSettings.category_style;
|
||||||
|
if (categoryStyle === 'bullet') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (category) {
|
if (category) {
|
||||||
var color = get(category, 'color'),
|
let color = get(category, 'color');
|
||||||
textColor = get(category, 'text_color');
|
let textColor = get(category, 'text_color');
|
||||||
|
|
||||||
if (color || textColor) {
|
if (color || textColor) {
|
||||||
var style = "";
|
let style = "";
|
||||||
if (color) { style += "background-color: #" + color + "; border-color: #" + color + ";"; }
|
if (color) {
|
||||||
if (textColor) { style += "color: #" + textColor + "; "; }
|
if (categoryStyle === "bar") {
|
||||||
|
style += `border-color: #${color};`;
|
||||||
|
} else if (categoryStyle === "box") {
|
||||||
|
style += `background-color: #${color};`;
|
||||||
|
if (textColor) { style += "color: #" + textColor + "; "; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return style.htmlSafe();
|
return style.htmlSafe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "background-color: #eee; color: #333".htmlSafe();
|
if (categoryStyle === 'box') {
|
||||||
|
return "background-color: #eee; color: #333".htmlSafe();
|
||||||
|
}
|
||||||
}.property('category'),
|
}.property('category'),
|
||||||
|
|
||||||
clickEventName: function() {
|
clickEventName: function() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { linkSeenCategoryHashtags, fetchUnseenCategoryHashtags } from 'discourse
|
||||||
import { linkSeenTagHashtags, fetchUnseenTagHashtags } from 'discourse/lib/link-tag-hashtag';
|
import { linkSeenTagHashtags, fetchUnseenTagHashtags } from 'discourse/lib/link-tag-hashtag';
|
||||||
import Composer from 'discourse/models/composer';
|
import Composer from 'discourse/models/composer';
|
||||||
import { load } from 'pretty-text/oneboxer';
|
import { load } from 'pretty-text/oneboxer';
|
||||||
|
import { applyInlineOneboxes } from 'pretty-text/inline-oneboxer';
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import InputValidation from 'discourse/models/input-validation';
|
import InputValidation from 'discourse/models/input-validation';
|
||||||
import { findRawTemplate } from 'discourse/lib/raw-templates';
|
import { findRawTemplate } from 'discourse/lib/raw-templates';
|
||||||
|
@ -58,6 +59,8 @@ export default Ember.Component.extend({
|
||||||
@computed
|
@computed
|
||||||
markdownOptions() {
|
markdownOptions() {
|
||||||
return {
|
return {
|
||||||
|
previewing: true,
|
||||||
|
|
||||||
lookupAvatarByPostNumber: (postNumber, topicId) => {
|
lookupAvatarByPostNumber: (postNumber, topicId) => {
|
||||||
const topic = this.get('topic');
|
const topic = this.get('topic');
|
||||||
if (!topic) { return; }
|
if (!topic) { return; }
|
||||||
|
@ -171,6 +174,10 @@ export default Ember.Component.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_loadInlineOneboxes(inline) {
|
||||||
|
applyInlineOneboxes(inline, ajax);
|
||||||
|
},
|
||||||
|
|
||||||
_loadOneboxes($oneboxes) {
|
_loadOneboxes($oneboxes) {
|
||||||
const post = this.get('composer.post');
|
const post = this.get('composer.post');
|
||||||
let refresh = false;
|
let refresh = false;
|
||||||
|
@ -572,6 +579,18 @@ export default Ember.Component.extend({
|
||||||
Ember.run.debounce(this, this._loadOneboxes, $oneboxes, 450);
|
Ember.run.debounce(this, this._loadOneboxes, $oneboxes, 450);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inline = {};
|
||||||
|
$('a.inline-onebox-loading', $preview).each(function(index, link) {
|
||||||
|
let $link = $(link);
|
||||||
|
$link.removeClass('inline-onebox-loading');
|
||||||
|
let text = $link.text();
|
||||||
|
inline[text] = inline[text] || [];
|
||||||
|
inline[text].push($link);
|
||||||
|
});
|
||||||
|
if (Object.keys(inline).length > 0) {
|
||||||
|
Ember.run.debounce(this, this._loadInlineOneboxes, inline, 450);
|
||||||
|
}
|
||||||
|
|
||||||
this.trigger('previewRefreshed', $preview);
|
this.trigger('previewRefreshed', $preview);
|
||||||
this.sendAction('afterRefresh', $preview);
|
this.sendAction('afterRefresh', $preview);
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: '',
|
||||||
|
|
||||||
|
@computed('composeState')
|
||||||
|
toggleIcon(composeState) {
|
||||||
|
if (composeState === "draft" || composeState === "saving") {
|
||||||
|
return "times";
|
||||||
|
}
|
||||||
|
return "chevron-down";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/*global Mousetrap:true */
|
/*global Mousetrap:true */
|
||||||
import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
|
import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
import { showSelector } from "discourse/lib/emoji/toolbar";
|
|
||||||
import Category from 'discourse/models/category';
|
import Category from 'discourse/models/category';
|
||||||
import { categoryHashtagTriggerRule } from 'discourse/lib/category-hashtags';
|
import { categoryHashtagTriggerRule } from 'discourse/lib/category-hashtags';
|
||||||
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
|
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
|
||||||
|
@ -78,7 +77,11 @@ class Toolbar {
|
||||||
group: 'insertions',
|
group: 'insertions',
|
||||||
icon: 'quote-right',
|
icon: 'quote-right',
|
||||||
shortcut: 'Shift+9',
|
shortcut: 'Shift+9',
|
||||||
perform: e => e.applyList('> ', 'blockquote_text')
|
perform: e => e.applyList(
|
||||||
|
'> ',
|
||||||
|
'blockquote_text',
|
||||||
|
{ applyEmptyLines: true, multiline: true }
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addButton({id: 'code', group: 'insertions', shortcut: 'Shift+C', action: 'formatCode'});
|
this.addButton({id: 'code', group: 'insertions', shortcut: 'Shift+C', action: 'formatCode'});
|
||||||
|
@ -198,6 +201,7 @@ export default Ember.Component.extend({
|
||||||
linkText: '',
|
linkText: '',
|
||||||
lastSel: null,
|
lastSel: null,
|
||||||
_mouseTrap: null,
|
_mouseTrap: null,
|
||||||
|
emojiPickerIsActive: false,
|
||||||
|
|
||||||
@computed('placeholder')
|
@computed('placeholder')
|
||||||
placeholderTranslated(placeholder) {
|
placeholderTranslated(placeholder) {
|
||||||
|
@ -328,7 +332,6 @@ export default Ember.Component.extend({
|
||||||
_applyEmojiAutocomplete($editorInput) {
|
_applyEmojiAutocomplete($editorInput) {
|
||||||
if (!this.siteSettings.enable_emoji) { return; }
|
if (!this.siteSettings.enable_emoji) { return; }
|
||||||
|
|
||||||
const register = this.register;
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
$editorInput.autocomplete({
|
$editorInput.autocomplete({
|
||||||
|
@ -346,20 +349,8 @@ export default Ember.Component.extend({
|
||||||
if (v.code) {
|
if (v.code) {
|
||||||
return `${v.code}:`;
|
return `${v.code}:`;
|
||||||
} else {
|
} else {
|
||||||
showSelector({
|
$editorInput.autocomplete({cancel: true});
|
||||||
appendTo: self.$(),
|
self.set('emojiPickerIsActive', true);
|
||||||
register,
|
|
||||||
onSelect: title => {
|
|
||||||
// Remove the previously type characters when a new emoji is selected from the selector.
|
|
||||||
let selected = self._getSelected();
|
|
||||||
let newPre = selected.pre.replace(/:[^:]+$/, ":");
|
|
||||||
let numOfRemovedChars = selected.pre.length - newPre.length;
|
|
||||||
selected.pre = newPre;
|
|
||||||
selected.start -= numOfRemovedChars;
|
|
||||||
selected.end -= numOfRemovedChars;
|
|
||||||
self._addText(selected, `${title}:`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -453,11 +444,15 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// perform the same operation over many lines of text
|
// perform the same operation over many lines of text
|
||||||
_getMultilineContents(lines, head, hval, hlen, tail, tlen) {
|
_getMultilineContents(lines, head, hval, hlen, tail, tlen, opts) {
|
||||||
let operation = OP.NONE;
|
let operation = OP.NONE;
|
||||||
|
|
||||||
|
const applyEmptyLines = opts && opts.applyEmptyLines;
|
||||||
|
|
||||||
return lines.map(l => {
|
return lines.map(l => {
|
||||||
if (l.length === 0) { return l; }
|
if (!applyEmptyLines && l.length === 0) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
if (operation !== OP.ADDED &&
|
if (operation !== OP.ADDED &&
|
||||||
(l.slice(0, hlen) === hval && tlen === 0 || l.slice(-tlen) === tail)) {
|
(l.slice(0, hlen) === hval && tlen === 0 || l.slice(-tlen) === tail)) {
|
||||||
|
@ -513,8 +508,15 @@ export default Ember.Component.extend({
|
||||||
this.set('value', `${pre.slice(0, -hlen)}${sel.value}${post.slice(tlen)}`);
|
this.set('value', `${pre.slice(0, -hlen)}${sel.value}${post.slice(tlen)}`);
|
||||||
this._selectText(sel.start - hlen, sel.value.length);
|
this._selectText(sel.start - hlen, sel.value.length);
|
||||||
} else {
|
} else {
|
||||||
const contents = this._getMultilineContents(lines, head, hval, hlen, tail, tlen);
|
const contents = this._getMultilineContents(
|
||||||
|
lines,
|
||||||
|
head,
|
||||||
|
hval,
|
||||||
|
hlen,
|
||||||
|
tail,
|
||||||
|
tlen,
|
||||||
|
opts
|
||||||
|
);
|
||||||
this.set('value', `${pre}${contents}${post}`);
|
this.set('value', `${pre}${contents}${post}`);
|
||||||
if (lines.length === 1 && tlen > 0) {
|
if (lines.length === 1 && tlen > 0) {
|
||||||
this._selectText(sel.start + hlen, sel.value.length);
|
this._selectText(sel.start + hlen, sel.value.length);
|
||||||
|
@ -525,9 +527,9 @@ export default Ember.Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_applyList(sel, head, exampleKey) {
|
_applyList(sel, head, exampleKey, opts) {
|
||||||
if (sel.value.indexOf("\n") !== -1) {
|
if (sel.value.indexOf("\n") !== -1) {
|
||||||
this._applySurround(sel, head, '', exampleKey);
|
this._applySurround(sel, head, '', exampleKey, opts);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const [hval, hlen] = getHead(head);
|
const [hval, hlen] = getHead(head);
|
||||||
|
@ -587,9 +589,10 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
if (post.length > 0) {
|
if (post.length > 0) {
|
||||||
post = post.replace(/^\n*/, "\n\n");
|
post = post.replace(/^\n*/, "\n\n");
|
||||||
|
} else {
|
||||||
|
post = "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const value = pre + text + post;
|
const value = pre + text + post;
|
||||||
const $textarea = this.$('textarea.d-editor-input');
|
const $textarea = this.$('textarea.d-editor-input');
|
||||||
|
|
||||||
|
@ -614,13 +617,28 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
emojiSelected(code) {
|
||||||
|
let selected = this._getSelected();
|
||||||
|
const captures = selected.pre.match(/\B:(\w*)$/);
|
||||||
|
|
||||||
|
if(_.isEmpty(captures)) {
|
||||||
|
this._addText(selected, `:${code}:`);
|
||||||
|
} else {
|
||||||
|
let numOfRemovedChars = selected.pre.length - captures[1].length;
|
||||||
|
selected.pre = selected.pre.slice(0, selected.pre.length - captures[1].length);
|
||||||
|
selected.start -= numOfRemovedChars;
|
||||||
|
selected.end -= numOfRemovedChars;
|
||||||
|
this._addText(selected, `${code}:`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
toolbarButton(button) {
|
toolbarButton(button) {
|
||||||
const selected = this._getSelected(button.trimLeading);
|
const selected = this._getSelected(button.trimLeading);
|
||||||
const toolbarEvent = {
|
const toolbarEvent = {
|
||||||
selected,
|
selected,
|
||||||
selectText: (from, length) => this._selectText(from, length),
|
selectText: (from, length) => this._selectText(from, length),
|
||||||
applySurround: (head, tail, exampleKey, opts) => this._applySurround(selected, head, tail, exampleKey, opts),
|
applySurround: (head, tail, exampleKey, opts) => this._applySurround(selected, head, tail, exampleKey, opts),
|
||||||
applyList: (head, exampleKey) => this._applyList(selected, head, exampleKey),
|
applyList: (head, exampleKey, opts) => this._applyList(selected, head, exampleKey, opts),
|
||||||
addText: text => this._addText(selected, text),
|
addText: text => this._addText(selected, text),
|
||||||
replaceText: text => this._addText({pre: '', post: ''}, text),
|
replaceText: text => this._addText({pre: '', post: ''}, text),
|
||||||
getText: () => this.get('value'),
|
getText: () => this.get('value'),
|
||||||
|
@ -692,11 +710,7 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
emoji() {
|
emoji() {
|
||||||
showSelector({
|
this.set('emojiPickerIsActive', !this.get('emojiPickerIsActive'));
|
||||||
appendTo: this.$(),
|
|
||||||
register: this.register,
|
|
||||||
onSelect: title => this._addText(this._getSelected(), `:${title}:`)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
elementId: 'discourse-modal',
|
elementId: 'discourse-modal',
|
||||||
classNameBindings: [':modal', ':hidden', 'modalClass'],
|
classNameBindings: [':modal', 'modalClass'],
|
||||||
attributeBindings: ['data-keyboard'],
|
attributeBindings: ['data-keyboard'],
|
||||||
|
|
||||||
// We handle ESC ourselves
|
// We handle ESC ourselves
|
||||||
|
@ -17,6 +17,7 @@ export default Ember.Component.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.appEvents.on('modal:body-shown', data => {
|
this.appEvents.on('modal:body-shown', data => {
|
||||||
|
this.$().removeClass('hidden');
|
||||||
if (data.title) {
|
if (data.title) {
|
||||||
this.set('title', I18n.t(data.title));
|
this.set('title', I18n.t(data.title));
|
||||||
} else if (data.rawTitle) {
|
} else if (data.rawTitle) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
@ -29,7 +30,7 @@ export default Ember.Component.extend(bufferedRender({
|
||||||
buffer.push("<h4 class='title'>" + title + "</h4>");
|
buffer.push("<h4 class='title'>" + title + "</h4>");
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.push(`<button class='btn standard dropdown-toggle ${this.get('buttonExtraClasses')}' data-toggle='dropdown'>${this.get('text')}</button>`);
|
buffer.push(`<button class='btn standard dropdown-toggle ${this.get('buttonExtraClasses') || ''}' data-toggle='dropdown'>${this.get('text')}</button>`);
|
||||||
buffer.push("<ul class='dropdown-menu'>");
|
buffer.push("<ul class='dropdown-menu'>");
|
||||||
|
|
||||||
const contents = this.get('dropDownContent');
|
const contents = this.get('dropDownContent');
|
||||||
|
@ -40,7 +41,15 @@ export default Ember.Component.extend(bufferedRender({
|
||||||
className = (self.get('activeItem') === id ? 'disabled': '');
|
className = (self.get('activeItem') === id ? 'disabled': '');
|
||||||
|
|
||||||
buffer.push("<li data-id=\"" + id + "\" class=\"" + className + "\"><a href>");
|
buffer.push("<li data-id=\"" + id + "\" class=\"" + className + "\"><a href>");
|
||||||
buffer.push("<span class='icon " + row.styleClasses + "'></span>");
|
|
||||||
|
if (row.icon) {
|
||||||
|
let iconClass = 'icon';
|
||||||
|
if (row.iconClass) {
|
||||||
|
iconClass += ` ${row.iconClass}`;
|
||||||
|
}
|
||||||
|
buffer.push(iconHTML(row.icon, { tagName: 'span', class: iconClass }));
|
||||||
|
}
|
||||||
|
|
||||||
buffer.push("<div><span class='title'>" + row.title + "</span>");
|
buffer.push("<div><span class='title'>" + row.title + "</span>");
|
||||||
buffer.push("<span>" + row.description + "</span></div>");
|
buffer.push("<span>" + row.description + "</span></div>");
|
||||||
buffer.push("</a></li>");
|
buffer.push("</a></li>");
|
||||||
|
|
|
@ -0,0 +1,543 @@
|
||||||
|
import { observes } from "ember-addons/ember-computed-decorators";
|
||||||
|
import { findRawTemplate } from "discourse/lib/raw-templates";
|
||||||
|
import { emojiUrlFor } from "discourse/lib/text";
|
||||||
|
import KeyValueStore from "discourse/lib/key-value-store";
|
||||||
|
import { emojis } from "pretty-text/emoji/data";
|
||||||
|
import { extendedEmojiList, isSkinTonableEmoji } from "pretty-text/emoji";
|
||||||
|
|
||||||
|
const keyValueStore = new KeyValueStore("discourse_emojis_");
|
||||||
|
const EMOJI_USAGE = "emojiUsage";
|
||||||
|
const EMOJI_SELECTED_DIVERSITY = "emojiSelectedDiversity";
|
||||||
|
const PER_ROW = 11;
|
||||||
|
const customEmojis = _.map(_.keys(extendedEmojiList()), code => {
|
||||||
|
return { code, src: emojiUrlFor(code) };
|
||||||
|
});
|
||||||
|
|
||||||
|
export function resetCache() {
|
||||||
|
keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
|
||||||
|
keyValueStore.setObject({ key: EMOJI_SELECTED_DIVERSITY, value: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let $picker, $filter, $results, $list, scrollPosition, $visibleSections, _checkTimeout;
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
willDestroyElement() {
|
||||||
|
this._super();
|
||||||
|
|
||||||
|
this._unbindEvents();
|
||||||
|
this.appEvents.off("emoji-picker:close");
|
||||||
|
},
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super();
|
||||||
|
|
||||||
|
this.appEvents.on("emoji-picker:close", () => this.set("active", false));
|
||||||
|
|
||||||
|
$picker = this.$(".emoji-picker");
|
||||||
|
|
||||||
|
if (!keyValueStore.getObject(EMOJI_USAGE)) {
|
||||||
|
keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
|
||||||
|
} else if(_.isPlainObject(keyValueStore.getObject(EMOJI_USAGE))) {
|
||||||
|
// handle legacy format
|
||||||
|
keyValueStore.setObject({ key: EMOJI_USAGE, value: _.keys(keyValueStore.getObject(EMOJI_USAGE)) });
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollPosition = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
didUpdateAttrs() {
|
||||||
|
this._super();
|
||||||
|
|
||||||
|
if (this.get("active")) {
|
||||||
|
this.show();
|
||||||
|
} else {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("filter")
|
||||||
|
filterChanged() {
|
||||||
|
$filter.find(".clear-filter").toggle(!_.isEmpty(this.get("filter")));
|
||||||
|
Ember.run.debounce(this, this._filterEmojisList, 250);
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("selectedDiversity")
|
||||||
|
selectedDiversityChanged() {
|
||||||
|
keyValueStore.setObject({key: EMOJI_SELECTED_DIVERSITY, value: this.get("selectedDiversity")});
|
||||||
|
|
||||||
|
$.each($list.find(".emoji[data-loaded='1'].diversity"), (_, button) => {
|
||||||
|
$(button).css("background-image", "").removeAttr("data-loaded");
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this.get("filter") !== "") {
|
||||||
|
$.each($results.find(".emoji.diversity"), (_, button) => this._setButtonBackground(button, true) );
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateSelectedDiversity();
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("recentEmojis")
|
||||||
|
recentEmojisChanged() {
|
||||||
|
const previousScrollTop = scrollPosition;
|
||||||
|
const $recentSection = $list.find(".section[data-section='recent']");
|
||||||
|
const $recentSectionGroup = $recentSection.find(".section-group");
|
||||||
|
const $recentCategory = $picker.find(".category-icon button[data-section='recent']").parent();
|
||||||
|
let persistScrollPosition = !$recentCategory.is(":visible") ? true : false;
|
||||||
|
|
||||||
|
// we set height to 0 to avoid it being taken into account for scroll position
|
||||||
|
if(_.isEmpty(this.get("recentEmojis"))) {
|
||||||
|
$recentCategory.hide();
|
||||||
|
$recentSection.css("height", 0).hide();
|
||||||
|
} else {
|
||||||
|
$recentCategory.show();
|
||||||
|
$recentSection.css("height", "auto").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const recentEmojis = _.map(this.get("recentEmojis"), code => {
|
||||||
|
return { code, src: emojiUrlFor(code) };
|
||||||
|
});
|
||||||
|
const template = findRawTemplate("emoji-picker-recent")({recentEmojis});
|
||||||
|
$recentSectionGroup.html(template);
|
||||||
|
|
||||||
|
if(persistScrollPosition) {
|
||||||
|
$list.scrollTop(previousScrollTop + $recentSection.outerHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
this._bindHover($recentSectionGroup);
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
$picker
|
||||||
|
.css({width: "", left: "", bottom: "", display: "none"})
|
||||||
|
.empty();
|
||||||
|
|
||||||
|
this.$().find(".emoji-picker-modal").remove();
|
||||||
|
|
||||||
|
this._unbindEvents();
|
||||||
|
|
||||||
|
clearTimeout(_checkTimeout);
|
||||||
|
},
|
||||||
|
|
||||||
|
show() {
|
||||||
|
const template = findRawTemplate("emoji-picker")({customEmojis});
|
||||||
|
$picker.html(template);
|
||||||
|
this.$().append("<div class='emoji-picker-modal'></div>");
|
||||||
|
|
||||||
|
$filter = $picker.find(".filter");
|
||||||
|
$results = $picker.find(".results");
|
||||||
|
$list = $picker.find(".list");
|
||||||
|
|
||||||
|
this.set("selectedDiversity", keyValueStore.getObject(EMOJI_SELECTED_DIVERSITY) || 1);
|
||||||
|
this.set("recentEmojis", keyValueStore.getObject(EMOJI_USAGE) || []);
|
||||||
|
|
||||||
|
this._bindEvents();
|
||||||
|
|
||||||
|
Ember.run.scheduleOnce("afterRender", this, function() {
|
||||||
|
this._sectionLoadingCheck();
|
||||||
|
this._loadCategoriesEmojis();
|
||||||
|
this._positionPicker();
|
||||||
|
this._scrollTo();
|
||||||
|
this._updateSelectedDiversity();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateSelectedDiversity() {
|
||||||
|
const $diversityPicker = $picker.find(".diversity-picker");
|
||||||
|
|
||||||
|
$diversityPicker.find(".diversity-scale").removeClass("selected");
|
||||||
|
$diversityPicker
|
||||||
|
.find(`.diversity-scale[data-level="${this.get("selectedDiversity")}"]`)
|
||||||
|
.addClass("selected");
|
||||||
|
},
|
||||||
|
|
||||||
|
_sectionLoadingCheck() {
|
||||||
|
_checkTimeout = setTimeout(() => { this._sectionLoadingCheck(); }, 500);
|
||||||
|
Ember.run.throttle(this, this._checkVisibleSection, 100);
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadCategoriesEmojis() {
|
||||||
|
$.each($picker.find(".categories-column button.emoji"), (_, button) => {
|
||||||
|
const $button = $(button);
|
||||||
|
const code = this._codeWithDiversity($button.data("tabicon"), false);
|
||||||
|
$button.css("background-image", `url("${emojiUrlFor(code)}")`);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindEvents() {
|
||||||
|
this._bindDiversityClick();
|
||||||
|
this._bindSectionsScroll();
|
||||||
|
this._bindEmojiClick($list.find(".section-group"));
|
||||||
|
this._bindClearRecentEmojisGroup();
|
||||||
|
this._bindResizing();
|
||||||
|
this._bindCategoryClick();
|
||||||
|
this._bindModalClick();
|
||||||
|
this._bindFilterInput();
|
||||||
|
|
||||||
|
if(!this.site.isMobileDevice) {
|
||||||
|
this._bindHover();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindModalClick() {
|
||||||
|
this.$(".emoji-picker-modal")
|
||||||
|
.on("click", () => this.set("active", false));
|
||||||
|
|
||||||
|
this.$(document).on("click.emoji-picker", (event) => {
|
||||||
|
const onPicker = $(event.target).parents(".emoji-picker").length === 1;
|
||||||
|
const onGrippie = event.target.className.indexOf("grippie") > -1;
|
||||||
|
if(!onPicker && !onGrippie) {
|
||||||
|
this.set("active", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_unbindEvents() {
|
||||||
|
this.$(window).off("resize");
|
||||||
|
this.$(".emoji-picker-modal").off("click");
|
||||||
|
Ember.$("#reply-control").off("div-resizing");
|
||||||
|
this.$(document).off("click.emoji-picker");
|
||||||
|
},
|
||||||
|
|
||||||
|
_filterEmojisList() {
|
||||||
|
if (this.get("filter") === "") {
|
||||||
|
$filter.find("input[name='filter']").val("");
|
||||||
|
$results.empty().hide();
|
||||||
|
$list.show();
|
||||||
|
} else {
|
||||||
|
const lowerCaseFilter = this.get("filter").toLowerCase();
|
||||||
|
const filterableEmojis = emojis.concat(_.keys(extendedEmojiList()));
|
||||||
|
const filteredCodes = _.filter(filterableEmojis, code => {
|
||||||
|
return code.indexOf(lowerCaseFilter) > -1;
|
||||||
|
}).slice(0, 30);
|
||||||
|
$results.empty().html(
|
||||||
|
_.map(filteredCodes, (code) => {
|
||||||
|
const hasDiversity = isSkinTonableEmoji(code);
|
||||||
|
const diversity = hasDiversity ? "diversity" : "";
|
||||||
|
const scaledCode = this._codeWithDiversity(code, hasDiversity);
|
||||||
|
return `<button style="background-image: url('${emojiUrlFor(scaledCode)}')" type="button" class="emoji ${diversity}" tabindex="-1" title="${code}"></button>`;
|
||||||
|
})
|
||||||
|
).show();
|
||||||
|
this._bindHover($results);
|
||||||
|
this._bindEmojiClick($results);
|
||||||
|
$list.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindFilterInput() {
|
||||||
|
const $input = $filter.find("input");
|
||||||
|
|
||||||
|
$input.on("input", (event) => {
|
||||||
|
this.set("filter", event.currentTarget.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$filter.find(".clear-filter").on("click", () => {
|
||||||
|
$input.val("").focus();
|
||||||
|
this.set("filter", "");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindCategoryClick() {
|
||||||
|
$picker.find(".category-icon").on("click", "button.emoji", (event) => {
|
||||||
|
this.set("filter", "");
|
||||||
|
$results.empty();
|
||||||
|
$list.show();
|
||||||
|
|
||||||
|
const section = $(event.currentTarget).data("section");
|
||||||
|
const $section = $list.find(`.section[data-section="${section}"]`);
|
||||||
|
const scrollTop = $list.scrollTop() + ($section.offset().top - $list.offset().top);
|
||||||
|
this._scrollTo(scrollTop);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindHover($hoverables) {
|
||||||
|
const replaceInfoContent = (html) => $picker.find(".footer .info").html(html || "");
|
||||||
|
|
||||||
|
($hoverables || $list.find(".section-group")).on({
|
||||||
|
mouseover: (event) => {
|
||||||
|
const code = this._codeForEmojiButton($(event.currentTarget));
|
||||||
|
const html = `<img src="${emojiUrlFor(code)}" class="emoji"> <span>:${code}:<span>`;
|
||||||
|
replaceInfoContent(html);
|
||||||
|
},
|
||||||
|
mouseleave: () => replaceInfoContent()
|
||||||
|
}, "button.emoji");
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindResizing() {
|
||||||
|
this.$(window).on("resize", () => {
|
||||||
|
Ember.run.throttle(this, this._positionPicker, 16);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ember.$("#reply-control").on("div-resizing", () => {
|
||||||
|
Ember.run.throttle(this, this._positionPicker, 16);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindClearRecentEmojisGroup() {
|
||||||
|
const $recent = $picker.find(".section[data-section='recent'] .clear-recent");
|
||||||
|
$recent.on("click", () => {
|
||||||
|
keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
|
||||||
|
this.set("recentEmojis", []);
|
||||||
|
this._scrollTo(0);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindEmojiClick($emojisContainer) {
|
||||||
|
const handler = (event) => {
|
||||||
|
const code = this._codeForEmojiButton($(event.currentTarget));
|
||||||
|
|
||||||
|
if($(event.currentTarget).parents(".section[data-section='recent']").length === 0) {
|
||||||
|
this._trackEmojiUsage(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendAction("emojiSelected", code);
|
||||||
|
|
||||||
|
if(this.$(".emoji-picker-modal").hasClass("fadeIn")) {
|
||||||
|
this.set("active", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(this.site.isMobileDevice) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$emojisContainer
|
||||||
|
.off("touchstart")
|
||||||
|
.on("touchstart", "button.emoji", (touchStartEvent) => {
|
||||||
|
const $this = $(touchStartEvent.currentTarget);
|
||||||
|
$this.on("touchend", (touchEndEvent) => {
|
||||||
|
handler.bind(self)(touchEndEvent);
|
||||||
|
$this.off("touchend");
|
||||||
|
});
|
||||||
|
$this.on("touchmove", () => $this.off("touchend") );
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$emojisContainer.off("click").on("click", "button.emoji", e => handler.bind(this)(e) );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindSectionsScroll() {
|
||||||
|
$list.on("scroll", () => {
|
||||||
|
scrollPosition = $list.scrollTop();
|
||||||
|
Ember.run.throttle(this, this._checkVisibleSection, 150);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkVisibleSection() {
|
||||||
|
// make sure we stop loading if picker has been removed
|
||||||
|
if(!$picker) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $sections = $list.find(".section");
|
||||||
|
const listHeight = $list.innerHeight();
|
||||||
|
let $selectedSection;
|
||||||
|
|
||||||
|
$visibleSections = _.filter($sections, section => {
|
||||||
|
const $section = $(section);
|
||||||
|
const sectionTop = $section.position().top;
|
||||||
|
return sectionTop + $section.height() > 0 && sectionTop < listHeight;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!_.isEmpty(this.get("recentEmojis")) && scrollPosition === 0) {
|
||||||
|
$selectedSection = $(_.first($visibleSections));
|
||||||
|
} else {
|
||||||
|
$selectedSection = $(_.last($visibleSections));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($selectedSection) {
|
||||||
|
$picker.find(".category-icon").removeClass("current");
|
||||||
|
$picker.find(`.category-icon button[data-section='${$selectedSection.data("section")}']`)
|
||||||
|
.parent()
|
||||||
|
.addClass("current");
|
||||||
|
|
||||||
|
this._loadVisibleSections();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadVisibleSections() {
|
||||||
|
if(!$visibleSections) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const listHeight = $list.innerHeight();
|
||||||
|
$visibleSections.forEach(visibleSection => {
|
||||||
|
const $unloadedEmojis = $(visibleSection).find("button.emoji[data-loaded!='1']");
|
||||||
|
$.each($unloadedEmojis, (_, button) => {
|
||||||
|
const $button = $(button);
|
||||||
|
const buttonTop = $button.position().top;
|
||||||
|
const buttonHeight = $button.height();
|
||||||
|
|
||||||
|
if(buttonTop + buttonHeight > 0 && buttonTop - buttonHeight < listHeight) {
|
||||||
|
this._setButtonBackground($button);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindDiversityClick() {
|
||||||
|
const $diversityScales = $picker.find(".diversity-picker .diversity-scale");
|
||||||
|
$diversityScales.on("click", (event) => {
|
||||||
|
const $selectedDiversity = $(event.currentTarget);
|
||||||
|
this.set("selectedDiversity", parseInt($selectedDiversity.data("level")));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_isReplyControlExpanded() {
|
||||||
|
const verticalSpace = this.$(window).height() -
|
||||||
|
Ember.$(".d-header").height() -
|
||||||
|
Ember.$("#reply-control").height();
|
||||||
|
|
||||||
|
return verticalSpace < $picker.height() - 48;
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionPicker(){
|
||||||
|
if(!this.get("active")) { return; }
|
||||||
|
|
||||||
|
let windowWidth = this.$(window).width();
|
||||||
|
|
||||||
|
const desktopModalePositioning = options => {
|
||||||
|
let attributes = {
|
||||||
|
width: Math.min(windowWidth, 400) - 12,
|
||||||
|
marginLeft: -(Math.min(windowWidth, 400)/2) + 6,
|
||||||
|
marginTop: -130,
|
||||||
|
left: "50%",
|
||||||
|
bottom: "",
|
||||||
|
top: "50%",
|
||||||
|
display: "flex"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$(".emoji-picker-modal").addClass("fadeIn");
|
||||||
|
$picker.css(_.merge(attributes, options));
|
||||||
|
};
|
||||||
|
|
||||||
|
const mobilePositioning = options => {
|
||||||
|
let attributes = {
|
||||||
|
width: windowWidth - 12,
|
||||||
|
marginLeft: 5,
|
||||||
|
marginTop: -130,
|
||||||
|
left: 0,
|
||||||
|
bottom: "",
|
||||||
|
top: "50%",
|
||||||
|
display: "flex"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$(".emoji-picker-modal").addClass("fadeIn");
|
||||||
|
$picker.css(_.merge(attributes, options));
|
||||||
|
};
|
||||||
|
|
||||||
|
const desktopPositioning = options => {
|
||||||
|
let attributes = {
|
||||||
|
width: windowWidth < 485 ? windowWidth - 12 : 400,
|
||||||
|
marginLeft: "",
|
||||||
|
marginTop: "",
|
||||||
|
right: "",
|
||||||
|
left: "",
|
||||||
|
bottom: 32,
|
||||||
|
top: "",
|
||||||
|
display:
|
||||||
|
"flex"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$(".emoji-picker-modal").removeClass("fadeIn");
|
||||||
|
$picker.css(_.merge(attributes, options));
|
||||||
|
};
|
||||||
|
|
||||||
|
if(Ember.testing) {
|
||||||
|
desktopPositioning();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.site.isMobileDevice) {
|
||||||
|
mobilePositioning();
|
||||||
|
} else {
|
||||||
|
if(this._isReplyControlExpanded()) {
|
||||||
|
let $editorWrapper = Ember.$(".d-editor-preview-wrapper");
|
||||||
|
if(($editorWrapper.is(":visible") && $editorWrapper.width() < 400) || windowWidth < 485) {
|
||||||
|
desktopModalePositioning();
|
||||||
|
} else {
|
||||||
|
if($editorWrapper.is(":visible")) {
|
||||||
|
let previewOffset = Ember.$(".d-editor-preview-wrapper").offset();
|
||||||
|
let replyControlOffset = Ember.$("#reply-control").offset();
|
||||||
|
let left = previewOffset.left - replyControlOffset.left;
|
||||||
|
desktopPositioning({left});
|
||||||
|
} else {
|
||||||
|
desktopPositioning({
|
||||||
|
right: (Ember.$("#reply-control").width() - Ember.$(".d-editor-container").width()) / 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(windowWidth < 485) {
|
||||||
|
desktopModalePositioning();
|
||||||
|
} else {
|
||||||
|
let previewInputOffset = Ember.$(".d-editor-input").offset();
|
||||||
|
let replyControlOffset = Ember.$("#reply-control").offset() || {left: 0};
|
||||||
|
let left = previewInputOffset.left - replyControlOffset.left;
|
||||||
|
desktopPositioning({left, bottom: Ember.$("#reply-control").height() - 48});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const infoMaxWidth = $picker.width() -
|
||||||
|
$picker.find(".categories-column").width() -
|
||||||
|
$picker.find(".diversity-picker").width() -
|
||||||
|
32;
|
||||||
|
$picker.find(".info").css("max-width", infoMaxWidth);
|
||||||
|
},
|
||||||
|
|
||||||
|
_codeWithDiversity(code, diversity) {
|
||||||
|
if(diversity && this.get("selectedDiversity") !== 1) {
|
||||||
|
return `${code}:t${this.get("selectedDiversity")}`;
|
||||||
|
} else {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_trackEmojiUsage(code) {
|
||||||
|
let recent = keyValueStore.getObject(EMOJI_USAGE) || [];
|
||||||
|
recent = recent.filter(r => r !== code);
|
||||||
|
recent.unshift(code);
|
||||||
|
recent.length = Math.min(recent.length, PER_ROW);
|
||||||
|
keyValueStore.setObject({ key: EMOJI_USAGE, value: recent });
|
||||||
|
this.set("recentEmojis", recent);
|
||||||
|
},
|
||||||
|
|
||||||
|
_scrollTo(y) {
|
||||||
|
const yPosition = _.isUndefined(y) ? scrollPosition : y;
|
||||||
|
|
||||||
|
$list.scrollTop(yPosition);
|
||||||
|
|
||||||
|
// if we don’t actually scroll we need to force it
|
||||||
|
if(yPosition === 0) {
|
||||||
|
$list.scroll();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_codeForEmojiButton($button) {
|
||||||
|
const title = $button.attr("title");
|
||||||
|
return this._codeWithDiversity(title, $button.hasClass("diversity"));
|
||||||
|
},
|
||||||
|
|
||||||
|
_setButtonBackground(button, diversity) {
|
||||||
|
const $button = $(button);
|
||||||
|
const code = this._codeWithDiversity(
|
||||||
|
$button.attr("title"),
|
||||||
|
diversity || $button.hasClass("diversity")
|
||||||
|
);
|
||||||
|
|
||||||
|
// force visual reloading if needed
|
||||||
|
if($button.css("background-image") !== "none") {
|
||||||
|
$button.css("background-image", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
$button
|
||||||
|
.attr("data-loaded", 1)
|
||||||
|
.css("background-image", `url("${emojiUrlFor(code)}")`);
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'button',
|
||||||
|
classNames: ['btn-flat'],
|
||||||
|
attributeBindings: ['disabled', 'translatedTitle:title'],
|
||||||
|
|
||||||
|
@computed("title")
|
||||||
|
translatedTitle(title) {
|
||||||
|
if (title) return I18n.t(title);
|
||||||
|
},
|
||||||
|
|
||||||
|
click() {
|
||||||
|
return this.attrs.action();
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
import { on } from 'ember-addons/ember-computed-decorators';
|
import { on } from 'ember-addons/ember-computed-decorators';
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import LogsNotice from 'discourse/services/logs-notice';
|
import LogsNotice from 'discourse/services/logs-notice';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { propertyEqual } from 'discourse/lib/computed';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: ["group-members-input"],
|
classNames: ["group-members-input"],
|
||||||
|
addButton: true,
|
||||||
|
|
||||||
@computed('model.limit', 'model.offset', 'model.user_count')
|
@computed('model.limit', 'model.offset', 'model.user_count')
|
||||||
currentPage(limit, offset, userCount) {
|
currentPage(limit, offset, userCount) {
|
||||||
|
|
|
@ -5,9 +5,14 @@ import DiscourseURL from 'discourse/lib/url';
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
||||||
@computed("model.public")
|
@computed("model.public_admission", "userIsGroupUser")
|
||||||
canJoinGroup(publicGroup) {
|
canJoinGroup(publicAdmission, userIsGroupUser) {
|
||||||
return publicGroup;
|
return publicAdmission && !userIsGroupUser;
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed("model.public_exit", "userIsGroupUser")
|
||||||
|
canLeaveGroup(publicExit, userIsGroupUser) {
|
||||||
|
return publicExit && userIsGroupUser;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("model.is_group_user", "model.id", "groupUserIds")
|
@computed("model.is_group_user", "model.id", "groupUserIds")
|
||||||
|
|
|
@ -15,31 +15,27 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
@on('didInsertElement')
|
@on('didInsertElement')
|
||||||
_initializeAutocomplete(opts) {
|
_initializeAutocomplete(opts) {
|
||||||
var self = this;
|
let selectedGroups;
|
||||||
var selectedGroups;
|
let groupNames = this.get('groupNames');
|
||||||
var groupNames = this.get('groupNames');
|
|
||||||
|
|
||||||
self.$('input').autocomplete({
|
this.$('input').autocomplete({
|
||||||
allowAny: false,
|
allowAny: false,
|
||||||
items: _.isArray(groupNames) ? groupNames : (Ember.isEmpty(groupNames)) ? [] : [groupNames],
|
items: _.isArray(groupNames) ? groupNames : (Ember.isEmpty(groupNames)) ? [] : [groupNames],
|
||||||
single: this.get('single'),
|
single: this.get('single'),
|
||||||
updateData: (opts && opts.updateData) ? opts.updateData : false,
|
updateData: (opts && opts.updateData) ? opts.updateData : false,
|
||||||
onChangeItems: function(items){
|
onChangeItems: items => {
|
||||||
selectedGroups = items;
|
selectedGroups = items;
|
||||||
self.set("groupNames", items.join(","));
|
this.set("groupNames", items.join(","));
|
||||||
},
|
},
|
||||||
transformComplete: function(g) {
|
transformComplete: g => {
|
||||||
return g.name;
|
return g.name;
|
||||||
},
|
},
|
||||||
dataSource: function(term) {
|
dataSource: term => {
|
||||||
return self.get("groupFinder")(term).then(function(groups){
|
return this.get("groupFinder")(term).then(groups => {
|
||||||
|
if(!selectedGroups) return groups;
|
||||||
|
|
||||||
if(!selectedGroups){
|
return groups.filter(group => {
|
||||||
return groups;
|
return !selectedGroups.any(s => s === group.name);
|
||||||
}
|
|
||||||
|
|
||||||
return groups.filter(function(group){
|
|
||||||
return !selectedGroups.any(function(s){return s === group.name;});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super();
|
this._super();
|
||||||
$('#discourse-modal').modal('hide');
|
$('#discourse-modal').modal('hide').addClass('hidden');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
|
import highlightText from 'discourse/lib/highlight-text';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
tagName: 'span',
|
tagName: 'span',
|
||||||
|
|
||||||
_highlightOnInsert: function() {
|
_highlightOnInsert: function() {
|
||||||
const term = this.get('highlight');
|
const term = this.get('highlight');
|
||||||
const self = this;
|
highlightText(this.$(), term);
|
||||||
|
|
||||||
if(!_.isEmpty(term)) {
|
|
||||||
self.$().highlight(term.split(/\s+/), {className: 'search-highlight'});
|
|
||||||
}
|
|
||||||
}.observes('highlight').on('didInsertElement')
|
}.observes('highlight').on('didInsertElement')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
|
|
||||||
export default Ember.Component.extend(bufferedRender({
|
export default Ember.Component.extend(bufferedRender({
|
||||||
classNameBindings: [':tip', 'good', 'bad'],
|
classNameBindings: [':tip', 'good', 'bad'],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import DropdownButton from 'discourse/components/dropdown-button';
|
import DropdownButton from 'discourse/components/dropdown-button';
|
||||||
import { allLevels, buttonDetails } from 'discourse/lib/notification-levels';
|
import { allLevels, buttonDetails } from 'discourse/lib/notification-levels';
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
export default DropdownButton.extend({
|
export default DropdownButton.extend({
|
||||||
|
@ -22,7 +22,8 @@ export default DropdownButton.extend({
|
||||||
id: l.id,
|
id: l.id,
|
||||||
title: I18n.t(`${start}.title`),
|
title: I18n.t(`${start}.title`),
|
||||||
description: I18n.t(`${start}.description`),
|
description: I18n.t(`${start}.description`),
|
||||||
styleClasses: `${l.key.dasherize()} fa fa-${l.icon}`
|
icon: l.icon,
|
||||||
|
iconClass: l.key.dasherize(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default Ember.Component.extend(CleansUp, {
|
||||||
|
|
||||||
if (!this.get('showPeriods')) {
|
if (!this.get('showPeriods')) {
|
||||||
if (!this.site.mobileView) {
|
if (!this.site.mobileView) {
|
||||||
const $chevron = this.$('i.fa-caret-down');
|
const $chevron = this.$('.d-icon-caret-down');
|
||||||
this.$('#period-popup').css($chevron.position());
|
this.$('#period-popup').css($chevron.position());
|
||||||
} else {
|
} else {
|
||||||
this.$('#period-popup').css({top: this.$().height()});
|
this.$('#period-popup').css({top: this.$().height()});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
import DropdownButton from 'discourse/components/dropdown-button';
|
import DropdownButton from 'discourse/components/dropdown-button';
|
||||||
|
|
||||||
export default DropdownButton.extend({
|
export default DropdownButton.extend({
|
||||||
|
@ -28,21 +30,28 @@ export default DropdownButton.extend({
|
||||||
{id: 'pinned',
|
{id: 'pinned',
|
||||||
title: I18n.t('topic_statuses.pinned' + globally + '.title'),
|
title: I18n.t('topic_statuses.pinned' + globally + '.title'),
|
||||||
description: I18n.t('topic_statuses.pinned' + globally + '.help'),
|
description: I18n.t('topic_statuses.pinned' + globally + '.help'),
|
||||||
styleClasses: 'fa fa-thumb-tack' },
|
icon: 'thumb-tack' },
|
||||||
{id: 'unpinned',
|
{id: 'unpinned',
|
||||||
title: I18n.t('topic_statuses.unpinned.title'),
|
title: I18n.t('topic_statuses.unpinned.title'),
|
||||||
description: I18n.t('topic_statuses.unpinned.help'),
|
description: I18n.t('topic_statuses.unpinned.help'),
|
||||||
styleClasses: 'fa fa-thumb-tack unpinned' }
|
icon: 'thumb-tack',
|
||||||
|
iconClass: 'unpinned' }
|
||||||
];
|
];
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
text: function() {
|
@computed('topic.pinned', 'topic.pinned_globally')
|
||||||
const globally = this.get('topic.pinned_globally') ? '_globally' : '';
|
text(pinned, pinnedGlobally) {
|
||||||
const state = this.get('topic.pinned') ? 'pinned' + globally : 'unpinned';
|
const globally = pinnedGlobally ? '_globally' : '';
|
||||||
|
const state = pinned ? 'pinned' + globally : 'unpinned';
|
||||||
|
|
||||||
return '<span class="fa fa-thumb-tack' + (state === 'unpinned' ? ' unpinned' : "") + '"></span> ' +
|
const icon = iconHTML(
|
||||||
|
'thumb-tack',
|
||||||
|
{ tagName: 'span', class: (state === 'unpinned' ? 'unpinned' : null) }
|
||||||
|
);
|
||||||
|
|
||||||
|
return icon +
|
||||||
I18n.t('topic_statuses.' + state + '.title') + "<span class='caret'></span>";
|
I18n.t('topic_statuses.' + state + '.title') + "<span class='caret'></span>";
|
||||||
}.property('topic.pinned', 'topic.unpinned'),
|
},
|
||||||
|
|
||||||
clicked(id) {
|
clicked(id) {
|
||||||
const topic = this.get('topic');
|
const topic = this.get('topic');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,13 @@ const REGEXP_CATEGORY_PREFIX = /^(category:|#)/ig;
|
||||||
const REGEXP_GROUP_PREFIX = /^group:/ig;
|
const REGEXP_GROUP_PREFIX = /^group:/ig;
|
||||||
const REGEXP_BADGE_PREFIX = /^badge:/ig;
|
const REGEXP_BADGE_PREFIX = /^badge:/ig;
|
||||||
const REGEXP_TAGS_PREFIX = /^(tags?:|#(?=[a-z0-9\-]+::tag))/ig;
|
const REGEXP_TAGS_PREFIX = /^(tags?:|#(?=[a-z0-9\-]+::tag))/ig;
|
||||||
const REGEXP_IN_PREFIX = /^in:/ig;
|
const REGEXP_IN_PREFIX = /^(in|with):/ig;
|
||||||
const REGEXP_STATUS_PREFIX = /^status:/ig;
|
const REGEXP_STATUS_PREFIX = /^status:/ig;
|
||||||
const REGEXP_MIN_POST_COUNT_PREFIX = /^min_post_count:/ig;
|
const REGEXP_MIN_POST_COUNT_PREFIX = /^min_post_count:/ig;
|
||||||
const REGEXP_POST_TIME_PREFIX = /^(before|after):/ig;
|
const REGEXP_POST_TIME_PREFIX = /^(before|after):/ig;
|
||||||
const REGEXP_TAGS_REPLACE = /(^(tags?:|#(?=[a-z0-9\-]+::tag))|::tag\s?$)/ig;
|
const REGEXP_TAGS_REPLACE = /(^(tags?:|#(?=[a-z0-9\-]+::tag))|::tag\s?$)/ig;
|
||||||
|
|
||||||
const REGEXP_IN_MATCH = /^in:(posted|watching|tracking|bookmarks|first|pinned|unpinned|wiki|unseen)/ig;
|
const REGEXP_IN_MATCH = /^(in|with):(posted|watching|tracking|bookmarks|first|pinned|unpinned|wiki|unseen|image)/ig;
|
||||||
const REGEXP_SPECIAL_IN_LIKES_MATCH = /^in:likes/ig;
|
const REGEXP_SPECIAL_IN_LIKES_MATCH = /^in:likes/ig;
|
||||||
const REGEXP_SPECIAL_IN_PRIVATE_MATCH = /^in:private/ig;
|
const REGEXP_SPECIAL_IN_PRIVATE_MATCH = /^in:private/ig;
|
||||||
const REGEXP_SPECIAL_IN_SEEN_MATCH = /^in:seen/ig;
|
const REGEXP_SPECIAL_IN_SEEN_MATCH = /^in:seen/ig;
|
||||||
|
@ -25,6 +25,8 @@ const REGEXP_CATEGORY_SLUG = /^(\#[a-zA-Z0-9\-:]+)/ig;
|
||||||
const REGEXP_CATEGORY_ID = /^(category:[0-9]+)/ig;
|
const REGEXP_CATEGORY_ID = /^(category:[0-9]+)/ig;
|
||||||
const REGEXP_POST_TIME_WHEN = /^(before|after)/ig;
|
const REGEXP_POST_TIME_WHEN = /^(before|after)/ig;
|
||||||
|
|
||||||
|
const IN_OPTIONS_MAPPING = {'images': 'with'};
|
||||||
|
|
||||||
export default Em.Component.extend({
|
export default Em.Component.extend({
|
||||||
classNames: ['search-advanced-options'],
|
classNames: ['search-advanced-options'],
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ export default Em.Component.extend({
|
||||||
{name: I18n.t('search.advanced.filters.pinned'), value: "pinned"},
|
{name: I18n.t('search.advanced.filters.pinned'), value: "pinned"},
|
||||||
{name: I18n.t('search.advanced.filters.unpinned'), value: "unpinned"},
|
{name: I18n.t('search.advanced.filters.unpinned'), value: "unpinned"},
|
||||||
{name: I18n.t('search.advanced.filters.wiki'), value: "wiki"},
|
{name: I18n.t('search.advanced.filters.wiki'), value: "wiki"},
|
||||||
|
{name: I18n.t('search.advanced.filters.images'), value: "images"},
|
||||||
],
|
],
|
||||||
statusOptions: [
|
statusOptions: [
|
||||||
{name: I18n.t('search.advanced.statuses.open'), value: "open"},
|
{name: I18n.t('search.advanced.statuses.open'), value: "open"},
|
||||||
|
@ -398,13 +401,17 @@ export default Em.Component.extend({
|
||||||
updateSearchTermForIn() {
|
updateSearchTermForIn() {
|
||||||
const match = this.filterBlocks(REGEXP_IN_MATCH);
|
const match = this.filterBlocks(REGEXP_IN_MATCH);
|
||||||
const inFilter = this.get('searchedTerms.in');
|
const inFilter = this.get('searchedTerms.in');
|
||||||
|
let keyword = 'in';
|
||||||
|
if(inFilter in IN_OPTIONS_MAPPING) {
|
||||||
|
keyword = IN_OPTIONS_MAPPING[inFilter];
|
||||||
|
}
|
||||||
let searchTerm = this.get('searchTerm') || '';
|
let searchTerm = this.get('searchTerm') || '';
|
||||||
|
|
||||||
if (inFilter) {
|
if (inFilter) {
|
||||||
if (match.length !== 0) {
|
if (match.length !== 0) {
|
||||||
searchTerm = searchTerm.replace(match[0], `in:${inFilter}`);
|
searchTerm = searchTerm.replace(match[0], `${keyword}:${inFilter}`);
|
||||||
} else {
|
} else {
|
||||||
searchTerm += ` in:${inFilter}`;
|
searchTerm += ` ${keyword}:${inFilter}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('searchTerm', searchTerm.trim());
|
this.set('searchTerm', searchTerm.trim());
|
||||||
|
@ -527,7 +534,7 @@ export default Em.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
groupFinder(term) {
|
groupFinder(term) {
|
||||||
return Group.findAll({search: term, ignore_automatic: false});
|
return Group.findAll({ term: term, ignore_automatic: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
badgeFinder(term) {
|
badgeFinder(term) {
|
||||||
|
|
|
@ -21,9 +21,8 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('expanded')
|
@computed('expanded')
|
||||||
iconClass() {
|
expandedIcon(expanded) {
|
||||||
if (this.get('expanded')) { return "fa fa-caret-down"; }
|
return expanded ? 'caret-down' : 'caret-right';
|
||||||
return "fa fa-caret-right";
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('tagId')
|
@computed('tagId')
|
||||||
|
@ -70,7 +69,7 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
@computed('tag')
|
@computed('tag')
|
||||||
dropdownButtonClass() {
|
dropdownButtonClass() {
|
||||||
var result = 'badge-category category-dropdown-button';
|
let result = 'dropdown-header category-dropdown-button';
|
||||||
if (Em.isNone(this.get('tag'))) {
|
if (Em.isNone(this.get('tag'))) {
|
||||||
result += ' home';
|
result += ' home';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import DropdownButton from 'discourse/components/dropdown-button';
|
import DropdownButton from 'discourse/components/dropdown-button';
|
||||||
import computed from "ember-addons/ember-computed-decorators";
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export default DropdownButton.extend({
|
||||||
{ id: 'manageGroups',
|
{ id: 'manageGroups',
|
||||||
title: I18n.t('tagging.manage_groups'),
|
title: I18n.t('tagging.manage_groups'),
|
||||||
description: I18n.t('tagging.manage_groups_description'),
|
description: I18n.t('tagging.manage_groups_description'),
|
||||||
styleClasses: 'fa fa-wrench' }
|
icon: 'wrench' }
|
||||||
];
|
];
|
||||||
return items;
|
return items;
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import Combobox from 'discourse-common/components/combo-box';
|
import Combobox from 'discourse-common/components/combo-box';
|
||||||
import { observes } from 'ember-addons/ember-computed-decorators';
|
import { observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { iconHTML } from 'discourse-common/helpers/fa-icon';
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
import { escapeExpression } from 'discourse/lib/utilities';
|
import { escapeExpression } from 'discourse/lib/utilities';
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ export default Ember.Component.extend(bufferedRender({
|
||||||
rerenderTriggers: ['topic.archived', 'topic.closed', 'topic.pinned', 'topic.visible', 'topic.unpinned', 'topic.is_warning'],
|
rerenderTriggers: ['topic.archived', 'topic.closed', 'topic.pinned', 'topic.visible', 'topic.unpinned', 'topic.is_warning'],
|
||||||
|
|
||||||
click(e) {
|
click(e) {
|
||||||
if ($(e.target).hasClass('fa-thumb-tack')) {
|
if ($(e.target).hasClass('d-icon-thumb-tack')) {
|
||||||
const topic = this.get('topic');
|
const topic = this.get('topic');
|
||||||
|
|
||||||
// only pin unpin for now
|
// only pin unpin for now
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { iconHTML } from 'discourse-common/lib/icon-library';
|
||||||
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
import { bufferedRender } from 'discourse-common/lib/buffered-render';
|
||||||
import Category from 'discourse/models/category';
|
import Category from 'discourse/models/category';
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ export default Ember.Component.extend(bufferedRender({
|
||||||
|
|
||||||
let autoCloseHours = this.get("duration") || 0;
|
let autoCloseHours = this.get("duration") || 0;
|
||||||
|
|
||||||
buffer.push('<h3><i class="fa fa-clock-o"></i> ');
|
buffer.push(`<h3>${iconHTML('clock-o')} `);
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
timeLeft: duration.humanize(true),
|
timeLeft: duration.humanize(true),
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue