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 01cc3154234..66f87c52e22 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
@@ -18,6 +18,7 @@ export default Controller.extend(ModalFunctionality, {
local: equal("selection", "local"),
remote: equal("selection", "remote"),
create: equal("selection", "create"),
+ directRepoInstall: equal("selection", "directRepoInstall"),
selection: "popular",
loading: false,
keyGenUrl: "/admin/themes/generate_key_pair",
@@ -26,6 +27,7 @@ export default Controller.extend(ModalFunctionality, {
checkPrivate: match("uploadUrl", /^git/),
localFile: null,
uploadUrl: null,
+ uploadName: null,
advancedVisible: false,
selectedType: alias("themesController.currentTab"),
component: equal("selectedType", COMPONENTS),
@@ -136,6 +138,7 @@ export default Controller.extend(ModalFunctionality, {
uploadUrl: null,
publicKey: null,
branch: null,
+ selection: "popular",
});
},
@@ -189,7 +192,7 @@ export default Controller.extend(ModalFunctionality, {
options.data.append("theme", this.localFile);
}
- if (this.remote || this.popular) {
+ if (this.remote || this.popular || this.directRepoInstall) {
const duplicate = this.themesController.model.content.find((theme) =>
this.themeHasSameUrl(theme, this.uploadUrl)
);
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 9397c938a9b..5eeae3a5516 100644
--- a/app/assets/javascripts/admin/addon/routes/admin-customize-themes.js
+++ b/app/assets/javascripts/admin/addon/routes/admin-customize-themes.js
@@ -1,8 +1,14 @@
import Route from "@ember/routing/route";
import showModal from "discourse/lib/show-modal";
+import { next } from "@ember/runloop";
import { showUnassignedComponentWarning } from "admin/routes/admin-customize-themes-show";
export default Route.extend({
+ queryParams: {
+ repoUrl: null,
+ repoName: null,
+ },
+
model() {
return this.store.findAll("theme");
},
@@ -10,6 +16,18 @@ export default Route.extend({
setupController(controller, model) {
this._super(controller, model);
controller.set("editingTheme", false);
+
+ if (controller.repoUrl) {
+ next(() => {
+ showModal("admin-install-theme", {
+ admin: true,
+ }).setProperties({
+ uploadUrl: controller.repoUrl,
+ uploadName: controller.repoName,
+ selection: "directRepoInstall",
+ });
+ });
+ }
},
actions: {
@@ -30,7 +48,12 @@ export default Route.extend({
addTheme(theme) {
this.refresh();
theme.setProperties({ recentlyInstalled: true });
- this.transitionTo("adminCustomizeThemes.show", theme.get("id"));
+ this.transitionTo("adminCustomizeThemes.show", theme.get("id"), {
+ queryParams: {
+ repoName: null,
+ repoUrl: null,
+ },
+ });
},
},
});
diff --git a/app/assets/javascripts/admin/addon/templates/modal/admin-install-theme.hbs b/app/assets/javascripts/admin/addon/templates/modal/admin-install-theme.hbs
index bbe8e4a83a2..5f09f339703 100644
--- a/app/assets/javascripts/admin/addon/templates/modal/admin-install-theme.hbs
+++ b/app/assets/javascripts/admin/addon/templates/modal/admin-install-theme.hbs
@@ -1,10 +1,12 @@
{{#d-modal-body class="upload-selector install-theme" title="admin.customize.theme.install"}}
-
- {{install-theme-item value="popular" selection=selection label="admin.customize.theme.install_popular"}}
- {{install-theme-item value="local" selection=selection label="admin.customize.theme.install_upload"}}
- {{install-theme-item value="remote" selection=selection label="admin.customize.theme.install_git_repo"}}
- {{install-theme-item value="create" selection=selection label="admin.customize.theme.install_create" showIcon=true}}
-
+ {{#unless directRepoInstall}}
+
+ {{install-theme-item value="popular" selection=selection label="admin.customize.theme.install_popular"}}
+ {{install-theme-item value="local" selection=selection label="admin.customize.theme.install_upload"}}
+ {{install-theme-item value="remote" selection=selection label="admin.customize.theme.install_git_repo"}}
+ {{install-theme-item value="create" selection=selection label="admin.customize.theme.install_create" showIcon=true}}
+
+ {{/unless}}
{{#if popular}}
@@ -97,6 +99,13 @@
}}
{{/if}}
+
+ {{#if directRepoInstall}}
+
+
{{html-safe (i18n "admin.customize.theme.direct_install_tip" name=uploadName)}}
+
{{uploadUrl}}
+
+ {{/if}}
{{/d-modal-body}}
diff --git a/app/assets/javascripts/admin/tests/admin/acceptance/admin-install-theme-modal-test.js b/app/assets/javascripts/admin/tests/admin/acceptance/admin-install-theme-modal-test.js
index 47054dbc5be..bbafc25c4f2 100644
--- a/app/assets/javascripts/admin/tests/admin/acceptance/admin-install-theme-modal-test.js
+++ b/app/assets/javascripts/admin/tests/admin/acceptance/admin-install-theme-modal-test.js
@@ -1,4 +1,4 @@
-import { acceptance, queryAll } from "discourse/tests/helpers/qunit-helpers";
+import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, visit } from "@ember/test-helpers";
import { test } from "qunit";
@@ -18,13 +18,14 @@ acceptance("Admin - Themes - Install modal", function (needs) {
await click(".install-theme-content .inputs .advanced-repo");
await fillIn(branchInput, "tests-passed");
await click(privateRepoCheckbox);
- assert.ok(queryAll(urlInput)[0].value === themeUrl, "url input is filled");
- assert.ok(
- queryAll(branchInput)[0].value === "tests-passed",
+ assert.equal(query(urlInput).value, themeUrl, "url input is filled");
+ assert.equal(
+ query(branchInput).value,
+ "tests-passed",
"branch input is filled"
);
assert.ok(
- queryAll(privateRepoCheckbox)[0].checked,
+ query(privateRepoCheckbox).checked,
"private repo checkbox is checked"
);
@@ -32,11 +33,21 @@ acceptance("Admin - Themes - Install modal", function (needs) {
await click(".create-actions .btn-primary");
await click("#remote");
- assert.ok(queryAll(urlInput)[0].value === "", "url input is reset");
- assert.ok(queryAll(branchInput)[0].value === "", "branch input is reset");
+ assert.equal(query(urlInput).value, "", "url input is reset");
+ assert.equal(query(branchInput).value, "", "branch input is reset");
assert.ok(
- !queryAll(privateRepoCheckbox)[0].checked,
+ !query(privateRepoCheckbox).checked,
"private repo checkbox unchecked"
);
});
+
+ test("modal can be auto-opened with the right query params", async function (assert) {
+ await visit("/admin/customize/themes?repoUrl=testUrl&repoName=testName");
+ assert.ok(query(".admin-install-theme-modal"), "modal is visible");
+ assert.equal(
+ query(".install-theme code").textContent.trim(),
+ "testUrl",
+ "repo url is visible"
+ );
+ });
});
diff --git a/app/assets/stylesheets/common/admin/customize-install-theme.scss b/app/assets/stylesheets/common/admin/customize-install-theme.scss
index 141365c6e6d..939d4be29b5 100644
--- a/app/assets/stylesheets/common/admin/customize-install-theme.scss
+++ b/app/assets/stylesheets/common/admin/customize-install-theme.scss
@@ -62,14 +62,18 @@
}
.install-theme-content {
- padding: 0px 0px 10px 20px;
- width: calc(100% - 200px);
+ width: calc(100% - 20px);
input[type="file"] {
width: 100%;
overflow: hidden; // Chrome needs this
}
}
+.install-theme-items + .install-theme-content {
+ padding: 0px 0px 10px 20px;
+ width: calc(100% - 200px);
+}
+
.repo {
input[type="text"] {
width: 90%;
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index b0ebd9d2649..b2843a7bb81 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -4190,6 +4190,7 @@ en:
included_components: "Included components"
add_all: "Add all"
import_web_tip: "Repository containing theme"
+ direct_install_tip: "Are you sure you want to install %{name} from the repository listed below?"
import_web_advanced: "Advanced..."
import_file_tip: ".tar.gz, .zip, or .dcstyle.json file containing theme"
is_private: "Theme is in a private git repository"