diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..aa854cde75 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,13 @@ +{ + "name": "Discourse", + "image": "discourse/discourse_dev:release", + "workspaceMount": "source=${localWorkspaceFolder}/../..,target=/var/www/discourse,type=bind", + "workspaceFolder": "/var/www/discourse", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + "postCreateCommand": "sudo /sbin/boot", + "extensions": ["rebornix.Ruby"], + "forwardPorts": [9292], + "remoteUser": "discourse" +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 58952b4eb3..320310db8d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,8 @@ "extends": "eslint-config-discourse", "rules": { "discourse-ember/global-ember": 2, - "no-duplicate-imports": 2 + "no-duplicate-imports": 2, + "sort-imports": 2 }, "globals": { "moduleFor": "off", diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 7e97daba6d..ab85796b3c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -45,10 +45,13 @@ bf88410126f73aab47b7e694e3c5b46453cec1b6 ce3fe2f4c4ddf166949ee3cec3d9ecbf9108ab52 # REFACTOR: Move qunit tests to a different directory structure -bc97c79a35d8acd283d4d8b79aa079bce9d127c6 +445d6ba45fe954fb7de11ce7b1392232160e2b63 # REFACTOR: Move javascript tests inside discourse app 23f24bfb510edb25b18b6a0d5485270c88df9b24 # DEV: Tidy up imports. (#11364) 1c2358ba162eb9f9ba9095c9afe30cf51dd85e04 + +# DEV: Sort imports alphabetically (#11382) +bbe5d8d5cf1220165842985c0e2cd4c454d501cd diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7b1bb84427..aefab9fadb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,5 +1,9 @@ version: 2 updates: +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" - package-ecosystem: bundler directory: "/" schedule: diff --git a/.gitignore b/.gitignore index d0359a12ee..2cf8e9eb13 100644 --- a/.gitignore +++ b/.gitignore @@ -137,8 +137,10 @@ node_modules # ignore generated api documentation files openapi/* -# ignore VSCode config files -.vscode +# ignore custom VSCode config files +.vscode/* +!.vscode/launch.json +!.vscode/tasks.json # ignore direnv .envrc diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..e1231a270f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Discourse", + "type": "Ruby", + "request": "launch", + "cwd": "/home/discourse/workspace/discourse", + // run bundle install before rails server + "preLaunchTask": "Prepare discourse", + "env": { "DISCOURSE_DEV_HOSTS": "${env:CLOUDENV_ENVIRONMENT_ID}-9292.apps.codespaces.githubusercontent.com", "UNICORN_BIND_ALL": "1", "UNICORN_WORKERS": "4", "DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE": "1" }, + "program": "bin/unicorn", + "args": ["-x"], + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..ad8af2fea2 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,12 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Prepare discourse", + "type": "shell", + "command": "cd /home/discourse/workspace/discourse && bundle install && yarn && bin/rake db:migrate" + }, + ], +} diff --git a/Dangerfile b/Dangerfile deleted file mode 100644 index 33cf8fc565..0000000000 --- a/Dangerfile +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -if github.pr_json && (github.pr_json["additions"] || 0) > 250 || (github.pr_json["deletions"] || 0) > 250 - warn("This pull request is big! We prefer smaller PRs whenever possible, as they are easier to review. Can this be split into a few smaller PRs?") -end - -prettier_offenses = `yarn --silent prettier --list-different "app/assets/stylesheets/**/*.scss" "app/assets/javascripts/**/*.js" "app/assets/javascripts/**/*.es6" "test/javascripts/**/*.es6"`.split("\n") - -unless prettier_offenses.empty? - fail(%{ -This PR doesn't match our required code formatting standards, as enforced by prettier.io. Here's how to set up prettier in your code editor.\n -#{prettier_offenses.map { |o| github.html_link(o) }.join("\n")} - }) -end - -locales_changes = git.modified_files.grep(%r{config/locales}) -has_non_en_locales_changes = locales_changes.grep_v(%r{config/locales/(?:client|server)\.(?:en|en_US)\.yml}).any? - -if locales_changes.any? && has_non_en_locales_changes - fail("Please submit your non-English translation updates via [Crowdin](https://translate.discourse.org/). You can read more on how to contribute translations [here](https://meta.discourse.org/t/contribute-a-translation-to-discourse/14882).") -end - -files = (git.added_files + git.modified_files) - .select { |path| !path.start_with?("plugins/") } - .select { |path| path.end_with?("es6") || path.end_with?("js") || path.end_with?("rb") } - -js_files = files.select { |path| path.end_with?(".js.es6") || path.end_with?(".js") } -js_test_files = js_files.select { |path| path.end_with?("-test.js.es6") } - -super_offenses = [] -self_offenses = [] -js_files.each do |path| - diff = git.diff_for_file(path) - - next if !diff - - diff.patch.lines.grep(/^\+\s\s/).each do |added_line| - super_offenses << path if added_line['this._super()'] - self_offenses << path if added_line[/(?:(^|\W)self\.?)/] - end -end - -jquery_find_offenses = [] -js_test_files.each do |path| - diff = git.diff_for_file(path) - - next if !diff - - diff.patch.lines.grep(/^\+\s\s/).each do |added_line| - jquery_find_offenses << path if added_line['this.$('] - end -end - -if !self_offenses.empty? - warn(%{ -Use fat arrow instead of self pattern.\n -#{self_offenses.uniq.map { |o| github.html_link(o) }.join("\n")} - }) -end - -if !super_offenses.empty? - warn(%{ -When possible use `this._super(...arguments)` instead of `this._super()`\n -#{super_offenses.uniq.map { |o| github.html_link(o) }.join("\n")} - }) -end - -if !jquery_find_offenses.empty? - warn(%{ -Use `find()` instead of `this.$` in js tests`\n -#{jquery_find_offenses.uniq.map { |o| github.html_link(o) }.join("\n")} - }) -end diff --git a/Gemfile b/Gemfile index cb86d7e4ba..3ea59bc92e 100644 --- a/Gemfile +++ b/Gemfile @@ -192,7 +192,6 @@ gem 'htmlentities', require: false # If you want to amend mini profiler to do the monkey patches in the railties # we are open to it. by deferring require to the initializer we can configure discourse installs without it -gem 'flamegraph', require: false gem 'rack-mini-profiler', require: ['enable_rails_patches'] gem 'unicorn', require: false, platform: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index 4f06749322..3b16e87e10 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -70,31 +70,32 @@ GEM coderay (>= 1.0.0) erubi (>= 1.0.0) rack (>= 0.9.0) - binding_of_caller (0.8.0) + binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) bootsnap (1.5.1) msgpack (~> 1.0) builder (3.2.4) - bullet (6.1.0) + bullet (6.1.2) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) byebug (11.1.3) cbor (0.5.9.6) certified (1.0.0) - chunky_png (1.3.14) + chunky_png (1.4.0) coderay (1.1.3) colored2 (3.1.2) - concurrent-ruby (1.1.7) + concurrent-ruby (1.1.8) connection_pool (2.2.3) cose (1.2.0) cbor (~> 0.5.9) openssl-signature_algorithm (~> 1.0) cppjieba_rb (0.3.3) - crack (0.4.4) + crack (0.4.5) + rexml crass (1.0.6) css_parser (1.7.1) addressable - debug_inspector (0.0.3) + debug_inspector (1.0.0) diff-lcs (1.4.4) diffy (3.4.0) discourse-ember-rails (0.18.6) @@ -112,7 +113,7 @@ GEM image_size (~> 1.5) in_threads (~> 1.3) progress (~> 3.0, >= 3.0.1) - docile (1.3.2) + docile (1.3.5) email_reply_trimmer (0.1.13) ember-data-source (3.0.2) ember-source (>= 2, < 3.0) @@ -121,19 +122,20 @@ GEM sprockets (>= 3.3, < 4.1) ember-source (2.18.2) erubi (1.10.0) - excon (0.78.0) + excon (0.78.1) execjs (2.7.0) exifr (1.3.9) fabrication (2.21.1) fakeweb (1.3.0) - faraday (1.1.0) + faraday (1.3.0) + faraday-net_http (~> 1.0) multipart-post (>= 1.2, < 3) ruby2_keywords + faraday-net_http (1.0.1) fast_blank (1.0.0) fast_xs (0.8.0) - fastimage (2.2.0) - ffi (1.13.1) - flamegraph (0.9.5) + fastimage (2.2.1) + ffi (1.14.2) fspath (3.1.2) gc_tracer (1.5.1) globalid (0.4.2) @@ -145,7 +147,7 @@ GEM hkdf (0.3.0) htmlentities (4.3.4) http_accept_language (2.1.1) - i18n (1.8.5) + i18n (1.8.7) concurrent-ruby (~> 1.0) image_size (1.5.0) in_threads (1.5.4) @@ -154,13 +156,17 @@ GEM rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (2.3.1) + json (2.5.1) json-schema (2.8.1) addressable (>= 2.4) jwt (2.2.2) kgio (2.11.3) libv8 (8.4.255.0) - listen (3.3.1) + libv8 (8.4.255.0-x86_64-darwin-18) + libv8 (8.4.255.0-x86_64-darwin-19) + libv8 (8.4.255.0-x86_64-darwin-20) + libv8 (8.4.255.0-x86_64-linux) + listen (3.4.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) lograge (0.11.2) @@ -172,7 +178,7 @@ GEM logstash-logger (0.26.1) logstash-event (~> 1.2) logster (2.9.4) - loofah (2.8.0) + loofah (2.9.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) lru_redux (1.1.0) @@ -180,40 +186,46 @@ GEM mail (2.7.1) mini_mime (>= 0.1.1) maxminddb (0.1.22) - memory_profiler (0.9.14) + memory_profiler (1.0.0) message_bus (3.3.4) rack (>= 1.1.3) method_source (1.0.0) mini_mime (1.0.2) - mini_portile2 (2.4.0) + mini_portile2 (2.5.0) mini_racer (0.3.1) libv8 (~> 8.4.255) - mini_scheduler (0.12.3) - sidekiq - mini_sql (0.3) + mini_scheduler (0.13.0) + sidekiq (>= 4.2.3) + mini_sql (1.0.1) mini_suffix (0.3.0) ffi (~> 1.9) - minitest (5.14.2) - mocha (1.11.2) - mock_redis (0.26.0) + minitest (5.14.3) + mocha (1.12.0) + mock_redis (0.27.3) + ruby2_keywords msgpack (1.3.3) multi_json (1.15.0) multi_xml (0.6.0) multipart-post (2.1.1) mustache (1.1.1) nio4r (2.5.4) - nokogiri (1.10.10) - mini_portile2 (~> 2.4.0) - nokogumbo (2.0.2) + nokogiri (1.11.1) + mini_portile2 (~> 2.5.0) + racc (~> 1.4) + nokogiri (1.11.1-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.11.1-x86_64-linux) + racc (~> 1.4) + nokogumbo (2.0.4) nokogiri (~> 1.8, >= 1.8.4) - oauth (0.5.4) + oauth (0.5.5) oauth2 (1.4.4) faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - oj (3.10.16) + oj (3.11.0) omniauth (1.9.1) hashie (>= 3.4.6) rack (>= 1.6.2, < 3) @@ -222,20 +234,21 @@ GEM omniauth-github (1.4.0) omniauth (~> 1.5) omniauth-oauth2 (>= 1.4.0, < 2.0) - omniauth-google-oauth2 (0.8.0) + omniauth-google-oauth2 (0.8.1) jwt (>= 2.0) + oauth2 (~> 1.1) omniauth (>= 1.1.1) omniauth-oauth2 (>= 1.6) omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.7.0) + omniauth-oauth2 (1.7.1) oauth2 (~> 1.4) - omniauth (~> 1.9) + omniauth (>= 1.9, < 3) omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) rack - onebox (2.2.1) + onebox (2.2.2) addressable (~> 2.7.0) htmlentities (~> 4.3) multi_json (~> 1.11) @@ -247,7 +260,7 @@ GEM parallel (1.20.1) parallel_tests (3.4.0) parallel - parser (2.7.2.0) + parser (3.0.0.0) ast (~> 2.4.1) pg (1.2.3) progress (3.5.2) @@ -260,11 +273,12 @@ GEM pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (4.0.6) - puma (5.0.4) + puma (5.1.1) nio4r (~> 2.0) r2 (0.2.7) + racc (1.5.2) rack (2.2.3) - rack-mini-profiler (2.2.0) + rack-mini-profiler (2.3.0) rack (>= 1.2.0) rack-protection (2.1.0) rack @@ -275,7 +289,7 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - rails_failover (0.6.2) + rails_failover (0.6.5) activerecord (~> 6.0) concurrent-ruby railties (~> 6.0) @@ -290,7 +304,7 @@ GEM thor (>= 0.20.3, < 2.0) rainbow (3.0.0) raindrops (0.19.1) - rake (13.0.1) + rake (13.0.3) rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) @@ -302,70 +316,70 @@ GEM redis (4.2.5) redis-namespace (1.8.0) redis (>= 3.0.4) - regexp_parser (2.0.0) + regexp_parser (2.0.3) request_store (1.5.0) rack (>= 1.4) rexml (3.2.4) rinku (2.0.6) rotp (6.2.0) - rqrcode (1.1.2) + rqrcode (1.2.0) chunky_png (~> 1.0) - rqrcode_core (~> 0.1) - rqrcode_core (0.1.2) + rqrcode_core (~> 0.2) + rqrcode_core (0.2.0) rspec (3.10.0) rspec-core (~> 3.10.0) rspec-expectations (~> 3.10.0) rspec-mocks (~> 3.10.0) - rspec-core (3.10.0) + rspec-core (3.10.1) rspec-support (~> 3.10.0) - rspec-expectations (3.10.0) + rspec-expectations (3.10.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) rspec-html-matchers (0.9.4) nokogiri (~> 1) rspec (>= 3.0.0.a, < 4) - rspec-mocks (3.10.0) + rspec-mocks (3.10.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) - rspec-rails (4.0.1) + rspec-rails (4.0.2) actionpack (>= 4.2) activesupport (>= 4.2) railties (>= 4.2) - rspec-core (~> 3.9) - rspec-expectations (~> 3.9) - rspec-mocks (~> 3.9) - rspec-support (~> 3.9) - rspec-support (3.10.0) + rspec-core (~> 3.10) + rspec-expectations (~> 3.10) + rspec-mocks (~> 3.10) + rspec-support (~> 3.10) + rspec-support (3.10.1) rswag-specs (2.3.1) activesupport (>= 3.1, < 7.0) json-schema (~> 2.2) railties (>= 3.1, < 7.0) rtlit (0.0.5) - rubocop (1.4.2) + rubocop (1.8.1) parallel (~> 1.10) - parser (>= 2.7.1.5) + parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8) + regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.1.1) + rubocop-ast (>= 1.2.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.2.0) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.4.0) parser (>= 2.7.1.5) rubocop-discourse (2.4.1) rubocop (>= 1.1.0) rubocop-rspec (>= 2.0.0) - rubocop-rspec (2.0.0) + rubocop-rspec (2.1.0) rubocop (~> 1.0) rubocop-ast (>= 1.1.0) ruby-prof (1.4.2) - ruby-progressbar (1.10.1) + ruby-progressbar (1.11.0) ruby-readability (0.7.0) guess_html_encoding (>= 0.0.4) nokogiri (>= 1.6.0) - ruby2_keywords (0.0.2) + ruby2_keywords (0.0.4) rubyzip (2.3.0) - sanitize (5.2.1) + sanitize (5.2.3) crass (~> 1.0.2) nokogiri (>= 1.8.0) nokogumbo (~> 2.0) @@ -381,13 +395,13 @@ GEM seed-fu (2.3.9) activerecord (>= 3.1) activesupport (>= 3.1) - shoulda-matchers (4.4.1) + shoulda-matchers (4.5.0) activesupport (>= 4.2.0) sidekiq (6.1.2) connection_pool (>= 2.2.2) rack (~> 2.0) redis (>= 4.2.0) - simplecov (0.20.0) + simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) @@ -403,22 +417,22 @@ GEM sshkey (2.0.0) stackprof (0.2.16) test-prof (0.12.2) - thor (1.0.1) + thor (1.1.0) thread_safe (0.3.6) tilt (2.0.10) - tzinfo (1.2.8) + tzinfo (1.2.9) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.7.7) - unicode-display_width (1.7.0) - unicorn (5.7.0) + unicode-display_width (2.0.0) + unicorn (5.8.0) kgio (~> 2.6) raindrops (~> 0.7) - uniform_notifier (1.13.0) - webmock (3.10.0) + uniform_notifier (1.13.2) + webmock (3.11.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -427,10 +441,14 @@ GEM jwt (~> 2.0) xorcist (1.1.2) yaml-lint (0.0.10) - zeitwerk (2.4.1) + zeitwerk (2.4.2) PLATFORMS ruby + x86_64-darwin-18 + x86_64-darwin-19 + x86_64-darwin-20 + x86_64-linux DEPENDENCIES actionmailer (= 6.0.3.3) @@ -471,7 +489,6 @@ DEPENDENCIES fast_blank fast_xs fastimage - flamegraph gc_tracer highline htmlentities @@ -558,4 +575,4 @@ DEPENDENCIES yaml-lint BUNDLED WITH - 2.1.4 + 2.2.3 diff --git a/README.md b/README.md index 91a9304300..9b78068886 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ The original Discourse code contributors can be found in [**AUTHORS.MD**](docs/A ## Copyright / License -Copyright 2014 - 2020 Civilized Discourse Construction Kit, Inc. +Copyright 2014 - 2021 Civilized Discourse Construction Kit, Inc. Licensed under the GNU General Public License Version 2.0 (or later); you may not use this work except in compliance with the License. diff --git a/app/assets/javascripts/admin.js.erb b/app/assets/javascripts/admin.js.erb index 41f0315deb..dda5756177 100644 --- a/app/assets/javascripts/admin.js.erb +++ b/app/assets/javascripts/admin.js.erb @@ -3,10 +3,10 @@ require_asset("main_include_admin.js") DiscoursePluginRegistry.admin_javascripts.each { |js| require_asset(js) } -DiscoursePluginRegistry.each_globbed_asset(admin: true) do |f, ext| +DiscoursePluginRegistry.each_globbed_asset(admin: true) do |f| if File.directory?(f) depend_on(f) - elsif f.to_s.end_with?(".#{ext}") + else require_asset(f) end end diff --git a/app/assets/javascripts/admin/addon/components/ace-editor.js b/app/assets/javascripts/admin/addon/components/ace-editor.js index 41c22eff56..4f70345003 100644 --- a/app/assets/javascripts/admin/addon/components/ace-editor.js +++ b/app/assets/javascripts/admin/addon/components/ace-editor.js @@ -1,6 +1,6 @@ import Component from "@ember/component"; -import loadScript from "discourse/lib/load-script"; import getURL from "discourse-common/lib/get-url"; +import loadScript from "discourse/lib/load-script"; import { observes } from "discourse-common/utils/decorators"; import { on } from "@ember/object/evented"; diff --git a/app/assets/javascripts/admin/addon/components/admin-backups-logs.js b/app/assets/javascripts/admin/addon/components/admin-backups-logs.js index 1bb36931a0..f691f3ffc6 100644 --- a/app/assets/javascripts/admin/addon/components/admin-backups-logs.js +++ b/app/assets/javascripts/admin/addon/components/admin-backups-logs.js @@ -1,8 +1,8 @@ -import I18n from "I18n"; -import { scheduleOnce } from "@ember/runloop"; -import Component from "@ember/component"; -import discourseDebounce from "discourse/lib/debounce"; import { observes, on } from "discourse-common/utils/decorators"; +import Component from "@ember/component"; +import I18n from "I18n"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { scheduleOnce } from "@ember/runloop"; export default Component.extend({ classNames: ["admin-backups-logs"], @@ -33,9 +33,7 @@ export default Component.extend({ } }, - @on("init") - @observes("logs.[]") - _updateFormattedLogs: discourseDebounce(function () { + _updateFormattedLogsFunc: function () { const logs = this.logs; if (logs.length === 0) { return; @@ -57,7 +55,13 @@ export default Component.extend({ this.renderLogs(); scheduleOnce("afterRender", this, this._scrollDown); - }, 150), + }, + + @on("init") + @observes("logs.[]") + _updateFormattedLogs() { + discourseDebounce(this, this._updateFormattedLogsFunc, 150); + }, renderLogs() { const formattedLogs = this.formattedLogs; diff --git a/app/assets/javascripts/admin/addon/components/admin-report-chart.js b/app/assets/javascripts/admin/addon/components/admin-report-chart.js index 20a190d9d2..8a894b9562 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-chart.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-chart.js @@ -1,8 +1,9 @@ -import { makeArray } from "discourse-common/lib/helpers"; -import { debounce, schedule } from "@ember/runloop"; import Component from "@ember/component"; -import { number } from "discourse/lib/formatter"; +import discourseDebounce from "discourse-common/lib/debounce"; import loadScript from "discourse/lib/load-script"; +import { makeArray } from "discourse-common/lib/helpers"; +import { number } from "discourse/lib/formatter"; +import { schedule } from "@ember/runloop"; export default Component.extend({ classNames: ["admin-report-chart"], @@ -14,7 +15,7 @@ export default Component.extend({ this._super(...arguments); this.resizeHandler = () => - debounce(this, this._scheduleChartRendering, 500); + discourseDebounce(this, this._scheduleChartRendering, 500); }, didInsertElement() { @@ -34,7 +35,7 @@ export default Component.extend({ didReceiveAttrs() { this._super(...arguments); - debounce(this, this._scheduleChartRendering, 100); + discourseDebounce(this, this._scheduleChartRendering, 100); }, _scheduleChartRendering() { diff --git a/app/assets/javascripts/admin/addon/components/admin-report-counts.js b/app/assets/javascripts/admin/addon/components/admin-report-counts.js index 6d3c0b398b..03c690dbbd 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-counts.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-counts.js @@ -1,5 +1,5 @@ -import { match } from "@ember/object/computed"; import Component from "@ember/component"; +import { match } from "@ember/object/computed"; export default Component.extend({ allTime: true, tagName: "tr", diff --git a/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js b/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js index 3519e6a163..4cac3b15db 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js @@ -1,8 +1,9 @@ -import { makeArray } from "discourse-common/lib/helpers"; -import { debounce, schedule } from "@ember/runloop"; import Component from "@ember/component"; -import { number } from "discourse/lib/formatter"; +import discourseDebounce from "discourse-common/lib/debounce"; import loadScript from "discourse/lib/load-script"; +import { makeArray } from "discourse-common/lib/helpers"; +import { number } from "discourse/lib/formatter"; +import { schedule } from "@ember/runloop"; export default Component.extend({ classNames: ["admin-report-chart", "admin-report-stacked-chart"], @@ -11,7 +12,7 @@ export default Component.extend({ this._super(...arguments); this.resizeHandler = () => - debounce(this, this._scheduleChartRendering, 500); + discourseDebounce(this, this._scheduleChartRendering, 500); }, didInsertElement() { @@ -31,7 +32,7 @@ export default Component.extend({ didReceiveAttrs() { this._super(...arguments); - debounce(this, this._scheduleChartRendering, 100); + discourseDebounce(this, this._scheduleChartRendering, 100); }, _scheduleChartRendering() { diff --git a/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js b/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js index b41304ec34..e12bc6432f 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import Component from "@ember/component"; +import I18n from "I18n"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; import { setting } from "discourse/lib/computed"; export default Component.extend({ diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js b/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js index 967370ab8e..aadf6e0f73 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js @@ -1,6 +1,6 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import Component from "@ember/component"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; export default Component.extend({ tagName: "td", diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table-header.js b/app/assets/javascripts/admin/addon/components/admin-report-table-header.js index f7c91dcab6..5c7cdf1e4c 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table-header.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table-header.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Component from "@ember/component"; +import discourseComputed from "discourse-common/utils/decorators"; export default Component.extend({ tagName: "th", diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table.js b/app/assets/javascripts/admin/addon/components/admin-report-table.js index b44ea784dd..a237e93ee4 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table.js @@ -1,7 +1,7 @@ +import Component from "@ember/component"; +import { alias } from "@ember/object/computed"; import discourseComputed from "discourse-common/utils/decorators"; import { makeArray } from "discourse-common/lib/helpers"; -import { alias } from "@ember/object/computed"; -import Component from "@ember/component"; const PAGES_LIMIT = 8; diff --git a/app/assets/javascripts/admin/addon/components/admin-report.js b/app/assets/javascripts/admin/addon/components/admin-report.js index eb9b06f703..31fc2c2973 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report.js +++ b/app/assets/javascripts/admin/addon/components/admin-report.js @@ -1,16 +1,16 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { makeArray } from "discourse-common/lib/helpers"; -import { alias, or, and, equal, notEmpty } from "@ember/object/computed"; -import EmberObject, { computed, action } from "@ember/object"; -import { next } from "@ember/runloop"; -import Component from "@ember/component"; -import ReportLoader from "discourse/lib/reports-loader"; -import { exportEntity } from "discourse/lib/export-csv"; -import { outputExportResult } from "discourse/lib/export-result"; +import EmberObject, { action, computed } from "@ember/object"; import Report, { SCHEMA_VERSION } from "admin/models/report"; +import { alias, and, equal, notEmpty, or } from "@ember/object/computed"; +import Component from "@ember/component"; +import I18n from "I18n"; +import ReportLoader from "discourse/lib/reports-loader"; +import discourseComputed from "discourse-common/utils/decorators"; +import { exportEntity } from "discourse/lib/export-csv"; import { isPresent } from "@ember/utils"; import { isTesting } from "discourse-common/config/environment"; +import { makeArray } from "discourse-common/lib/helpers"; +import { next } from "@ember/runloop"; +import { outputExportResult } from "discourse/lib/export-result"; const TABLE_OPTIONS = { perPage: 8, diff --git a/app/assets/javascripts/admin/addon/components/admin-theme-editor.js b/app/assets/javascripts/admin/addon/components/admin-theme-editor.js index c453c877d6..ac073c4b55 100644 --- a/app/assets/javascripts/admin/addon/components/admin-theme-editor.js +++ b/app/assets/javascripts/admin/addon/components/admin-theme-editor.js @@ -1,8 +1,8 @@ -import I18n from "I18n"; -import { next } from "@ember/runloop"; import Component from "@ember/component"; +import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; import { fmt } from "discourse/lib/computed"; +import { next } from "@ember/runloop"; export default Component.extend({ @discourseComputed("theme.targets", "onlyOverridden", "showAdvanced") diff --git a/app/assets/javascripts/admin/addon/components/admin-user-field-item.js b/app/assets/javascripts/admin/addon/components/admin-user-field-item.js index 17634d5c49..c9642e3c94 100644 --- a/app/assets/javascripts/admin/addon/components/admin-user-field-item.js +++ b/app/assets/javascripts/admin/addon/components/admin-user-field-item.js @@ -1,16 +1,16 @@ -import I18n from "I18n"; -import { isEmpty } from "@ember/utils"; -import { empty } from "@ember/object/computed"; -import { scheduleOnce } from "@ember/runloop"; -import Component from "@ember/component"; -import UserField from "admin/models/user-field"; -import { bufferedProperty } from "discourse/mixins/buffered-content"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import { propertyEqual, i18n } from "discourse/lib/computed"; import discourseComputed, { observes, on, } from "discourse-common/utils/decorators"; +import { i18n, propertyEqual } from "discourse/lib/computed"; +import Component from "@ember/component"; +import I18n from "I18n"; +import UserField from "admin/models/user-field"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import { empty } from "@ember/object/computed"; +import { isEmpty } from "@ember/utils"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { scheduleOnce } from "@ember/runloop"; export default Component.extend(bufferedProperty("userField"), { editing: empty("userField.id"), diff --git a/app/assets/javascripts/admin/addon/components/admin-watched-word.js b/app/assets/javascripts/admin/addon/components/admin-watched-word.js index 061c83d56a..266b02b3c6 100644 --- a/app/assets/javascripts/admin/addon/components/admin-watched-word.js +++ b/app/assets/javascripts/admin/addon/components/admin-watched-word.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; import Component from "@ember/component"; -import { iconHTML } from "discourse-common/lib/icon-library"; +import I18n from "I18n"; import bootbox from "bootbox"; +import { iconHTML } from "discourse-common/lib/icon-library"; export default Component.extend({ classNames: ["watched-word"], diff --git a/app/assets/javascripts/admin/addon/components/admin-web-hook-event-chooser.js b/app/assets/javascripts/admin/addon/components/admin-web-hook-event-chooser.js index 98e39518bf..1c8e59fd27 100644 --- a/app/assets/javascripts/admin/addon/components/admin-web-hook-event-chooser.js +++ b/app/assets/javascripts/admin/addon/components/admin-web-hook-event-chooser.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import Component from "@ember/component"; +import I18n from "I18n"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; export default Component.extend({ classNames: ["hook-event"], diff --git a/app/assets/javascripts/admin/addon/components/admin-web-hook-event.js b/app/assets/javascripts/admin/addon/components/admin-web-hook-event.js index 75f1326a48..fbcf1594e0 100644 --- a/app/assets/javascripts/admin/addon/components/admin-web-hook-event.js +++ b/app/assets/javascripts/admin/addon/components/admin-web-hook-event.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import Component from "@ember/component"; -import { ajax } from "discourse/lib/ajax"; -import { popupAjaxError } from "discourse/lib/ajax-error"; import { ensureJSON, plainJSON, prettyJSON } from "discourse/lib/formatter"; +import Component from "@ember/component"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Component.extend({ tagName: "li", diff --git a/app/assets/javascripts/admin/addon/components/admin-web-hook-status.js b/app/assets/javascripts/admin/addon/components/admin-web-hook-status.js index 818970f125..a80a769e94 100644 --- a/app/assets/javascripts/admin/addon/components/admin-web-hook-status.js +++ b/app/assets/javascripts/admin/addon/components/admin-web-hook-status.js @@ -1,6 +1,6 @@ +import Component from "@ember/component"; import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; -import Component from "@ember/component"; import { iconHTML } from "discourse-common/lib/icon-library"; export default Component.extend({ diff --git a/app/assets/javascripts/admin/addon/components/color-input.js b/app/assets/javascripts/admin/addon/components/color-input.js index 3d7dad5e00..c563fedc94 100644 --- a/app/assets/javascripts/admin/addon/components/color-input.js +++ b/app/assets/javascripts/admin/addon/components/color-input.js @@ -1,8 +1,8 @@ -import { schedule } from "@ember/runloop"; -import Component from "@ember/component"; -import { computed, action } from "@ember/object"; +import { action, computed } from "@ember/object"; import loadScript, { loadCSS } from "discourse/lib/load-script"; +import Component from "@ember/component"; import { observes } from "discourse-common/utils/decorators"; +import { schedule } from "@ember/runloop"; /** An input field for a color. diff --git a/app/assets/javascripts/admin/addon/components/email-styles-editor.js b/app/assets/javascripts/admin/addon/components/email-styles-editor.js index c40f8a543e..6f7cf6d021 100644 --- a/app/assets/javascripts/admin/addon/components/email-styles-editor.js +++ b/app/assets/javascripts/admin/addon/components/email-styles-editor.js @@ -1,8 +1,8 @@ +import Component from "@ember/component"; import I18n from "I18n"; +import bootbox from "bootbox"; import discourseComputed from "discourse-common/utils/decorators"; import { reads } from "@ember/object/computed"; -import Component from "@ember/component"; -import bootbox from "bootbox"; export default Component.extend({ editorId: reads("fieldName"), diff --git a/app/assets/javascripts/admin/addon/components/embeddable-host.js b/app/assets/javascripts/admin/addon/components/embeddable-host.js index 9846c9fc7b..a0f546227b 100644 --- a/app/assets/javascripts/admin/addon/components/embeddable-host.js +++ b/app/assets/javascripts/admin/addon/components/embeddable-host.js @@ -1,16 +1,12 @@ +import Category from "discourse/models/category"; +import Component from "@ember/component"; import I18n from "I18n"; -import discourseComputed, { - on, - observes, -} from "discourse-common/utils/decorators"; +import bootbox from "bootbox"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import discourseComputed from "discourse-common/utils/decorators"; import { isEmpty } from "@ember/utils"; import { or } from "@ember/object/computed"; -import { schedule } from "@ember/runloop"; -import Component from "@ember/component"; -import { bufferedProperty } from "discourse/mixins/buffered-content"; import { popupAjaxError } from "discourse/lib/ajax-error"; -import Category from "discourse/models/category"; -import bootbox from "bootbox"; export default Component.extend(bufferedProperty("host"), { editToggled: false, @@ -19,14 +15,6 @@ export default Component.extend(bufferedProperty("host"), { editing: or("host.isNew", "editToggled"), - @on("didInsertElement") - @observes("editing") - _focusOnInput() { - schedule("afterRender", () => { - this.element.querySelector(".host-name").focus(); - }); - }, - @discourseComputed("buffered.host", "host.isSaving") cantSave(host, isSaving) { return isSaving || isEmpty(host); diff --git a/app/assets/javascripts/admin/addon/components/embedding-setting.js b/app/assets/javascripts/admin/addon/components/embedding-setting.js index 8c1a187ac6..7b8417aa06 100644 --- a/app/assets/javascripts/admin/addon/components/embedding-setting.js +++ b/app/assets/javascripts/admin/addon/components/embedding-setting.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Component from "@ember/component"; +import discourseComputed from "discourse-common/utils/decorators"; export default Component.extend({ classNames: ["embed-setting"], diff --git a/app/assets/javascripts/admin/addon/components/highlighted-code.js b/app/assets/javascripts/admin/addon/components/highlighted-code.js index f5486db8d9..21cfaf6b15 100644 --- a/app/assets/javascripts/admin/addon/components/highlighted-code.js +++ b/app/assets/javascripts/admin/addon/components/highlighted-code.js @@ -1,5 +1,5 @@ +import { observes, on } from "discourse-common/utils/decorators"; import Component from "@ember/component"; -import { on, observes } from "discourse-common/utils/decorators"; import highlightSyntax from "discourse/lib/highlight-syntax"; export default Component.extend({ diff --git a/app/assets/javascripts/admin/addon/components/ip-lookup.js b/app/assets/javascripts/admin/addon/components/ip-lookup.js index db19cb25c3..99929048a4 100644 --- a/app/assets/javascripts/admin/addon/components/ip-lookup.js +++ b/app/assets/javascripts/admin/addon/components/ip-lookup.js @@ -1,12 +1,12 @@ -import I18n from "I18n"; -import EmberObject from "@ember/object"; -import { later } from "@ember/runloop"; -import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; -import { ajax } from "discourse/lib/ajax"; import AdminUser from "admin/models/admin-user"; -import copyText from "discourse/lib/copy-text"; +import Component from "@ember/component"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import copyText from "discourse/lib/copy-text"; +import discourseComputed from "discourse-common/utils/decorators"; +import { later } from "@ember/runloop"; export default Component.extend({ classNames: ["ip-lookup"], diff --git a/app/assets/javascripts/admin/addon/components/penalty-post-action.js b/app/assets/javascripts/admin/addon/components/penalty-post-action.js index 4a46bbbea7..e010272447 100644 --- a/app/assets/javascripts/admin/addon/components/penalty-post-action.js +++ b/app/assets/javascripts/admin/addon/components/penalty-post-action.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; import discourseComputed, { afterRender, } from "discourse-common/utils/decorators"; -import { equal } from "@ember/object/computed"; import Component from "@ember/component"; +import I18n from "I18n"; +import { equal } from "@ember/object/computed"; const ACTIONS = ["delete", "delete_replies", "edit", "none"]; diff --git a/app/assets/javascripts/admin/addon/components/permalink-form.js b/app/assets/javascripts/admin/addon/components/permalink-form.js index b7238f5700..a5a8a95e35 100644 --- a/app/assets/javascripts/admin/addon/components/permalink-form.js +++ b/app/assets/javascripts/admin/addon/components/permalink-form.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import { schedule } from "@ember/runloop"; import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; -import { fmt } from "discourse/lib/computed"; +import I18n from "I18n"; import Permalink from "admin/models/permalink"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; +import { fmt } from "discourse/lib/computed"; +import { schedule } from "@ember/runloop"; export default Component.extend({ classNames: ["permalink-form"], diff --git a/app/assets/javascripts/admin/addon/components/report-filters/bool.js b/app/assets/javascripts/admin/addon/components/report-filters/bool.js index 0a752c54e2..544709791c 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/bool.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/bool.js @@ -1,5 +1,5 @@ -import { action } from "@ember/object"; import FilterComponent from "admin/components/report-filters/filter"; +import { action } from "@ember/object"; export default FilterComponent.extend({ checked: false, diff --git a/app/assets/javascripts/admin/addon/components/report-filters/category.js b/app/assets/javascripts/admin/addon/components/report-filters/category.js index 4cbe965193..877c3aee7a 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/category.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/category.js @@ -1,6 +1,6 @@ +import FilterComponent from "admin/components/report-filters/filter"; import { action } from "@ember/object"; import { readOnly } from "@ember/object/computed"; -import FilterComponent from "admin/components/report-filters/filter"; export default FilterComponent.extend({ category: readOnly("filter.default"), diff --git a/app/assets/javascripts/admin/addon/components/report-filters/group.js b/app/assets/javascripts/admin/addon/components/report-filters/group.js index 5cf379332b..30dd4c7b1b 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/group.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/group.js @@ -1,5 +1,5 @@ -import { computed } from "@ember/object"; import FilterComponent from "admin/components/report-filters/filter"; +import { computed } from "@ember/object"; export default FilterComponent.extend({ classNames: ["group-filter"], diff --git a/app/assets/javascripts/admin/addon/components/resumable-upload.js b/app/assets/javascripts/admin/addon/components/resumable-upload.js index 0afa189a1d..8e3ce18e8c 100644 --- a/app/assets/javascripts/admin/addon/components/resumable-upload.js +++ b/app/assets/javascripts/admin/addon/components/resumable-upload.js @@ -1,9 +1,9 @@ -import getURL from "discourse-common/lib/get-url"; -import I18n from "I18n"; +import discourseComputed, { on } from "discourse-common/utils/decorators"; import { later, schedule } from "@ember/runloop"; import Component from "@ember/component"; +import I18n from "I18n"; +import getURL from "discourse-common/lib/get-url"; import { iconHTML } from "discourse-common/lib/icon-library"; -import discourseComputed, { on } from "discourse-common/utils/decorators"; /*global Resumable:true */ diff --git a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js index e738c81b85..40dd71ad9a 100644 --- a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js +++ b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; import discourseComputed, { on } from "discourse-common/utils/decorators"; -import { schedule } from "@ember/runloop"; import Component from "@ember/component"; -import bootbox from "bootbox"; +import I18n from "I18n"; import ScreenedIpAddress from "admin/models/screened-ip-address"; +import bootbox from "bootbox"; +import { schedule } from "@ember/runloop"; /** A form to create an IP address that will be blocked or allowed. diff --git a/app/assets/javascripts/admin/addon/components/secret-value-list.js b/app/assets/javascripts/admin/addon/components/secret-value-list.js index 9b59c26d3a..5ad0e5b3ce 100644 --- a/app/assets/javascripts/admin/addon/components/secret-value-list.js +++ b/app/assets/javascripts/admin/addon/components/secret-value-list.js @@ -1,6 +1,6 @@ +import Component from "@ember/component"; import I18n from "I18n"; import { isEmpty } from "@ember/utils"; -import Component from "@ember/component"; import { on } from "discourse-common/utils/decorators"; import { set } from "@ember/object"; diff --git a/app/assets/javascripts/admin/addon/components/simple-list.js b/app/assets/javascripts/admin/addon/components/simple-list.js index f3db4c5973..96136c98e2 100644 --- a/app/assets/javascripts/admin/addon/components/simple-list.js +++ b/app/assets/javascripts/admin/addon/components/simple-list.js @@ -1,6 +1,6 @@ -import { empty } from "@ember/object/computed"; import Component from "@ember/component"; import { action } from "@ember/object"; +import { empty } from "@ember/object/computed"; import { on } from "discourse-common/utils/decorators"; export default Component.extend({ diff --git a/app/assets/javascripts/admin/addon/components/site-setting.js b/app/assets/javascripts/admin/addon/components/site-setting.js index 695ddac781..888daa3117 100644 --- a/app/assets/javascripts/admin/addon/components/site-setting.js +++ b/app/assets/javascripts/admin/addon/components/site-setting.js @@ -1,7 +1,7 @@ -import Component from "@ember/component"; import BufferedContent from "discourse/mixins/buffered-content"; -import SiteSetting from "admin/models/site-setting"; +import Component from "@ember/component"; import SettingComponent from "admin/mixins/setting-component"; +import SiteSetting from "admin/models/site-setting"; import { readOnly } from "@ember/object/computed"; export default Component.extend(BufferedContent, SettingComponent, { diff --git a/app/assets/javascripts/admin/addon/components/site-settings/bool.js b/app/assets/javascripts/admin/addon/components/site-settings/bool.js index a565648c6d..70d7c59ae0 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/bool.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/bool.js @@ -1,6 +1,6 @@ +import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; import { isEmpty } from "@ember/utils"; -import Component from "@ember/component"; export default Component.extend({ @discourseComputed("value") diff --git a/app/assets/javascripts/admin/addon/components/site-settings/category-list.js b/app/assets/javascripts/admin/addon/components/site-settings/category-list.js index 0369756c08..9dc792e6de 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/category-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/category-list.js @@ -1,5 +1,5 @@ -import Component from "@ember/component"; import Category from "discourse/models/category"; +import Component from "@ember/component"; import { computed } from "@ember/object"; export default Component.extend({ diff --git a/app/assets/javascripts/admin/addon/components/site-settings/color.js b/app/assets/javascripts/admin/addon/components/site-settings/color.js index 7e5e71effc..8d098cb7d8 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/color.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/color.js @@ -1,5 +1,5 @@ +import { action, computed } from "@ember/object"; import Component from "@ember/component"; -import { computed, action } from "@ember/object"; function RGBToHex(rgb) { // Choose correct separator diff --git a/app/assets/javascripts/admin/addon/components/site-settings/group-list.js b/app/assets/javascripts/admin/addon/components/site-settings/group-list.js index f7ea894503..ad9dbbfd1c 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/group-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/group-list.js @@ -1,5 +1,5 @@ -import { computed } from "@ember/object"; import Component from "@ember/component"; +import { computed } from "@ember/object"; export default Component.extend({ tokenSeparator: "|", diff --git a/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js b/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js index e5723668d7..d679063df1 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js @@ -1,6 +1,6 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Component from "@ember/component"; import { action } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; export default Component.extend({ @discourseComputed("value") diff --git a/app/assets/javascripts/admin/addon/components/site-text-summary.js b/app/assets/javascripts/admin/addon/components/site-text-summary.js index abe4f5fa63..071091f12b 100644 --- a/app/assets/javascripts/admin/addon/components/site-text-summary.js +++ b/app/assets/javascripts/admin/addon/components/site-text-summary.js @@ -1,6 +1,6 @@ import Component from "@ember/component"; -import { on } from "discourse-common/utils/decorators"; import highlightHTML from "discourse/lib/highlight-html"; +import { on } from "discourse-common/utils/decorators"; export default Component.extend({ classNames: ["site-text"], diff --git a/app/assets/javascripts/admin/addon/components/suspension-details.js b/app/assets/javascripts/admin/addon/components/suspension-details.js index f9edc0e225..e99a7e1c5b 100644 --- a/app/assets/javascripts/admin/addon/components/suspension-details.js +++ b/app/assets/javascripts/admin/addon/components/suspension-details.js @@ -1,8 +1,8 @@ import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; import I18n from "I18n"; -import { equal } from "@ember/object/computed"; import { action } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; +import { equal } from "@ember/object/computed"; const CUSTOM_REASON_KEY = "custom"; diff --git a/app/assets/javascripts/admin/addon/components/tags-uploader.js b/app/assets/javascripts/admin/addon/components/tags-uploader.js index 3c547adf8d..1dc3bfc467 100644 --- a/app/assets/javascripts/admin/addon/components/tags-uploader.js +++ b/app/assets/javascripts/admin/addon/components/tags-uploader.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import { alias } from "@ember/object/computed"; import Component from "@ember/component"; +import I18n from "I18n"; import UploadMixin from "discourse/mixins/upload"; +import { alias } from "@ember/object/computed"; import bootbox from "bootbox"; export default Component.extend(UploadMixin, { diff --git a/app/assets/javascripts/admin/addon/components/theme-setting-editor.js b/app/assets/javascripts/admin/addon/components/theme-setting-editor.js index cf87683ff7..8ceaf32bbb 100644 --- a/app/assets/javascripts/admin/addon/components/theme-setting-editor.js +++ b/app/assets/javascripts/admin/addon/components/theme-setting-editor.js @@ -1,5 +1,5 @@ -import Component from "@ember/component"; import BufferedContent from "discourse/mixins/buffered-content"; +import Component from "@ember/component"; import SettingComponent from "admin/mixins/setting-component"; import { ajax } from "discourse/lib/ajax"; import { url } from "discourse/lib/computed"; diff --git a/app/assets/javascripts/admin/addon/components/theme-setting-relatives-selector.js b/app/assets/javascripts/admin/addon/components/theme-setting-relatives-selector.js index b23760f665..4f02a14768 100644 --- a/app/assets/javascripts/admin/addon/components/theme-setting-relatives-selector.js +++ b/app/assets/javascripts/admin/addon/components/theme-setting-relatives-selector.js @@ -1,5 +1,5 @@ -import Component from "@ember/component"; import BufferedContent from "discourse/mixins/buffered-content"; +import Component from "@ember/component"; import SettingComponent from "admin/mixins/setting-component"; export default Component.extend(BufferedContent, SettingComponent, { diff --git a/app/assets/javascripts/admin/addon/components/theme-translation.js b/app/assets/javascripts/admin/addon/components/theme-translation.js index 6174aeb4eb..7a598db1c8 100644 --- a/app/assets/javascripts/admin/addon/components/theme-translation.js +++ b/app/assets/javascripts/admin/addon/components/theme-translation.js @@ -1,7 +1,7 @@ -import { alias } from "@ember/object/computed"; -import Component from "@ember/component"; import BufferedContent from "discourse/mixins/buffered-content"; +import Component from "@ember/component"; import SettingComponent from "admin/mixins/setting-component"; +import { alias } from "@ember/object/computed"; export default Component.extend(BufferedContent, SettingComponent, { layoutName: "admin/templates/components/site-setting", diff --git a/app/assets/javascripts/admin/addon/components/themes-list-item.js b/app/assets/javascripts/admin/addon/components/themes-list-item.js index d8af9eabc7..edc1783535 100644 --- a/app/assets/javascripts/admin/addon/components/themes-list-item.js +++ b/app/assets/javascripts/admin/addon/components/themes-list-item.js @@ -1,10 +1,10 @@ -import { gt, and } from "@ember/object/computed"; -import { schedule } from "@ember/runloop"; -import Component from "@ember/component"; +import { and, gt } from "@ember/object/computed"; import discourseComputed, { observes } from "discourse-common/utils/decorators"; -import { iconHTML } from "discourse-common/lib/icon-library"; +import Component from "@ember/component"; import { escape } from "pretty-text/sanitizer"; +import { iconHTML } from "discourse-common/lib/icon-library"; import { isTesting } from "discourse-common/config/environment"; +import { schedule } from "@ember/runloop"; const MAX_COMPONENTS = 4; diff --git a/app/assets/javascripts/admin/addon/components/themes-list.js b/app/assets/javascripts/admin/addon/components/themes-list.js index cdad5e454a..715ca9ccee 100644 --- a/app/assets/javascripts/admin/addon/components/themes-list.js +++ b/app/assets/javascripts/admin/addon/components/themes-list.js @@ -1,6 +1,6 @@ -import { gt, equal } from "@ember/object/computed"; +import { COMPONENTS, THEMES } from "admin/models/theme"; +import { equal, gt } from "@ember/object/computed"; import Component from "@ember/component"; -import { THEMES, COMPONENTS } from "admin/models/theme"; import discourseComputed from "discourse-common/utils/decorators"; import { inject as service } from "@ember/service"; diff --git a/app/assets/javascripts/admin/addon/components/value-list.js b/app/assets/javascripts/admin/addon/components/value-list.js index 9951eee3f4..aa89de7f38 100644 --- a/app/assets/javascripts/admin/addon/components/value-list.js +++ b/app/assets/javascripts/admin/addon/components/value-list.js @@ -1,7 +1,7 @@ import discourseComputed, { on } from "discourse-common/utils/decorators"; -import { makeArray } from "discourse-common/lib/helpers"; import { empty, reads } from "@ember/object/computed"; import Component from "@ember/component"; +import { makeArray } from "discourse-common/lib/helpers"; export default Component.extend({ classNameBindings: [":value-list"], diff --git a/app/assets/javascripts/admin/addon/components/watched-word-form.js b/app/assets/javascripts/admin/addon/components/watched-word-form.js index 5dc9d7b8e6..788103f793 100644 --- a/app/assets/javascripts/admin/addon/components/watched-word-form.js +++ b/app/assets/javascripts/admin/addon/components/watched-word-form.js @@ -1,13 +1,13 @@ -import I18n from "I18n"; -import { isEmpty } from "@ember/utils"; -import { schedule } from "@ember/runloop"; +import discourseComputed, { + observes, + on, +} from "discourse-common/utils/decorators"; import Component from "@ember/component"; +import I18n from "I18n"; import WatchedWord from "admin/models/watched-word"; import bootbox from "bootbox"; -import discourseComputed, { - on, - observes, -} from "discourse-common/utils/decorators"; +import { isEmpty } from "@ember/utils"; +import { schedule } from "@ember/runloop"; export default Component.extend({ classNames: ["watched-word-form"], diff --git a/app/assets/javascripts/admin/addon/components/watched-word-uploader.js b/app/assets/javascripts/admin/addon/components/watched-word-uploader.js index 800c0d4988..00c8ce4d99 100644 --- a/app/assets/javascripts/admin/addon/components/watched-word-uploader.js +++ b/app/assets/javascripts/admin/addon/components/watched-word-uploader.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import Component from "@ember/component"; +import I18n from "I18n"; import UploadMixin from "discourse/mixins/upload"; +import { alias } from "@ember/object/computed"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; export default Component.extend(UploadMixin, { type: "txt", diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js index 880a2c6435..5b4ee4ee0a 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js @@ -1,5 +1,5 @@ -import { popupAjaxError } from "discourse/lib/ajax-error"; import Controller from "@ember/controller"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ actions: { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js index 06e495109c..8d56042a67 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import { isBlank } from "@ember/utils"; import Controller from "@ember/controller"; +import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; +import { isBlank } from "@ember/utils"; import { popupAjaxError } from "discourse/lib/ajax-error"; import showModal from "discourse/lib/show-modal"; diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js index 11251a45e6..28a883d985 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js @@ -1,8 +1,8 @@ -import { bufferedProperty } from "discourse/mixins/buffered-content"; import Controller from "@ember/controller"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import { empty } from "@ember/object/computed"; import { isEmpty } from "@ember/utils"; import { popupAjaxError } from "discourse/lib/ajax-error"; -import { empty } from "@ember/object/computed"; import showModal from "discourse/lib/show-modal"; export default Controller.extend(bufferedProperty("model"), { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js b/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js index c32e70f633..c53adeecf9 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import { alias, equal } from "@ember/object/computed"; import Controller, { inject as controller } from "@ember/controller"; +import { alias, equal } from "@ember/object/computed"; +import { i18n, setting } from "discourse/lib/computed"; +import I18n from "I18n"; import { ajax } from "discourse/lib/ajax"; -import discourseComputed from "discourse-common/utils/decorators"; -import { setting, i18n } from "discourse/lib/computed"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend({ adminBackups: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js b/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js index 8c70f05439..e8a1694e2c 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js @@ -1,5 +1,5 @@ -import { alias } from "@ember/object/computed"; import Controller, { inject as controller } from "@ember/controller"; +import { alias } from "@ember/object/computed"; export default Controller.extend({ adminBackups: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-backups.js b/app/assets/javascripts/admin/addon/controllers/admin-backups.js index 83a93d8898..77dfbc3132 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-backups.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-backups.js @@ -1,4 +1,4 @@ -import { not, and } from "@ember/object/computed"; +import { and, not } from "@ember/object/computed"; import Controller from "@ember/controller"; export default Controller.extend({ noOperationIsRunning: not("model.isOperationRunning"), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-badges-award.js b/app/assets/javascripts/admin/addon/controllers/admin-badges-award.js index f3ef51d701..218b3cb0e0 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-badges-award.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-badges-award.js @@ -1,8 +1,8 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; +import I18n from "I18n"; import { ajax } from "discourse/lib/ajax"; -import { popupAjaxError } from "discourse/lib/ajax-error"; import bootbox from "bootbox"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ saving: false, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-badges-show.js b/app/assets/javascripts/admin/addon/controllers/admin-badges-show.js index 3fec918ba9..3653af5fb1 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-badges-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-badges-show.js @@ -1,12 +1,12 @@ -import I18n from "I18n"; -import discourseComputed, { observes } from "discourse-common/utils/decorators"; -import { reads } from "@ember/object/computed"; import Controller, { inject as controller } from "@ember/controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import { bufferedProperty } from "discourse/mixins/buffered-content"; -import { propertyNotEqual } from "discourse/lib/computed"; -import { run } from "@ember/runloop"; +import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import bootbox from "bootbox"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { propertyNotEqual } from "discourse/lib/computed"; +import { reads } from "@ember/object/computed"; +import { run } from "@ember/runloop"; export default Controller.extend(bufferedProperty("model"), { adminBadges: controller(), @@ -56,6 +56,11 @@ export default Controller.extend(bufferedProperty("model"), { return modelQuery && modelQuery.trim().length > 0; }, + @discourseComputed("model.i18n_name") + textCustomizationPrefix(i18n_name) { + return `badges.${i18n_name}.`; + }, + @observes("model.id") _resetSaving: function () { this.set("saving", false); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-badges.js b/app/assets/javascripts/admin/addon/controllers/admin-badges.js index 433c49bac5..11d78fc4cc 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-badges.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-badges.js @@ -1,6 +1,6 @@ import Controller from "@ember/controller"; -import { inject as service } from "@ember/service"; import discourseComputed from "discourse-common/utils/decorators"; +import { inject as service } from "@ember/service"; export default Controller.extend({ routing: service("-routing"), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-colors-show.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-colors-show.js index 5fa6218839..37394fd17f 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-colors-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-colors-show.js @@ -1,8 +1,8 @@ +import Controller from "@ember/controller"; import I18n from "I18n"; +import bootbox from "bootbox"; import discourseComputed from "discourse-common/utils/decorators"; import { later } from "@ember/runloop"; -import Controller from "@ember/controller"; -import bootbox from "bootbox"; export default Controller.extend({ @discourseComputed("model.colors", "onlyOverridden") diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js index 01898b161a..7f06b1f3f0 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js @@ -1,8 +1,8 @@ -import I18n from "I18n"; -import EmberObject from "@ember/object"; import Controller from "@ember/controller"; -import showModal from "discourse/lib/show-modal"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; +import showModal from "discourse/lib/show-modal"; export default Controller.extend({ @discourseComputed("model.@each.id") diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js index f1190600e8..79813399b2 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; +import I18n from "I18n"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend({ @discourseComputed("model.isSaving") diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js index f5f7a563ef..d20f812ca3 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; import Controller, { inject as controller } from "@ember/controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import { bufferedProperty } from "discourse/mixins/buffered-content"; +import I18n from "I18n"; import { action } from "@ember/object"; import bootbox from "bootbox"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import discourseComputed from "discourse-common/utils/decorators"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend(bufferedProperty("emailTemplate"), { adminCustomizeEmailTemplates: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js index 415cf1d157..a3d7f360e0 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js @@ -1,6 +1,6 @@ -import { sort } from "@ember/object/computed"; -import { action } from "@ember/object"; import Controller from "@ember/controller"; +import { action } from "@ember/object"; +import { sort } from "@ember/object/computed"; export default Controller.extend({ sortedTemplates: sort("emailTemplates", "titleSorting"), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js index 7da0720744..a178f2c999 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js @@ -1,7 +1,7 @@ -import { not } from "@ember/object/computed"; import Controller from "@ember/controller"; import { ajax } from "discourse/lib/ajax"; import { bufferedProperty } from "discourse/mixins/buffered-content"; +import { not } from "@ember/object/computed"; import { propertyEqual } from "discourse/lib/computed"; export default Controller.extend(bufferedProperty("model"), { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js index 889d90a921..2e1536d181 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; -import { url } from "discourse/lib/computed"; +import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; +import { url } from "discourse/lib/computed"; export default Controller.extend({ section: null, @@ -64,5 +64,9 @@ export default Controller.extend({ } } }, + + goBack() { + this.replaceRoute(this.showRouteName, this.model.id); + }, }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js index 9e9afda71d..ba3a2d323c 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js @@ -1,21 +1,21 @@ -import I18n from "I18n"; -import { makeArray } from "discourse-common/lib/helpers"; +import { COMPONENTS, THEMES } from "admin/models/theme"; import { empty, filterBy, - match, mapBy, + match, notEmpty, } from "@ember/object/computed"; import Controller from "@ember/controller"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; +import ThemeSettings from "admin/models/theme-settings"; +import bootbox from "bootbox"; import discourseComputed from "discourse-common/utils/decorators"; -import { url } from "discourse/lib/computed"; +import { makeArray } from "discourse-common/lib/helpers"; import { popupAjaxError } from "discourse/lib/ajax-error"; import showModal from "discourse/lib/show-modal"; -import ThemeSettings from "admin/models/theme-settings"; -import { THEMES, COMPONENTS } from "admin/models/theme"; -import EmberObject from "@ember/object"; -import bootbox from "bootbox"; +import { url } from "discourse/lib/computed"; const THEME_UPLOAD_VAR = 2; diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js index 3ffe9301f1..17dda66040 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js @@ -1,6 +1,6 @@ import Controller from "@ember/controller"; -import discourseComputed from "discourse-common/utils/decorators"; import { THEMES } from "admin/models/theme"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend({ currentTab: THEMES, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js index fe97fb0855..a831b686bc 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js @@ -1,13 +1,13 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { makeArray } from "discourse-common/lib/helpers"; import Controller, { inject } from "@ember/controller"; -import { setting } from "discourse/lib/computed"; import AdminDashboard from "admin/models/admin-dashboard"; -import Report from "admin/models/report"; +import I18n from "I18n"; import PeriodComputationMixin from "admin/mixins/period-computation"; +import Report from "admin/models/report"; import { computed } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; import getURL from "discourse-common/lib/get-url"; +import { makeArray } from "discourse-common/lib/helpers"; +import { setting } from "discourse/lib/computed"; function staticReport(reportType) { return computed("reports.[]", function () { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js index 6781c50bde..16e632d6e2 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js @@ -1,8 +1,8 @@ -import getURL from "discourse-common/lib/get-url"; -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; import PeriodComputationMixin from "admin/mixins/period-computation"; import { computed } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; +import getURL from "discourse-common/lib/get-url"; export default Controller.extend(PeriodComputationMixin, { @discourseComputed diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js index 966304a0e5..ab10591c80 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js @@ -1,7 +1,7 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { debounce } from "@ember/runloop"; import Controller from "@ember/controller"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import discourseComputed from "discourse-common/utils/decorators"; +import discourseDebounce from "discourse-common/lib/debounce"; const { get } = Ember; @@ -34,7 +34,7 @@ export default Controller.extend({ actions: { filterReports(filter) { - debounce(this, this._performFiltering, filter, INPUT_DELAY); + discourseDebounce(this, this._performFiltering, filter, INPUT_DELAY); }, }, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js index 29e1ad0c5a..89955953fb 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js @@ -1,9 +1,9 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Controller, { inject } from "@ember/controller"; -import { setting } from "discourse/lib/computed"; -import { computed } from "@ember/object"; import AdminDashboard from "admin/models/admin-dashboard"; import VersionCheck from "admin/models/version-check"; +import { computed } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; +import { setting } from "discourse/lib/computed"; const PROBLEMS_CHECK_MINUTES = 1; diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js b/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js index 07721cdff0..1500549564 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js @@ -1,11 +1,11 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs"; -import discourseDebounce from "discourse/lib/debounce"; -import { observes } from "discourse-common/utils/decorators"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { observes } from "discourse-common/utils/decorators"; export default AdminEmailLogsController.extend({ @observes("filter.{status,user,address,type}") - filterEmailLogs: discourseDebounce(function () { - this.loadLogs(); - }, INPUT_DELAY), + filterEmailLogs() { + discourseDebounce(this, this.loadLogs, INPUT_DELAY); + }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-index.js b/app/assets/javascripts/admin/addon/controllers/admin-email-index.js index f356731e6d..18bfd4a8c4 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-index.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; -import { empty } from "@ember/object/computed"; import Controller from "@ember/controller"; +import I18n from "I18n"; import { ajax } from "discourse/lib/ajax"; -import { observes } from "discourse-common/utils/decorators"; import bootbox from "bootbox"; +import { empty } from "@ember/object/computed"; +import { observes } from "discourse-common/utils/decorators"; export default Controller.extend({ /** diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js b/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js index 4b6ba80ce6..4210f9cff2 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js @@ -1,8 +1,8 @@ -import { empty, or, notEmpty } from "@ember/object/computed"; +import { empty, notEmpty, or } from "@ember/object/computed"; import Controller from "@ember/controller"; import EmailPreview from "admin/models/email-preview"; -import { popupAjaxError } from "discourse/lib/ajax-error"; import bootbox from "bootbox"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ username: null, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-received.js b/app/assets/javascripts/admin/addon/controllers/admin-email-received.js index ab02337866..0a2933fa23 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-received.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-received.js @@ -1,14 +1,14 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs"; -import discourseDebounce from "discourse/lib/debounce"; -import IncomingEmail from "admin/models/incoming-email"; -import { observes } from "discourse-common/utils/decorators"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import IncomingEmail from "admin/models/incoming-email"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { observes } from "discourse-common/utils/decorators"; export default AdminEmailLogsController.extend({ @observes("filter.{status,from,to,subject}") - filterIncomingEmails: discourseDebounce(function () { - this.loadLogs(IncomingEmail); - }, INPUT_DELAY), + filterIncomingEmails() { + discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY); + }, actions: { loadMore() { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js b/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js index 2c160648c6..89c67f3cf9 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js @@ -1,14 +1,14 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs"; -import discourseDebounce from "discourse/lib/debounce"; -import IncomingEmail from "admin/models/incoming-email"; -import { observes } from "discourse-common/utils/decorators"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import IncomingEmail from "admin/models/incoming-email"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { observes } from "discourse-common/utils/decorators"; export default AdminEmailLogsController.extend({ @observes("filter.{status,from,to,subject,error}") - filterIncomingEmails: discourseDebounce(function () { - this.loadLogs(IncomingEmail); - }, INPUT_DELAY), + filterIncomingEmails() { + discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY); + }, actions: { loadMore() { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js b/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js index 2c7890cde8..5cc83109f8 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js @@ -1,11 +1,11 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs"; -import discourseDebounce from "discourse/lib/debounce"; -import { observes } from "discourse-common/utils/decorators"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { observes } from "discourse-common/utils/decorators"; export default AdminEmailLogsController.extend({ @observes("filter.{status,user,address,type,reply_key}") - filterEmailLogs: discourseDebounce(function () { - this.loadLogs(); - }, INPUT_DELAY), + filterEmailLogs() { + discourseDebounce(this, this.loadLogs, INPUT_DELAY); + }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js b/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js index 07721cdff0..1500549564 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js @@ -1,11 +1,11 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs"; -import discourseDebounce from "discourse/lib/debounce"; -import { observes } from "discourse-common/utils/decorators"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { observes } from "discourse-common/utils/decorators"; export default AdminEmailLogsController.extend({ @observes("filter.{status,user,address,type}") - filterEmailLogs: discourseDebounce(function () { - this.loadLogs(); - }, INPUT_DELAY), + filterEmailLogs() { + discourseDebounce(this, this.loadLogs, INPUT_DELAY); + }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-embedding.js b/app/assets/javascripts/admin/addon/controllers/admin-embedding.js index df7f856ed5..147d4dd35a 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-embedding.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-embedding.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; +import discourseComputed from "discourse-common/utils/decorators"; import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ diff --git a/app/assets/javascripts/admin/addon/controllers/admin-emojis.js b/app/assets/javascripts/admin/addon/controllers/admin-emojis.js index 4019cb188e..94e284c0c9 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-emojis.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-emojis.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; -import { sort } from "@ember/object/computed"; import EmberObject, { action, computed } from "@ember/object"; import Controller from "@ember/controller"; +import I18n from "I18n"; import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import { sort } from "@ember/object/computed"; const ALL_FILTER = "all"; diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js index 134968eb10..ed3cd6489d 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js @@ -1,7 +1,7 @@ import Controller from "@ember/controller"; +import ScreenedEmail from "admin/models/screened-email"; import { exportEntity } from "discourse/lib/export-csv"; import { outputExportResult } from "discourse/lib/export-result"; -import ScreenedEmail from "admin/models/screened-email"; export default Controller.extend({ loading: false, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js index 68ac649425..fb923131ed 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js @@ -1,25 +1,29 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; -import discourseDebounce from "discourse/lib/debounce"; -import { outputExportResult } from "discourse/lib/export-result"; -import { exportEntity } from "discourse/lib/export-csv"; -import ScreenedIpAddress from "admin/models/screened-ip-address"; -import { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import ScreenedIpAddress from "admin/models/screened-ip-address"; import bootbox from "bootbox"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { exportEntity } from "discourse/lib/export-csv"; +import { observes } from "discourse-common/utils/decorators"; +import { outputExportResult } from "discourse/lib/export-result"; export default Controller.extend({ loading: false, filter: null, savedIpAddress: null, - @observes("filter") - show: discourseDebounce(function () { + _debouncedShow() { this.set("loading", true); ScreenedIpAddress.findAll(this.filter).then((result) => { this.setProperties({ model: result, loading: false }); }); - }, INPUT_DELAY), + }, + + @observes("filter") + show() { + discourseDebounce(this, this._debouncedShow, INPUT_DELAY); + }, actions: { allow(record) { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js index 90d008bb86..86621f5968 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js @@ -1,7 +1,7 @@ import Controller from "@ember/controller"; +import ScreenedUrl from "admin/models/screened-url"; import { exportEntity } from "discourse/lib/export-csv"; import { outputExportResult } from "discourse/lib/export-result"; -import ScreenedUrl from "admin/models/screened-url"; export default Controller.extend({ loading: false, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js index 70496049d1..2758a10aa1 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js @@ -1,10 +1,10 @@ import Controller from "@ember/controller"; import EmberObject from "@ember/object"; -import { scheduleOnce } from "@ember/runloop"; +import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; import { exportEntity } from "discourse/lib/export-csv"; import { outputExportResult } from "discourse/lib/export-result"; -import I18n from "I18n"; +import { scheduleOnce } from "@ember/runloop"; export default Controller.extend({ queryParams: ["filters"], diff --git a/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js b/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js index 729cdab0c8..b11b397311 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js @@ -1,22 +1,26 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; -import discourseDebounce from "discourse/lib/debounce"; -import Permalink from "admin/models/permalink"; -import { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import Permalink from "admin/models/permalink"; import bootbox from "bootbox"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { observes } from "discourse-common/utils/decorators"; export default Controller.extend({ loading: false, filter: null, - @observes("filter") - show: discourseDebounce(function () { + _debouncedShow() { Permalink.findAll(this.filter).then((result) => { this.set("model", result); this.set("loading", false); }); - }, INPUT_DELAY), + }, + + @observes("filter") + show() { + discourseDebounce(this, this._debouncedShow, INPUT_DELAY); + }, actions: { recordAdded(arg) { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-plugins.js b/app/assets/javascripts/admin/addon/controllers/admin-plugins.js index 955aaba5c3..d19c5584aa 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-plugins.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-plugins.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend({ @discourseComputed diff --git a/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js b/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js index c20dfc1c2e..64a2c5de93 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend({ queryParams: ["start_date", "end_date", "filters", "chart_grouping"], diff --git a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js index 2e2bcb4f73..bf110796f2 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js @@ -1,5 +1,5 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; +import I18n from "I18n"; export const DEFAULT_PERIOD = "yearly"; export default Controller.extend({ diff --git a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js index 8ee5dd5df1..2d4f22211b 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js @@ -1,6 +1,6 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; import { DEFAULT_PERIOD } from "admin/controllers/admin-search-logs-index"; +import I18n from "I18n"; export default Controller.extend({ loading: false, diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js b/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js index 5a12f1d717..2727c56010 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Controller, { inject as controller } from "@ember/controller"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend({ adminSiteSettings: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js index 02e7ab8f07..58859ae933 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import { isEmpty } from "@ember/utils"; -import { alias } from "@ember/object/computed"; import Controller from "@ember/controller"; -import discourseDebounce from "discourse/lib/debounce"; -import { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import { alias } from "@ember/object/computed"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { isEmpty } from "@ember/utils"; +import { observes } from "discourse-common/utils/decorators"; export default Controller.extend({ filter: null, @@ -112,13 +112,19 @@ export default Controller.extend({ }, @observes("filter", "onlyOverridden", "model") - filterContent: discourseDebounce(function () { - if (this._skipBounce) { - this.set("_skipBounce", false); - } else { - this.filterContentNow(this.categoryNameKey); - } - }, INPUT_DELAY), + filterContent() { + discourseDebounce( + this, + () => { + if (this._skipBounce) { + this.set("_skipBounce", false); + } else { + this.filterContentNow(this.categoryNameKey); + } + }, + INPUT_DELAY + ); + }, actions: { clearFilter() { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js index b33bbe3968..cc7bac3267 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js @@ -1,12 +1,13 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import { bufferedProperty } from "discourse/mixins/buffered-content"; +import I18n from "I18n"; import bootbox from "bootbox"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import discourseComputed from "discourse-common/utils/decorators"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend(bufferedProperty("siteText"), { saved: false, + queryParams: ["locale"], @discourseComputed("buffered.value") saveDisabled(value) { @@ -15,9 +16,11 @@ export default Controller.extend(bufferedProperty("siteText"), { actions: { saveChanges() { - const buffered = this.buffered; + const attrs = this.buffered.getProperties("value"); + attrs.locale = this.locale; + this.siteText - .save(buffered.getProperties("value")) + .save(attrs) .then(() => { this.commitBuffer(); this.set("saved", true); @@ -27,10 +30,11 @@ export default Controller.extend(bufferedProperty("siteText"), { revertChanges() { this.set("saved", false); + bootbox.confirm(I18n.t("admin.site_text.revert_confirm"), (result) => { if (result) { this.siteText - .revert() + .revert(this.locale) .then((props) => { const buffered = this.buffered; buffered.setProperties(props); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js b/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js index e46096c751..2f2b708d17 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js @@ -1,43 +1,88 @@ -import { debounce } from "@ember/runloop"; import Controller from "@ember/controller"; +import discourseComputed from "discourse-common/utils/decorators"; +import discourseDebounce from "discourse-common/lib/debounce"; let lastSearch; export default Controller.extend({ searching: false, siteTexts: null, preferred: false, - queryParams: ["q", "overridden"], + queryParams: ["q", "overridden", "locale"], + locale: null, q: null, overridden: false, + init() { + this._super(...arguments); + + this.set("locale", this.siteSettings.default_locale); + }, + _performSearch() { this.store - .find("site-text", this.getProperties("q", "overridden")) + .find("site-text", this.getProperties("q", "overridden", "locale")) .then((results) => { this.set("siteTexts", results); }) .finally(() => this.set("searching", false)); }, + @discourseComputed() + availableLocales() { + return JSON.parse(this.siteSettings.available_locales); + }, + + @discourseComputed("locale") + fallbackLocaleFullName() { + if (this.siteTexts.extras.fallback_locale) { + return this.availableLocales.find((l) => { + return l.value === this.siteTexts.extras.fallback_locale; + }).name; + } + }, + + @discourseComputed("locale") + showFallbackLocaleWarning() { + return ( + this.siteSettings.allow_user_locale && + this.siteSettings.set_locale_from_accept_language_header && + this.fallbackLocaleFullName + ); + }, + actions: { edit(siteText) { - this.transitionToRoute("adminSiteText.edit", siteText.get("id")); + this.transitionToRoute("adminSiteText.edit", siteText.get("id"), { + queryParams: { + locale: this.locale, + localeFullName: this.availableLocales[this.locale], + }, + }); }, toggleOverridden() { this.toggleProperty("overridden"); this.set("searching", true); - debounce(this, this._performSearch, 400); + discourseDebounce(this, this._performSearch, 400); }, search() { const q = this.q; if (q !== lastSearch) { this.set("searching", true); - debounce(this, this._performSearch, 400); + discourseDebounce(this, this._performSearch, 400); lastSearch = q; } }, + + updateLocale(value) { + this.setProperties({ + searching: true, + locale: value, + }); + + discourseDebounce(this, this._performSearch, 400); + }, }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js b/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js index 6951a7b562..2c5212e4ba 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js @@ -1,11 +1,11 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { alias, sort } from "@ember/object/computed"; -import { next } from "@ember/runloop"; import Controller, { inject as controller } from "@ember/controller"; +import { alias, sort } from "@ember/object/computed"; import GrantBadgeController from "discourse/mixins/grant-badge-controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; +import I18n from "I18n"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; +import { next } from "@ember/runloop"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend(GrantBadgeController, { adminUser: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js b/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js index 913ed729a7..9b37e931da 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js @@ -1,8 +1,8 @@ -import I18n from "I18n"; import { gte, sort } from "@ember/object/computed"; import Controller from "@ember/controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; +import I18n from "I18n"; import bootbox from "bootbox"; +import { popupAjaxError } from "discourse/lib/ajax-error"; const MAX_FIELDS = 30; diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js index 2bed595b3f..81a42481e2 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js @@ -1,16 +1,19 @@ -import I18n from "I18n"; -import { notEmpty, and } from "@ember/object/computed"; -import { inject as service } from "@ember/service"; -import Controller from "@ember/controller"; -import { ajax } from "discourse/lib/ajax"; +import DiscourseURL, { userPath } from "discourse/lib/url"; +import { and, notEmpty } from "@ember/object/computed"; +import { fmt, propertyNotEqual, setting } from "discourse/lib/computed"; +import AdminUser from "admin/models/admin-user"; import CanCheckEmails from "discourse/mixins/can-check-emails"; -import { propertyNotEqual, setting, fmt } from "discourse/lib/computed"; -import { userPath } from "discourse/lib/url"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import discourseComputed from "discourse-common/utils/decorators"; -import { htmlSafe } from "@ember/template"; -import showModal from "discourse/lib/show-modal"; +import Controller from "@ember/controller"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; +import getURL from "discourse-common/lib/get-url"; +import { htmlSafe } from "@ember/template"; +import { iconHTML } from "discourse-common/lib/icon-library"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { inject as service } from "@ember/service"; +import showModal from "discourse/lib/show-modal"; export default Controller.extend(CanCheckEmails, { adminTools: service(), @@ -141,10 +144,21 @@ export default Controller.extend(CanCheckEmails, { actions: { impersonate() { - return this.model.impersonate(); + return this.model + .impersonate() + .then(() => DiscourseURL.redirectTo("/")) + .catch((e) => { + if (e.status === 404) { + bootbox.alert(I18n.t("admin.impersonate.not_found")); + } else { + bootbox.alert(I18n.t("admin.impersonate.invalid")); + } + }); }, logOut() { - return this.model.logOut(); + return this.model + .logOut() + .then(() => bootbox.alert(I18n.t("admin.user.logged_out"))); }, resetBounceScore() { return this.model.resetBounceScore(); @@ -152,20 +166,56 @@ export default Controller.extend(CanCheckEmails, { approve() { return this.model.approve(this.currentUser); }, + + _formatError(event) { + return `http: ${event.status} - ${event.body}`; + }, + deactivate() { - return this.model.deactivate(); + return this.model + .deactivate() + .then(() => + this.model.setProperties({ active: false, can_activate: true }) + ) + .catch((e) => { + const error = I18n.t("admin.user.deactivate_failed", { + error: this._formatError(e), + }); + bootbox.alert(error); + }); }, sendActivationEmail() { - return this.model.sendActivationEmail(); + return this.model + .sendActivationEmail() + .then(() => bootbox.alert(I18n.t("admin.user.activation_email_sent"))) + .catch(popupAjaxError); }, activate() { - return this.model.activate(); + return this.model + .activate() + .then(() => + this.model.setProperties({ + active: true, + can_deactivate: !this.model.staff, + }) + ) + .catch((e) => { + const error = I18n.t("admin.user.activate_failed", { + error: this._formatError(e), + }); + bootbox.alert(error); + }); }, revokeAdmin() { return this.model.revokeAdmin(); }, grantAdmin() { - return this.model.grantAdmin(); + return this.model + .grantAdmin() + .then(() => { + bootbox.alert(I18n.t("admin.user.grant_admin_confirm")); + }) + .catch(popupAjaxError); }, revokeModeration() { return this.model.revokeModeration(); @@ -174,13 +224,41 @@ export default Controller.extend(CanCheckEmails, { return this.model.grantModeration(); }, saveTrustLevel() { - return this.model.saveTrustLevel(); + return this.model + .saveTrustLevel() + .then(() => window.location.reload()) + .catch((e) => { + let error; + if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { + error = e.jqXHR.responseJSON.errors[0]; + } + error = + error || + I18n.t("admin.user.trust_level_change_failed", { + error: this._formatError(e), + }); + bootbox.alert(error); + }); }, restoreTrustLevel() { return this.model.restoreTrustLevel(); }, lockTrustLevel(locked) { - return this.model.lockTrustLevel(locked); + return this.model + .lockTrustLevel(locked) + .then(() => window.location.reload()) + .catch((e) => { + let error; + if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { + error = e.jqXHR.responseJSON.errors[0]; + } + error = + error || + I18n.t("admin.user.trust_level_change_failed", { + error: this._formatError(e), + }); + bootbox.alert(error); + }); }, unsilence() { return this.model.unsilence(); @@ -189,11 +267,119 @@ export default Controller.extend(CanCheckEmails, { return this.model.silence(); }, deleteAllPosts() { - return this.model.deleteAllPosts(); + let deletedPosts = 0; + let deletedPercentage = 0; + const user = this.model; + const message = I18n.messageFormat( + "admin.user.delete_all_posts_confirm_MF", + { + POSTS: user.get("post_count"), + TOPICS: user.get("topic_count"), + } + ); + + const performDelete = (progressModal) => { + this.model + .deleteAllPosts() + .then(({ posts_deleted }) => { + if (posts_deleted === 0) { + user.set("post_count", 0); + progressModal.send("closeModal"); + } else { + deletedPosts += posts_deleted; + deletedPercentage = Math.floor( + (deletedPosts * 100) / user.get("post_count") + ); + progressModal.setProperties({ + deletedPercentage: deletedPercentage, + }); + performDelete(progressModal); + } + }) + .catch((e) => { + progressModal.send("closeModal"); + let error; + AdminUser.find(user.get("id")).then((u) => user.setProperties(u)); + if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { + error = e.jqXHR.responseJSON.errors[0]; + } + error = error || I18n.t("admin.user.delete_posts_failed"); + bootbox.alert(error); + }); + }; + + const buttons = [ + { + label: I18n.t("composer.cancel"), + class: "d-modal-cancel", + link: true, + }, + { + label: + `${iconHTML("exclamation-triangle")} ` + + I18n.t("admin.user.delete_all_posts"), + class: "btn btn-danger", + callback: () => { + const progressModal = openProgressModal(); + performDelete(progressModal); + }, + }, + ]; + + const openProgressModal = () => { + return showModal("admin-delete-user-posts-progress", { + admin: true, + }); + }; + + bootbox.dialog(message, buttons, { classes: "delete-all-posts" }); }, + anonymize() { - return this.model.anonymize(); + const user = this.model; + const message = I18n.t("admin.user.anonymize_confirm"); + + const performAnonymize = () => { + this.model + .anonymize() + .then((data) => { + if (data.success) { + if (data.username) { + document.location = getURL( + `/admin/users/${user.get("id")}/${data.username}` + ); + } else { + document.location = getURL("/admin/users/list/active"); + } + } else { + bootbox.alert(I18n.t("admin.user.anonymize_failed")); + if (data.user) { + user.setProperties(data.user); + } + } + }) + .catch(() => bootbox.alert(I18n.t("admin.user.anonymize_failed"))); + }; + const buttons = [ + { + label: I18n.t("composer.cancel"), + class: "cancel", + link: true, + }, + { + label: + `${iconHTML("exclamation-triangle")} ` + + I18n.t("admin.user.anonymize_yes"), + class: "btn btn-danger", + callback: () => { + performAnonymize(); + }, + }, + ]; + + bootbox.dialog(message, buttons, { classes: "delete-user-modal" }); }, + disableSecondFactor() { return this.model.disableSecondFactor(); }, @@ -210,11 +396,68 @@ export default Controller.extend(CanCheckEmails, { destroy() { const postCount = this.get("model.post_count"); const maxPostCount = this.siteSettings.delete_all_posts_max; - if (postCount <= maxPostCount) { - return this.model.destroy({ deletePosts: true }); - } else { - return this.model.destroy(); - } + const user = this.model; + const message = I18n.t("admin.user.delete_confirm"); + const location = document.location.pathname; + + const performDestroy = (block) => { + bootbox.dialog(I18n.t("admin.user.deleting_user")); + let formData = { context: location }; + if (block) { + formData["block_email"] = true; + formData["block_urls"] = true; + formData["block_ip"] = true; + } + if (postCount <= maxPostCount) { + formData["delete_posts"] = true; + } + this.model + .destroy(formData) + .then((data) => { + if (data.deleted) { + if (/^\/admin\/users\/list\//.test(location)) { + document.location = location; + } else { + document.location = getURL("/admin/users/list/active"); + } + } else { + bootbox.alert(I18n.t("admin.user.delete_failed")); + if (data.user) { + user.setProperties(data.user); + } + } + }) + .catch(() => { + AdminUser.find(user.get("id")).then((u) => user.setProperties(u)); + bootbox.alert(I18n.t("admin.user.delete_failed")); + }); + }; + + const buttons = [ + { + label: I18n.t("composer.cancel"), + class: "btn", + link: true, + }, + { + label: + `${iconHTML("exclamation-triangle")} ` + + I18n.t("admin.user.delete_and_block"), + class: "btn btn-danger", + callback: () => { + performDestroy(true); + }, + }, + { + label: I18n.t("admin.user.delete_dont_block"), + class: "btn btn-primary", + callback: () => { + performDestroy(false); + }, + }, + ]; + + bootbox.dialog(message, buttons, { classes: "delete-user-modal" }); }, promptTargetUser() { @@ -235,7 +478,31 @@ export default Controller.extend(CanCheckEmails, { }, merge(targetUsername) { - return this.model.merge({ targetUsername }); + const user = this.model; + const location = document.location.pathname; + + let formData = { context: location }; + + if (targetUsername) { + formData["target_username"] = targetUsername; + } + + this.model + .merge(formData) + .then((response) => { + if (response.success) { + showModal("admin-merge-users-progress", { + admin: true, + model: this.model, + }); + } else { + bootbox.alert(I18n.t("admin.user.merge_failed")); + } + }) + .catch(() => { + AdminUser.find(user.id).then((u) => user.setProperties(u)); + bootbox.alert(I18n.t("admin.user.merge_failed")); + }); }, viewActionLogs() { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js b/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js index fd20b6c308..b0b25706e5 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js @@ -1,11 +1,11 @@ -import I18n from "I18n"; import discourseComputed, { observes } from "discourse-common/utils/decorators"; -import Controller from "@ember/controller"; -import discourseDebounce from "discourse/lib/debounce"; -import { i18n } from "discourse/lib/computed"; import AdminUser from "admin/models/admin-user"; import CanCheckEmails from "discourse/mixins/can-check-emails"; +import Controller from "@ember/controller"; +import I18n from "I18n"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { i18n } from "discourse/lib/computed"; export default Controller.extend(CanCheckEmails, { model: null, @@ -32,9 +32,9 @@ export default Controller.extend(CanCheckEmails, { }, @observes("listFilter") - _filterUsers: discourseDebounce(function () { - this.resetFilters(); - }, INPUT_DELAY), + _filterUsers() { + discourseDebounce(this, this.resetFilters, INPUT_DELAY); + }, resetFilters() { this._page = 1; diff --git a/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js b/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js index 6a9b78bf29..1daa8a6ec3 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js @@ -1,13 +1,13 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { or } from "@ember/object/computed"; -import { schedule } from "@ember/runloop"; import Controller, { inject as controller } from "@ember/controller"; +import I18n from "I18n"; import WatchedWord from "admin/models/watched-word"; import { ajax } from "discourse/lib/ajax"; -import { fmt } from "discourse/lib/computed"; -import showModal from "discourse/lib/show-modal"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; +import { fmt } from "discourse/lib/computed"; +import { or } from "@ember/object/computed"; +import { schedule } from "@ember/runloop"; +import showModal from "discourse/lib/show-modal"; export default Controller.extend({ adminWatchedWords: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js b/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js index 151fc82c33..cfd86c6c22 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js @@ -1,10 +1,10 @@ -import { isEmpty } from "@ember/utils"; -import { alias } from "@ember/object/computed"; -import EmberObject from "@ember/object"; import Controller from "@ember/controller"; -import discourseDebounce from "discourse/lib/debounce"; -import { observes } from "discourse-common/utils/decorators"; +import EmberObject from "@ember/object"; import { INPUT_DELAY } from "discourse-common/config/environment"; +import { alias } from "@ember/object/computed"; +import discourseDebounce from "discourse-common/lib/debounce"; +import { isEmpty } from "@ember/utils"; +import { observes } from "discourse-common/utils/decorators"; export default Controller.extend({ filter: null, @@ -48,10 +48,16 @@ export default Controller.extend({ }, @observes("filter") - filterContent: discourseDebounce(function () { - this.filterContentNow(); - this.set("filtered", !isEmpty(this.filter)); - }, INPUT_DELAY), + filterContent() { + discourseDebounce( + this, + function () { + this.filterContentNow(); + this.set("filtered", !isEmpty(this.filter)); + }, + INPUT_DELAY + ); + }, actions: { clearFilter() { diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js index 49c87926d2..cdb4c9b615 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js @@ -1,7 +1,7 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import Controller from "@ember/controller"; import { ajax } from "discourse/lib/ajax"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js index f2e9f2178d..26b5fb20d0 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js @@ -1,13 +1,13 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { isEmpty } from "@ember/utils"; -import { alias } from "@ember/object/computed"; import Controller, { inject as controller } from "@ember/controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import { extractDomainFromUrl } from "discourse/lib/utilities"; import EmberObject from "@ember/object"; -import { isAbsoluteURL } from "discourse-common/lib/get-url"; +import I18n from "I18n"; +import { alias } from "@ember/object/computed"; import bootbox from "bootbox"; +import discourseComputed from "discourse-common/utils/decorators"; +import { extractDomainFromUrl } from "discourse/lib/utilities"; +import { isAbsoluteURL } from "discourse-common/lib/get-url"; +import { isEmpty } from "@ember/utils"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ adminWebHooks: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js index cc13ea9e9d..6e1acf97dc 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; -import { popupAjaxError } from "discourse/lib/ajax-error"; +import I18n from "I18n"; import bootbox from "bootbox"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend({ actions: { diff --git a/app/assets/javascripts/admin/addon/controllers/admin.js b/app/assets/javascripts/admin/addon/controllers/admin.js index 4c51eb38b7..03838b789c 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin.js +++ b/app/assets/javascripts/admin/addon/controllers/admin.js @@ -1,7 +1,7 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { inject as service } from "@ember/service"; import Controller from "@ember/controller"; import { dasherize } from "@ember/string"; +import discourseComputed from "discourse-common/utils/decorators"; +import { inject as service } from "@ember/service"; export default Controller.extend({ router: service(), diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-add-upload.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-add-upload.js index 12b2be4f4a..876ac3ae9a 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-add-upload.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-add-upload.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import { isEmpty } from "@ember/utils"; -import { and, not } from "@ember/object/computed"; import Controller, { inject as controller } from "@ember/controller"; +import { and, not } from "@ember/object/computed"; +import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import ModalFunctionality from "discourse/mixins/modal-functionality"; import { ajax } from "discourse/lib/ajax"; -import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import { isEmpty } from "@ember/utils"; import { popupAjaxError } from "discourse/lib/ajax-error"; const THEME_FIELD_VARIABLE_TYPE_IDS = [2, 3, 4]; diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-badge-preview.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-badge-preview.js index 90af87cb73..322436303f 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-badge-preview.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-badge-preview.js @@ -1,6 +1,6 @@ -import I18n from "I18n"; import { alias, map } from "@ember/object/computed"; import Controller from "@ember/controller"; +import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; import { escapeExpression } from "discourse/lib/utilities"; diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-delete-user-posts-progress.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-delete-user-posts-progress.js new file mode 100644 index 0000000000..61b9bae999 --- /dev/null +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-delete-user-posts-progress.js @@ -0,0 +1,6 @@ +import Controller from "@ember/controller"; +import ModalFunctionality from "discourse/mixins/modal-functionality"; + +export default Controller.extend(ModalFunctionality, { + deletedPercentage: 0, +}); diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-edit-badge-groupings.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-edit-badge-groupings.js index cedbf43632..aa7d5665fa 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-edit-badge-groupings.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-edit-badge-groupings.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; -import Controller from "@ember/controller"; import { A } from "@ember/array"; -import { ajax } from "discourse/lib/ajax"; +import Controller from "@ember/controller"; +import I18n from "I18n"; import ModalFunctionality from "discourse/mixins/modal-functionality"; -import { observes } from "discourse-common/utils/decorators"; +import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import { observes } from "discourse-common/utils/decorators"; export default Controller.extend(ModalFunctionality, { @observes("model") diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js index 45df8e4628..6055baa1fe 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js @@ -1,7 +1,7 @@ -import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; -import ModalFunctionality from "discourse/mixins/modal-functionality"; import IncomingEmail from "admin/models/incoming-email"; +import ModalFunctionality from "discourse/mixins/modal-functionality"; +import discourseComputed from "discourse-common/utils/decorators"; import { longDate } from "discourse/lib/formatter"; import { popupAjaxError } from "discourse/lib/ajax-error"; diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-install-theme.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-install-theme.js index 4bdb6ca85c..01cc315423 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-install-theme.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-install-theme.js @@ -1,12 +1,12 @@ -import I18n from "I18n"; -import { equal, match, alias } from "@ember/object/computed"; +import { COMPONENTS, THEMES } from "admin/models/theme"; import Controller, { inject as controller } from "@ember/controller"; +import { alias, equal, match } from "@ember/object/computed"; +import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import ModalFunctionality from "discourse/mixins/modal-functionality"; +import { POPULAR_THEMES } from "discourse-common/helpers/popular-themes"; import { ajax } from "discourse/lib/ajax"; import { popupAjaxError } from "discourse/lib/ajax-error"; -import discourseComputed, { observes } from "discourse-common/utils/decorators"; -import { THEMES, COMPONENTS } from "admin/models/theme"; -import { POPULAR_THEMES } from "discourse-common/helpers/popular-themes"; import { set } from "@ember/object"; const MIN_NAME_LENGTH = 4; @@ -26,7 +26,6 @@ export default Controller.extend(ModalFunctionality, { checkPrivate: match("uploadUrl", /^git/), localFile: null, uploadUrl: null, - urlPlaceholder: "https://github.com/discourse/sample_theme", advancedVisible: false, selectedType: alias("themesController.currentTab"), component: equal("selectedType", COMPONENTS), @@ -76,12 +75,15 @@ export default Controller.extend(ModalFunctionality, { ); }, + @discourseComputed("privateChecked") + urlPlaceholder(privateChecked) { + return privateChecked + ? "git@github.com:discourse/sample_theme.git" + : "https://github.com/discourse/sample_theme"; + }, + @observes("privateChecked") privateWasChecked() { - this.privateChecked - ? this.set("urlPlaceholder", "git@github.com:discourse/sample_theme.git") - : this.set("urlPlaceholder", "https://github.com/discourse/sample_theme"); - const checked = this.privateChecked; if (checked && !this._keyLoading) { this._keyLoading = true; @@ -125,6 +127,27 @@ export default Controller.extend(ModalFunctionality, { return privateChecked && checkPrivate && publicKey; }, + onClose() { + this.setProperties({ + duplicateRemoteThemeWarning: null, + privateChecked: false, + privateKey: null, + localFile: null, + uploadUrl: null, + publicKey: null, + branch: null, + }); + }, + + themeHasSameUrl(theme, url) { + const themeUrl = theme.remote_theme && theme.remote_theme.remote_url; + return ( + themeUrl && + url && + url.replace(/\.git$/, "") === themeUrl.replace(/\.git$/, "") + ); + }, + actions: { uploadLocaleFile() { this.set("localFile", $("#file-input")[0].files[0]); @@ -167,6 +190,17 @@ export default Controller.extend(ModalFunctionality, { } if (this.remote || this.popular) { + const duplicate = this.themesController.model.content.find((theme) => + this.themeHasSameUrl(theme, this.uploadUrl) + ); + if (duplicate && !this.duplicateRemoteThemeWarning) { + const warning = I18n.t( + "admin.customize.theme.duplicate_remote_theme", + { name: duplicate.name } + ); + this.set("duplicateRemoteThemeWarning", warning); + return; + } options.data = { remote: this.uploadUrl, branch: this.branch, diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-confirmation.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-confirmation.js index f2233c07a3..48be2946bc 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-confirmation.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-confirmation.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; import Controller, { inject as controller } from "@ember/controller"; +import I18n from "I18n"; import ModalFunctionality from "discourse/mixins/modal-functionality"; -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import { action } from "@ember/object"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend(ModalFunctionality, { adminUserIndex: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-progress.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-progress.js new file mode 100644 index 0000000000..3d9248d36d --- /dev/null +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-progress.js @@ -0,0 +1,31 @@ +import Controller from "@ember/controller"; +import DiscourseURL from "discourse/lib/url"; +import I18n from "I18n"; +import ModalFunctionality from "discourse/mixins/modal-functionality"; +import messageBus from "message-bus-client"; + +export default Controller.extend(ModalFunctionality, { + message: I18n.t("admin.user.merging_user"), + + onShow() { + messageBus.subscribe("/merge_user", (data) => { + if (data.merged) { + if (/^\/admin\/users\/list\//.test(location)) { + DiscourseURL.redirectTo(location); + } else { + DiscourseURL.redirectTo( + `/admin/users/${data.user.id}/${data.user.username}` + ); + } + } else if (data.message) { + this.set("message", data.message); + } else if (data.failed) { + this.set("message", I18n.t("admin.user.merge_failed")); + } + }); + }, + + onClose() { + this.messageBus.unsubscribe("/merge_user"); + }, +}); diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-prompt.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-prompt.js index baaf7cef7a..2a088dff31 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-prompt.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-merge-users-prompt.js @@ -1,8 +1,8 @@ import Controller, { inject as controller } from "@ember/controller"; import ModalFunctionality from "discourse/mixins/modal-functionality"; -import discourseComputed from "discourse-common/utils/decorators"; -import { alias } from "@ember/object/computed"; import { action } from "@ember/object"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend(ModalFunctionality, { adminUserIndex: controller(), diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-reseed.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-reseed.js index b29a800aa0..672f6d8db3 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-reseed.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-reseed.js @@ -1,5 +1,5 @@ -import I18n from "I18n"; import Controller from "@ember/controller"; +import I18n from "I18n"; import ModalFunctionality from "discourse/mixins/modal-functionality"; import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-silence-user.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-silence-user.js index e379b903c2..b76565f815 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-silence-user.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-silence-user.js @@ -1,7 +1,7 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { isEmpty } from "@ember/utils"; import Controller from "@ember/controller"; import PenaltyController from "admin/mixins/penalty-controller"; +import discourseComputed from "discourse-common/utils/decorators"; +import { isEmpty } from "@ember/utils"; export default Controller.extend(PenaltyController, { silenceUntil: null, diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-suspend-user.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-suspend-user.js index 4997f62947..2712b57cf2 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-suspend-user.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-suspend-user.js @@ -1,7 +1,7 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { isEmpty } from "@ember/utils"; import Controller from "@ember/controller"; import PenaltyController from "admin/mixins/penalty-controller"; +import discourseComputed from "discourse-common/utils/decorators"; +import { isEmpty } from "@ember/utils"; export default Controller.extend(PenaltyController, { suspendUntil: null, diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-uploaded-image-list.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-uploaded-image-list.js index 0aeffaad59..7ab4cb6984 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-uploaded-image-list.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-uploaded-image-list.js @@ -1,5 +1,5 @@ +import { observes, on } from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; -import { on, observes } from "discourse-common/utils/decorators"; import ModalFunctionality from "discourse/mixins/modal-functionality"; export default Controller.extend(ModalFunctionality, { diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js index b088cccb75..215cc08a6d 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js @@ -1,6 +1,6 @@ import Controller from "@ember/controller"; -import discourseComputed from "discourse-common/utils/decorators"; import ModalFunctionality from "discourse/mixins/modal-functionality"; +import discourseComputed from "discourse-common/utils/decorators"; export default Controller.extend(ModalFunctionality, { @discourseComputed("value", "model.compiledRegularExpression") diff --git a/app/assets/javascripts/admin/addon/helpers/check-icon.js b/app/assets/javascripts/admin/addon/helpers/check-icon.js index 51fb238550..14ae3e649c 100644 --- a/app/assets/javascripts/admin/addon/helpers/check-icon.js +++ b/app/assets/javascripts/admin/addon/helpers/check-icon.js @@ -1,6 +1,6 @@ +import { htmlSafe } from "@ember/template"; import { registerUnbound } from "discourse-common/lib/helpers"; import { renderIcon } from "discourse-common/lib/icon-library"; -import { htmlSafe } from "@ember/template"; registerUnbound("check-icon", function (value) { let icon = value ? "check" : "times"; diff --git a/app/assets/javascripts/admin/addon/helpers/disposition-icon.js b/app/assets/javascripts/admin/addon/helpers/disposition-icon.js index 03960ff289..5dbd069cf3 100644 --- a/app/assets/javascripts/admin/addon/helpers/disposition-icon.js +++ b/app/assets/javascripts/admin/addon/helpers/disposition-icon.js @@ -1,5 +1,5 @@ -import { iconHTML } from "discourse-common/lib/icon-library"; import Helper from "@ember/component/helper"; +import { iconHTML } from "discourse-common/lib/icon-library"; export default Helper.extend({ compute([disposition]) { diff --git a/app/assets/javascripts/admin/addon/helpers/post-action-title.js b/app/assets/javascripts/admin/addon/helpers/post-action-title.js index 2d8e3c3fe8..9a1d213d93 100644 --- a/app/assets/javascripts/admin/addon/helpers/post-action-title.js +++ b/app/assets/javascripts/admin/addon/helpers/post-action-title.js @@ -1,5 +1,5 @@ -import I18n from "I18n"; import Helper from "@ember/component/helper"; +import I18n from "I18n"; function postActionTitle([id, nameKey]) { let title = I18n.t(`admin.flags.short_names.${nameKey}`, { diff --git a/app/assets/javascripts/admin/addon/helpers/preserve-newlines.js b/app/assets/javascripts/admin/addon/helpers/preserve-newlines.js index 16639f30cc..3d7f2e019e 100644 --- a/app/assets/javascripts/admin/addon/helpers/preserve-newlines.js +++ b/app/assets/javascripts/admin/addon/helpers/preserve-newlines.js @@ -1,5 +1,5 @@ -import { htmlHelper } from "discourse-common/lib/helpers"; import { escapeExpression } from "discourse/lib/utilities"; +import { htmlHelper } from "discourse-common/lib/helpers"; export default htmlHelper((str) => escapeExpression(str).replace(/\n/g, "
") diff --git a/app/assets/javascripts/admin/addon/mixins/penalty-controller.js b/app/assets/javascripts/admin/addon/mixins/penalty-controller.js index 250d60664f..55514dfe48 100644 --- a/app/assets/javascripts/admin/addon/mixins/penalty-controller.js +++ b/app/assets/javascripts/admin/addon/mixins/penalty-controller.js @@ -1,10 +1,10 @@ import I18n from "I18n"; -import ModalFunctionality from "discourse/mixins/modal-functionality"; -import { extractError } from "discourse/lib/ajax-error"; import Mixin from "@ember/object/mixin"; -import { next } from "@ember/runloop"; +import ModalFunctionality from "discourse/mixins/modal-functionality"; import { Promise } from "rsvp"; import bootbox from "bootbox"; +import { extractError } from "discourse/lib/ajax-error"; +import { next } from "@ember/runloop"; export default Mixin.create(ModalFunctionality, { errorMessage: null, diff --git a/app/assets/javascripts/admin/addon/mixins/period-computation.js b/app/assets/javascripts/admin/addon/mixins/period-computation.js index 7b8afe796a..b46503e73c 100644 --- a/app/assets/javascripts/admin/addon/mixins/period-computation.js +++ b/app/assets/javascripts/admin/addon/mixins/period-computation.js @@ -1,6 +1,6 @@ -import discourseComputed from "discourse-common/utils/decorators"; import DiscourseURL from "discourse/lib/url"; import Mixin from "@ember/object/mixin"; +import discourseComputed from "discourse-common/utils/decorators"; export default Mixin.create({ queryParams: ["period"], diff --git a/app/assets/javascripts/admin/addon/mixins/setting-component.js b/app/assets/javascripts/admin/addon/mixins/setting-component.js index c7d42df43a..d96bd40c22 100644 --- a/app/assets/javascripts/admin/addon/mixins/setting-component.js +++ b/app/assets/javascripts/admin/addon/mixins/setting-component.js @@ -1,14 +1,14 @@ -import I18n from "I18n"; -import { warn } from "@ember/debug"; -import discourseComputed from "discourse-common/utils/decorators"; import { alias, oneWay } from "@ember/object/computed"; -import { categoryLinkHTML } from "discourse/helpers/category-link"; -import { on } from "@ember/object/evented"; +import I18n from "I18n"; import Mixin from "@ember/object/mixin"; -import showModal from "discourse/lib/show-modal"; import { Promise } from "rsvp"; import { ajax } from "discourse/lib/ajax"; +import { categoryLinkHTML } from "discourse/helpers/category-link"; +import discourseComputed from "discourse-common/utils/decorators"; import { htmlSafe } from "@ember/template"; +import { on } from "@ember/object/evented"; +import showModal from "discourse/lib/show-modal"; +import { warn } from "@ember/debug"; const CUSTOM_TYPES = [ "bool", diff --git a/app/assets/javascripts/admin/addon/mixins/setting-object.js b/app/assets/javascripts/admin/addon/mixins/setting-object.js index 5a40360b08..29dbb0d967 100644 --- a/app/assets/javascripts/admin/addon/mixins/setting-object.js +++ b/app/assets/javascripts/admin/addon/mixins/setting-object.js @@ -1,7 +1,7 @@ import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { computed } from "@ember/object"; import Mixin from "@ember/object/mixin"; +import { computed } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; import { isPresent } from "@ember/utils"; export default Mixin.create({ diff --git a/app/assets/javascripts/admin/addon/models/admin-dashboard.js b/app/assets/javascripts/admin/addon/models/admin-dashboard.js index dec30faf2d..400ebe161b 100644 --- a/app/assets/javascripts/admin/addon/models/admin-dashboard.js +++ b/app/assets/javascripts/admin/addon/models/admin-dashboard.js @@ -1,5 +1,5 @@ -import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; const GENERAL_ATTRIBUTES = [ "updated_at", diff --git a/app/assets/javascripts/admin/addon/models/admin-user.js b/app/assets/javascripts/admin/addon/models/admin-user.js index 0bc1132623..1a86426c5b 100644 --- a/app/assets/javascripts/admin/addon/models/admin-user.js +++ b/app/assets/javascripts/admin/addon/models/admin-user.js @@ -1,16 +1,14 @@ -import getURL from "discourse-common/lib/get-url"; -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { filter, or, gt, lt, not } from "@ember/object/computed"; -import { iconHTML } from "discourse-common/lib/icon-library"; -import { ajax } from "discourse/lib/ajax"; -import { propertyNotEqual } from "discourse/lib/computed"; -import { popupAjaxError } from "discourse/lib/ajax-error"; +import { filter, gt, lt, not, or } from "@ember/object/computed"; import Group from "discourse/models/group"; -import DiscourseURL, { userPath } from "discourse/lib/url"; +import I18n from "I18n"; import { Promise } from "rsvp"; import User from "discourse/models/user"; -import bootbox from "bootbox"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; +import getURL from "discourse-common/lib/get-url"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { propertyNotEqual } from "discourse/lib/computed"; +import { userPath } from "discourse/lib/url"; const wrapAdmin = (user) => (user ? AdminUser.create(user) : null); @@ -80,74 +78,9 @@ const AdminUser = User.extend({ }, deleteAllPosts() { - let deletedPosts = 0; - const user = this; - const message = I18n.messageFormat( - "admin.user.delete_all_posts_confirm_MF", - { - POSTS: user.get("post_count"), - TOPICS: user.get("topic_count"), - } - ); - const buttons = [ - { - label: I18n.t("composer.cancel"), - class: "d-modal-cancel", - link: true, - }, - { - label: - `${iconHTML("exclamation-triangle")} ` + - I18n.t("admin.user.delete_all_posts"), - class: "btn btn-danger", - callback: () => { - openProgressModal(); - performDelete(); - }, - }, - ]; - const openProgressModal = () => { - bootbox.dialog( - `

${I18n.t( - "admin.user.delete_posts_progress" - )}

`, - [], - { classes: "delete-posts-progress" } - ); - }; - const performDelete = () => { - let deletedPercentage = 0; - return ajax(`/admin/users/${user.get("id")}/delete_posts_batch`, { - type: "PUT", - }) - .then(({ posts_deleted }) => { - if (posts_deleted === 0) { - user.set("post_count", 0); - bootbox.hideAll(); - } else { - deletedPosts += posts_deleted; - deletedPercentage = Math.floor( - (deletedPosts * 100) / user.get("post_count") - ); - $(".delete-posts-progress .progress-bar > span").css({ - width: `${deletedPercentage}%`, - }); - performDelete(); - } - }) - .catch((e) => { - bootbox.hideAll(); - let error; - AdminUser.find(user.get("id")).then((u) => user.setProperties(u)); - if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { - error = e.jqXHR.responseJSON.errors[0]; - } - error = error || I18n.t("admin.user.delete_posts_failed"); - bootbox.alert(error); - }); - }; - - bootbox.dialog(message, buttons, { classes: "delete-all-posts" }); + return ajax(`/admin/users/${this.get("id")}/delete_posts_batch`, { + type: "PUT", + }); }, revokeAdmin() { @@ -165,11 +98,7 @@ const AdminUser = User.extend({ grantAdmin() { return ajax(`/admin/users/${this.id}/grant_admin`, { type: "PUT", - }) - .then(() => { - bootbox.alert(I18n.t("admin.user.grant_admin_confirm")); - }) - .catch(popupAjaxError); + }); }, revokeModeration() { @@ -232,20 +161,7 @@ const AdminUser = User.extend({ return ajax(`/admin/users/${this.id}/trust_level`, { type: "PUT", data: { level: this.trust_level }, - }) - .then(() => window.location.reload()) - .catch((e) => { - let error; - if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { - error = e.jqXHR.responseJSON.errors[0]; - } - error = - error || - I18n.t("admin.user.trust_level_change_failed", { - error: this._formatError(e), - }); - bootbox.alert(error); - }); + }); }, restoreTrustLevel() { @@ -256,20 +172,7 @@ const AdminUser = User.extend({ return ajax(`/admin/users/${this.id}/trust_level_lock`, { type: "PUT", data: { locked: !!locked }, - }) - .then(() => window.location.reload()) - .catch((e) => { - let error; - if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { - error = e.jqXHR.responseJSON.errors[0]; - } - error = - error || - I18n.t("admin.user.trust_level_change_failed", { - error: this._formatError(e), - }); - bootbox.alert(error); - }); + }); }, canLockTrustLevel: lt("trust_level", 4), @@ -300,49 +203,27 @@ const AdminUser = User.extend({ return ajax("/admin/users/" + this.id + "/log_out", { type: "POST", data: { username_or_email: this.username }, - }).then(() => bootbox.alert(I18n.t("admin.user.logged_out"))); + }); }, impersonate() { return ajax("/admin/impersonate", { type: "POST", data: { username_or_email: this.username }, - }) - .then(() => (document.location = getURL("/"))) - .catch((e) => { - if (e.status === 404) { - bootbox.alert(I18n.t("admin.impersonate.not_found")); - } else { - bootbox.alert(I18n.t("admin.impersonate.invalid")); - } - }); + }); }, activate() { return ajax(`/admin/users/${this.id}/activate`, { type: "PUT", - }) - .then(() => window.location.reload()) - .catch((e) => { - const error = I18n.t("admin.user.activate_failed", { - error: this._formatError(e), - }); - bootbox.alert(error); - }); + }); }, deactivate() { return ajax(`/admin/users/${this.id}/deactivate`, { type: "PUT", data: { context: document.location.pathname }, - }) - .then(() => window.location.reload()) - .catch((e) => { - const error = I18n.t("admin.user.deactivate_failed", { - error: this._formatError(e), - }); - bootbox.alert(error); - }); + }); }, unsilence() { @@ -370,160 +251,27 @@ const AdminUser = User.extend({ return ajax(userPath("action/send_activation_email"), { type: "POST", data: { username: this.username }, - }) - .then(() => bootbox.alert(I18n.t("admin.user.activation_email_sent"))) - .catch(popupAjaxError); + }); }, anonymize() { - const user = this; - const message = I18n.t("admin.user.anonymize_confirm"); - - const performAnonymize = function () { - return ajax(`/admin/users/${user.get("id")}/anonymize.json`, { - type: "PUT", - }) - .then(function (data) { - if (data.success) { - if (data.username) { - document.location = getURL( - `/admin/users/${user.get("id")}/${data.username}` - ); - } else { - document.location = getURL("/admin/users/list/active"); - } - } else { - bootbox.alert(I18n.t("admin.user.anonymize_failed")); - if (data.user) { - user.setProperties(data.user); - } - } - }) - .catch(() => bootbox.alert(I18n.t("admin.user.anonymize_failed"))); - }; - - const buttons = [ - { - label: I18n.t("composer.cancel"), - class: "cancel", - link: true, - }, - { - label: - `${iconHTML("exclamation-triangle")} ` + - I18n.t("admin.user.anonymize_yes"), - class: "btn btn-danger", - callback: function () { - performAnonymize(); - }, - }, - ]; - - bootbox.dialog(message, buttons, { classes: "delete-user-modal" }); + return ajax(`/admin/users/${this.id}/anonymize.json`, { + type: "PUT", + }); }, - destroy(opts) { - const user = this; - const message = I18n.t("admin.user.delete_confirm"); - const location = document.location.pathname; - - const performDestroy = function (block) { - bootbox.dialog(I18n.t("admin.user.deleting_user")); - let formData = { context: location }; - if (block) { - formData["block_email"] = true; - formData["block_urls"] = true; - formData["block_ip"] = true; - } - if (opts && opts.deletePosts) { - formData["delete_posts"] = true; - } - return ajax(`/admin/users/${user.get("id")}.json`, { - type: "DELETE", - data: formData, - }) - .then(function (data) { - if (data.deleted) { - if (/^\/admin\/users\/list\//.test(location)) { - document.location = location; - } else { - document.location = getURL("/admin/users/list/active"); - } - } else { - bootbox.alert(I18n.t("admin.user.delete_failed")); - if (data.user) { - user.setProperties(data.user); - } - } - }) - .catch(function () { - AdminUser.find(user.get("id")).then((u) => user.setProperties(u)); - bootbox.alert(I18n.t("admin.user.delete_failed")); - }); - }; - - const buttons = [ - { - label: I18n.t("composer.cancel"), - class: "btn", - link: true, - }, - { - label: - `${iconHTML("exclamation-triangle")} ` + - I18n.t("admin.user.delete_and_block"), - class: "btn btn-danger", - callback: function () { - performDestroy(true); - }, - }, - { - label: I18n.t("admin.user.delete_dont_block"), - class: "btn btn-primary", - callback: function () { - performDestroy(false); - }, - }, - ]; - - bootbox.dialog(message, buttons, { classes: "delete-user-modal" }); + destroy(formData) { + return ajax(`/admin/users/${this.id}.json`, { + type: "DELETE", + data: formData, + }); }, - merge(opts) { - const user = this; - const location = document.location.pathname; - - bootbox.dialog(I18n.t("admin.user.merging_user")); - let formData = { context: location }; - - if (opts && opts.targetUsername) { - formData["target_username"] = opts.targetUsername; - } - - return ajax(`/admin/users/${user.id}/merge.json`, { + merge(formData) { + return ajax(`/admin/users/${this.id}/merge.json`, { type: "POST", data: formData, - }) - .then((data) => { - if (data.merged) { - if (/^\/admin\/users\/list\//.test(location)) { - DiscourseURL.redirectTo(location); - } else { - DiscourseURL.redirectTo( - `/admin/users/${data.user.id}/${data.user.username}` - ); - } - } else { - bootbox.alert(I18n.t("admin.user.merge_failed")); - if (data.user) { - user.setProperties(data.user); - } - } - }) - .catch(() => { - AdminUser.find(user.id).then((u) => user.setProperties(u)); - bootbox.alert(I18n.t("admin.user.merge_failed")); - }); + }); }, loadDetails() { @@ -553,10 +301,6 @@ const AdminUser = User.extend({ @discourseComputed("approved_by") approvedBy: wrapAdmin, - _formatError(event) { - return `http: ${event.status} - ${event.body}`; - }, - deleteSSORecord() { return ajax(`/admin/users/${this.id}/sso_record.json`, { type: "DELETE", diff --git a/app/assets/javascripts/admin/addon/models/api-key.js b/app/assets/javascripts/admin/addon/models/api-key.js index adf186d454..be5475a4ab 100644 --- a/app/assets/javascripts/admin/addon/models/api-key.js +++ b/app/assets/javascripts/admin/addon/models/api-key.js @@ -1,8 +1,8 @@ -import discourseComputed from "discourse-common/utils/decorators"; import AdminUser from "admin/models/admin-user"; import RestModel from "discourse/models/rest"; import { ajax } from "discourse/lib/ajax"; import { computed } from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; import { fmt } from "discourse/lib/computed"; const ApiKey = RestModel.extend({ diff --git a/app/assets/javascripts/admin/addon/models/backup-status.js b/app/assets/javascripts/admin/addon/models/backup-status.js index 474c3c1688..dffad0d060 100644 --- a/app/assets/javascripts/admin/addon/models/backup-status.js +++ b/app/assets/javascripts/admin/addon/models/backup-status.js @@ -1,6 +1,6 @@ +import EmberObject from "@ember/object"; import discourseComputed from "discourse-common/utils/decorators"; import { not } from "@ember/object/computed"; -import EmberObject from "@ember/object"; export default EmberObject.extend({ restoreDisabled: not("restoreEnabled"), diff --git a/app/assets/javascripts/admin/addon/models/backup.js b/app/assets/javascripts/admin/addon/models/backup.js index 4112b06f2b..717192e8ac 100644 --- a/app/assets/javascripts/admin/addon/models/backup.js +++ b/app/assets/javascripts/admin/addon/models/backup.js @@ -1,10 +1,6 @@ -import getURL from "discourse-common/lib/get-url"; -import I18n from "I18n"; -import { ajax } from "discourse/lib/ajax"; -import { extractError } from "discourse/lib/ajax-error"; import EmberObject from "@ember/object"; import MessageBus from "message-bus-client"; -import bootbox from "bootbox"; +import { ajax } from "discourse/lib/ajax"; const Backup = EmberObject.extend({ destroy() { @@ -21,16 +17,7 @@ const Backup = EmberObject.extend({ Backup.reopenClass({ find() { - return ajax("/admin/backups.json") - .then((backups) => backups.map((backup) => Backup.create(backup))) - .catch((error) => { - bootbox.alert( - I18n.t("admin.backups.backup_storage_error", { - error_message: extractError(error), - }) - ); - return []; - }); + return ajax("/admin/backups.json"); }, start(withUploads) { @@ -43,33 +30,18 @@ Backup.reopenClass({ with_uploads: withUploads, client_id: MessageBus.clientId, }, - }).then((result) => { - if (!result.success) { - bootbox.alert(result.message); - } }); }, cancel() { return ajax("/admin/backups/cancel.json", { type: "DELETE", - }).then((result) => { - if (!result.success) { - bootbox.alert(result.message); - } }); }, rollback() { return ajax("/admin/backups/rollback.json", { type: "POST", - }).then((result) => { - if (!result.success) { - bootbox.alert(result.message); - } else { - // redirect to homepage (session might be lost) - window.location = getURL("/"); - } }); }, }); diff --git a/app/assets/javascripts/admin/addon/models/color-scheme-color.js b/app/assets/javascripts/admin/addon/models/color-scheme-color.js index f5427d542c..49cb552a92 100644 --- a/app/assets/javascripts/admin/addon/models/color-scheme-color.js +++ b/app/assets/javascripts/admin/addon/models/color-scheme-color.js @@ -1,10 +1,10 @@ -import I18n from "I18n"; import discourseComputed, { observes, on, } from "discourse-common/utils/decorators"; -import { propertyNotEqual } from "discourse/lib/computed"; import EmberObject from "@ember/object"; +import I18n from "I18n"; +import { propertyNotEqual } from "discourse/lib/computed"; const ColorSchemeColor = EmberObject.extend({ @on("init") diff --git a/app/assets/javascripts/admin/addon/models/color-scheme.js b/app/assets/javascripts/admin/addon/models/color-scheme.js index 4bce289ba7..e1b73ad14e 100644 --- a/app/assets/javascripts/admin/addon/models/color-scheme.js +++ b/app/assets/javascripts/admin/addon/models/color-scheme.js @@ -1,11 +1,11 @@ -import I18n from "I18n"; import { A } from "@ember/array"; import ArrayProxy from "@ember/array/proxy"; -import discourseComputed from "discourse-common/utils/decorators"; -import { not } from "@ember/object/computed"; -import { ajax } from "discourse/lib/ajax"; import ColorSchemeColor from "admin/models/color-scheme-color"; import EmberObject from "@ember/object"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; +import { not } from "@ember/object/computed"; const ColorScheme = EmberObject.extend({ init() { diff --git a/app/assets/javascripts/admin/addon/models/email-log.js b/app/assets/javascripts/admin/addon/models/email-log.js index 18406ceb7a..6565611974 100644 --- a/app/assets/javascripts/admin/addon/models/email-log.js +++ b/app/assets/javascripts/admin/addon/models/email-log.js @@ -1,7 +1,7 @@ -import getURL from "discourse-common/lib/get-url"; -import { ajax } from "discourse/lib/ajax"; import AdminUser from "admin/models/admin-user"; import EmberObject from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; +import getURL from "discourse-common/lib/get-url"; const EmailLog = EmberObject.extend({}); diff --git a/app/assets/javascripts/admin/addon/models/email-preview.js b/app/assets/javascripts/admin/addon/models/email-preview.js index 893fb5b4fb..96ffe2f949 100644 --- a/app/assets/javascripts/admin/addon/models/email-preview.js +++ b/app/assets/javascripts/admin/addon/models/email-preview.js @@ -1,5 +1,5 @@ -import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; const EmailPreview = EmberObject.extend({}); diff --git a/app/assets/javascripts/admin/addon/models/email-settings.js b/app/assets/javascripts/admin/addon/models/email-settings.js index 52ac14acec..f959df408f 100644 --- a/app/assets/javascripts/admin/addon/models/email-settings.js +++ b/app/assets/javascripts/admin/addon/models/email-settings.js @@ -1,5 +1,5 @@ -import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; const EmailSettings = EmberObject.extend({}); diff --git a/app/assets/javascripts/admin/addon/models/email-template.js b/app/assets/javascripts/admin/addon/models/email-template.js index b58da0457f..4be7d9fff9 100644 --- a/app/assets/javascripts/admin/addon/models/email-template.js +++ b/app/assets/javascripts/admin/addon/models/email-template.js @@ -1,5 +1,5 @@ -import { ajax } from "discourse/lib/ajax"; import RestModel from "discourse/models/rest"; +import { ajax } from "discourse/lib/ajax"; const { getProperties } = Ember; export default RestModel.extend({ diff --git a/app/assets/javascripts/admin/addon/models/flag-type.js b/app/assets/javascripts/admin/addon/models/flag-type.js index 607cb755d8..5859584ce7 100644 --- a/app/assets/javascripts/admin/addon/models/flag-type.js +++ b/app/assets/javascripts/admin/addon/models/flag-type.js @@ -1,6 +1,6 @@ import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; import RestModel from "discourse/models/rest"; +import discourseComputed from "discourse-common/utils/decorators"; export default RestModel.extend({ @discourseComputed("id") diff --git a/app/assets/javascripts/admin/addon/models/incoming-email.js b/app/assets/javascripts/admin/addon/models/incoming-email.js index 42eb995f85..8489ae8dd3 100644 --- a/app/assets/javascripts/admin/addon/models/incoming-email.js +++ b/app/assets/javascripts/admin/addon/models/incoming-email.js @@ -1,6 +1,6 @@ -import { ajax } from "discourse/lib/ajax"; import AdminUser from "admin/models/admin-user"; import EmberObject from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; const IncomingEmail = EmberObject.extend({}); diff --git a/app/assets/javascripts/admin/addon/models/permalink.js b/app/assets/javascripts/admin/addon/models/permalink.js index de61b27fd4..a2e8445b08 100644 --- a/app/assets/javascripts/admin/addon/models/permalink.js +++ b/app/assets/javascripts/admin/addon/models/permalink.js @@ -1,8 +1,8 @@ +import Category from "discourse/models/category"; +import DiscourseURL from "discourse/lib/url"; +import EmberObject from "@ember/object"; import { ajax } from "discourse/lib/ajax"; import discourseComputed from "discourse-common/utils/decorators"; -import DiscourseURL from "discourse/lib/url"; -import Category from "discourse/models/category"; -import EmberObject from "@ember/object"; const Permalink = EmberObject.extend({ save: function () { diff --git a/app/assets/javascripts/admin/addon/models/report.js b/app/assets/javascripts/admin/addon/models/report.js index a7b3d5786d..baa0aba16f 100644 --- a/app/assets/javascripts/admin/addon/models/report.js +++ b/app/assets/javascripts/admin/addon/models/report.js @@ -1,19 +1,19 @@ -import getURL from "discourse-common/lib/get-url"; -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { makeArray } from "discourse-common/lib/helpers"; -import { isEmpty } from "@ember/utils"; -import EmberObject from "@ember/object"; -import { ajax } from "discourse/lib/ajax"; -import round from "discourse/lib/round"; +import { durationTiny, number } from "discourse/lib/formatter"; import { + escapeExpression, fillMissingDates, formatUsername, toNumber, - escapeExpression, } from "discourse/lib/utilities"; -import { number, durationTiny } from "discourse/lib/formatter"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; +import getURL from "discourse-common/lib/get-url"; +import { isEmpty } from "@ember/utils"; +import { makeArray } from "discourse-common/lib/helpers"; import { renderAvatar } from "discourse/helpers/user-avatar"; +import round from "discourse/lib/round"; // Change this line each time report format change // and you want to ensure cache is reset diff --git a/app/assets/javascripts/admin/addon/models/screened-email.js b/app/assets/javascripts/admin/addon/models/screened-email.js index 4e902488d1..857cca0d63 100644 --- a/app/assets/javascripts/admin/addon/models/screened-email.js +++ b/app/assets/javascripts/admin/addon/models/screened-email.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; const ScreenedEmail = EmberObject.extend({ @discourseComputed("action") diff --git a/app/assets/javascripts/admin/addon/models/screened-ip-address.js b/app/assets/javascripts/admin/addon/models/screened-ip-address.js index 33e2b44317..a7d29aab31 100644 --- a/app/assets/javascripts/admin/addon/models/screened-ip-address.js +++ b/app/assets/javascripts/admin/addon/models/screened-ip-address.js @@ -1,8 +1,8 @@ +import EmberObject from "@ember/object"; import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; import discourseComputed from "discourse-common/utils/decorators"; import { equal } from "@ember/object/computed"; -import { ajax } from "discourse/lib/ajax"; -import EmberObject from "@ember/object"; const ScreenedIpAddress = EmberObject.extend({ @discourseComputed("action_name") diff --git a/app/assets/javascripts/admin/addon/models/screened-url.js b/app/assets/javascripts/admin/addon/models/screened-url.js index a7bc7cfa6f..f3769c7d2f 100644 --- a/app/assets/javascripts/admin/addon/models/screened-url.js +++ b/app/assets/javascripts/admin/addon/models/screened-url.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; const ScreenedUrl = EmberObject.extend({ @discourseComputed("action") diff --git a/app/assets/javascripts/admin/addon/models/site-setting.js b/app/assets/javascripts/admin/addon/models/site-setting.js index 350281e616..49ed58366e 100644 --- a/app/assets/javascripts/admin/addon/models/site-setting.js +++ b/app/assets/javascripts/admin/addon/models/site-setting.js @@ -1,7 +1,7 @@ -import I18n from "I18n"; -import { ajax } from "discourse/lib/ajax"; -import Setting from "admin/mixins/setting-object"; import EmberObject from "@ember/object"; +import I18n from "I18n"; +import Setting from "admin/mixins/setting-object"; +import { ajax } from "discourse/lib/ajax"; import discourseComputed from "discourse-common/utils/decorators"; const SiteSetting = EmberObject.extend(Setting, { diff --git a/app/assets/javascripts/admin/addon/models/site-text.js b/app/assets/javascripts/admin/addon/models/site-text.js index 7dcd614402..c25a5b30a0 100644 --- a/app/assets/javascripts/admin/addon/models/site-text.js +++ b/app/assets/javascripts/admin/addon/models/site-text.js @@ -1,10 +1,10 @@ -import { ajax } from "discourse/lib/ajax"; import RestModel from "discourse/models/rest"; -const { getProperties } = Ember; +import { ajax } from "discourse/lib/ajax"; +import { getProperties } from "@ember/object"; export default RestModel.extend({ - revert() { - return ajax(`/admin/customize/site_texts/${this.id}`, { + revert(locale) { + return ajax(`/admin/customize/site_texts/${this.id}?locale=${locale}`, { type: "DELETE", }).then((result) => getProperties(result.site_text, "value", "can_revert")); }, diff --git a/app/assets/javascripts/admin/addon/models/staff-action-log.js b/app/assets/javascripts/admin/addon/models/staff-action-log.js index 09d84b6791..70d86c41e7 100644 --- a/app/assets/javascripts/admin/addon/models/staff-action-log.js +++ b/app/assets/javascripts/admin/addon/models/staff-action-log.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; -import discourseComputed from "discourse-common/utils/decorators"; -import { ajax } from "discourse/lib/ajax"; import AdminUser from "admin/models/admin-user"; -import { escapeExpression } from "discourse/lib/utilities"; +import I18n from "I18n"; import RestModel from "discourse/models/rest"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; +import { escapeExpression } from "discourse/lib/utilities"; function format(label, value, escape = true) { return value diff --git a/app/assets/javascripts/admin/addon/models/theme-settings.js b/app/assets/javascripts/admin/addon/models/theme-settings.js index a823592ad2..d91c3e583e 100644 --- a/app/assets/javascripts/admin/addon/models/theme-settings.js +++ b/app/assets/javascripts/admin/addon/models/theme-settings.js @@ -1,4 +1,4 @@ -import Setting from "admin/mixins/setting-object"; import EmberObject from "@ember/object"; +import Setting from "admin/mixins/setting-object"; export default EmberObject.extend(Setting, {}); diff --git a/app/assets/javascripts/admin/addon/models/theme.js b/app/assets/javascripts/admin/addon/models/theme.js index 10c78c5b82..d41ecb7f5f 100644 --- a/app/assets/javascripts/admin/addon/models/theme.js +++ b/app/assets/javascripts/admin/addon/models/theme.js @@ -1,9 +1,9 @@ -import I18n from "I18n"; -import { get } from "@ember/object"; +import { gt, or } from "@ember/object/computed"; import { isBlank, isEmpty } from "@ember/utils"; -import { or, gt } from "@ember/object/computed"; +import I18n from "I18n"; import RestModel from "discourse/models/rest"; import discourseComputed from "discourse-common/utils/decorators"; +import { get } from "@ember/object"; import { popupAjaxError } from "discourse/lib/ajax-error"; const THEME_UPLOAD_VAR = 2; @@ -253,6 +253,11 @@ const Theme = RestModel.extend({ } }, + @discourseComputed("recentlyInstalled", "component", "hasParents") + warnUnassignedComponent(recent, component, hasParents) { + return recent && component && !hasParents; + }, + removeChildTheme(theme) { const childThemes = this.childThemes; childThemes.removeObject(theme); diff --git a/app/assets/javascripts/admin/addon/models/tl3-requirements.js b/app/assets/javascripts/admin/addon/models/tl3-requirements.js index a6b31363b9..920d6e5f66 100644 --- a/app/assets/javascripts/admin/addon/models/tl3-requirements.js +++ b/app/assets/javascripts/admin/addon/models/tl3-requirements.js @@ -1,5 +1,5 @@ -import discourseComputed from "discourse-common/utils/decorators"; import EmberObject from "@ember/object"; +import discourseComputed from "discourse-common/utils/decorators"; export default EmberObject.extend({ @discourseComputed("days_visited", "time_period") diff --git a/app/assets/javascripts/admin/addon/models/version-check.js b/app/assets/javascripts/admin/addon/models/version-check.js index 53882d6eca..4f939064af 100644 --- a/app/assets/javascripts/admin/addon/models/version-check.js +++ b/app/assets/javascripts/admin/addon/models/version-check.js @@ -1,6 +1,6 @@ -import discourseComputed from "discourse-common/utils/decorators"; -import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; const VersionCheck = EmberObject.extend({ @discourseComputed("updated_at") diff --git a/app/assets/javascripts/admin/addon/models/watched-word.js b/app/assets/javascripts/admin/addon/models/watched-word.js index 938b25f7bc..741d037249 100644 --- a/app/assets/javascripts/admin/addon/models/watched-word.js +++ b/app/assets/javascripts/admin/addon/models/watched-word.js @@ -1,6 +1,6 @@ +import EmberObject from "@ember/object"; import I18n from "I18n"; import { ajax } from "discourse/lib/ajax"; -import EmberObject from "@ember/object"; const WatchedWord = EmberObject.extend({ save() { diff --git a/app/assets/javascripts/admin/addon/models/web-hook.js b/app/assets/javascripts/admin/addon/models/web-hook.js index 677d76aa88..8dd568a9fb 100644 --- a/app/assets/javascripts/admin/addon/models/web-hook.js +++ b/app/assets/javascripts/admin/addon/models/web-hook.js @@ -1,9 +1,9 @@ -import { isEmpty } from "@ember/utils"; -import RestModel from "discourse/models/rest"; +import discourseComputed, { observes } from "discourse-common/utils/decorators"; import Category from "discourse/models/category"; import Group from "discourse/models/group"; -import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import RestModel from "discourse/models/rest"; import Site from "discourse/models/site"; +import { isEmpty } from "@ember/utils"; export default RestModel.extend({ content_type: 1, // json diff --git a/app/assets/javascripts/admin/addon/routes/admin-backups-index.js b/app/assets/javascripts/admin/addon/routes/admin-backups-index.js index aee755b705..cb05c26580 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-backups-index.js +++ b/app/assets/javascripts/admin/addon/routes/admin-backups-index.js @@ -1,5 +1,5 @@ -import Route from "@ember/routing/route"; import Backup from "admin/models/backup"; +import Route from "@ember/routing/route"; export default Route.extend({ activate() { @@ -12,7 +12,9 @@ export default Route.extend({ }, model() { - return Backup.find(); + return Backup.find().then((backups) => + backups.map((backup) => Backup.create(backup)) + ); }, deactivate() { diff --git a/app/assets/javascripts/admin/addon/routes/admin-backups-logs.js b/app/assets/javascripts/admin/addon/routes/admin-backups-logs.js index e2e3a933c8..8de1ef5240 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-backups-logs.js +++ b/app/assets/javascripts/admin/addon/routes/admin-backups-logs.js @@ -1,6 +1,6 @@ import EmberObject from "@ember/object"; -import Route from "@ember/routing/route"; import PreloadStore from "discourse/lib/preload-store"; +import Route from "@ember/routing/route"; export default Route.extend({ // since the logs are pushed via the message bus diff --git a/app/assets/javascripts/admin/addon/routes/admin-backups.js b/app/assets/javascripts/admin/addon/routes/admin-backups.js index 41c6cb0f8b..063eeec9d7 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-backups.js +++ b/app/assets/javascripts/admin/addon/routes/admin-backups.js @@ -1,14 +1,15 @@ -import getURL from "discourse-common/lib/get-url"; -import I18n from "I18n"; -import EmberObject from "@ember/object"; -import DiscourseRoute from "discourse/routes/discourse"; -import { ajax } from "discourse/lib/ajax"; -import showModal from "discourse/lib/show-modal"; -import BackupStatus from "admin/models/backup-status"; import Backup from "admin/models/backup"; +import BackupStatus from "admin/models/backup-status"; +import DiscourseRoute from "discourse/routes/discourse"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; import PreloadStore from "discourse/lib/preload-store"; import User from "discourse/models/user"; +import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import { extractError } from "discourse/lib/ajax-error"; +import getURL from "discourse-common/lib/get-url"; +import showModal from "discourse/lib/show-modal"; const LOG_CHANNEL = "/admin/backups/logs"; @@ -74,7 +75,11 @@ export default DiscourseRoute.extend({ startBackup(withUploads) { this.transitionTo("admin.backups.logs"); - Backup.start(withUploads); + Backup.start(withUploads).then((result) => { + if (!result.success) { + bootbox.alert(result.message); + } + }); }, destroyBackup(backup) { @@ -135,7 +140,14 @@ export default DiscourseRoute.extend({ I18n.t("yes_value"), (confirmed) => { if (confirmed) { - Backup.rollback(); + Backup.rollback().then((result) => { + if (!result.success) { + bootbox.alert(result.message); + } else { + // redirect to homepage (session might be lost) + window.location = getURL("/"); + } + }); } } ); @@ -152,12 +164,22 @@ export default DiscourseRoute.extend({ }, remoteUploadSuccess() { - Backup.find().then((backups) => { - this.controllerFor("adminBackupsIndex").set( - "model", - backups.map((backup) => Backup.create(backup)) - ); - }); + Backup.find() + .then((backups) => backups.map((backup) => Backup.create(backup))) + .then((backups) => { + this.controllerFor("adminBackupsIndex").set( + "model", + backups.map((backup) => Backup.create(backup)) + ); + }) + .catch((error) => { + bootbox.alert( + I18n.t("admin.backups.backup_storage_error", { + error_message: extractError(error), + }) + ); + return []; + }); }, }, }); diff --git a/app/assets/javascripts/admin/addon/routes/admin-badges-show.js b/app/assets/javascripts/admin/addon/routes/admin-badges-show.js index c95cae8afa..a370cd32d8 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-badges-show.js +++ b/app/assets/javascripts/admin/addon/routes/admin-badges-show.js @@ -1,10 +1,10 @@ +import Badge from "discourse/models/badge"; import I18n from "I18n"; -import { get } from "@ember/object"; import Route from "@ember/routing/route"; import { ajax } from "discourse/lib/ajax"; -import Badge from "discourse/models/badge"; -import showModal from "discourse/lib/show-modal"; import bootbox from "bootbox"; +import { get } from "@ember/object"; +import showModal from "discourse/lib/show-modal"; export default Route.extend({ serialize(m) { diff --git a/app/assets/javascripts/admin/addon/routes/admin-badges.js b/app/assets/javascripts/admin/addon/routes/admin-badges.js index 59bc0944cb..ac4b9e9b53 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-badges.js +++ b/app/assets/javascripts/admin/addon/routes/admin-badges.js @@ -1,8 +1,8 @@ -import I18n from "I18n"; -import DiscourseRoute from "discourse/routes/discourse"; -import { ajax } from "discourse/lib/ajax"; import Badge from "discourse/models/badge"; import BadgeGrouping from "discourse/models/badge-grouping"; +import DiscourseRoute from "discourse/routes/discourse"; +import I18n from "I18n"; +import { ajax } from "discourse/lib/ajax"; export default DiscourseRoute.extend({ _json: null, diff --git a/app/assets/javascripts/admin/addon/routes/admin-customize-colors.js b/app/assets/javascripts/admin/addon/routes/admin-customize-colors.js index b2d4f2c16b..cf2dc3d18d 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-customize-colors.js +++ b/app/assets/javascripts/admin/addon/routes/admin-customize-colors.js @@ -1,5 +1,5 @@ -import Route from "@ember/routing/route"; import ColorScheme from "admin/models/color-scheme"; +import Route from "@ember/routing/route"; export default Route.extend({ model() { diff --git a/app/assets/javascripts/admin/addon/routes/admin-customize-themes-edit.js b/app/assets/javascripts/admin/addon/routes/admin-customize-themes-edit.js index 030645e445..0d55baa6ce 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-customize-themes-edit.js +++ b/app/assets/javascripts/admin/addon/routes/admin-customize-themes-edit.js @@ -28,7 +28,7 @@ export default Route.extend({ const fields = wrapper.model .get("fields") [wrapper.target].map((f) => f.name); - if (wrapper.model.remote_theme) { + if (wrapper.model.remote_theme && wrapper.model.remote_theme.is_git) { this.transitionTo("adminCustomizeThemes.index"); return; } diff --git a/app/assets/javascripts/admin/addon/routes/admin-customize-themes-show.js b/app/assets/javascripts/admin/addon/routes/admin-customize-themes-show.js index feaf0ef7ae..5bcf95d3d2 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-customize-themes-show.js +++ b/app/assets/javascripts/admin/addon/routes/admin-customize-themes-show.js @@ -1,7 +1,21 @@ +import { COMPONENTS, THEMES } from "admin/models/theme"; import I18n from "I18n"; import Route from "@ember/routing/route"; import { scrollTop } from "discourse/mixins/scroll-top"; -import { THEMES, COMPONENTS } from "admin/models/theme"; + +export function showUnassignedComponentWarning(theme, callback) { + bootbox.confirm( + I18n.t("admin.customize.theme.unsaved_parent_themes"), + I18n.t("admin.customize.theme.discard"), + I18n.t("admin.customize.theme.stay"), + (result) => { + if (!result) { + theme.set("recentlyInstalled", false); + } + callback(result); + } + ); +} export default Route.extend({ serialize(model) { @@ -11,7 +25,7 @@ export default Route.extend({ model(params) { const all = this.modelFor("adminCustomizeThemes"); const model = all.findBy("id", parseInt(params.theme_id, 10)); - return model ? model : this.replaceWith("adminCustomizeTheme.index"); + return model ? model : this.replaceWith("adminCustomizeThemes.index"); }, setupController(controller, model) { @@ -55,19 +69,13 @@ export default Route.extend({ }, willTransition(transition) { const model = this.controller.model; - if (model.recentlyInstalled && !model.hasParents && model.component) { + if (model.warnUnassignedComponent) { transition.abort(); - bootbox.confirm( - I18n.t("admin.customize.theme.unsaved_parent_themes"), - I18n.t("admin.customize.theme.discard"), - I18n.t("admin.customize.theme.stay"), - (result) => { - if (!result) { - this.controller.model.setProperties({ recentlyInstalled: false }); - transition.retry(); - } + showUnassignedComponentWarning(model, (result) => { + if (!result) { + transition.retry(); } - ); + }); } }, }, diff --git a/app/assets/javascripts/admin/addon/routes/admin-customize-themes.js b/app/assets/javascripts/admin/addon/routes/admin-customize-themes.js index 2da0266f42..9397c938a9 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-customize-themes.js +++ b/app/assets/javascripts/admin/addon/routes/admin-customize-themes.js @@ -1,5 +1,6 @@ import Route from "@ember/routing/route"; import showModal from "discourse/lib/show-modal"; +import { showUnassignedComponentWarning } from "admin/routes/admin-customize-themes-show"; export default Route.extend({ model() { @@ -13,7 +14,17 @@ export default Route.extend({ actions: { installModal() { - showModal("admin-install-theme", { admin: true }); + const currentTheme = this.controllerFor("adminCustomizeThemes.show") + .model; + if (currentTheme && currentTheme.warnUnassignedComponent) { + showUnassignedComponentWarning(currentTheme, (result) => { + if (!result) { + showModal("admin-install-theme", { admin: true }); + } + }); + } else { + showModal("admin-install-theme", { admin: true }); + } }, addTheme(theme) { diff --git a/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js b/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js index 041b25fc05..d89010c9ef 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js +++ b/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js @@ -1,5 +1,5 @@ -import showModal from "discourse/lib/show-modal"; import AdminEmailLogs from "admin/routes/admin-email-logs"; +import showModal from "discourse/lib/show-modal"; export default AdminEmailLogs.extend({ status: "bounced", diff --git a/app/assets/javascripts/admin/addon/routes/admin-email-preview-digest.js b/app/assets/javascripts/admin/addon/routes/admin-email-preview-digest.js index 03d72f0f82..730bcd0e7e 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-email-preview-digest.js +++ b/app/assets/javascripts/admin/addon/routes/admin-email-preview-digest.js @@ -1,5 +1,5 @@ -import DiscourseRoute from "discourse/routes/discourse"; import EmailPreview, { oneWeekAgo } from "admin/models/email-preview"; +import DiscourseRoute from "discourse/routes/discourse"; export default DiscourseRoute.extend({ model() { diff --git a/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js b/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js index e5d4501549..ce45fa8962 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js +++ b/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js @@ -1,5 +1,5 @@ -import showModal from "discourse/lib/show-modal"; import AdminEmailIncomings from "admin/routes/admin-email-incomings"; +import showModal from "discourse/lib/show-modal"; export default AdminEmailIncomings.extend({ status: "rejected", diff --git a/app/assets/javascripts/admin/addon/routes/admin-emojis.js b/app/assets/javascripts/admin/addon/routes/admin-emojis.js index 5db8760a51..5047bd6f82 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-emojis.js +++ b/app/assets/javascripts/admin/addon/routes/admin-emojis.js @@ -1,5 +1,5 @@ -import EmberObject from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import EmberObject from "@ember/object"; import { ajax } from "discourse/lib/ajax"; export default DiscourseRoute.extend({ diff --git a/app/assets/javascripts/admin/addon/routes/admin-logs-staff-action-logs.js b/app/assets/javascripts/admin/addon/routes/admin-logs-staff-action-logs.js index a3c3f196e0..68657da533 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-logs-staff-action-logs.js +++ b/app/assets/javascripts/admin/addon/routes/admin-logs-staff-action-logs.js @@ -1,6 +1,6 @@ import DiscourseRoute from "discourse/routes/discourse"; -import showModal from "discourse/lib/show-modal"; import EmberObject from "@ember/object"; +import showModal from "discourse/lib/show-modal"; export default DiscourseRoute.extend({ queryParams: { diff --git a/app/assets/javascripts/admin/addon/routes/admin-search-logs-index.js b/app/assets/javascripts/admin/addon/routes/admin-search-logs-index.js index c688b8ebba..c04f3b22b8 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-search-logs-index.js +++ b/app/assets/javascripts/admin/addon/routes/admin-search-logs-index.js @@ -1,5 +1,5 @@ -import EmberObject from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import EmberObject from "@ember/object"; import { ajax } from "discourse/lib/ajax"; export default DiscourseRoute.extend({ diff --git a/app/assets/javascripts/admin/addon/routes/admin-search-logs-term.js b/app/assets/javascripts/admin/addon/routes/admin-search-logs-term.js index 989d258384..b9613fe04f 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-search-logs-term.js +++ b/app/assets/javascripts/admin/addon/routes/admin-search-logs-term.js @@ -1,5 +1,5 @@ -import EmberObject from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import EmberObject from "@ember/object"; import { ajax } from "discourse/lib/ajax"; import { fillMissingDates } from "discourse/lib/utilities"; import { translateResults } from "discourse/lib/search"; diff --git a/app/assets/javascripts/admin/addon/routes/admin-site-settings-category.js b/app/assets/javascripts/admin/addon/routes/admin-site-settings-category.js index be2a2180d2..aab0b337db 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-site-settings-category.js +++ b/app/assets/javascripts/admin/addon/routes/admin-site-settings-category.js @@ -1,6 +1,6 @@ -import I18n from "I18n"; -import EmberObject from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; export default DiscourseRoute.extend({ model(params) { diff --git a/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js b/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js index fe720907c7..40c74fced3 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js +++ b/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js @@ -1,10 +1,30 @@ import Route from "@ember/routing/route"; +import { ajax } from "discourse/lib/ajax"; + export default Route.extend({ + queryParams: { + locale: { replace: true }, + }, + model(params) { - return this.store.find("site-text", params.id); + return ajax( + `/admin/customize/site_texts/${params.id}?locale=${params.locale}` + ).then((result) => { + return this.store.createRecord("site-text", result.site_text); + }); }, setupController(controller, siteText) { - controller.setProperties({ siteText, saved: false }); + const locales = JSON.parse(this.siteSettings.available_locales); + + const localeFullName = locales.find((locale) => { + return locale.value === controller.locale; + }).name; + + controller.setProperties({ + siteText, + saved: false, + localeFullName: localeFullName, + }); }, }); diff --git a/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js b/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js index 036438235d..255315a846 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js +++ b/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js @@ -1,17 +1,18 @@ import Route from "@ember/routing/route"; -import showModal from "discourse/lib/show-modal"; import { getProperties } from "@ember/object"; +import showModal from "discourse/lib/show-modal"; export default Route.extend({ queryParams: { q: { replace: true }, overridden: { replace: true }, + locale: { replace: true }, }, model(params) { return this.store.find( "site-text", - getProperties(params, "q", "overridden") + getProperties(params, "q", "overridden", "locale") ); }, diff --git a/app/assets/javascripts/admin/addon/routes/admin-user-badges.js b/app/assets/javascripts/admin/addon/routes/admin-user-badges.js index f15649f92d..f9549e39e6 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-user-badges.js +++ b/app/assets/javascripts/admin/addon/routes/admin-user-badges.js @@ -1,6 +1,6 @@ +import Badge from "discourse/models/badge"; import DiscourseRoute from "discourse/routes/discourse"; import UserBadge from "discourse/models/user-badge"; -import Badge from "discourse/models/badge"; export default DiscourseRoute.extend({ model() { diff --git a/app/assets/javascripts/admin/addon/routes/admin-user.js b/app/assets/javascripts/admin/addon/routes/admin-user.js index 90436dabd4..d9627ba571 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-user.js +++ b/app/assets/javascripts/admin/addon/routes/admin-user.js @@ -1,6 +1,6 @@ -import { get } from "@ember/object"; -import DiscourseRoute from "discourse/routes/discourse"; import AdminUser from "admin/models/admin-user"; +import DiscourseRoute from "discourse/routes/discourse"; +import { get } from "@ember/object"; export default DiscourseRoute.extend({ serialize(model) { diff --git a/app/assets/javascripts/admin/addon/routes/admin-users-list.js b/app/assets/javascripts/admin/addon/routes/admin-users-list.js index db8106a8ed..4630c8efc8 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-users-list.js +++ b/app/assets/javascripts/admin/addon/routes/admin-users-list.js @@ -1,7 +1,7 @@ +import AdminUser from "admin/models/admin-user"; import DiscourseRoute from "discourse/routes/discourse"; import { exportEntity } from "discourse/lib/export-csv"; import { outputExportResult } from "discourse/lib/export-result"; -import AdminUser from "admin/models/admin-user"; export default DiscourseRoute.extend({ actions: { diff --git a/app/assets/javascripts/admin/addon/routes/admin-watched-words-action.js b/app/assets/javascripts/admin/addon/routes/admin-watched-words-action.js index 3c770f7e09..fe1ce75ab7 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-watched-words-action.js +++ b/app/assets/javascripts/admin/addon/routes/admin-watched-words-action.js @@ -1,6 +1,6 @@ -import I18n from "I18n"; -import EmberObject from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import EmberObject from "@ember/object"; +import I18n from "I18n"; export default DiscourseRoute.extend({ model(params) { diff --git a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js index b07b390d40..1b7923224b 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js +++ b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js @@ -1,5 +1,5 @@ -import { get } from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import { get } from "@ember/object"; export default DiscourseRoute.extend({ model(params) { diff --git a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js index a5eb3dd873..6d7c64f955 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js +++ b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js @@ -1,5 +1,5 @@ -import { get } from "@ember/object"; import DiscourseRoute from "discourse/routes/discourse"; +import { get } from "@ember/object"; export default DiscourseRoute.extend({ serialize(model) { diff --git a/app/assets/javascripts/admin/addon/routes/admin.js b/app/assets/javascripts/admin/addon/routes/admin.js index c84051d171..e0949ba414 100644 --- a/app/assets/javascripts/admin/addon/routes/admin.js +++ b/app/assets/javascripts/admin/addon/routes/admin.js @@ -1,5 +1,5 @@ -import I18n from "I18n"; import DiscourseRoute from "discourse/routes/discourse"; +import I18n from "I18n"; export default DiscourseRoute.extend({ titleToken() { diff --git a/app/assets/javascripts/admin/addon/services/admin-tools.js b/app/assets/javascripts/admin/addon/services/admin-tools.js index fc02b998fe..16294be1b3 100644 --- a/app/assets/javascripts/admin/addon/services/admin-tools.js +++ b/app/assets/javascripts/admin/addon/services/admin-tools.js @@ -1,16 +1,16 @@ -import I18n from "I18n"; +import AdminUser from "admin/models/admin-user"; // A service that can act as a bridge between the front end Discourse application // and the admin application. Use this if you need front end code to access admin // modules. Inject it optionally, and if it exists go to town! -import AdminUser from "admin/models/admin-user"; -import { iconHTML } from "discourse-common/lib/icon-library"; -import { ajax } from "discourse/lib/ajax"; -import showModal from "discourse/lib/show-modal"; -import { getOwner } from "discourse-common/lib/get-owner"; -import Service from "@ember/service"; +import I18n from "I18n"; import { Promise } from "rsvp"; +import Service from "@ember/service"; +import { ajax } from "discourse/lib/ajax"; import bootbox from "bootbox"; +import { getOwner } from "discourse-common/lib/get-owner"; +import { iconHTML } from "discourse-common/lib/icon-library"; +import showModal from "discourse/lib/show-modal"; export default Service.extend({ init() { diff --git a/app/assets/javascripts/admin/addon/templates/badges-show.hbs b/app/assets/javascripts/admin/addon/templates/badges-show.hbs index 49741c8bc6..82057b103c 100644 --- a/app/assets/javascripts/admin/addon/templates/badges-show.hbs +++ b/app/assets/javascripts/admin/addon/templates/badges-show.hbs @@ -4,6 +4,11 @@ {{#if readOnly}} {{input type="text" name="name" value=buffered.name disabled=true}} +

+ {{#link-to "adminSiteText.edit" (concat textCustomizationPrefix "name")}} + {{i18n "admin.badges.read_only_setting_help"}} + {{/link-to}} +

{{else}} {{input type="text" name="name" value=buffered.name}} {{/if}} @@ -64,6 +69,11 @@ {{#if buffered.system}} {{textarea name="description" value=buffered.description disabled=true}} +

+ {{#link-to "adminSiteText.edit" (concat textCustomizationPrefix "description")}} + {{i18n "admin.badges.read_only_setting_help"}} + {{/link-to}} +

{{else}} {{textarea name="description" value=buffered.description}} {{/if}} @@ -73,6 +83,11 @@ {{#if buffered.system}} {{textarea name="long_description" value=buffered.long_description disabled=true}} +

+ {{#link-to "adminSiteText.edit" (concat textCustomizationPrefix "long_description")}} + {{i18n "admin.badges.read_only_setting_help"}} + {{/link-to}} +

{{else}} {{textarea name="long_description" value=buffered.long_description}} {{/if}} diff --git a/app/assets/javascripts/admin/addon/templates/components/embeddable-host.hbs b/app/assets/javascripts/admin/addon/templates/components/embeddable-host.hbs index 7d73d93a2b..db8d108308 100644 --- a/app/assets/javascripts/admin/addon/templates/components/embeddable-host.hbs +++ b/app/assets/javascripts/admin/addon/templates/components/embeddable-host.hbs @@ -1,7 +1,7 @@ {{#if editing}}
{{i18n "admin.embedding.host"}}
- {{input value=buffered.host placeholder="example.com" enter=(action "save") class="host-name"}} + {{input value=buffered.host placeholder="example.com" enter=(action "save") class="host-name" autofocus=true}}
{{i18n "admin.embedding.class_name"}}
diff --git a/app/assets/javascripts/admin/addon/templates/components/watched-word-form.hbs b/app/assets/javascripts/admin/addon/templates/components/watched-word-form.hbs index 0aa201b602..eba5ecabda 100644 --- a/app/assets/javascripts/admin/addon/templates/components/watched-word-form.hbs +++ b/app/assets/javascripts/admin/addon/templates/components/watched-word-form.hbs @@ -1,5 +1,5 @@ {{i18n "admin.watched_words.form.label"}} -{{text-field value=word disabled=formSubmitted class="watched-word-input" autocorrect="off" autocapitalize="off" placeholderKey=placeholderKey}} +{{text-field value=word disabled=formSubmitted class="watched-word-input" autocorrect="off" autocapitalize="off" placeholderKey=placeholderKey title=(i18n placeholderKey)}} {{d-button class="btn-default" action=(action "submit") disabled=formSubmitted label="admin.watched_words.form.add"}} {{#if showMessage}} diff --git a/app/assets/javascripts/admin/addon/templates/customize-colors-show.hbs b/app/assets/javascripts/admin/addon/templates/customize-colors-show.hbs index e359c1fe67..eeabe4e5c9 100644 --- a/app/assets/javascripts/admin/addon/templates/customize-colors-show.hbs +++ b/app/assets/javascripts/admin/addon/templates/customize-colors-show.hbs @@ -41,31 +41,34 @@
- {{#if model.theme_id}} - {{inline-edit-checkbox action=(action "applyUserSelectable") labelKey="admin.customize.theme.color_scheme_user_selectable" checked=model.user_selectable modelId=model.id}} - {{else}} - - {{/if}} + {{#unless model.theme_id}} +
+ +
+ {{/unless}} + +
+ {{#if model.theme_id}} + {{inline-edit-checkbox action=(action "applyUserSelectable") labelKey="admin.customize.theme.color_scheme_user_selectable" checked=model.user_selectable modelId=model.id}} + {{else}} + + {{/if}} +
{{#if colors.length}} - + - + diff --git a/app/assets/javascripts/admin/addon/templates/customize-themes-edit.hbs b/app/assets/javascripts/admin/addon/templates/customize-themes-edit.hbs index a4e7fa583f..32e3521f65 100644 --- a/app/assets/javascripts/admin/addon/templates/customize-themes-edit.hbs +++ b/app/assets/javascripts/admin/addon/templates/customize-themes-edit.hbs @@ -1,6 +1,21 @@
-

{{i18n "admin.customize.theme.edit_css_html"}} {{#link-to showRouteName model.id replace=true}}{{model.name}}{{/link-to}}

+
+ {{d-button + title="go_back" + action=(action "goBack") + icon="chevron-left" + class="btn-small editor-back-button" + }} + + + {{i18n "admin.customize.theme.edit_css_html"}} + {{#link-to showRouteName model.id replace=true class="editor-theme-name" + }} + {{model.name}} + {{/link-to}} + +
{{admin-theme-editor theme=model @@ -15,14 +30,24 @@
- - {{/unless}} + {{/if}} + diff --git a/app/assets/javascripts/discourse/app/templates/components/emoji-picker.hbs b/app/assets/javascripts/discourse/app/templates/components/emoji-picker.hbs index f5873c44a1..7dd6db19eb 100644 --- a/app/assets/javascripts/discourse/app/templates/components/emoji-picker.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/emoji-picker.hbs @@ -84,7 +84,7 @@ {{d-button icon=diversityScale.icon class=(concat "diversity-scale " diversityScale.name) - title=(concat "emoji_picker." diversityScale.name "_tone") + title=diversityScale.title action=(action "onDiversitySelection" index) }} {{/each}} diff --git a/app/assets/javascripts/discourse/app/templates/components/future-date-input.hbs b/app/assets/javascripts/discourse/app/templates/components/future-date-input.hbs index 43c7e421e0..aa92210bc7 100644 --- a/app/assets/javascripts/discourse/app/templates/components/future-date-input.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/future-date-input.hbs @@ -1,7 +1,7 @@
{{#unless isBasedOnDuration}}
- + {{future-date-input-selector minimumResultsForSearch=-1 statusType=statusType diff --git a/app/assets/javascripts/discourse/app/templates/components/google-search.hbs b/app/assets/javascripts/discourse/app/templates/components/google-search.hbs index cbe90dcbce..16b84de567 100644 --- a/app/assets/javascripts/discourse/app/templates/components/google-search.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/google-search.hbs @@ -1,6 +1,6 @@
- + diff --git a/app/assets/javascripts/discourse/app/templates/components/groups-form-interaction-fields.hbs b/app/assets/javascripts/discourse/app/templates/components/groups-form-interaction-fields.hbs index 12bcf7b137..82725adc49 100644 --- a/app/assets/javascripts/discourse/app/templates/components/groups-form-interaction-fields.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/groups-form-interaction-fields.hbs @@ -94,10 +94,11 @@ {{notifications-button - value=model.default_notification_level + value=defaultNotificationLevel class="groups-form-default-notification-level" options=(hash i18nPrefix="groups.notifications" ) + onChange=(action (mut model.default_notification_level)) }}
diff --git a/app/assets/javascripts/discourse/app/templates/components/html-with-links.hbs b/app/assets/javascripts/discourse/app/templates/components/html-with-links.hbs new file mode 100644 index 0000000000..889d9eeadc --- /dev/null +++ b/app/assets/javascripts/discourse/app/templates/components/html-with-links.hbs @@ -0,0 +1 @@ +{{yield}} diff --git a/app/assets/javascripts/discourse/app/templates/components/invite-link-panel.hbs b/app/assets/javascripts/discourse/app/templates/components/invite-link-panel.hbs index 17f2e30bfb..75bbb20e4a 100644 --- a/app/assets/javascripts/discourse/app/templates/components/invite-link-panel.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/invite-link-panel.hbs @@ -26,7 +26,7 @@ - {{input type="number" value=maxRedemptionAllowed class="max-redemptions-allowed-input" min="2" max=siteSettings.invite_link_max_redemptions_limit}} + {{input type="number" value=maxRedemptionAllowed class="max-redemptions-allowed-input" min="1" max=siteSettings.invite_link_max_redemptions_limit}}
+ +{{plugin-outlet + name="after-topic-list-body" + args=(hash + topics=topics + selected=selected + bulkSelectEnabled=bulkSelectEnabled + lastVisitedTopic=lastVisitedTopic + discoveryList=discoveryList + hideCategory=hideCategory) + tagName="" + connectorTagName=""}} diff --git a/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs b/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs index 28e08da19e..b14298cd26 100644 --- a/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs @@ -81,9 +81,9 @@
  • {{d-button class="btn-default" - action=(action "togglePosts" this.user) + action=(action "filterPosts" this.user) icon="filter" - translatedLabel=this.togglePostsLabel}} + translatedLabel=this.filterPostsLabel}}
  • {{/if}} {{#if this.hasUserFilters}} @@ -142,7 +142,11 @@ {{else}} {{#if this.user.bio_excerpt}} -
    {{html-safe this.user.bio_excerpt}}
    +
    + {{#html-with-links}} + {{html-safe this.user.bio_excerpt}} + {{/html-with-links}} +
    {{/if}} {{/if}} diff --git a/app/assets/javascripts/discourse/app/templates/components/user-notification-schedule-day.hbs b/app/assets/javascripts/discourse/app/templates/components/user-notification-schedule-day.hbs new file mode 100644 index 0000000000..b03f167228 --- /dev/null +++ b/app/assets/javascripts/discourse/app/templates/components/user-notification-schedule-day.hbs @@ -0,0 +1,22 @@ + + + + {{#if endTimeOptions}} + + + {{/if}} + diff --git a/app/assets/javascripts/discourse/app/templates/components/user-notification-schedule.hbs b/app/assets/javascripts/discourse/app/templates/components/user-notification-schedule.hbs new file mode 100644 index 0000000000..acc1486e76 --- /dev/null +++ b/app/assets/javascripts/discourse/app/templates/components/user-notification-schedule.hbs @@ -0,0 +1,26 @@ +
    + + {{preference-checkbox + labelKey="user.notification_schedule.label" + checked=model.user_notification_schedule.enabled}} + + {{#if model.user_notification_schedule.enabled}} +
    {{i18n "user.notification_schedule.tip"}}
    + +
    - {{i18n "admin.customize.color"}} - {{#unless model.theme_id}} - - {{/unless}} -
    {{dayLabel}} + {{combo-box + valueProperty="value" + content=startTimeOptions + value=startTimeValue + onChange=onChangeStartTime + }} + {{i18n "user.notification_schedule.to"}} + {{combo-box + valueProperty="value" + content=endTimeOptions + value=endTimeValue + onChange=onChangeEndTime + }} +
    + + {{#each days as |day|}} + {{user-notification-schedule-day + day=day.day + startTimeOptions=day.startTimeOptions + startTimeValue=day.startTimeValue + onChangeStartTime=day.onChangeStartTime + endTimeOptions=day.endTimeOptions + endTimeValue=day.endTimeValue + onChangeEndTime=day.onChangeEndTime + }} + {{/each}} + +
    + {{/if}} + diff --git a/app/assets/javascripts/discourse/app/templates/discovery.hbs b/app/assets/javascripts/discourse/app/templates/discovery.hbs index 6358886107..a5f57bbd41 100644 --- a/app/assets/javascripts/discourse/app/templates/discovery.hbs +++ b/app/assets/javascripts/discourse/app/templates/discovery.hbs @@ -1,41 +1,37 @@ -{{#if errorHtml}} - {{html-safe errorHtml}} -{{else}} +
    + {{discourse-banner user=currentUser banner=site.banner}} + {{#unless viewingCategoriesList}} + {{category-read-only-banner category=category readOnly=navigationCategory.cannotCreateTopicOnCategory}} + {{/unless}} +
    + +
    - {{discourse-banner user=currentUser banner=site.banner}} - {{#unless viewingCategoriesList}} - {{category-read-only-banner category=category readOnly=navigationCategory.cannotCreateTopicOnCategory}} - {{/unless}} + {{outlet "navigation-bar"}}
    +
    -
    -
    - {{outlet "navigation-bar"}} -
    -
    +{{conditional-loading-spinner condition=loading}} - {{conditional-loading-spinner condition=loading}} +{{plugin-outlet name="discovery-above"}} - {{plugin-outlet name="discovery-above"}} - -
    -
    -
    -
    - {{outlet "header-list-container"}} -
    -
    -
    -
    -
    -
    - {{plugin-outlet name="discovery-list-container-top" - args=(hash category=category listLoading=loading)}} - {{outlet "list-container"}} -
    +
    +
    +
    +
    + {{outlet "header-list-container"}}
    +
    +
    +
    + {{plugin-outlet name="discovery-list-container-top" + args=(hash category=category listLoading=loading)}} + {{outlet "list-container"}} +
    +
    +
    +
    - {{plugin-outlet name="discovery-below"}} -{{/if}} +{{plugin-outlet name="discovery-below"}} diff --git a/app/assets/javascripts/discourse/app/templates/full-page-search.hbs b/app/assets/javascripts/discourse/app/templates/full-page-search.hbs index f95bc36dc7..fcbd8c506d 100644 --- a/app/assets/javascripts/discourse/app/templates/full-page-search.hbs +++ b/app/assets/javascripts/discourse/app/templates/full-page-search.hbs @@ -4,8 +4,8 @@
    {{#unless site.mobileView}} {{/unless}} @@ -87,7 +87,7 @@ {{/if}} - {{topic-status topic=result.topic disableActions=true showPrivateMessageIcon=true}} + {{raw "topic-status" topic=result.topic showPrivateMessageIcon=true}} {{#if result.useTopicTitleHeadline}} {{html-safe result.topicTitleHeadline}} @@ -104,16 +104,16 @@ {{category-link result.topic.category.parentCategory}} {{/if}} {{category-link result.topic.category hideParent=true}} - {{#each result.topic.tags as |tag|}} - {{discourse-tag tag isPrivateMessage=isPrivateMessage}} - {{/each}} + {{#if result.topic}} + {{discourse-tags result.topic}} + {{/if}} {{plugin-outlet name="full-page-search-category" args=(hash result=result)}}
    - {{format-age result.created_at}} + {{format-date result.created_at format="tiny"}} {{#if result.blurb}} - {{/if}} @@ -193,7 +193,7 @@ {{#if site.mobileView}} {{/if}} diff --git a/app/assets/javascripts/discourse/app/templates/group-activity-posts.hbs b/app/assets/javascripts/discourse/app/templates/group-activity-posts.hbs index f134929e6c..8e833dc151 100644 --- a/app/assets/javascripts/discourse/app/templates/group-activity-posts.hbs +++ b/app/assets/javascripts/discourse/app/templates/group-activity-posts.hbs @@ -1,7 +1,7 @@ {{#load-more selector=".user-stream-item" action=(action "loadMore")}}
    {{#each model as |post|}} - {{group-post post=post class="user-stream-item item"}} + {{group-post post=post}} {{else}}
    {{i18n emptyText}}
    {{/each}} diff --git a/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs b/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs index 604ac18524..8560c2f1ae 100644 --- a/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs +++ b/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs @@ -1,4 +1,7 @@
    + + {{plugin-outlet name="before-manage-group-tags" args=(hash model=model) tagName=""}} +
    {{i18n "groups.manage.tags.description"}}
    diff --git a/app/assets/javascripts/discourse/app/templates/groups/index.hbs b/app/assets/javascripts/discourse/app/templates/groups/index.hbs index 5abcf07eeb..ee9e3fe4ee 100644 --- a/app/assets/javascripts/discourse/app/templates/groups/index.hbs +++ b/app/assets/javascripts/discourse/app/templates/groups/index.hbs @@ -1,3 +1,5 @@ +{{plugin-outlet name="before-groups-index-container" tagName=""}} + {{#d-section pageClass="groups"}}
    {{/if}} - {{text-field value=nameInput placeholderKey="directory.filter_name" class="filter-name no-blur"}} + {{input + value=(readonly nameInput) + input=(action "onFilterChanged" value="target.value") + placeholderKey="directory.filter_name" + class="filter-name no-blur" + }}
    {{#conditional-loading-spinner condition=model.loading}} diff --git a/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs b/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs index 67429842ef..bb86ad93f6 100644 --- a/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs +++ b/app/assets/javascripts/discourse/app/templates/modal/avatar-selector.hbs @@ -12,21 +12,21 @@ {{radio-button id="system-avatar" name="avatar" value="system" selection=selected}}
    -
    - {{radio-button id="gravatar" name="avatar" value="gravatar" selection=selected}} - - - {{d-button action=(action "refreshGravatar") - translatedTitle=(i18n "user.change_avatar.refresh_gravatar_title" gravatarName=gravatarName) - disabled=gravatarRefreshDisabled - icon="sync" - class="btn-default avatar-selector-refresh-gravatar"}} - - {{#if gravatarFailed}} -

    {{I18n "user.change_avatar.gravatar_failed" gravatarName=gravatarName}}

    - {{/if}} -
    {{#if allowAvatarUpload}} +
    + {{radio-button id="gravatar" name="avatar" value="gravatar" selection=selected}} + + + {{d-button action=(action "refreshGravatar") + translatedTitle=(i18n "user.change_avatar.refresh_gravatar_title" gravatarName=gravatarName) + disabled=gravatarRefreshDisabled + icon="sync" + class="btn-default avatar-selector-refresh-gravatar"}} + + {{#if gravatarFailed}} +

    {{I18n "user.change_avatar.gravatar_failed" gravatarName=gravatarName}}

    + {{/if}} +
    {{radio-button id="uploaded-avatar" name="avatar" value="uploaded" selection=selected}}