diff --git a/app/assets/styles.css b/app/assets/styles.css index 568ad17c..53758712 100644 --- a/app/assets/styles.css +++ b/app/assets/styles.css @@ -27,6 +27,14 @@ html { vertical-align: middle; } +.deprecated-warning { + padding: var(--spacing-2); + border-radius: var(--radius-lg); + border: 1px solid var(--color-gray-800); + margin-bottom: var(--spacing-2); + line-break: anywhere; +} + main a.edit-icon { height: 1rem; width: 16px; diff --git a/app/components/class-field-description.gjs b/app/components/class-field-description.gjs index 436d298f..bc31b607 100644 --- a/app/components/class-field-description.gjs +++ b/app/components/class-field-description.gjs @@ -142,6 +142,19 @@ export default class ClassFieldDescription extends Component { {{/if}} + + {{#if @field.deprecated}} +
+

This {{@type}} is deprecated!

+ {{#if @field.deprecationMessage}} + + {{/if}} +
+ {{/if}} + diff --git a/app/models/class.js b/app/models/class.js index 39208d0a..ddffdccd 100644 --- a/app/models/class.js +++ b/app/models/class.js @@ -13,6 +13,9 @@ export default class Class extends Model { @attr() deprecated; + @attr() + deprecationMessage; + @attr() access; diff --git a/app/models/module.js b/app/models/module.js index 9fdbf22c..d8a14fdd 100644 --- a/app/models/module.js +++ b/app/models/module.js @@ -23,6 +23,9 @@ export default class Module extends ClassModel { @attr() allstaticfunctions; + @attr() + deprecated; + @belongsTo('project-version', { async: false, inverse: null }) projectVersion; } diff --git a/app/serializers/application.js b/app/serializers/application.js index 1d128732..ad36ae15 100644 --- a/app/serializers/application.js +++ b/app/serializers/application.js @@ -30,4 +30,11 @@ export default class Application extends JSONAPISerializer { return normalizedDocument; } + + keyForAttribute(key) { + if (key === 'deprecationMessage') { + return key; + } + return super.keyForAttribute(key); + } } diff --git a/app/templates/project-version/classes/class.gjs b/app/templates/project-version/classes/class.gjs index 41d65f0b..172e525c 100644 --- a/app/templates/project-version/classes/class.gjs +++ b/app/templates/project-version/classes/class.gjs @@ -136,6 +136,16 @@ import ApiIndex from 'ember-api-docs/components/api-index'; {{/if}} + {{#if @model.deprecated}} +
+
+

This class is deprecated!

+

+
+ {{/if}} {{#if (and (not (eq @controller.static 1)) @controller.hasImportExample)}} {{/if}} diff --git a/app/templates/project-version/modules/module.gjs b/app/templates/project-version/modules/module.gjs index 4a1870db..ce63a020 100644 --- a/app/templates/project-version/modules/module.gjs +++ b/app/templates/project-version/modules/module.gjs @@ -3,7 +3,9 @@ import { LinkTo } from '@ember/routing'; import { array } from '@ember/helper'; import MarkdownToHtml from 'ember-cli-showdown/components/markdown-to-html'; import not from 'ember-truth-helpers/helpers/not'; +import notEq from 'ember-truth-helpers/helpers/not-eq'; import and from 'ember-truth-helpers/helpers/and'; +import or from 'ember-truth-helpers/helpers/or'; import gt from 'ember-truth-helpers/helpers/gt'; import functionHeadingId from 'ember-api-docs/helpers/function-heading-id'; import betterGet from 'ember-api-docs/helpers/better-get'; @@ -19,6 +21,9 @@ import betterGet from 'ember-api-docs/helpers/better-get'; {{#if @controller.model.access}}{{@controller.model.access}}{{/if}} + {{#if @controller.model.deprecated}}deprecated{{/if}} {{/if}} @@ -122,6 +127,27 @@ import betterGet from 'ember-api-docs/helpers/better-get'; {{/each}} {{/if}} + {{#if (notEq @controller.model.name "ember-data-overview")}} + {{#if + (not + (or + @controller.submodules + @controller.classesAndNamespaces + (and + @controller.functionHeadings + (gt @controller.functionHeadings.length 0) + ) + ) + ) + }} +

+ No submodules, classes, namespaces, or functions are visible. Some may + be hidden because private and deprecated packages are not shown. + Toggle "Show Private / Deprecated packages" in the sidebar to reveal + them. +

+ {{/if}} + {{/if}} {{outlet}} diff --git a/tests/acceptance/module-test.js b/tests/acceptance/module-test.js index b2471afc..c605eacf 100644 --- a/tests/acceptance/module-test.js +++ b/tests/acceptance/module-test.js @@ -46,6 +46,58 @@ module('Acceptance | Module', function (hooks) { assert.equal(findAll('.spec-method-list li').length, numberSubModules); }); + test('does not show the empty-module warning when the module has submodules', async function (assert) { + await visit('ember/1.0/modules/ember'); + + assert + .dom('[data-test-empty-module-warning]') + .doesNotExist('no warning when module has submodules'); + }); + + test('does not show the empty-module warning when the module has public classes or namespaces', async function (assert) { + await visit('ember/1.0/modules/ember-handlebars'); + + assert + .dom('[data-test-empty-module-warning]') + .doesNotExist('no warning when module has public classes'); + }); + + test('does not show the empty-module warning when the module has public functions', async function (assert) { + // ember/2.16/modules/jquery has only public static functions ($) and no classes, namespaces, or submodules + await visit('ember/2.16/modules/jquery'); + + assert + .dom('[data-test-empty-module-warning]') + .doesNotExist('no warning when module has public functions'); + }); + + test('does not show the empty-module warning on the ember-data-overview page', async function (assert) { + // ember-data-overview has no content at all, but is excluded from the warning by name + await visit('ember-data/4.7/modules/ember-data-overview'); + + assert + .dom('[data-test-empty-module-warning]') + .doesNotExist( + 'no warning on ember-data-overview regardless of empty content', + ); + }); + + test('shows a note when all content is hidden by the private/deprecated filter', async function (assert) { + // ember-htmlbars in 1.13 has only a private class (HandlebarsCompatibleHelper) + // and no public classes, namespaces, submodules, or functions + await visit('ember/1.13/modules/ember-htmlbars'); + + assert + .dom('[data-test-empty-module-warning]') + .exists('warning shown when no public content is visible'); + + await click('[data-test-private-deprecated-toggle]'); + + assert + .dom('[data-test-empty-module-warning]') + .doesNotExist('warning hidden after showing private/deprecated content'); + }); + test('display submodule parent', async function (assert) { await visit('ember/1.0/modules/ember-application');