mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 10:20:58 -06:00
DEV: Convert theme-upload
modal to component-based API (#22699)
This commit is contained in:
parent
a5b810fe18
commit
f3b7351ff6
@ -0,0 +1,47 @@
|
|||||||
|
<DModal
|
||||||
|
class="add-upload-modal"
|
||||||
|
@title={{i18n "admin.customize.theme.add_upload"}}
|
||||||
|
@closeModal={{@closeModal}}
|
||||||
|
@flash={{this.flash}}
|
||||||
|
>
|
||||||
|
<:body>
|
||||||
|
<div class="inputs">
|
||||||
|
<section class="field">
|
||||||
|
<input
|
||||||
|
{{on "change" this.updateName}}
|
||||||
|
type="file"
|
||||||
|
id="file-input"
|
||||||
|
accept="*"
|
||||||
|
/>
|
||||||
|
<label for="file-input">
|
||||||
|
{{i18n "admin.customize.theme.upload_file_tip"}}
|
||||||
|
</label>
|
||||||
|
</section>
|
||||||
|
<section class="field">
|
||||||
|
<label for="theme-variable-name">
|
||||||
|
{{i18n "admin.customize.theme.variable_name"}}
|
||||||
|
</label>
|
||||||
|
<Input id="theme-variable-name" @value={{this.name}} />
|
||||||
|
</section>
|
||||||
|
{{#if this.fileSelected}}
|
||||||
|
{{#if this.errorMessage}}
|
||||||
|
<span class="alert alert-error">{{this.errorMessage}}</span>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</:body>
|
||||||
|
<:footer>
|
||||||
|
<DButton
|
||||||
|
@action={{this.upload}}
|
||||||
|
@disabled={{this.disabled}}
|
||||||
|
class="btn btn-primary"
|
||||||
|
@icon="upload"
|
||||||
|
@label="admin.customize.theme.upload"
|
||||||
|
/>
|
||||||
|
<DButton
|
||||||
|
class="btn-flat d-modal-cancel"
|
||||||
|
@action={{@closeModal}}
|
||||||
|
@label="cancel"
|
||||||
|
/>
|
||||||
|
</:footer>
|
||||||
|
</DModal>
|
@ -0,0 +1,112 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import { isEmpty } from "@ember/utils";
|
||||||
|
|
||||||
|
const THEME_FIELD_VARIABLE_TYPE_IDS = [2, 3, 4];
|
||||||
|
const SCSS_VARIABLE_NAMES = [
|
||||||
|
// common/foundation/colors.scss
|
||||||
|
"primary",
|
||||||
|
"secondary",
|
||||||
|
"tertiary",
|
||||||
|
"quaternary",
|
||||||
|
"header_background",
|
||||||
|
"header_primary",
|
||||||
|
"highlight",
|
||||||
|
"danger",
|
||||||
|
"success",
|
||||||
|
"love",
|
||||||
|
// common/foundation/math.scss
|
||||||
|
"E",
|
||||||
|
"PI",
|
||||||
|
"LN2",
|
||||||
|
"SQRT2",
|
||||||
|
// common/foundation/variables.scss
|
||||||
|
"small-width",
|
||||||
|
"medium-width",
|
||||||
|
"large-width",
|
||||||
|
"google",
|
||||||
|
"instagram",
|
||||||
|
"facebook",
|
||||||
|
"cas",
|
||||||
|
"twitter",
|
||||||
|
"github",
|
||||||
|
"base-font-size",
|
||||||
|
"base-line-height",
|
||||||
|
"base-font-family",
|
||||||
|
"primary-low",
|
||||||
|
"primary-medium",
|
||||||
|
"secondary-low",
|
||||||
|
"secondary-medium",
|
||||||
|
"tertiary-low",
|
||||||
|
"quaternary-low",
|
||||||
|
"highlight-low",
|
||||||
|
"highlight-medium",
|
||||||
|
"danger-low",
|
||||||
|
"danger-medium",
|
||||||
|
"success-low",
|
||||||
|
"love-low",
|
||||||
|
];
|
||||||
|
|
||||||
|
export default class ThemeUploadAdd extends Component {
|
||||||
|
@tracked name;
|
||||||
|
@tracked fileSelected = false;
|
||||||
|
@tracked flash;
|
||||||
|
|
||||||
|
get disabled() {
|
||||||
|
return this.errorMessage && this.fileSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
get errorMessage() {
|
||||||
|
if (!this.name) {
|
||||||
|
return;
|
||||||
|
} else if (!this.name.match(/^[a-z_][a-z0-9_-]*$/i)) {
|
||||||
|
return I18n.t("admin.customize.theme.variable_name_error.invalid_syntax");
|
||||||
|
} else if (SCSS_VARIABLE_NAMES.includes(name.toLowerCase())) {
|
||||||
|
return I18n.t("admin.customize.theme.variable_name_error.no_overwrite");
|
||||||
|
} else if (
|
||||||
|
this.args.model.themeFields.some(
|
||||||
|
(tf) =>
|
||||||
|
THEME_FIELD_VARIABLE_TYPE_IDS.includes(tf.type_id) &&
|
||||||
|
this.name === tf.name
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return I18n.t("admin.customize.theme.variable_name_error.must_be_unique");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
updateName(e) {
|
||||||
|
if (isEmpty(this.name)) {
|
||||||
|
this.name = e.target.files[0].name.split(".")[0];
|
||||||
|
}
|
||||||
|
this.fileSelected = e.target.files[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async upload() {
|
||||||
|
const file = document.getElementById("file-input").files[0];
|
||||||
|
const options = {
|
||||||
|
type: "POST",
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
data: new FormData(),
|
||||||
|
};
|
||||||
|
options.data.append("file", file);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await ajax("/admin/themes/upload_asset", options);
|
||||||
|
const upload = {
|
||||||
|
upload_id: result.upload_id,
|
||||||
|
name: this.name,
|
||||||
|
original_filename: file.name,
|
||||||
|
};
|
||||||
|
this.args.model.addUpload(upload);
|
||||||
|
this.args.closeModal();
|
||||||
|
} catch (e) {
|
||||||
|
this.flash = e.jqXHR.responseJSON.errors.join(". ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,14 +14,15 @@ import ThemeSettings from "admin/models/theme-settings";
|
|||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import { makeArray } from "discourse-common/lib/helpers";
|
import { makeArray } from "discourse-common/lib/helpers";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import showModal from "discourse/lib/show-modal";
|
|
||||||
import { url } from "discourse/lib/computed";
|
import { url } from "discourse/lib/computed";
|
||||||
|
import ThemeUploadAddModal from "../components/theme-upload-add";
|
||||||
|
|
||||||
const THEME_UPLOAD_VAR = 2;
|
const THEME_UPLOAD_VAR = 2;
|
||||||
|
|
||||||
export default class AdminCustomizeThemesShowController extends Controller {
|
export default class AdminCustomizeThemesShowController extends Controller {
|
||||||
@service dialog;
|
@service dialog;
|
||||||
@service router;
|
@service router;
|
||||||
|
@service modal;
|
||||||
|
|
||||||
editRouteName = "adminCustomizeThemes.edit";
|
editRouteName = "adminCustomizeThemes.edit";
|
||||||
|
|
||||||
@ -274,7 +275,12 @@ export default class AdminCustomizeThemesShowController extends Controller {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
addUploadModal() {
|
addUploadModal() {
|
||||||
showModal("admin-add-upload", { admin: true, name: "" });
|
this.modal.show(ThemeUploadAddModal, {
|
||||||
|
model: {
|
||||||
|
themeFields: this.model.theme_fields,
|
||||||
|
addUpload: this.addUpload,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -1,146 +0,0 @@
|
|||||||
import { action } from "@ember/object";
|
|
||||||
import { and, not } from "@ember/object/computed";
|
|
||||||
import Controller, { inject as controller } from "@ember/controller";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { observes } from "@ember-decorators/object";
|
|
||||||
import I18n from "I18n";
|
|
||||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
||||||
|
|
||||||
const THEME_FIELD_VARIABLE_TYPE_IDS = [2, 3, 4];
|
|
||||||
|
|
||||||
const SCSS_VARIABLE_NAMES = [
|
|
||||||
// common/foundation/colors.scss
|
|
||||||
"primary",
|
|
||||||
"secondary",
|
|
||||||
"tertiary",
|
|
||||||
"quaternary",
|
|
||||||
"header_background",
|
|
||||||
"header_primary",
|
|
||||||
"highlight",
|
|
||||||
"danger",
|
|
||||||
"success",
|
|
||||||
"love",
|
|
||||||
// common/foundation/math.scss
|
|
||||||
"E",
|
|
||||||
"PI",
|
|
||||||
"LN2",
|
|
||||||
"SQRT2",
|
|
||||||
// common/foundation/variables.scss
|
|
||||||
"small-width",
|
|
||||||
"medium-width",
|
|
||||||
"large-width",
|
|
||||||
"google",
|
|
||||||
"instagram",
|
|
||||||
"facebook",
|
|
||||||
"cas",
|
|
||||||
"twitter",
|
|
||||||
"github",
|
|
||||||
"base-font-size",
|
|
||||||
"base-line-height",
|
|
||||||
"base-font-family",
|
|
||||||
"primary-low",
|
|
||||||
"primary-medium",
|
|
||||||
"secondary-low",
|
|
||||||
"secondary-medium",
|
|
||||||
"tertiary-low",
|
|
||||||
"quaternary-low",
|
|
||||||
"highlight-low",
|
|
||||||
"highlight-medium",
|
|
||||||
"danger-low",
|
|
||||||
"danger-medium",
|
|
||||||
"success-low",
|
|
||||||
"love-low",
|
|
||||||
];
|
|
||||||
|
|
||||||
export default class AdminAddUploadController extends Controller.extend(
|
|
||||||
ModalFunctionality
|
|
||||||
) {
|
|
||||||
@controller adminCustomizeThemesShow;
|
|
||||||
|
|
||||||
uploadUrl = "/admin/themes/upload_asset";
|
|
||||||
|
|
||||||
@and("nameValid", "fileSelected") enabled;
|
|
||||||
@not("enabled") disabled;
|
|
||||||
|
|
||||||
onShow() {
|
|
||||||
this.set("name", null);
|
|
||||||
this.set("fileSelected", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@discourseComputed("name", "adminCustomizeThemesShow.model.theme_fields")
|
|
||||||
errorMessage(name, themeFields) {
|
|
||||||
if (name) {
|
|
||||||
if (!name.match(/^[a-z_][a-z0-9_-]*$/i)) {
|
|
||||||
return I18n.t(
|
|
||||||
"admin.customize.theme.variable_name_error.invalid_syntax"
|
|
||||||
);
|
|
||||||
} else if (SCSS_VARIABLE_NAMES.includes(name.toLowerCase())) {
|
|
||||||
return I18n.t("admin.customize.theme.variable_name_error.no_overwrite");
|
|
||||||
} else if (
|
|
||||||
themeFields.some(
|
|
||||||
(tf) =>
|
|
||||||
THEME_FIELD_VARIABLE_TYPE_IDS.includes(tf.type_id) &&
|
|
||||||
name === tf.name
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return I18n.t(
|
|
||||||
"admin.customize.theme.variable_name_error.must_be_unique"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@discourseComputed("errorMessage")
|
|
||||||
nameValid(errorMessage) {
|
|
||||||
return null === errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@observes("name")
|
|
||||||
uploadChanged() {
|
|
||||||
const file = $("#file-input")[0];
|
|
||||||
this.set("fileSelected", file && file.files[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
updateName() {
|
|
||||||
let name = this.name;
|
|
||||||
if (isEmpty(name)) {
|
|
||||||
name = $("#file-input")[0].files[0].name;
|
|
||||||
this.set("name", name.split(".")[0]);
|
|
||||||
}
|
|
||||||
this.uploadChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
upload() {
|
|
||||||
const file = $("#file-input")[0].files[0];
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
type: "POST",
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
data: new FormData(),
|
|
||||||
};
|
|
||||||
|
|
||||||
options.data.append("file", file);
|
|
||||||
|
|
||||||
ajax(this.uploadUrl, options)
|
|
||||||
.then((result) => {
|
|
||||||
const upload = {
|
|
||||||
upload_id: result.upload_id,
|
|
||||||
name: this.name,
|
|
||||||
original_filename: file.name,
|
|
||||||
};
|
|
||||||
this.adminCustomizeThemesShow.send("addUpload", upload);
|
|
||||||
this.send("closeModal");
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
popupAjaxError(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<DModalBody @class="add-upload-modal" @title="admin.customize.theme.add_upload">
|
|
||||||
<div class="inputs">
|
|
||||||
<section class="field">
|
|
||||||
<input
|
|
||||||
onchange={{action "updateName"}}
|
|
||||||
type="file"
|
|
||||||
id="file-input"
|
|
||||||
accept="*"
|
|
||||||
/>
|
|
||||||
<label for="file-input">{{i18n
|
|
||||||
"admin.customize.theme.upload_file_tip"
|
|
||||||
}}</label>
|
|
||||||
</section>
|
|
||||||
<section class="field">
|
|
||||||
<label for="theme-variable-name">{{i18n
|
|
||||||
"admin.customize.theme.variable_name"
|
|
||||||
}}</label>
|
|
||||||
<Input id="theme-variable-name" @value={{this.name}} />
|
|
||||||
</section>
|
|
||||||
{{#if this.fileSelected}}
|
|
||||||
{{#if this.errorMessage}}
|
|
||||||
<span class="alert alert-error">{{this.errorMessage}}</span>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</DModalBody>
|
|
||||||
|
|
||||||
<div class="modal-footer">
|
|
||||||
<DButton
|
|
||||||
@action={{action "upload"}}
|
|
||||||
@disabled={{this.disabled}}
|
|
||||||
@class="btn btn-primary"
|
|
||||||
@icon="upload"
|
|
||||||
@label="admin.customize.theme.upload"
|
|
||||||
/>
|
|
||||||
<DModalCancel @close={{route-action "closeModal"}} />
|
|
||||||
</div>
|
|
@ -54,7 +54,6 @@ const KNOWN_LEGACY_MODALS = [
|
|||||||
"tag-upload",
|
"tag-upload",
|
||||||
"topic-summary",
|
"topic-summary",
|
||||||
"user-status",
|
"user-status",
|
||||||
"admin-add-upload",
|
|
||||||
"admin-merge-users-prompt",
|
"admin-merge-users-prompt",
|
||||||
"admin-start-backup",
|
"admin-start-backup",
|
||||||
"admin-watched-word-test",
|
"admin-watched-word-test",
|
||||||
|
Loading…
Reference in New Issue
Block a user