discourse/app/assets/javascripts/admin/controllers/modals/admin-install-theme.js
2020-03-13 17:03:08 -04:00

199 lines
5.3 KiB
JavaScript

import { equal, match, alias } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
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;
export default Controller.extend(ModalFunctionality, {
adminCustomizeThemes: controller(),
themesController: controller("adminCustomizeThemes"),
popular: equal("selection", "popular"),
local: equal("selection", "local"),
remote: equal("selection", "remote"),
create: equal("selection", "create"),
selection: "popular",
loading: false,
keyGenUrl: "/admin/themes/generate_key_pair",
importUrl: "/admin/themes/import",
recordType: "theme",
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),
init() {
this._super(...arguments);
this.createTypes = [
{ name: I18n.t("admin.customize.theme.theme"), value: THEMES },
{ name: I18n.t("admin.customize.theme.component"), value: COMPONENTS }
];
},
@discourseComputed("themesController.installedThemes")
themes(installedThemes) {
return POPULAR_THEMES.map(t => {
if (installedThemes.includes(t.name)) {
set(t, "installed", true);
}
return t;
});
},
@discourseComputed(
"loading",
"remote",
"uploadUrl",
"local",
"localFile",
"create",
"nameTooShort"
)
installDisabled(
isLoading,
isRemote,
uploadUrl,
isLocal,
localFile,
isCreate,
nameTooShort
) {
return (
isLoading ||
(isRemote && !uploadUrl) ||
(isLocal && !localFile) ||
(isCreate && nameTooShort)
);
},
@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;
ajax(this.keyGenUrl, { method: "POST" })
.then(pair => {
this.setProperties({
privateKey: pair.private_key,
publicKey: pair.public_key
});
})
.catch(popupAjaxError)
.finally(() => {
this._keyLoading = false;
});
}
},
@discourseComputed("name")
nameTooShort(name) {
return !name || name.length < MIN_NAME_LENGTH;
},
@discourseComputed("component")
placeholder(component) {
if (component) {
return I18n.t("admin.customize.theme.component_name");
} else {
return I18n.t("admin.customize.theme.theme_name");
}
},
@discourseComputed("selection")
submitLabel(selection) {
return `admin.customize.theme.${
selection === "create" ? "create" : "install"
}`;
},
@discourseComputed("privateChecked", "checkPrivate", "publicKey")
showPublicKey(privateChecked, checkPrivate, publicKey) {
return privateChecked && checkPrivate && publicKey;
},
actions: {
uploadLocaleFile() {
this.set("localFile", $("#file-input")[0].files[0]);
},
toggleAdvanced() {
this.toggleProperty("advancedVisible");
},
installThemeFromList(url) {
this.set("uploadUrl", url);
this.send("installTheme");
},
installTheme() {
if (this.create) {
this.set("loading", true);
const theme = this.store.createRecord(this.recordType);
theme
.save({ name: this.name, component: this.component })
.then(() => {
this.themesController.send("addTheme", theme);
this.send("closeModal");
})
.catch(popupAjaxError)
.finally(() => this.set("loading", false));
return;
}
let options = {
type: "POST"
};
if (this.local) {
options.processData = false;
options.contentType = false;
options.data = new FormData();
options.data.append("theme", this.localFile);
}
if (this.remote || this.popular) {
options.data = {
remote: this.uploadUrl,
branch: this.branch
};
if (this.privateChecked) {
options.data.private_key = this.privateKey;
}
}
if (this.get("model.user_id")) {
// Used by theme-creator
options.data["user_id"] = this.get("model.user_id");
}
this.set("loading", true);
ajax(this.importUrl, options)
.then(result => {
const theme = this.store.createRecord(this.recordType, result.theme);
this.adminCustomizeThemes.send("addTheme", theme);
this.send("closeModal");
})
.then(() => {
this.setProperties({ privateKey: null, publicKey: null });
})
.catch(popupAjaxError)
.finally(() => this.set("loading", false));
}
}
});