DEV: Update linting config and run gjs-codemod (#209)
This commit is contained in:
parent
2caa04329b
commit
082ef1246a
|
@ -1,3 +1,4 @@
|
|||
< 3.5.0.beta5-dev: 92e29f51d5f7f8058895ceae681b0f0cfee157b2
|
||||
< 3.5.0.beta1-dev: 4e42539cda9a54d7827bcdf51b6dfbcf56d24cc9
|
||||
< 3.4.0.beta2-dev: 12dfb332bf830b1c8c9a24b86f5327504e9ab672
|
||||
< 3.4.0.beta1-dev: 7721b1646dead4719c02868ef7965f1b27c74eb3
|
||||
|
|
44
Gemfile.lock
44
Gemfile.lock
|
@ -14,30 +14,31 @@ GEM
|
|||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
uri (>= 0.13.1)
|
||||
ast (2.4.2)
|
||||
base64 (0.2.0)
|
||||
benchmark (0.4.0)
|
||||
bigdecimal (3.1.9)
|
||||
ast (2.4.3)
|
||||
base64 (0.3.0)
|
||||
benchmark (0.4.1)
|
||||
bigdecimal (3.2.0)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.0)
|
||||
drb (2.2.1)
|
||||
connection_pool (2.5.3)
|
||||
drb (2.2.3)
|
||||
i18n (1.14.7)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.10.2)
|
||||
language_server-protocol (3.17.0.4)
|
||||
json (2.12.2)
|
||||
language_server-protocol (3.17.0.5)
|
||||
lint_roller (1.1.0)
|
||||
logger (1.6.6)
|
||||
logger (1.7.0)
|
||||
minitest (5.25.5)
|
||||
parallel (1.26.3)
|
||||
parser (3.3.7.1)
|
||||
parallel (1.27.0)
|
||||
parser (3.3.8.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
prettier_print (1.2.1)
|
||||
prism (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (3.1.12)
|
||||
rack (3.1.15)
|
||||
rainbow (3.1.1)
|
||||
regexp_parser (2.10.0)
|
||||
rubocop (1.74.0)
|
||||
rubocop (1.75.8)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
|
@ -45,11 +46,12 @@ GEM
|
|||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.38.1)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-ast (1.44.1)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.4)
|
||||
rubocop-capybara (2.22.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
|
@ -65,13 +67,13 @@ GEM
|
|||
rubocop-factory_bot (2.27.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rails (2.30.3)
|
||||
rubocop-rails (2.32.0)
|
||||
activesupport (>= 4.2.0)
|
||||
lint_roller (~> 1.1)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.72.1, < 2.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-rspec (3.5.0)
|
||||
rubocop (>= 1.75.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
rubocop-rspec (3.6.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec_rails (2.31.0)
|
||||
|
@ -97,4 +99,4 @@ DEPENDENCIES
|
|||
syntax_tree
|
||||
|
||||
BUNDLED WITH
|
||||
2.6.6
|
||||
2.6.9
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import Component from "@ember/component";
|
||||
import { on } from "@ember/modifier";
|
||||
import { tagName } from "@ember-decorators/component";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
|
||||
@tagName("")
|
||||
export default class DocsCategory extends Component {
|
||||
@discourseComputed("category")
|
||||
categoryName(category) {
|
||||
return this.site.categories.findBy("id", category.id).name;
|
||||
}
|
||||
|
||||
<template>
|
||||
<a
|
||||
href
|
||||
{{on "click" this.selectCategory}}
|
||||
class="docs-item docs-category {{if this.category.active 'selected'}}"
|
||||
>
|
||||
{{icon (if this.category.active "circle-xmark" "far-circle")}}
|
||||
|
||||
<span class="docs-item-id category-id">{{this.categoryName}}</span>
|
||||
<span
|
||||
class="docs-item-count category-count"
|
||||
>{{this.category.count}}</span>
|
||||
</a>
|
||||
</template>
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<a
|
||||
href
|
||||
{{action this.selectCategory}}
|
||||
class="docs-item docs-category {{if this.category.active 'selected'}}"
|
||||
>
|
||||
{{d-icon (if this.category.active "circle-xmark" "far-circle")}}
|
||||
|
||||
<span class="docs-item-id category-id">{{this.categoryName}}</span>
|
||||
<span class="docs-item-count category-count">{{this.category.count}}</span>
|
||||
</a>
|
|
@ -1,11 +0,0 @@
|
|||
import Component from "@ember/component";
|
||||
import { tagName } from "@ember-decorators/component";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
|
||||
@tagName("")
|
||||
export default class DocsCategory extends Component {
|
||||
@discourseComputed("category")
|
||||
categoryName(category) {
|
||||
return this.site.categories.findBy("id", category.id).name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
import Component, { Input } from "@ember/component";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
@classNames("docs-search")
|
||||
export default class DocsSearch extends Component {
|
||||
@action
|
||||
onKeyDown(event) {
|
||||
if (event.key === "Enter") {
|
||||
this.set("searchTerm", event.target.value);
|
||||
this.onSearch(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
clearSearch() {
|
||||
this.set("searchTerm", "");
|
||||
this.onSearch("");
|
||||
}
|
||||
|
||||
<template>
|
||||
<span class="docs-search-wrapper">
|
||||
<Input
|
||||
@type="text"
|
||||
@value={{readonly this.searchTerm}}
|
||||
class="no-blur docs-search-bar"
|
||||
autocorrect="off"
|
||||
placeholder={{i18n "docs.search.placeholder"}}
|
||||
autocapitalize="off"
|
||||
{{on "keydown" this.onKeyDown}}
|
||||
/>
|
||||
|
||||
{{#if this.searchTerm}}
|
||||
<DButton
|
||||
@action={{action "clearSearch"}}
|
||||
class="clear-search"
|
||||
@label="docs.search.clear"
|
||||
/>
|
||||
{{else}}
|
||||
{{icon "magnifying-glass"}}
|
||||
{{/if}}
|
||||
</span>
|
||||
</template>
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<span class="docs-search-wrapper">
|
||||
<Input
|
||||
@type="text"
|
||||
@value={{readonly this.searchTerm}}
|
||||
class="no-blur docs-search-bar"
|
||||
autocorrect="off"
|
||||
placeholder={{i18n "docs.search.placeholder"}}
|
||||
autocapitalize="off"
|
||||
{{on "keydown" this.onKeyDown}}
|
||||
/>
|
||||
|
||||
{{#if this.searchTerm}}
|
||||
<DButton
|
||||
@action={{action "clearSearch"}}
|
||||
class="clear-search"
|
||||
@label="docs.search.clear"
|
||||
/>
|
||||
{{else}}
|
||||
{{d-icon "magnifying-glass"}}
|
||||
{{/if}}
|
||||
</span>
|
|
@ -1,20 +0,0 @@
|
|||
import Component from "@ember/component";
|
||||
import { action } from "@ember/object";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
|
||||
@classNames("docs-search")
|
||||
export default class DocsSearch extends Component {
|
||||
@action
|
||||
onKeyDown(event) {
|
||||
if (event.key === "Enter") {
|
||||
this.set("searchTerm", event.target.value);
|
||||
this.onSearch(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
clearSearch() {
|
||||
this.set("searchTerm", "");
|
||||
this.onSearch("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import Component from "@ember/component";
|
||||
import { on } from "@ember/modifier";
|
||||
import { tagName } from "@ember-decorators/component";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
|
||||
@tagName("")
|
||||
export default class DocsTag extends Component {
|
||||
<template>
|
||||
<a
|
||||
href
|
||||
{{on "click" this.selectTag}}
|
||||
class="docs-item docs-tag
|
||||
{{if this.tag.active 'selected'}}{{if this.subtag 'subtag'}}"
|
||||
>
|
||||
{{icon (if this.tag.active "circle-xmark" "plus")}}
|
||||
|
||||
<span class="docs-item-id tag-id">{{this.tag.id}}</span>
|
||||
<span class="docs-item-count tag-count">{{this.tag.count}}</span>
|
||||
</a>
|
||||
</template>
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<a
|
||||
href
|
||||
{{action this.selectTag}}
|
||||
class="docs-item docs-tag
|
||||
{{if this.tag.active 'selected'}}{{if this.subtag 'subtag'}}"
|
||||
>
|
||||
{{#unless this.tag.active}}
|
||||
{{d-icon "plus"}}
|
||||
{{/unless}}
|
||||
|
||||
{{#if this.tag.active}}
|
||||
{{d-icon "circle-xmark"}}
|
||||
{{/if}}
|
||||
|
||||
<span class="docs-item-id tag-id">{{this.tag.id}}</span>
|
||||
<span class="docs-item-count tag-count">{{this.tag.count}}</span>
|
||||
</a>
|
|
@ -1,5 +0,0 @@
|
|||
import Component from "@ember/component";
|
||||
import { tagName } from "@ember-decorators/component";
|
||||
|
||||
@tagName("")
|
||||
export default class DocsTag extends Component {}
|
|
@ -2,9 +2,15 @@ import Component from "@ember/component";
|
|||
import { reads } from "@ember/object/computed";
|
||||
import { service } from "@ember/service";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import MountWidget from "discourse/components/mount-widget";
|
||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
import htmlSafe from "discourse/helpers/html-safe";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import computed, { bind } from "discourse/lib/decorators";
|
||||
import transformPost from "discourse/lib/transform-post";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
@classNames("docs-topic")
|
||||
export default class DocsTopic extends Component {
|
||||
|
@ -55,4 +61,28 @@ export default class DocsTopic extends Component {
|
|||
document.body.classList.remove("archetype-docs-topic");
|
||||
document.removeEventListener("scroll", this.debounceScrollEvent);
|
||||
}
|
||||
|
||||
<template>
|
||||
<DButton
|
||||
@label="docs.topic.back"
|
||||
class="docs-nav-link return"
|
||||
@action={{this.return}}
|
||||
/>
|
||||
|
||||
<div class="topic-content">
|
||||
<h1>{{htmlSafe this.topic.fancyTitle}}</h1>
|
||||
|
||||
{{! template-lint-disable no-capital-arguments }}
|
||||
<MountWidget @widget="post" @model={{this.model}} @args={{this.post}} />
|
||||
</div>
|
||||
|
||||
<a class="docs-nav-link more" href="/t/{{this.topic.id}}">
|
||||
{{icon "far-comment"}}
|
||||
{{i18n "docs.topic.navigate_to_topic"}}
|
||||
</a>
|
||||
|
||||
<span>
|
||||
<PluginOutlet @name="after-docs-topic" @connectorTagName="div" />
|
||||
</span>
|
||||
</template>
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<DButton
|
||||
@label="docs.topic.back"
|
||||
class="docs-nav-link return"
|
||||
@action={{this.return}}
|
||||
/>
|
||||
|
||||
<div class="topic-content">
|
||||
<h1>{{html-safe this.topic.fancyTitle}}</h1>
|
||||
|
||||
{{! template-lint-disable no-capital-arguments }}
|
||||
<MountWidget @widget="post" @model={{this.model}} @args={{this.post}} />
|
||||
</div>
|
||||
|
||||
<a class="docs-nav-link more" href="/t/{{this.topic.id}}">
|
||||
{{d-icon "far-comment"}}
|
||||
{{i18n "docs.topic.navigate_to_topic"}}
|
||||
</a>
|
||||
|
||||
<span>
|
||||
<PluginOutlet @name="after-docs-topic" @connectorTagName="div" />
|
||||
</span>
|
|
@ -312,12 +312,14 @@ export default class DocsIndexController extends Controller {
|
|||
}
|
||||
|
||||
@action
|
||||
onChangeFilterSolved(solvedFilter) {
|
||||
this.set("filterSolved", solvedFilter);
|
||||
onChangeFilterSolved(event) {
|
||||
this.set("filterSolved", event.target.checked);
|
||||
}
|
||||
|
||||
@action
|
||||
updateSelectedTags(tag) {
|
||||
updateSelectedTags(tag, event) {
|
||||
event?.preventDefault();
|
||||
|
||||
let filter = this.filterTags;
|
||||
if (filter && filter.includes(tag.id)) {
|
||||
filter = filter
|
||||
|
@ -337,15 +339,15 @@ export default class DocsIndexController extends Controller {
|
|||
}
|
||||
|
||||
@action
|
||||
updateSelectedCategories(category) {
|
||||
updateSelectedCategories(category, event) {
|
||||
event?.preventDefault();
|
||||
|
||||
const filterCategories =
|
||||
category.id === parseInt(this.filterCategories, 10) ? null : category.id;
|
||||
this.setProperties({
|
||||
filterCategories,
|
||||
selectedTopic: null,
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
import { Input } from "@ember/component";
|
||||
import { fn } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import { and, eq } from "truth-helpers";
|
||||
import BasicTopicList from "discourse/components/basic-topic-list";
|
||||
import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import EmptyState from "discourse/components/empty-state";
|
||||
import LoadMore from "discourse/components/load-more";
|
||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||
import lazyHash from "discourse/helpers/lazy-hash";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import DocsCategory from "../components/docs-category";
|
||||
import DocsTag from "../components/docs-tag";
|
||||
import DocsTopic from "../components/docs-topic";
|
||||
|
||||
export default RouteTemplate(
|
||||
<template>
|
||||
<ConditionalLoadingSpinner @condition={{@controller.isLoading}}>
|
||||
{{#if @controller.noContent}}
|
||||
<EmptyState
|
||||
@title={{@controller.emptyState.title}}
|
||||
@body={{@controller.emptyState.body}}
|
||||
/>
|
||||
{{else}}
|
||||
<div class="docs-browse">
|
||||
{{#if @controller.site.mobileView}}
|
||||
{{#unless @controller.selectedTopic}}
|
||||
<DButton
|
||||
class="docs-expander"
|
||||
@icon={{if @controller.expandedFilters "angle-up" "angle-down"}}
|
||||
@action={{@controller.toggleFilters}}
|
||||
@label="docs.filter_button"
|
||||
/>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
<div class="docs-filters">
|
||||
{{#if @controller.expandedFilters}}
|
||||
{{#if @controller.canFilterSolved}}
|
||||
<div class="docs-items docs-solved">
|
||||
<label class="checkbox-label docs-item">
|
||||
<Input
|
||||
@type="checkbox"
|
||||
@checked={{readonly @controller.filterSolved}}
|
||||
{{on "input" @controller.onChangeFilterSolved}}
|
||||
/>
|
||||
<PluginOutlet @name="custom-checkbox" />
|
||||
{{i18n "docs.filter_solved"}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if @controller.categories}}
|
||||
<div class="docs-items docs-categories">
|
||||
<section class="item-controls">
|
||||
<h3>
|
||||
{{i18n "docs.categories"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
(eq @controller.categorySort.type "alpha")
|
||||
"categories-alphabet active"
|
||||
"categories-alphabet"
|
||||
}}
|
||||
@icon={{@controller.categorySortAlphaIcon}}
|
||||
@action={{@controller.toggleCategorySort}}
|
||||
@actionParam="alpha"
|
||||
/>
|
||||
<DButton
|
||||
class={{if
|
||||
(eq @controller.categorySort.type "numeric")
|
||||
"categories-amount active"
|
||||
"categories-amount"
|
||||
}}
|
||||
@icon={{@controller.categorySortNumericIcon}}
|
||||
@action={{@controller.toggleCategorySort}}
|
||||
@actionParam="numeric"
|
||||
/>
|
||||
<PluginOutlet
|
||||
@name="categories-controls-buttons-bottom"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
{{#if @controller.showCategoryFilter}}
|
||||
<Input
|
||||
@value={{@controller.categoryFilter}}
|
||||
class="filter"
|
||||
placeholder={{i18n "docs.categories_filter_placeholder"}}
|
||||
/>
|
||||
{{/if}}
|
||||
<ul>
|
||||
{{#each @controller.sortedCategories as |category|}}
|
||||
<li>
|
||||
<DocsCategory
|
||||
@category={{category}}
|
||||
@selectCategory={{fn
|
||||
@controller.updateSelectedCategories
|
||||
category
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if (and @controller.tags @controller.shouldShowTags)}}
|
||||
<div class="docs-items docs-tags">
|
||||
<section class="item-controls">
|
||||
<h3>
|
||||
{{i18n "docs.tags"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
(eq @controller.tagSort.type "alpha")
|
||||
"tags-alphabet active"
|
||||
"tags-alphabet"
|
||||
}}
|
||||
@icon={{@controller.tagSortAlphaIcon}}
|
||||
@action={{@controller.toggleTagSort}}
|
||||
@actionParam="alpha"
|
||||
/>
|
||||
<DButton
|
||||
class={{if
|
||||
(eq @controller.tagSort.type "numeric")
|
||||
"tags-amount active"
|
||||
"tags-amount"
|
||||
}}
|
||||
@icon={{@controller.tagSortNumericIcon}}
|
||||
@action={{@controller.toggleTagSort}}
|
||||
@actionParam="numeric"
|
||||
/>
|
||||
<PluginOutlet @name="tags-controls-buttons-bottom" />
|
||||
</div>
|
||||
</section>
|
||||
{{#if @controller.showTagFilter}}
|
||||
<Input
|
||||
@value={{@controller.tagFilter}}
|
||||
class="filter"
|
||||
placeholder={{i18n "docs.tags_filter_placeholder"}}
|
||||
/>
|
||||
{{/if}}
|
||||
<PluginOutlet
|
||||
@name="before-docs-tag-list"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{lazyHash
|
||||
tags=@controller.tags
|
||||
updateSelectedTags=@controller.updateSelectedTags
|
||||
}}
|
||||
/>
|
||||
<ul>
|
||||
{{#each @controller.sortedTags as |tag|}}
|
||||
<li class="docs-filter-tag-{{tag.id}}">
|
||||
<DocsTag
|
||||
@tag={{tag}}
|
||||
@selectTag={{fn @controller.updateSelectedTags tag}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if
|
||||
(and @controller.tagGroups @controller.shouldShowTagsByGroup)
|
||||
}}
|
||||
<div class="docs-items docs-tags">
|
||||
<section class="item-controls">
|
||||
<h3>
|
||||
{{i18n "docs.tags"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
(eq @controller.tagSort.type "alpha")
|
||||
"tags-alphabet active"
|
||||
"tags-alphabet"
|
||||
}}
|
||||
@icon={{@controller.tagSortAlphaIcon}}
|
||||
@action={{@controller.toggleTagSort}}
|
||||
@actionParam="alpha"
|
||||
/>
|
||||
<DButton
|
||||
class={{if
|
||||
(eq @controller.tagSort.type "numeric")
|
||||
"tags-amount active"
|
||||
"tags-amount"
|
||||
}}
|
||||
@icon={{@controller.tagSortNumericIcon}}
|
||||
@action={{@controller.toggleTagSort}}
|
||||
@actionParam="numeric"
|
||||
/>
|
||||
<PluginOutlet @name="tags-controls-buttons-bottom" />
|
||||
</div>
|
||||
</section>
|
||||
{{#if @controller.showTagFilter}}
|
||||
<Input
|
||||
@value={{@controller.tagFilter}}
|
||||
class="filter"
|
||||
placeholder={{i18n "docs.tags_filter_placeholder"}}
|
||||
/>
|
||||
{{/if}}
|
||||
<PluginOutlet
|
||||
@name="before-docs-tag-list"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{lazyHash
|
||||
tags=@controller.tags
|
||||
updateSelectedTags=@controller.updateSelectedTags
|
||||
}}
|
||||
/>
|
||||
<ul>
|
||||
{{#each @controller.sortedTagGroups as |tagGroup|}}
|
||||
<li class="docs-filter-tag-group-{{tagGroup.id}}">
|
||||
{{tagGroup.name}}
|
||||
<ul>
|
||||
{{#each tagGroup.tags as |tag|}}
|
||||
<li class="docs-filter-tag-{{@controller.id}}">
|
||||
<DocsTag
|
||||
@tag={{tag}}
|
||||
@selectTag={{fn
|
||||
@controller.updateSelectedTags
|
||||
tag
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if @controller.selectedTopic}}
|
||||
<ConditionalLoadingSpinner
|
||||
@condition={{@controller.isTopicLoading}}
|
||||
>
|
||||
<DocsTopic
|
||||
@topic={{@controller.topic}}
|
||||
@return={{@controller.returnToList}}
|
||||
/>
|
||||
<PluginOutlet
|
||||
@name="below-docs-topic"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{lazyHash topic=@controller.topic}}
|
||||
/>
|
||||
</ConditionalLoadingSpinner>
|
||||
{{else}}
|
||||
<div class="docs-results">
|
||||
{{#if @controller.isSearchingOrFiltered}}
|
||||
{{#if @controller.emptyResults}}
|
||||
<div class="result-count no-result">
|
||||
{{i18n "search.no_results"}}
|
||||
</div>
|
||||
<span>
|
||||
<PluginOutlet
|
||||
@name="after-docs-empty-results"
|
||||
@connectorTagName="div"
|
||||
/>
|
||||
</span>
|
||||
{{else}}
|
||||
<div class="result-count">
|
||||
{{i18n "docs.search.results" count=@controller.topicCount}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#unless @controller.emptyResults}}
|
||||
<LoadMore
|
||||
@selector=".topic-list tr"
|
||||
@action={{@controller.loadMore}}
|
||||
>
|
||||
<BasicTopicList
|
||||
@topics={{@controller.topics}}
|
||||
@ascending={{@controller.ascending}}
|
||||
@order={{@controller.orderColumn}}
|
||||
@changeSort={{@controller.sortBy}}
|
||||
/>
|
||||
</LoadMore>
|
||||
<ConditionalLoadingSpinner
|
||||
@condition={{@controller.isLoadingMore}}
|
||||
/>
|
||||
{{/unless}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
||||
</template>
|
||||
);
|
|
@ -1,260 +0,0 @@
|
|||
<ConditionalLoadingSpinner @condition={{this.isLoading}}>
|
||||
{{#if this.noContent}}
|
||||
<EmptyState
|
||||
@title={{this.emptyState.title}}
|
||||
@body={{this.emptyState.body}}
|
||||
/>
|
||||
{{else}}
|
||||
<div class="docs-browse">
|
||||
{{#if this.site.mobileView}}
|
||||
{{#unless this.selectedTopic}}
|
||||
<DButton
|
||||
class="docs-expander"
|
||||
@icon={{if this.expandedFilters "angle-up" "angle-down"}}
|
||||
@action={{action "toggleFilters"}}
|
||||
@label="docs.filter_button"
|
||||
/>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
<div class="docs-filters">
|
||||
{{#if this.expandedFilters}}
|
||||
{{#if this.canFilterSolved}}
|
||||
<div class="docs-items docs-solved">
|
||||
<label class="checkbox-label docs-item">
|
||||
<Input
|
||||
@type="checkbox"
|
||||
@checked={{readonly this.filterSolved}}
|
||||
{{on
|
||||
"input"
|
||||
(action "onChangeFilterSolved" value="target.checked")
|
||||
}}
|
||||
/>
|
||||
<PluginOutlet @name="custom-checkbox" />
|
||||
{{i18n "docs.filter_solved"}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.categories}}
|
||||
<div class="docs-items docs-categories">
|
||||
<section class="item-controls">
|
||||
<h3>
|
||||
{{i18n "docs.categories"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
(eq this.categorySort.type "alpha")
|
||||
"categories-alphabet active"
|
||||
"categories-alphabet"
|
||||
}}
|
||||
@icon={{this.categorySortAlphaIcon}}
|
||||
@action={{this.toggleCategorySort}}
|
||||
@actionParam="alpha"
|
||||
/>
|
||||
<DButton
|
||||
class={{if
|
||||
(eq this.categorySort.type "numeric")
|
||||
"categories-amount active"
|
||||
"categories-amount"
|
||||
}}
|
||||
@icon={{this.categorySortNumericIcon}}
|
||||
@action={{this.toggleCategorySort}}
|
||||
@actionParam="numeric"
|
||||
/>
|
||||
<PluginOutlet @name="categories-controls-buttons-bottom" />
|
||||
</div>
|
||||
</section>
|
||||
{{#if this.showCategoryFilter}}
|
||||
<Input
|
||||
@value={{this.categoryFilter}}
|
||||
class="filter"
|
||||
placeholder={{i18n "docs.categories_filter_placeholder"}}
|
||||
/>
|
||||
{{/if}}
|
||||
<ul>
|
||||
{{#each this.sortedCategories as |category|}}
|
||||
<li>
|
||||
<DocsCategory
|
||||
@category={{category}}
|
||||
@selectCategory={{action
|
||||
"updateSelectedCategories"
|
||||
category
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if (and this.tags this.shouldShowTags)}}
|
||||
<div class="docs-items docs-tags">
|
||||
<section class="item-controls">
|
||||
<h3>
|
||||
{{i18n "docs.tags"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
(eq this.tagSort.type "alpha")
|
||||
"tags-alphabet active"
|
||||
"tags-alphabet"
|
||||
}}
|
||||
@icon={{this.tagSortAlphaIcon}}
|
||||
@action={{this.toggleTagSort}}
|
||||
@actionParam="alpha"
|
||||
/>
|
||||
<DButton
|
||||
class={{if
|
||||
(eq this.tagSort.type "numeric")
|
||||
"tags-amount active"
|
||||
"tags-amount"
|
||||
}}
|
||||
@icon={{this.tagSortNumericIcon}}
|
||||
@action={{this.toggleTagSort}}
|
||||
@actionParam="numeric"
|
||||
/>
|
||||
<PluginOutlet @name="tags-controls-buttons-bottom" />
|
||||
</div>
|
||||
</section>
|
||||
{{#if this.showTagFilter}}
|
||||
<Input
|
||||
@value={{this.tagFilter}}
|
||||
class="filter"
|
||||
placeholder={{i18n "docs.tags_filter_placeholder"}}
|
||||
/>
|
||||
{{/if}}
|
||||
<PluginOutlet
|
||||
@name="before-docs-tag-list"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{hash
|
||||
tags=this.tags
|
||||
updateSelectedTags=this.updateSelectedTags
|
||||
}}
|
||||
/>
|
||||
<ul>
|
||||
{{#each this.sortedTags as |tag|}}
|
||||
<li class="docs-filter-tag-{{tag.id}}">
|
||||
<DocsTag
|
||||
@tag={{tag}}
|
||||
@selectTag={{action "updateSelectedTags" tag}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (and this.tagGroups this.shouldShowTagsByGroup)}}
|
||||
<div class="docs-items docs-tags">
|
||||
<section class="item-controls">
|
||||
<h3>
|
||||
{{i18n "docs.tags"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
(eq this.tagSort.type "alpha")
|
||||
"tags-alphabet active"
|
||||
"tags-alphabet"
|
||||
}}
|
||||
@icon={{this.tagSortAlphaIcon}}
|
||||
@action={{this.toggleTagSort}}
|
||||
@actionParam="alpha"
|
||||
/>
|
||||
<DButton
|
||||
class={{if
|
||||
(eq this.tagSort.type "numeric")
|
||||
"tags-amount active"
|
||||
"tags-amount"
|
||||
}}
|
||||
@icon={{this.tagSortNumericIcon}}
|
||||
@action={{this.toggleTagSort}}
|
||||
@actionParam="numeric"
|
||||
/>
|
||||
<PluginOutlet @name="tags-controls-buttons-bottom" />
|
||||
</div>
|
||||
</section>
|
||||
{{#if this.showTagFilter}}
|
||||
<Input
|
||||
@value={{this.tagFilter}}
|
||||
class="filter"
|
||||
placeholder={{i18n "docs.tags_filter_placeholder"}}
|
||||
/>
|
||||
{{/if}}
|
||||
<PluginOutlet
|
||||
@name="before-docs-tag-list"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{hash
|
||||
tags=this.tags
|
||||
updateSelectedTags=this.updateSelectedTags
|
||||
}}
|
||||
/>
|
||||
<ul>
|
||||
{{#each this.sortedTagGroups as |tagGroup|}}
|
||||
<li class="docs-filter-tag-group-{{tagGroup.id}}">
|
||||
{{tagGroup.name}}
|
||||
<ul>
|
||||
{{#each tagGroup.tags as |tag|}}
|
||||
<li class="docs-filter-tag-{{this.id}}">
|
||||
<DocsTag
|
||||
@tag={{tag}}
|
||||
@selectTag={{action "updateSelectedTags" tag}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if this.selectedTopic}}
|
||||
<ConditionalLoadingSpinner @condition={{this.isTopicLoading}}>
|
||||
<DocsTopic @topic={{this.topic}} @return={{action "returnToList"}} />
|
||||
<PluginOutlet
|
||||
@name="below-docs-topic"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{hash topic=this.topic}}
|
||||
/>
|
||||
</ConditionalLoadingSpinner>
|
||||
{{else}}
|
||||
<div class="docs-results">
|
||||
{{#if this.isSearchingOrFiltered}}
|
||||
{{#if this.emptyResults}}
|
||||
<div class="result-count no-result">
|
||||
{{i18n "search.no_results"}}
|
||||
</div>
|
||||
<span>
|
||||
<PluginOutlet
|
||||
@name="after-docs-empty-results"
|
||||
@connectorTagName="div"
|
||||
/>
|
||||
</span>
|
||||
{{else}}
|
||||
<div class="result-count">
|
||||
{{i18n "docs.search.results" count=this.topicCount}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#unless this.emptyResults}}
|
||||
<LoadMore @selector=".topic-list tr" @action={{this.loadMore}}>
|
||||
<BasicTopicList
|
||||
@topics={{this.topics}}
|
||||
@ascending={{this.ascending}}
|
||||
@order={{this.orderColumn}}
|
||||
@changeSort={{action "sortBy"}}
|
||||
/>
|
||||
</LoadMore>
|
||||
<ConditionalLoadingSpinner @condition={{this.isLoadingMore}} />
|
||||
{{/unless}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</ConditionalLoadingSpinner>
|
|
@ -0,0 +1,30 @@
|
|||
import RouteTemplate from "ember-route-template";
|
||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||
import lazyHash from "discourse/helpers/lazy-hash";
|
||||
import DocsSearch from "../components/docs-search";
|
||||
|
||||
export default RouteTemplate(
|
||||
<template>
|
||||
<div class="docs">
|
||||
<span>
|
||||
<PluginOutlet
|
||||
@name="before-docs-search"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{lazyHash
|
||||
selectCategory=@controller.updateSelectedCategories
|
||||
selectTag=@controller.updateSelectedTags
|
||||
tags=@controller.indexController.tags
|
||||
categories=@controller.indexController.categories
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<DocsSearch
|
||||
@searchTerm={{readonly @controller.indexController.searchTerm}}
|
||||
@onSearch={{@controller.performSearch}}
|
||||
/>
|
||||
|
||||
{{outlet}}
|
||||
</div>
|
||||
</template>
|
||||
);
|
|
@ -1,21 +0,0 @@
|
|||
<div class="docs">
|
||||
<span>
|
||||
<PluginOutlet
|
||||
@name="before-docs-search"
|
||||
@connectorTagName="div"
|
||||
@outletArgs={{hash
|
||||
selectCategory=(action "updateSelectedCategories")
|
||||
selectTag=(action "updateSelectedTags")
|
||||
tags=this.indexController.tags
|
||||
categories=this.indexController.categories
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<DocsSearch
|
||||
@searchTerm={{readonly this.indexController.searchTerm}}
|
||||
@onSearch={{action "performSearch"}}
|
||||
/>
|
||||
|
||||
{{outlet}}
|
||||
</div>
|
|
@ -1,3 +1,5 @@
|
|||
@use "lib/viewport";
|
||||
|
||||
.docs-search-wrapper {
|
||||
position: relative;
|
||||
width: 500px;
|
||||
|
@ -10,7 +12,7 @@
|
|||
color: var(--primary-low-mid);
|
||||
pointer-events: none;
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
@media screen and (width <= 400px) {
|
||||
// Just decoration, remove on small screens
|
||||
display: none;
|
||||
}
|
||||
|
@ -34,7 +36,7 @@
|
|||
justify-content: center;
|
||||
padding: 1.5em 1em;
|
||||
|
||||
@include breakpoint(mobile-extra-large, min-width) {
|
||||
@include viewport.from(sm) {
|
||||
// More breathing room on larger screens
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
@ -80,7 +82,7 @@
|
|||
// be more narrow than content if needed
|
||||
min-width: 200px;
|
||||
|
||||
@include breakpoint(tablet, min-width) {
|
||||
@include viewport.from(md) {
|
||||
padding-right: 2em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@discourse/lint-configs": "2.11.1",
|
||||
"ember-template-lint": "7.0.1",
|
||||
"eslint": "9.22.0",
|
||||
"@discourse/lint-configs": "2.23.0",
|
||||
"ember-template-lint": "7.7.0",
|
||||
"eslint": "9.28.0",
|
||||
"prettier": "3.5.3",
|
||||
"stylelint": "16.16.0"
|
||||
"stylelint": "16.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 22",
|
||||
|
|
872
pnpm-lock.yaml
872
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue