diff --git a/admin/assets/javascripts/discourse/components/docker-manager/repo-status.hbs b/admin/assets/javascripts/discourse/components/docker-manager/repo-status.hbs deleted file mode 100644 index 3d9288d4..00000000 --- a/admin/assets/javascripts/discourse/components/docker-manager/repo-status.hbs +++ /dev/null @@ -1,62 +0,0 @@ - - - {{#if this.officialRepoBadge}} - {{d-icon - this.officialRepoBadge - translatedTitle=this.officialRepoBadgeTitle - class="check-circle" - }} - {{/if}} - - - - {{@repo.name}} - - {{@repo.prettyVersion}} - - - - - {{#if @repo.checkingStatus}} - {{i18n "admin.docker.checking"}} - {{else if @repo.upToDate}} - {{i18n "admin.docker.up_to_date"}} - {{else}} -
-

{{i18n "admin.docker.new_version_available"}}

- - - - -
- {{/if}} - - \ No newline at end of file diff --git a/admin/assets/javascripts/discourse/components/docker-manager/repo-status.js b/admin/assets/javascripts/discourse/components/docker-manager/repo-status.js deleted file mode 100644 index a870cd95..00000000 --- a/admin/assets/javascripts/discourse/components/docker-manager/repo-status.js +++ /dev/null @@ -1,56 +0,0 @@ -import Component from "@glimmer/component"; -import { action } from "@ember/object"; -import { inject as service } from "@ember/service"; -import I18n from "I18n"; - -export default class RepoStatus extends Component { - @service router; - @service upgradeStore; - - get upgradeDisabled() { - // Allow to see the currently running update - if (this.args.upgradingRepo) { - return false; - } - - // Disable other buttons when an update is running - if (this.upgradeStore.running) { - return true; - } - - // docker_manager has to be updated before other plugins - return ( - !this.args.managerRepo.upToDate && - this.args.managerRepo !== this.args.repo - ); - } - - get officialRepoBadge() { - if (this.args.repo.fork) { - return "exclamation-circle"; - } else if (this.args.repo.official) { - return "check-circle"; - } - } - - get officialRepoBadgeTitle() { - if (this.args.repo.fork) { - return I18n.t("admin.docker.forked_plugin"); - } else if (this.args.repo.official) { - return I18n.t("admin.docker.official_plugin"); - } - } - - get upgradeButtonLabel() { - if (this.args.repo.upgrading) { - return I18n.t("admin.docker.updating"); - } else { - return I18n.t("admin.docker.update_action"); - } - } - - @action - upgrade() { - this.router.transitionTo("update.show", this.args.repo); - } -} diff --git a/admin/assets/javascripts/discourse/components/repo-status.gjs b/admin/assets/javascripts/discourse/components/repo-status.gjs new file mode 100644 index 00000000..b364d011 --- /dev/null +++ b/admin/assets/javascripts/discourse/components/repo-status.gjs @@ -0,0 +1,121 @@ +import Component from "@glimmer/component"; +import { action } from "@ember/object"; +import { inject as service } from "@ember/service"; +import DButton from "discourse/components/d-button"; +import FormatDate from "discourse/helpers/format-date"; +import icon from "discourse-common/helpers/d-icon"; +import i18n from "discourse-common/helpers/i18n"; +import I18n from "I18n"; +import CommitUrl from "../helpers/commit-url"; +import NewCommits from "../helpers/new-commits"; + +export default class RepoStatus extends Component { + @service router; + @service upgradeStore; + + get upgradeDisabled() { + // Allow to see the currently running update + if (this.args.upgradingRepo) { + return false; + } + + // Disable other buttons when an update is running + if (this.upgradeStore.running) { + return true; + } + + // docker_manager has to be updated before other plugins + return ( + !this.args.managerRepo.upToDate && + this.args.managerRepo !== this.args.repo + ); + } + + get upgradeButtonLabel() { + if (this.args.repo.upgrading) { + return I18n.t("admin.docker.updating"); + } else { + return I18n.t("admin.docker.update_action"); + } + } + + @action + upgrade() { + this.router.transitionTo("update.show", this.args.repo); + } + + +} diff --git a/admin/assets/javascripts/discourse/helpers/commit-url.js b/admin/assets/javascripts/discourse/helpers/commit-url.js new file mode 100644 index 00000000..802e213c --- /dev/null +++ b/admin/assets/javascripts/discourse/helpers/commit-url.js @@ -0,0 +1,16 @@ +import { htmlSafe } from "@ember/template"; + +export default function commitUrl(cssClass, version, prettyVersion, url) { + if (!prettyVersion) { + return ""; + } + + if (!url) { + return prettyVersion; + } + + const repoUrl = url.substr(0, url.search(/(\.git)?$/)); + const description = `${prettyVersion}`; + + return new htmlSafe(description); +} diff --git a/admin/assets/javascripts/discourse/models/repo.js b/admin/assets/javascripts/discourse/models/repo.js index c23d9bf3..729d04e6 100644 --- a/admin/assets/javascripts/discourse/models/repo.js +++ b/admin/assets/javascripts/discourse/models/repo.js @@ -1,6 +1,8 @@ -import { tracked } from "@glimmer/tracking"; +import { cached, tracked } from "@glimmer/tracking"; +import { capitalize } from "@ember/string"; import { TrackedObject } from "@ember-compat/tracked-built-ins"; import { ajax } from "discourse/lib/ajax"; +import AdminPlugin from "admin/models/admin-plugin"; let loaded = []; export let needsImageUpgrade = false; @@ -74,6 +76,7 @@ export default class Repo { @tracked checking = false; @tracked lastCheckedAt = null; @tracked latest = new TrackedObject({}); + @tracked plugin = null; // model attributes @tracked name = null; @@ -94,8 +97,12 @@ export default class Repo { } } + if (attributes.plugin) { + this.plugin = AdminPlugin.create(attributes.plugin); + } + for (const [key, value] of Object.entries(attributes)) { - if (key === "latest") { + if (["latest", "plugin"].includes(key)) { continue; } @@ -103,6 +110,31 @@ export default class Repo { } } + @cached + get nameTitleized() { + if (this.plugin) { + return this.plugin.nameTitleized; + } + + return capitalize(this.name); + } + + get linkUrl() { + if (this.plugin) { + return this.plugin.linkUrl; + } + + return this.url; + } + + get author() { + if (this.plugin) { + return this.plugin.author; + } + + return null; + } + get checkingStatus() { return this.unloaded || this.checking; } @@ -111,6 +143,10 @@ export default class Repo { return !this.upgrading && this.version === this.latest?.version; } + get hasNewVersion() { + return !this.checkingStatus && !this.upToDate; + } + get prettyVersion() { return this.pretty_version || this.version?.substring(0, 8); } diff --git a/admin/assets/javascripts/discourse/routes/update-show.js b/admin/assets/javascripts/discourse/routes/update-show.js index 7813ae77..a808069a 100644 --- a/admin/assets/javascripts/discourse/routes/update-show.js +++ b/admin/assets/javascripts/discourse/routes/update-show.js @@ -4,6 +4,7 @@ import Repo from "../models/repo"; export default class UpgradeShow extends Route { @service upgradeStore; + @service router; model(params) { if (params.id === "all") { @@ -14,6 +15,11 @@ export default class UpgradeShow extends Route { } async afterModel(model) { + if (!model) { + this.router.replaceWith("/404"); + return; + } + if (Array.isArray(model)) { const repos = await Repo.findLatestAll(); diff --git a/admin/assets/javascripts/discourse/templates/update-index.hbs b/admin/assets/javascripts/discourse/templates/update-index.hbs index 3b0595ab..30d14ea5 100644 --- a/admin/assets/javascripts/discourse/templates/update-index.hbs +++ b/admin/assets/javascripts/discourse/templates/update-index.hbs @@ -1,4 +1,21 @@ -

{{i18n "admin.docker.update_title"}}

+
+

{{i18n "admin.docker.update_title"}}

+ {{#unless this.outdated}} + + {{#if this.allUpToDate}} + {{i18n "admin.docker.all_up_to_date"}} + {{else}} + {{i18n "admin.docker.update_all"}} + {{/if}} + + {{/unless}} +
{{#if this.outdated}}

{{i18n "admin.docker.outdated_image_header"}}

@@ -18,29 +35,18 @@

{{else}} - - +
- - - + + + + + {{#each this.model as |repo|}} - ` + hbs`` ); assert - .dom("span.current.commit-hash") + .dom("a.current.commit-hash") .hasText("v2.2.0.beta6 +98", "tag version is used when present"); assert - .dom("span.new.commit-hash") + .dom("a.new.commit-hash") .hasText("v2.2.0.beta6 +101", "tag version is used when present"); assert @@ -76,36 +76,32 @@ module("Integration | Component | RepoStatus", function (hooks) { await settled(); assert.strictEqual( - query("span.current.commit-hash").textContent.trim(), + query("a.current.commit-hash").textContent.trim(), "8f65e4f", "commit hash is used when tag version is absent" ); assert.strictEqual( - query("span.new.commit-hash").textContent.trim(), + query("a.new.commit-hash").textContent.trim(), "2b006c0", "commit hash is used when tag version is absent" ); }); - test("official check mark", async function (assert) { + test("official plugin", async function (assert) { const store = getOwner(this).lookup("service:store"); + repoProps.plugin = { name: "discourse", isOfficial: true }; this.set("repo", store.createRecord("repo", repoProps)); this.set("managerRepo", store.createRecord("repo", managerProps)); await render( - hbs`` + hbs`` ); - assert - .dom("svg.d-icon-check-circle") - .doesNotExist("green check is absent when not official"); - - this.repo.official = true; - await settled(); - - assert - .dom("svg.d-icon-check-circle") - .exists("green check is present when official"); + assert.strictEqual( + query("div.repo__author").textContent.trim(), + "By Discourse", + "shows plugin author" + ); }); test("update button", async function (assert) { @@ -114,7 +110,7 @@ module("Integration | Component | RepoStatus", function (hooks) { this.set("managerRepo", store.createRecord("repo", managerProps)); await render( - hbs`` + hbs`` ); assert
{{i18n "admin.docker.repository"}}{{i18n "admin.docker.status"}}{{i18n "admin.docker.repo.name"}}{{i18n "admin.docker.repo.commit_hash"}}{{i18n "admin.docker.repo.last_updated"}}{{i18n "admin.docker.repo.latest_version"}}{{i18n "admin.docker.repo.status"}}