Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-26 02:50:28 +01:00
Update workflow to add frontend tests && handle deprecations
Dieser Commit ist enthalten in:
Ursprung
a19a1fa3b1
Commit
a2106bf592
16 geänderte Dateien mit 82 neuen und 58 gelöschten Zeilen
16
.github/workflows/plugin-tests.yml
gevendort
16
.github/workflows/plugin-tests.yml
gevendort
|
@ -73,18 +73,6 @@ jobs:
|
||||||
ref: "${{ github.base_ref }}"
|
ref: "${{ github.base_ref }}"
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Check spec existence
|
|
||||||
id: check_spec
|
|
||||||
uses: andstor/file-existence-action@v1
|
|
||||||
with:
|
|
||||||
files: "plugins/${{ steps.repo-name.outputs.value }}/spec"
|
|
||||||
|
|
||||||
- name: Check qunit existence
|
|
||||||
id: check_qunit
|
|
||||||
uses: andstor/file-existence-action@v1
|
|
||||||
with:
|
|
||||||
files: "plugins/${{ steps.repo-name.outputs.value }}/test/javascripts"
|
|
||||||
|
|
||||||
- name: Setup Git
|
- name: Setup Git
|
||||||
run: |
|
run: |
|
||||||
git config --global user.email "ci@ci.invalid"
|
git config --global user.email "ci@ci.invalid"
|
||||||
|
@ -140,7 +128,7 @@ jobs:
|
||||||
bin/rake db:migrate
|
bin/rake db:migrate
|
||||||
|
|
||||||
- name: Plugin RSpec with Coverage
|
- name: Plugin RSpec with Coverage
|
||||||
if: matrix.build_type == 'backend' && steps.check_spec.outputs.files_exists == 'true'
|
if: matrix.build_type == 'backend'
|
||||||
run: |
|
run: |
|
||||||
if [ -e plugins/${{ steps.repo-name.outputs.value }}/.simplecov ]
|
if [ -e plugins/${{ steps.repo-name.outputs.value }}/.simplecov ]
|
||||||
then
|
then
|
||||||
|
@ -150,6 +138,6 @@ jobs:
|
||||||
bin/rake plugin:spec[${{ steps.repo-name.outputs.value }}]
|
bin/rake plugin:spec[${{ steps.repo-name.outputs.value }}]
|
||||||
|
|
||||||
- name: Plugin QUnit
|
- name: Plugin QUnit
|
||||||
if: matrix.build_type == 'frontend' && steps.check_qunit.outputs.files_exists == 'true'
|
if: matrix.build_type == 'frontend'
|
||||||
run: bundle exec rake plugin:qunit['${{ steps.repo-name.outputs.value }}','1200000']
|
run: bundle exec rake plugin:qunit['${{ steps.repo-name.outputs.value }}','1200000']
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
|
|
|
@ -7,6 +7,7 @@ import userSearch from "../lib/user-search";
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import TextField from "@ember/component/text-field";
|
||||||
|
|
||||||
const template = function (params) {
|
const template = function (params) {
|
||||||
const options = params.options;
|
const options = params.options;
|
||||||
|
@ -31,7 +32,7 @@ const template = function (params) {
|
||||||
return new Handlebars.SafeString(html).string;
|
return new Handlebars.SafeString(html).string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Ember.TextField.extend({
|
export default TextField.extend({
|
||||||
attributeBindings: ["autofocus", "maxLength"],
|
attributeBindings: ["autofocus", "maxLength"],
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
autocapitalize: false,
|
autocapitalize: false,
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
import Category from "discourse/models/category";
|
import Category from "discourse/models/category";
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
layoutName: 'wizard/templates/components/wizard-field-category',
|
layoutName: "wizard/templates/components/wizard-field-category",
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
const property = this.field.property || "id";
|
const property = this.field.property || "id";
|
||||||
|
|
|
@ -3,9 +3,10 @@ import {
|
||||||
observes,
|
observes,
|
||||||
} from "discourse-common/utils/decorators";
|
} from "discourse-common/utils/decorators";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
layoutName: 'wizard/templates/components/wizard-field-composer',
|
layoutName: "wizard/templates/components/wizard-field-composer",
|
||||||
|
|
||||||
showPreview: false,
|
showPreview: false,
|
||||||
classNameBindings: [
|
classNameBindings: [
|
||||||
|
|
|
@ -87,7 +87,7 @@ export default Component.extend({
|
||||||
@observes("step.message")
|
@observes("step.message")
|
||||||
_handleMessage: function () {
|
_handleMessage: function () {
|
||||||
const message = this.get("step.message");
|
const message = this.get("step.message");
|
||||||
this.sendAction("showMessage", message);
|
this.showMessage(message);
|
||||||
},
|
},
|
||||||
|
|
||||||
keyPress(event) {
|
keyPress(event) {
|
||||||
|
@ -162,7 +162,7 @@ export default Component.extend({
|
||||||
if (response["final"]) {
|
if (response["final"]) {
|
||||||
CustomWizard.finished(response);
|
CustomWizard.finished(response);
|
||||||
} else {
|
} else {
|
||||||
this.sendAction("goNext", response);
|
this.goNext(response);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => this.animateInvalidFields())
|
.catch(() => this.animateInvalidFields())
|
||||||
|
@ -181,7 +181,7 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
showMessage(message) {
|
showMessage(message) {
|
||||||
this.sendAction("showMessage", message);
|
this.sendAction(message);
|
||||||
},
|
},
|
||||||
|
|
||||||
stylingDropdownChanged(id, value) {
|
stylingDropdownChanged(id, value) {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import computed from "discourse-common/utils/decorators";
|
import computed from "discourse-common/utils/decorators";
|
||||||
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
|
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
import TextField from "@ember/component/text-field";
|
||||||
|
|
||||||
export default Ember.TextField.extend({
|
export default TextField.extend({
|
||||||
attributeBindings: [
|
attributeBindings: [
|
||||||
"autocorrect",
|
"autocorrect",
|
||||||
"autocapitalize",
|
"autocapitalize",
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
export default {
|
export default {
|
||||||
run(app, container) {
|
run(app) {
|
||||||
|
// siteSettings must always be registered first
|
||||||
|
if (!app.hasRegistration("site-settings:main")) {
|
||||||
|
const siteSettings = app.SiteSettings;
|
||||||
|
app.register("site-settings:main", siteSettings, { instantiate: false });
|
||||||
|
}
|
||||||
|
|
||||||
const Store = requirejs("discourse/services/store").default;
|
const Store = requirejs("discourse/services/store").default;
|
||||||
const Site = requirejs(
|
const Site = requirejs(
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/models/site"
|
"discourse/plugins/discourse-custom-wizard/wizard/models/site"
|
||||||
|
@ -7,12 +13,13 @@ export default {
|
||||||
const Session = requirejs("discourse/models/session").default;
|
const Session = requirejs("discourse/models/session").default;
|
||||||
const RestAdapter = requirejs("discourse/adapters/rest").default;
|
const RestAdapter = requirejs("discourse/adapters/rest").default;
|
||||||
const messageBus = requirejs("message-bus-client").default;
|
const messageBus = requirejs("message-bus-client").default;
|
||||||
const sniffCapabilites = requirejs("discourse/pre-initializers/sniff-capabilities").default;
|
const sniffCapabilites = requirejs(
|
||||||
|
"discourse/pre-initializers/sniff-capabilities"
|
||||||
|
).default;
|
||||||
|
|
||||||
const site = Site.current();
|
const site = Site.current();
|
||||||
const session = Session.current();
|
const session = Session.current();
|
||||||
|
|
||||||
const registrations = [
|
const registrations = [
|
||||||
["site-settings:main", app.SiteSettings, false],
|
|
||||||
["message-bus:main", messageBus, false],
|
["message-bus:main", messageBus, false],
|
||||||
["site:main", site, false],
|
["site:main", site, false],
|
||||||
["session:main", session, false],
|
["session:main", session, false],
|
||||||
|
@ -26,18 +33,18 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const targets = ["controller", "component", "route", "model", "adapter", "mixin"];
|
const targets = ["controller", "component", "route", "model", "adapter"];
|
||||||
const injections = [
|
|
||||||
["siteSettings", "site-settings:main"],
|
|
||||||
["messageBus", "message-bus:main"],
|
|
||||||
["site", "site:main"],
|
|
||||||
["session", "session:main"],
|
|
||||||
["store", "service:store"],
|
|
||||||
["appEvents", "service:app-events"]
|
|
||||||
];
|
|
||||||
|
|
||||||
injections.forEach(injection => {
|
targets.forEach((t) => {
|
||||||
targets.forEach((t) => app.inject(t, injection[0], injection[1]));
|
app.inject(t, "appEvents", "service:app-events");
|
||||||
|
app.inject(t, "store", "service:store");
|
||||||
|
app.inject(t, "site", "site:main");
|
||||||
|
});
|
||||||
|
|
||||||
|
targets.concat("service").forEach((t) => {
|
||||||
|
app.inject(t, "session", "session:main");
|
||||||
|
app.inject(t, "messageBus", "message-bus:main");
|
||||||
|
app.inject(t, "siteSettings", "site-settings:main");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!app.hasRegistration("capabilities:main")) {
|
if (!app.hasRegistration("capabilities:main")) {
|
||||||
|
|
|
@ -20,6 +20,11 @@ export default {
|
||||||
const DEditor = requirejs("discourse/components/d-editor").default;
|
const DEditor = requirejs("discourse/components/d-editor").default;
|
||||||
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
||||||
const toMarkdown = requirejs("discourse/lib/to-markdown").default;
|
const toMarkdown = requirejs("discourse/lib/to-markdown").default;
|
||||||
|
const discourseComputed = requirejs("discourse-common/utils/decorators")
|
||||||
|
.default;
|
||||||
|
const WizardI18n = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n"
|
||||||
|
).default;
|
||||||
const isInside = (text, regex) => {
|
const isInside = (text, regex) => {
|
||||||
const matches = text.match(regex);
|
const matches = text.match(regex);
|
||||||
return matches && matches.length % 2;
|
return matches && matches.length % 2;
|
||||||
|
@ -44,6 +49,17 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@discourseComputed("placeholder", "placeholderOverride")
|
||||||
|
placeholderTranslated(placeholder, placeholderOverride) {
|
||||||
|
if (placeholderOverride) {
|
||||||
|
return placeholderOverride;
|
||||||
|
}
|
||||||
|
if (placeholder) {
|
||||||
|
return WizardI18n(placeholder);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
_wizardInsertText(args = {}) {
|
_wizardInsertText(args = {}) {
|
||||||
if (args.fieldId === this.fieldId) {
|
if (args.fieldId === this.fieldId) {
|
||||||
this.insertText(args.text, args.options);
|
this.insertText(args.text, args.options);
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default {
|
||||||
const Session = requirejs("discourse/models/session").default;
|
const Session = requirejs("discourse/models/session").default;
|
||||||
const session = Session.current();
|
const session = Session.current();
|
||||||
session.set("highlightJsPath", setupData.highlightJsPath);
|
session.set("highlightJsPath", setupData.highlightJsPath);
|
||||||
|
session.set("markdownItUrl", setupData.markdownItUrl);
|
||||||
|
|
||||||
[
|
[
|
||||||
'register-files',
|
'register-files',
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { ajax } from "wizard/lib/ajax";
|
import { ajax } from "wizard/lib/ajax";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL, { getURLWithCDN } from "discourse-common/lib/get-url";
|
||||||
|
import { run } from "@ember/runloop";
|
||||||
|
import { Promise } from "rsvp";
|
||||||
|
|
||||||
const _loaded = {};
|
const _loaded = {};
|
||||||
const _loading = {};
|
const _loading = {};
|
||||||
|
@ -25,7 +27,7 @@ function loadWithTag(path, cb) {
|
||||||
) {
|
) {
|
||||||
s = s.onload = s.onreadystatechange = null;
|
s = s.onload = s.onreadystatechange = null;
|
||||||
if (!abort) {
|
if (!abort) {
|
||||||
Ember.run(null, cb);
|
run(null, cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -38,7 +40,7 @@ export function loadCSS(url) {
|
||||||
export default function loadScript(url, opts) {
|
export default function loadScript(url, opts) {
|
||||||
// TODO: Remove this once plugins have been updated not to use it:
|
// TODO: Remove this once plugins have been updated not to use it:
|
||||||
if (url === "defer/html-sanitizer-bundle") {
|
if (url === "defer/html-sanitizer-bundle") {
|
||||||
return Ember.RSVP.Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
@ -51,7 +53,7 @@ export default function loadScript(url, opts) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Ember.RSVP.Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
url = getURL(url);
|
url = getURL(url);
|
||||||
|
|
||||||
// If we already loaded this url
|
// If we already loaded this url
|
||||||
|
@ -63,7 +65,7 @@ export default function loadScript(url, opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let done;
|
let done;
|
||||||
_loading[url] = new Ember.RSVP.Promise(function (_done) {
|
_loading[url] = new Promise(function (_done) {
|
||||||
done = _done;
|
done = _done;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -84,8 +86,8 @@ export default function loadScript(url, opts) {
|
||||||
|
|
||||||
// Scripts should always load from CDN
|
// Scripts should always load from CDN
|
||||||
// CSS is type text, to accept it from a CDN we would need to handle CORS
|
// CSS is type text, to accept it from a CDN we would need to handle CORS
|
||||||
if (!opts.css && Discourse.CDN && url[0] === "/" && url[1] !== "/") {
|
if (!opts.css) {
|
||||||
cdnUrl = Discourse.CDN.replace(/\/$/, "") + url;
|
cdnUrl = getURLWithCDN(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some javascript depends on the path of where it is loaded (ace editor)
|
// Some javascript depends on the path of where it is loaded (ace editor)
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { default as PrettyText, buildOptions } from "pretty-text/pretty-text";
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL from "discourse-common/lib/get-url";
|
||||||
import { getOwner } from "discourse-common/lib/get-owner";
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
import { Promise } from "rsvp";
|
||||||
|
import Session from "discourse/models/session";
|
||||||
|
|
||||||
export function cook(text, options) {
|
export function cook(text, options) {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
|
@ -18,11 +20,15 @@ export function cook(text, options) {
|
||||||
// everything should eventually move to async API and this should be renamed
|
// everything should eventually move to async API and this should be renamed
|
||||||
// cook
|
// cook
|
||||||
export function cookAsync(text, options) {
|
export function cookAsync(text, options) {
|
||||||
if (Discourse.MarkdownItURL) {
|
let markdownItURL = Session.currentProp("markdownItURL");
|
||||||
return loadScript(Discourse.MarkdownItURL)
|
if (markdownItURL) {
|
||||||
|
return (
|
||||||
|
loadScript(markdownItURL)
|
||||||
.then(() => cook(text, options))
|
.then(() => cook(text, options))
|
||||||
.catch((e) => Ember.Logger.error(e));
|
// eslint-disable-next-line no-console
|
||||||
|
.catch((e) => console.error(e))
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return Ember.RSVP.Promise.resolve(cook(text));
|
return Promise.resolve(cook(text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
||||||
import { debounce } from "@ember/runloop";
|
import { debounce } from "@ember/runloop";
|
||||||
import getUrl from "discourse-common/lib/get-url";
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
import { Promise } from "rsvp";
|
||||||
|
|
||||||
let cache = {},
|
let cache = {},
|
||||||
cacheTopicId,
|
cacheTopicId,
|
||||||
|
@ -120,7 +121,7 @@ export default function userSearch(options) {
|
||||||
|
|
||||||
currentTerm = term;
|
currentTerm = term;
|
||||||
|
|
||||||
return new Ember.RSVP.Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
// TODO site setting for allowed regex in username
|
// TODO site setting for allowed regex in username
|
||||||
if (term.match(/[^\w_\-\.@\+]/)) {
|
if (term.match(/[^\w_\-\.@\+]/)) {
|
||||||
resolve([]);
|
resolve([]);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import ValidState from "wizard/mixins/valid-state";
|
||||||
import { ajax } from "wizard/lib/ajax";
|
import { ajax } from "wizard/lib/ajax";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import { translatedText } from "discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n";
|
import { translatedText } from "discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n";
|
||||||
|
import { later } from "@ember/runloop";
|
||||||
|
|
||||||
export default EmberObject.extend(ValidState, {
|
export default EmberObject.extend(ValidState, {
|
||||||
id: null,
|
id: null,
|
||||||
|
@ -109,6 +110,6 @@ export default EmberObject.extend(ValidState, {
|
||||||
state: "error",
|
state: "error",
|
||||||
text: message,
|
text: message,
|
||||||
});
|
});
|
||||||
Ember.run.later(() => this.set("message", null), 6000);
|
later(() => this.set("message", null), 6000);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -112,8 +112,7 @@ CustomWizard.reopenClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Site.currentProp("categoriesList", categories);
|
Site.currentProp("categories", categories);
|
||||||
Site.currentProp("sortedCategories", categories);
|
|
||||||
Site.currentProp("listByActivity", categories);
|
Site.currentProp("listByActivity", categories);
|
||||||
Site.currentProp("categoriesById", categoriesById);
|
Site.currentProp("categoriesById", categoriesById);
|
||||||
Site.currentProp(
|
Site.currentProp(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{{d-editor
|
{{d-editor
|
||||||
tabindex=field.tabindex
|
tabindex=field.tabindex
|
||||||
value=composer.reply
|
value=composer.reply
|
||||||
placeholderTranslated=replyPlaceholder
|
placeholderOverride=replyPlaceholder
|
||||||
previewUpdated=(action "previewUpdated")
|
previewUpdated=(action "previewUpdated")
|
||||||
markdownOptions=markdownOptions
|
markdownOptions=markdownOptions
|
||||||
extraButtons=(action "extraButtons")
|
extraButtons=(action "extraButtons")
|
||||||
|
|
|
@ -13,8 +13,7 @@
|
||||||
{{#if step.permitted}}
|
{{#if step.permitted}}
|
||||||
{{wizard-step step=step
|
{{wizard-step step=step
|
||||||
wizard=wizard
|
wizard=wizard
|
||||||
goNext="goNext"
|
goNext=(action "goNext")
|
||||||
goBack=(action "goBack")
|
goBack=(action "goBack")
|
||||||
finished="finished"
|
showMessage=(action "showMessage")}}
|
||||||
showMessage="showMessage"}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
Laden …
In neuem Issue referenzieren