FEATURE: Quick theme installs via query parameters (#12128)
This commit is contained in:
parent
e175e17ebb
commit
916e1d85cf
|
@ -18,6 +18,7 @@ export default Controller.extend(ModalFunctionality, {
|
||||||
local: equal("selection", "local"),
|
local: equal("selection", "local"),
|
||||||
remote: equal("selection", "remote"),
|
remote: equal("selection", "remote"),
|
||||||
create: equal("selection", "create"),
|
create: equal("selection", "create"),
|
||||||
|
directRepoInstall: equal("selection", "directRepoInstall"),
|
||||||
selection: "popular",
|
selection: "popular",
|
||||||
loading: false,
|
loading: false,
|
||||||
keyGenUrl: "/admin/themes/generate_key_pair",
|
keyGenUrl: "/admin/themes/generate_key_pair",
|
||||||
|
@ -26,6 +27,7 @@ export default Controller.extend(ModalFunctionality, {
|
||||||
checkPrivate: match("uploadUrl", /^git/),
|
checkPrivate: match("uploadUrl", /^git/),
|
||||||
localFile: null,
|
localFile: null,
|
||||||
uploadUrl: null,
|
uploadUrl: null,
|
||||||
|
uploadName: null,
|
||||||
advancedVisible: false,
|
advancedVisible: false,
|
||||||
selectedType: alias("themesController.currentTab"),
|
selectedType: alias("themesController.currentTab"),
|
||||||
component: equal("selectedType", COMPONENTS),
|
component: equal("selectedType", COMPONENTS),
|
||||||
|
@ -136,6 +138,7 @@ export default Controller.extend(ModalFunctionality, {
|
||||||
uploadUrl: null,
|
uploadUrl: null,
|
||||||
publicKey: null,
|
publicKey: null,
|
||||||
branch: null,
|
branch: null,
|
||||||
|
selection: "popular",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -189,7 +192,7 @@ export default Controller.extend(ModalFunctionality, {
|
||||||
options.data.append("theme", this.localFile);
|
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) =>
|
const duplicate = this.themesController.model.content.find((theme) =>
|
||||||
this.themeHasSameUrl(theme, this.uploadUrl)
|
this.themeHasSameUrl(theme, this.uploadUrl)
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
import showModal from "discourse/lib/show-modal";
|
import showModal from "discourse/lib/show-modal";
|
||||||
|
import { next } from "@ember/runloop";
|
||||||
import { showUnassignedComponentWarning } from "admin/routes/admin-customize-themes-show";
|
import { showUnassignedComponentWarning } from "admin/routes/admin-customize-themes-show";
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
|
queryParams: {
|
||||||
|
repoUrl: null,
|
||||||
|
repoName: null,
|
||||||
|
},
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
return this.store.findAll("theme");
|
return this.store.findAll("theme");
|
||||||
},
|
},
|
||||||
|
@ -10,6 +16,18 @@ export default Route.extend({
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
this._super(controller, model);
|
this._super(controller, model);
|
||||||
controller.set("editingTheme", false);
|
controller.set("editingTheme", false);
|
||||||
|
|
||||||
|
if (controller.repoUrl) {
|
||||||
|
next(() => {
|
||||||
|
showModal("admin-install-theme", {
|
||||||
|
admin: true,
|
||||||
|
}).setProperties({
|
||||||
|
uploadUrl: controller.repoUrl,
|
||||||
|
uploadName: controller.repoName,
|
||||||
|
selection: "directRepoInstall",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -30,7 +48,12 @@ export default Route.extend({
|
||||||
addTheme(theme) {
|
addTheme(theme) {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
theme.setProperties({ recentlyInstalled: true });
|
theme.setProperties({ recentlyInstalled: true });
|
||||||
this.transitionTo("adminCustomizeThemes.show", theme.get("id"));
|
this.transitionTo("adminCustomizeThemes.show", theme.get("id"), {
|
||||||
|
queryParams: {
|
||||||
|
repoName: null,
|
||||||
|
repoUrl: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
{{#d-modal-body class="upload-selector install-theme" title="admin.customize.theme.install"}}
|
{{#d-modal-body class="upload-selector install-theme" title="admin.customize.theme.install"}}
|
||||||
<div class="install-theme-items">
|
{{#unless directRepoInstall}}
|
||||||
{{install-theme-item value="popular" selection=selection label="admin.customize.theme.install_popular"}}
|
<div class="install-theme-items">
|
||||||
{{install-theme-item value="local" selection=selection label="admin.customize.theme.install_upload"}}
|
{{install-theme-item value="popular" selection=selection label="admin.customize.theme.install_popular"}}
|
||||||
{{install-theme-item value="remote" selection=selection label="admin.customize.theme.install_git_repo"}}
|
{{install-theme-item value="local" selection=selection label="admin.customize.theme.install_upload"}}
|
||||||
{{install-theme-item value="create" selection=selection label="admin.customize.theme.install_create" showIcon=true}}
|
{{install-theme-item value="remote" selection=selection label="admin.customize.theme.install_git_repo"}}
|
||||||
</div>
|
{{install-theme-item value="create" selection=selection label="admin.customize.theme.install_create" showIcon=true}}
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
<div class="install-theme-content">
|
<div class="install-theme-content">
|
||||||
{{#if popular}}
|
{{#if popular}}
|
||||||
<div class="popular-theme-items">
|
<div class="popular-theme-items">
|
||||||
|
@ -97,6 +99,13 @@
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if directRepoInstall}}
|
||||||
|
<div class="repo">
|
||||||
|
<div class="label">{{html-safe (i18n "admin.customize.theme.direct_install_tip" name=uploadName)}}</div>
|
||||||
|
<pre><code>{{uploadUrl}}</code></pre>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{/d-modal-body}}
|
{{/d-modal-body}}
|
||||||
|
|
|
@ -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 { click, fillIn, visit } from "@ember/test-helpers";
|
||||||
import { test } from "qunit";
|
import { test } from "qunit";
|
||||||
|
|
||||||
|
@ -18,13 +18,14 @@ acceptance("Admin - Themes - Install modal", function (needs) {
|
||||||
await click(".install-theme-content .inputs .advanced-repo");
|
await click(".install-theme-content .inputs .advanced-repo");
|
||||||
await fillIn(branchInput, "tests-passed");
|
await fillIn(branchInput, "tests-passed");
|
||||||
await click(privateRepoCheckbox);
|
await click(privateRepoCheckbox);
|
||||||
assert.ok(queryAll(urlInput)[0].value === themeUrl, "url input is filled");
|
assert.equal(query(urlInput).value, themeUrl, "url input is filled");
|
||||||
assert.ok(
|
assert.equal(
|
||||||
queryAll(branchInput)[0].value === "tests-passed",
|
query(branchInput).value,
|
||||||
|
"tests-passed",
|
||||||
"branch input is filled"
|
"branch input is filled"
|
||||||
);
|
);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
queryAll(privateRepoCheckbox)[0].checked,
|
query(privateRepoCheckbox).checked,
|
||||||
"private repo checkbox is 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(".create-actions .btn-primary");
|
||||||
await click("#remote");
|
await click("#remote");
|
||||||
assert.ok(queryAll(urlInput)[0].value === "", "url input is reset");
|
assert.equal(query(urlInput).value, "", "url input is reset");
|
||||||
assert.ok(queryAll(branchInput)[0].value === "", "branch input is reset");
|
assert.equal(query(branchInput).value, "", "branch input is reset");
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!queryAll(privateRepoCheckbox)[0].checked,
|
!query(privateRepoCheckbox).checked,
|
||||||
"private repo checkbox unchecked"
|
"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"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -62,14 +62,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.install-theme-content {
|
.install-theme-content {
|
||||||
padding: 0px 0px 10px 20px;
|
width: calc(100% - 20px);
|
||||||
width: calc(100% - 200px);
|
|
||||||
input[type="file"] {
|
input[type="file"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden; // Chrome needs this
|
overflow: hidden; // Chrome needs this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.install-theme-items + .install-theme-content {
|
||||||
|
padding: 0px 0px 10px 20px;
|
||||||
|
width: calc(100% - 200px);
|
||||||
|
}
|
||||||
|
|
||||||
.repo {
|
.repo {
|
||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
|
|
@ -4190,6 +4190,7 @@ en:
|
||||||
included_components: "Included components"
|
included_components: "Included components"
|
||||||
add_all: "Add all"
|
add_all: "Add all"
|
||||||
import_web_tip: "Repository containing theme"
|
import_web_tip: "Repository containing theme"
|
||||||
|
direct_install_tip: "Are you sure you want to install <strong>%{name}</strong> from the repository listed below?"
|
||||||
import_web_advanced: "Advanced..."
|
import_web_advanced: "Advanced..."
|
||||||
import_file_tip: ".tar.gz, .zip, or .dcstyle.json file containing theme"
|
import_file_tip: ".tar.gz, .zip, or .dcstyle.json file containing theme"
|
||||||
is_private: "Theme is in a private git repository"
|
is_private: "Theme is in a private git repository"
|
||||||
|
|
Loading…
Reference in New Issue